diff --git a/arch/arm/dts/mt8518.dtsi b/arch/arm/dts/mt8518.dtsi index c2d17fda4a..56da91a9fe 100644 --- a/arch/arm/dts/mt8518.dtsi +++ b/arch/arm/dts/mt8518.dtsi @@ -74,6 +74,19 @@ }; }; + usb0: usb@11100000 { + compatible = "mediatek,mt8518-musb"; + reg = <0x11100000 0x1000>; + reg-names = "control"; + clocks = <&topckgen CLK_TOP_USB20_48M>, + <&topckgen CLK_TOP_USBIF>, + <&topckgen CLK_TOP_USB>; + clock-names = "usbpll", "usbmcu", "usb"; + interrupts = ; + interrupt-names = "mc"; + status = "okay"; + }; + mmc0: mmc@11120000 { compatible = "mediatek,mt8516-mmc"; reg = <0x11120000 0x1000>; diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index fc5b8f634d..d20703739f 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h @@ -7,7 +7,11 @@ #ifndef __ASM_ARM_DMA_MAPPING_H #define __ASM_ARM_DMA_MAPPING_H +#include +#include +#include #include +#include #define dma_mapping_error(x, y) 0 @@ -25,12 +29,27 @@ static inline void dma_free_coherent(void *addr) static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) { - return (unsigned long)vaddr; + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir == DMA_FROM_DEVICE) + invalidate_dcache_range(addr, addr + len); + else + flush_dcache_range(addr, addr + len); + + return addr; } static inline void dma_unmap_single(volatile void *vaddr, size_t len, - unsigned long paddr) + enum dma_data_direction dir) { + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir != DMA_TO_DEVICE) + invalidate_dcache_range(addr, addr + len); } #endif /* __ASM_ARM_DMA_MAPPING_H */ diff --git a/arch/arm/include/asm/handoff.h b/arch/arm/include/asm/handoff.h new file mode 100644 index 0000000000..0790d2ab1e --- /dev/null +++ b/arch/arm/include/asm/handoff.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Architecture-specific SPL handoff information for ARM + * + * Copyright 2019 Amarula Solutions, BV + * Written by Michael Trimarchi + */ + +#ifndef __asm_handoff_h +#define __asm_handoff_h + +/** + * struct arch_spl_handoff - architecture-specific handoff info + * + * @usable_ram_top: Value returned by board_get_usable_ram_top() in SPL + */ +struct arch_spl_handoff { + ulong usable_ram_top; +}; + +#endif diff --git a/arch/nds32/include/asm/dma-mapping.h b/arch/nds32/include/asm/dma-mapping.h index e6808dc840..c8876ceadd 100644 --- a/arch/nds32/include/asm/dma-mapping.h +++ b/arch/nds32/include/asm/dma-mapping.h @@ -6,7 +6,11 @@ #ifndef __ASM_NDS_DMA_MAPPING_H #define __ASM_NDS_DMA_MAPPING_H +#include +#include +#include #include +#include static void *dma_alloc_coherent(size_t len, unsigned long *handle) { @@ -17,12 +21,27 @@ static void *dma_alloc_coherent(size_t len, unsigned long *handle) static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) { - return (unsigned long)vaddr; + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir == DMA_FROM_DEVICE) + invalidate_dcache_range(addr, addr + len); + else + flush_dcache_range(addr, addr + len); + + return addr; } static inline void dma_unmap_single(volatile void *vaddr, size_t len, - unsigned long paddr) + enum dma_data_direction dir) { + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir != DMA_TO_DEVICE) + invalidate_dcache_range(addr, addr + len); } #endif /* __ASM_NDS_DMA_MAPPING_H */ diff --git a/arch/riscv/include/asm/dma-mapping.h b/arch/riscv/include/asm/dma-mapping.h index 3d930c90ec..6cc3946959 100644 --- a/arch/riscv/include/asm/dma-mapping.h +++ b/arch/riscv/include/asm/dma-mapping.h @@ -9,7 +9,11 @@ #ifndef __ASM_RISCV_DMA_MAPPING_H #define __ASM_RISCV_DMA_MAPPING_H +#include +#include +#include #include +#include #define dma_mapping_error(x, y) 0 @@ -27,12 +31,27 @@ static inline void dma_free_coherent(void *addr) static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) { - return (unsigned long)vaddr; + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir == DMA_FROM_DEVICE) + invalidate_dcache_range(addr, addr + len); + else + flush_dcache_range(addr, addr + len); + + return addr; } static inline void dma_unmap_single(volatile void *vaddr, size_t len, - unsigned long paddr) + enum dma_data_direction dir) { + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir != DMA_TO_DEVICE) + invalidate_dcache_range(addr, addr + len); } #endif /* __ASM_RISCV_DMA_MAPPING_H */ diff --git a/arch/x86/include/asm/dma-mapping.h b/arch/x86/include/asm/dma-mapping.h index b353ff0bef..900b99b8a6 100644 --- a/arch/x86/include/asm/dma-mapping.h +++ b/arch/x86/include/asm/dma-mapping.h @@ -7,7 +7,11 @@ #ifndef __ASM_X86_DMA_MAPPING_H #define __ASM_X86_DMA_MAPPING_H +#include +#include +#include #include +#include #define dma_mapping_error(x, y) 0 @@ -25,12 +29,27 @@ static inline void dma_free_coherent(void *addr) static inline unsigned long dma_map_single(volatile void *vaddr, size_t len, enum dma_data_direction dir) { - return (unsigned long)vaddr; + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir == DMA_FROM_DEVICE) + invalidate_dcache_range(addr, addr + len); + else + flush_dcache_range(addr, addr + len); + + return addr; } static inline void dma_unmap_single(volatile void *vaddr, size_t len, - unsigned long paddr) + enum dma_data_direction dir) { + unsigned long addr = (unsigned long)vaddr; + + len = ALIGN(len, ARCH_DMA_MINALIGN); + + if (dir != DMA_TO_DEVICE) + invalidate_dcache_range(addr, addr + len); } #endif /* __ASM_X86_DMA_MAPPING_H */ diff --git a/board/mediatek/mt8518/mt8518_ap1.c b/board/mediatek/mt8518/mt8518_ap1.c index 9710907fe2..2ac7c6cd18 100644 --- a/board/mediatek/mt8518/mt8518_ap1.c +++ b/board/mediatek/mt8518/mt8518_ap1.c @@ -16,3 +16,21 @@ int board_init(void) debug("gd->fdt_blob is %p\n", gd->fdt_blob); return 0; } + +int board_late_init(void) +{ +#ifdef CONFIG_USB_GADGET + struct udevice *dev; + int ret; +#endif + +#ifdef CONFIG_USB_GADGET + ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev); + if (ret) { + pr_err("%s: Cannot find USB device\n", __func__); + return ret; + } +#endif + + return 0; +} diff --git a/board/novtech/meerkat96/MAINTAINERS b/board/novtech/meerkat96/MAINTAINERS index 0eca2940d5..2a53b63099 100644 --- a/board/novtech/meerkat96/MAINTAINERS +++ b/board/novtech/meerkat96/MAINTAINERS @@ -1,5 +1,5 @@ MEERKAT96 BOARD -M: Shawn Guo +M: Shawn Guo S: Maintained F: board/novtech/meerkat96 F: include/configs/meerkat96.h diff --git a/cmd/mtd.c b/cmd/mtd.c index 1b6b8dda2b..a559b5a4a3 100644 --- a/cmd/mtd.c +++ b/cmd/mtd.c @@ -387,7 +387,7 @@ static int do_mtd_erase(cmd_tbl_t *cmdtp, int flag, int argc, struct mtd_info *mtd; u64 off, len; bool scrub; - int ret; + int ret = 0; if (argc < 2) return CMD_RET_USAGE; @@ -423,22 +423,22 @@ static int do_mtd_erase(cmd_tbl_t *cmdtp, int flag, int argc, erase_op.mtd = mtd; erase_op.addr = off; - erase_op.len = len; + erase_op.len = mtd->erasesize; erase_op.scrub = scrub; - while (erase_op.len) { + while (len) { ret = mtd_erase(mtd, &erase_op); - /* Abort if its not a bad block error */ - if (ret != -EIO) - break; + if (ret) { + /* Abort if its not a bad block error */ + if (ret != -EIO) + break; + printf("Skipping bad block at 0x%08llx\n", + erase_op.addr); + } - printf("Skipping bad block at 0x%08llx\n", erase_op.fail_addr); - - /* Skip bad block and continue behind it */ - erase_op.len -= erase_op.fail_addr - erase_op.addr; - erase_op.len -= mtd->erasesize; - erase_op.addr = erase_op.fail_addr + mtd->erasesize; + len -= mtd->erasesize; + erase_op.addr += mtd->erasesize; } if (ret && ret != -EIO) diff --git a/common/board_r.c b/common/board_r.c index 8a0c1114e7..4f56c19fcc 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -864,6 +864,9 @@ static init_fnc_t init_sequence_r[] = { #endif #if defined(CONFIG_PRAM) initr_mem, +#endif +#ifdef CONFIG_BLOCK_CACHE + blkcache_init, #endif run_main_loop, }; diff --git a/configs/mt8518_ap1_emmc_defconfig b/configs/mt8518_ap1_emmc_defconfig index 586b825bd3..50219dd446 100644 --- a/configs/mt8518_ap1_emmc_defconfig +++ b/configs/mt8518_ap1_emmc_defconfig @@ -9,13 +9,21 @@ CONFIG_NR_DRAM_BANKS=1 CONFIG_FIT=y CONFIG_FIT_SIGNATURE=y CONFIG_DEFAULT_FDT_FILE="mt8518-ap1-emmc.dtb" +CONFIG_BOARD_LATE_INIT=y CONFIG_SYS_PROMPT="MT8518> " CONFIG_CMD_BOOTMENU=y CONFIG_CMD_MMC=y +CONFIG_EFI_PARTITION=y CONFIG_DEFAULT_DEVICE_TREE="mt8518-ap1-emmc" CONFIG_REGMAP=y CONFIG_SYSCON=y CONFIG_CLK=y +CONFIG_USB_FUNCTION_FASTBOOT=y +CONFIG_FASTBOOT_BUF_ADDR=0x56000000 +CONFIG_FASTBOOT_BUF_SIZE=0x1E00000 +CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT=y +CONFIG_FASTBOOT_FLASH=y +CONFIG_FASTBOOT_FLASH_MMC_DEV=0 CONFIG_DM_MMC=y CONFIG_MMC_HS200_SUPPORT=y CONFIG_MMC_MTK=y @@ -27,6 +35,14 @@ CONFIG_DM_SERIAL=y CONFIG_MTK_SERIAL=y CONFIG_TIMER=y CONFIG_MTK_TIMER=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_MUSB_GADGET=y +CONFIG_USB_MUSB_MT85XX=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_MANUFACTURER="Mediatek." +CONFIG_USB_GADGET_VENDOR_NUM=0x0bb4 +CONFIG_USB_GADGET_PRODUCT_NUM=0x0c01 CONFIG_WDT=y CONFIG_WDT_MTK=y CONFIG_LZ4=y diff --git a/drivers/block/blkcache.c b/drivers/block/blkcache.c index 1fa64989d3..f603aa129d 100644 --- a/drivers/block/blkcache.c +++ b/drivers/block/blkcache.c @@ -21,13 +21,20 @@ struct block_cache_node { char *cache; }; -static LIST_HEAD(block_cache); +static struct list_head block_cache; static struct block_cache_stats _stats = { .max_blocks_per_entry = 8, .max_entries = 32 }; +int blkcache_init(void) +{ + INIT_LIST_HEAD(&block_cache); + + return 0; +} + static struct block_cache_node *cache_find(int iftype, int devnum, lbaint_t start, lbaint_t blkcnt, unsigned long blksz) diff --git a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c index 5a098f83cc..46b9f1825c 100644 --- a/drivers/crypto/rsa_mod_exp/mod_exp_sw.c +++ b/drivers/crypto/rsa_mod_exp/mod_exp_sw.c @@ -9,8 +9,8 @@ #include #include -int mod_exp_sw(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, - struct key_prop *prop, uint8_t *out) +static int mod_exp_sw(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, + struct key_prop *prop, uint8_t *out) { int ret = 0; diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index 9f85054bfb..d4436dfc91 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -104,6 +104,36 @@ config FASTBOOT_FLASH_NAND_TRIMFFS When flashing NAND enable the DROP_FFS flag to drop trailing all-0xff pages. +config FASTBOOT_MMC_BOOT1_SUPPORT + bool "Enable EMMC_BOOT1 flash/erase" + depends on FASTBOOT_FLASH_MMC && EFI_PARTITION && ARCH_MEDIATEK + help + The fastboot "flash" and "erase" commands normally does operations + on EMMC userdata. Define this to enable the special commands to + flash/erase EMMC_BOOT1. + The default target name for updating EMMC_BOOT1 is "mmc0boot0". + +config FASTBOOT_MMC_BOOT1_NAME + string "Target name for updating EMMC_BOOT1" + depends on FASTBOOT_MMC_BOOT1_SUPPORT + default "mmc0boot0" + help + The fastboot "flash" and "erase" commands support operations on + EMMC_BOOT1. This occurs when the specified "EMMC_BOOT1 name" on + the "fastboot flash" and "fastboot erase" commands match the value + defined here. + The default target name for updating EMMC_BOOT1 is "mmc0boot0". + +config FASTBOOT_MMC_USER_NAME + string "Target name for erasing EMMC_USER" + depends on FASTBOOT_FLASH_MMC && EFI_PARTITION && ARCH_MEDIATEK + default "mmc0" + help + The fastboot "erase" command supports erasing EMMC_USER. This occurs + when the specified "EMMC_USER name" on the "fastboot erase" commands + match the value defined here. + The default target name for erasing EMMC_USER is "mmc0". + config FASTBOOT_GPT_NAME string "Target name for updating GPT" depends on FASTBOOT_FLASH_MMC && EFI_PARTITION diff --git a/drivers/fastboot/fb_mmc.c b/drivers/fastboot/fb_mmc.c index b0b19c5762..d7cf9f4aac 100644 --- a/drivers/fastboot/fb_mmc.c +++ b/drivers/fastboot/fb_mmc.c @@ -129,6 +129,76 @@ static void write_raw_image(struct blk_desc *dev_desc, disk_partition_t *info, fastboot_okay(NULL, response); } +#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT +static int fb_mmc_erase_mmc_hwpart(struct blk_desc *dev_desc) +{ + lbaint_t blks; + + debug("Start Erasing mmc hwpart[%u]...\n", dev_desc->hwpart); + + blks = fb_mmc_blk_write(dev_desc, 0, dev_desc->lba, NULL); + + if (blks != dev_desc->lba) { + pr_err("Failed to erase mmc hwpart[%u]\n", dev_desc->hwpart); + return 1; + } + + printf("........ erased %lu bytes from mmc hwpart[%u]\n", + dev_desc->lba * dev_desc->blksz, dev_desc->hwpart); + + return 0; +} + +static void fb_mmc_boot1_ops(struct blk_desc *dev_desc, void *buffer, + u32 buff_sz, char *response) +{ + lbaint_t blkcnt; + lbaint_t blks; + unsigned long blksz; + + // To operate on EMMC_BOOT1 (mmc0boot0), we first change the hwpart + if (blk_dselect_hwpart(dev_desc, 1)) { + pr_err("Failed to select hwpart\n"); + fastboot_fail("Failed to select hwpart", response); + return; + } + + if (buffer) { /* flash */ + + /* determine number of blocks to write */ + blksz = dev_desc->blksz; + blkcnt = ((buff_sz + (blksz - 1)) & ~(blksz - 1)); + blkcnt = lldiv(blkcnt, blksz); + + if (blkcnt > dev_desc->lba) { + pr_err("Image size too large\n"); + fastboot_fail("Image size too large", response); + return; + } + + debug("Start Flashing Image to EMMC_BOOT1...\n"); + + blks = fb_mmc_blk_write(dev_desc, 0, blkcnt, buffer); + + if (blks != blkcnt) { + pr_err("Failed to write EMMC_BOOT1\n"); + fastboot_fail("Failed to write EMMC_BOOT1", response); + return; + } + + printf("........ wrote %lu bytes to EMMC_BOOT1\n", + blkcnt * blksz); + } else { /* erase */ + if (fb_mmc_erase_mmc_hwpart(dev_desc)) { + fastboot_fail("Failed to erase EMMC_BOOT1", response); + return; + } + } + + fastboot_okay(NULL, response); +} +#endif + #ifdef CONFIG_ANDROID_BOOT_IMAGE /** * Read Android boot image header from boot partition. @@ -345,8 +415,21 @@ void fastboot_mmc_flash_write(const char *cmd, void *download_buffer, return; } +#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT + if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) { + fb_mmc_boot1_ops(dev_desc, download_buffer, + download_bytes, response); + return; + } +#endif + #if CONFIG_IS_ENABLED(EFI_PARTITION) +#ifndef CONFIG_FASTBOOT_MMC_USER_NAME if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) { +#else + if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0 || + strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) { +#endif printf("%s: updating MBR, Primary and Backup GPT(s)\n", __func__); if (is_valid_gpt_buf(dev_desc, download_buffer)) { @@ -457,6 +540,25 @@ void fastboot_mmc_erase(const char *cmd, char *response) return; } +#ifdef CONFIG_FASTBOOT_MMC_BOOT1_SUPPORT + if (strcmp(cmd, CONFIG_FASTBOOT_MMC_BOOT1_NAME) == 0) { + /* erase EMMC boot1 */ + fb_mmc_boot1_ops(dev_desc, NULL, 0, response); + return; + } +#endif + +#ifdef CONFIG_FASTBOOT_MMC_USER_NAME + if (strcmp(cmd, CONFIG_FASTBOOT_MMC_USER_NAME) == 0) { + /* erase EMMC userdata */ + if (fb_mmc_erase_mmc_hwpart(dev_desc)) + fastboot_fail("Failed to erase EMMC_USER", response); + else + fastboot_okay(NULL, response); + return; + } +#endif + ret = part_get_info_by_name_or_alias(dev_desc, cmd, &info); if (ret < 0) { pr_err("cannot find partition: '%s'\n", cmd); diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c index 669410d97f..5a8506dcb6 100644 --- a/drivers/mmc/tmio-common.c +++ b/drivers/mmc/tmio-common.c @@ -4,6 +4,7 @@ * Author: Masahiro Yamada */ +#include #include #include #include @@ -76,26 +77,6 @@ void tmio_sd_writel(struct tmio_sd_priv *priv, writel(val, priv->regbase + reg); } -static dma_addr_t __dma_map_single(void *ptr, size_t size, - enum dma_data_direction dir) -{ - unsigned long addr = (unsigned long)ptr; - - if (dir == DMA_FROM_DEVICE) - invalidate_dcache_range(addr, addr + size); - else - flush_dcache_range(addr, addr + size); - - return addr; -} - -static void __dma_unmap_single(dma_addr_t addr, size_t size, - enum dma_data_direction dir) -{ - if (dir != DMA_TO_DEVICE) - invalidate_dcache_range(addr, addr + size); -} - static int tmio_sd_check_error(struct udevice *dev, struct mmc_cmd *cmd) { struct tmio_sd_priv *priv = dev_get_priv(dev); @@ -362,7 +343,7 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data) tmio_sd_writel(priv, tmp, TMIO_SD_DMA_MODE); - dma_addr = __dma_map_single(buf, len, dir); + dma_addr = dma_map_single(buf, len, dir); tmio_sd_dma_start(priv, dma_addr); @@ -371,7 +352,7 @@ static int tmio_sd_dma_xfer(struct udevice *dev, struct mmc_data *data) if (poll_flag == TMIO_SD_DMA_INFO1_END_RD) udelay(1); - __dma_unmap_single(dma_addr, len, dir); + dma_unmap_single(buf, len, dir); return ret; } diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 0a7ca8a8df..8537c609fb 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -5,7 +5,7 @@ * Copyright (C) 2009-2010, Intel Corporation and its suppliers. */ -#include +#include #include #include #include @@ -17,35 +17,6 @@ #include "denali.h" -static dma_addr_t dma_map_single(void *dev, void *ptr, size_t size, - enum dma_data_direction dir) -{ - unsigned long addr = (unsigned long)ptr; - - size = ALIGN(size, ARCH_DMA_MINALIGN); - - if (dir == DMA_FROM_DEVICE) - invalidate_dcache_range(addr, addr + size); - else - flush_dcache_range(addr, addr + size); - - return addr; -} - -static void dma_unmap_single(void *dev, dma_addr_t addr, size_t size, - enum dma_data_direction dir) -{ - size = ALIGN(size, ARCH_DMA_MINALIGN); - - if (dir != DMA_TO_DEVICE) - invalidate_dcache_range(addr, addr + size); -} - -static int dma_mapping_error(void *dev, dma_addr_t addr) -{ - return 0; -} - #define DENALI_NAND_NAME "denali-nand" /* for Indexed Addressing */ @@ -565,7 +536,7 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; int ret = 0; - dma_addr = dma_map_single(denali->dev, buf, size, dir); + dma_addr = dma_map_single(buf, size, dir); if (dma_mapping_error(denali->dev, dma_addr)) { dev_dbg(denali->dev, "Failed to DMA-map buffer. Trying PIO.\n"); return denali_pio_xfer(denali, buf, size, page, raw, write); @@ -606,7 +577,7 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, iowrite32(0, denali->reg + DMA_ENABLE); - dma_unmap_single(denali->dev, dma_addr, size, dir); + dma_unmap_single(buf, size, dir); if (irq_status & INTR__ERASED_PAGE) memset(buf, 0xff, size); diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 8359425378..0d4929bec1 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -327,8 +327,6 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet, macb->tx_ring[tx_head].addr = paddr; barrier(); macb_flush_ring_desc(macb, TX); - /* Do we need check paddr and length is dcache line aligned? */ - flush_dcache_range(paddr, paddr + ALIGN(length, ARCH_DMA_MINALIGN)); macb_writel(macb, NCR, MACB_BIT(TE) | MACB_BIT(RE) | MACB_BIT(TSTART)); /* @@ -344,7 +342,7 @@ static int _macb_send(struct macb_device *macb, const char *name, void *packet, udelay(1); } - dma_unmap_single(packet, length, paddr); + dma_unmap_single(packet, length, DMA_TO_DEVICE); if (i <= MACB_TX_TIMEOUT) { if (ctrl & MACB_BIT(TX_UNDERRUN)) diff --git a/drivers/remoteproc/rproc-elf-loader.c b/drivers/remoteproc/rproc-elf-loader.c index 538481241f..d234592445 100644 --- a/drivers/remoteproc/rproc-elf-loader.c +++ b/drivers/remoteproc/rproc-elf-loader.c @@ -189,7 +189,7 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size) ops = rproc_get_ops(dev); /* Load each program header */ - for (i = 0; i < ehdr->e_phnum; ++i) { + for (i = 0; i < ehdr->e_phnum; i++, phdr++) { void *dst = (void *)(uintptr_t)phdr->p_paddr; void *src = (void *)addr + phdr->p_offset; @@ -211,7 +211,6 @@ int rproc_elf32_load_image(struct udevice *dev, unsigned long addr, ulong size) roundup((unsigned long)dst + phdr->p_filesz, ARCH_DMA_MINALIGN) - rounddown((unsigned long)dst, ARCH_DMA_MINALIGN)); - ++phdr; } return 0; diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig index 35a3bd192a..893b89d49b 100644 --- a/drivers/rng/Kconfig +++ b/drivers/rng/Kconfig @@ -9,7 +9,6 @@ config DM_RNG config RNG_SANDBOX bool "Sandbox random number generator" depends on SANDBOX && DM_RNG - select CONFIG_LIB_RAND help Enable random number generator for sandbox. This is an emulation of a rng device. diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index a92d2b1de8..9851663dc5 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -171,6 +171,13 @@ void NS16550_init(NS16550_t com_port, int baud_divisor) == UART_LSR_THRE) { if (baud_divisor != -1) NS16550_setbrg(com_port, baud_divisor); + else { + // Re-use old baud rate divisor to flush transmit reg. + const int dll = serial_in(&com_port->dll); + const int dlm = serial_in(&com_port->dlm); + const int divisor = dll | (dlm << 8); + NS16550_setbrg(com_port, divisor); + } serial_out(0, &com_port->mdr1); } #endif diff --git a/drivers/usb/musb-new/Kconfig b/drivers/usb/musb-new/Kconfig index 79ad14ef66..6cf8a2b60b 100644 --- a/drivers/usb/musb-new/Kconfig +++ b/drivers/usb/musb-new/Kconfig @@ -47,6 +47,15 @@ config USB_MUSB_DSPS bool "TI DSPS platforms" if USB_MUSB_HOST || USB_MUSB_GADGET +config USB_MUSB_MT85XX + bool "Enable Mediatek MT85XX DRC USB controller" + depends on DM_USB && ARCH_MEDIATEK + default n + help + Say y to enable Mediatek MT85XX USB DRC controller support + if it is available on your Mediatek MUSB IP based platform. + DMA controllers are ignored. This driver follow musb-new + driver and usb gadget framework. config USB_MUSB_PIC32 bool "Enable Microchip PIC32 DRC USB controller" @@ -76,7 +85,7 @@ endif config USB_MUSB_PIO_ONLY bool "Disable DMA (always use PIO)" - default y if USB_MUSB_AM35X || USB_MUSB_PIC32 || USB_MUSB_OMAP2PLUS || USB_MUSB_DSPS || USB_MUSB_SUNXI + default y if USB_MUSB_AM35X || USB_MUSB_PIC32 || USB_MUSB_OMAP2PLUS || USB_MUSB_DSPS || USB_MUSB_SUNXI || USB_MUSB_MT85XX help All data is copied between memory and FIFO by the CPU. DMA controllers are ignored. diff --git a/drivers/usb/musb-new/Makefile b/drivers/usb/musb-new/Makefile index ec7852ce94..6355eb12dd 100644 --- a/drivers/usb/musb-new/Makefile +++ b/drivers/usb/musb-new/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_USB_MUSB_HOST) += musb_host.o musb_core.o musb_uboot.o obj-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o obj-$(CONFIG_USB_MUSB_DA8XX) += da8xx.o obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o +obj-$(CONFIG_USB_MUSB_MT85XX) += mt85xx.o obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o obj-$(CONFIG_USB_MUSB_PIC32) += pic32.o obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o diff --git a/drivers/usb/musb-new/mt85xx.c b/drivers/usb/musb-new/mt85xx.c new file mode 100644 index 0000000000..131fd7dd79 --- /dev/null +++ b/drivers/usb/musb-new/mt85xx.c @@ -0,0 +1,417 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek "glue layer" + * + * Copyright (C) 2019-2021 by Mediatek + * Based on the AllWinner SUNXI "glue layer" code. + * Copyright (C) 2015 Hans de Goede + * Copyright (C) 2013 Jussi Kivilinna + * + * This file is part of the Inventra Controller Driver for Linux. + */ +#include +#include +#include +#include +#include +#include +#include +#include "linux-compat.h" +#include "musb_core.h" +#include "musb_uboot.h" + +#define DBG_I(fmt, ...) \ + pr_info(fmt, ##__VA_ARGS__) + +struct mtk_musb_config { + struct musb_hdrc_config *config; +}; + +struct mtk_musb_glue { + struct musb_host_data mdata; + struct clk usbpllclk; + struct clk usbmcuclk; + struct clk usbclk; + struct mtk_musb_config *cfg; + struct device dev; +}; + +#define to_mtk_musb_glue(d) container_of(d, struct mtk_musb_glue, dev) + +/****************************************************************************** + * phy settings + ******************************************************************************/ +#define USB20_PHY_BASE 0x11110800 +#define USBPHY_READ8(offset) \ + readb((void *)(USB20_PHY_BASE + (offset))) +#define USBPHY_WRITE8(offset, value) \ + writeb(value, (void *)(USB20_PHY_BASE + (offset))) +#define USBPHY_SET8(offset, mask) \ + USBPHY_WRITE8(offset, (USBPHY_READ8(offset)) | (mask)) +#define USBPHY_CLR8(offset, mask) \ + USBPHY_WRITE8(offset, (USBPHY_READ8(offset)) & (~(mask))) + +static void mt_usb_phy_poweron(void) +{ + /* + * switch to USB function. + * (system register, force ip into usb mode). + */ + USBPHY_CLR8(0x6b, 0x04); + USBPHY_CLR8(0x6e, 0x01); + USBPHY_CLR8(0x21, 0x03); + + /* RG_USB20_BC11_SW_EN = 1'b0 */ + USBPHY_SET8(0x22, 0x04); + USBPHY_CLR8(0x1a, 0x80); + + /* RG_USB20_DP_100K_EN = 1'b0 */ + /* RG_USB20_DP_100K_EN = 1'b0 */ + USBPHY_CLR8(0x22, 0x03); + + /*OTG enable*/ + USBPHY_SET8(0x20, 0x10); + /* release force suspendm */ + USBPHY_CLR8(0x6a, 0x04); + + mdelay(800); + + /* force enter device mode */ + USBPHY_CLR8(0x6c, 0x10); + USBPHY_SET8(0x6c, 0x2E); + USBPHY_SET8(0x6d, 0x3E); +} + +static void mt_usb_phy_savecurrent(void) +{ + /* + * switch to USB function. + * (system register, force ip into usb mode). + */ + USBPHY_CLR8(0x6b, 0x04); + USBPHY_CLR8(0x6e, 0x01); + USBPHY_CLR8(0x21, 0x03); + + /* release force suspendm */ + USBPHY_CLR8(0x6a, 0x04); + USBPHY_SET8(0x68, 0x04); + /* RG_DPPULLDOWN./RG_DMPULLDOWN. */ + USBPHY_SET8(0x68, 0xc0); + /* RG_XCVRSEL[1:0] = 2'b01 */ + USBPHY_CLR8(0x68, 0x30); + USBPHY_SET8(0x68, 0x10); + /* RG_TERMSEL = 1'b1 */ + USBPHY_SET8(0x68, 0x04); + /* RG_DATAIN[3:0] = 4'b0000 */ + USBPHY_CLR8(0x69, 0x3c); + + /* + * force_dp_pulldown, force_dm_pulldown, + * force_xcversel, force_termsel. + */ + USBPHY_SET8(0x6a, 0xba); + + /* RG_USB20_BC11_SW_EN = 1'b0 */ + USBPHY_CLR8(0x1a, 0x80); + /* RG_USB20_OTG_VBUSSCMP_EN = 1'b0 */ + USBPHY_CLR8(0x1a, 0x10); + + mdelay(800); + + USBPHY_CLR8(0x6a, 0x04); + /* rg_usb20_pll_stable = 1 */ + //USBPHY_SET8(0x63, 0x02); + + mdelay(1); + + /* force suspendm = 1 */ + //USBPHY_SET8(0x6a, 0x04); +} + +static void mt_usb_phy_recover(void) +{ + /* clean PUPD_BIST_EN */ + /* PUPD_BIST_EN = 1'b0 */ + /* PMIC will use it to detect charger type */ + USBPHY_CLR8(0x1d, 0x10); + + /* force_uart_en = 1'b0 */ + USBPHY_CLR8(0x6b, 0x04); + /* RG_UART_EN = 1'b0 */ + USBPHY_CLR8(0x6e, 0x01); + /* force_uart_en = 1'b0 */ + USBPHY_CLR8(0x6a, 0x04); + + USBPHY_CLR8(0x21, 0x03); + USBPHY_CLR8(0x68, 0xf4); + + /* RG_DATAIN[3:0] = 4'b0000 */ + USBPHY_CLR8(0x69, 0x3c); + + USBPHY_CLR8(0x6a, 0xba); + + /* RG_USB20_BC11_SW_EN = 1'b0 */ + USBPHY_CLR8(0x1a, 0x80); + /* RG_USB20_OTG_VBUSSCMP_EN = 1'b1 */ + USBPHY_SET8(0x1a, 0x10); + + //HQA adjustment + USBPHY_CLR8(0x18, 0x08); + USBPHY_SET8(0x18, 0x06); + mdelay(800); + + /* force enter device mode */ + //USBPHY_CLR8(0x6c, 0x10); + //USBPHY_SET8(0x6c, 0x2E); + //USBPHY_SET8(0x6d, 0x3E); + + /* enable VRT internal R architecture */ + /* RG_USB20_INTR_EN = 1'b1 */ + USBPHY_SET8(0x00, 0x20); +} + +/****************************************************************************** + * MUSB Glue code + ******************************************************************************/ + +static irqreturn_t mtk_musb_interrupt(int irq, void *__hci) +{ + struct musb *musb = __hci; + irqreturn_t retval = IRQ_NONE; + + /* read and flush interrupts */ + musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB); +// last_int_usb = musb->int_usb; + if (musb->int_usb) + musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb); + musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX); + if (musb->int_tx) + musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx); + musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX); + if (musb->int_rx) + musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx); + + if (musb->int_usb || musb->int_tx || musb->int_rx) + retval |= musb_interrupt(musb); + + return retval; +} + +/* musb_core does not call enable / disable in a balanced manner */ +static bool enabled; + +static int mtk_musb_enable(struct musb *musb) +{ + struct mtk_musb_glue *glue = to_mtk_musb_glue(musb->controller); + + DBG_I("%s():\n", __func__); + + musb_ep_select(musb->mregs, 0); + musb_writeb(musb->mregs, MUSB_FADDR, 0); + + if (enabled) + return 0; + + mt_usb_phy_recover(); + + enabled = true; + + return 0; +} + +static void mtk_musb_disable(struct musb *musb) +{ + struct mtk_musb_glue *glue = to_mtk_musb_glue(musb->controller); + int ret; + + DBG_I("%s():\n", __func__); + + if (!enabled) + return; + + mt_usb_phy_savecurrent(); + + enabled = false; +} + +static int mtk_musb_init(struct musb *musb) +{ + struct mtk_musb_glue *glue = to_mtk_musb_glue(musb->controller); + int ret; + + DBG_I("%s():\n", __func__); + + ret = clk_enable(&glue->usbpllclk); + if (ret) { + dev_err(dev, "failed to enable usbpll clock\n"); + return ret; + } + ret = clk_enable(&glue->usbmcuclk); + if (ret) { + dev_err(dev, "failed to enable usbmcu clock\n"); + return ret; + } + ret = clk_enable(&glue->usbclk); + if (ret) { + dev_err(dev, "failed to enable usb clock\n"); + return ret; + } + + musb->isr = mtk_musb_interrupt; + + return 0; +} + +static int mtk_musb_exit(struct musb *musb) +{ + struct mtk_musb_glue *glue = to_mtk_musb_glue(musb->controller); + + clk_disable(&glue->usbclk); + clk_disable(&glue->usbmcuclk); + clk_disable(&glue->usbpllclk); + + return 0; +} + +static const struct musb_platform_ops mtk_musb_ops = { + .init = mtk_musb_init, + .exit = mtk_musb_exit, + .enable = mtk_musb_enable, + .disable = mtk_musb_disable, +}; + +/* MTK OTG supports up to 7 endpoints */ +#define MTK_MUSB_MAX_EP_NUM 8 +#define MTK_MUSB_RAM_BITS 16 + +static struct musb_fifo_cfg mtk_musb_mode_cfg[] = { + MUSB_EP_FIFO_SINGLE(1, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(1, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(2, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(2, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(3, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(3, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(4, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(4, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(5, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(5, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(6, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(6, FIFO_RX, 512), + MUSB_EP_FIFO_SINGLE(7, FIFO_TX, 512), + MUSB_EP_FIFO_SINGLE(7, FIFO_RX, 512), +}; + +static struct musb_hdrc_config musb_config = { + .fifo_cfg = mtk_musb_mode_cfg, + .fifo_cfg_size = ARRAY_SIZE(mtk_musb_mode_cfg), + .multipoint = true, + .dyn_fifo = true, + .num_eps = MTK_MUSB_MAX_EP_NUM, + .ram_bits = MTK_MUSB_RAM_BITS, +}; + +static int musb_usb_probe(struct udevice *dev) +{ + struct mtk_musb_glue *glue = dev_get_priv(dev); + struct musb_host_data *host = &glue->mdata; + struct musb_hdrc_platform_data pdata; + void *base = dev_read_addr_ptr(dev); + int ret; + + DBG_I("%s():\n", __func__); + +#ifdef CONFIG_USB_MUSB_HOST + struct usb_bus_priv *priv = dev_get_uclass_priv(dev); +#endif + + if (!base) + return -EINVAL; + + glue->cfg = (struct mtk_musb_config *)dev_get_driver_data(dev); + if (!glue->cfg) + return -EINVAL; + + ret = clk_get_by_name(dev, "usbpll", &glue->usbpllclk); + if (ret) { + dev_err(dev, "failed to get usbpll clock\n"); + return ret; + } + ret = clk_get_by_name(dev, "usbmcu", &glue->usbmcuclk); + if (ret) { + dev_err(dev, "failed to get usbmcu clock\n"); + return ret; + } + ret = clk_get_by_name(dev, "usb", &glue->usbclk); + if (ret) { + dev_err(dev, "failed to get usb clock\n"); + return ret; + } + + memset(&pdata, 0, sizeof(pdata)); + pdata.power = (u8)400; + pdata.platform_ops = &mtk_musb_ops; + pdata.config = glue->cfg->config; + +#ifdef CONFIG_USB_MUSB_HOST + priv->desc_before_addr = true; + + pdata.mode = MUSB_HOST; + host->host = musb_init_controller(&pdata, &glue->dev, base); + if (!host->host) + return -EIO; + + ret = musb_lowlevel_init(host); + if (!ret) + printf("MTK MUSB OTG (Host)\n"); +#else + pdata.mode = MUSB_PERIPHERAL; + host->host = musb_register(&pdata, &glue->dev, base); + if (!host->host) + return -EIO; + + printf("MTK MUSB OTG (Peripheral)\n"); +#endif + + mt_usb_phy_poweron(); + + return ret; +} + +static int musb_usb_remove(struct udevice *dev) +{ + struct mtk_musb_glue *glue = dev_get_priv(dev); + struct musb_host_data *host = &glue->mdata; + + musb_stop(host->host); + free(host->host); + host->host = NULL; + + return 0; +} + +static const struct mtk_musb_config mt8518_cfg = { + .config = &musb_config, +}; + +static const struct udevice_id mtk_musb_ids[] = { + { .compatible = "mediatek,mt8518-musb", + .data = (ulong)&mt8518_cfg }, + { } +}; + +U_BOOT_DRIVER(mtk_musb) = { + .name = "mtk_musb", +#ifdef CONFIG_USB_MUSB_HOST + .id = UCLASS_USB, +#else + .id = UCLASS_USB_GADGET_GENERIC, +#endif + .of_match = mtk_musb_ids, + .probe = musb_usb_probe, + .remove = musb_usb_remove, +#ifdef CONFIG_USB_MUSB_HOST + .ops = &musb_usb_ops, +#endif + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct mtk_musb_glue), +}; diff --git a/include/blk.h b/include/blk.h index d0c033aece..6f541bb2ba 100644 --- a/include/blk.h +++ b/include/blk.h @@ -113,6 +113,12 @@ struct blk_desc { (PAD_SIZE(size, blk_desc->blksz)) #if CONFIG_IS_ENABLED(BLOCK_CACHE) + +/** + * blkcache_init() - initialize the block cache list pointers + */ +int blkcache_init(void); + /** * blkcache_read() - attempt to read a set of blocks from cache * @@ -123,7 +129,7 @@ struct blk_desc { * @param blksz - size in bytes of each block * @param buf - buffer to contain cached data * - * @return - '1' if block returned from cache, '0' otherwise. + * @return - 1 if block returned from cache, 0 otherwise. */ int blkcache_read(int iftype, int dev, lbaint_t start, lbaint_t blkcnt, diff --git a/include/configs/mt8518.h b/include/configs/mt8518.h index 514722be99..276fbc285f 100644 --- a/include/configs/mt8518.h +++ b/include/configs/mt8518.h @@ -11,7 +11,6 @@ #include -/* Machine ID */ #define CONFIG_SYS_NONCACHED_MEMORY SZ_1M #define CONFIG_CPU_ARMV8 @@ -54,10 +53,15 @@ #define ENV_BOOT_CMD \ "mtk_boot=run boot_rd_img;bootm;\0" +#define ENV_FASTBOOT \ + "serial#=1234567890ABCDEF\0" \ + "board=mt8518\0" + #define CONFIG_EXTRA_ENV_SETTINGS \ "fdt_high=0x6c000000\0" \ ENV_DEVICE_SETTINGS \ ENV_BOOT_READ_IMAGE \ + ENV_FASTBOOT \ ENV_BOOT_CMD \ "bootcmd=run mtk_boot;\0" \ diff --git a/include/mtd.h b/include/mtd.h index 65fcd3c700..b0f8693386 100644 --- a/include/mtd.h +++ b/include/mtd.h @@ -11,4 +11,6 @@ int mtd_probe(struct udevice *dev); int mtd_probe_devices(void); +void board_mtdparts_default(const char **mtdids, const char **mtdparts); + #endif /* _MTD_H_ */ diff --git a/lib/Kconfig b/lib/Kconfig index d040a87d26..ab6aff710d 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -150,7 +150,8 @@ config REGEX choice prompt "Pseudo-random library support type" - depends on NET_RANDOM_ETHADDR || RANDOM_UUID || CMD_UUID + depends on NET_RANDOM_ETHADDR || RANDOM_UUID || CMD_UUID || \ + RNG_SANDBOX || UT_LIB && AES default LIB_RAND help Select the library to provide pseudo-random number generator diff --git a/lib/Makefile b/lib/Makefile index 51eba80b89..15259d0473 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -58,7 +58,7 @@ obj-$(CONFIG_TPM_V1) += tpm-v1.o obj-$(CONFIG_TPM_V2) += tpm-v2.o endif -obj-$(CONFIG_RSA) += rsa/ +obj-$(CONFIG_$(SPL_)RSA) += rsa/ obj-$(CONFIG_SHA1) += sha1.o obj-$(CONFIG_SHA256) += sha256.o diff --git a/tools/fdtgrep.c b/tools/fdtgrep.c index 8f44f599c1..2a8058f57f 100644 --- a/tools/fdtgrep.c +++ b/tools/fdtgrep.c @@ -805,7 +805,7 @@ static int do_fdtgrep(struct display_info *disp, const char *filename) * we do another pass to actually record them. */ for (i = 0; i < 2; i++) { - region = malloc(count * sizeof(struct fdt_region)); + region = realloc(region, count * sizeof(struct fdt_region)); if (!region) { fprintf(stderr, "Out of memory for %d regions\n", count); @@ -823,8 +823,10 @@ static int do_fdtgrep(struct display_info *disp, const char *filename) } if (count <= max_regions) break; + } + if (count > max_regions) { free(region); - fprintf(stderr, "Internal error with fdtgrep_find_region)(\n"); + fprintf(stderr, "Internal error with fdtgrep_find_region()\n"); return -1; } diff --git a/tools/genboardscfg.py b/tools/genboardscfg.py index 24df13e500..4f6382bc7c 100755 --- a/tools/genboardscfg.py +++ b/tools/genboardscfg.py @@ -10,8 +10,6 @@ Converter from Kconfig and MAINTAINERS to a board database. Run 'tools/genboardscfg.py' to create a board database. Run 'tools/genboardscfg.py -h' for available options. - -Python 2.6 or later, but not Python 3.x is necessary to run this script. """ import errno