diff options
46 files changed, 520 insertions, 68 deletions
diff --git a/arch/arm/dts/zynq-microzed.dts b/arch/arm/dts/zynq-microzed.dts index e841a1d6166..793ab44eae2 100644 --- a/arch/arm/dts/zynq-microzed.dts +++ b/arch/arm/dts/zynq-microzed.dts @@ -24,6 +24,7 @@ }; &qspi { + u-boot,dm-pre-reloc; status = "okay"; }; diff --git a/arch/arm/dts/zynq-zc706.dts b/arch/arm/dts/zynq-zc706.dts index 1ba3a1c6e8d..1610520f7a7 100644 --- a/arch/arm/dts/zynq-zc706.dts +++ b/arch/arm/dts/zynq-zc706.dts @@ -306,6 +306,7 @@ }; &qspi { + u-boot,dm-pre-reloc; status = "okay"; }; diff --git a/arch/arm/dts/zynq-zed.dts b/arch/arm/dts/zynq-zed.dts index 5ec59e2b4c6..ec9b2f7b547 100644 --- a/arch/arm/dts/zynq-zed.dts +++ b/arch/arm/dts/zynq-zed.dts @@ -61,6 +61,7 @@ }; &qspi { + u-boot,dm-pre-reloc; status = "okay"; }; diff --git a/arch/arm/dts/zynq-zybo.dts b/arch/arm/dts/zynq-zybo.dts index fbbb8911910..d04e9625d29 100644 --- a/arch/arm/dts/zynq-zybo.dts +++ b/arch/arm/dts/zynq-zybo.dts @@ -31,8 +31,9 @@ }; usb_phy0: phy0 { - compatible = "usb-nop-xceiv"; #phy-cells = <0>; + compatible = "usb-nop-xceiv"; + reset-gpios = <&gpio0 46 1>; }; }; diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h index e223988b7d9..35964d603b3 100644 --- a/arch/arm/include/asm/arch-zynqmp/hardware.h +++ b/arch/arm/include/asm/arch-zynqmp/hardware.h @@ -13,9 +13,6 @@ #define ZYNQ_GEM_BASEADDR2 0xFF0D0000 #define ZYNQ_GEM_BASEADDR3 0xFF0E0000 -#define ZYNQ_SPI_BASEADDR0 0xFF040000 -#define ZYNQ_SPI_BASEADDR1 0xFF050000 - #define ZYNQ_I2C_BASEADDR0 0xFF020000 #define ZYNQ_I2C_BASEADDR1 0xFF030000 diff --git a/arch/arm/mach-zynq/include/mach/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h index 830e1fea180..79347a83eaf 100644 --- a/arch/arm/mach-zynq/include/mach/hardware.h +++ b/arch/arm/mach-zynq/include/mach/hardware.h @@ -14,8 +14,6 @@ #define ZYNQ_GEM_BASEADDR1 0xE000C000 #define ZYNQ_I2C_BASEADDR0 0xE0004000 #define ZYNQ_I2C_BASEADDR1 0xE0005000 -#define ZYNQ_SPI_BASEADDR0 0xE0006000 -#define ZYNQ_SPI_BASEADDR1 0xE0007000 #define ZYNQ_QSPI_BASEADDR 0xE000D000 #define ZYNQ_SMC_BASEADDR 0xE000E000 #define ZYNQ_NAND_BASEADDR 0xE1000000 diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 01bae5d67e3..2f17e977a4b 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -100,7 +100,6 @@ int checkboard(void) int dram_init(void) { -#if CONFIG_IS_ENABLED(OF_CONTROL) int node; fdt_addr_t addr; fdt_size_t size; @@ -118,9 +117,6 @@ int dram_init(void) return -1; } gd->ram_size = size; -#else - gd->ram_size = CONFIG_SYS_SDRAM_SIZE; -#endif zynq_ddrc_init(); return 0; diff --git a/cmd/i2c.c b/cmd/i2c.c index b3bb64408fe..18ce789d7ed 100644 --- a/cmd/i2c.c +++ b/cmd/i2c.c @@ -1141,7 +1141,7 @@ static void decode_bits (u_char const b, char const *str[], int const do_once) */ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { - enum { unknown, EDO, SDRAM, DDR2 } type; + enum { unknown, EDO, SDRAM, DDR, DDR2, DDR3, DDR4 } type; uint chip; u_char data[128]; @@ -1228,10 +1228,22 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) type = SDRAM; puts ("SDRAM\n"); break; + case 7: + type = DDR; + puts("DDR\n"); + break; case 8: type = DDR2; puts ("DDR2\n"); break; + case 11: + type = DDR3; + puts("DDR3\n"); + break; + case 12: + type = DDR4; + puts("DDR4\n"); + break; default: type = unknown; puts ("unknown\n"); diff --git a/configs/am437x_sk_evm_defconfig b/configs/am437x_sk_evm_defconfig index 9eb41f93222..3e916db972e 100644 --- a/configs/am437x_sk_evm_defconfig +++ b/configs/am437x_sk_evm_defconfig @@ -23,3 +23,4 @@ CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_TIMER=y CONFIG_OMAP_TIMER=y +CONFIG_DMA=y diff --git a/configs/xilinx_zynqmp_ep_defconfig b/configs/xilinx_zynqmp_ep_defconfig index 281191809ab..c2bbb47487f 100644 --- a/configs/xilinx_zynqmp_ep_defconfig +++ b/configs/xilinx_zynqmp_ep_defconfig @@ -25,5 +25,6 @@ CONFIG_CMD_TIME=y CONFIG_CMD_TIMER=y CONFIG_OF_EMBED=y CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_ZYNQ_SDHCI=y CONFIG_ZYNQ_GEM=y # CONFIG_REGEX is not set diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig index a3a66ec41a3..4c5152fa73e 100644 --- a/configs/zynq_microzed_defconfig +++ b/configs/zynq_microzed_defconfig @@ -13,6 +13,7 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_ZYNQ_SDHCI=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/zynq_picozed_defconfig b/configs/zynq_picozed_defconfig index fbc603fd95c..f34e2e3e265 100644 --- a/configs/zynq_picozed_defconfig +++ b/configs/zynq_picozed_defconfig @@ -10,4 +10,5 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_ZYNQ_SDHCI=y CONFIG_ZYNQ_GEM=y diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig index 3540653e227..f01874f23f9 100644 --- a/configs/zynq_zc702_defconfig +++ b/configs/zynq_zc702_defconfig @@ -12,6 +12,7 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_ZYNQ_SDHCI=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y diff --git a/configs/zynq_zc706_defconfig b/configs/zynq_zc706_defconfig index f333b7a2bfe..215f00dae9f 100644 --- a/configs/zynq_zc706_defconfig +++ b/configs/zynq_zc706_defconfig @@ -13,6 +13,7 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_ZYNQ_SDHCI=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig index ebfdeb098b5..cec722f38b3 100644 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@ -14,6 +14,7 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_ZYNQ_SDHCI=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig index 58680127aa5..4a2a2fc3ce4 100644 --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@ -13,6 +13,7 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_ZYNQ_SDHCI=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH_SPANSION=y diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig index ebaae49da1d..7c23feca423 100644 --- a/configs/zynq_zybo_defconfig +++ b/configs/zynq_zybo_defconfig @@ -13,6 +13,7 @@ CONFIG_CMD_GPIO=y # CONFIG_CMD_SETEXPR is not set CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_ZYNQ_SDHCI=y CONFIG_SPI_FLASH=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_ZYNQ_GEM=y diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index e69de29bb2d..1b92c7789d4 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -0,0 +1,22 @@ +menu "DMA Support" + +config DMA + bool "Enable Driver Model for DMA drivers" + depends on DM + help + Enable driver model for DMA. DMA engines can do + asynchronous data transfers without involving the host + CPU. Currently, this framework can be used to offload + memory copies to and from devices like qspi, ethernet + etc Drivers provide methods to access the DMA devices + buses that is used to transfer data to and from memory. + The uclass interface is defined in include/dma.h. + +config TI_EDMA3 + bool "TI EDMA3 driver" + help + Enable the TI EDMA3 driver for DRA7xx and AM43xx evms. + This driver support data transfer between memory + regions. + +endmenu # menu "DMA Support" diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index f95fe70a999..39b78b2a3d6 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -5,6 +5,8 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_DMA) += dma-uclass.o + obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o obj-$(CONFIG_APBH_DMA) += apbh_dma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c new file mode 100644 index 00000000000..ea21fd9c6fe --- /dev/null +++ b/drivers/dma/dma-uclass.c @@ -0,0 +1,72 @@ +/* + * Direct Memory Access U-Class driver + * + * (C) Copyright 2015 + * Texas Instruments Incorporated, <www.ti.com> + * + * Author: Mugunthan V N <mugunthanvnm@ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <dma.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <dm/device-internal.h> +#include <errno.h> + +DECLARE_GLOBAL_DATA_PTR; + +int dma_get_device(u32 transfer_type, struct udevice **devp) +{ + struct udevice *dev; + int ret; + + for (ret = uclass_first_device(UCLASS_DMA, &dev); dev && !ret; + ret = uclass_next_device(&dev)) { + struct dma_dev_priv *uc_priv; + + uc_priv = dev_get_uclass_priv(dev); + if (uc_priv->supported & transfer_type) + break; + } + + if (!dev) { + error("No DMA device found that supports %x type\n", + transfer_type); + return -EPROTONOSUPPORT; + } + + *devp = dev; + + return ret; +} + +int dma_memcpy(void *dst, void *src, size_t len) +{ + struct udevice *dev; + const struct dma_ops *ops; + int ret; + + ret = dma_get_device(DMA_SUPPORTS_MEM_TO_MEM, &dev); + if (ret < 0) + return ret; + + ops = device_get_ops(dev); + if (!ops->transfer) + return -ENOSYS; + + /* Invalidate the area, so no writeback into the RAM races with DMA */ + invalidate_dcache_range((unsigned long)dst, (unsigned long)dst + + roundup(len, ARCH_DMA_MINALIGN)); + + return ops->transfer(dev, DMA_MEM_TO_MEM, dst, src, len); +} + +UCLASS_DRIVER(dma) = { + .id = UCLASS_DMA, + .name = "dma", + .flags = DM_UC_FLAG_SEQ_ALIAS, + .per_device_auto_alloc_size = sizeof(struct dma_dev_priv), +}; diff --git a/drivers/dma/ti-edma3.c b/drivers/dma/ti-edma3.c index d6a427f2e21..247843891e2 100644 --- a/drivers/dma/ti-edma3.c +++ b/drivers/dma/ti-edma3.c @@ -11,6 +11,9 @@ #include <asm/io.h> #include <common.h> +#include <dma.h> +#include <dm/device.h> +#include <asm/omap_common.h> #include <asm/ti-common/ti-edma3.h> #define EDMA3_SL_BASE(slot) (0x4000 + ((slot) << 5)) @@ -31,6 +34,10 @@ #define EDMA3_QEESR 0x108c #define EDMA3_QSECR 0x1094 +struct ti_edma3_priv { + u32 base; +}; + /** * qedma3_start - start qdma on a channel * @base: base address of edma @@ -383,8 +390,8 @@ void qedma3_stop(u32 base, struct edma3_channel_config *cfg) __raw_writel(0, base + EDMA3_QCHMAP(cfg->chnum)); } -void edma3_transfer(unsigned long edma3_base_addr, unsigned int - edma_slot_num, void *dst, void *src, size_t len) +void __edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num, + void *dst, void *src, size_t len) { struct edma3_slot_config slot; struct edma3_channel_config edma_channel; @@ -460,3 +467,74 @@ void edma3_transfer(unsigned long edma3_base_addr, unsigned int qedma3_stop(edma3_base_addr, &edma_channel); } } + +#ifndef CONFIG_DMA + +void edma3_transfer(unsigned long edma3_base_addr, unsigned int edma_slot_num, + void *dst, void *src, size_t len) +{ + __edma3_transfer(edma3_base_addr, edma_slot_num, dst, src, len); +} + +#else + +static int ti_edma3_transfer(struct udevice *dev, int direction, void *dst, + void *src, size_t len) +{ + struct ti_edma3_priv *priv = dev_get_priv(dev); + + /* enable edma3 clocks */ + enable_edma3_clocks(); + + switch (direction) { + case DMA_MEM_TO_MEM: + __edma3_transfer(priv->base, 1, dst, src, len); + break; + default: + error("Transfer type not implemented in DMA driver\n"); + break; + } + + /* disable edma3 clocks */ + disable_edma3_clocks(); + + return 0; +} + +static int ti_edma3_ofdata_to_platdata(struct udevice *dev) +{ + struct ti_edma3_priv *priv = dev_get_priv(dev); + + priv->base = dev_get_addr(dev); + + return 0; +} + +static int ti_edma3_probe(struct udevice *dev) +{ + struct dma_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + uc_priv->supported = DMA_SUPPORTS_MEM_TO_MEM; + + return 0; +} + +static const struct dma_ops ti_edma3_ops = { + .transfer = ti_edma3_transfer, +}; + +static const struct udevice_id ti_edma3_ids[] = { + { .compatible = "ti,edma3" }, + { } +}; + +U_BOOT_DRIVER(ti_edma3) = { + .name = "ti_edma3", + .id = UCLASS_DMA, + .of_match = ti_edma3_ids, + .ops = &ti_edma3_ops, + .ofdata_to_platdata = ti_edma3_ofdata_to_platdata, + .probe = ti_edma3_probe, + .priv_auto_alloc_size = sizeof(struct ti_edma3_priv), +}; +#endif /* CONFIG_DMA */ diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 9f4b766f7a4..9d3f7e908fb 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -37,4 +37,10 @@ config PIC32_SDHCI help Support for Microchip PIC32 SDHCI controller. +config ZYNQ_SDHCI + bool "Arasan SDHCI controller support" + depends on DM_MMC && OF_CONTROL + help + Support for Arasan SDHCI host controller on Zynq/ZynqMP ARM SoCs platform + endmenu diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 8a60c72926d..3c365d5e9ad 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -16,6 +16,7 @@ #include <spi.h> #include <spi_flash.h> #include <linux/log2.h> +#include <dma.h> #include "sf_internal.h" @@ -454,8 +455,16 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, return ret; } +/* + * TODO: remove the weak after all the other spi_flash_copy_mmap + * implementations removed from drivers + */ void __weak spi_flash_copy_mmap(void *data, void *offset, size_t len) { +#ifdef CONFIG_DMA + if (!dma_memcpy(data, offset, len)) + return; +#endif memcpy(data, offset, len); } diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index bba48da4099..259a87fcc59 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -203,6 +203,14 @@ static int rtl8211x_startup(struct phy_device *phydev) return 0; } +static int rtl8211e_startup(struct phy_device *phydev) +{ + genphy_update_link(phydev); + genphy_parse_link(phydev); + + return 0; +} + static int rtl8211f_startup(struct phy_device *phydev) { /* Read the Status (2x to make sure link is right) */ @@ -230,7 +238,7 @@ static struct phy_driver RTL8211E_driver = { .mask = 0xffffff, .features = PHY_GBIT_FEATURES, .config = &rtl8211x_config, - .startup = &rtl8211x_startup, + .startup = &rtl8211e_startup, .shutdown = &genphy_shutdown, }; diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 93dad338b37..28da9ddfd85 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -105,7 +105,7 @@ static void ns16550_writeb(NS16550_t port, int offset, int value) * As far as we know it doesn't make sense to support selection of * these options at run-time, so use the existing CONFIG options. */ - serial_out_shift(addr, plat->reg_shift, value); + serial_out_shift(addr + plat->reg_offset, plat->reg_shift, value); } static int ns16550_readb(NS16550_t port, int offset) @@ -116,7 +116,7 @@ static int ns16550_readb(NS16550_t port, int offset) offset *= 1 << plat->reg_shift; addr = map_physmem(plat->base, 0, MAP_NOCACHE) + offset; - return serial_in_shift(addr, plat->reg_shift); + return serial_in_shift(addr + plat->reg_offset, plat->reg_shift); } /* We can clean these up once everything is moved to driver model */ @@ -401,6 +401,8 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev) return -EINVAL; plat->base = addr; + plat->reg_offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, + "reg-offset", 0); plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg-shift", 0); plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset, diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index e79d997cbab..66d54e32ab3 100644 --- a/drivers/serial/serial_zynq.c +++ b/drivers/serial/serial_zynq.c @@ -19,7 +19,7 @@ DECLARE_GLOBAL_DATA_PTR; -#define ZYNQ_UART_SR_TXFULL 0x00000010 /* TX FIFO full */ +#define ZYNQ_UART_SR_TXEMPTY (1 << 3) /* TX FIFO empty */ #define ZYNQ_UART_SR_TXACTIVE (1 << 11) /* TX active */ #define ZYNQ_UART_SR_RXEMPTY 0x00000002 /* RX FIFO empty */ @@ -97,7 +97,7 @@ static void _uart_zynq_serial_init(struct uart_zynq *regs) static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c) { - if (readl(®s->channel_sts) & ZYNQ_UART_SR_TXFULL) + if (!(readl(®s->channel_sts) & ZYNQ_UART_SR_TXEMPTY)) return -EAGAIN; writel(c, ®s->tx_rx_fifo); diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c index 85f9e85fd4b..95cdfa36ef1 100644 --- a/drivers/spi/omap3_spi.c +++ b/drivers/spi/omap3_spi.c @@ -336,7 +336,6 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, struct omap3_spi_slave *ds = to_omap3_spi(slave); ulong start; int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf); - int irqstatus = readl(&ds->regs->irqstatus); int i=0; /*Enable SPI channel*/ @@ -351,7 +350,6 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len, /*Shift in and out 1 byte at time*/ for (i=0; i < len; i++){ /* Write: wait for TX empty (TXS == 1)*/ - irqstatus |= (1<< (4*(ds->slave.bus))); start = get_timer(0); while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) & OMAP3_MCSPI_CHSTAT_TXS)) { diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index 677c020b110..5561f36762f 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -158,6 +158,7 @@ static int spi_child_pre_probe(struct udevice *dev) slave->max_hz = plat->max_hz; slave->mode = plat->mode; slave->mode_rx = plat->mode_rx; + slave->wordlen = SPI_DEFAULT_WORDLEN; return 0; } diff --git a/drivers/spi/ti_qspi.c b/drivers/spi/ti_qspi.c index b5c974ce383..409a5c41ab9 100644 --- a/drivers/spi/ti_qspi.c +++ b/drivers/spi/ti_qspi.c @@ -277,7 +277,7 @@ static int __ti_qspi_xfer(struct ti_qspi_priv *priv, unsigned int bitlen, } /* TODO: control from sf layer to here through dm-spi */ -#ifdef CONFIG_TI_EDMA3 +#if defined(CONFIG_TI_EDMA3) && !defined(CONFIG_DMA) void spi_flash_copy_mmap(void *data, void *offset, size_t len) { unsigned int addr = (unsigned int) (data); diff --git a/drivers/video/Makefile b/drivers/video/Makefile index d19a1d9042b..9b635fc4037 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -52,6 +52,7 @@ obj-$(CONFIG_VIDEO_IPUV3) += mxc_ipuv3_fb.o ipu_common.o ipu_disp.o obj-$(CONFIG_VIDEO_MVEBU) += mvebu_lcd.o obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o obj-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o +obj-$(CONFIG_VIDEO_S3C) += s3c-fb.o videomodes.o obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o obj-$(CONFIG_VIDEO_SED13806) += sed13806.o obj-$(CONFIG_VIDEO_SM501) += sm501.o diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index f15c9645464..ef4984becb4 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -117,7 +117,7 @@ #define VIDEO_HW_BITBLT #endif -#ifdef CONFIG_VIDEO_MXS +#if defined(CONFIG_VIDEO_MXS) || defined(CONFIG_VIDEO_S3C) #define VIDEO_FB_16BPP_WORD_SWAP #endif diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index c249f047f5b..e16f95a02ce 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -289,6 +289,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, } #endif default: + free(data); return -ENOSYS; } diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c new file mode 100644 index 00000000000..521eb75a823 --- /dev/null +++ b/drivers/video/s3c-fb.c @@ -0,0 +1,172 @@ +/* + * S3C24x0 LCD driver + * + * NOTE: Only 16/24 bpp operation with TFT LCD is supported. + * + * Copyright (C) 2014 Marek Vasut <marex@denx.de> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <malloc.h> +#include <video_fb.h> + +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/s3c24x0_cpu.h> + +#include "videomodes.h" + +static GraphicDevice panel; + +/* S3C requires the FB to be 4MiB aligned. */ +#define S3CFB_ALIGN (4 << 20) + +#define S3CFB_LCDCON1_CLKVAL(x) ((x) << 8) +#define S3CFB_LCDCON1_PNRMODE_TFT (0x3 << 5) +#define S3CFB_LCDCON1_BPPMODE_TFT_16BPP (0xc << 1) +#define S3CFB_LCDCON1_BPPMODE_TFT_24BPP (0xd << 1) + +#define S3CFB_LCDCON2_VBPD(x) ((x) << 24) +#define S3CFB_LCDCON2_LINEVAL(x) ((x) << 14) +#define S3CFB_LCDCON2_VFPD(x) ((x) << 6) +#define S3CFB_LCDCON2_VSPW(x) ((x) << 0) + +#define S3CFB_LCDCON3_HBPD(x) ((x) << 19) +#define S3CFB_LCDCON3_HOZVAL(x) ((x) << 8) +#define S3CFB_LCDCON3_HFPD(x) ((x) << 0) + +#define S3CFB_LCDCON4_HSPW(x) ((x) << 0) + +#define S3CFB_LCDCON5_BPP24BL (1 << 12) +#define S3CFB_LCDCON5_FRM565 (1 << 11) +#define S3CFB_LCDCON5_HWSWP (1 << 0) + +#define PS2KHZ(ps) (1000000000UL / (ps)) + +/* + * Example: + * setenv videomode video=ctfb:x:800,y:480,depth:16,mode:0,\ + * pclk:30066,le:41,ri:89,up:45,lo:12, + * hs:1,vs:1,sync:100663296,vmode:0 + */ +static void s3c_lcd_init(GraphicDevice *panel, + struct ctfb_res_modes *mode, int bpp) +{ + uint32_t clk_divider; + struct s3c24x0_lcd *regs = s3c24x0_get_base_lcd(); + + /* Stop the controller. */ + clrbits_le32(®s->lcdcon1, 1); + + /* Calculate clock divider. */ + clk_divider = (get_HCLK() / PS2KHZ(mode->pixclock)) / 1000; + clk_divider = DIV_ROUND_UP(clk_divider, 2); + if (clk_divider) + clk_divider -= 1; + + /* Program LCD configuration. */ + switch (bpp) { + case 16: + writel(S3CFB_LCDCON1_BPPMODE_TFT_16BPP | + S3CFB_LCDCON1_PNRMODE_TFT | + S3CFB_LCDCON1_CLKVAL(clk_divider), + ®s->lcdcon1); + writel(S3CFB_LCDCON5_HWSWP | S3CFB_LCDCON5_FRM565, + ®s->lcdcon5); + break; + case 24: + writel(S3CFB_LCDCON1_BPPMODE_TFT_24BPP | + S3CFB_LCDCON1_PNRMODE_TFT | + S3CFB_LCDCON1_CLKVAL(clk_divider), + ®s->lcdcon1); + writel(S3CFB_LCDCON5_BPP24BL, ®s->lcdcon5); + break; + } + + writel(S3CFB_LCDCON2_LINEVAL(mode->yres - 1) | + S3CFB_LCDCON2_VBPD(mode->upper_margin - 1) | + S3CFB_LCDCON2_VFPD(mode->lower_margin - 1) | + S3CFB_LCDCON2_VSPW(mode->vsync_len - 1), + ®s->lcdcon2); + + writel(S3CFB_LCDCON3_HBPD(mode->right_margin - 1) | + S3CFB_LCDCON3_HFPD(mode->left_margin - 1) | + S3CFB_LCDCON3_HOZVAL(mode->xres - 1), + ®s->lcdcon3); + + writel(S3CFB_LCDCON4_HSPW(mode->hsync_len - 1), + ®s->lcdcon4); + + /* Write FB address. */ + writel(panel->frameAdrs >> 1, ®s->lcdsaddr1); + writel((panel->frameAdrs + + (mode->xres * mode->yres * panel->gdfBytesPP)) >> 1, + ®s->lcdsaddr2); + writel(mode->xres * bpp / 16, ®s->lcdsaddr3); + + /* Start the controller. */ + setbits_le32(®s->lcdcon1, 1); +} + +void *video_hw_init(void) +{ + int bpp = -1; + char *penv; + void *fb; + struct ctfb_res_modes mode; + + puts("Video: "); + + /* Suck display configuration from "videomode" variable */ + penv = getenv("videomode"); + if (!penv) { + puts("S3CFB: 'videomode' variable not set!\n"); + return NULL; + } + + bpp = video_get_params(&mode, penv); + + /* fill in Graphic device struct */ + sprintf(panel.modeIdent, "%dx%dx%d", mode.xres, mode.yres, bpp); + + panel.winSizeX = mode.xres; + panel.winSizeY = mode.yres; + panel.plnSizeX = mode.xres; + panel.plnSizeY = mode.yres; + + switch (bpp) { + case 24: + panel.gdfBytesPP = 4; + panel.gdfIndex = GDF_32BIT_X888RGB; + break; + case 16: + panel.gdfBytesPP = 2; + panel.gdfIndex = GDF_16BIT_565RGB; + break; + default: + printf("S3CFB: Invalid BPP specified! (bpp = %i)\n", bpp); + return NULL; + } + + panel.memSize = mode.xres * mode.yres * panel.gdfBytesPP; + + /* Allocate framebuffer */ + fb = memalign(S3CFB_ALIGN, roundup(panel.memSize, S3CFB_ALIGN)); + if (!fb) { + printf("S3CFB: Error allocating framebuffer!\n"); + return NULL; + } + + /* Wipe framebuffer */ + memset(fb, 0, panel.memSize); + + panel.frameAdrs = (u32)fb; + + printf("%s\n", panel.modeIdent); + + /* Start framebuffer */ + s3c_lcd_init(&panel, &mode, bpp); + + return (void *)&panel; +} diff --git a/drivers/video/stb_truetype.h b/drivers/video/stb_truetype.h index 91d8e6f905c..26e483cf566 100644 --- a/drivers/video/stb_truetype.h +++ b/drivers/video/stb_truetype.h @@ -2426,7 +2426,10 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info if (scale_x == 0) scale_x = scale_y; if (scale_y == 0) { - if (scale_x == 0) return NULL; + if (scale_x == 0) { + STBTT_free(vertices, info->userdata); + return NULL; + } scale_y = scale_x; } diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index 28622dec188..da868b82371 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -89,18 +89,14 @@ # define CONFIG_CMD_SF #endif -#if defined(CONFIG_ZYNQ_SDHCI0) || defined(CONFIG_ZYNQ_SDHCI1) +#if defined(CONFIG_ZYNQ_SDHCI) # define CONFIG_MMC # define CONFIG_GENERIC_MMC # define CONFIG_SDHCI -# define CONFIG_ZYNQ_SDHCI # define CONFIG_CMD_MMC # ifndef CONFIG_ZYNQ_SDHCI_MAX_FREQ # define CONFIG_ZYNQ_SDHCI_MAX_FREQ 200000000 # endif -#endif - -#if defined(CONFIG_ZYNQ_SDHCI) # define CONFIG_FAT_WRITE # define CONFIG_CMD_EXT4_WRITE #endif diff --git a/include/configs/xilinx_zynqmp_ep.h b/include/configs/xilinx_zynqmp_ep.h index 9906c426f50..337312e58c0 100644 --- a/include/configs/xilinx_zynqmp_ep.h +++ b/include/configs/xilinx_zynqmp_ep.h @@ -13,7 +13,6 @@ #ifndef __CONFIG_ZYNQMP_EP_H #define __CONFIG_ZYNQMP_EP_H -#define CONFIG_ZYNQ_SDHCI0 #define CONFIG_ZYNQ_SDHCI_MAX_FREQ 52000000 #define CONFIG_ZYNQ_SDHCI_MIN_FREQ (CONFIG_ZYNQ_SDHCI_MAX_FREQ << 9) #define CONFIG_ZYNQ_I2C0 diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index e8c3ef0c387..4a81d41d0f8 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -50,6 +50,7 @@ # define CONFIG_MII # define CONFIG_SYS_FAULT_ECHO_LINK_DOWN # define CONFIG_PHY_MARVELL +# define CONFIG_PHY_REALTEK # define CONFIG_BOOTP_SERVERIP # define CONFIG_BOOTP_BOOTPATH # define CONFIG_BOOTP_GATEWAY @@ -86,11 +87,10 @@ #endif /* MMC */ -#if defined(CONFIG_ZYNQ_SDHCI0) || defined(CONFIG_ZYNQ_SDHCI1) +#if defined(CONFIG_ZYNQ_SDHCI) # define CONFIG_MMC # define CONFIG_GENERIC_MMC # define CONFIG_SDHCI -# define CONFIG_ZYNQ_SDHCI # define CONFIG_CMD_MMC # define CONFIG_ZYNQ_SDHCI_MAX_FREQ 52000000 #endif @@ -131,7 +131,7 @@ "dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \ "thor_ram=run dfu_ram_info && thordown 0 ram 0\0" -# if defined(CONFIG_ZYNQ_SDHCI0) || defined(CONFIG_ZYNQ_SDHCI1) +# if defined(CONFIG_ZYNQ_SDHCI) # define CONFIG_DFU_MMC # define DFU_ALT_INFO_MMC \ "dfu_mmc_info=" \ @@ -197,7 +197,11 @@ /* Environment */ #ifndef CONFIG_ENV_IS_NOWHERE # ifndef CONFIG_SYS_NO_FLASH +/* Environment in NOR flash */ # define CONFIG_ENV_IS_IN_FLASH +# elif defined(CONFIG_ZYNQ_QSPI) +/* Environment in Serial Flash */ +# define CONFIG_ENV_IS_IN_SPI_FLASH # elif defined(CONFIG_SYS_NO_FLASH) # define CONFIG_ENV_IS_NOWHERE # endif @@ -227,8 +231,7 @@ "usbboot=if usb start; then " \ "echo Copying FIT from USB to RAM... && " \ "load usb 0 ${load_addr} ${fit_image} && " \ - "bootm ${load_addr}\0" \ - "fi\0" \ + "bootm ${load_addr}; fi\0" \ DFU_ALT_INFO #define CONFIG_BOOTCOMMAND "run $modeboot" @@ -288,9 +291,7 @@ #define CONFIG_SYS_BOOTM_LEN (60 * 1024 * 1024) /* Boot FreeBSD/vxWorks from an ELF image */ -#if defined(CONFIG_ZYNQ_BOOT_FREEBSD) -# define CONFIG_SYS_MMC_MAX_DEVICE 1 -#endif +#define CONFIG_SYS_MMC_MAX_DEVICE 1 #define CONFIG_SYS_LDSCRIPT "arch/arm/mach-zynq/u-boot.lds" @@ -307,11 +308,12 @@ #define CONFIG_SPL_LIBGENERIC_SUPPORT #define CONFIG_SPL_SERIAL_SUPPORT #define CONFIG_SPL_BOARD_INIT +#define CONFIG_SPL_RAM_DEVICE #define CONFIG_SPL_LDSCRIPT "arch/arm/mach-zynq/u-boot-spl.lds" /* MMC support */ -#ifdef CONFIG_ZYNQ_SDHCI0 +#ifdef CONFIG_ZYNQ_SDHCI #define CONFIG_SPL_MMC_SUPPORT #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 /* address 0x60000 */ #define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x200 /* 256 KB */ diff --git a/include/configs/zynq_microzed.h b/include/configs/zynq_microzed.h index 169ee36d3f5..e66088da4f7 100644 --- a/include/configs/zynq_microzed.h +++ b/include/configs/zynq_microzed.h @@ -10,12 +10,8 @@ #ifndef __CONFIG_ZYNQ_MICROZED_H #define __CONFIG_ZYNQ_MICROZED_H -#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024) - #define CONFIG_SYS_NO_FLASH -#define CONFIG_ZYNQ_SDHCI0 - #include <configs/zynq-common.h> #endif /* __CONFIG_ZYNQ_MICROZED_H */ diff --git a/include/configs/zynq_picozed.h b/include/configs/zynq_picozed.h index 47fad66acdd..adc4d0f11e6 100644 --- a/include/configs/zynq_picozed.h +++ b/include/configs/zynq_picozed.h @@ -10,13 +10,9 @@ #ifndef __CONFIG_ZYNQ_PICOZED_H #define __CONFIG_ZYNQ_PICOZED_H -#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024) - #define CONFIG_SYS_NO_FLASH -#define CONFIG_ZYNQ_SDHCI1 #define CONFIG_ZYNQ_USB -#define CONFIG_ZYNQ_BOOT_FREEBSD #include <configs/zynq-common.h> diff --git a/include/configs/zynq_zc70x.h b/include/configs/zynq_zc70x.h index c52a6552e78..8a045900f62 100644 --- a/include/configs/zynq_zc70x.h +++ b/include/configs/zynq_zc70x.h @@ -10,15 +10,11 @@ #ifndef __CONFIG_ZYNQ_ZC70X_H #define __CONFIG_ZYNQ_ZC70X_H -#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024) - #define CONFIG_SYS_NO_FLASH -#define CONFIG_ZYNQ_SDHCI0 #define CONFIG_ZYNQ_USB #define CONFIG_ZYNQ_I2C0 #define CONFIG_ZYNQ_EEPROM -#define CONFIG_ZYNQ_BOOT_FREEBSD #include <configs/zynq-common.h> diff --git a/include/configs/zynq_zc770.h b/include/configs/zynq_zc770.h index 32ea1f37d6a..35622ae3464 100644 --- a/include/configs/zynq_zc770.h +++ b/include/configs/zynq_zc770.h @@ -10,20 +10,11 @@ #ifndef __CONFIG_ZYNQ_ZC770_H #define __CONFIG_ZYNQ_ZC770_H -#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024) - #define CONFIG_SYS_NO_FLASH -#if defined(CONFIG_ZC770_XM010) -# define CONFIG_ZYNQ_SDHCI0 - -#elif defined(CONFIG_ZC770_XM011) - -#elif defined(CONFIG_ZC770_XM012) +#if defined(CONFIG_ZC770_XM012) # undef CONFIG_SYS_NO_FLASH -#elif defined(CONFIG_ZC770_XM013) - #endif #include <configs/zynq-common.h> diff --git a/include/configs/zynq_zed.h b/include/configs/zynq_zed.h index 1488bfe165d..150cb4a0df9 100644 --- a/include/configs/zynq_zed.h +++ b/include/configs/zynq_zed.h @@ -10,13 +10,9 @@ #ifndef __CONFIG_ZYNQ_ZED_H #define __CONFIG_ZYNQ_ZED_H -#define CONFIG_SYS_SDRAM_SIZE (512 * 1024 * 1024) - #define CONFIG_SYS_NO_FLASH #define CONFIG_ZYNQ_USB -#define CONFIG_ZYNQ_SDHCI0 -#define CONFIG_ZYNQ_BOOT_FREEBSD #include <configs/zynq-common.h> diff --git a/include/configs/zynq_zybo.h b/include/configs/zynq_zybo.h index c53ba79d48b..0882fe36bd8 100644 --- a/include/configs/zynq_zybo.h +++ b/include/configs/zynq_zybo.h @@ -11,13 +11,14 @@ #ifndef __CONFIG_ZYNQ_ZYBO_H #define __CONFIG_ZYNQ_ZYBO_H -#define CONFIG_SYS_SDRAM_SIZE (512 * 1024 * 1024) - #define CONFIG_SYS_NO_FLASH #define CONFIG_ZYNQ_USB -#define CONFIG_ZYNQ_SDHCI0 -#define CONFIG_ZYNQ_BOOT_FREEBSD +#define CONFIG_ZYNQ_I2C0 +#define CONFIG_ZYNQ_I2C1 +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1 +#define CONFIG_DISPLAY +#define CONFIG_I2C_EDID /* Define ZYBO PS Clock Frequency to 50MHz */ #define CONFIG_ZYNQ_PS_CLK_FREQ 50000000UL diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 73cd3ac94c1..3bea30807db 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -31,6 +31,7 @@ enum uclass_id { UCLASS_CROS_EC, /* Chrome OS EC */ UCLASS_DISK, /* Disk controller, e.g. SATA */ UCLASS_DISPLAY, /* Display (e.g. DisplayPort, HDMI) */ + UCLASS_DMA, /* Direct Memory Access */ UCLASS_RAM, /* RAM controller */ UCLASS_ETH, /* Ethernet device */ UCLASS_GPIO, /* Bank of general-purpose I/O pins */ diff --git a/include/dma.h b/include/dma.h new file mode 100644 index 00000000000..71fa77f2ea8 --- /dev/null +++ b/include/dma.h @@ -0,0 +1,86 @@ +/* + * (C) Copyright 2015 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _DMA_H_ +#define _DMA_H_ + +/* + * enum dma_direction - dma transfer direction indicator + * @DMA_MEM_TO_MEM: Memcpy mode + * @DMA_MEM_TO_DEV: From Memory to Device + * @DMA_DEV_TO_MEM: From Device to Memory + * @DMA_DEV_TO_DEV: From Device to Device + */ +enum dma_direction { + DMA_MEM_TO_MEM, + DMA_MEM_TO_DEV, + DMA_DEV_TO_MEM, + DMA_DEV_TO_DEV, +}; + +#define DMA_SUPPORTS_MEM_TO_MEM BIT(0) +#define DMA_SUPPORTS_MEM_TO_DEV BIT(1) +#define DMA_SUPPORTS_DEV_TO_MEM BIT(2) +#define DMA_SUPPORTS_DEV_TO_DEV BIT(3) + +/* + * struct dma_ops - Driver model DMA operations + * + * The uclass interface is implemented by all DMA devices which use + * driver model. + */ +struct dma_ops { + /* + * Get the current timer count + * + * @dev: The DMA device + * @direction: direction of data transfer should be one from + enum dma_direction + * @dst: Destination pointer + * @src: Source pointer + * @len: Length of the data to be copied. + * @return: 0 if OK, -ve on error + */ + int (*transfer)(struct udevice *dev, int direction, void *dst, + void *src, size_t len); +}; + +/* + * struct dma_dev_priv - information about a device used by the uclass + * + * @supported: mode of transfers that DMA can support, should be + * one/multiple of DMA_SUPPORTS_* + */ +struct dma_dev_priv { + u32 supported; +}; + +/* + * dma_get_device - get a DMA device which supports transfer + * type of transfer_type + * + * @transfer_type - transfer type should be one/multiple of + * DMA_SUPPORTS_* + * @devp - udevice pointer to return the found device + * @return - will return on success and devp will hold the + * pointer to the device + */ +int dma_get_device(u32 transfer_type, struct udevice **devp); + +/* + * dma_memcpy - try to use DMA to do a mem copy which will be + * much faster than CPU mem copy + * + * @dst - destination pointer + * @src - souce pointer + * @len - data length to be copied + * @return - on successful transfer returns no of bytes + transferred and on failure return error code. + */ +int dma_memcpy(void *dst, void *src, size_t len); + +#endif /* _DMA_H_ */ diff --git a/include/ns16550.h b/include/ns16550.h index 4e620676c45..5eeacd6ff94 100644 --- a/include/ns16550.h +++ b/include/ns16550.h @@ -54,6 +54,7 @@ */ struct ns16550_platdata { unsigned long base; + int reg_offset; int reg_shift; int clock; }; |