diff options
Diffstat (limited to 'drivers')
147 files changed, 2666 insertions, 5337 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 049f7efd10..9bc5283c26 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -20,14 +20,6 @@ config SATA See also CMD_SATA which provides command-line support. -config SYS_SATA_MAX_PORTS - int "Maximum supported SATA ports" - depends on SCSI_AHCI && !DM_SCSI - default 1 - help - Sets the maximum number of ports to scan when looking for devices. - Ports from 0 to (this value - 1) are scanned. - config LIBATA bool help @@ -44,7 +36,7 @@ menu "SATA/SCSI device support" config AHCI_PCI bool "Support for PCI-based AHCI controller" depends on PCI - depends on DM_SCSI + depends on SCSI depends on SCSI_AHCI help Enables support for the PCI-based AHCI controller. @@ -55,13 +47,13 @@ config SPL_AHCI_PCI bool "Support for PCI-based AHCI controller for SPL" depends on SPL depends on SPL_PCI - depends on SPL_SATA && DM_SCSI + depends on SPL_SATA && SCSI config DWC_AHCI bool "Enable Synopsys DWC AHCI driver support" select SCSI_AHCI select PHY - depends on DM_SCSI + depends on SCSI help Enable this driver to support Sata devices through Synopsys DWC AHCI module. @@ -91,7 +83,7 @@ config AHCI_MVEBU bool "Marvell EBU AHCI SATA support" depends on ARCH_MVEBU || ARCH_OCTEON select SCSI_AHCI - select DM_SCSI + select SCSI help This option enables support for the Marvell EBU SoC's onboard AHCI SATA. @@ -112,7 +104,7 @@ if SATA config SATA_CEVA bool "Ceva Sata controller" depends on AHCI - depends on DM_SCSI + depends on SCSI help This option enables Ceva Sata controller hard IP available on Xilinx ZynqMP. Support up to 2 external devices. Compliant with SATA 3.1 and diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index 0b6f91098a..af6f0bf278 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_SATA) += sata.o sata_bootdev.o obj-$(CONFIG_SATA_CEVA) += sata_ceva.o obj-$(CONFIG_SATA_MV) += sata_mv.o obj-$(CONFIG_SATA_SIL) += sata_sil.o -obj-$(CONFIG_SANDBOX) += sata_sandbox.o obj-$(CONFIG_AHCI_MVEBU) += ahci_mvebu.o obj-$(CONFIG_SUNXI_AHCI) += ahci_sunxi.o obj-$(CONFIG_MTK_AHCI) += mtk_ahci.o diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index cb2c648a91..04ddc33946 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -33,10 +33,6 @@ static int ata_io_flush(struct ahci_uc_priv *uc_priv, u8 port); -#ifndef CONFIG_DM_SCSI -struct ahci_uc_priv *probe_ent = NULL; -#endif - #define writel_with_flush(a,b) do { writel(a,b); readl(b); } while (0) /* @@ -169,11 +165,6 @@ int ahci_reset(void __iomem *base) static int ahci_host_init(struct ahci_uc_priv *uc_priv) { -#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI) - struct udevice *dev = uc_priv->dev; - struct pci_child_plat *pplat = dev_get_parent_plat(dev); - u16 tmp16; -#endif void __iomem *mmio = uc_priv->mmio_base; u32 tmp, cap_save, cmd; int i, j, ret; @@ -194,14 +185,6 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) writel(cap_save, mmio + HOST_CAP); writel_with_flush(0xf, mmio + HOST_PORTS_IMPL); -#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI) - if (pplat->vendor == PCI_VENDOR_ID_INTEL) { - u16 tmp16; - - dm_pci_read_config16(dev, 0x92, &tmp16); - dm_pci_write_config16(dev, 0x92, tmp16 | 0xf); - } -#endif uc_priv->cap = readl(mmio + HOST_CAP); uc_priv->port_map = readl(mmio + HOST_PORTS_IMPL); port_map = uc_priv->port_map; @@ -210,11 +193,6 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) debug("cap 0x%x port_map 0x%x n_ports %d\n", uc_priv->cap, uc_priv->port_map, uc_priv->n_ports); -#if !defined(CONFIG_DM_SCSI) - if (uc_priv->n_ports > CONFIG_SYS_SATA_MAX_PORTS) - uc_priv->n_ports = CONFIG_SYS_SATA_MAX_PORTS; -#endif - for (i = 0; i < uc_priv->n_ports; i++) { if (!(port_map & (1 << i))) continue; @@ -313,23 +291,12 @@ static int ahci_host_init(struct ahci_uc_priv *uc_priv) writel(tmp | HOST_IRQ_EN, mmio + HOST_CTL); tmp = readl(mmio + HOST_CTL); debug("HOST_CTL 0x%x\n", tmp); -#if !defined(CONFIG_DM_SCSI) -#ifndef CONFIG_SCSI_AHCI_PLAT - dm_pci_read_config16(dev, PCI_COMMAND, &tmp16); - tmp |= PCI_COMMAND_MASTER; - dm_pci_write_config16(dev, PCI_COMMAND, tmp16); -#endif -#endif return 0; } static void ahci_print_info(struct ahci_uc_priv *uc_priv) { -#if !defined(CONFIG_SCSI_AHCI_PLAT) && !defined(CONFIG_DM_SCSI) - struct udevice *dev = uc_priv->dev; - u16 cc; -#endif void __iomem *mmio = uc_priv->mmio_base; u32 vers, cap, cap2, impl, speed; const char *speed_s; @@ -350,19 +317,7 @@ static void ahci_print_info(struct ahci_uc_priv *uc_priv) else speed_s = "?"; -#if defined(CONFIG_SCSI_AHCI_PLAT) || defined(CONFIG_DM_SCSI) scc_s = "SATA"; -#else - dm_pci_read_config16(dev, 0x0a, &cc); - if (cc == 0x0101) - scc_s = "IDE"; - else if (cc == 0x0106) - scc_s = "SATA"; - else if (cc == 0x0104) - scc_s = "RAID"; - else - scc_s = "unknown"; -#endif printf("AHCI %02x%02x.%02x%02x " "%u slots %u ports %s Gbps 0x%x impl %s mode\n", (vers >> 24) & 0xff, @@ -397,12 +352,8 @@ static void ahci_print_info(struct ahci_uc_priv *uc_priv) cap2 & (1 << 0) ? "boh " : ""); } -#if defined(CONFIG_DM_SCSI) || !defined(CONFIG_SCSI_AHCI_PLAT) static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev) { -#if !defined(CONFIG_DM_SCSI) - u16 vendor; -#endif int rc; uc_priv->dev = dev; @@ -415,21 +366,8 @@ static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev) uc_priv->pio_mask = 0x1f; uc_priv->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */ -#if !defined(CONFIG_DM_SCSI) - uc_priv->mmio_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_5, 0, 0, - PCI_REGION_TYPE, PCI_REGION_MEM); - - /* Take from kernel: - * JMicron-specific fixup: - * make sure we're in AHCI mode - */ - dm_pci_read_config16(dev, PCI_VENDOR_ID, &vendor); - if (vendor == 0x197b) - dm_pci_write_config8(dev, 0x41, 0xa1); -#else struct scsi_plat *plat = dev_get_uclass_plat(dev); uc_priv->mmio_base = (void *)plat->base; -#endif debug("ahci mmio_base=0x%p\n", uc_priv->mmio_base); /* initialize adapter */ @@ -444,7 +382,6 @@ static int ahci_init_one(struct ahci_uc_priv *uc_priv, struct udevice *dev) err_out: return rc; } -#endif #define MAX_DATA_BYTE_COUNT (4*1024*1024) @@ -893,12 +830,7 @@ static int ata_scsiop_test_unit_ready(struct ahci_uc_priv *uc_priv, static int ahci_scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) { - struct ahci_uc_priv *uc_priv; -#ifdef CONFIG_DM_SCSI - uc_priv = dev_get_uclass_priv(dev->parent); -#else - uc_priv = probe_ent; -#endif + struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev->parent); int ret; switch (pccb->cmd[0]) { @@ -953,41 +885,12 @@ static int ahci_start_ports(struct ahci_uc_priv *uc_priv) return 0; } -#ifndef CONFIG_DM_SCSI -void scsi_low_level_init(int busdevfunc) -{ - struct ahci_uc_priv *uc_priv; - -#ifndef CONFIG_SCSI_AHCI_PLAT - probe_ent = calloc(1, sizeof(struct ahci_uc_priv)); - if (!probe_ent) { - printf("%s: No memory for uc_priv\n", __func__); - return; - } - uc_priv = probe_ent; - struct udevice *dev; - int ret; - - ret = dm_pci_bus_find_bdf(busdevfunc, &dev); - if (ret) - return; - ahci_init_one(uc_priv, dev); -#else - uc_priv = probe_ent; -#endif - - ahci_start_ports(uc_priv); -} -#endif - -#ifndef CONFIG_SCSI_AHCI_PLAT int ahci_init_one_dm(struct udevice *dev) { struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); return ahci_init_one(uc_priv, dev); } -#endif int ahci_start_ports_dm(struct udevice *dev) { @@ -996,65 +899,6 @@ int ahci_start_ports_dm(struct udevice *dev) return ahci_start_ports(uc_priv); } -#ifdef CONFIG_SCSI_AHCI_PLAT -static int ahci_init_common(struct ahci_uc_priv *uc_priv, void __iomem *base) -{ - int rc; - - uc_priv->host_flags = ATA_FLAG_SATA - | ATA_FLAG_NO_LEGACY - | ATA_FLAG_MMIO - | ATA_FLAG_PIO_DMA - | ATA_FLAG_NO_ATAPI; - uc_priv->pio_mask = 0x1f; - uc_priv->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */ - - uc_priv->mmio_base = base; - - /* initialize adapter */ - rc = ahci_host_init(uc_priv); - if (rc) - goto err_out; - - ahci_print_info(uc_priv); - - rc = ahci_start_ports(uc_priv); - -err_out: - return rc; -} - -#ifndef CONFIG_DM_SCSI -int ahci_init(void __iomem *base) -{ - struct ahci_uc_priv *uc_priv; - - probe_ent = malloc(sizeof(struct ahci_uc_priv)); - if (!probe_ent) { - printf("%s: No memory for uc_priv\n", __func__); - return -ENOMEM; - } - - uc_priv = probe_ent; - memset(uc_priv, 0, sizeof(struct ahci_uc_priv)); - - return ahci_init_common(uc_priv, base); -} -#endif - -int ahci_init_dm(struct udevice *dev, void __iomem *base) -{ - struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); - - return ahci_init_common(uc_priv, base); -} - -void __weak scsi_init(void) -{ -} - -#endif /* CONFIG_SCSI_AHCI_PLAT */ - /* * In the general case of generic rotating media it makes sense to have a * flush capability. It probably even makes sense in the case of SSDs because @@ -1098,7 +942,6 @@ static int ahci_scsi_bus_reset(struct udevice *dev) return 0; } -#ifdef CONFIG_DM_SCSI int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp) { struct udevice *dev; @@ -1190,16 +1033,3 @@ U_BOOT_DRIVER(ahci_scsi) = { .id = UCLASS_SCSI, .ops = &scsi_ops, }; -#else -int scsi_exec(struct udevice *dev, struct scsi_cmd *pccb) -{ - return ahci_scsi_exec(dev, pccb); -} - -__weak int scsi_bus_reset(struct udevice *dev) -{ - return ahci_scsi_bus_reset(dev); - - return 0; -} -#endif diff --git a/drivers/ata/sata.c b/drivers/ata/sata.c index 64fc078bad..784d9bbeac 100644 --- a/drivers/ata/sata.c +++ b/drivers/ata/sata.c @@ -18,10 +18,6 @@ #include <dm/device-internal.h> #include <dm/uclass-internal.h> -#ifndef CONFIG_AHCI -struct blk_desc sata_dev_desc[CONFIG_SYS_SATA_MAX_DEVICE]; -#endif - int sata_reset(struct udevice *dev) { struct ahci_ops *ops = ahci_get_ops(dev); @@ -88,15 +84,6 @@ int sata_rescan(bool verbose) return ret; } -#ifndef CONFIG_AHCI -#ifdef CONFIG_PARTITIONS -struct blk_desc *sata_get_dev(int dev) -{ - return (dev < CONFIG_SYS_SATA_MAX_DEVICE) ? &sata_dev_desc[dev] : NULL; -} -#endif -#endif - static unsigned long sata_bread(struct udevice *dev, lbaint_t start, lbaint_t blkcnt, void *dst) { @@ -109,51 +96,6 @@ static unsigned long sata_bwrite(struct udevice *dev, lbaint_t start, return -ENOSYS; } -#ifndef CONFIG_AHCI -int __sata_initialize(void) -{ - int rc, ret = -1; - int i; - - for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) { - memset(&sata_dev_desc[i], 0, sizeof(struct blk_desc)); - sata_dev_desc[i].uclass_id = UCLASS_AHCI; - sata_dev_desc[i].devnum = i; - sata_dev_desc[i].part_type = PART_TYPE_UNKNOWN; - sata_dev_desc[i].type = DEV_TYPE_HARDDISK; - sata_dev_desc[i].lba = 0; - sata_dev_desc[i].blksz = 512; - sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz); - rc = init_sata(i); - if (!rc) { - rc = scan_sata(i); - if (!rc && sata_dev_desc[i].lba > 0 && - sata_dev_desc[i].blksz > 0) { - part_init(&sata_dev_desc[i]); - ret = i; - } - } - } - - return ret; -} -int sata_initialize(void) __attribute__((weak, alias("__sata_initialize"))); - -__weak int __sata_stop(void) -{ - int i, err = 0; - - for (i = 0; i < CONFIG_SYS_SATA_MAX_DEVICE; i++) - err |= reset_sata(i); - - if (err) - printf("Could not reset some SATA devices\n"); - - return err; -} -int sata_stop(void) __attribute__((weak, alias("__sata_stop"))); -#endif - static const struct blk_ops sata_blk_ops = { .read = sata_bread, .write = sata_bwrite, diff --git a/drivers/ata/sata_sandbox.c b/drivers/ata/sata_sandbox.c deleted file mode 100644 index e64cc4a5c1..0000000000 --- a/drivers/ata/sata_sandbox.c +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2015 Google, Inc - * Written by Simon Glass <sjg@chromium.org> - */ - -#include <common.h> -#include <blk.h> - -int init_sata(int dev) -{ - return 0; -} - -int reset_sata(int dev) -{ - return 0; -} - -int scan_sata(int dev) -{ - return 0; -} - -ulong sata_read(int dev, ulong blknr, lbaint_t blkcnt, void *buffer) -{ - return 0; -} - -ulong sata_write(int dev, ulong blknr, lbaint_t blkcnt, const void *buffer) -{ - return 0; -} diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 048a6caef0..6ad18889f6 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -13,7 +13,7 @@ config BLK config SPL_LEGACY_BLOCK bool # "Enable Legacy Block Device" - depends on SPL && !DM_SPL + depends on SPL default y if SPL_MMC || SPL_USB_STORAGE || SCSI || NVME || IDE default y if SPL_AHCI_PCI help @@ -265,6 +265,7 @@ config SYS_64BIT_LBA config RKMTD bool "Rockchip rkmtd virtual block device" + select RANDOM_UUID help Enable "rkmtd" class and driver to create a virtual block device to transfer Rockchip boot block data to and from NAND with block diff --git a/drivers/block/Makefile b/drivers/block/Makefile index fdcba5c831..fe6a1fcf48 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -15,7 +15,8 @@ obj-$(CONFIG_RKMTD) += rkmtd.o endif obj-$(CONFIG_SANDBOX) += sandbox.o host-uclass.o host_dev.o obj-$(CONFIG_$(SPL_TPL_)BLOCK_CACHE) += blkcache.o -obj-$(CONFIG_BLKMAP) += blkmap.o +obj-$(CONFIG_$(SPL_TPL_)BLKMAP) += blkmap.o +obj-$(CONFIG_$(SPL_TPL_)BLKMAP) += blkmap_helper.o obj-$(CONFIG_EFI_MEDIA) += efi-media-uclass.o obj-$(CONFIG_EFI_MEDIA_SANDBOX) += sb_efi_media.o diff --git a/drivers/block/blkmap.c b/drivers/block/blkmap.c index 149a4cac3e..21201409ed 100644 --- a/drivers/block/blkmap.c +++ b/drivers/block/blkmap.c @@ -66,21 +66,6 @@ struct blkmap_slice { void (*destroy)(struct blkmap *bm, struct blkmap_slice *bms); }; -/** - * struct blkmap - Block map - * - * Data associated with a blkmap. - * - * @label: Human readable name of this blkmap - * @blk: Underlying block device - * @slices: List of slices associated with this blkmap - */ -struct blkmap { - char *label; - struct udevice *blk; - struct list_head slices; -}; - static bool blkmap_slice_contains(struct blkmap_slice *bms, lbaint_t blknr) { return (blknr >= bms->blknr) && (blknr < (bms->blknr + bms->blkcnt)); diff --git a/drivers/block/blkmap_helper.c b/drivers/block/blkmap_helper.c new file mode 100644 index 0000000000..bfba14110d --- /dev/null +++ b/drivers/block/blkmap_helper.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * blkmap helper function + * + * Copyright (c) 2023, Linaro Limited + */ + +#include <blk.h> +#include <blkmap.h> +#include <dm/device.h> +#include <dm/device-internal.h> + +int blkmap_create_ramdisk(const char *label, ulong image_addr, ulong image_size, + struct udevice **devp) +{ + int ret; + lbaint_t blknum; + struct blkmap *bm; + struct blk_desc *desc; + struct udevice *bm_dev; + + ret = blkmap_create(label, &bm_dev); + if (ret) { + log_err("failed to create blkmap\n"); + return ret; + } + + bm = dev_get_plat(bm_dev); + desc = dev_get_uclass_plat(bm->blk); + blknum = image_size >> desc->log2blksz; + ret = blkmap_map_pmem(bm_dev, 0, blknum, image_addr); + if (ret) { + log_err("Unable to map %#llx at block %d : %d\n", + (unsigned long long)image_addr, 0, ret); + goto err; + } + log_info("Block %d+0x" LBAF " mapped to %#llx\n", 0, blknum, + (unsigned long long)image_addr); + + ret = device_probe(bm->blk); + if (ret) + goto err; + + if (devp) + *devp = bm_dev; + + return 0; + +err: + blkmap_destroy(bm_dev); + + return ret; +} diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index e5ada5b6d4..eecfacd7fc 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1104,46 +1104,12 @@ static int ast2600_clk_enable(struct clk *clk) return 0; } -struct clk_ops ast2600_clk_ops = { - .get_rate = ast2600_clk_get_rate, - .set_rate = ast2600_clk_set_rate, - .enable = ast2600_clk_enable, -}; - -static int ast2600_clk_probe(struct udevice *dev) -{ - struct ast2600_clk_priv *priv = dev_get_priv(dev); - - priv->scu = devfdt_get_addr_ptr(dev); - if (IS_ERR(priv->scu)) - return PTR_ERR(priv->scu); - - ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); - ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); - ast2600_configure_mac12_clk(priv->scu); - ast2600_configure_mac34_clk(priv->scu); - ast2600_configure_rsa_ecc_clk(priv->scu); - - return 0; -} - -static int ast2600_clk_bind(struct udevice *dev) -{ - int ret; - - /* The reset driver does not have a device node, so bind it here */ - ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); - if (ret) - debug("Warning: No reset driver: ret=%d\n", ret); - - return 0; -} - struct aspeed_clks { ulong id; const char *name; }; +#if IS_ENABLED(CONFIG_CMD_CLK) static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HPLL, "hpll" }, { ASPEED_CLK_MPLL, "mpll" }, @@ -1158,18 +1124,12 @@ static struct aspeed_clks aspeed_clk_names[] = { { ASPEED_CLK_HUARTX, "huxclk" }, }; -int soc_clk_dump(void) +static void ast2600_clk_dump(struct udevice *dev) { - struct udevice *dev; struct clk clk; unsigned long rate; int i, ret; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu), - &dev); - if (ret) - return ret; - printf("Clk\t\tHz\n"); for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) { @@ -1202,6 +1162,45 @@ int soc_clk_dump(void) return 0; } +#endif + +struct clk_ops ast2600_clk_ops = { + .get_rate = ast2600_clk_get_rate, + .set_rate = ast2600_clk_set_rate, + .enable = ast2600_clk_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = ast2600_clk_dump, +#endif +}; + +static int ast2600_clk_probe(struct udevice *dev) +{ + struct ast2600_clk_priv *priv = dev_get_priv(dev); + + priv->scu = devfdt_get_addr_ptr(dev); + if (IS_ERR(priv->scu)) + return PTR_ERR(priv->scu); + + ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig); + ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig); + ast2600_configure_mac12_clk(priv->scu); + ast2600_configure_mac34_clk(priv->scu); + ast2600_configure_rsa_ecc_clk(priv->scu); + + return 0; +} + +static int ast2600_clk_bind(struct udevice *dev) +{ + int ret; + + /* The reset driver does not have a device node, so bind it here */ + ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev); + if (ret) + debug("Warning: No reset driver: ret=%d\n", ret); + + return 0; +} static const struct udevice_id ast2600_clk_ids[] = { { .compatible = "aspeed,ast2600-scu", }, diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index b52d926f33..025c7a7aa2 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -17,6 +17,7 @@ #include <linux/clk/at91_pmc.h> #include <linux/delay.h> #include <linux/io.h> +#include <linux/time.h> #include "pmc.h" #define UBOOT_DM_CLK_AT91_MAIN_RC "at91-main-rc-clk" @@ -25,7 +26,6 @@ #define UBOOT_DM_CLK_AT91_SAM9X5_MAIN "at91-sam9x5-main-clk" #define MOR_KEY_MASK GENMASK(23, 16) -#define USEC_PER_SEC 1000000UL #define SLOW_CLOCK_FREQ 32768 #define clk_main_parent_select(s) (((s) & \ diff --git a/drivers/clk/clk_k210.c b/drivers/clk/clk_k210.c index c534cc07e0..7432ae8f06 100644 --- a/drivers/clk/clk_k210.c +++ b/drivers/clk/clk_k210.c @@ -16,6 +16,7 @@ #include <dt-bindings/mfd/k210-sysctl.h> #include <k210/pll.h> #include <linux/bitfield.h> +#include <asm/barrier.h> DECLARE_GLOBAL_DATA_PTR; @@ -1238,52 +1239,6 @@ static int k210_clk_request(struct clk *clk) return 0; } -static const struct clk_ops k210_clk_ops = { - .request = k210_clk_request, - .set_rate = k210_clk_set_rate, - .get_rate = k210_clk_get_rate, - .set_parent = k210_clk_set_parent, - .enable = k210_clk_enable, - .disable = k210_clk_disable, -}; - -static int k210_clk_probe(struct udevice *dev) -{ - int ret; - struct k210_clk_priv *priv = dev_get_priv(dev); - - priv->base = dev_read_addr_ptr(dev_get_parent(dev)); - if (!priv->base) - return -EINVAL; - - ret = clk_get_by_index(dev, 0, &priv->in0); - if (ret) - return ret; - - /* - * Force setting defaults, even before relocation. This is so we can - * set the clock rate for PLL1 before we relocate into aisram. - */ - if (!(gd->flags & GD_FLG_RELOC)) - clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); - - return 0; -} - -static const struct udevice_id k210_clk_ids[] = { - { .compatible = "canaan,k210-clk" }, - { }, -}; - -U_BOOT_DRIVER(k210_clk) = { - .name = "k210_clk", - .id = UCLASS_CLK, - .of_match = k210_clk_ids, - .ops = &k210_clk_ops, - .probe = k210_clk_probe, - .priv_auto = sizeof(struct k210_clk_priv), -}; - #if IS_ENABLED(CONFIG_CMD_CLK) static char show_enabled(struct k210_clk_priv *priv, int id) { @@ -1322,16 +1277,10 @@ static void show_clks(struct k210_clk_priv *priv, int id, int depth) } } -int soc_clk_dump(void) +static void k210_clk_dump(struct udevice *dev) { - int ret; - struct udevice *dev; struct k210_clk_priv *priv; - ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(k210_clk), - &dev); - if (ret) - return ret; priv = dev_get_priv(dev); puts(" Rate Enabled Name\n"); @@ -1339,6 +1288,54 @@ int soc_clk_dump(void) printf(" %-9lu %-7c %*s%s\n", clk_get_rate(&priv->in0), 'y', 0, "", priv->in0.dev->name); show_clks(priv, K210_CLK_IN0, 1); - return 0; } #endif + +static const struct clk_ops k210_clk_ops = { + .request = k210_clk_request, + .set_rate = k210_clk_set_rate, + .get_rate = k210_clk_get_rate, + .set_parent = k210_clk_set_parent, + .enable = k210_clk_enable, + .disable = k210_clk_disable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = k210_clk_dump, +#endif +}; + +static int k210_clk_probe(struct udevice *dev) +{ + int ret; + struct k210_clk_priv *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev_get_parent(dev)); + if (!priv->base) + return -EINVAL; + + ret = clk_get_by_index(dev, 0, &priv->in0); + if (ret) + return ret; + + /* + * Force setting defaults, even before relocation. This is so we can + * set the clock rate for PLL1 before we relocate into aisram. + */ + if (!(gd->flags & GD_FLG_RELOC)) + clk_set_defaults(dev, CLK_DEFAULTS_POST_FORCE); + + return 0; +} + +static const struct udevice_id k210_clk_ids[] = { + { .compatible = "canaan,k210-clk" }, + { }, +}; + +U_BOOT_DRIVER(k210_clk) = { + .name = "k210_clk", + .id = UCLASS_CLK, + .of_match = k210_clk_ids, + .ops = &k210_clk_ops, + .probe = k210_clk_probe, + .priv_auto = sizeof(struct k210_clk_priv), +}; diff --git a/drivers/clk/clk_pic32.c b/drivers/clk/clk_pic32.c index ef06a7fb9f..a77d0e7419 100644 --- a/drivers/clk/clk_pic32.c +++ b/drivers/clk/clk_pic32.c @@ -20,6 +20,8 @@ DECLARE_GLOBAL_DATA_PTR; +#define CLK_MHZ(x) ((x) / 1000000) + /* Primary oscillator */ #define SYS_POSC_CLK_HZ 24000000 @@ -385,9 +387,44 @@ static ulong pic32_set_rate(struct clk *clk, ulong rate) return rate; } +#if IS_ENABLED(CONFIG_CMD_CLK) +static void pic32_dump(struct udevice *dev) +{ + int i; + struct clk clk; + + clk.dev = dev; + + clk.id = PLLCLK; + printf("PLL Speed: %lu MHz\n", + CLK_MHZ(pic32_get_rate(&clk))); + + clk.id = PB7CLK; + printf("CPU Speed: %lu MHz\n", CLK_MHZ(pic32_get_rate(&clk))); + + clk.id = MPLL; + printf("MPLL Speed: %lu MHz\n", CLK_MHZ(pic32_get_rate(&clk))); + + for (i = PB1CLK; i <= PB7CLK; i++) { + clk.id = i; + printf("PB%d Clock Speed: %lu MHz\n", i - PB1CLK + 1, + CLK_MHZ(pic32_get_rate(&clk))); + } + + for (i = REF1CLK; i <= REF5CLK; i++) { + clk.id = i; + printf("REFO%d Clock Speed: %lu MHz\n", i - REF1CLK + 1, + CLK_MHZ(pic32_get_rate(&clk))); + } +} +#endif + static struct clk_ops pic32_pic32_clk_ops = { .set_rate = pic32_set_rate, .get_rate = pic32_get_rate, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = pic32_dump, +#endif }; static int pic32_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_versal.c b/drivers/clk/clk_versal.c index c473643603..42ab032bf7 100644 --- a/drivers/clk/clk_versal.c +++ b/drivers/clk/clk_versal.c @@ -555,7 +555,8 @@ static int versal_clock_get_rate(u32 clk_id, u64 *clk_rate) return 0; } -int soc_clk_dump(void) +#if IS_ENABLED(CONFIG_CMD_CLK) +static void versal_clk_dump(struct udevice __always_unused *dev) { u64 clk_rate = 0; u32 type, ret, i = 0; @@ -575,9 +576,8 @@ int soc_clk_dump(void) printf("clk: %s freq:%lld\n", clock[i].clk_name, clk_rate); } - - return 0; } +#endif static void versal_get_clock_info(void) { @@ -769,6 +769,9 @@ static struct clk_ops versal_clk_ops = { .set_rate = versal_clk_set_rate, .get_rate = versal_clk_get_rate, .enable = versal_clk_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = versal_clk_dump, +#endif }; static const struct udevice_id versal_clk_ids[] = { diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c index e80500e382..34f964d72a 100644 --- a/drivers/clk/clk_zynq.c +++ b/drivers/clk/clk_zynq.c @@ -454,12 +454,64 @@ static int dummy_enable(struct clk *clk) return 0; } +#if IS_ENABLED(CONFIG_CMD_CLK) +static const char * const clk_names[clk_max] = { + "armpll", "ddrpll", "iopll", + "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", "gem1", + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", + "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", + "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", + "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", + "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", + "smc_aper", "swdt", "dbg_trc", "dbg_apb" +}; + +static void zynq_clk_dump(struct udevice *dev) +{ + int i, ret; + + printf("clk\t\tfrequency\n"); + for (i = 0; i < clk_max; i++) { + const char *name = clk_names[i]; + + if (name) { + struct clk clk; + unsigned long rate; + + clk.id = i; + ret = clk_request(dev, &clk); + if (ret < 0) { + printf("%s clk_request() failed: %d\n", + __func__, ret); + break; + } + + rate = clk_get_rate(&clk); + + clk_free(&clk); + + if ((rate == (unsigned long)-ENOSYS) || + (rate == (unsigned long)-ENXIO)) + printf("%10s%20s\n", name, "unknown"); + else + printf("%10s%20lu\n", name, rate); + } + } +} +#endif + static struct clk_ops zynq_clk_ops = { .get_rate = zynq_clk_get_rate, #ifndef CONFIG_SPL_BUILD .set_rate = zynq_clk_set_rate, #endif .enable = dummy_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = zynq_clk_dump, +#endif }; static int zynq_clk_probe(struct udevice *dev) diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index 1cfe0e25b1..0ffac194a1 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/drivers/clk/clk_zynqmp.c @@ -735,16 +735,11 @@ static ulong zynqmp_clk_set_rate(struct clk *clk, ulong rate) } } -int soc_clk_dump(void) +#if IS_ENABLED(CONFIG_CMD_CLK) +static void zynqmp_clk_dump(struct udevice *dev) { - struct udevice *dev; int i, ret; - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(zynqmp_clk), &dev); - if (ret) - return ret; - printf("clk\t\tfrequency\n"); for (i = 0; i < clk_max; i++) { const char *name = clk_names[i]; @@ -754,8 +749,11 @@ int soc_clk_dump(void) clk.id = i; ret = clk_request(dev, &clk); - if (ret < 0) - return ret; + if (ret < 0) { + printf("%s clk_request() failed: %d\n", + __func__, ret); + break; + } rate = clk_get_rate(&clk); @@ -769,9 +767,8 @@ int soc_clk_dump(void) printf("%10s%20lu\n", name, rate); } } - - return 0; } +#endif static int zynqmp_get_freq_by_name(char *name, struct udevice *dev, ulong *freq) { @@ -844,6 +841,7 @@ static int zynqmp_clk_enable(struct clk *clk) break; case qspi_ref ... can1_ref: case lpd_lsbus: + case topsw_lsbus: clkact_shift = 24; mask = 0x1; break; @@ -871,6 +869,9 @@ static struct clk_ops zynqmp_clk_ops = { .set_rate = zynqmp_clk_set_rate, .get_rate = zynqmp_clk_get_rate, .enable = zynqmp_clk_enable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = zynqmp_clk_dump, +#endif }; static const struct udevice_id zynqmp_clk_ids[] = { diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c index ceeead3434..9600672e07 100644 --- a/drivers/clk/imx/clk-imx8.c +++ b/drivers/clk/imx/clk-imx8.c @@ -43,18 +43,12 @@ static int imx8_clk_enable(struct clk *clk) } #if IS_ENABLED(CONFIG_CMD_CLK) -int soc_clk_dump(void) +static void imx8_clk_dump(struct udevice *dev) { - struct udevice *dev; struct clk clk; unsigned long rate; int i, ret; - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(imx8_clk), &dev); - if (ret) - return ret; - printf("Clk\t\tHz\n"); for (i = 0; i < num_clks; i++) { @@ -84,8 +78,6 @@ int soc_clk_dump(void) printf("%s(%3lu):\t%lu\n", imx8_clk_names[i].name, imx8_clk_names[i].id, rate); } - - return 0; } #endif @@ -94,6 +86,9 @@ static struct clk_ops imx8_clk_ops = { .get_rate = imx8_clk_get_rate, .enable = imx8_clk_enable, .disable = imx8_clk_disable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = imx8_clk_dump, +#endif }; static int imx8_clk_probe(struct udevice *dev) diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index 692823e74b..457acb8a40 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -83,6 +83,20 @@ static const char *imx8mn_i2c3_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_ static const char *imx8mn_i2c4_sels[] = {"clock-osc-24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out", "video_pll_out", "audio_pll2_out", "sys_pll1_133m", }; +#ifndef CONFIG_SPL_BUILD +static const char *imx8mn_pwm1_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", + "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll_out", }; + +static const char *imx8mn_pwm2_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", + "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll_out", }; + +static const char *imx8mn_pwm3_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", + "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll_out", }; + +static const char *imx8mn_pwm4_sels[] = {"clock-osc-24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", + "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll_out", }; +#endif + static const char *imx8mn_wdog_sels[] = {"clock-osc-24m", "sys_pll1_133m", "sys_pll1_160m", "m7_alt_pll", "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", }; @@ -330,6 +344,22 @@ static int imx8mn_clk_probe(struct udevice *dev) clk_dm(IMX8MN_CLK_ENET1_ROOT, imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0)); + clk_dm(IMX8MN_CLK_PWM1, + imx8m_clk_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380)); + clk_dm(IMX8MN_CLK_PWM2, + imx8m_clk_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400)); + clk_dm(IMX8MN_CLK_PWM3, + imx8m_clk_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480)); + clk_dm(IMX8MN_CLK_PWM4, + imx8m_clk_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500)); + clk_dm(IMX8MN_CLK_PWM1_ROOT, + imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0)); + clk_dm(IMX8MN_CLK_PWM2_ROOT, + imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0)); + clk_dm(IMX8MN_CLK_PWM3_ROOT, + imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0)); + clk_dm(IMX8MN_CLK_PWM4_ROOT, + imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0)); #endif #if CONFIG_IS_ENABLED(DM_SPI) diff --git a/drivers/clk/meson/a1.c b/drivers/clk/meson/a1.c index d0f5bb3753..5220a337a8 100644 --- a/drivers/clk/meson/a1.c +++ b/drivers/clk/meson/a1.c @@ -607,14 +607,6 @@ static int meson_clk_set_parent(struct clk *clk, struct clk *parent_clk) return meson_mux_set_parent_by_id(clk, parent_clk->id); } -static struct clk_ops meson_clk_ops = { - .disable = meson_clk_disable, - .enable = meson_clk_enable, - .get_rate = meson_clk_get_rate, - .set_rate = meson_clk_set_rate, - .set_parent = meson_clk_set_parent, -}; - static int meson_clk_probe(struct udevice *dev) { struct meson_clk *priv = dev_get_priv(dev); @@ -644,15 +636,7 @@ static const struct udevice_id meson_clk_ids[] = { { } }; -U_BOOT_DRIVER(meson_clk) = { - .name = "meson-clk-a1", - .id = UCLASS_CLK, - .of_match = meson_clk_ids, - .priv_auto = sizeof(struct meson_clk), - .ops = &meson_clk_ops, - .probe = meson_clk_probe, -}; - +#if IS_ENABLED(CONFIG_CMD_CLK) static const char *meson_clk_get_name(struct clk *clk, int id) { const struct meson_clk_info *info; @@ -662,7 +646,7 @@ static const char *meson_clk_get_name(struct clk *clk, int id) return IS_ERR(info) ? "unknown" : info->name; } -static int meson_clk_dump(struct clk *clk) +static int meson_clk_dump_single(struct clk *clk) { const struct meson_clk_info *info; struct meson_clk *priv; @@ -697,7 +681,7 @@ static int meson_clk_dump(struct clk *clk) return 0; } -static int meson_clk_dump_dev(struct udevice *dev) +static void meson_clk_dump(struct udevice *dev) { int i; struct meson_clk_data *data; @@ -710,26 +694,30 @@ static int meson_clk_dump_dev(struct udevice *dev) data = (struct meson_clk_data *)dev_get_driver_data(dev); for (i = 0; i < data->num_clocks; i++) { - meson_clk_dump(&(struct clk){ + meson_clk_dump_single(&(struct clk){ .dev = dev, .id = i }); } - - return 0; } +#endif -int soc_clk_dump(void) -{ - struct udevice *dev; - int i = 0; - - while (!uclass_get_device(UCLASS_CLK, i++, &dev)) { - if (dev->driver == DM_DRIVER_GET(meson_clk)) { - meson_clk_dump_dev(dev); - printf("\n"); - } - } +static struct clk_ops meson_clk_ops = { + .disable = meson_clk_disable, + .enable = meson_clk_enable, + .get_rate = meson_clk_get_rate, + .set_rate = meson_clk_set_rate, + .set_parent = meson_clk_set_parent, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = meson_clk_dump, +#endif +}; - return 0; -} +U_BOOT_DRIVER(meson_clk) = { + .name = "meson-clk-a1", + .id = UCLASS_CLK, + .of_match = meson_clk_ids, + .priv_auto = sizeof(struct meson_clk), + .ops = &meson_clk_ops, + .probe = meson_clk_probe, +}; diff --git a/drivers/clk/mvebu/armada-37xx-periph.c b/drivers/clk/mvebu/armada-37xx-periph.c index e75052f383..1a7097029a 100644 --- a/drivers/clk/mvebu/armada-37xx-periph.c +++ b/drivers/clk/mvebu/armada-37xx-periph.c @@ -488,33 +488,36 @@ static int armada_37xx_periph_clk_dump(struct udevice *dev) static int clk_dump(const char *name, int (*func)(struct udevice *)) { struct udevice *dev; + int ret; if (uclass_get_device_by_name(UCLASS_CLK, name, &dev)) { printf("Cannot find device %s\n", name); return -ENODEV; } - return func(dev); + ret = func(dev); + if (ret) + printf("Dump failed for %s: %d\n", name, ret); + + return ret; } int armada_37xx_tbg_clk_dump(struct udevice *); -int soc_clk_dump(void) +static void armada37xx_clk_dump(struct udevice __always_unused *dev) { printf(" xtal at %u000000 Hz\n\n", get_ref_clk()); if (clk_dump("tbg@13200", armada_37xx_tbg_clk_dump)) - return 1; + return; if (clk_dump("nb-periph-clk@13000", armada_37xx_periph_clk_dump)) - return 1; + return; if (clk_dump("sb-periph-clk@18000", armada_37xx_periph_clk_dump)) - return 1; - - return 0; + return; } #endif @@ -605,6 +608,9 @@ static const struct clk_ops armada_37xx_periph_clk_ops = { .set_parent = armada_37xx_periph_clk_set_parent, .enable = armada_37xx_periph_clk_enable, .disable = armada_37xx_periph_clk_disable, +#if IS_ENABLED(CONFIG_CMD_CLK) + .dump = armada37xx_clk_dump, +#endif }; static const struct udevice_id armada_37xx_periph_clk_ids[] = { diff --git a/drivers/clk/nuvoton/clk_npcm.c b/drivers/clk/nuvoton/clk_npcm.c index 8d71f2a24b..18cb9cddbf 100644 --- a/drivers/clk/nuvoton/clk_npcm.c +++ b/drivers/clk/nuvoton/clk_npcm.c @@ -135,7 +135,7 @@ static u32 npcm_clk_get_div(struct clk *clk) return div; } -static u32 npcm_clk_set_div(struct clk *clk, u32 div) +static int npcm_clk_set_div(struct clk *clk, u32 div) { struct npcm_clk_priv *priv = dev_get_priv(clk->dev); struct npcm_clk_div *divider; @@ -145,6 +145,9 @@ static u32 npcm_clk_set_div(struct clk *clk, u32 div) if (!divider) return -EINVAL; + if (divider->flags & DIV_RO) + return 0; + if (divider->flags & PRE_DIV2) div = div >> 1; @@ -153,6 +156,12 @@ static u32 npcm_clk_set_div(struct clk *clk, u32 div) else clkdiv = ilog2(div); + if (clkdiv > (divider->mask >> (ffs(divider->mask) - 1))) { + printf("clkdiv(%d) for clk(%ld) is over limit\n", + clkdiv, clk->id); + return -EINVAL; + } + val = readl(priv->base + divider->reg); val &= ~divider->mask; val |= (clkdiv << (ffs(divider->mask) - 1)) & divider->mask; @@ -253,8 +262,8 @@ static ulong npcm_clk_set_rate(struct clk *clk, ulong rate) if (ret) return ret; - debug("%s: rate %lu, new rate (%lu / %u)\n", __func__, rate, parent_rate, div); - return (parent_rate / div); + debug("%s: rate %lu, new rate %lu\n", __func__, rate, npcm_clk_get_rate(clk)); + return npcm_clk_get_rate(clk); } static int npcm_clk_set_parent(struct clk *clk, struct clk *parent) diff --git a/drivers/clk/nuvoton/clk_npcm.h b/drivers/clk/nuvoton/clk_npcm.h index 06b60dc8b8..b4726d8381 100644 --- a/drivers/clk/nuvoton/clk_npcm.h +++ b/drivers/clk/nuvoton/clk_npcm.h @@ -50,6 +50,7 @@ #define PRE_DIV2 BIT(2) /* Pre divisor = 2 */ #define POST_DIV2 BIT(3) /* Post divisor = 2 */ #define FIXED_PARENT BIT(4) /* clock source is fixed */ +#define DIV_RO BIT(5) /* divider is read-only */ /* Parameters of PLL configuration */ struct npcm_clk_pll { diff --git a/drivers/clk/nuvoton/clk_npcm8xx.c b/drivers/clk/nuvoton/clk_npcm8xx.c index 27e3cfcf55..d1b32e3237 100644 --- a/drivers/clk/nuvoton/clk_npcm8xx.c +++ b/drivers/clk/nuvoton/clk_npcm8xx.c @@ -45,12 +45,12 @@ static struct npcm_clk_select npcm8xx_clk_selectors[] = { }; static struct npcm_clk_div npcm8xx_clk_dividers[] = { - {NPCM8XX_CLK_AHB, CLKDIV1, CLK4DIV, DIV_TYPE1 | PRE_DIV2}, - {NPCM8XX_CLK_APB2, CLKDIV2, APB2CKDIV, DIV_TYPE2}, - {NPCM8XX_CLK_APB5, CLKDIV2, APB5CKDIV, DIV_TYPE2}, - {NPCM8XX_CLK_SPI0, CLKDIV3, SPI0CKDIV, DIV_TYPE1}, - {NPCM8XX_CLK_SPI1, CLKDIV3, SPI1CKDIV, DIV_TYPE1}, - {NPCM8XX_CLK_SPI3, CLKDIV1, SPI3CKDIV, DIV_TYPE1}, + {NPCM8XX_CLK_AHB, CLKDIV1, CLK4DIV, DIV_TYPE1 | PRE_DIV2 | DIV_RO}, + {NPCM8XX_CLK_APB2, CLKDIV2, APB2CKDIV, DIV_TYPE2 | DIV_RO}, + {NPCM8XX_CLK_APB5, CLKDIV2, APB5CKDIV, DIV_TYPE2 | DIV_RO}, + {NPCM8XX_CLK_SPI0, CLKDIV3, SPI0CKDIV, DIV_TYPE1 | DIV_RO}, + {NPCM8XX_CLK_SPI1, CLKDIV3, SPI1CKDIV, DIV_TYPE1 | DIV_RO}, + {NPCM8XX_CLK_SPI3, CLKDIV1, SPI3CKDIV, DIV_TYPE1 | DIV_RO}, {NPCM8XX_CLK_SPIX, CLKDIV3, SPIXCKDIV, DIV_TYPE1}, {NPCM8XX_CLK_UART, CLKDIV1, UARTDIV1, DIV_TYPE1}, {NPCM8XX_CLK_UART2, CLKDIV3, UARTDIV2, DIV_TYPE1}, diff --git a/drivers/clk/stm32/clk-stm32f.c b/drivers/clk/stm32/clk-stm32f.c index ed7660196e..d68c75ed20 100644 --- a/drivers/clk/stm32/clk-stm32f.c +++ b/drivers/clk/stm32/clk-stm32f.c @@ -522,17 +522,20 @@ static ulong stm32_set_rate(struct clk *clk, ulong rate) /* get the current PLLSAIR output freq */ pllsair_rate = stm32_clk_get_pllsai_rate(priv, PLLSAIR); - best_div = pllsair_rate / rate; - - /* look into pllsaidivr_table if this divider is available*/ - for (i = 0 ; i < sizeof(pllsaidivr_table); i++) - if (best_div == pllsaidivr_table[i]) { - /* set pll_saidivr with found value */ - clrsetbits_le32(®s->dckcfgr, - RCC_DCKCFGR_PLLSAIDIVR_MASK, - pllsaidivr_table[i]); - return rate; - } + if ((pllsair_rate % rate) == 0) { + best_div = pllsair_rate / rate; + + /* look into pllsaidivr_table if this divider is available */ + for (i = 0 ; i < sizeof(pllsaidivr_table); i++) + if (best_div == pllsaidivr_table[i]) { + /* set pll_saidivr with found value */ + clrsetbits_le32(®s->dckcfgr, + RCC_DCKCFGR_PLLSAIDIVR_MASK, + pllsaidivr_table[i] << + RCC_DCKCFGR_PLLSAIDIVR_SHIFT); + return rate; + } + } /* * As no pllsaidivr value is suitable to obtain requested freq, diff --git a/drivers/clk/stm32/clk-stm32mp1.c b/drivers/clk/stm32/clk-stm32mp1.c index f3ac8c7583..6f000c8e44 100644 --- a/drivers/clk/stm32/clk-stm32mp1.c +++ b/drivers/clk/stm32/clk-stm32mp1.c @@ -2225,10 +2225,13 @@ static void stm32mp1_osc_init(struct udevice *dev) } } -static void __maybe_unused stm32mp1_clk_dump(struct stm32mp1_clk_priv *priv) +static void __maybe_unused stm32mp1_clk_dump(struct udevice *dev) { char buf[32]; int i, s, p; + struct stm32mp1_clk_priv *priv; + + priv = dev_get_priv(dev); printf("Clocks:\n"); for (i = 0; i < _PARENT_NB; i++) { @@ -2252,27 +2255,6 @@ static void __maybe_unused stm32mp1_clk_dump(struct stm32mp1_clk_priv *priv) } } -#ifdef CONFIG_CMD_CLK -int soc_clk_dump(void) -{ - struct udevice *dev; - struct stm32mp1_clk_priv *priv; - int ret; - - ret = uclass_get_device_by_driver(UCLASS_CLK, - DM_DRIVER_GET(stm32mp1_clock), - &dev); - if (ret) - return ret; - - priv = dev_get_priv(dev); - - stm32mp1_clk_dump(priv); - - return 0; -} -#endif - static int stm32mp1_clk_probe(struct udevice *dev) { int result = 0; @@ -2302,7 +2284,7 @@ static int stm32mp1_clk_probe(struct udevice *dev) #if defined(VERBOSE_DEBUG) /* display debug information for probe after relocation */ if (gd->flags & GD_FLG_RELOC) - stm32mp1_clk_dump(priv); + stm32mp1_clk_dump(dev); #endif gd->cpu_clk = stm32mp1_clk_get(priv, _CK_MPU); @@ -2333,6 +2315,9 @@ static const struct clk_ops stm32mp1_clk_ops = { .disable = stm32mp1_clk_disable, .get_rate = stm32mp1_clk_get_rate, .set_rate = stm32mp1_clk_set_rate, +#if IS_ENABLED(CONFIG_CMD_CLK) && !IS_ENABLED(CONFIG_SPL_BUILD) + .dump = stm32mp1_clk_dump, +#endif }; U_BOOT_DRIVER(stm32mp1_clock) = { diff --git a/drivers/core/Kconfig b/drivers/core/Kconfig index 737d4590d5..1081d61fcf 100644 --- a/drivers/core/Kconfig +++ b/drivers/core/Kconfig @@ -87,7 +87,7 @@ config DM_STATS config SPL_DM_STATS bool "Collect and show driver model stats in SPL" - depends on DM_SPL + depends on SPL_DM help Enable this to collect and display memory statistics about driver model. This can help to figure out where all the memory is going and diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c index f72ea416cf..21a233f90f 100644 --- a/drivers/core/ofnode.c +++ b/drivers/core/ofnode.c @@ -83,6 +83,11 @@ static oftree oftree_ensure(void *fdt) if (check_tree_count()) return oftree_null(); + if (fdt_check_header(fdt)) { + log_err("Invalid device tree blob header\n"); + return oftree_null(); + } + /* register the new tree */ i = oftree_count++; oftree_list[i] = fdt; diff --git a/drivers/ddr/imx/phy/helper.c b/drivers/ddr/imx/phy/helper.c index 855a874ac1..b9b2403012 100644 --- a/drivers/ddr/imx/phy/helper.c +++ b/drivers/ddr/imx/phy/helper.c @@ -49,6 +49,13 @@ void ddr_load_train_firmware(enum fw_type type) unsigned long imem_start = (unsigned long)_end + fw_offset; unsigned long dmem_start; unsigned long imem_len = IMEM_LEN, dmem_len = DMEM_LEN; + static enum fw_type last_type = -1; + + /* If FW doesn't change, we can save the loading. */ + if (last_type == type) + return; + + last_type = type; #ifdef CONFIG_SPL_OF_CONTROL if (gd->fdt_blob && !fdt_check_header(gd->fdt_blob)) { diff --git a/drivers/dfu/Kconfig b/drivers/dfu/Kconfig index 4e80e85d10..0360d9da14 100644 --- a/drivers/dfu/Kconfig +++ b/drivers/dfu/Kconfig @@ -19,6 +19,7 @@ config DFU_WRITE_ALT config DFU_TFTP bool "DFU via TFTP" + depends on NETDEVICES select UPDATE_COMMON select DFU_OVER_TFTP help @@ -111,5 +112,14 @@ config SYS_DFU_MAX_FILE_SIZE the buffer once we've been given the whole file. Define this to the maximum filesize (in bytes) for the buffer. If undefined it defaults to the CONFIG_SYS_DFU_DATA_BUF_SIZE. + +config DFU_NAME_MAX_SIZE + int "Size of the name to be added in dfu entity" + default 32 + depends on DFU + help + This value is used to maximum size. If name is longer than default size, + we need to change the proper maximum size. + endif endmenu diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 0af5460421..3c64e89464 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -87,7 +87,6 @@ endif config DMA_LEGACY bool "Legacy DMA support" - default y if FSLDMAFEC help Enable legacy DMA support. This does not use driver model and should be migrated to the new API. diff --git a/drivers/dma/MCD_dmaApi.c b/drivers/dma/MCD_dmaApi.c deleted file mode 100644 index af0e134522..0000000000 --- a/drivers/dma/MCD_dmaApi.c +++ /dev/null @@ -1,1010 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. - */ - -/*Main C file for multi-channel DMA API. */ - -#include <common.h> - -#include <MCD_dma.h> -#include <MCD_tasksInit.h> -#include <MCD_progCheck.h> - -/********************************************************************/ -/* This is an API-internal pointer to the DMA's registers */ -dmaRegs *MCD_dmaBar; - -/* - * These are the real and model task tables as generated by the - * build process - */ -extern TaskTableEntry MCD_realTaskTableSrc[NCHANNELS]; -extern TaskTableEntry MCD_modelTaskTableSrc[NUMOFVARIANTS]; - -/* - * However, this (usually) gets relocated to on-chip SRAM, at which - * point we access them as these tables - */ -volatile TaskTableEntry *MCD_taskTable; -TaskTableEntry *MCD_modelTaskTable; - -/* - * MCD_chStatus[] is an array of status indicators for remembering - * whether a DMA has ever been attempted on each channel, pausing - * status, etc. - */ -static int MCD_chStatus[NCHANNELS] = { - MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, - MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, - MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, - MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA -}; - -/* Prototypes for local functions */ -static void MCD_memcpy(int *dest, int *src, u32 size); -static void MCD_resmActions(int channel); - -/* - * Buffer descriptors used for storage of progress info for single Dmas - * Also used as storage for the DMA for CRCs for single DMAs - * Otherwise, the DMA does not parse these buffer descriptors - */ -#ifdef MCD_INCLUDE_EU -extern MCD_bufDesc MCD_singleBufDescs[NCHANNELS]; -#else -MCD_bufDesc MCD_singleBufDescs[NCHANNELS]; -#endif -MCD_bufDesc *MCD_relocBuffDesc; - -/* Defines for the debug control register's functions */ -#define DBG_CTL_COMP1_TASK (0x00002000) -#define DBG_CTL_ENABLE (DBG_CTL_AUTO_ARM | \ - DBG_CTL_BREAK | \ - DBG_CTL_INT_BREAK | \ - DBG_CTL_COMP1_TASK) -#define DBG_CTL_DISABLE (DBG_CTL_AUTO_ARM | \ - DBG_CTL_INT_BREAK | \ - DBG_CTL_COMP1_TASK) -#define DBG_KILL_ALL_STAT (0xFFFFFFFF) - -/* Offset to context save area where progress info is stored */ -#define CSAVE_OFFSET 10 - -/* Defines for Byte Swapping */ -#define MCD_BYTE_SWAP_KILLER 0xFFF8888F -#define MCD_NO_BYTE_SWAP_ATALL 0x00040000 - -/* Execution Unit Identifiers */ -#define MAC 0 /* legacy - not used */ -#define LUAC 1 /* legacy - not used */ -#define CRC 2 /* legacy - not used */ -#define LURC 3 /* Logic Unit with CRC */ - -/* Task Identifiers */ -#define TASK_CHAINNOEU 0 -#define TASK_SINGLENOEU 1 -#ifdef MCD_INCLUDE_EU -#define TASK_CHAINEU 2 -#define TASK_SINGLEEU 3 -#define TASK_FECRX 4 -#define TASK_FECTX 5 -#else -#define TASK_CHAINEU 0 -#define TASK_SINGLEEU 1 -#define TASK_FECRX 2 -#define TASK_FECTX 3 -#endif - -/* - * Structure to remember which variant is on which channel - * TBD- need this? - */ -typedef struct MCD_remVariants_struct MCD_remVariant; -struct MCD_remVariants_struct { - int remDestRsdIncr[NCHANNELS]; /* -1,0,1 */ - int remSrcRsdIncr[NCHANNELS]; /* -1,0,1 */ - s16 remDestIncr[NCHANNELS]; /* DestIncr */ - s16 remSrcIncr[NCHANNELS]; /* srcIncr */ - u32 remXferSize[NCHANNELS]; /* xferSize */ -}; - -/* Structure to remember the startDma parameters for each channel */ -MCD_remVariant MCD_remVariants; -/********************************************************************/ -/* Function: MCD_initDma - * Purpose: Initializes the DMA API by setting up a pointer to the DMA - * registers, relocating and creating the appropriate task - * structures, and setting up some global settings - * Arguments: - * dmaBarAddr - pointer to the multichannel DMA registers - * taskTableDest - location to move DMA task code and structs to - * flags - operational parameters - * Return Value: - * MCD_TABLE_UNALIGNED if taskTableDest is not 512-byte aligned - * MCD_OK otherwise - */ -extern u32 MCD_funcDescTab0[]; - -int MCD_initDma(dmaRegs * dmaBarAddr, void *taskTableDest, u32 flags) -{ - int i; - TaskTableEntry *entryPtr; - - /* setup the local pointer to register set */ - MCD_dmaBar = dmaBarAddr; - - /* do we need to move/create a task table */ - if ((flags & MCD_RELOC_TASKS) != 0) { - int fixedSize; - u32 *fixedPtr; - /*int *tablePtr = taskTableDest;TBD */ - int varTabsOffset, funcDescTabsOffset, contextSavesOffset; - int taskDescTabsOffset; - int taskTableSize, varTabsSize, funcDescTabsSize, - contextSavesSize; - int taskDescTabSize; - - int i; - - /* check if physical address is aligned on 512 byte boundary */ - if (((u32) taskTableDest & 0x000001ff) != 0) - return (MCD_TABLE_UNALIGNED); - - /* set up local pointer to task Table */ - MCD_taskTable = taskTableDest; - - /* - * Create a task table: - * - compute aligned base offsets for variable tables and - * function descriptor tables, then - * - loop through the task table and setup the pointers - * - copy over model task table with the the actual task - * descriptor tables - */ - - taskTableSize = NCHANNELS * sizeof(TaskTableEntry); - /* align variable tables to size */ - varTabsOffset = taskTableSize + (u32) taskTableDest; - if ((varTabsOffset & (VAR_TAB_SIZE - 1)) != 0) - varTabsOffset = - (varTabsOffset + VAR_TAB_SIZE) & (~VAR_TAB_SIZE); - /* align function descriptor tables */ - varTabsSize = NCHANNELS * VAR_TAB_SIZE; - funcDescTabsOffset = varTabsOffset + varTabsSize; - - if ((funcDescTabsOffset & (FUNCDESC_TAB_SIZE - 1)) != 0) - funcDescTabsOffset = - (funcDescTabsOffset + - FUNCDESC_TAB_SIZE) & (~FUNCDESC_TAB_SIZE); - - funcDescTabsSize = FUNCDESC_TAB_NUM * FUNCDESC_TAB_SIZE; - contextSavesOffset = funcDescTabsOffset + funcDescTabsSize; - contextSavesSize = (NCHANNELS * CONTEXT_SAVE_SIZE); - fixedSize = - taskTableSize + varTabsSize + funcDescTabsSize + - contextSavesSize; - - /* zero the thing out */ - fixedPtr = (u32 *) taskTableDest; - for (i = 0; i < (fixedSize / 4); i++) - fixedPtr[i] = 0; - - entryPtr = (TaskTableEntry *) MCD_taskTable; - /* set up fixed pointers */ - for (i = 0; i < NCHANNELS; i++) { - /* update ptr to local value */ - entryPtr[i].varTab = (u32) varTabsOffset; - entryPtr[i].FDTandFlags = - (u32) funcDescTabsOffset | MCD_TT_FLAGS_DEF; - entryPtr[i].contextSaveSpace = (u32) contextSavesOffset; - varTabsOffset += VAR_TAB_SIZE; -#ifdef MCD_INCLUDE_EU - /* if not there is only one, just point to the - same one */ - funcDescTabsOffset += FUNCDESC_TAB_SIZE; -#endif - contextSavesOffset += CONTEXT_SAVE_SIZE; - } - /* copy over the function descriptor table */ - for (i = 0; i < FUNCDESC_TAB_NUM; i++) { - MCD_memcpy((void *)(entryPtr[i]. - FDTandFlags & ~MCD_TT_FLAGS_MASK), - (void *)MCD_funcDescTab0, FUNCDESC_TAB_SIZE); - } - - /* copy model task table to where the context saves stuff - leaves off */ - MCD_modelTaskTable = (TaskTableEntry *) contextSavesOffset; - - MCD_memcpy((void *)MCD_modelTaskTable, - (void *)MCD_modelTaskTableSrc, - NUMOFVARIANTS * sizeof(TaskTableEntry)); - - /* point to local version of model task table */ - entryPtr = MCD_modelTaskTable; - taskDescTabsOffset = (u32) MCD_modelTaskTable + - (NUMOFVARIANTS * sizeof(TaskTableEntry)); - - /* copy actual task code and update TDT ptrs in local - model task table */ - for (i = 0; i < NUMOFVARIANTS; i++) { - taskDescTabSize = - entryPtr[i].TDTend - entryPtr[i].TDTstart + 4; - MCD_memcpy((void *)taskDescTabsOffset, - (void *)entryPtr[i].TDTstart, - taskDescTabSize); - entryPtr[i].TDTstart = (u32) taskDescTabsOffset; - taskDescTabsOffset += taskDescTabSize; - entryPtr[i].TDTend = (u32) taskDescTabsOffset - 4; - } -#ifdef MCD_INCLUDE_EU - /* Tack single DMA BDs onto end of code so API controls - where they are since DMA might write to them */ - MCD_relocBuffDesc = - (MCD_bufDesc *) (entryPtr[NUMOFVARIANTS - 1].TDTend + 4); -#else - /* DMA does not touch them so they can be wherever and we - don't need to waste SRAM on them */ - MCD_relocBuffDesc = MCD_singleBufDescs; -#endif - } else { - /* point the would-be relocated task tables and the - buffer descriptors to the ones the linker generated */ - - if (((u32) MCD_realTaskTableSrc & 0x000001ff) != 0) - return (MCD_TABLE_UNALIGNED); - - /* need to add code to make sure that every thing else is - aligned properly TBD. this is problematic if we init - more than once or after running tasks, need to add - variable to see if we have aleady init'd */ - entryPtr = MCD_realTaskTableSrc; - for (i = 0; i < NCHANNELS; i++) { - if (((entryPtr[i].varTab & (VAR_TAB_SIZE - 1)) != 0) || - ((entryPtr[i]. - FDTandFlags & (FUNCDESC_TAB_SIZE - 1)) != 0)) - return (MCD_TABLE_UNALIGNED); - } - - MCD_taskTable = MCD_realTaskTableSrc; - MCD_modelTaskTable = MCD_modelTaskTableSrc; - MCD_relocBuffDesc = MCD_singleBufDescs; - } - - /* Make all channels as totally inactive, and remember them as such: */ - - MCD_dmaBar->taskbar = (u32) MCD_taskTable; - for (i = 0; i < NCHANNELS; i++) { - MCD_dmaBar->taskControl[i] = 0x0; - MCD_chStatus[i] = MCD_NO_DMA; - } - - /* Set up pausing mechanism to inactive state: */ - /* no particular values yet for either comparator registers */ - MCD_dmaBar->debugComp1 = 0; - MCD_dmaBar->debugComp2 = 0; - MCD_dmaBar->debugControl = DBG_CTL_DISABLE; - MCD_dmaBar->debugStatus = DBG_KILL_ALL_STAT; - - /* enable or disable commbus prefetch, really need an ifdef or - something to keep from trying to set this in the 8220 */ - if ((flags & MCD_COMM_PREFETCH_EN) != 0) - MCD_dmaBar->ptdControl &= ~PTD_CTL_COMM_PREFETCH; - else - MCD_dmaBar->ptdControl |= PTD_CTL_COMM_PREFETCH; - - return (MCD_OK); -} - -/*********************** End of MCD_initDma() ***********************/ - -/********************************************************************/ -/* Function: MCD_dmaStatus - * Purpose: Returns the status of the DMA on the requested channel - * Arguments: channel - channel number - * Returns: Predefined status indicators - */ -int MCD_dmaStatus(int channel) -{ - u16 tcrValue; - - if ((channel < 0) || (channel >= NCHANNELS)) - return (MCD_CHANNEL_INVALID); - - tcrValue = MCD_dmaBar->taskControl[channel]; - if ((tcrValue & TASK_CTL_EN) == 0) { /* nothing running */ - /* if last reported with task enabled */ - if (MCD_chStatus[channel] == MCD_RUNNING - || MCD_chStatus[channel] == MCD_IDLE) - MCD_chStatus[channel] = MCD_DONE; - } else { /* something is running */ - - /* There are three possibilities: paused, running or idle. */ - if (MCD_chStatus[channel] == MCD_RUNNING - || MCD_chStatus[channel] == MCD_IDLE) { - MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT; - /* This register is selected to know which initiator is - actually asserted. */ - if ((MCD_dmaBar->ptdDebug >> channel) & 0x1) - MCD_chStatus[channel] = MCD_RUNNING; - else - MCD_chStatus[channel] = MCD_IDLE; - /* do not change the status if it is already paused. */ - } - } - return MCD_chStatus[channel]; -} - -/******************** End of MCD_dmaStatus() ************************/ - -/********************************************************************/ -/* Function: MCD_startDma - * Ppurpose: Starts a particular kind of DMA - * Arguments: - * srcAddr - the channel on which to run the DMA - * srcIncr - the address to move data from, or buffer-descriptor address - * destAddr - the amount to increment the source address per transfer - * destIncr - the address to move data to - * dmaSize - the amount to increment the destination address per transfer - * xferSize - the number bytes in of each data movement (1, 2, or 4) - * initiator - what device initiates the DMA - * priority - priority of the DMA - * flags - flags describing the DMA - * funcDesc - description of byte swapping, bit swapping, and CRC actions - * srcAddrVirt - virtual buffer descriptor address TBD - * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK - */ - -int MCD_startDma(int channel, s8 * srcAddr, s16 srcIncr, s8 * destAddr, - s16 destIncr, u32 dmaSize, u32 xferSize, u32 initiator, - int priority, u32 flags, u32 funcDesc -#ifdef MCD_NEED_ADDR_TRANS - s8 * srcAddrVirt -#endif - ) -{ - int srcRsdIncr, destRsdIncr; - int *cSave; - short xferSizeIncr; - int tcrCount = 0; -#ifdef MCD_INCLUDE_EU - u32 *realFuncArray; -#endif - - if ((channel < 0) || (channel >= NCHANNELS)) - return (MCD_CHANNEL_INVALID); - - /* tbd - need to determine the proper response to a bad funcDesc when - not including EU functions, for now, assign a benign funcDesc, but - maybe should return an error */ -#ifndef MCD_INCLUDE_EU - funcDesc = MCD_FUNC_NOEU1; -#endif - -#ifdef MCD_DEBUG - printf("startDma:Setting up params\n"); -#endif - /* Set us up for task-wise priority. We don't technically need to do - this on every start, but since the register involved is in the same - longword as other registers that users are in control of, setting - it more than once is probably preferable. That since the - documentation doesn't seem to be completely consistent about the - nature of the PTD control register. */ - MCD_dmaBar->ptdControl |= (u16) 0x8000; - - /* Not sure what we need to keep here rtm TBD */ -#if 1 - /* Calculate additional parameters to the regular DMA calls. */ - srcRsdIncr = srcIncr < 0 ? -1 : (srcIncr > 0 ? 1 : 0); - destRsdIncr = destIncr < 0 ? -1 : (destIncr > 0 ? 1 : 0); - - xferSizeIncr = (xferSize & 0xffff) | 0x20000000; - - /* Remember for each channel which variant is running. */ - MCD_remVariants.remSrcRsdIncr[channel] = srcRsdIncr; - MCD_remVariants.remDestRsdIncr[channel] = destRsdIncr; - MCD_remVariants.remDestIncr[channel] = destIncr; - MCD_remVariants.remSrcIncr[channel] = srcIncr; - MCD_remVariants.remXferSize[channel] = xferSize; -#endif - - cSave = - (int *)(MCD_taskTable[channel].contextSaveSpace) + CSAVE_OFFSET + - CURRBD; - -#ifdef MCD_INCLUDE_EU - /* may move this to EU specific calls */ - realFuncArray = - (u32 *) (MCD_taskTable[channel].FDTandFlags & 0xffffff00); - /* Modify the LURC's normal and byte-residue-loop functions according - to parameter. */ - realFuncArray[(LURC * 16)] = xferSize == 4 ? - funcDesc : xferSize == 2 ? - funcDesc & 0xfffff00f : funcDesc & 0xffff000f; - realFuncArray[(LURC * 16 + 1)] = - (funcDesc & MCD_BYTE_SWAP_KILLER) | MCD_NO_BYTE_SWAP_ATALL; -#endif - /* Write the initiator field in the TCR, and also set the - initiator-hold bit. Note that,due to a hardware quirk, this could - collide with an MDE access to the initiator-register file, so we - have to verify that the write reads back correctly. */ - - MCD_dmaBar->taskControl[channel] = - (initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM; - - while (((MCD_dmaBar->taskControl[channel] & 0x1fff) != - ((initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM)) - && (tcrCount < 1000)) { - tcrCount++; - /*MCD_dmaBar->ptd_tcr[channel] = (initiator << 8) | 0x0020; */ - MCD_dmaBar->taskControl[channel] = - (initiator << 8) | TASK_CTL_HIPRITSKEN | - TASK_CTL_HLDINITNUM; - } - - MCD_dmaBar->priority[channel] = (u8) priority & PRIORITY_PRI_MASK; - /* should be albe to handle this stuff with only one write to ts reg - - tbd */ - if (channel < 8 && channel >= 0) { - MCD_dmaBar->taskSize0 &= ~(0xf << (7 - channel) * 4); - MCD_dmaBar->taskSize0 |= - (xferSize & 3) << (((7 - channel) * 4) + 2); - MCD_dmaBar->taskSize0 |= (xferSize & 3) << ((7 - channel) * 4); - } else { - MCD_dmaBar->taskSize1 &= ~(0xf << (15 - channel) * 4); - MCD_dmaBar->taskSize1 |= - (xferSize & 3) << (((15 - channel) * 4) + 2); - MCD_dmaBar->taskSize1 |= (xferSize & 3) << ((15 - channel) * 4); - } - - /* setup task table flags/options which mostly control the line - buffers */ - MCD_taskTable[channel].FDTandFlags &= ~MCD_TT_FLAGS_MASK; - MCD_taskTable[channel].FDTandFlags |= (MCD_TT_FLAGS_MASK & flags); - - if (flags & MCD_FECTX_DMA) { - /* TDTStart and TDTEnd */ - MCD_taskTable[channel].TDTstart = - MCD_modelTaskTable[TASK_FECTX].TDTstart; - MCD_taskTable[channel].TDTend = - MCD_modelTaskTable[TASK_FECTX].TDTend; - MCD_startDmaENetXmit((char *)srcAddr, (char *)srcAddr, - (char *)destAddr, MCD_taskTable, - channel); - } else if (flags & MCD_FECRX_DMA) { - /* TDTStart and TDTEnd */ - MCD_taskTable[channel].TDTstart = - MCD_modelTaskTable[TASK_FECRX].TDTstart; - MCD_taskTable[channel].TDTend = - MCD_modelTaskTable[TASK_FECRX].TDTend; - MCD_startDmaENetRcv((char *)srcAddr, (char *)srcAddr, - (char *)destAddr, MCD_taskTable, - channel); - } else if (flags & MCD_SINGLE_DMA) { - /* this buffer descriptor is used for storing off initial - parameters for later progress query calculation and for the - DMA to write the resulting checksum. The DMA does not use - this to determine how to operate, that info is passed with - the init routine */ - MCD_relocBuffDesc[channel].srcAddr = srcAddr; - MCD_relocBuffDesc[channel].destAddr = destAddr; - - /* definitely not its final value */ - MCD_relocBuffDesc[channel].lastDestAddr = destAddr; - - MCD_relocBuffDesc[channel].dmaSize = dmaSize; - MCD_relocBuffDesc[channel].flags = 0; /* not used */ - MCD_relocBuffDesc[channel].csumResult = 0; /* not used */ - MCD_relocBuffDesc[channel].next = 0; /* not used */ - - /* Initialize the progress-querying stuff to show no - progress: */ - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[SRCPTR + CSAVE_OFFSET] = (int)srcAddr; - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[DESTPTR + CSAVE_OFFSET] = (int)destAddr; - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0; - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[CURRBD + CSAVE_OFFSET] = -(u32) & (MCD_relocBuffDesc[channel]); - /* tbd - need to keep the user from trying to call the EU - routine when MCD_INCLUDE_EU is not defined */ - if (funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2) { - /* TDTStart and TDTEnd */ - MCD_taskTable[channel].TDTstart = - MCD_modelTaskTable[TASK_SINGLENOEU].TDTstart; - MCD_taskTable[channel].TDTend = - MCD_modelTaskTable[TASK_SINGLENOEU].TDTend; - MCD_startDmaSingleNoEu((char *)srcAddr, srcIncr, - (char *)destAddr, destIncr, - (int)dmaSize, xferSizeIncr, - flags, (int *) - &(MCD_relocBuffDesc[channel]), - cSave, MCD_taskTable, channel); - } else { - /* TDTStart and TDTEnd */ - MCD_taskTable[channel].TDTstart = - MCD_modelTaskTable[TASK_SINGLEEU].TDTstart; - MCD_taskTable[channel].TDTend = - MCD_modelTaskTable[TASK_SINGLEEU].TDTend; - MCD_startDmaSingleEu((char *)srcAddr, srcIncr, - (char *)destAddr, destIncr, - (int)dmaSize, xferSizeIncr, - flags, (int *) - &(MCD_relocBuffDesc[channel]), - cSave, MCD_taskTable, channel); - } - } else { /* chained DMAS */ - /* Initialize the progress-querying stuff to show no - progress: */ -#if 1 - /* (!defined(MCD_NEED_ADDR_TRANS)) */ - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[SRCPTR + CSAVE_OFFSET] - = (int)((MCD_bufDesc *) srcAddr)->srcAddr; - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[DESTPTR + CSAVE_OFFSET] - = (int)((MCD_bufDesc *) srcAddr)->destAddr; -#else - /* if using address translation, need the virtual addr of the - first buffdesc */ - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[SRCPTR + CSAVE_OFFSET] - = (int)((MCD_bufDesc *) srcAddrVirt)->srcAddr; - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[DESTPTR + CSAVE_OFFSET] - = (int)((MCD_bufDesc *) srcAddrVirt)->destAddr; -#endif - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0; - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[CURRBD + CSAVE_OFFSET] = (u32) srcAddr; - - if (funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2) { - /*TDTStart and TDTEnd */ - MCD_taskTable[channel].TDTstart = - MCD_modelTaskTable[TASK_CHAINNOEU].TDTstart; - MCD_taskTable[channel].TDTend = - MCD_modelTaskTable[TASK_CHAINNOEU].TDTend; - MCD_startDmaChainNoEu((int *)srcAddr, srcIncr, - destIncr, xferSize, - xferSizeIncr, cSave, - MCD_taskTable, channel); - } else { - /*TDTStart and TDTEnd */ - MCD_taskTable[channel].TDTstart = - MCD_modelTaskTable[TASK_CHAINEU].TDTstart; - MCD_taskTable[channel].TDTend = - MCD_modelTaskTable[TASK_CHAINEU].TDTend; - MCD_startDmaChainEu((int *)srcAddr, srcIncr, destIncr, - xferSize, xferSizeIncr, cSave, - MCD_taskTable, channel); - } - } - MCD_chStatus[channel] = MCD_IDLE; - return (MCD_OK); -} - -/************************ End of MCD_startDma() *********************/ - -/********************************************************************/ -/* Function: MCD_XferProgrQuery - * Purpose: Returns progress of DMA on requested channel - * Arguments: channel - channel to retrieve progress for - * progRep - pointer to user supplied MCD_XferProg struct - * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK - * - * Notes: - * MCD_XferProgrQuery() upon completing or after aborting a DMA, or - * while the DMA is in progress, this function returns the first - * DMA-destination address not (or not yet) used in the DMA. When - * encountering a non-ready buffer descriptor, the information for - * the last completed descriptor is returned. - * - * MCD_XferProgQuery() has to avoid the possibility of getting - * partially-updated information in the event that we should happen - * to query DMA progress just as the DMA is updating it. It does that - * by taking advantage of the fact context is not saved frequently for - * the most part. We therefore read it at least twice until we get the - * same information twice in a row. - * - * Because a small, but not insignificant, amount of time is required - * to write out the progress-query information, especially upon - * completion of the DMA, it would be wise to guarantee some time lag - * between successive readings of the progress-query information. - */ - -/* How many iterations of the loop below to execute to stabilize values */ -#define STABTIME 0 - -int MCD_XferProgrQuery(int channel, MCD_XferProg * progRep) -{ - MCD_XferProg prevRep; - int again; /* true if we are to try again to ge - consistent results */ - int i; /* used as a time-waste counter */ - int destDiffBytes; /* Total no of bytes that we think actually - got xfered. */ - int numIterations; /* number of iterations */ - int bytesNotXfered; /* bytes that did not get xfered. */ - s8 *LWAlignedInitDestAddr, *LWAlignedCurrDestAddr; - int subModVal, addModVal; /* Mode values to added and subtracted - from the final destAddr */ - - if ((channel < 0) || (channel >= NCHANNELS)) - return (MCD_CHANNEL_INVALID); - - /* Read a trial value for the progress-reporting values */ - prevRep.lastSrcAddr = - (s8 *) ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[SRCPTR + CSAVE_OFFSET]; - prevRep.lastDestAddr = - (s8 *) ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[DESTPTR + CSAVE_OFFSET]; - prevRep.dmaSize = - ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DCOUNT + - CSAVE_OFFSET]; - prevRep.currBufDesc = - (MCD_bufDesc *) ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[CURRBD + CSAVE_OFFSET]; - /* Repeatedly reread those values until they match previous values: */ - do { - /* Waste a little bit of time to ensure stability: */ - for (i = 0; i < STABTIME; i++) { - /* make sure this loop does something so that it - doesn't get optimized out */ - i += i >> 2; - } - /* Check them again: */ - progRep->lastSrcAddr = - (s8 *) ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[SRCPTR + CSAVE_OFFSET]; - progRep->lastDestAddr = - (s8 *) ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[DESTPTR + CSAVE_OFFSET]; - progRep->dmaSize = - ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[DCOUNT + CSAVE_OFFSET]; - progRep->currBufDesc = - (MCD_bufDesc *) ((volatile int *)MCD_taskTable[channel]. - contextSaveSpace)[CURRBD + CSAVE_OFFSET]; - /* See if they match: */ - if (prevRep.lastSrcAddr != progRep->lastSrcAddr - || prevRep.lastDestAddr != progRep->lastDestAddr - || prevRep.dmaSize != progRep->dmaSize - || prevRep.currBufDesc != progRep->currBufDesc) { - /* If they don't match, remember previous values and - try again: */ - prevRep.lastSrcAddr = progRep->lastSrcAddr; - prevRep.lastDestAddr = progRep->lastDestAddr; - prevRep.dmaSize = progRep->dmaSize; - prevRep.currBufDesc = progRep->currBufDesc; - again = MCD_TRUE; - } else - again = MCD_FALSE; - } while (again == MCD_TRUE); - - /* Update the dCount, srcAddr and destAddr */ - /* To calculate dmaCount, we consider destination address. C - overs M1,P1,Z for destination */ - switch (MCD_remVariants.remDestRsdIncr[channel]) { - case MINUS1: - subModVal = - ((int)progRep-> - lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - - 1); - addModVal = - ((int)progRep->currBufDesc-> - destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1); - LWAlignedInitDestAddr = - (progRep->currBufDesc->destAddr) - addModVal; - LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal; - destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr; - bytesNotXfered = - (destDiffBytes / MCD_remVariants.remDestIncr[channel]) * - (MCD_remVariants.remDestIncr[channel] - + MCD_remVariants.remXferSize[channel]); - progRep->dmaSize = - destDiffBytes - bytesNotXfered + addModVal - subModVal; - break; - case ZERO: - progRep->lastDestAddr = progRep->currBufDesc->destAddr; - break; - case PLUS1: - /* This value has to be subtracted from the final - calculated dCount. */ - subModVal = - ((int)progRep->currBufDesc-> - destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1); - /* These bytes are already in lastDestAddr. */ - addModVal = - ((int)progRep-> - lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - - 1); - LWAlignedInitDestAddr = - (progRep->currBufDesc->destAddr) - subModVal; - LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal; - destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr); - numIterations = - (LWAlignedCurrDestAddr - - LWAlignedInitDestAddr) / - MCD_remVariants.remDestIncr[channel]; - bytesNotXfered = - numIterations * (MCD_remVariants.remDestIncr[channel] - - MCD_remVariants.remXferSize[channel]); - progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal; - break; - default: - break; - } - - /* This covers M1,P1,Z for source */ - switch (MCD_remVariants.remSrcRsdIncr[channel]) { - case MINUS1: - progRep->lastSrcAddr = - progRep->currBufDesc->srcAddr + - (MCD_remVariants.remSrcIncr[channel] * - (progRep->dmaSize / MCD_remVariants.remXferSize[channel])); - break; - case ZERO: - progRep->lastSrcAddr = progRep->currBufDesc->srcAddr; - break; - case PLUS1: - progRep->lastSrcAddr = - progRep->currBufDesc->srcAddr + - (MCD_remVariants.remSrcIncr[channel] * - (progRep->dmaSize / MCD_remVariants.remXferSize[channel])); - break; - default: - break; - } - - return (MCD_OK); -} - -/******************* End of MCD_XferProgrQuery() ********************/ - -/********************************************************************/ -/* MCD_resmActions() does the majority of the actions of a DMA resume. - * It is called from MCD_killDma() and MCD_resumeDma(). It has to be - * a separate function because the kill function has to negate the task - * enable before resuming it, but the resume function has to do nothing - * if there is no DMA on that channel (i.e., if the enable bit is 0). - */ -static void MCD_resmActions(int channel) -{ - MCD_dmaBar->debugControl = DBG_CTL_DISABLE; - MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus; - /* This register is selected to know which initiator is - actually asserted. */ - MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT; - - if ((MCD_dmaBar->ptdDebug >> channel) & 0x1) - MCD_chStatus[channel] = MCD_RUNNING; - else - MCD_chStatus[channel] = MCD_IDLE; -} - -/********************* End of MCD_resmActions() *********************/ - -/********************************************************************/ -/* Function: MCD_killDma - * Purpose: Halt the DMA on the requested channel, without any - * intention of resuming the DMA. - * Arguments: channel - requested channel - * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK - * - * Notes: - * A DMA may be killed from any state, including paused state, and it - * always goes to the MCD_HALTED state even if it is killed while in - * the MCD_NO_DMA or MCD_IDLE states. - */ -int MCD_killDma(int channel) -{ - /* MCD_XferProg progRep; */ - - if ((channel < 0) || (channel >= NCHANNELS)) - return (MCD_CHANNEL_INVALID); - - MCD_dmaBar->taskControl[channel] = 0x0; - MCD_resumeDma(channel); - /* - * This must be after the write to the TCR so that the task doesn't - * start up again momentarily, and before the status assignment so - * as to override whatever MCD_resumeDma() may do to the channel - * status. - */ - MCD_chStatus[channel] = MCD_HALTED; - - /* - * Update the current buffer descriptor's lastDestAddr field - * - * MCD_XferProgrQuery (channel, &progRep); - * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr; - */ - return (MCD_OK); -} - -/************************ End of MCD_killDma() **********************/ - -/********************************************************************/ -/* Function: MCD_continDma - * Purpose: Continue a DMA which as stopped due to encountering an - * unready buffer descriptor. - * Arguments: channel - channel to continue the DMA on - * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK - * - * Notes: - * This routine does not check to see if there is a task which can - * be continued. Also this routine should not be used with single DMAs. - */ -int MCD_continDma(int channel) -{ - if ((channel < 0) || (channel >= NCHANNELS)) - return (MCD_CHANNEL_INVALID); - - MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN; - MCD_chStatus[channel] = MCD_RUNNING; - - return (MCD_OK); -} - -/********************** End of MCD_continDma() **********************/ - -/********************************************************************* - * MCD_pauseDma() and MCD_resumeDma() below use the DMA's debug unit - * to freeze a task and resume it. We freeze a task by breakpointing - * on the stated task. That is, not any specific place in the task, - * but any time that task executes. In particular, when that task - * executes, we want to freeze that task and only that task. - * - * The bits of the debug control register influence interrupts vs. - * breakpoints as follows: - * - Bits 14 and 0 enable or disable debug functions. If enabled, you - * will get the interrupt but you may or may not get a breakpoint. - * - Bits 2 and 1 decide whether you also get a breakpoint in addition - * to an interrupt. - * - * The debug unit can do these actions in response to either internally - * detected breakpoint conditions from the comparators, or in response - * to the external breakpoint pin, or both. - * - Bits 14 and 1 perform the above-described functions for - * internally-generated conditions, i.e., the debug comparators. - * - Bits 0 and 2 perform the above-described functions for external - * conditions, i.e., the breakpoint external pin. - * - * Note that, although you "always" get the interrupt when you turn - * the debug functions, the interrupt can nevertheless, if desired, be - * masked by the corresponding bit in the PTD's IMR. Note also that - * this means that bits 14 and 0 must enable debug functions before - * bits 1 and 2, respectively, have any effect. - * - * NOTE: It's extremely important to not pause more than one DMA channel - * at a time. - ********************************************************************/ - -/********************************************************************/ -/* Function: MCD_pauseDma - * Purpose: Pauses the DMA on a given channel (if any DMA is running - * on that channel). - * Arguments: channel - * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK - */ -int MCD_pauseDma(int channel) -{ - /* MCD_XferProg progRep; */ - - if ((channel < 0) || (channel >= NCHANNELS)) - return (MCD_CHANNEL_INVALID); - - if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN) { - MCD_dmaBar->debugComp1 = channel; - MCD_dmaBar->debugControl = - DBG_CTL_ENABLE | (1 << (channel + 16)); - MCD_chStatus[channel] = MCD_PAUSED; - - /* - * Update the current buffer descriptor's lastDestAddr field - * - * MCD_XferProgrQuery (channel, &progRep); - * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr; - */ - } - return (MCD_OK); -} - -/************************* End of MCD_pauseDma() ********************/ - -/********************************************************************/ -/* Function: MCD_resumeDma - * Purpose: Resumes the DMA on a given channel (if any DMA is - * running on that channel). - * Arguments: channel - channel on which to resume DMA - * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK - */ -int MCD_resumeDma(int channel) -{ - if ((channel < 0) || (channel >= NCHANNELS)) - return (MCD_CHANNEL_INVALID); - - if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN) - MCD_resmActions(channel); - - return (MCD_OK); -} - -/************************ End of MCD_resumeDma() ********************/ - -/********************************************************************/ -/* Function: MCD_csumQuery - * Purpose: Provide the checksum after performing a non-chained DMA - * Arguments: channel - channel to report on - * csum - pointer to where to write the checksum/CRC - * Returns: MCD_ERROR if the channel is invalid, else MCD_OK - * - * Notes: - * - */ -int MCD_csumQuery(int channel, u32 * csum) -{ -#ifdef MCD_INCLUDE_EU - if ((channel < 0) || (channel >= NCHANNELS)) - return (MCD_CHANNEL_INVALID); - - *csum = MCD_relocBuffDesc[channel].csumResult; - return (MCD_OK); -#else - return (MCD_ERROR); -#endif -} - -/*********************** End of MCD_resumeDma() *********************/ - -/********************************************************************/ -/* Function: MCD_getCodeSize - * Purpose: Provide the size requirements of the microcoded tasks - * Returns: Size in bytes - */ -int MCD_getCodeSize(void) -{ -#ifdef MCD_INCLUDE_EU - return (0x2b5c); -#else - return (0x173c); -#endif -} - -/********************** End of MCD_getCodeSize() ********************/ - -/********************************************************************/ -/* Function: MCD_getVersion - * Purpose: Provide the version string and number - * Arguments: longVersion - user supplied pointer to a pointer to a char - * which points to the version string - * Returns: Version number and version string (by reference) - */ -char MCD_versionString[] = "Multi-channel DMA API Alpha v0.3 (2004-04-26)"; -#define MCD_REV_MAJOR 0x00 -#define MCD_REV_MINOR 0x03 - -int MCD_getVersion(char **longVersion) -{ - *longVersion = MCD_versionString; - return ((MCD_REV_MAJOR << 8) | MCD_REV_MINOR); -} - -/********************** End of MCD_getVersion() *********************/ - -/********************************************************************/ -/* Private version of memcpy() - * Note that everything this is used for is longword-aligned. - */ -static void MCD_memcpy(int *dest, int *src, u32 size) -{ - u32 i; - - for (i = 0; i < size; i += sizeof(int), dest++, src++) - *dest = *src; -} diff --git a/drivers/dma/MCD_tasks.c b/drivers/dma/MCD_tasks.c deleted file mode 100644 index 453d95413d..0000000000 --- a/drivers/dma/MCD_tasks.c +++ /dev/null @@ -1,2413 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. - */ - -/* Contains task code and structures for Multi-channel DMA */ - -#include <common.h> - -#include <MCD_dma.h> - -u32 MCD_varTab0[]; -u32 MCD_varTab1[]; -u32 MCD_varTab2[]; -u32 MCD_varTab3[]; -u32 MCD_varTab4[]; -u32 MCD_varTab5[]; -u32 MCD_varTab6[]; -u32 MCD_varTab7[]; -u32 MCD_varTab8[]; -u32 MCD_varTab9[]; -u32 MCD_varTab10[]; -u32 MCD_varTab11[]; -u32 MCD_varTab12[]; -u32 MCD_varTab13[]; -u32 MCD_varTab14[]; -u32 MCD_varTab15[]; - -u32 MCD_funcDescTab0[]; -#ifdef MCD_INCLUDE_EU -u32 MCD_funcDescTab1[]; -u32 MCD_funcDescTab2[]; -u32 MCD_funcDescTab3[]; -u32 MCD_funcDescTab4[]; -u32 MCD_funcDescTab5[]; -u32 MCD_funcDescTab6[]; -u32 MCD_funcDescTab7[]; -u32 MCD_funcDescTab8[]; -u32 MCD_funcDescTab9[]; -u32 MCD_funcDescTab10[]; -u32 MCD_funcDescTab11[]; -u32 MCD_funcDescTab12[]; -u32 MCD_funcDescTab13[]; -u32 MCD_funcDescTab14[]; -u32 MCD_funcDescTab15[]; -#endif - -u32 MCD_contextSave0[]; -u32 MCD_contextSave1[]; -u32 MCD_contextSave2[]; -u32 MCD_contextSave3[]; -u32 MCD_contextSave4[]; -u32 MCD_contextSave5[]; -u32 MCD_contextSave6[]; -u32 MCD_contextSave7[]; -u32 MCD_contextSave8[]; -u32 MCD_contextSave9[]; -u32 MCD_contextSave10[]; -u32 MCD_contextSave11[]; -u32 MCD_contextSave12[]; -u32 MCD_contextSave13[]; -u32 MCD_contextSave14[]; -u32 MCD_contextSave15[]; - -u32 MCD_realTaskTableSrc[] = { - 0x00000000, - 0x00000000, - (u32) MCD_varTab0, /* Task 0 Variable Table */ - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ - 0x00000000, - 0x00000000, - (u32) MCD_contextSave0, /* Task 0 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab1, /* Task 1 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab1, /* Task 1 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave1, /* Task 1 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab2, /* Task 2 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab2, /* Task 2 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave2, /* Task 2 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab3, /* Task 3 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab3, /* Task 3 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave3, /* Task 3 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab4, /* Task 4 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab4, /* Task 4 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave4, /* Task 4 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab5, /* Task 5 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab5, /* Task 5 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave5, /* Task 5 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab6, /* Task 6 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab6, /* Task 6 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave6, /* Task 6 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab7, /* Task 7 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab7, /* Task 7 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave7, /* Task 7 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab8, /* Task 8 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab8, /* Task 8 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave8, /* Task 8 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab9, /* Task 9 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab9, /* Task 9 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave9, /* Task 9 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab10, /* Task 10 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab10, /* Task 10 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave10, /* Task 10 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab11, /* Task 11 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab11, /* Task 11 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave11, /* Task 11 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab12, /* Task 12 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab12, /* Task 12 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave12, /* Task 12 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab13, /* Task 13 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab13, /* Task 13 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave13, /* Task 13 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab14, /* Task 14 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab14, /* Task 14 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave14, /* Task 14 context save space */ - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_varTab15, /* Task 15 Variable Table */ -#ifdef MCD_INCLUDE_EU - (u32) MCD_funcDescTab15, /* Task 15 Fn Desc. Table & Flags */ -#else - (u32) MCD_funcDescTab0, /* Task 0 Fn Desc. Table & Flags */ -#endif - 0x00000000, - 0x00000000, - (u32) MCD_contextSave15, /* Task 15 context save space */ - 0x00000000, -}; - -u32 MCD_varTab0[] = { /* Task 0 Variable Table */ - 0x00000000, /* var[0] */ - 0x00000000, /* var[1] */ - 0x00000000, /* var[2] */ - 0x00000000, /* var[3] */ - 0x00000000, /* var[4] */ - 0x00000000, /* var[5] */ - 0x00000000, /* var[6] */ - 0x00000000, /* var[7] */ - 0x00000000, /* var[8] */ - 0x00000000, /* var[9] */ - 0x00000000, /* var[10] */ - 0x00000000, /* var[11] */ - 0x00000000, /* var[12] */ - 0x00000000, /* var[13] */ - 0x00000000, /* var[14] */ - 0x00000000, /* var[15] */ - 0x00000000, /* var[16] */ - 0x00000000, /* var[17] */ - 0x00000000, /* var[18] */ - 0x00000000, /* var[19] */ - 0x00000000, /* var[20] */ - 0x00000000, /* var[21] */ - 0x00000000, /* var[22] */ - 0x00000000, /* var[23] */ - 0xe0000000, /* inc[0] */ - 0x20000000, /* inc[1] */ - 0x2000ffff, /* inc[2] */ - 0x00000000, /* inc[3] */ - 0x00000000, /* inc[4] */ - 0x00000000, /* inc[5] */ - 0x00000000, /* inc[6] */ - 0x00000000, /* inc[7] */ -}; - -u32 MCD_varTab1[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab2[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab3[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab4[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab5[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab6[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab7[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab8[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab9[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab10[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab11[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab12[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab13[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab14[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_varTab15[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xe0000000, - 0x20000000, - 0x2000ffff, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_funcDescTab0[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -#ifdef MCD_INCLUDE_EU -u32 MCD_funcDescTab1[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab2[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab3[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab4[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab5[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab6[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab7[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab8[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab9[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab10[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab11[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab12[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab13[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab14[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; - -u32 MCD_funcDescTab15[] = { - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0xa0045670, - 0xa0000000, - 0xa0000000, - 0x20000000, - 0x21800000, - 0x21e00000, - 0x20400000, - 0x20500000, - 0x205a0000, - 0x20a00000, - 0x202fa000, - 0x202f9000, - 0x202ea000, - 0x202da000, - 0x202e2000, - 0x202f2000, -}; -#endif /*MCD_INCLUDE_EU */ - -u32 MCD_contextSave0[128]; /* Task 0 context save space */ -u32 MCD_contextSave1[128]; /* Task 1 context save space */ -u32 MCD_contextSave2[128]; /* Task 2 context save space */ -u32 MCD_contextSave3[128]; /* Task 3 context save space */ -u32 MCD_contextSave4[128]; /* Task 4 context save space */ -u32 MCD_contextSave5[128]; /* Task 5 context save space */ -u32 MCD_contextSave6[128]; /* Task 6 context save space */ -u32 MCD_contextSave7[128]; /* Task 7 context save space */ -u32 MCD_contextSave8[128]; /* Task 8 context save space */ -u32 MCD_contextSave9[128]; /* Task 9 context save space */ -u32 MCD_contextSave10[128]; /* Task 10 context save space */ -u32 MCD_contextSave11[128]; /* Task 11 context save space */ -u32 MCD_contextSave12[128]; /* Task 12 context save space */ -u32 MCD_contextSave13[128]; /* Task 13 context save space */ -u32 MCD_contextSave14[128]; /* Task 14 context save space */ -u32 MCD_contextSave15[128]; /* Task 15 context save space */ - -u32 MCD_ChainNoEu_TDT[]; -u32 MCD_SingleNoEu_TDT[]; -#ifdef MCD_INCLUDE_EU -u32 MCD_ChainEu_TDT[]; -u32 MCD_SingleEu_TDT[]; -#endif -u32 MCD_ENetRcv_TDT[]; -u32 MCD_ENetXmit_TDT[]; - -u32 MCD_modelTaskTableSrc[] = { - (u32) MCD_ChainNoEu_TDT, - (u32) & ((u8 *) MCD_ChainNoEu_TDT)[0x0000016c], - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_SingleNoEu_TDT, - (u32) & ((u8 *) MCD_SingleNoEu_TDT)[0x000000d4], - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -#ifdef MCD_INCLUDE_EU - (u32) MCD_ChainEu_TDT, - (u32) & ((u8 *) MCD_ChainEu_TDT)[0x000001b4], - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_SingleEu_TDT, - (u32) & ((u8 *) MCD_SingleEu_TDT)[0x00000124], - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -#endif - (u32) MCD_ENetRcv_TDT, - (u32) & ((u8 *) MCD_ENetRcv_TDT)[0x0000009c], - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - (u32) MCD_ENetXmit_TDT, - (u32) & ((u8 *) MCD_ENetXmit_TDT)[0x000000d0], - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -u32 MCD_ChainNoEu_TDT[] = { - 0x80004000, - 0x8118801b, - 0xb8c60018, - 0x10002b10, - 0x7000000d, - 0x018cf89f, - 0x6000000a, - 0x080cf89f, - 0x000001f8, - 0x98180364, - 0x8118801b, - 0xf8c6001a, - 0xb8c6601b, - 0x10002710, - 0x00000f18, - 0xb8c6001d, - 0x10001310, - 0x60000007, - 0x014cf88b, - 0x98c6001c, - 0x00000710, - 0x98c70018, - 0x10001f10, - 0x0000c818, - 0x000001f8, - 0xc1476018, - 0xc003231d, - 0x811a601b, - 0xc1862102, - 0x849be009, - 0x03fed7b8, - 0xda9b001b, - 0x9b9be01b, - 0x1000cb20, - 0x70000006, - 0x088cf88f, - 0x1000cb28, - 0x70000006, - 0x088cf88f, - 0x1000cb30, - 0x70000006, - 0x088cf88f, - 0x1000cb38, - 0x0000c728, - 0x000001f8, - 0xc1476018, - 0xc003241d, - 0x811a601b, - 0xda9b001b, - 0x9b9be01b, - 0x0000d3a0, - 0xc1862102, - 0x849be009, - 0x0bfed7b8, - 0xda9b001b, - 0x9b9be01b, - 0x1000cb20, - 0x70000006, - 0x088cf88f, - 0x1000cb28, - 0x70000006, - 0x088cf88f, - 0x1000cb30, - 0x70000006, - 0x088cf88f, - 0x1000cb38, - 0x0000c728, - 0x000001f8, - 0x8118801b, - 0xd8c60018, - 0x98c6601c, - 0x6000000b, - 0x0c8cfc9f, - 0x000001f8, - 0xa146001e, - 0x10000b08, - 0x10002050, - 0xb8c60018, - 0x10002b10, - 0x7000000a, - 0x080cf89f, - 0x6000000d, - 0x018cf89f, - 0x000001f8, - 0x8618801b, - 0x7000000e, - 0x084cf21f, - 0xd8990336, - 0x8019801b, - 0x040001f8, - 0x000001f8, - 0x000001f8, -}; - -u32 MCD_SingleNoEu_TDT[] = { - 0x8198001b, - 0x7000000d, - 0x080cf81f, - 0x8198801b, - 0x6000000e, - 0x084cf85f, - 0x000001f8, - 0x8298001b, - 0x7000000d, - 0x010cf81f, - 0x6000000e, - 0x018cf81f, - 0xc202601b, - 0xc002221c, - 0x809a601b, - 0xc10420c2, - 0x839be009, - 0x03fed7b8, - 0xda9b001b, - 0x9b9be01b, - 0x70000006, - 0x088cf889, - 0x1000cb28, - 0x70000006, - 0x088cf889, - 0x1000cb30, - 0x70000006, - 0x088cf889, - 0x0000cb38, - 0x000001f8, - 0xc202601b, - 0xc002229c, - 0x809a601b, - 0xda9b001b, - 0x9b9be01b, - 0x0000d3a0, - 0xc10420c2, - 0x839be009, - 0x0bfed7b8, - 0xda9b001b, - 0x9b9be01b, - 0x70000006, - 0x088cf889, - 0x1000cb28, - 0x70000006, - 0x088cf889, - 0x1000cb30, - 0x70000006, - 0x088cf889, - 0x0000cb38, - 0x000001f8, - 0xc318022d, - 0x8018801b, - 0x040001f8, -}; - -#ifdef MCD_INCLUDE_EU -u32 MCD_ChainEu_TDT[] = { - 0x80004000, - 0x8198801b, - 0xb8c68018, - 0x10002f10, - 0x7000000d, - 0x01ccf89f, - 0x6000000a, - 0x080cf89f, - 0x000001f8, - 0x981803a4, - 0x8198801b, - 0xf8c6801a, - 0xb8c6e01b, - 0x10002b10, - 0x00001318, - 0xb8c6801d, - 0x10001710, - 0x60000007, - 0x018cf88c, - 0x98c6801c, - 0x00000b10, - 0x98c78018, - 0x10002310, - 0x0000c820, - 0x000001f8, - 0x8698801b, - 0x7000000f, - 0x084cf2df, - 0xd899042d, - 0x8019801b, - 0x60000003, - 0x2cd7c7df, - 0xd8990364, - 0x8019801b, - 0x60000003, - 0x2c17c7df, - 0x000001f8, - 0xc1c7e018, - 0xc003a35e, - 0x819a601b, - 0xc206a142, - 0x851be009, - 0x63fe0000, - 0x0d4cfddf, - 0xda9b001b, - 0x9b9be01b, - 0x70000002, - 0x004cf81f, - 0x1000cb20, - 0x70000006, - 0x088cf891, - 0x1000cb28, - 0x70000006, - 0x088cf891, - 0x1000cb30, - 0x70000006, - 0x088cf891, - 0x1000cb38, - 0x0000c728, - 0x000001f8, - 0xc1c7e018, - 0xc003a49e, - 0x819a601b, - 0xda9b001b, - 0x9b9be01b, - 0x0000d3a0, - 0xc206a142, - 0x851be009, - 0x6bfe0000, - 0x0d4cfddf, - 0xda9b001b, - 0x9b9be01b, - 0x70000002, - 0x004cf81f, - 0x1000cb20, - 0x70000006, - 0x088cf891, - 0x1000cb28, - 0x70000006, - 0x088cf891, - 0x1000cb30, - 0x70000006, - 0x088cf891, - 0x1000cb38, - 0x0000c728, - 0x000001f8, - 0x8198801b, - 0xd8c68018, - 0x98c6e01c, - 0x6000000b, - 0x0c8cfc9f, - 0x0000cc08, - 0xa1c6801e, - 0x10000f08, - 0x10002458, - 0xb8c68018, - 0x10002f10, - 0x7000000a, - 0x080cf89f, - 0x6000000d, - 0x01ccf89f, - 0x000001f8, - 0x8698801b, - 0x7000000e, - 0x084cf25f, - 0xd899037f, - 0x8019801b, - 0x040001f8, - 0x000001f8, - 0x000001f8, -}; - -u32 MCD_SingleEu_TDT[] = { - 0x8218001b, - 0x7000000d, - 0x080cf81f, - 0x8218801b, - 0x6000000e, - 0x084cf85f, - 0x000001f8, - 0x8318001b, - 0x7000000d, - 0x014cf81f, - 0x6000000e, - 0x01ccf81f, - 0x8498001b, - 0x7000000f, - 0x080cf19f, - 0xd81882a4, - 0x8019001b, - 0x60000003, - 0x2c97c7df, - 0xd818826d, - 0x8019001b, - 0x60000003, - 0x2c17c7df, - 0x000001f8, - 0xc282e01b, - 0xc002a25e, - 0x811a601b, - 0xc184a102, - 0x841be009, - 0x63fe0000, - 0x0d4cfddf, - 0xda9b001b, - 0x9b9be01b, - 0x70000002, - 0x004cf99f, - 0x70000006, - 0x088cf88b, - 0x1000cb28, - 0x70000006, - 0x088cf88b, - 0x1000cb30, - 0x70000006, - 0x088cf88b, - 0x0000cb38, - 0x000001f8, - 0xc282e01b, - 0xc002a31e, - 0x811a601b, - 0xda9b001b, - 0x9b9be01b, - 0x0000d3a0, - 0xc184a102, - 0x841be009, - 0x6bfe0000, - 0x0d4cfddf, - 0xda9b001b, - 0x9b9be01b, - 0x70000002, - 0x004cf99f, - 0x70000006, - 0x088cf88b, - 0x1000cb28, - 0x70000006, - 0x088cf88b, - 0x1000cb30, - 0x70000006, - 0x088cf88b, - 0x0000cb38, - 0x000001f8, - 0x8144801c, - 0x0000c008, - 0xc398027f, - 0x8018801b, - 0x040001f8, -}; -#endif -u32 MCD_ENetRcv_TDT[] = { - 0x80004000, - 0x81988000, - 0x10000788, - 0x6000000a, - 0x080cf05f, - 0x98180209, - 0x81c40004, - 0x7000000e, - 0x010cf05f, - 0x7000000c, - 0x01ccf05f, - 0x70000004, - 0x014cf049, - 0x70000004, - 0x004cf04a, - 0x00000b88, - 0xc4030150, - 0x8119e012, - 0x03e0cf90, - 0x81188000, - 0x000ac788, - 0xc4030000, - 0x8199e000, - 0x70000004, - 0x084cfc8b, - 0x60000005, - 0x0cccf841, - 0x81c60000, - 0xc399021b, - 0x80198000, - 0x00008400, - 0x00000f08, - 0x81988000, - 0x10000788, - 0x6000000a, - 0x080cf05f, - 0xc2188209, - 0x80190000, - 0x040001f8, - 0x000001f8, -}; - -u32 MCD_ENetXmit_TDT[] = { - 0x80004000, - 0x81988000, - 0x10000788, - 0x6000000a, - 0x080cf05f, - 0x98180309, - 0x80004003, - 0x81c60004, - 0x7000000e, - 0x014cf05f, - 0x7000000c, - 0x028cf05f, - 0x7000000d, - 0x018cf05f, - 0x70000004, - 0x01ccf04d, - 0x10000b90, - 0x60000004, - 0x020cf0a1, - 0xc3188312, - 0x83c70000, - 0x00001f10, - 0xc583a3c3, - 0x81042325, - 0x03e0c798, - 0xd8990000, - 0x9999e000, - 0x000acf98, - 0xd8992306, - 0x9999e03f, - 0x03eac798, - 0xd8990000, - 0x9999e000, - 0x000acf98, - 0xd8990000, - 0x99832302, - 0x0beac798, - 0x81988000, - 0x6000000b, - 0x0c4cfc5f, - 0x81c80000, - 0xc5190312, - 0x80198000, - 0x00008400, - 0x00000f08, - 0x81988000, - 0x10000788, - 0x6000000a, - 0x080cf05f, - 0xc2988309, - 0x80190000, - 0x040001f8, - 0x000001f8, -}; - -#ifdef MCD_INCLUDE_EU -MCD_bufDesc MCD_singleBufDescs[NCHANNELS]; -#endif diff --git a/drivers/dma/MCD_tasksInit.c b/drivers/dma/MCD_tasksInit.c deleted file mode 100644 index 079cd0af3c..0000000000 --- a/drivers/dma/MCD_tasksInit.c +++ /dev/null @@ -1,225 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. - */ - -#include <common.h> - -/* Functions for initializing variable tables of different types of tasks. */ - -/* - * Do not edit! - */ - -#include <MCD_dma.h> - -extern dmaRegs *MCD_dmaBar; - -/* Task 0 */ - -void MCD_startDmaChainNoEu(int *currBD, short srcIncr, short destIncr, - int xferSize, short xferSizeIncr, int *cSave, - volatile TaskTableEntry * taskTable, int channel) -{ - volatile TaskTableEntry *taskChan = taskTable + channel; - - MCD_SET_VAR(taskChan, 2, (u32) currBD); /* var[2] */ - MCD_SET_VAR(taskChan, 25, (u32) (0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */ - MCD_SET_VAR(taskChan, 24, (u32) (0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */ - MCD_SET_VAR(taskChan, 11, (u32) xferSize); /* var[11] */ - MCD_SET_VAR(taskChan, 26, (u32) (0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */ - MCD_SET_VAR(taskChan, 0, (u32) cSave); /* var[0] */ - MCD_SET_VAR(taskChan, 1, (u32) 0x00000000); /* var[1] */ - MCD_SET_VAR(taskChan, 3, (u32) 0x00000000); /* var[3] */ - MCD_SET_VAR(taskChan, 4, (u32) 0x00000000); /* var[4] */ - MCD_SET_VAR(taskChan, 5, (u32) 0x00000000); /* var[5] */ - MCD_SET_VAR(taskChan, 6, (u32) 0x00000000); /* var[6] */ - MCD_SET_VAR(taskChan, 7, (u32) 0x00000000); /* var[7] */ - MCD_SET_VAR(taskChan, 8, (u32) 0x00000000); /* var[8] */ - MCD_SET_VAR(taskChan, 9, (u32) 0x00000000); /* var[9] */ - MCD_SET_VAR(taskChan, 10, (u32) 0x00000000); /* var[10] */ - MCD_SET_VAR(taskChan, 12, (u32) 0x00000000); /* var[12] */ - MCD_SET_VAR(taskChan, 13, (u32) 0x80000000); /* var[13] */ - MCD_SET_VAR(taskChan, 14, (u32) 0x00000010); /* var[14] */ - MCD_SET_VAR(taskChan, 15, (u32) 0x00000004); /* var[15] */ - MCD_SET_VAR(taskChan, 16, (u32) 0x08000000); /* var[16] */ - MCD_SET_VAR(taskChan, 27, (u32) 0x00000000); /* inc[3] */ - MCD_SET_VAR(taskChan, 28, (u32) 0x80000000); /* inc[4] */ - MCD_SET_VAR(taskChan, 29, (u32) 0x80000001); /* inc[5] */ - MCD_SET_VAR(taskChan, 30, (u32) 0x40000000); /* inc[6] */ - - /* Set the task's Enable bit in its Task Control Register */ - MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; -} - -/* Task 1 */ - -void MCD_startDmaSingleNoEu(char *srcAddr, short srcIncr, char *destAddr, - short destIncr, int dmaSize, short xferSizeIncr, - int flags, int *currBD, int *cSave, - volatile TaskTableEntry * taskTable, int channel) -{ - volatile TaskTableEntry *taskChan = taskTable + channel; - - MCD_SET_VAR(taskChan, 7, (u32) srcAddr); /* var[7] */ - MCD_SET_VAR(taskChan, 25, (u32) (0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */ - MCD_SET_VAR(taskChan, 2, (u32) destAddr); /* var[2] */ - MCD_SET_VAR(taskChan, 24, (u32) (0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */ - MCD_SET_VAR(taskChan, 3, (u32) dmaSize); /* var[3] */ - MCD_SET_VAR(taskChan, 26, (u32) (0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */ - MCD_SET_VAR(taskChan, 5, (u32) flags); /* var[5] */ - MCD_SET_VAR(taskChan, 1, (u32) currBD); /* var[1] */ - MCD_SET_VAR(taskChan, 0, (u32) cSave); /* var[0] */ - MCD_SET_VAR(taskChan, 4, (u32) 0x00000000); /* var[4] */ - MCD_SET_VAR(taskChan, 6, (u32) 0x00000000); /* var[6] */ - MCD_SET_VAR(taskChan, 8, (u32) 0x00000000); /* var[8] */ - MCD_SET_VAR(taskChan, 9, (u32) 0x00000004); /* var[9] */ - MCD_SET_VAR(taskChan, 10, (u32) 0x08000000); /* var[10] */ - MCD_SET_VAR(taskChan, 27, (u32) 0x00000000); /* inc[3] */ - MCD_SET_VAR(taskChan, 28, (u32) 0x80000001); /* inc[4] */ - MCD_SET_VAR(taskChan, 29, (u32) 0x40000000); /* inc[5] */ - - /* Set the task's Enable bit in its Task Control Register */ - MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; -} - -/* Task 2 */ - -void MCD_startDmaChainEu(int *currBD, short srcIncr, short destIncr, - int xferSize, short xferSizeIncr, int *cSave, - volatile TaskTableEntry * taskTable, int channel) -{ - volatile TaskTableEntry *taskChan = taskTable + channel; - - MCD_SET_VAR(taskChan, 3, (u32) currBD); /* var[3] */ - MCD_SET_VAR(taskChan, 25, (u32) (0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */ - MCD_SET_VAR(taskChan, 24, (u32) (0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */ - MCD_SET_VAR(taskChan, 12, (u32) xferSize); /* var[12] */ - MCD_SET_VAR(taskChan, 26, (u32) (0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */ - MCD_SET_VAR(taskChan, 0, (u32) cSave); /* var[0] */ - MCD_SET_VAR(taskChan, 1, (u32) 0x00000000); /* var[1] */ - MCD_SET_VAR(taskChan, 2, (u32) 0x00000000); /* var[2] */ - MCD_SET_VAR(taskChan, 4, (u32) 0x00000000); /* var[4] */ - MCD_SET_VAR(taskChan, 5, (u32) 0x00000000); /* var[5] */ - MCD_SET_VAR(taskChan, 6, (u32) 0x00000000); /* var[6] */ - MCD_SET_VAR(taskChan, 7, (u32) 0x00000000); /* var[7] */ - MCD_SET_VAR(taskChan, 8, (u32) 0x00000000); /* var[8] */ - MCD_SET_VAR(taskChan, 9, (u32) 0x00000000); /* var[9] */ - MCD_SET_VAR(taskChan, 10, (u32) 0x00000000); /* var[10] */ - MCD_SET_VAR(taskChan, 11, (u32) 0x00000000); /* var[11] */ - MCD_SET_VAR(taskChan, 13, (u32) 0x00000000); /* var[13] */ - MCD_SET_VAR(taskChan, 14, (u32) 0x80000000); /* var[14] */ - MCD_SET_VAR(taskChan, 15, (u32) 0x00000010); /* var[15] */ - MCD_SET_VAR(taskChan, 16, (u32) 0x00000001); /* var[16] */ - MCD_SET_VAR(taskChan, 17, (u32) 0x00000004); /* var[17] */ - MCD_SET_VAR(taskChan, 18, (u32) 0x08000000); /* var[18] */ - MCD_SET_VAR(taskChan, 27, (u32) 0x00000000); /* inc[3] */ - MCD_SET_VAR(taskChan, 28, (u32) 0x80000000); /* inc[4] */ - MCD_SET_VAR(taskChan, 29, (u32) 0xc0000000); /* inc[5] */ - MCD_SET_VAR(taskChan, 30, (u32) 0x80000001); /* inc[6] */ - MCD_SET_VAR(taskChan, 31, (u32) 0x40000000); /* inc[7] */ - - /* Set the task's Enable bit in its Task Control Register */ - MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; -} - -/* Task 3 */ - -void MCD_startDmaSingleEu(char *srcAddr, short srcIncr, char *destAddr, - short destIncr, int dmaSize, short xferSizeIncr, - int flags, int *currBD, int *cSave, - volatile TaskTableEntry * taskTable, int channel) -{ - volatile TaskTableEntry *taskChan = taskTable + channel; - - MCD_SET_VAR(taskChan, 8, (u32) srcAddr); /* var[8] */ - MCD_SET_VAR(taskChan, 25, (u32) (0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */ - MCD_SET_VAR(taskChan, 3, (u32) destAddr); /* var[3] */ - MCD_SET_VAR(taskChan, 24, (u32) (0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */ - MCD_SET_VAR(taskChan, 4, (u32) dmaSize); /* var[4] */ - MCD_SET_VAR(taskChan, 26, (u32) (0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */ - MCD_SET_VAR(taskChan, 6, (u32) flags); /* var[6] */ - MCD_SET_VAR(taskChan, 2, (u32) currBD); /* var[2] */ - MCD_SET_VAR(taskChan, 0, (u32) cSave); /* var[0] */ - MCD_SET_VAR(taskChan, 1, (u32) 0x00000000); /* var[1] */ - MCD_SET_VAR(taskChan, 5, (u32) 0x00000000); /* var[5] */ - MCD_SET_VAR(taskChan, 7, (u32) 0x00000000); /* var[7] */ - MCD_SET_VAR(taskChan, 9, (u32) 0x00000000); /* var[9] */ - MCD_SET_VAR(taskChan, 10, (u32) 0x00000001); /* var[10] */ - MCD_SET_VAR(taskChan, 11, (u32) 0x00000004); /* var[11] */ - MCD_SET_VAR(taskChan, 12, (u32) 0x08000000); /* var[12] */ - MCD_SET_VAR(taskChan, 27, (u32) 0x00000000); /* inc[3] */ - MCD_SET_VAR(taskChan, 28, (u32) 0xc0000000); /* inc[4] */ - MCD_SET_VAR(taskChan, 29, (u32) 0x80000000); /* inc[5] */ - MCD_SET_VAR(taskChan, 30, (u32) 0x80000001); /* inc[6] */ - MCD_SET_VAR(taskChan, 31, (u32) 0x40000000); /* inc[7] */ - - /* Set the task's Enable bit in its Task Control Register */ - MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; -} - -/* Task 4 */ - -void MCD_startDmaENetRcv(char *bDBase, char *currBD, char *rcvFifoPtr, - volatile TaskTableEntry * taskTable, int channel) -{ - volatile TaskTableEntry *taskChan = taskTable + channel; - - MCD_SET_VAR(taskChan, 0, (u32) bDBase); /* var[0] */ - MCD_SET_VAR(taskChan, 3, (u32) currBD); /* var[3] */ - MCD_SET_VAR(taskChan, 6, (u32) rcvFifoPtr); /* var[6] */ - MCD_SET_VAR(taskChan, 1, (u32) 0x00000000); /* var[1] */ - MCD_SET_VAR(taskChan, 2, (u32) 0x00000000); /* var[2] */ - MCD_SET_VAR(taskChan, 4, (u32) 0x00000000); /* var[4] */ - MCD_SET_VAR(taskChan, 5, (u32) 0x00000000); /* var[5] */ - MCD_SET_VAR(taskChan, 7, (u32) 0x00000000); /* var[7] */ - MCD_SET_VAR(taskChan, 8, (u32) 0x00000000); /* var[8] */ - MCD_SET_VAR(taskChan, 9, (u32) 0x0000ffff); /* var[9] */ - MCD_SET_VAR(taskChan, 10, (u32) 0x30000000); /* var[10] */ - MCD_SET_VAR(taskChan, 11, (u32) 0x0fffffff); /* var[11] */ - MCD_SET_VAR(taskChan, 12, (u32) 0x00000008); /* var[12] */ - MCD_SET_VAR(taskChan, 24, (u32) 0x00000000); /* inc[0] */ - MCD_SET_VAR(taskChan, 25, (u32) 0x60000000); /* inc[1] */ - MCD_SET_VAR(taskChan, 26, (u32) 0x20000004); /* inc[2] */ - MCD_SET_VAR(taskChan, 27, (u32) 0x40000000); /* inc[3] */ - - /* Set the task's Enable bit in its Task Control Register */ - MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; -} - -/* Task 5 */ - -void MCD_startDmaENetXmit(char *bDBase, char *currBD, char *xmitFifoPtr, - volatile TaskTableEntry * taskTable, int channel) -{ - volatile TaskTableEntry *taskChan = taskTable + channel; - - MCD_SET_VAR(taskChan, 0, (u32) bDBase); /* var[0] */ - MCD_SET_VAR(taskChan, 3, (u32) currBD); /* var[3] */ - MCD_SET_VAR(taskChan, 11, (u32) xmitFifoPtr); /* var[11] */ - MCD_SET_VAR(taskChan, 1, (u32) 0x00000000); /* var[1] */ - MCD_SET_VAR(taskChan, 2, (u32) 0x00000000); /* var[2] */ - MCD_SET_VAR(taskChan, 4, (u32) 0x00000000); /* var[4] */ - MCD_SET_VAR(taskChan, 5, (u32) 0x00000000); /* var[5] */ - MCD_SET_VAR(taskChan, 6, (u32) 0x00000000); /* var[6] */ - MCD_SET_VAR(taskChan, 7, (u32) 0x00000000); /* var[7] */ - MCD_SET_VAR(taskChan, 8, (u32) 0x00000000); /* var[8] */ - MCD_SET_VAR(taskChan, 9, (u32) 0x00000000); /* var[9] */ - MCD_SET_VAR(taskChan, 10, (u32) 0x00000000); /* var[10] */ - MCD_SET_VAR(taskChan, 12, (u32) 0x00000000); /* var[12] */ - MCD_SET_VAR(taskChan, 13, (u32) 0x0000ffff); /* var[13] */ - MCD_SET_VAR(taskChan, 14, (u32) 0xffffffff); /* var[14] */ - MCD_SET_VAR(taskChan, 15, (u32) 0x00000004); /* var[15] */ - MCD_SET_VAR(taskChan, 16, (u32) 0x00000008); /* var[16] */ - MCD_SET_VAR(taskChan, 24, (u32) 0x00000000); /* inc[0] */ - MCD_SET_VAR(taskChan, 25, (u32) 0x60000000); /* inc[1] */ - MCD_SET_VAR(taskChan, 26, (u32) 0x40000000); /* inc[2] */ - MCD_SET_VAR(taskChan, 27, (u32) 0xc000fffc); /* inc[3] */ - MCD_SET_VAR(taskChan, 28, (u32) 0xe0000004); /* inc[4] */ - MCD_SET_VAR(taskChan, 29, (u32) 0x80000000); /* inc[5] */ - MCD_SET_VAR(taskChan, 30, (u32) 0x4000ffff); /* inc[6] */ - MCD_SET_VAR(taskChan, 31, (u32) 0xe0000001); /* inc[7] */ - - /* Set the task's Enable bit in its Task Control Register */ - MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; -} diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index a75572fe5d..48811eaaeb 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -5,7 +5,6 @@ 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_BCM6348_IUDMA) += bcm6348-iudma.o obj-$(CONFIG_FSL_DMA) += fsl_dma.o diff --git a/drivers/dma/ti/Makefile b/drivers/dma/ti/Makefile index 6807eb8e8b..f4e0271efb 100644 --- a/drivers/dma/ti/Makefile +++ b/drivers/dma/ti/Makefile @@ -8,3 +8,4 @@ k3-psil-data-$(CONFIG_SOC_K3_J721E) += k3-psil-j721e.o k3-psil-data-$(CONFIG_SOC_K3_J721S2) += k3-psil-j721s2.o k3-psil-data-$(CONFIG_SOC_K3_AM642) += k3-psil-am64.o k3-psil-data-$(CONFIG_SOC_K3_AM625) += k3-psil-am62.o +k3-psil-data-$(CONFIG_SOC_K3_AM62A7) += k3-psil-am62a.o diff --git a/drivers/dma/ti/k3-psil-am62a.c b/drivers/dma/ti/k3-psil-am62a.c new file mode 100644 index 0000000000..ca9d71f914 --- /dev/null +++ b/drivers/dma/ti/k3-psil-am62a.c @@ -0,0 +1,196 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2022 Texas Instruments Incorporated - https://www.ti.com + */ + +#include <linux/kernel.h> + +#include "k3-psil-priv.h" + +#define PSIL_PDMA_XY_TR(x) \ + { \ + .thread_id = x, \ + .ep_config = { \ + .ep_type = PSIL_EP_PDMA_XY, \ + .mapped_channel_id = -1, \ + .default_flow_id = -1, \ + }, \ + } + +#define PSIL_PDMA_XY_PKT(x) \ + { \ + .thread_id = x, \ + .ep_config = { \ + .ep_type = PSIL_EP_PDMA_XY, \ + .mapped_channel_id = -1, \ + .default_flow_id = -1, \ + .pkt_mode = 1, \ + }, \ + } + +#define PSIL_ETHERNET(x, ch, flow_base, flow_cnt) \ + { \ + .thread_id = x, \ + .ep_config = { \ + .ep_type = PSIL_EP_NATIVE, \ + .pkt_mode = 1, \ + .needs_epib = 1, \ + .psd_size = 16, \ + .mapped_channel_id = ch, \ + .flow_start = flow_base, \ + .flow_num = flow_cnt, \ + .default_flow_id = flow_base, \ + }, \ + } + +#define PSIL_SAUL(x, ch, flow_base, flow_cnt, default_flow, tx) \ + { \ + .thread_id = x, \ + .ep_config = { \ + .ep_type = PSIL_EP_NATIVE, \ + .pkt_mode = 1, \ + .needs_epib = 1, \ + .psd_size = 64, \ + .mapped_channel_id = ch, \ + .flow_start = flow_base, \ + .flow_num = flow_cnt, \ + .default_flow_id = default_flow, \ + .notdpkt = tx, \ + }, \ + } + +#define PSIL_PDMA_MCASP(x) \ + { \ + .thread_id = x, \ + .ep_config = { \ + .ep_type = PSIL_EP_PDMA_XY, \ + .pdma_acc32 = 1, \ + .pdma_burst = 1, \ + }, \ + } + +#define PSIL_CSI2RX(x) \ + { \ + .thread_id = x, \ + .ep_config = { \ + .ep_type = PSIL_EP_NATIVE, \ + }, \ + } + +/* PSI-L source thread IDs, used for RX (DMA_DEV_TO_MEM) */ +static struct psil_ep am62a_src_ep_map[] = { + /* SAUL */ + PSIL_SAUL(0x7504, 20, 35, 8, 35, 0), + PSIL_SAUL(0x7505, 21, 35, 8, 36, 0), + PSIL_SAUL(0x7506, 22, 43, 8, 43, 0), + PSIL_SAUL(0x7507, 23, 43, 8, 44, 0), + /* PDMA_MAIN0 - SPI0-3 */ + PSIL_PDMA_XY_PKT(0x4302), + PSIL_PDMA_XY_PKT(0x4303), + PSIL_PDMA_XY_PKT(0x4304), + PSIL_PDMA_XY_PKT(0x4305), + PSIL_PDMA_XY_PKT(0x4306), + PSIL_PDMA_XY_PKT(0x4307), + PSIL_PDMA_XY_PKT(0x4308), + PSIL_PDMA_XY_PKT(0x4309), + PSIL_PDMA_XY_PKT(0x430a), + PSIL_PDMA_XY_PKT(0x430b), + PSIL_PDMA_XY_PKT(0x430c), + PSIL_PDMA_XY_PKT(0x430d), + /* PDMA_MAIN1 - UART0-6 */ + PSIL_PDMA_XY_PKT(0x4400), + PSIL_PDMA_XY_PKT(0x4401), + PSIL_PDMA_XY_PKT(0x4402), + PSIL_PDMA_XY_PKT(0x4403), + PSIL_PDMA_XY_PKT(0x4404), + PSIL_PDMA_XY_PKT(0x4405), + PSIL_PDMA_XY_PKT(0x4406), + /* PDMA_MAIN2 - MCASP0-2 */ + PSIL_PDMA_MCASP(0x4500), + PSIL_PDMA_MCASP(0x4501), + PSIL_PDMA_MCASP(0x4502), + /* CPSW3G */ + PSIL_ETHERNET(0x4600, 19, 19, 16), + /* CSI2RX */ + PSIL_CSI2RX(0x5000), + PSIL_CSI2RX(0x5001), + PSIL_CSI2RX(0x5002), + PSIL_CSI2RX(0x5003), + PSIL_CSI2RX(0x5004), + PSIL_CSI2RX(0x5005), + PSIL_CSI2RX(0x5006), + PSIL_CSI2RX(0x5007), + PSIL_CSI2RX(0x5008), + PSIL_CSI2RX(0x5009), + PSIL_CSI2RX(0x500a), + PSIL_CSI2RX(0x500b), + PSIL_CSI2RX(0x500c), + PSIL_CSI2RX(0x500d), + PSIL_CSI2RX(0x500e), + PSIL_CSI2RX(0x500f), + PSIL_CSI2RX(0x5010), + PSIL_CSI2RX(0x5011), + PSIL_CSI2RX(0x5012), + PSIL_CSI2RX(0x5013), + PSIL_CSI2RX(0x5014), + PSIL_CSI2RX(0x5015), + PSIL_CSI2RX(0x5016), + PSIL_CSI2RX(0x5017), + PSIL_CSI2RX(0x5018), + PSIL_CSI2RX(0x5019), + PSIL_CSI2RX(0x501a), + PSIL_CSI2RX(0x501b), + PSIL_CSI2RX(0x501c), + PSIL_CSI2RX(0x501d), + PSIL_CSI2RX(0x501e), + PSIL_CSI2RX(0x501f), +}; + +/* PSI-L destination thread IDs, used for TX (DMA_MEM_TO_DEV) */ +static struct psil_ep am62a_dst_ep_map[] = { + /* SAUL */ + PSIL_SAUL(0xf500, 27, 83, 8, 83, 1), + PSIL_SAUL(0xf501, 28, 91, 8, 91, 1), + /* PDMA_MAIN0 - SPI0-3 */ + PSIL_PDMA_XY_PKT(0xc302), + PSIL_PDMA_XY_PKT(0xc303), + PSIL_PDMA_XY_PKT(0xc304), + PSIL_PDMA_XY_PKT(0xc305), + PSIL_PDMA_XY_PKT(0xc306), + PSIL_PDMA_XY_PKT(0xc307), + PSIL_PDMA_XY_PKT(0xc308), + PSIL_PDMA_XY_PKT(0xc309), + PSIL_PDMA_XY_PKT(0xc30a), + PSIL_PDMA_XY_PKT(0xc30b), + PSIL_PDMA_XY_PKT(0xc30c), + PSIL_PDMA_XY_PKT(0xc30d), + /* PDMA_MAIN1 - UART0-6 */ + PSIL_PDMA_XY_PKT(0xc400), + PSIL_PDMA_XY_PKT(0xc401), + PSIL_PDMA_XY_PKT(0xc402), + PSIL_PDMA_XY_PKT(0xc403), + PSIL_PDMA_XY_PKT(0xc404), + PSIL_PDMA_XY_PKT(0xc405), + PSIL_PDMA_XY_PKT(0xc406), + /* PDMA_MAIN2 - MCASP0-2 */ + PSIL_PDMA_MCASP(0xc500), + PSIL_PDMA_MCASP(0xc501), + PSIL_PDMA_MCASP(0xc502), + /* CPSW3G */ + PSIL_ETHERNET(0xc600, 19, 19, 8), + PSIL_ETHERNET(0xc601, 20, 27, 8), + PSIL_ETHERNET(0xc602, 21, 35, 8), + PSIL_ETHERNET(0xc603, 22, 43, 8), + PSIL_ETHERNET(0xc604, 23, 51, 8), + PSIL_ETHERNET(0xc605, 24, 59, 8), + PSIL_ETHERNET(0xc606, 25, 67, 8), + PSIL_ETHERNET(0xc607, 26, 75, 8), +}; + +struct psil_ep_map am62a_ep_map = { + .name = "am62a", + .src = am62a_src_ep_map, + .src_count = ARRAY_SIZE(am62a_src_ep_map), + .dst = am62a_dst_ep_map, + .dst_count = ARRAY_SIZE(am62a_dst_ep_map), +}; diff --git a/drivers/dma/ti/k3-psil-priv.h b/drivers/dma/ti/k3-psil-priv.h index 563bc57e20..83f873b84c 100644 --- a/drivers/dma/ti/k3-psil-priv.h +++ b/drivers/dma/ti/k3-psil-priv.h @@ -42,5 +42,6 @@ extern struct psil_ep_map j721e_ep_map; extern struct psil_ep_map j721s2_ep_map; extern struct psil_ep_map am64_ep_map; extern struct psil_ep_map am62_ep_map; +extern struct psil_ep_map am62a_ep_map; #endif /* K3_PSIL_PRIV_H_ */ diff --git a/drivers/dma/ti/k3-psil.c b/drivers/dma/ti/k3-psil.c index 963321aa1e..d4d4fede8f 100644 --- a/drivers/dma/ti/k3-psil.c +++ b/drivers/dma/ti/k3-psil.c @@ -26,6 +26,8 @@ struct psil_endpoint_config *psil_get_ep_config(u32 thread_id) soc_ep_map = &am64_ep_map; else if (IS_ENABLED(CONFIG_SOC_K3_AM625)) soc_ep_map = &am62_ep_map; + else if (IS_ENABLED(CONFIG_SOC_K3_AM62A7)) + soc_ep_map = &am62a_ep_map; } if (thread_id & K3_PSIL_DST_THREAD_ID_OFFSET && soc_ep_map->dst) { diff --git a/drivers/fastboot/Kconfig b/drivers/fastboot/Kconfig index 837c6f1180..11fc0fe1c8 100644 --- a/drivers/fastboot/Kconfig +++ b/drivers/fastboot/Kconfig @@ -1,4 +1,5 @@ menu "Fastboot support" + depends on CMDLINE config FASTBOOT bool diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c index 4e9d9b719c..3576b06772 100644 --- a/drivers/fastboot/fb_common.c +++ b/drivers/fastboot/fb_common.c @@ -91,6 +91,7 @@ void fastboot_okay(const char *reason, char *response) */ int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) { + int ret; static const char * const boot_cmds[] = { [FASTBOOT_REBOOT_REASON_BOOTLOADER] = "bootonce-bootloader", [FASTBOOT_REBOOT_REASON_FASTBOOTD] = "boot-fastboot", @@ -105,7 +106,18 @@ int __weak fastboot_set_reboot_flag(enum fastboot_reboot_reason reason) if (reason >= FASTBOOT_REBOOT_REASONS_COUNT) return -EINVAL; - return bcb_write_reboot_reason(mmc_dev, "misc", boot_cmds[reason]); + ret = bcb_find_partition_and_load("mmc", mmc_dev, "misc"); + if (ret) + goto out; + + ret = bcb_set(BCB_FIELD_COMMAND, boot_cmds[reason]); + if (ret) + goto out; + + ret = bcb_store(); +out: + bcb_reset(); + return ret; } /** diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 8ea15c7ed3..dfad798a2e 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -8,6 +8,7 @@ #include <common.h> #include <cpu_func.h> #include <dm.h> +#include <dm/device_compat.h> #include <dm/lists.h> #include <log.h> #include <zynqmp_firmware.h> @@ -290,10 +291,31 @@ int zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) static int zynqmp_power_probe(struct udevice *dev) { + struct udevice *ipi_dev; + ofnode ipi_node; int ret; debug("%s, (dev=%p)\n", __func__, dev); + /* + * Probe all IPI parent node driver. It is important to have IPI + * devices available when requested by mbox_get_by* API. + * If IPI device isn't available, then mailbox request fails and + * that causes system boot failure. + * To avoid this make sure all IPI parent drivers are probed here, + * and IPI parent driver binds each child node to mailbox driver. + * This way mbox_get_by_* API will have correct mailbox device + * driver probed. + */ + ofnode_for_each_compatible_node(ipi_node, "xlnx,zynqmp-ipi-mailbox") { + ret = uclass_get_device_by_ofnode(UCLASS_NOP, ipi_node, &ipi_dev); + if (ret) { + dev_err(dev, "failed to get IPI device from node %s\n", + ofnode_get_name(ipi_node)); + return ret; + } + } + ret = mbox_get_by_name(dev, "tx", &zynqmp_power.tx_chan); if (ret) { debug("%s: Cannot find tx mailbox\n", __func__); diff --git a/drivers/firmware/scmi/sandbox-scmi_agent.c b/drivers/firmware/scmi/sandbox-scmi_agent.c index d131809626..cc9011c731 100644 --- a/drivers/firmware/scmi/sandbox-scmi_agent.c +++ b/drivers/firmware/scmi/sandbox-scmi_agent.c @@ -66,10 +66,10 @@ struct scmi_channel { }; static u8 protocols[] = { - SCMI_PROTOCOL_ID_POWER_DOMAIN, - SCMI_PROTOCOL_ID_CLOCK, - SCMI_PROTOCOL_ID_RESET_DOMAIN, - SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN, + CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN, (SCMI_PROTOCOL_ID_POWER_DOMAIN,)) + CONFIG_IS_ENABLED(CLK_SCMI, (SCMI_PROTOCOL_ID_CLOCK,)) + CONFIG_IS_ENABLED(RESET_SCMI, (SCMI_PROTOCOL_ID_RESET_DOMAIN,)) + CONFIG_IS_ENABLED(DM_REGULATOR_SCMI, (SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN,)) }; #define NUM_PROTOCOLS ARRAY_SIZE(protocols) @@ -1124,6 +1124,13 @@ unsigned int sandbox_scmi_channel_id(struct udevice *dev) return chan->channel_id; } +static int sandbox_proto_not_supported(struct scmi_msg *msg) +{ + *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED; + + return 0; +} + static int sandbox_scmi_test_process_msg(struct udevice *dev, struct scmi_channel *channel, struct scmi_msg *msg) @@ -1160,6 +1167,9 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev, } break; case SCMI_PROTOCOL_ID_POWER_DOMAIN: + if (!CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN)) + return sandbox_proto_not_supported(msg); + switch (msg->message_id) { case SCMI_PROTOCOL_VERSION: return sandbox_scmi_pwd_protocol_version(dev, msg); @@ -1180,6 +1190,9 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev, } break; case SCMI_PROTOCOL_ID_CLOCK: + if (!CONFIG_IS_ENABLED(CLK_SCMI)) + return sandbox_proto_not_supported(msg); + switch (msg->message_id) { case SCMI_PROTOCOL_ATTRIBUTES: return sandbox_scmi_clock_protocol_attribs(dev, msg); @@ -1196,6 +1209,9 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev, } break; case SCMI_PROTOCOL_ID_RESET_DOMAIN: + if (!CONFIG_IS_ENABLED(RESET_SCMI)) + return sandbox_proto_not_supported(msg); + switch (msg->message_id) { case SCMI_RESET_DOMAIN_ATTRIBUTES: return sandbox_scmi_rd_attribs(dev, msg); @@ -1206,6 +1222,9 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev, } break; case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN: + if (!CONFIG_IS_ENABLED(DM_REGULATOR_SCMI)) + return sandbox_proto_not_supported(msg); + switch (msg->message_id) { case SCMI_VOLTAGE_DOMAIN_ATTRIBUTES: return sandbox_scmi_voltd_attribs(dev, msg); @@ -1224,8 +1243,7 @@ static int sandbox_scmi_test_process_msg(struct udevice *dev, case SCMI_PROTOCOL_ID_SYSTEM: case SCMI_PROTOCOL_ID_PERF: case SCMI_PROTOCOL_ID_SENSOR: - *(u32 *)msg->out_msg = SCMI_NOT_SUPPORTED; - return 0; + return sandbox_proto_not_supported(msg); default: break; } diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c index facb5b06ff..603e2bb40a 100644 --- a/drivers/firmware/scmi/sandbox-scmi_devices.c +++ b/drivers/firmware/scmi/sandbox-scmi_devices.c @@ -62,12 +62,13 @@ static int sandbox_scmi_devices_remove(struct udevice *dev) if (!devices) return 0; - for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) { - int ret2 = reset_free(devices->reset + n); + if (CONFIG_IS_ENABLED(RESET_SCMI)) + for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) { + int ret2 = reset_free(devices->reset + n); - if (ret2 && !ret) - ret = ret2; - } + if (ret2 && !ret) + ret = ret2; + } return ret; } @@ -89,39 +90,53 @@ static int sandbox_scmi_devices_probe(struct udevice *dev) .regul_count = SCMI_TEST_DEVICES_VOLTD_COUNT, }; - ret = power_domain_get_by_index(dev, priv->devices.pwdom, 0); - if (ret) { - dev_err(dev, "%s: Failed on power domain\n", __func__); - return ret; - } - - for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) { - ret = clk_get_by_index(dev, n, priv->devices.clk + n); + if (CONFIG_IS_ENABLED(SCMI_POWER_DOMAIN)) { + ret = power_domain_get_by_index(dev, priv->devices.pwdom, 0); if (ret) { - dev_err(dev, "%s: Failed on clk %zu\n", __func__, n); + dev_err(dev, "%s: Failed on power domain\n", __func__); return ret; } } - for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) { - ret = reset_get_by_index(dev, n, priv->devices.reset + n); - if (ret) { - dev_err(dev, "%s: Failed on reset %zu\n", __func__, n); - goto err_reset; + if (CONFIG_IS_ENABLED(CLK_SCMI)) { + for (n = 0; n < SCMI_TEST_DEVICES_CLK_COUNT; n++) { + ret = clk_get_by_index(dev, n, priv->devices.clk + n); + if (ret) { + dev_err(dev, "%s: Failed on clk %zu\n", + __func__, n); + return ret; + } } } - for (n = 0; n < SCMI_TEST_DEVICES_VOLTD_COUNT; n++) { - char name[32]; - - ret = snprintf(name, sizeof(name), "regul%zu-supply", n); - assert(ret >= 0 && ret < sizeof(name)); + if (CONFIG_IS_ENABLED(RESET_SCMI)) { + for (n = 0; n < SCMI_TEST_DEVICES_RD_COUNT; n++) { + ret = reset_get_by_index(dev, n, + priv->devices.reset + n); + if (ret) { + dev_err(dev, "%s: Failed on reset %zu\n", + __func__, n); + goto err_reset; + } + } + } - ret = device_get_supply_regulator(dev, name, - priv->devices.regul + n); - if (ret) { - dev_err(dev, "%s: Failed on voltd %zu\n", __func__, n); - goto err_regul; + if (CONFIG_IS_ENABLED(DM_REGULATOR_SCMI)) { + for (n = 0; n < SCMI_TEST_DEVICES_VOLTD_COUNT; n++) { + char name[32]; + + ret = snprintf(name, sizeof(name), "regul%zu-supply", + n); + assert(ret >= 0 && ret < sizeof(name)); + + ret = device_get_supply_regulator(dev, name, + priv->devices.regul + + n); + if (ret) { + dev_err(dev, "%s: Failed on voltd %zu\n", + __func__, n); + goto err_regul; + } } } @@ -130,8 +145,9 @@ static int sandbox_scmi_devices_probe(struct udevice *dev) err_regul: n = SCMI_TEST_DEVICES_RD_COUNT; err_reset: - for (; n > 0; n--) - reset_free(priv->devices.reset + n - 1); + if (CONFIG_IS_ENABLED(RESET_SCMI)) + for (; n > 0; n--) + reset_free(priv->devices.reset + n - 1); return ret; } diff --git a/drivers/i2c/stm32f7_i2c.c b/drivers/i2c/stm32f7_i2c.c index b6c71789ee..eaa1d69289 100644 --- a/drivers/i2c/stm32f7_i2c.c +++ b/drivers/i2c/stm32f7_i2c.c @@ -20,6 +20,7 @@ #include <linux/err.h> #include <linux/io.h> #include <linux/printk.h> +#include <linux/time.h> /* STM32 I2C registers */ struct stm32_i2c_regs { @@ -121,8 +122,6 @@ struct stm32_i2c_regs { #define STM32_SCLH_MAX BIT(8) #define STM32_SCLL_MAX BIT(8) -#define STM32_NSEC_PER_SEC 1000000000L - /** * struct stm32_i2c_spec - private i2c specification timing * @rate: I2C bus speed (Hz) @@ -591,7 +590,7 @@ static int stm32_i2c_choose_solution(u32 i2cclk, struct stm32_i2c_timings *s) { struct stm32_i2c_timings *v; - u32 i2cbus = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, + u32 i2cbus = DIV_ROUND_CLOSEST(NSEC_PER_SEC, setup->speed_freq); u32 clk_error_prev = i2cbus; u32 clk_min, clk_max; @@ -607,8 +606,8 @@ static int stm32_i2c_choose_solution(u32 i2cclk, dnf_delay = setup->dnf * i2cclk; tsync = af_delay_min + dnf_delay + (2 * i2cclk); - clk_max = STM32_NSEC_PER_SEC / specs->rate_min; - clk_min = STM32_NSEC_PER_SEC / specs->rate_max; + clk_max = NSEC_PER_SEC / specs->rate_min; + clk_min = NSEC_PER_SEC / specs->rate_max; /* * Among Prescaler possibilities discovered above figures out SCL Low @@ -686,7 +685,7 @@ static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, const struct stm32_i2c_spec *specs; struct stm32_i2c_timings *v, *_v; struct list_head solutions; - u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, setup->clock_src); + u32 i2cclk = DIV_ROUND_CLOSEST(NSEC_PER_SEC, setup->clock_src); int ret; specs = get_specs(setup->speed_freq); diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig index 996b757e6d..9837960198 100644 --- a/drivers/led/Kconfig +++ b/drivers/led/Kconfig @@ -49,6 +49,14 @@ config LED_CORTINA This option enables support for LEDs connected to the Cortina Access CAxxxx SOCs. +config LED_LP5562 + bool "LED Support for LP5562" + depends on LED && DM_I2C + help + This option enables support for LEDs connected to the TI LP5562 + 4 channel I2C LED controller. Driver fully supports blink on the + B/G/R LEDs. White LED can blink, but re-uses the period from blue. + config LED_PWM bool "LED PWM" depends on LED && DM_PWM diff --git a/drivers/led/Makefile b/drivers/led/Makefile index 49ae91961d..2bcb858908 100644 --- a/drivers/led/Makefile +++ b/drivers/led/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_LED_BCM6858) += led_bcm6858.o obj-$(CONFIG_LED_PWM) += led_pwm.o obj-$(CONFIG_$(SPL_)LED_GPIO) += led_gpio.o obj-$(CONFIG_LED_CORTINA) += led_cortina.o +obj-$(CONFIG_LED_LP5562) += led_lp5562.o diff --git a/drivers/led/led-uclass.c b/drivers/led/led-uclass.c index 68ca3c2970..a4be56fc25 100644 --- a/drivers/led/led-uclass.c +++ b/drivers/led/led-uclass.c @@ -11,9 +11,27 @@ #include <errno.h> #include <led.h> #include <dm/device-internal.h> +#include <dm/lists.h> #include <dm/root.h> #include <dm/uclass-internal.h> +int led_bind_generic(struct udevice *parent, const char *driver_name) +{ + struct udevice *dev; + ofnode node; + int ret; + + dev_for_each_subnode(node, parent) { + ret = device_bind_driver_to_node(parent, driver_name, + ofnode_get_name(node), + node, &dev); + if (ret) + return ret; + } + + return 0; +} + int led_get_by_label(const char *label, struct udevice **devp) { struct udevice *dev; @@ -71,8 +89,10 @@ static int led_post_bind(struct udevice *dev) struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev); const char *default_state; - uc_plat->label = dev_read_string(dev, "label"); if (!uc_plat->label) + uc_plat->label = dev_read_string(dev, "label"); + + if (!uc_plat->label && !dev_read_string(dev, "compatible")) uc_plat->label = ofnode_get_name(dev_ofnode(dev)); uc_plat->default_state = LEDST_COUNT; diff --git a/drivers/led/led_gpio.c b/drivers/led/led_gpio.c index fbed151b5d..71421de628 100644 --- a/drivers/led/led_gpio.c +++ b/drivers/led/led_gpio.c @@ -11,7 +11,6 @@ #include <log.h> #include <malloc.h> #include <asm/gpio.h> -#include <dm/lists.h> struct led_gpio_priv { struct gpio_desc gpio; @@ -80,19 +79,7 @@ static int led_gpio_remove(struct udevice *dev) static int led_gpio_bind(struct udevice *parent) { - struct udevice *dev; - ofnode node; - int ret; - - dev_for_each_subnode(node, parent) { - ret = device_bind_driver_to_node(parent, "gpio_led", - ofnode_get_name(node), - node, &dev); - if (ret) - return ret; - } - - return 0; + return led_bind_generic(parent, "gpio_led"); } static const struct led_ops gpio_led_ops = { diff --git a/drivers/led/led_lp5562.c b/drivers/led/led_lp5562.c new file mode 100644 index 0000000000..431d7e10ab --- /dev/null +++ b/drivers/led/led_lp5562.c @@ -0,0 +1,577 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Doug Zobel <douglas.zobel@climate.com> + * + * Driver for TI lp5562 4 channel LED driver. There are only 3 + * engines available for the 4 LEDs, so white and blue LEDs share + * the same engine. This means that the blink period is shared + * between them. Changing the period of blue blink will affect + * the white period (and vice-versa). Blue and white On/Off + * states remain independent (as would PWM brightness if that's + * ever added to the LED core). + */ + +#include <dm.h> +#include <errno.h> +#include <led.h> +#include <i2c.h> +#include <asm/gpio.h> +#include <linux/delay.h> + +#define DEFAULT_CURRENT 100 /* 10 mA */ +#define MIN_BLINK_PERIOD 32 /* ms */ +#define MAX_BLINK_PERIOD 2248 /* ms */ + +/* Register Map */ +#define REG_ENABLE 0x00 +#define REG_OP_MODE 0x01 +#define REG_B_PWM 0x02 +#define REG_G_PWM 0x03 +#define REG_R_PWM 0x04 +#define REG_B_CUR 0x05 +#define REG_G_CUR 0x06 +#define REG_R_CUR 0x07 +#define REG_CONFIG 0x08 +#define REG_ENG1_PC 0x09 +#define REG_ENG2_PC 0x0A +#define REG_ENG3_PC 0x0B +#define REG_STATUS 0x0C +#define REG_RESET 0x0D +#define REG_W_PWM 0x0E +#define REG_W_CUR 0x0F +#define REG_ENG1_MEM_BEGIN 0x10 +#define REG_ENG2_MEM_BEGIN 0x30 +#define REG_ENG3_MEM_BEGIN 0x50 +#define REG_LED_MAP 0x70 + +/* LED Register Values */ +/* 0x00 ENABLE */ +#define REG_ENABLE_CHIP_ENABLE (0x1 << 6) +#define REG_ENABLE_ENG_EXEC_HOLD 0x0 +#define REG_ENABLE_ENG_EXEC_RUN 0x2 +#define REG_ENABLE_ENG_EXEC_MASK 0x3 + +/* 0x01 OP MODE */ +#define REG_OP_MODE_DISABLED 0x0 +#define REG_OP_MODE_LOAD_SRAM 0x1 +#define REG_OP_MODE_RUN 0x2 +#define REG_OP_MODE_MASK 0x3 + +/* 0x02, 0x03, 0x04, 0x0E PWM */ +#define REG_PWM_MIN_VALUE 0 +#define REG_PWM_MAX_VALUE 0xFF + +/* 0x08 CONFIG */ +#define REG_CONFIG_EXT_CLK 0x0 +#define REG_CONFIG_INT_CLK 0x1 +#define REG_CONFIG_AUTO_CLK 0x2 +#define REG_CONFIG_CLK_MASK 0x3 + +/* 0x0D RESET */ +#define REG_RESET_RESET 0xFF + +/* 0x70 LED MAP */ +#define REG_LED_MAP_ENG_MASK 0x03 +#define REG_LED_MAP_W_ENG_SHIFT 6 +#define REG_LED_MAP_R_ENG_SHIFT 4 +#define REG_LED_MAP_G_ENG_SHIFT 2 +#define REG_LED_MAP_B_ENG_SHIFT 0 + +/* Engine program related */ +#define REG_ENGINE_MEM_SIZE 0x20 +#define LED_PGRM_RAMP_INCREMENT_SHIFT 0 +#define LED_PGRM_RAMP_SIGN_SHIFT 7 +#define LED_PGRM_RAMP_STEP_SHIFT 8 +#define LED_PGRM_RAMP_PRESCALE_SHIFT 14 + +struct lp5562_led_wrap_priv { + struct gpio_desc enable_gpio; +}; + +struct lp5562_led_priv { + u8 reg_pwm; + u8 reg_current; + u8 map_shift; + u8 enginenum; +}; + +/* enum values map to LED_MAP (0x70) values */ +enum lp5562_led_ctl_mode { + I2C = 0x0, +#ifdef CONFIG_LED_BLINK + ENGINE1 = 0x1, + ENGINE2 = 0x2, + ENGINE3 = 0x3 +#endif +}; + +/* + * Update a register value + * dev - I2C udevice (parent of led) + * regnum - register number to update + * value - value to write to register + * mask - mask of bits that should be changed + */ +static int lp5562_led_reg_update(struct udevice *dev, int regnum, + u8 value, u8 mask) +{ + int ret; + + if (mask == 0xFF) + ret = dm_i2c_reg_write(dev, regnum, value); + else + ret = dm_i2c_reg_clrset(dev, regnum, mask, value); + + + /* + * Data sheet says "Delay between consecutive I2C writes to + * ENABLE register (00h) need to be longer than 488 μs + * (typical)." and "Delay between consecutive I2C writes to + * OP_MODE register need to be longer than 153 μs (typ)." + * + * The linux driver does usleep_range(500, 600) and + * usleep_range(200, 300), respectively. + */ + switch (regnum) { + case REG_ENABLE: + udelay(600); + break; + case REG_OP_MODE: + udelay(300); + break; + } + + return ret; +} + +#ifdef CONFIG_LED_BLINK +/* + * Program the lp5562 engine + * dev - I2C udevice (parent of led) + * program - array of commands + * size - number of commands in program array (1-16) + * engine - engine number (1-3) + */ +static int lp5562_led_program_engine(struct udevice *dev, u16 *program, + u8 size, u8 engine) +{ + int ret, cmd; + u8 engine_reg = REG_ENG1_MEM_BEGIN + + ((engine - 1) * REG_ENGINE_MEM_SIZE); + u8 shift = (3 - engine) * 2; + __be16 prog_be[16]; + + if (size < 1 || size > 16 || engine < 1 || engine > 3) + return -EINVAL; + + for (cmd = 0; cmd < size; cmd++) + prog_be[cmd] = cpu_to_be16(program[cmd]); + + /* set engine mode to 'disabled' */ + ret = lp5562_led_reg_update(dev, REG_OP_MODE, + REG_OP_MODE_DISABLED << shift, + REG_OP_MODE_MASK << shift); + if (ret != 0) + goto done; + + /* set exec mode to 'hold' */ + ret = lp5562_led_reg_update(dev, REG_ENABLE, + REG_ENABLE_ENG_EXEC_HOLD << shift, + REG_ENABLE_ENG_EXEC_MASK << shift); + if (ret != 0) + goto done; + + /* set engine mode to 'load SRAM' */ + ret = lp5562_led_reg_update(dev, REG_OP_MODE, + REG_OP_MODE_LOAD_SRAM << shift, + REG_OP_MODE_MASK << shift); + if (ret != 0) + goto done; + + /* send the re-ordered program sequence */ + ret = dm_i2c_write(dev, engine_reg, (uchar *)prog_be, sizeof(u16) * size); + if (ret != 0) + goto done; + + /* set engine mode to 'run' */ + ret = lp5562_led_reg_update(dev, REG_OP_MODE, + REG_OP_MODE_RUN << shift, + REG_OP_MODE_MASK << shift); + if (ret != 0) + goto done; + + /* set engine exec to 'run' */ + ret = lp5562_led_reg_update(dev, REG_ENABLE, + REG_ENABLE_ENG_EXEC_RUN << shift, + REG_ENABLE_ENG_EXEC_MASK << shift); + +done: + return ret; +} + +/* + * Get the LED's current control mode (I2C or ENGINE[1-3]) + * dev - led udevice (child udevice) + */ +static enum lp5562_led_ctl_mode lp5562_led_get_control_mode(struct udevice *dev) +{ + struct lp5562_led_priv *priv = dev_get_priv(dev); + u8 data; + enum lp5562_led_ctl_mode mode = I2C; + + if (dm_i2c_read(dev_get_parent(dev), REG_LED_MAP, &data, 1) == 0) + mode = (data & (REG_LED_MAP_ENG_MASK << priv->map_shift)) + >> priv->map_shift; + + return mode; +} +#endif + +/* + * Set the LED's control mode to I2C or ENGINE[1-3] + * dev - led udevice (child udevice) + * mode - mode to change to + */ +static int lp5562_led_set_control_mode(struct udevice *dev, + enum lp5562_led_ctl_mode mode) +{ + struct lp5562_led_priv *priv = dev_get_priv(dev); + + return (lp5562_led_reg_update(dev_get_parent(dev), REG_LED_MAP, + mode << priv->map_shift, + REG_LED_MAP_ENG_MASK << priv->map_shift)); +} + +/* + * Return the LED's PWM value; If LED is in BLINK state, then it is + * under engine control mode which doesn't use this PWM value. + * dev - led udevice (child udevice) + */ +static int lp5562_led_get_pwm(struct udevice *dev) +{ + struct lp5562_led_priv *priv = dev_get_priv(dev); + u8 data; + + if (dm_i2c_read(dev_get_parent(dev), priv->reg_pwm, &data, 1) != 0) + return -EINVAL; + + return data; +} + +/* + * Set the LED's PWM value and configure it to use this (I2C mode). + * dev - led udevice (child udevice) + * value - PWM value (0 - 255) + */ +static int lp5562_led_set_pwm(struct udevice *dev, u8 value) +{ + struct lp5562_led_priv *priv = dev_get_priv(dev); + + if (lp5562_led_reg_update(dev_get_parent(dev), priv->reg_pwm, + value, 0xff) != 0) + return -EINVAL; + + /* set LED to I2C register mode */ + return lp5562_led_set_control_mode(dev, I2C); +} + +/* + * Return the led's current state + * dev - led udevice (child udevice) + * + */ +static enum led_state_t lp5562_led_get_state(struct udevice *dev) +{ + enum led_state_t state = LEDST_ON; + + if (lp5562_led_get_pwm(dev) == REG_PWM_MIN_VALUE) + state = LEDST_OFF; + +#ifdef CONFIG_LED_BLINK + if (lp5562_led_get_control_mode(dev) != I2C) + state = LEDST_BLINK; +#endif + + return state; +} + +/* + * Set the led state + * dev - led udevice (child udevice) + * state - State to set the LED to + */ +static int lp5562_led_set_state(struct udevice *dev, enum led_state_t state) +{ +#ifdef CONFIG_LED_BLINK + struct lp5562_led_priv *priv = dev_get_priv(dev); +#endif + + switch (state) { + case LEDST_OFF: + return lp5562_led_set_pwm(dev, REG_PWM_MIN_VALUE); + case LEDST_ON: + return lp5562_led_set_pwm(dev, REG_PWM_MAX_VALUE); +#ifdef CONFIG_LED_BLINK + case LEDST_BLINK: + return lp5562_led_set_control_mode(dev, priv->enginenum); +#endif + case LEDST_TOGGLE: + if (lp5562_led_get_state(dev) == LEDST_OFF) + return lp5562_led_set_state(dev, LEDST_ON); + else + return lp5562_led_set_state(dev, LEDST_OFF); + break; + default: + return -EINVAL; + } + + return 0; +} + +#ifdef CONFIG_LED_BLINK +/* + * Set the blink period of an LED; note blue and white share the same + * engine so changing the period of one affects the other. + * dev - led udevice (child udevice) + * period_ms - blink period in ms + */ +static int lp5562_led_set_period(struct udevice *dev, int period_ms) +{ + struct lp5562_led_priv *priv = dev_get_priv(dev); + u8 opcode = 0; + u16 program[7]; + u16 wait_time; + + /* Blink is implemented as an engine program. Simple on/off + * for short periods, or fade in/fade out for longer periods: + * + * if (period_ms < 500): + * set PWM to 100% + * pause for period / 2 + * set PWM to 0% + * pause for period / 2 + * goto start + * + * else + * raise PWM 0% -> 50% in 62.7 ms + * raise PWM 50% -> 100% in 62.7 ms + * pause for (period - 4 * 62.7) / 2 + * lower PWM 100% -> 50% in 62.7 ms + * lower PWM 50% -> 0% in 62.7 ms + * pause for (period - 4 * 62.7) / 2 + * goto start + */ + + if (period_ms < MIN_BLINK_PERIOD) + period_ms = MIN_BLINK_PERIOD; + else if (period_ms > MAX_BLINK_PERIOD) + period_ms = MAX_BLINK_PERIOD; + + if (period_ms < 500) { + /* Simple on/off blink */ + wait_time = period_ms / 2; + + /* 1st command is full brightness */ + program[opcode++] = + (1 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + REG_PWM_MAX_VALUE; + + /* 2nd command is wait (period / 2) using 15.6ms steps */ + program[opcode++] = + (1 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + (((wait_time * 10) / 156) << LED_PGRM_RAMP_STEP_SHIFT) | + (0 << LED_PGRM_RAMP_INCREMENT_SHIFT); + + /* 3rd command is 0% brightness */ + program[opcode++] = + (1 << LED_PGRM_RAMP_PRESCALE_SHIFT); + + /* 4th command is wait (period / 2) using 15.6ms steps */ + program[opcode++] = + (1 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + (((wait_time * 10) / 156) << LED_PGRM_RAMP_STEP_SHIFT) | + (0 << LED_PGRM_RAMP_INCREMENT_SHIFT); + + /* 5th command: repeat */ + program[opcode++] = 0x00; + } else { + /* fade-in / fade-out blink */ + wait_time = ((period_ms - 251) / 2); + + /* ramp up time is 256 * 0.49ms (125.4ms) done in 2 steps */ + /* 1st command is ramp up 1/2 way */ + program[opcode++] = + (0 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + (1 << LED_PGRM_RAMP_STEP_SHIFT) | + (127 << LED_PGRM_RAMP_INCREMENT_SHIFT); + + /* 2nd command is ramp up rest of the way */ + program[opcode++] = + (0 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + (1 << LED_PGRM_RAMP_STEP_SHIFT) | + (127 << LED_PGRM_RAMP_INCREMENT_SHIFT); + + /* 3rd: wait ((period - 2 * ramp_time) / 2) (15.6ms steps) */ + program[opcode++] = + (1 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + (((wait_time * 10) / 156) << LED_PGRM_RAMP_STEP_SHIFT) | + (0 << LED_PGRM_RAMP_INCREMENT_SHIFT); + + /* ramp down is same as ramp up with sign bit set */ + /* 4th command is ramp down 1/2 way */ + program[opcode++] = + (0 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + (1 << LED_PGRM_RAMP_STEP_SHIFT) | + (1 << LED_PGRM_RAMP_SIGN_SHIFT) | + (127 << LED_PGRM_RAMP_INCREMENT_SHIFT); + + /* 5th command is ramp down rest of the way */ + program[opcode++] = + (0 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + (1 << LED_PGRM_RAMP_STEP_SHIFT) | + (1 << LED_PGRM_RAMP_SIGN_SHIFT) | + (127 << LED_PGRM_RAMP_INCREMENT_SHIFT); + + /* 6th: wait ((period - 2 * ramp_time) / 2) (15.6ms steps) */ + program[opcode++] = + (1 << LED_PGRM_RAMP_PRESCALE_SHIFT) | + (((wait_time * 10) / 156) << LED_PGRM_RAMP_STEP_SHIFT) | + (0 << LED_PGRM_RAMP_INCREMENT_SHIFT); + + /* 7th command: repeat */ + program[opcode++] = 0x00; + } + + return lp5562_led_program_engine(dev_get_parent(dev), program, + opcode, priv->enginenum); +} +#endif + +static const struct led_ops lp5562_led_ops = { + .get_state = lp5562_led_get_state, + .set_state = lp5562_led_set_state, +#ifdef CONFIG_LED_BLINK + .set_period = lp5562_led_set_period, +#endif +}; + +static int lp5562_led_probe(struct udevice *dev) +{ + struct lp5562_led_priv *priv = dev_get_priv(dev); + u8 current; + int ret = 0; + + /* Child LED nodes */ + switch (dev_read_addr(dev)) { + case 0: + priv->reg_current = REG_R_CUR; + priv->reg_pwm = REG_R_PWM; + priv->map_shift = REG_LED_MAP_R_ENG_SHIFT; + priv->enginenum = 1; + break; + case 1: + priv->reg_current = REG_G_CUR; + priv->reg_pwm = REG_G_PWM; + priv->map_shift = REG_LED_MAP_G_ENG_SHIFT; + priv->enginenum = 2; + break; + case 2: + priv->reg_current = REG_B_CUR; + priv->reg_pwm = REG_B_PWM; + priv->map_shift = REG_LED_MAP_B_ENG_SHIFT; + priv->enginenum = 3; /* shared with white */ + break; + case 3: + priv->reg_current = REG_W_CUR; + priv->map_shift = REG_LED_MAP_W_ENG_SHIFT; + priv->enginenum = 3; /* shared with blue */ + break; + default: + return -EINVAL; + } + + current = dev_read_u8_default(dev, "max-cur", DEFAULT_CURRENT); + + ret = lp5562_led_reg_update(dev_get_parent(dev), priv->reg_current, + current, 0xff); + + return ret; +} + +static int lp5562_led_bind(struct udevice *dev) +{ + struct led_uc_plat *uc_plat = dev_get_uclass_plat(dev); + + /* + * For the child nodes, parse a "chan-name" property, since + * the DT bindings for this device use that instead of + * "label". + */ + uc_plat->label = dev_read_string(dev, "chan-name"); + + return 0; +} + +U_BOOT_DRIVER(lp5562_led) = { + .name = "lp5562-led", + .id = UCLASS_LED, + .bind = lp5562_led_bind, + .probe = lp5562_led_probe, + .priv_auto = sizeof(struct lp5562_led_priv), + .ops = &lp5562_led_ops, +}; + + +static int lp5562_led_wrap_probe(struct udevice *dev) +{ + struct lp5562_led_wrap_priv *priv = dev_get_priv(dev); + u8 clock_mode; + int ret; + + /* Enable gpio if needed */ + if (gpio_request_by_name(dev, "enabled-gpios", 0, + &priv->enable_gpio, GPIOD_IS_OUT) == 0) { + dm_gpio_set_value(&priv->enable_gpio, 1); + udelay(1000); + } + + /* Ensure all registers have default values. */ + ret = lp5562_led_reg_update(dev, REG_RESET, REG_RESET_RESET, 0xff); + if (ret) + return ret; + udelay(10000); + + /* Enable the chip */ + ret = lp5562_led_reg_update(dev, REG_ENABLE, REG_ENABLE_CHIP_ENABLE, 0xff); + if (ret) + return ret; + + /* + * The DT bindings say 0=auto, 1=internal, 2=external, while + * the register[0:1] values are 0=external, 1=internal, + * 2=auto. + */ + clock_mode = dev_read_u8_default(dev, "clock-mode", 0); + ret = lp5562_led_reg_update(dev, REG_CONFIG, 2 - clock_mode, REG_CONFIG_CLK_MASK); + + return ret; +} + +static int lp5562_led_wrap_bind(struct udevice *dev) +{ + return led_bind_generic(dev, "lp5562-led"); +} + +static const struct udevice_id lp5562_led_ids[] = { + { .compatible = "ti,lp5562" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(lp5562_led_wrap) = { + .name = "lp5562-led-wrap", + .id = UCLASS_NOP, + .of_match = lp5562_led_ids, + .bind = lp5562_led_wrap_bind, + .probe = lp5562_led_wrap_probe, + .priv_auto = sizeof(struct lp5562_led_wrap_priv), +}; diff --git a/drivers/led/led_pwm.c b/drivers/led/led_pwm.c index 7c8eae9337..ae6de3087a 100644 --- a/drivers/led/led_pwm.c +++ b/drivers/led/led_pwm.c @@ -9,7 +9,6 @@ #include <errno.h> #include <led.h> #include <malloc.h> -#include <dm/lists.h> #include <pwm.h> #define LEDS_PWM_DRIVER_NAME "led_pwm" @@ -136,18 +135,7 @@ static int led_pwm_of_to_plat(struct udevice *dev) static int led_pwm_bind(struct udevice *parent) { - struct udevice *dev; - ofnode node; - int ret; - - dev_for_each_subnode(node, parent) { - ret = device_bind_driver_to_node(parent, LEDS_PWM_DRIVER_NAME, - ofnode_get_name(node), - node, &dev); - if (ret) - return ret; - } - return 0; + return led_bind_generic(parent, LEDS_PWM_DRIVER_NAME); } static const struct led_ops led_pwm_ops = { diff --git a/drivers/mailbox/zynqmp-ipi.c b/drivers/mailbox/zynqmp-ipi.c index 3e4ec47389..eb86847bbe 100644 --- a/drivers/mailbox/zynqmp-ipi.c +++ b/drivers/mailbox/zynqmp-ipi.c @@ -8,9 +8,13 @@ #include <common.h> #include <log.h> #include <asm/io.h> +#include <asm/system.h> #include <dm.h> #include <mailbox-uclass.h> #include <dm/device_compat.h> +#include <dm/lists.h> +#include <dm/of_access.h> +#include <linux/arm-smccc.h> #include <linux/ioport.h> #include <linux/io.h> #include <wait_bit.h> @@ -21,6 +25,43 @@ #define IPI_BIT_MASK_PMU0 0x10000 #define IPI_INT_REG_BASE_APU 0xFF300000 +/* IPI agent ID any */ +#define IPI_ID_ANY 0xFFUL + +/* indicate if ZynqMP IPI mailbox driver uses SMC calls or HVC calls */ +#define USE_SMC 0 + +/* Default IPI SMC function IDs */ +#define SMC_IPI_MAILBOX_OPEN 0x82001000U +#define SMC_IPI_MAILBOX_RELEASE 0x82001001U +#define SMC_IPI_MAILBOX_STATUS_ENQUIRY 0x82001002U +#define SMC_IPI_MAILBOX_NOTIFY 0x82001003U +#define SMC_IPI_MAILBOX_ACK 0x82001004U +#define SMC_IPI_MAILBOX_ENABLE_IRQ 0x82001005U +#define SMC_IPI_MAILBOX_DISABLE_IRQ 0x82001006U + +/* IPI SMC Macros */ + +/* + * Flag to indicate if notification interrupt + * to be disabled. + */ +#define IPI_SMC_ENQUIRY_DIRQ_MASK BIT(0) + +/* + * Flag to indicate if notification interrupt + * to be enabled. + */ +#define IPI_SMC_ACK_EIRQ_MASK BIT(0) + +/* IPI mailbox status */ +#define IPI_MB_STATUS_IDLE 0 +#define IPI_MB_STATUS_SEND_PENDING 1 +#define IPI_MB_STATUS_RECV_PENDING 2 + +#define IPI_MB_CHNL_TX 0 /* IPI mailbox TX channel */ +#define IPI_MB_CHNL_RX 1 /* IPI mailbox RX channel */ + struct ipi_int_regs { u32 trig; /* 0x0 */ u32 obs; /* 0x4 */ @@ -39,8 +80,24 @@ struct zynqmp_ipi { void __iomem *local_res_regs; void __iomem *remote_req_regs; void __iomem *remote_res_regs; + u32 remote_id; + u32 local_id; + bool el3_supported; }; +static int zynqmp_ipi_fw_call(struct zynqmp_ipi *ipi_mbox, + unsigned long a0, unsigned long a3) +{ + struct arm_smccc_res res = {0}; + unsigned long a1, a2; + + a1 = ipi_mbox->local_id; + a2 = ipi_mbox->remote_id; + arm_smccc_smc(a0, a1, a2, a3, 0, 0, 0, 0, &res); + + return (int)res.a0; +} + static int zynqmp_ipi_send(struct mbox_chan *chan, const void *data) { const struct zynqmp_ipi_msg *msg = (struct zynqmp_ipi_msg *)data; @@ -51,6 +108,21 @@ static int zynqmp_ipi_send(struct mbox_chan *chan, const void *data) for (size_t i = 0; i < msg->len; i++) writel(msg->buf[i], &mbx[i]); + /* Use SMC calls for Exception Level less than 3 where TF-A is available */ + if (!IS_ENABLED(CONFIG_SPL_BUILD) && current_el() < 3) { + ret = zynqmp_ipi_fw_call(zynqmp, SMC_IPI_MAILBOX_NOTIFY, 0); + + debug("%s, send %ld bytes\n", __func__, msg->len); + + return ret; + } + + /* Return if EL3 is not supported */ + if (!zynqmp->el3_supported) { + dev_err(chan->dev, "mailbox in EL3 only supported for zynqmp"); + return -EOPNOTSUPP; + } + /* Write trigger interrupt */ writel(IPI_BIT_MASK_PMU0, &ipi_int_apu->trig); @@ -67,29 +139,50 @@ static int zynqmp_ipi_recv(struct mbox_chan *chan, void *data) struct zynqmp_ipi_msg *msg = (struct zynqmp_ipi_msg *)data; struct zynqmp_ipi *zynqmp = dev_get_priv(chan->dev); u32 *mbx = (u32 *)zynqmp->local_res_regs; + int ret = 0; /* * PMU Firmware does not trigger IPI interrupt for API call responses so - * there is no need to check ISR flags + * there is no need to check ISR flags for EL3. */ for (size_t i = 0; i < msg->len; i++) msg->buf[i] = readl(&mbx[i]); + /* Ack to remote if EL is not 3 */ + if (!IS_ENABLED(CONFIG_SPL_BUILD) && current_el() < 3) { + ret = zynqmp_ipi_fw_call(zynqmp, SMC_IPI_MAILBOX_ACK, + IPI_SMC_ACK_EIRQ_MASK); + } + debug("%s, recv %ld bytes\n", __func__, msg->len); - return 0; + return ret; }; -static int zynqmp_ipi_probe(struct udevice *dev) +static int zynqmp_ipi_dest_probe(struct udevice *dev) { struct zynqmp_ipi *zynqmp = dev_get_priv(dev); struct resource res; ofnode node; + int ret; debug("%s(dev=%p)\n", __func__, dev); - /* Get subnode where the regs are defined */ - /* Note IPI mailbox node needs to be the first one in DT */ - node = ofnode_first_subnode(dev_ofnode(dev)); + node = dev_ofnode(dev); + + if (IS_ENABLED(CONFIG_SPL_BUILD) || of_machine_is_compatible("xlnx,zynqmp")) + zynqmp->el3_supported = true; + + ret = dev_read_u32(dev->parent, "xlnx,ipi-id", &zynqmp->local_id); + if (ret) { + dev_err(dev, "can't get local ipi id\n"); + return ret; + } + + ret = ofnode_read_u32(node, "xlnx,ipi-id", &zynqmp->remote_id); + if (ret) { + dev_err(dev, "can't get remote ipi id\n"); + return ret; + } if (ofnode_read_resource_byname(node, "local_request_region", &res)) { dev_err(dev, "No reg property for local_request_region\n"); @@ -97,6 +190,8 @@ static int zynqmp_ipi_probe(struct udevice *dev) }; zynqmp->local_req_regs = devm_ioremap(dev, res.start, (res.start - res.end)); + if (!zynqmp->local_req_regs) + return -EINVAL; if (ofnode_read_resource_byname(node, "local_response_region", &res)) { dev_err(dev, "No reg property for local_response_region\n"); @@ -104,6 +199,8 @@ static int zynqmp_ipi_probe(struct udevice *dev) }; zynqmp->local_res_regs = devm_ioremap(dev, res.start, (res.start - res.end)); + if (!zynqmp->local_res_regs) + return -EINVAL; if (ofnode_read_resource_byname(node, "remote_request_region", &res)) { dev_err(dev, "No reg property for remote_request_region\n"); @@ -111,6 +208,8 @@ static int zynqmp_ipi_probe(struct udevice *dev) }; zynqmp->remote_req_regs = devm_ioremap(dev, res.start, (res.start - res.end)); + if (!zynqmp->remote_req_regs) + return -EINVAL; if (ofnode_read_resource_byname(node, "remote_response_region", &res)) { dev_err(dev, "No reg property for remote_response_region\n"); @@ -118,25 +217,59 @@ static int zynqmp_ipi_probe(struct udevice *dev) }; zynqmp->remote_res_regs = devm_ioremap(dev, res.start, (res.start - res.end)); + if (!zynqmp->remote_res_regs) + return -EINVAL; return 0; }; -static const struct udevice_id zynqmp_ipi_ids[] = { - { .compatible = "xlnx,zynqmp-ipi-mailbox" }, - { } +static int zynqmp_ipi_probe(struct udevice *dev) +{ + struct udevice *cdev; + ofnode cnode; + int ret; + + debug("%s(dev=%p)\n", __func__, dev); + + dev_for_each_subnode(cnode, dev) { + ret = device_bind_driver_to_node(dev, "zynqmp_ipi_dest", + ofnode_get_name(cnode), + cnode, &cdev); + if (ret) + return ret; + } + + return 0; }; -struct mbox_ops zynqmp_ipi_mbox_ops = { +struct mbox_ops zynqmp_ipi_dest_mbox_ops = { .send = zynqmp_ipi_send, .recv = zynqmp_ipi_recv, }; +static const struct udevice_id zynqmp_ipi_dest_ids[] = { + { .compatible = "xlnx,zynqmp-ipi-dest-mailbox" }, + { } +}; + +U_BOOT_DRIVER(zynqmp_ipi_dest) = { + .name = "zynqmp_ipi_dest", + .id = UCLASS_MAILBOX, + .of_match = zynqmp_ipi_dest_ids, + .probe = zynqmp_ipi_dest_probe, + .priv_auto = sizeof(struct zynqmp_ipi), + .ops = &zynqmp_ipi_dest_mbox_ops, +}; + +static const struct udevice_id zynqmp_ipi_ids[] = { + { .compatible = "xlnx,zynqmp-ipi-mailbox" }, + { } +}; + U_BOOT_DRIVER(zynqmp_ipi) = { .name = "zynqmp_ipi", - .id = UCLASS_MAILBOX, + .id = UCLASS_NOP, .of_match = zynqmp_ipi_ids, .probe = zynqmp_ipi_probe, - .priv_auto = sizeof(struct zynqmp_ipi), - .ops = &zynqmp_ipi_mbox_ops, + .flags = DM_FLAG_PROBE_AFTER_BIND, }; diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-ebi.c index 212bb4f5dc..a722a3836f 100644 --- a/drivers/memory/stm32-fmc2-ebi.c +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -14,6 +14,7 @@ #include <linux/err.h> #include <linux/iopoll.h> #include <linux/ioport.h> +#include <linux/time.h> /* FMC2 Controller Registers */ #define FMC2_BCR1 0x0 @@ -90,8 +91,6 @@ #define FMC2_BTR_DATLAT_MAX 0xf #define FMC2_PCSCNTR_CSCOUNT_MAX 0xff -#define FMC2_NSEC_PER_SEC 1000000000L - enum stm32_fmc2_ebi_bank { FMC2_EBI1 = 0, FMC2_EBI2, @@ -279,7 +278,7 @@ static u32 stm32_fmc2_ebi_ns_to_clock_cycles(struct stm32_fmc2_ebi *ebi, int cs, u32 setup) { unsigned long hclk = clk_get_rate(&ebi->clk); - unsigned long hclkp = FMC2_NSEC_PER_SEC / (hclk / 1000); + unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000); return DIV_ROUND_UP(setup * 1000, hclkp); } diff --git a/drivers/memory/ti-aemif.c b/drivers/memory/ti-aemif.c index c4bc88c151..41325eb0f9 100644 --- a/drivers/memory/ti-aemif.c +++ b/drivers/memory/ti-aemif.c @@ -7,6 +7,7 @@ */ #include <common.h> +#include <asm/arch/hardware.h> #include <asm/ti-common/ti-aemif.h> #define AEMIF_WAITCYCLE_CONFIG (KS2_AEMIF_CNTRL_BASE + 0x4) diff --git a/drivers/misc/gsc.c b/drivers/misc/gsc.c index 65c9c2c6ce..feb02f9706 100644 --- a/drivers/misc/gsc.c +++ b/drivers/misc/gsc.c @@ -531,10 +531,10 @@ static int do_gsc(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[] if (!gsc_wd_disable(dev)) return CMD_RET_SUCCESS; } else if (strcasecmp(argv[1], "thermal") == 0) { - char *cmd, *val; + const char *cmd, *val; - cmd = (argc > 2) ? argv[2] : NULL; - val = (argc > 3) ? argv[3] : NULL; + cmd = cmd_arg2(argc, argv); + val = cmd_arg3(argc, argv); if (!gsc_thermal(dev, cmd, val)) return CMD_RET_SUCCESS; } diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c index 7c01bf23d5..e3b6b4cd74 100644 --- a/drivers/misc/qfw.c +++ b/drivers/misc/qfw.c @@ -7,6 +7,7 @@ #define LOG_CATEGORY UCLASS_QFW #include <common.h> +#include <acpi/acpi_table.h> #include <bootdev.h> #include <bootflow.h> #include <bootmeth.h> diff --git a/drivers/mmc/octeontx_hsmmc.h b/drivers/mmc/octeontx_hsmmc.h index 70844b1cba..9849121f17 100644 --- a/drivers/mmc/octeontx_hsmmc.h +++ b/drivers/mmc/octeontx_hsmmc.h @@ -32,8 +32,6 @@ */ #define MMC_TIMEOUT_SHORT 20 -#define NSEC_PER_SEC 1000000000L - #define MAX_NO_OF_TAPS 64 #define EXT_CSD_POWER_CLASS 187 /* R/W */ diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index c638980ea2..c2fc80b10f 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -31,7 +31,7 @@ obj-$(CONFIG_NVMXIP) += nvmxip/ else ifneq ($(mtd-y),) -obj-$(CONFIG_SPL_MTD_SUPPORT) += mtd.o +obj-$(CONFIG_SPL_MTD) += mtd.o endif obj-$(CONFIG_$(SPL_TPL_)NAND_SUPPORT) += nand/ obj-$(CONFIG_SPL_ONENAND_SUPPORT) += onenand/ diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index a13e6f59cb..bb9994b862 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -447,6 +447,22 @@ config NAND_PXA3XX This enables the driver for the NAND flash device found on PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2). +config NAND_SANDBOX + bool "Support for NAND in sandbox" + depends on SANDBOX + select SYS_NAND_SELF_INIT + select SPL_SYS_NAND_SELF_INIT + select SPL_NAND_INIT + select SYS_NAND_SOFT_ECC + select BCH + select NAND_ECC_BCH + imply CMD_NAND + help + Enable a dummy NAND driver for sandbox. It simulates any number of + arbitrary NAND chips with a RAM buffer. It will also inject errors to + test ECC. At the moment, only 8-bit busses and single-chip devices are + supported. + config NAND_SUNXI bool "Support for NAND on Allwinner SoCs" default ARCH_SUNXI @@ -659,20 +675,13 @@ config SYS_NAND_ONFI_DETECTION And fetching device parameters flashed on device, by parsing ONFI parameter page. -config SYS_NAND_PAGE_COUNT - hex "NAND chip page count" - depends on SPL_NAND_SUPPORT && (NAND_ATMEL || NAND_MXC || \ - SPL_NAND_AM33XX_BCH || SPL_NAND_LOAD || SPL_NAND_SIMPLE || \ - NAND_OMAP_GPMC) - help - Number of pages in the NAND chip. - config SYS_NAND_PAGE_SIZE hex "NAND chip page size" depends on ARCH_SUNXI || NAND_OMAP_GPMC || NAND_LPC32XX_SLC || \ SPL_NAND_SIMPLE || (NAND_MXC && SPL_NAND_SUPPORT) || \ MVEBU_SPL_BOOT_DEVICE_NAND || \ - (NAND_ATMEL && SPL_NAND_SUPPORT) || SPL_GENERATE_ATMEL_PMECC_HEADER + (NAND_ATMEL && SPL_NAND_SUPPORT) || \ + SPL_GENERATE_ATMEL_PMECC_HEADER || NAND_SANDBOX depends on !NAND_MXS && !NAND_DENALI_DT && !NAND_LPC32XX_MLC && !NAND_MT7621 help Number of data bytes in one page for the NAND chip on the diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index add2b4cf65..ddbba899e5 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_NAND_PXA3XX) += pxa3xx_nand.o obj-$(CONFIG_TEGRA_NAND) += tegra_nand.o obj-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o obj-$(CONFIG_NAND_OMAP_ELM) += omap_elm.o +obj-$(CONFIG_NAND_SANDBOX) += sand_nand.o obj-$(CONFIG_NAND_SUNXI) += sunxi_nand.o obj-$(CONFIG_NAND_MXIC) += mxic_nand.o obj-$(CONFIG_NAND_ZYNQ) += zynq_nand.o diff --git a/drivers/mtd/nand/raw/am335x_spl_bch.c b/drivers/mtd/nand/raw/am335x_spl_bch.c index 6ab3f1f42c..6831af98b7 100644 --- a/drivers/mtd/nand/raw/am335x_spl_bch.c +++ b/drivers/mtd/nand/raw/am335x_spl_bch.c @@ -11,6 +11,7 @@ #include <common.h> #include <nand.h> +#include <system-constants.h> #include <asm/io.h> #include <linux/delay.h> #include <linux/mtd/nand_ecc.h> @@ -32,7 +33,7 @@ static int nand_command(int block, int page, uint32_t offs, u8 cmd) { struct nand_chip *this = mtd_to_nand(mtd); - int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; + int page_addr = page + block * SYS_NAND_BLOCK_PAGES; void (*hwctrl)(struct mtd_info *mtd, int cmd, unsigned int ctrl) = this->cmd_ctrl; @@ -217,6 +218,11 @@ void nand_init(void) nand_command(0, 0, 0, NAND_CMD_RESET); } +unsigned int nand_page_size(void) +{ + return nand_to_mtd(&nand_chip)->writesize; +} + /* Unselect after operation */ void nand_deselect(void) { diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index fa962ba591..a2151f9849 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -64,6 +64,7 @@ #include <linux/mfd/syscon/atmel-smc.h> #include <linux/mtd/rawnand.h> #include <linux/mtd/mtd.h> +#include <linux/time.h> #include <mach/at91_sfr.h> #include <nand.h> #include <regmap.h> @@ -71,8 +72,6 @@ #include "pmecc.h" -#define NSEC_PER_SEC 1000000000L - #define ATMEL_HSMC_NFC_CFG 0x0 #define ATMEL_HSMC_NFC_CFG_SPARESIZE(x) (((x) / 4) << 24) #define ATMEL_HSMC_NFC_CFG_SPARESIZE_MASK GENMASK(30, 24) @@ -352,40 +351,6 @@ static int atmel_nfc_wait(struct atmel_hsmc_nand_controller *nc, bool poll, return ret; } -static void iowrite8_rep(void *addr, const uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) - writeb(buf[i], addr); -} - -static void ioread8_rep(void *addr, uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) - buf[i] = readb(addr); -} - -static void ioread16_rep(void *addr, void *buf, int len) -{ - int i; - u16 *p = (u16 *)buf; - - for (i = 0; i < len; i++) - p[i] = readw(addr); -} - -static void iowrite16_rep(void *addr, const void *buf, int len) -{ - int i; - u16 *p = (u16 *)buf; - - for (i = 0; i < len; i++) - writew(p[i], addr); -} - static u8 atmel_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *chip = mtd_to_nand(mtd); diff --git a/drivers/mtd/nand/raw/atmel_nand.c b/drivers/mtd/nand/raw/atmel_nand.c index 6b17e744a6..6d94e7af38 100644 --- a/drivers/mtd/nand/raw/atmel_nand.c +++ b/drivers/mtd/nand/raw/atmel_nand.c @@ -12,6 +12,7 @@ #include <common.h> #include <log.h> +#include <system-constants.h> #include <asm/gpio.h> #include <asm/arch/gpio.h> #include <dm/device_compat.h> @@ -1258,7 +1259,7 @@ static struct nand_chip nand_chip; static int nand_command(int block, int page, uint32_t offs, u8 cmd) { struct nand_chip *this = mtd_to_nand(mtd); - int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; + int page_addr = page + block * SYS_NAND_BLOCK_PAGES; void (*hwctrl)(struct mtd_info *mtd, int cmd, unsigned int ctrl) = this->cmd_ctrl; @@ -1359,7 +1360,7 @@ int spl_nand_erase_one(int block, int page) if (nand_chip.select_chip) nand_chip.select_chip(mtd, 0); - page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; + page_addr = page + block * SYS_NAND_BLOCK_PAGES; hwctrl(mtd, NAND_CMD_ERASE1, NAND_CTRL_CLE | NAND_CTRL_CHANGE); /* Row address */ hwctrl(mtd, (page_addr & 0xff), NAND_CTRL_ALE | NAND_CTRL_CHANGE); @@ -1451,6 +1452,11 @@ void nand_init(void) nand_chip.select_chip(mtd, 0); } +unsigned int nand_page_size(void) +{ + return nand_to_mtd(&nand_chip)->writesize; +} + void nand_deselect(void) { if (nand_chip.select_chip) diff --git a/drivers/mtd/nand/raw/denali_spl.c b/drivers/mtd/nand/raw/denali_spl.c index 690279c997..165a23312c 100644 --- a/drivers/mtd/nand/raw/denali_spl.c +++ b/drivers/mtd/nand/raw/denali_spl.c @@ -234,4 +234,9 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) return 0; } +unsigned int nand_page_size(void) +{ + return page_size; +} + void nand_deselect(void) {} diff --git a/drivers/mtd/nand/raw/fsl_ifc_spl.c b/drivers/mtd/nand/raw/fsl_ifc_spl.c index c67065eaf8..69d26f1f79 100644 --- a/drivers/mtd/nand/raw/fsl_ifc_spl.c +++ b/drivers/mtd/nand/raw/fsl_ifc_spl.c @@ -106,6 +106,8 @@ static inline int bad_block(uchar *marker, int port_size) return __raw_readw((u16 *)marker) != 0xffff; } +static int saved_page_size; + int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst) { struct fsl_ifc_fcm *gregs = (void *)CFG_SYS_IFC_ADDR; @@ -150,6 +152,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst) if (port_size == 8) bad_marker = 5; } + saved_page_size = page_size; ver = ifc_in32(&gregs->ifc_rev); if (ver >= FSL_IFC_V2_0_0) @@ -302,6 +305,11 @@ void nand_init(void) { } +unsigned int nand_page_size(void) +{ + return saved_page_size; +} + void nand_deselect(void) { } diff --git a/drivers/mtd/nand/raw/lpc32xx_nand_mlc.c b/drivers/mtd/nand/raw/lpc32xx_nand_mlc.c index ac2e669d46..f8ae216d56 100644 --- a/drivers/mtd/nand/raw/lpc32xx_nand_mlc.c +++ b/drivers/mtd/nand/raw/lpc32xx_nand_mlc.c @@ -765,4 +765,9 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) return 0; } +unsigned int nand_page_size(void) +{ + return BYTES_PER_PAGE; +} + #endif /* CONFIG_SPL_BUILD */ diff --git a/drivers/mtd/nand/raw/mt7621_nand_spl.c b/drivers/mtd/nand/raw/mt7621_nand_spl.c index 114fc8b7ce..a2be9ba80e 100644 --- a/drivers/mtd/nand/raw/mt7621_nand_spl.c +++ b/drivers/mtd/nand/raw/mt7621_nand_spl.c @@ -203,6 +203,11 @@ unsigned long nand_size(void) return SZ_2G; } +unsigned int nand_page_size(void) +{ + return nfc_dev.nand.mtd.writesize; +} + void nand_deselect(void) { } diff --git a/drivers/mtd/nand/raw/mxc_nand_spl.c b/drivers/mtd/nand/raw/mxc_nand_spl.c index 309e75d01e..a855c9987f 100644 --- a/drivers/mtd/nand/raw/mxc_nand_spl.c +++ b/drivers/mtd/nand/raw/mxc_nand_spl.c @@ -13,6 +13,7 @@ #include <common.h> #include <hang.h> #include <nand.h> +#include <system-constants.h> #include <linux/mtd/rawnand.h> #include <asm/arch/imx-regs.h> #include <asm/io.h> @@ -304,13 +305,13 @@ int nand_spl_load_image(uint32_t from, unsigned int size, void *buf) * Check if we have crossed a block boundary, and if so * check for bad block. */ - if (!(page % CONFIG_SYS_NAND_PAGE_COUNT)) { + if (!(page % SYS_NAND_BLOCK_PAGES)) { /* * Yes, new block. See if this block is good. If not, * loop until we find a good block. */ while (is_badblock(page)) { - page = page + CONFIG_SYS_NAND_PAGE_COUNT; + page = page + SYS_NAND_BLOCK_PAGES; /* Check i we've reached the end of flash. */ if (page >= maxpages) return -1; @@ -350,3 +351,8 @@ __used void nand_boot(void) void nand_init(void) {} void nand_deselect(void) {} + +unsigned int nand_page_size(void) +{ + return CONFIG_SYS_NAND_PAGE_SIZE; +} diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 65eab4c808..fd65772af8 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -31,6 +31,7 @@ #include <linux/errno.h> #include <linux/mtd/rawnand.h> #include <linux/sizes.h> +#include <linux/time.h> #include <linux/types.h> #include <linux/math64.h> @@ -52,8 +53,6 @@ #endif #define MXS_NAND_BCH_TIMEOUT 10000 -#define USEC_PER_SEC 1000000 -#define NSEC_PER_SEC 1000000000L #define TO_CYCLES(duration, period) DIV_ROUND_UP_ULL(duration, period) diff --git a/drivers/mtd/nand/raw/mxs_nand_spl.c b/drivers/mtd/nand/raw/mxs_nand_spl.c index 300662994c..f7d3f02f85 100644 --- a/drivers/mtd/nand/raw/mxs_nand_spl.c +++ b/drivers/mtd/nand/raw/mxs_nand_spl.c @@ -295,6 +295,11 @@ int nand_default_bbt(struct mtd_info *mtd) return 0; } +unsigned int nand_page_size(void) +{ + return nand_to_mtd(&nand_chip)->writesize; +} + void nand_deselect(void) { } diff --git a/drivers/mtd/nand/raw/nand.c b/drivers/mtd/nand/raw/nand.c index eacd99c4e2..4c18861aa2 100644 --- a/drivers/mtd/nand/raw/nand.c +++ b/drivers/mtd/nand/raw/nand.c @@ -60,13 +60,11 @@ int nand_register(int devnum, struct mtd_info *mtd) sprintf(dev_name[devnum], "nand%d", devnum); mtd->name = dev_name[devnum]; -#ifdef CONFIG_MTD /* * Add MTD device so that we can reference it later * via the mtdcore infrastructure (e.g. ubi). */ add_mtd_device(mtd); -#endif total_nand_size += mtd->size / 1024; @@ -76,6 +74,23 @@ int nand_register(int devnum, struct mtd_info *mtd) return 0; } +void nand_unregister(struct mtd_info *mtd) +{ + int devnum = nand_mtd_to_devnum(mtd); + + if (devnum < 0) + return; + + if (nand_curr_device == devnum) + nand_curr_device = -1; + + total_nand_size -= mtd->size / 1024; + + del_mtd_device(nand_info[devnum]); + + nand_info[devnum] = NULL; +} + #if !CONFIG_IS_ENABLED(SYS_NAND_SELF_INIT) static void nand_init_chip(int i) { @@ -100,6 +115,8 @@ static void nand_init_chip(int i) #endif #ifdef CONFIG_MTD_CONCAT +struct mtd_info *concat_mtd; + static void create_mtd_concat(void) { struct mtd_info *nand_info_list[CONFIG_SYS_MAX_NAND_DEVICE]; @@ -114,28 +131,40 @@ static void create_mtd_concat(void) } } if (nand_devices_found > 1) { - struct mtd_info *mtd; char c_mtd_name[16]; /* * We detected multiple devices. Concatenate them together. */ sprintf(c_mtd_name, "nand%d", nand_devices_found); - mtd = mtd_concat_create(nand_info_list, nand_devices_found, - c_mtd_name); + concat_mtd = mtd_concat_create(nand_info_list, + nand_devices_found, c_mtd_name); - if (mtd == NULL) + if (!concat_mtd) return; - nand_register(nand_devices_found, mtd); + nand_register(nand_devices_found, concat_mtd); } return; } + +static void destroy_mtd_concat(void) +{ + if (!concat_mtd) + return; + + mtd_concat_destroy(concat_mtd); + concat_mtd = NULL; +} #else static void create_mtd_concat(void) { } + +static void destroy_mtd_concat(void) +{ +} #endif unsigned long nand_size(void) @@ -143,10 +172,10 @@ unsigned long nand_size(void) return total_nand_size; } +static int initialized; + void nand_init(void) { - static int initialized; - /* * Avoid initializing NAND Flash multiple times, * otherwise it will calculate a wrong total size. @@ -174,3 +203,22 @@ void nand_init(void) create_mtd_concat(); } + +void nand_reinit(void) +{ + int i; + + destroy_mtd_concat(); + for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++) + assert(!nand_info[i]); + + initialized = 0; + nand_init(); +} + +unsigned int nand_page_size(void) +{ + struct mtd_info *mtd = get_nand_dev_by_index(nand_curr_device); + + return mtd ? mtd->writesize : 1; +} diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 6b4adcf6bd..c40a0f23d7 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -245,39 +245,6 @@ static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) chip->write_buf(mtd, (uint8_t *)&word, 2); } -static void iowrite8_rep(void *addr, const uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) - writeb(buf[i], addr); -} -static void ioread8_rep(void *addr, uint8_t *buf, int len) -{ - int i; - - for (i = 0; i < len; i++) - buf[i] = readb(addr); -} - -static void ioread16_rep(void *addr, void *buf, int len) -{ - int i; - u16 *p = (u16 *) buf; - - for (i = 0; i < len; i++) - p[i] = readw(addr); -} - -static void iowrite16_rep(void *addr, void *buf, int len) -{ - int i; - u16 *p = (u16 *) buf; - - for (i = 0; i < len; i++) - writew(p[i], addr); -} - /** * nand_write_buf - [DEFAULT] write buffer to chip * @mtd: MTD device structure @@ -4462,17 +4429,14 @@ ident_done: else if (chip->jedec_version) pr_info("%s %s\n", manufacturer_desc->name, chip->jedec_params.model); - else + else if (manufacturer_desc) pr_info("%s %s\n", manufacturer_desc->name, type->name); #else if (chip->jedec_version) pr_info("%s %s\n", manufacturer_desc->name, chip->jedec_params.model); - else + else if (manufacturer_desc) pr_info("%s %s\n", manufacturer_desc->name, type->name); - - pr_info("%s %s\n", manufacturer_desc->name, - type->name); #endif pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", diff --git a/drivers/mtd/nand/raw/nand_spl_loaders.c b/drivers/mtd/nand/raw/nand_spl_loaders.c index 156b44d835..db4213ea3d 100644 --- a/drivers/mtd/nand/raw/nand_spl_loaders.c +++ b/drivers/mtd/nand/raw/nand_spl_loaders.c @@ -12,8 +12,11 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) while (block <= lastblock) { if (!nand_is_bad_block(block)) { /* Skip bad blocks */ - while (page < CONFIG_SYS_NAND_PAGE_COUNT) { + while (size && page < SYS_NAND_BLOCK_PAGES) { nand_read_page(block, page, dst); + + size -= min(size, CONFIG_SYS_NAND_PAGE_SIZE - + page_offset); /* * When offs is not aligned to page address the * extra offset is copied to dst as well. Copy diff --git a/drivers/mtd/nand/raw/nand_spl_simple.c b/drivers/mtd/nand/raw/nand_spl_simple.c index 2f3af9edd4..80d6e0e1e4 100644 --- a/drivers/mtd/nand/raw/nand_spl_simple.c +++ b/drivers/mtd/nand/raw/nand_spl_simple.c @@ -6,6 +6,7 @@ #include <common.h> #include <nand.h> +#include <system-constants.h> #include <asm/io.h> #include <linux/mtd/nand_ecc.h> #include <linux/mtd/rawnand.h> @@ -27,7 +28,7 @@ static int nand_command(int block, int page, uint32_t offs, u8 cmd) { struct nand_chip *this = mtd_to_nand(mtd); - int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; + int page_addr = page + block * SYS_NAND_BLOCK_PAGES; while (!this->dev_ready(mtd)) ; @@ -59,7 +60,7 @@ static int nand_command(int block, int page, uint32_t offs, u8 cmd) { struct nand_chip *this = mtd_to_nand(mtd); - int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT; + int page_addr = page + block * SYS_NAND_BLOCK_PAGES; void (*hwctrl)(struct mtd_info *mtd, int cmd, unsigned int ctrl) = this->cmd_ctrl; @@ -226,6 +227,11 @@ void nand_init(void) nand_chip.select_chip(mtd, 0); } +unsigned int nand_page_size(void) +{ + return nand_to_mtd(&nand_chip)->writesize; +} + /* Unselect after operation */ void nand_deselect(void) { diff --git a/drivers/mtd/nand/raw/octeontx_nand.c b/drivers/mtd/nand/raw/octeontx_nand.c index 65a03d22c1..3b20685fac 100644 --- a/drivers/mtd/nand/raw/octeontx_nand.c +++ b/drivers/mtd/nand/raw/octeontx_nand.c @@ -24,6 +24,7 @@ #include <linux/mtd/nand_bch.h> #include <linux/mtd/nand_ecc.h> #include <linux/mtd/rawnand.h> +#include <linux/time.h> #include <asm/global_data.h> #include <asm/io.h> #include <asm/types.h> @@ -291,7 +292,6 @@ union ndf_cmd { #define OCTEONTX_NAND_DRIVER_NAME "octeontx_nand" #define NDF_TIMEOUT 1000 /** Timeout in ms */ -#define USEC_PER_SEC 1000000 /** Linux compatibility */ #ifndef NAND_MAX_CHIPS # define NAND_MAX_CHIPS 8 /** Linux compatibility */ #endif diff --git a/drivers/mtd/nand/raw/omap_gpmc.c b/drivers/mtd/nand/raw/omap_gpmc.c index 1a5ed0de31..0e25bd5dc2 100644 --- a/drivers/mtd/nand/raw/omap_gpmc.c +++ b/drivers/mtd/nand/raw/omap_gpmc.c @@ -6,6 +6,7 @@ #include <common.h> #include <log.h> +#include <system-constants.h> #include <asm/io.h> #include <dm/uclass.h> #include <linux/errno.h> @@ -1298,7 +1299,7 @@ static int nand_is_bad_block(int block) static int nand_read_page(int block, int page, uchar *dst) { - int page_addr = block * CONFIG_SYS_NAND_PAGE_COUNT + page; + int page_addr = block * SYS_NAND_BLOCK_PAGES + page; loff_t ofs = page_addr * CONFIG_SYS_NAND_PAGE_SIZE; int ret; size_t len = CONFIG_SYS_NAND_PAGE_SIZE; diff --git a/drivers/mtd/nand/raw/sand_nand.c b/drivers/mtd/nand/raw/sand_nand.c new file mode 100644 index 0000000000..229d7b5b65 --- /dev/null +++ b/drivers/mtd/nand/raw/sand_nand.c @@ -0,0 +1,707 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) Sean Anderson <seanga2@gmail.com> + */ + +#define LOG_CATEGORY UCLASS_MTD +#include <errno.h> +#include <hexdump.h> +#include <log.h> +#include <nand.h> +#include <os.h> +#include <rand.h> +#include <spl.h> +#include <system-constants.h> +#include <dm/device_compat.h> +#include <dm/read.h> +#include <dm/uclass.h> +#include <asm/bitops.h> +#include <linux/bitmap.h> +#include <linux/mtd/rawnand.h> +#include <linux/sizes.h> + +enum sand_nand_state { + STATE_READY, + STATE_IDLE, + STATE_READ, + STATE_READ_ID, + STATE_READ_ONFI, + STATE_PARAM_ONFI, + STATE_STATUS, + STATE_PROG, + STATE_ERASE, +}; + +static const char *const state_name[] = { + [STATE_READY] = "READY", + [STATE_IDLE] = "IDLE", + [STATE_READ] = "READ", + [STATE_READ_ID] = "READ_ID", + [STATE_READ_ONFI] = "READ_ONFI", + [STATE_PARAM_ONFI] = "PARAM_ONFI", + [STATE_STATUS] = "STATUS", + [STATE_PROG] = "PROG", + [STATE_ERASE] = "ERASE", +}; + +/** + * struct sand_nand_chip - Per-device private data + * @nand: The nand chip + * @node: The next device in this controller + * @programmed: Bitmap of whether sectors are programmed + * @id: ID to report for NAND_CMD_READID + * @id_len: Length of @id + * @onfi: Three copies of ONFI parameter page + * @status: Status to report for NAND_CMD_STATUS + * @chunksize: Size of one "chunk" (page + oob) in bytes + * @pageize: Size of one page in bytes + * @pages: Total number of pages + * @pages_per_erase: Number of pages per eraseblock + * @err_count: Number of errors to inject per @err_step_bits of data + * @err_step_bits: Number of data bits per error "step" + * @err_steps: Number of err steps in a page + * @cs: Chip select for this device + * @state: Current state of the device + * @column: Column of the most-recent command + * @page_addr: Page address of the most-recent command + * @fd: File descriptor for the backing data + * @fd_page_addr: Page address that @fd is seek'd to + * @selected: Whether this device is selected + * @tmp: "Cache" buffer used to store transferred data before committing it + * @tmp_dirty: Whether @tmp is dirty (modified) or clean (all ones) + * + * Data is stored with the OOB area in-line. For example, with 512-byte pages + * and and 16-byte OOB areas, the first page would start at offset 0, the second + * at offset 528, the third at offset 1056, and so on + */ +struct sand_nand_chip { + struct nand_chip nand; + struct list_head node; + long *programmed; + const u8 *id; + u32 chunksize, pagesize, pages, pages_per_erase; + u32 err_count, err_step_bits, err_steps, ecc_bits; + unsigned int cs; + enum sand_nand_state state; + int column, page_addr, fd, fd_page_addr; + bool selected, tmp_dirty; + u8 status; + u8 id_len; + u8 tmp[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE]; + u8 onfi[sizeof(struct nand_onfi_params) * 3]; +}; + +#define SAND_DEBUG(chip, fmt, ...) \ + dev_dbg((chip)->nand.mtd.dev, "%u (%s): " fmt, (chip)->cs, \ + state_name[(chip)->state], ##__VA_ARGS__) + +static inline void to_state(struct sand_nand_chip *chip, + enum sand_nand_state new_state) +{ + if (new_state != chip->state) + SAND_DEBUG(chip, "to state %s\n", state_name[new_state]); + chip->state = new_state; +} + +static inline struct sand_nand_chip *to_sand_nand(struct nand_chip *nand) +{ + return container_of(nand, struct sand_nand_chip, nand); +} + +struct sand_nand_priv { + struct list_head chips; +}; + +static int sand_nand_dev_ready(struct mtd_info *mtd) +{ + return 1; +} + +static int sand_nand_wait(struct mtd_info *mtd, struct nand_chip *chip) +{ + u8 status; + + return nand_status_op(chip, &status) ?: status; +} + +static int sand_nand_seek(struct sand_nand_chip *chip) +{ + if (chip->fd_page_addr == chip->page_addr) + return 0; + + if (os_lseek(chip->fd, (off_t)chip->page_addr * chip->chunksize, + OS_SEEK_SET) < 0) { + SAND_DEBUG(chip, "could not seek: %d\n", errno); + return -EIO; + } + + chip->fd_page_addr = chip->page_addr; + return 0; +} + +static void sand_nand_inject_error(struct sand_nand_chip *chip, + unsigned int step, unsigned int pos) +{ + int byte, index; + + if (pos < chip->err_step_bits) { + __change_bit(step * chip->err_step_bits + pos, chip->tmp); + return; + } + + /* + * Only ECC bytes are covered in the OOB area, so + * pretend that those are the only bytes which can have + * errors. + */ + byte = (pos - chip->err_step_bits + step * chip->ecc_bits) / 8; + index = chip->nand.ecc.layout->eccpos[byte]; + /* Avoid endianness issues by working with bytes */ + chip->tmp[chip->pagesize + index] ^= BIT(pos & 0x7); +} + +static int sand_nand_read(struct sand_nand_chip *chip) +{ + unsigned int i, stop = 0; + + if (chip->column == chip->pagesize) + stop = chip->err_step_bits; + + if (test_bit(chip->page_addr, chip->programmed)) { + if (sand_nand_seek(chip)) + return -EIO; + + if (os_read(chip->fd, chip->tmp, chip->chunksize) != + chip->chunksize) { + SAND_DEBUG(chip, "could not read: %d\n", errno); + return -EIO; + } + chip->fd_page_addr++; + } else if (chip->tmp_dirty) { + memset(chip->tmp + chip->column, 0xff, + chip->chunksize - chip->column); + } + + /* + * Inject some errors; this is Method A from "An Efficient Algorithm for + * Sequential Random Sampling" (Vitter 87). This is still slow when + * generating a lot (dozens) of ECC errors. + * + * To avoid generating too many errors in any one ECC step, we separate + * our error generation by ECC step. + */ + chip->tmp_dirty = true; + for (i = 0; i < chip->err_steps; i++) { + u32 bit_errors = chip->err_count; + unsigned int j = chip->err_step_bits + chip->ecc_bits; + + while (bit_errors) { + unsigned int u = rand(); + float quot = 1ULL << 32; + + do { + quot *= j - bit_errors; + quot /= j; + j--; + + if (j < stop) + goto next; + } while (u < quot); + + sand_nand_inject_error(chip, i, j); + bit_errors--; + } +next: + ; + } + + return 0; +} + +static void sand_nand_command(struct mtd_info *mtd, unsigned int command, + int column, int page_addr) +{ + struct nand_chip *nand = mtd_to_nand(mtd); + struct sand_nand_chip *chip = to_sand_nand(nand); + enum sand_nand_state new_state = chip->state; + + SAND_DEBUG(chip, "command=%02x column=%d page_addr=%d\n", command, + column, page_addr); + + if (!chip->selected) + return; + + switch (chip->state) { + case STATE_READY: + if (command == NAND_CMD_RESET) + goto reset; + break; + case STATE_PROG: + new_state = STATE_IDLE; + if (command != NAND_CMD_PAGEPROG || + test_and_set_bit(chip->page_addr, chip->programmed)) { + chip->status |= NAND_STATUS_FAIL; + break; + } + + if (sand_nand_seek(chip)) { + chip->status |= NAND_STATUS_FAIL; + break; + } + + if (os_write(chip->fd, chip->tmp, chip->chunksize) != + chip->chunksize) { + SAND_DEBUG(chip, "could not write: %d\n", errno); + chip->status |= NAND_STATUS_FAIL; + break; + } + + chip->fd_page_addr++; + break; + case STATE_ERASE: + new_state = STATE_IDLE; + if (command != NAND_CMD_ERASE2) { + chip->status |= NAND_STATUS_FAIL; + break; + } + + if (chip->page_addr < 0 || + chip->page_addr >= chip->pages || + chip->page_addr % chip->pages_per_erase) + chip->status |= NAND_STATUS_FAIL; + else + bitmap_clear(chip->programmed, chip->page_addr, + chip->pages_per_erase); + break; + default: + chip->column = column; + chip->page_addr = page_addr; + switch (command) { + case NAND_CMD_READOOB: + if (column >= 0) + chip->column += chip->pagesize; + fallthrough; + case NAND_CMD_READ0: + new_state = STATE_IDLE; + if (page_addr < 0 || page_addr >= chip->pages) + break; + + if (chip->column < 0 || chip->column >= chip->chunksize) + break; + + if (sand_nand_read(chip)) + break; + + chip->page_addr = page_addr; + new_state = STATE_READ; + break; + case NAND_CMD_ERASE1: + new_state = STATE_ERASE; + chip->status = ~NAND_STATUS_FAIL; + break; + case NAND_CMD_STATUS: + new_state = STATE_STATUS; + chip->column = 0; + break; + case NAND_CMD_SEQIN: + new_state = STATE_PROG; + chip->status = ~NAND_STATUS_FAIL; + if (page_addr < 0 || page_addr >= chip->pages || + chip->column < 0 || + chip->column >= chip->chunksize) { + chip->status |= NAND_STATUS_FAIL; + } else if (chip->tmp_dirty) { + memset(chip->tmp, 0xff, chip->chunksize); + chip->tmp_dirty = false; + } + break; + case NAND_CMD_READID: + if (chip->onfi[0] && column == 0x20) + new_state = STATE_READ_ONFI; + else + new_state = STATE_READ_ID; + chip->column = 0; + break; + case NAND_CMD_PARAM: + if (chip->onfi[0] && !column) + new_state = STATE_PARAM_ONFI; + else + new_state = STATE_IDLE; + break; + case NAND_CMD_RESET: +reset: + new_state = STATE_IDLE; + chip->column = -1; + chip->page_addr = -1; + chip->status = ~NAND_STATUS_FAIL; + break; + default: + new_state = STATE_IDLE; + SAND_DEBUG(chip, "Unsupported command %02x\n", command); + } + } + + to_state(chip, new_state); +} + +static void sand_nand_select_chip(struct mtd_info *mtd, int n) +{ + struct nand_chip *nand = mtd_to_nand(mtd); + struct sand_nand_chip *chip = to_sand_nand(nand); + + chip->selected = !n; +} + +static void sand_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) +{ + struct nand_chip *nand = mtd_to_nand(mtd); + struct sand_nand_chip *chip = to_sand_nand(nand); + unsigned int to_copy; + int src_len = 0; + const u8 *src = NULL; + + if (!chip->selected) + goto copy; + + switch (chip->state) { + case STATE_READ: + src = chip->tmp; + src_len = chip->chunksize; + break; + case STATE_READ_ID: + src = chip->id; + src_len = chip->id_len; + break; + case STATE_READ_ONFI: + src = "ONFI"; + src_len = 4; + break; + case STATE_PARAM_ONFI: + src = chip->onfi; + src_len = sizeof(chip->onfi); + break; + case STATE_STATUS: + src = &chip->status; + src_len = 1; + break; + default: + break; + } + +copy: + if (chip->column >= 0) + to_copy = max(min(len, src_len - chip->column), 0); + else + to_copy = 0; + memcpy(buf, src + chip->column, to_copy); + memset(buf + to_copy, 0xff, len - to_copy); + chip->column += to_copy; + + if (len == 1) { + SAND_DEBUG(chip, "read [ %02x ]\n", buf[0]); + } else if (src_len) { + SAND_DEBUG(chip, "read %d bytes\n", len); +#ifdef VERBOSE_DEBUG + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); +#endif + } + + if (src_len && chip->column == src_len) + to_state(chip, STATE_IDLE); +} + +static u8 sand_nand_read_byte(struct mtd_info *mtd) +{ + u8 ret; + + sand_nand_read_buf(mtd, &ret, 1); + return ret; +} + +static u16 sand_nand_read_word(struct mtd_info *mtd) +{ + struct nand_chip *nand = mtd_to_nand(mtd); + struct sand_nand_chip *chip = to_sand_nand(nand); + + SAND_DEBUG(chip, "16-bit access unsupported\n"); + return sand_nand_read_byte(mtd) | 0xff00; +} + +static void sand_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) +{ + struct nand_chip *nand = mtd_to_nand(mtd); + struct sand_nand_chip *chip = to_sand_nand(nand); + + SAND_DEBUG(chip, "write %d bytes\n", len); +#ifdef VERBOSE_DEBUG + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); +#endif + + if (chip->state != STATE_PROG || chip->status & NAND_STATUS_FAIL) + return; + + chip->tmp_dirty = true; + len = min((unsigned int)len, chip->chunksize - chip->column); + memcpy(chip->tmp + chip->column, buf, len); + chip->column += len; +} + +static struct nand_chip *nand_chip; + +int sand_nand_remove(struct udevice *dev) +{ + struct sand_nand_priv *priv = dev_get_priv(dev); + struct sand_nand_chip *chip; + + list_for_each_entry(chip, &priv->chips, node) { + struct nand_chip *nand = &chip->nand; + + if (nand_chip == nand) + nand_chip = NULL; + + nand_unregister(nand_to_mtd(nand)); + free(chip->programmed); + os_close(chip->fd); + free(chip); + } + + return 0; +} + +static int sand_nand_probe(struct udevice *dev) +{ + struct sand_nand_priv *priv = dev_get_priv(dev); + struct sand_nand_chip *chip; + int ret, devnum = 0; + ofnode np; + + INIT_LIST_HEAD(&priv->chips); + + dev_for_each_subnode(np, dev) { + struct nand_chip *nand; + struct mtd_info *mtd; + u32 erasesize, oobsize, pagesize, pages; + u32 err_count, err_step_size; + off_t expected_size; + char filename[30]; + fdt_addr_t cs; + const u8 *id, *onfi; + int id_len, onfi_len; + + cs = ofnode_get_addr_size_index_notrans(np, 0, NULL); + if (cs == FDT_ADDR_T_NONE) { + dev_dbg(dev, "Invalid cs for chip %s\n", + ofnode_get_name(np)); + ret = -ENOENT; + goto err; + } + + id = ofnode_read_prop(np, "sandbox,id", &id_len); + if (!id) { + dev_dbg(dev, "No sandbox,id property for chip %s\n", + ofnode_get_name(np)); + ret = -EINVAL; + goto err; + } + + onfi = ofnode_read_prop(np, "sandbox,onfi", &onfi_len); + if (onfi && onfi_len != sizeof(struct nand_onfi_params)) { + dev_dbg(dev, "Invalid length %d for onfi params\n", + onfi_len); + ret = -EINVAL; + goto err; + } + + ret = ofnode_read_u32(np, "sandbox,erasesize", &erasesize); + if (ret) { + dev_dbg(dev, "No sandbox,erasesize property for chip %s", + ofnode_get_name(np)); + goto err; + } + + ret = ofnode_read_u32(np, "sandbox,oobsize", &oobsize); + if (ret) { + dev_dbg(dev, "No sandbox,oobsize property for chip %s", + ofnode_get_name(np)); + goto err; + } + + ret = ofnode_read_u32(np, "sandbox,pagesize", &pagesize); + if (ret) { + dev_dbg(dev, "No sandbox,pagesize property for chip %s", + ofnode_get_name(np)); + goto err; + } + + ret = ofnode_read_u32(np, "sandbox,pages", &pages); + if (ret) { + dev_dbg(dev, "No sandbox,pages property for chip %s", + ofnode_get_name(np)); + goto err; + } + + ret = ofnode_read_u32(np, "sandbox,err-count", &err_count); + if (ret) { + dev_dbg(dev, + "No sandbox,err-count property for chip %s", + ofnode_get_name(np)); + goto err; + } + + ret = ofnode_read_u32(np, "sandbox,err-step-size", + &err_step_size); + if (ret) { + dev_dbg(dev, + "No sandbox,err-step-size property for chip %s", + ofnode_get_name(np)); + goto err; + } + + chip = calloc(sizeof(*chip), 1); + if (!chip) { + ret = -ENOMEM; + goto err; + } + + chip->cs = cs; + chip->id = id; + chip->id_len = id_len; + chip->chunksize = pagesize + oobsize; + chip->pagesize = pagesize; + chip->pages = pages; + chip->pages_per_erase = erasesize / pagesize; + memset(chip->tmp, 0xff, chip->chunksize); + + chip->err_count = err_count; + chip->err_step_bits = err_step_size * 8; + chip->err_steps = pagesize / err_step_size; + + expected_size = (off_t)pages * chip->chunksize; + snprintf(filename, sizeof(filename), + "/tmp/u-boot.nand%d.XXXXXX", devnum); + chip->fd = os_mktemp(filename, expected_size); + if (chip->fd < 0) { + dev_dbg(dev, "Could not create temp file %s\n", + filename); + ret = chip->fd; + goto err_chip; + } + + chip->programmed = calloc(sizeof(long), + BITS_TO_LONGS(pages)); + if (!chip->programmed) { + ret = -ENOMEM; + goto err_fd; + } + + if (onfi) { + memcpy(chip->onfi, onfi, onfi_len); + memcpy(chip->onfi + onfi_len, onfi, onfi_len); + memcpy(chip->onfi + 2 * onfi_len, onfi, onfi_len); + } + + nand = &chip->nand; + nand->options = spl_in_proper() ? 0 : NAND_SKIP_BBTSCAN; + nand->flash_node = np; + nand->dev_ready = sand_nand_dev_ready; + nand->cmdfunc = sand_nand_command; + nand->waitfunc = sand_nand_wait; + nand->select_chip = sand_nand_select_chip; + nand->read_byte = sand_nand_read_byte; + nand->read_word = sand_nand_read_word; + nand->read_buf = sand_nand_read_buf; + nand->write_buf = sand_nand_write_buf; + nand->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; + + mtd = nand_to_mtd(nand); + mtd->dev = dev; + + ret = nand_scan(mtd, CONFIG_SYS_NAND_MAX_CHIPS); + if (ret) { + dev_dbg(dev, "Could not scan chip %s: %d\n", + ofnode_get_name(np), ret); + goto err_prog; + } + chip->ecc_bits = nand->ecc.layout->eccbytes * 8 / + chip->err_steps; + + ret = nand_register(devnum, mtd); + if (ret) { + dev_dbg(dev, "Could not register nand %d: %d\n", devnum, + ret); + goto err_prog; + } + + if (!nand_chip) + nand_chip = nand; + + list_add_tail(&chip->node, &priv->chips); + devnum++; + continue; + +err_prog: + free(chip->programmed); +err_fd: + os_close(chip->fd); +err_chip: + free(chip); + goto err; + } + + return 0; + +err: + sand_nand_remove(dev); + return ret; +} + +static const struct udevice_id sand_nand_ids[] = { + { .compatible = "sandbox,nand" }, + { } +}; + +U_BOOT_DRIVER(sand_nand) = { + .name = "sand-nand", + .id = UCLASS_MTD, + .of_match = sand_nand_ids, + .probe = sand_nand_probe, + .remove = sand_nand_remove, + .priv_auto = sizeof(struct sand_nand_priv), +}; + +void board_nand_init(void) +{ + struct udevice *dev; + int err; + + err = uclass_get_device_by_driver(UCLASS_MTD, DM_DRIVER_REF(sand_nand), + &dev); + if (err && err != -ENODEV) + log_info("Failed to get sandbox NAND: %d\n", err); +} + +#if IS_ENABLED(CONFIG_SPL_BUILD) && IS_ENABLED(CONFIG_SPL_NAND_INIT) +void nand_deselect(void) +{ + nand_chip->select_chip(nand_to_mtd(nand_chip), -1); +} + +static int nand_is_bad_block(int block) +{ + struct mtd_info *mtd = nand_to_mtd(nand_chip); + + return mtd_block_isbad(mtd, block << mtd->erasesize_shift); +} + +static int nand_read_page(int block, int page, uchar *dst) +{ + struct mtd_info *mtd = nand_to_mtd(nand_chip); + loff_t ofs = ((loff_t)block << mtd->erasesize_shift) + + ((loff_t)page << mtd->writesize_shift); + size_t len = mtd->writesize; + + return nand_read(mtd, ofs, &len, dst); +} + +#include "nand_spl_loaders.c" +#endif /* CONFIG_SPL_NAND_INIT */ diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index 64be6486b4..3528824575 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -22,6 +22,7 @@ #include <linux/ioport.h> #include <linux/mtd/rawnand.h> #include <linux/printk.h> +#include <linux/time.h> /* Bad block marker length */ #define FMC2_BBM_LEN 2 @@ -127,8 +128,6 @@ #define FMC2_BCHDSR4_EBP7 GENMASK(12, 0) #define FMC2_BCHDSR4_EBP8 GENMASK(28, 16) -#define FMC2_NSEC_PER_SEC 1000000000L - #define FMC2_TIMEOUT_5S 5000000 enum stm32_fmc2_ecc { @@ -603,7 +602,7 @@ static void stm32_fmc2_nfc_calc_timings(struct nand_chip *chip, struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); struct stm32_fmc2_timings *tims = &nand->timings; unsigned long hclk = clk_get_rate(&nfc->clk); - unsigned long hclkp = FMC2_NSEC_PER_SEC / (hclk / 1000); + unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000); unsigned long timing, tar, tclr, thiz, twait; unsigned long tset_mem, tset_att, thold_mem, thold_att; diff --git a/drivers/mtd/nand/raw/sunxi_nand_spl.c b/drivers/mtd/nand/raw/sunxi_nand_spl.c index 6de0b0a355..c9b8c78ed7 100644 --- a/drivers/mtd/nand/raw/sunxi_nand_spl.c +++ b/drivers/mtd/nand/raw/sunxi_nand_spl.c @@ -524,9 +524,10 @@ static int nand_read_buffer(struct nfc_config *conf, uint32_t offs, return 0; } +static struct nfc_config conf; + int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) { - static struct nfc_config conf = { }; int ret; ret = nand_detect_config(&conf, offs, dest); @@ -536,6 +537,11 @@ int nand_spl_load_image(uint32_t offs, unsigned int size, void *dest) return nand_read_buffer(&conf, offs, size, dest); } +unsigned int nand_page_size(void) +{ + return conf.page_size; +} + void nand_deselect(void) { struct sunxi_ccm_reg *const ccm = diff --git a/drivers/mtd/onenand/onenand_uboot.c b/drivers/mtd/onenand/onenand_uboot.c index 04791df69b..ecacabefad 100644 --- a/drivers/mtd/onenand/onenand_uboot.c +++ b/drivers/mtd/onenand/onenand_uboot.c @@ -44,14 +44,12 @@ void onenand_init(void) puts("Flex-"); puts("OneNAND: "); -#ifdef CONFIG_MTD /* * Add MTD device so that we can reference it later * via the mtdcore infrastructure (e.g. ubi). */ onenand_mtd.name = dev_name; add_mtd_device(&onenand_mtd); -#endif } print_size(onenand_chip.chipsize, "\n"); } diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index ebab4d9f2e..23ad2c29d0 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -471,14 +471,6 @@ config SYS_UNIFY_CACHE depends on MCFFEC bool "Invalidate icache during ethernet operations" -config FSLDMAFEC - bool "ColdFire DMA Ethernet Support" - select PHYLIB - select SYS_DISCOVER_PHY - help - This driver supports the network interface units in the - ColdFire family. - config KS8851_MLL bool "Microchip KS8851-MLL controller driver" help diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 1ce6fea323..f9aed1646c 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -37,7 +37,6 @@ obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o obj-$(CONFIG_FEC_MXC) += fec_mxc.o obj-$(CONFIG_FMAN_ENET) += fm/ obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o -obj-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o mcfmii.o obj-$(CONFIG_FSL_ENETC) += fsl_enetc.o fsl_enetc_mdio.o obj-$(CONFIG_FSL_LS_MDIO) += fsl_ls_mdio.o obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/ diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index a4e3698c60..e40e399c80 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1711,6 +1711,10 @@ static const struct udevice_id eqos_ids[] = { .compatible = "nxp,imx8mp-dwmac-eqos", .data = (ulong)&eqos_imx_config }, + { + .compatible = "nxp,imx93-dwmac-eqos", + .data = (ulong)&eqos_imx_config + }, #endif #if IS_ENABLED(CONFIG_DWC_ETH_QOS_ROCKCHIP) { diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c index 60f3f3f5a1..e3f55dd981 100644 --- a/drivers/net/dwc_eth_qos_imx.c +++ b/drivers/net/dwc_eth_qos_imx.c @@ -181,6 +181,9 @@ static int eqos_set_tx_clk_speed_imx(struct udevice *dev) ulong rate; int ret; + if (device_is_compatible(dev, "nxp,imx93-dwmac-eqos")) + return 0; + debug("%s(dev=%p):\n", __func__, dev); if (eqos->phy->interface == PHY_INTERFACE_MODE_RMII) diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c index 7dfa821909..a8caa0f092 100644 --- a/drivers/net/fm/fm.c +++ b/drivers/net/fm/fm.c @@ -3,7 +3,6 @@ * Copyright 2009-2011 Freescale Semiconductor, Inc. * Dave Liu <daveliu@freescale.com> */ -#include <common.h> #include <env.h> #include <fs_loader.h> #include <image.h> diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c deleted file mode 100644 index cc61a10740..0000000000 --- a/drivers/net/fsl_mcdmafec.c +++ /dev/null @@ -1,592 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2000-2004 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2007 Freescale Semiconductor, Inc. - * TsiChung Liew (Tsi-Chung.Liew@freescale.com) - * - * Conversion to DM - * (C) 2019 Angelo Dureghello <angelo.dureghello@timesys.com> - */ - -#include <common.h> -#include <env.h> -#include <hang.h> -#include <malloc.h> -#include <command.h> -#include <config.h> -#include <net.h> -#include <miiphy.h> -#include <asm/global_data.h> -#include <linux/delay.h> -#include <linux/mii.h> -#include <asm/immap.h> -#include <asm/fsl_mcdmafec.h> - -#include "MCD_dma.h" - -#undef ET_DEBUG -#undef MII_DEBUG - -/* Ethernet Transmit and Receive Buffers */ -#define DBUF_LENGTH 1520 -#define PKT_MAXBUF_SIZE 1518 -#define FIFO_ERRSTAT (FIFO_STAT_RXW | FIFO_STAT_UF | FIFO_STAT_OF) - -/* RxBD bits definitions */ -#define BD_ENET_RX_ERR (BD_ENET_RX_LG | BD_ENET_RX_NO | BD_ENET_RX_CR | \ - BD_ENET_RX_OV | BD_ENET_RX_TR) - -DECLARE_GLOBAL_DATA_PTR; - -static void init_eth_info(struct fec_info_dma *info) -{ - /* setup Receive and Transmit buffer descriptor */ -#ifdef CFG_SYS_FEC_BUF_USE_SRAM - static u32 tmp; - - if (info->index == 0) - tmp = CFG_SYS_INIT_RAM_ADDR + 0x1000; - else - info->rxbd = (cbd_t *)DBUF_LENGTH; - - info->rxbd = (cbd_t *)((u32)info->rxbd + tmp); - tmp = (u32)info->rxbd; - info->txbd = - (cbd_t *)((u32)info->txbd + tmp + - (PKTBUFSRX * sizeof(cbd_t))); - tmp = (u32)info->txbd; - info->txbuf = - (char *)((u32)info->txbuf + tmp + - (CFG_SYS_TX_ETH_BUFFER * sizeof(cbd_t))); - tmp = (u32)info->txbuf; -#else - info->rxbd = - (cbd_t *)memalign(CONFIG_SYS_CACHELINE_SIZE, - (PKTBUFSRX * sizeof(cbd_t))); - info->txbd = - (cbd_t *)memalign(CONFIG_SYS_CACHELINE_SIZE, - (CFG_SYS_TX_ETH_BUFFER * sizeof(cbd_t))); - info->txbuf = - (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, DBUF_LENGTH); -#endif - -#ifdef ET_DEBUG - printf("rxbd %x txbd %x\n", (int)info->rxbd, (int)info->txbd); -#endif - info->phy_name = (char *)memalign(CONFIG_SYS_CACHELINE_SIZE, 32); -} - -static void fec_halt(struct udevice *dev) -{ - struct fec_info_dma *info = dev_get_priv(dev); - volatile fecdma_t *fecp = (fecdma_t *)info->iobase; - int counter = 0xffff; - - /* issue graceful stop command to the FEC transmitter if necessary */ - fecp->tcr |= FEC_TCR_GTS; - - /* wait for graceful stop to register */ - while ((counter--) && (!(fecp->eir & FEC_EIR_GRA))) - ; - - /* Disable DMA tasks */ - MCD_killDma(info->tx_task); - MCD_killDma(info->rx_task); - - /* Disable the Ethernet Controller */ - fecp->ecr &= ~FEC_ECR_ETHER_EN; - - /* Clear FIFO status registers */ - fecp->rfsr &= FIFO_ERRSTAT; - fecp->tfsr &= FIFO_ERRSTAT; - - fecp->frst = 0x01000000; - - /* Issue a reset command to the FEC chip */ - fecp->ecr |= FEC_ECR_RESET; - - /* wait at least 20 clock cycles */ - mdelay(10); - -#ifdef ET_DEBUG - printf("Ethernet task stopped\n"); -#endif -} - -#ifdef ET_DEBUG -static void dbg_fec_regs(struct eth_device *dev) -{ - struct fec_info_dma *info = dev->priv; - volatile fecdma_t *fecp = (fecdma_t *)info->iobase; - - printf("=====\n"); - printf("ievent %x - %x\n", (int)&fecp->eir, fecp->eir); - printf("imask %x - %x\n", (int)&fecp->eimr, fecp->eimr); - printf("ecntrl %x - %x\n", (int)&fecp->ecr, fecp->ecr); - printf("mii_mframe %x - %x\n", (int)&fecp->mmfr, fecp->mmfr); - printf("mii_speed %x - %x\n", (int)&fecp->mscr, fecp->mscr); - printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc); - printf("r_cntrl %x - %x\n", (int)&fecp->rcr, fecp->rcr); - printf("r hash %x - %x\n", (int)&fecp->rhr, fecp->rhr); - printf("x_cntrl %x - %x\n", (int)&fecp->tcr, fecp->tcr); - printf("padr_l %x - %x\n", (int)&fecp->palr, fecp->palr); - printf("padr_u %x - %x\n", (int)&fecp->paur, fecp->paur); - printf("op_pause %x - %x\n", (int)&fecp->opd, fecp->opd); - printf("iadr_u %x - %x\n", (int)&fecp->iaur, fecp->iaur); - printf("iadr_l %x - %x\n", (int)&fecp->ialr, fecp->ialr); - printf("gadr_u %x - %x\n", (int)&fecp->gaur, fecp->gaur); - printf("gadr_l %x - %x\n", (int)&fecp->galr, fecp->galr); - printf("x_wmrk %x - %x\n", (int)&fecp->tfwr, fecp->tfwr); - printf("r_fdata %x - %x\n", (int)&fecp->rfdr, fecp->rfdr); - printf("r_fstat %x - %x\n", (int)&fecp->rfsr, fecp->rfsr); - printf("r_fctrl %x - %x\n", (int)&fecp->rfcr, fecp->rfcr); - printf("r_flrfp %x - %x\n", (int)&fecp->rlrfp, fecp->rlrfp); - printf("r_flwfp %x - %x\n", (int)&fecp->rlwfp, fecp->rlwfp); - printf("r_frfar %x - %x\n", (int)&fecp->rfar, fecp->rfar); - printf("r_frfrp %x - %x\n", (int)&fecp->rfrp, fecp->rfrp); - printf("r_frfwp %x - %x\n", (int)&fecp->rfwp, fecp->rfwp); - printf("t_fdata %x - %x\n", (int)&fecp->tfdr, fecp->tfdr); - printf("t_fstat %x - %x\n", (int)&fecp->tfsr, fecp->tfsr); - printf("t_fctrl %x - %x\n", (int)&fecp->tfcr, fecp->tfcr); - printf("t_flrfp %x - %x\n", (int)&fecp->tlrfp, fecp->tlrfp); - printf("t_flwfp %x - %x\n", (int)&fecp->tlwfp, fecp->tlwfp); - printf("t_ftfar %x - %x\n", (int)&fecp->tfar, fecp->tfar); - printf("t_ftfrp %x - %x\n", (int)&fecp->tfrp, fecp->tfrp); - printf("t_ftfwp %x - %x\n", (int)&fecp->tfwp, fecp->tfwp); - printf("frst %x - %x\n", (int)&fecp->frst, fecp->frst); - printf("ctcwr %x - %x\n", (int)&fecp->ctcwr, fecp->ctcwr); -} -#endif - -static void set_fec_duplex_speed(volatile fecdma_t *fecp, int dup_spd) -{ - struct bd_info *bd = gd->bd; - - if ((dup_spd >> 16) == FULL) { - /* Set maximum frame length */ - fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE | - FEC_RCR_PROM | 0x100; - fecp->tcr = FEC_TCR_FDEN; - } else { - /* Half duplex mode */ - fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | - FEC_RCR_MII_MODE | FEC_RCR_DRT; - fecp->tcr &= ~FEC_TCR_FDEN; - } - - if ((dup_spd & 0xFFFF) == _100BASET) { -#ifdef MII_DEBUG - printf("100Mbps\n"); -#endif - bd->bi_ethspeed = 100; - } else { -#ifdef MII_DEBUG - printf("10Mbps\n"); -#endif - bd->bi_ethspeed = 10; - } -} - -static void fec_set_hwaddr(volatile fecdma_t *fecp, u8 *mac) -{ - u8 curr_byte; /* byte for which to compute the CRC */ - int byte; /* loop - counter */ - int bit; /* loop - counter */ - u32 crc = 0xffffffff; /* initial value */ - - for (byte = 0; byte < 6; byte++) { - curr_byte = mac[byte]; - for (bit = 0; bit < 8; bit++) { - if ((curr_byte & 0x01) ^ (crc & 0x01)) { - crc >>= 1; - crc = crc ^ 0xedb88320; - } else { - crc >>= 1; - } - curr_byte >>= 1; - } - } - - crc = crc >> 26; - - /* Set individual hash table register */ - if (crc >= 32) { - fecp->ialr = (1 << (crc - 32)); - fecp->iaur = 0; - } else { - fecp->ialr = 0; - fecp->iaur = (1 << crc); - } - - /* Set physical address */ - fecp->palr = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3]; - fecp->paur = (mac[4] << 24) + (mac[5] << 16) + 0x8808; - - /* Clear multicast address hash table */ - fecp->gaur = 0; - fecp->galr = 0; -} - -static int fec_init(struct udevice *dev) -{ - struct fec_info_dma *info = dev_get_priv(dev); - volatile fecdma_t *fecp = (fecdma_t *)info->iobase; - int rval, i; - uchar enetaddr[6]; - -#ifdef ET_DEBUG - printf("fec_init: iobase 0x%08x ...\n", info->iobase); -#endif - - fecpin_setclear(info, 1); - fec_halt(dev); - - mii_init(); - set_fec_duplex_speed(fecp, info->dup_spd); - - /* We use strictly polling mode only */ - fecp->eimr = 0; - - /* Clear any pending interrupt */ - fecp->eir = 0xffffffff; - - /* Set station address */ - if (info->index == 0) - rval = eth_env_get_enetaddr("ethaddr", enetaddr); - else - rval = eth_env_get_enetaddr("eth1addr", enetaddr); - - if (!rval) { - puts("Please set a valid MAC address\n"); - return -EINVAL; - } - - fec_set_hwaddr(fecp, enetaddr); - - /* Set Opcode/Pause Duration Register */ - fecp->opd = 0x00010020; - - /* Setup Buffers and Buffer Descriptors */ - info->rx_idx = 0; - info->tx_idx = 0; - - /* Setup Receiver Buffer Descriptors (13.14.24.18) - * Settings: Empty, Wrap */ - for (i = 0; i < PKTBUFSRX; i++) { - info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY; - info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN; - info->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i]; - } - info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP; - - /* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19) - * Settings: Last, Tx CRC */ - for (i = 0; i < CFG_SYS_TX_ETH_BUFFER; i++) { - info->txbd[i].cbd_sc = 0; - info->txbd[i].cbd_datlen = 0; - info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]); - } - info->txbd[CFG_SYS_TX_ETH_BUFFER - 1].cbd_sc |= BD_ENET_TX_WRAP; - - info->used_tbd_idx = 0; - info->clean_tbd_num = CFG_SYS_TX_ETH_BUFFER; - - /* Set Rx FIFO alarm and granularity value */ - fecp->rfcr = 0x0c000000; - fecp->rfar = 0x0000030c; - - /* Set Tx FIFO granularity value */ - fecp->tfcr = FIFO_CTRL_FRAME | FIFO_CTRL_GR(6) | 0x00040000; - fecp->tfar = 0x00000080; - - fecp->tfwr = 0x2; - fecp->ctcwr = 0x03000000; - - /* Enable DMA receive task */ - MCD_startDma(info->rx_task, - (s8 *)info->rxbd, - 0, - (s8 *)&fecp->rfdr, - 4, - 0, - 4, - info->rx_init, - info->rx_pri, - (MCD_FECRX_DMA | MCD_TT_FLAGS_DEF), - (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) - ); - - /* Enable DMA tx task with no ready buffer descriptors */ - MCD_startDma(info->tx_task, - (s8 *)info->txbd, - 0, - (s8 *)&fecp->tfdr, - 4, - 0, - 4, - info->tx_init, - info->tx_pri, - (MCD_FECTX_DMA | MCD_TT_FLAGS_DEF), - (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) - ); - - /* Now enable the transmit and receive processing */ - fecp->ecr |= FEC_ECR_ETHER_EN; - - return 0; -} - -static int mcdmafec_init(struct udevice *dev) -{ - return fec_init(dev); -} - -static int mcdmafec_send(struct udevice *dev, void *packet, int length) -{ - struct fec_info_dma *info = dev_get_priv(dev); - cbd_t *p_tbd, *p_used_tbd; - u16 phy_status; - - miiphy_read(dev->name, info->phy_addr, MII_BMSR, &phy_status); - - /* process all the consumed TBDs */ - while (info->clean_tbd_num < CFG_SYS_TX_ETH_BUFFER) { - p_used_tbd = &info->txbd[info->used_tbd_idx]; - if (p_used_tbd->cbd_sc & BD_ENET_TX_READY) { -#ifdef ET_DEBUG - printf("Cannot clean TBD %d, in use\n", - info->clean_tbd_num); -#endif - return 0; - } - - /* clean this buffer descriptor */ - if (info->used_tbd_idx == (CFG_SYS_TX_ETH_BUFFER - 1)) - p_used_tbd->cbd_sc = BD_ENET_TX_WRAP; - else - p_used_tbd->cbd_sc = 0; - - /* update some indeces for a correct handling of TBD ring */ - info->clean_tbd_num++; - info->used_tbd_idx = (info->used_tbd_idx + 1) - % CFG_SYS_TX_ETH_BUFFER; - } - - /* Check for valid length of data. */ - if (length > 1500 || length <= 0) - return -1; - - /* Check the number of vacant TxBDs. */ - if (info->clean_tbd_num < 1) { - printf("No available TxBDs ...\n"); - return -1; - } - - /* Get the first TxBD to send the mac header */ - p_tbd = &info->txbd[info->tx_idx]; - p_tbd->cbd_datlen = length; - p_tbd->cbd_bufaddr = (u32)packet; - p_tbd->cbd_sc |= BD_ENET_TX_LAST | BD_ENET_TX_TC | BD_ENET_TX_READY; - info->tx_idx = (info->tx_idx + 1) % CFG_SYS_TX_ETH_BUFFER; - - /* Enable DMA transmit task */ - MCD_continDma(info->tx_task); - - info->clean_tbd_num -= 1; - - /* wait until frame is sent . */ - while (p_tbd->cbd_sc & BD_ENET_TX_READY) - udelay(10); - - return (int)(info->txbd[info->tx_idx].cbd_sc & BD_ENET_TX_STATS); -} - -static int mcdmafec_recv(struct udevice *dev, int flags, uchar **packetp) -{ - struct fec_info_dma *info = dev_get_priv(dev); - volatile fecdma_t *fecp = (fecdma_t *)info->iobase; - - cbd_t *prbd = &info->rxbd[info->rx_idx]; - u32 ievent; - int frame_length, len = 0; - - /* Check if any critical events have happened */ - ievent = fecp->eir; - if (ievent != 0) { - fecp->eir = ievent; - - if (ievent & (FEC_EIR_BABT | FEC_EIR_TXERR | FEC_EIR_RXERR)) { - printf("fec_recv: error\n"); - fec_halt(dev); - fec_init(dev); - return 0; - } - - if (ievent & FEC_EIR_HBERR) { - /* Heartbeat error */ - fecp->tcr |= FEC_TCR_GTS; - } - - if (ievent & FEC_EIR_GRA) { - /* Graceful stop complete */ - if (fecp->tcr & FEC_TCR_GTS) { - printf("fec_recv: tcr_gts\n"); - fec_halt(dev); - fecp->tcr &= ~FEC_TCR_GTS; - fec_init(dev); - } - } - } - - if (!(prbd->cbd_sc & BD_ENET_RX_EMPTY)) { - if ((prbd->cbd_sc & BD_ENET_RX_LAST) && - !(prbd->cbd_sc & BD_ENET_RX_ERR) && - ((prbd->cbd_datlen - 4) > 14)) { - /* Get buffer address and size */ - frame_length = prbd->cbd_datlen - 4; - - /* Fill the buffer and pass it to upper layers */ - net_process_received_packet((uchar *)prbd->cbd_bufaddr, - frame_length); - len = frame_length; - } - - /* Reset buffer descriptor as empty */ - if (info->rx_idx == (PKTBUFSRX - 1)) - prbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY); - else - prbd->cbd_sc = BD_ENET_RX_EMPTY; - - prbd->cbd_datlen = PKTSIZE_ALIGN; - - /* Now, we have an empty RxBD, restart the DMA receive task */ - MCD_continDma(info->rx_task); - - /* Increment BD count */ - info->rx_idx = (info->rx_idx + 1) % PKTBUFSRX; - } - - return len; -} - -static void mcdmafec_halt(struct udevice *dev) -{ - fec_halt(dev); -} - -static const struct eth_ops mcdmafec_ops = { - .start = mcdmafec_init, - .send = mcdmafec_send, - .recv = mcdmafec_recv, - .stop = mcdmafec_halt, -}; - -/* - * Boot sequence, called just after mcffec_of_to_plat, - * as DM way, it replaces old mcffec_initialize. - */ -static int mcdmafec_probe(struct udevice *dev) -{ - struct fec_info_dma *info = dev_get_priv(dev); - struct eth_pdata *pdata = dev_get_plat(dev); - int node = dev_of_offset(dev); - int retval; - const u32 *val; - - info->index = dev_seq(dev); - info->iobase = pdata->iobase; - info->miibase = pdata->iobase; - info->phy_addr = -1; - - val = fdt_getprop(gd->fdt_blob, node, "rx-task", NULL); - if (val) - info->rx_task = fdt32_to_cpu(*val); - - val = fdt_getprop(gd->fdt_blob, node, "tx-task", NULL); - if (val) - info->tx_task = fdt32_to_cpu(*val); - - val = fdt_getprop(gd->fdt_blob, node, "rx-prioprity", NULL); - if (val) - info->rx_pri = fdt32_to_cpu(*val); - - val = fdt_getprop(gd->fdt_blob, node, "tx-prioprity", NULL); - if (val) - info->tx_pri = fdt32_to_cpu(*val); - - val = fdt_getprop(gd->fdt_blob, node, "rx-init", NULL); - if (val) - info->rx_init = fdt32_to_cpu(*val); - - val = fdt_getprop(gd->fdt_blob, node, "tx-init", NULL); - if (val) - info->tx_init = fdt32_to_cpu(*val); - -#ifdef CFG_SYS_FEC_BUF_USE_SRAM - u32 tmp = CFG_SYS_INIT_RAM_ADDR + 0x1000; -#endif - init_eth_info(info); - -#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) - info->bus = mdio_alloc(); - if (!info->bus) - return -ENOMEM; - strlcpy(info->bus->name, dev->name, MDIO_NAME_LEN); - info->bus->read = mcffec_miiphy_read; - info->bus->write = mcffec_miiphy_write; - - retval = mdio_register(info->bus); - if (retval < 0) - return retval; -#endif - - return 0; -} - -static int mcdmafec_remove(struct udevice *dev) -{ - struct fec_info_dma *priv = dev_get_priv(dev); - - mdio_unregister(priv->bus); - mdio_free(priv->bus); - - return 0; -} - -/* - * Boot sequence, called 1st - */ -static int mcdmafec_of_to_plat(struct udevice *dev) -{ - struct eth_pdata *pdata = dev_get_plat(dev); - const u32 *val; - - pdata->iobase = dev_read_addr(dev); - /* Default to 10Mbit/s */ - pdata->max_speed = 10; - - val = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "max-speed", NULL); - if (val) - pdata->max_speed = fdt32_to_cpu(*val); - - return 0; -} - -static const struct udevice_id mcdmafec_ids[] = { - { .compatible = "fsl,mcf-dma-fec" }, - { } -}; - -U_BOOT_DRIVER(mcffec) = { - .name = "mcdmafec", - .id = UCLASS_ETH, - .of_match = mcdmafec_ids, - .of_to_plat = mcdmafec_of_to_plat, - .probe = mcdmafec_probe, - .remove = mcdmafec_remove, - .ops = &mcdmafec_ops, - .priv_auto = sizeof(struct fec_info_dma), - .plat_auto = sizeof(struct eth_pdata), -}; diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index 396cac76d6..7e1036b227 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -446,6 +446,20 @@ U_BOOT_PHY_DRIVER(rtl8211f) = { .writeext = &rtl8211f_phy_extwrite, }; +/* Support for RTL8211F-VD PHY */ +U_BOOT_PHY_DRIVER(rtl8211fvd) = { + .name = "RealTek RTL8211F-VD", + .uid = 0x1cc878, + .mask = 0xffffff, + .features = PHY_GBIT_FEATURES, + .probe = &rtl8211f_probe, + .config = &rtl8211f_config, + .startup = &rtl8211f_startup, + .shutdown = &genphy_shutdown, + .readext = &rtl8211f_phy_extread, + .writeext = &rtl8211f_phy_extwrite, +}; + /* Support for RTL8201F PHY */ U_BOOT_PHY_DRIVER(rtl8201f) = { .name = "RealTek RTL8201F 10/100Mbps Ethernet", diff --git a/drivers/net/qe/uccf.c b/drivers/net/qe/uccf.c index 306f1ea1db..00848a1a37 100644 --- a/drivers/net/qe/uccf.c +++ b/drivers/net/qe/uccf.c @@ -6,7 +6,6 @@ * based on source code of Shlomi Gridish */ -#include <common.h> #include <malloc.h> #include <linux/errno.h> #include <asm/io.h> diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 54f2232768..ef151ee51b 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -903,12 +903,11 @@ static int axi_emac_of_to_plat(struct udevice *dev) ret = dev_read_phandle_with_args(dev, "axistream-connected", NULL, 0, 0, &axistream_node); - if (ret) { - printf("%s: axistream is not found\n", __func__); - return -EINVAL; - } + if (!ret) + plat->dmatx = (struct axidma_reg *)ofnode_get_addr(axistream_node.node); + else + plat->dmatx = (struct axidma_reg *)dev_read_addr_index(dev, 1); - plat->dmatx = (struct axidma_reg *)ofnode_get_addr(axistream_node.node); if (!plat->dmatx) { printf("%s: axi_dma register space not found\n", __func__); return -EINVAL; diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c index 53fd121e90..3db460b5f9 100644 --- a/drivers/pci/pcie_xilinx.c +++ b/drivers/pci/pcie_xilinx.c @@ -8,11 +8,10 @@ #include <common.h> #include <dm.h> #include <pci.h> -#include <asm/global_data.h> #include <linux/bitops.h> #include <linux/printk.h> - -#include <asm/io.h> +#include <linux/io.h> +#include <linux/err.h> /** * struct xilinx_pcie - Xilinx PCIe controller state @@ -25,6 +24,8 @@ struct xilinx_pcie { /* Register definitions */ #define XILINX_PCIE_REG_PSCR 0x144 #define XILINX_PCIE_REG_PSCR_LNKUP BIT(11) +#define XILINX_PCIE_REG_RPSC 0x148 +#define XILINX_PCIE_REG_RPSC_BEN BIT(0) /** * pcie_xilinx_link_up() - Check whether the PCIe link is up @@ -140,20 +141,22 @@ static int pcie_xilinx_write_config(struct udevice *bus, pci_dev_t bdf, static int pcie_xilinx_of_to_plat(struct udevice *dev) { struct xilinx_pcie *pcie = dev_get_priv(dev); - struct fdt_resource reg_res; - DECLARE_GLOBAL_DATA_PTR; - int err; - - err = fdt_get_resource(gd->fdt_blob, dev_of_offset(dev), "reg", - 0, ®_res); - if (err < 0) { - pr_err("\"reg\" resource not found\n"); - return err; - } - - pcie->cfg_base = map_physmem(reg_res.start, - fdt_resource_size(®_res), - MAP_NOCACHE); + fdt_addr_t addr; + fdt_size_t size; + u32 rpsc; + + addr = dev_read_addr_size(dev, &size); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + pcie->cfg_base = devm_ioremap(dev, addr, size); + if (IS_ERR(pcie->cfg_base)) + return PTR_ERR(pcie->cfg_base); + + /* Enable the Bridge enable bit */ + rpsc = __raw_readl(pcie->cfg_base + XILINX_PCIE_REG_RPSC); + rpsc |= XILINX_PCIE_REG_RPSC_BEN; + __raw_writel(rpsc, pcie->cfg_base + XILINX_PCIE_REG_RPSC); return 0; } diff --git a/drivers/phy/meson-axg-mipi-dphy.c b/drivers/phy/meson-axg-mipi-dphy.c index cf2a1cd14c..a69b6c9759 100644 --- a/drivers/phy/meson-axg-mipi-dphy.c +++ b/drivers/phy/meson-axg-mipi-dphy.c @@ -25,6 +25,7 @@ #include <linux/bitops.h> #include <linux/compat.h> #include <linux/bitfield.h> +#include <linux/time.h> /* [31] soft reset for the phy. * 1: reset. 0: dessert the reset. @@ -170,8 +171,6 @@ #define MIPI_DSI_TEST_CTRL0 0x3c #define MIPI_DSI_TEST_CTRL1 0x40 -#define NSEC_PER_MSEC 1000000L - struct phy_meson_axg_mipi_dphy_priv { struct regmap *regmap; #if CONFIG_IS_ENABLED(CLK) diff --git a/drivers/phy/phy-core-mipi-dphy.c b/drivers/phy/phy-core-mipi-dphy.c index ba5f648612..bb61816add 100644 --- a/drivers/phy/phy-core-mipi-dphy.c +++ b/drivers/phy/phy-core-mipi-dphy.c @@ -6,11 +6,10 @@ #include <common.h> #include <div64.h> +#include <linux/time.h> #include <phy-mipi-dphy.h> -#define PSEC_PER_SEC 1000000000000LL - /* * Minimum D-PHY timings based on MIPI D-PHY specification. Derived * from the valid ranges specified in Section 6.9, Table 14, Page 41 diff --git a/drivers/phy/phy-imx8mq-usb.c b/drivers/phy/phy-imx8mq-usb.c index b660eadecf..e5e96e77a6 100644 --- a/drivers/phy/phy-imx8mq-usb.c +++ b/drivers/phy/phy-imx8mq-usb.c @@ -231,16 +231,10 @@ static int imx8mq_usb_phy_power_off(struct phy *usb_phy) return 0; } -static int imx8mq_usb_phy_exit(struct phy *usb_phy) -{ - return imx8mq_usb_phy_power_off(usb_phy); -} - struct phy_ops imx8mq_usb_phy_ops = { .init = imx8mpq_usb_phy_init, .power_on = imx8mq_usb_phy_power_on, .power_off = imx8mq_usb_phy_power_off, - .exit = imx8mq_usb_phy_exit, }; int imx8mq_usb_phy_probe(struct udevice *dev) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c index 9ed7af0d6e..5be76e0533 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-dsidphy.c @@ -15,6 +15,7 @@ #include <linux/clk-provider.h> #include <linux/delay.h> #include <linux/math64.h> +#include <linux/time.h> #include <phy-mipi-dphy.h> #include <reset.h> @@ -186,8 +187,6 @@ #define DSI_PHY_STATUS 0xb0 #define PHY_LOCK BIT(0) -#define PSEC_PER_SEC 1000000000000LL - #define msleep(a) udelay(a * 1000) enum phy_max_rate { diff --git a/drivers/pinctrl/pinctrl_stm32.c b/drivers/pinctrl/pinctrl_stm32.c index 8bb7588714..7120b8edba 100644 --- a/drivers/pinctrl/pinctrl_stm32.c +++ b/drivers/pinctrl/pinctrl_stm32.c @@ -505,6 +505,8 @@ static const struct udevice_id stm32_pinctrl_ids[] = { { .compatible = "st,stm32mp157-pinctrl" }, { .compatible = "st,stm32mp157-z-pinctrl" }, { .compatible = "st,stm32mp135-pinctrl" }, + { .compatible = "st,stm32mp257-pinctrl" }, + { .compatible = "st,stm32mp257-z-pinctrl" }, { } }; diff --git a/drivers/pwm/pwm-aspeed.c b/drivers/pwm/pwm-aspeed.c index ba98641c86..b03472d234 100644 --- a/drivers/pwm/pwm-aspeed.c +++ b/drivers/pwm/pwm-aspeed.c @@ -49,6 +49,7 @@ #include <dm/device_compat.h> #include <linux/math64.h> #include <linux/bitfield.h> +#include <linux/time.h> #include <asm/io.h> /* The channel number of Aspeed pwm controller */ @@ -77,8 +78,6 @@ /* PWM fixed value */ #define PWM_ASPEED_FIXED_PERIOD 0xff -#define NSEC_PER_SEC 1000000000L - struct aspeed_pwm_priv { struct clk clk; struct regmap *regmap; diff --git a/drivers/pwm/pwm-at91.c b/drivers/pwm/pwm-at91.c index 95597aee55..3ff1fb6d5c 100644 --- a/drivers/pwm/pwm-at91.c +++ b/drivers/pwm/pwm-at91.c @@ -14,11 +14,11 @@ #include <dm.h> #include <linux/bitops.h> #include <linux/io.h> +#include <linux/time.h> #include <pwm.h> #define PERIOD_BITS 16 #define PWM_MAX_PRES 10 -#define NSEC_PER_SEC 1000000000L #define PWM_ENA 0x04 #define PWM_CHANNEL_OFFSET 0x20 diff --git a/drivers/pwm/pwm-cadence-ttc.c b/drivers/pwm/pwm-cadence-ttc.c index dc3b314b0c..d9f6736a7a 100644 --- a/drivers/pwm/pwm-cadence-ttc.c +++ b/drivers/pwm/pwm-cadence-ttc.c @@ -17,6 +17,7 @@ #include <linux/bitfield.h> #include <linux/math64.h> #include <linux/log2.h> +#include <linux/time.h> #include <dm/device_compat.h> #define CLOCK_CONTROL 0 @@ -37,8 +38,6 @@ #define COUNTER_INTERVAL_ENABLE BIT(1) #define COUNTER_COUNTING_DISABLE BIT(0) -#define NSEC_PER_SEC 1000000000L - #define TTC_REG(reg, channel) ((reg) + (channel) * sizeof(u32)) #define TTC_CLOCK_CONTROL(reg, channel) \ TTC_REG((reg) + CLOCK_CONTROL, (channel)) diff --git a/drivers/pwm/pwm-meson.c b/drivers/pwm/pwm-meson.c index 2311910a63..60959720da 100644 --- a/drivers/pwm/pwm-meson.c +++ b/drivers/pwm/pwm-meson.c @@ -26,8 +26,7 @@ #include <linux/math64.h> #include <linux/bitfield.h> #include <linux/clk-provider.h> - -#define NSEC_PER_SEC 1000000000L +#include <linux/time.h> #define REG_PWM_A 0x0 #define REG_PWM_B 0x4 diff --git a/drivers/pwm/pwm-mtk.c b/drivers/pwm/pwm-mtk.c index 11e7444019..ad845ed966 100644 --- a/drivers/pwm/pwm-mtk.c +++ b/drivers/pwm/pwm-mtk.c @@ -12,6 +12,7 @@ #include <div64.h> #include <linux/bitops.h> #include <linux/io.h> +#include <linux/time.h> /* PWM registers and bits definitions */ #define PWMCON 0x00 @@ -27,8 +28,6 @@ #define PWM_CLK_DIV_MAX 7 #define MAX_PWM_NUM 8 -#define NSEC_PER_SEC 1000000000L - enum mtk_pwm_reg_ver { PWM_REG_V1, PWM_REG_V2, diff --git a/drivers/pwm/pwm-ti-ehrpwm.c b/drivers/pwm/pwm-ti-ehrpwm.c index f09914519b..fefa3c65ec 100644 --- a/drivers/pwm/pwm-ti-ehrpwm.c +++ b/drivers/pwm/pwm-ti-ehrpwm.c @@ -14,8 +14,7 @@ #include <dm/device_compat.h> #include <pwm.h> #include <asm/io.h> - -#define NSEC_PER_SEC 1000000000L +#include <linux/time.h> /* Time base module registers */ #define TI_EHRPWM_TBCTL 0x00 diff --git a/drivers/qe/fdt.c b/drivers/qe/fdt.c index 6195c7c444..fa9e406556 100644 --- a/drivers/qe/fdt.c +++ b/drivers/qe/fdt.c @@ -6,7 +6,6 @@ * Wolfgang Denk, DENX Software Engineering, wd@denx.de. */ -#include <common.h> #include <asm/global_data.h> #include <linux/libfdt.h> #include <fdt_support.h> diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c index 2825dc6f9a..9631337b8d 100644 --- a/drivers/qe/qe.c +++ b/drivers/qe/qe.c @@ -6,7 +6,6 @@ * based on source code of Shlomi Gridish */ -#include <common.h> #include <malloc.h> #include <command.h> #include <asm/global_data.h> @@ -24,6 +23,9 @@ #include <asm/armv8/mmu.h> #include <asm/arch/cpu.h> #endif +#ifdef CONFIG_PPC +#include <asm/ppc.h> +#endif #define MPC85xx_DEVDISR_QE_DISABLE 0x1 diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a8014129d3..7e21c4ae2b 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1,46 +1,9 @@ config SCSI - bool "Support SCSI controllers" + bool "Support SCSI controllers with driver model" help This enables support for SCSI (Small Computer System Interface), a parallel interface widely used with storage peripherals such as hard drives and optical drives. The SCSI standards define physical interfaces as well as protocols for controlling devices and - tranferring data. - -config DM_SCSI - bool "Support SCSI controllers with driver model" - help - This option enables the SCSI (Small Computer System Interface) uclass - which supports SCSI and SATA HDDs. For every device configuration - (IDs/LUNs) a block device is created with RAW read/write and - filesystem support. - -if SCSI && !DM_SCSI - -config SCSI_AHCI_PLAT - bool "Platform-specific init of AHCI" - help - This enables a way for boards to set up an AHCI device manually, by - called ahci_init() and providing an ahci_reset() mechanism. - - This is deprecated. An AHCI driver should be provided instead. - -config SYS_SCSI_MAX_SCSI_ID - int "Maximum supported SCSI ID" - default 1 - help - Sets the maximum number of SCSI IDs to scan when looking for devices. - IDs from 0 to (this value - 1) are scanned. - - This is deprecated and is not needed when BLK is enabled. - -config SYS_SCSI_MAX_LUN - int "Maximum support SCSI LUN" - default 1 - help - Sets the maximum number of SCSI Logical Unit Numbers (LUNs) to scan on - devices. LUNs from 0 to (this value - 1) are scanned. - - This is deprecated and is not needed when CONFIG_DM_SCSI is enabled. - -endif + tranferring data. For every device configuration (IDs/LUNs) a block + device is created with RAW read/write and filesystem support. diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index d8d6de5909..628be4c89f 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -4,25 +4,16 @@ # Wolfgang Denk, DENX Software Engineering, wd@denx.de. ifndef CONFIG_SPL_BUILD -obj-$(CONFIG_DM_SCSI) += scsi-uclass.o -obj-$(CONFIG_SCSI) += scsi.o - +obj-$(CONFIG_SCSI) += scsi.o scsi-uclass.o ifdef CONFIG_SCSI -ifdef CONFIG_DM_SCSI obj-$(CONFIG_$(SPL_TPL_)BOOTSTD) += scsi_bootdev.o +obj-$(CONFIG_SANDBOX) += sandbox_scsi.o +obj-$(CONFIG_SANDBOX) += scsi_emul.o endif endif -endif - ifdef CONFIG_SPL_BUILD ifdef CONFIG_SPL_SATA -obj-$(CONFIG_DM_SCSI) += scsi-uclass.o -obj-$(CONFIG_SCSI) += scsi.o +obj-$(CONFIG_SCSI) += scsi.o scsi-uclass.o endif endif - -ifdef CONFIG_SCSI -obj-$(CONFIG_SANDBOX) += sandbox_scsi.o -obj-$(CONFIG_SANDBOX) += scsi_emul.o -endif diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 1330482c16..79ee400d12 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -21,38 +21,10 @@ #include <dm/device-internal.h> #include <dm/uclass-internal.h> -#if !defined(CONFIG_DM_SCSI) -# ifdef CFG_SCSI_DEV_LIST -# define SCSI_DEV_LIST CFG_SCSI_DEV_LIST -# else -# ifdef CONFIG_SATA_ULI5288 - -# define SCSI_VEND_ID 0x10b9 -# define SCSI_DEV_ID 0x5288 - -# elif !defined(CONFIG_SCSI_AHCI_PLAT) -# error no scsi device defined -# endif -# define SCSI_DEV_LIST {SCSI_VEND_ID, SCSI_DEV_ID} -# endif -#endif - -#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) && \ - !defined(CONFIG_DM_SCSI) -const struct pci_device_id scsi_device_list[] = { SCSI_DEV_LIST }; -#endif static struct scsi_cmd tempccb; /* temporary scsi command buffer */ DEFINE_CACHE_ALIGN_BUFFER(u8, tempbuff, 512); /* temporary data buffer */ -#if !defined(CONFIG_DM_SCSI) -static int scsi_max_devs; /* number of highest available scsi device */ - -static int scsi_curr_dev; /* current device */ - -static struct blk_desc scsi_dev_desc[SCSI_MAX_DEVICE]; -#endif - /* almost the maximum amount of the scsi_ext command.. */ #define SCSI_MAX_BLK 0xFFFF #define SCSI_LBA48_READ 0xFFFFFFF @@ -107,7 +79,6 @@ static void scsi_setup_inquiry(struct scsi_cmd *pccb) pccb->msgout[0] = SCSI_IDENTIFY; /* NOT USED */ } -#ifdef CONFIG_BLK static void scsi_setup_read_ext(struct scsi_cmd *pccb, lbaint_t start, unsigned short blocks) { @@ -286,59 +257,6 @@ static int scsi_buffer_aligned(struct udevice *dev, struct bounce_buffer *state) return 1; } #endif /* CONFIG_BOUNCE_BUFFER */ -#endif - -#if defined(CONFIG_PCI) && !defined(CONFIG_SCSI_AHCI_PLAT) && \ - !defined(CONFIG_DM_SCSI) -void scsi_init(void) -{ - int busdevfunc = -1; - int i; - /* - * Find a device from the list, this driver will support a single - * controller. - */ - for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) { - /* get PCI Device ID */ - struct udevice *dev; - int ret; - - ret = dm_pci_find_device(scsi_device_list[i].vendor, - scsi_device_list[i].device, 0, &dev); - if (!ret) { - busdevfunc = dm_pci_get_bdf(dev); - break; - } - if (busdevfunc != -1) - break; - } - - if (busdevfunc == -1) { - printf("Error: SCSI Controller(s) "); - for (i = 0; i < ARRAY_SIZE(scsi_device_list); i++) { - printf("%04X:%04X ", - scsi_device_list[i].vendor, - scsi_device_list[i].device); - } - printf("not found\n"); - return; - } -#ifdef DEBUG - else { - printf("SCSI Controller (%04X,%04X) found (%d:%d:%d)\n", - scsi_device_list[i].vendor, - scsi_device_list[i].device, - (busdevfunc >> 16) & 0xFF, - (busdevfunc >> 11) & 0x1F, - (busdevfunc >> 8) & 0x7); - } -#endif - bootstage_start(BOOTSTAGE_ID_ACCUM_SCSI, "ahci"); - scsi_low_level_init(busdevfunc); - scsi_scan(true); - bootstage_accum(BOOTSTAGE_ID_ACCUM_SCSI); -} -#endif /* copy src to dest, skipping leading and trailing blanks * and null terminate the string @@ -462,25 +380,6 @@ static void scsi_init_dev_desc_priv(struct blk_desc *dev_desc) #endif /* CONFIG_BOUNCE_BUFFER */ } -#if !defined(CONFIG_DM_SCSI) -/** - * scsi_init_dev_desc - initialize all SCSI specific blk_desc properties - * - * @dev_desc: Block device description pointer - * @devnum: Device number - */ -static void scsi_init_dev_desc(struct blk_desc *dev_desc, int devnum) -{ - dev_desc->lba = 0; - dev_desc->blksz = 0; - dev_desc->uclass_id = UCLASS_SCSI; - dev_desc->devnum = devnum; - dev_desc->part_type = PART_TYPE_UNKNOWN; - - scsi_init_dev_desc_priv(dev_desc); -} -#endif - /** * scsi_detect_dev - Detect scsi device * @@ -569,7 +468,6 @@ removable: * (re)-scan the scsi bus and reports scsi device info * to the user if mode = 1 */ -#if defined(CONFIG_DM_SCSI) static int do_scsi_scan_one(struct udevice *dev, int id, int lun, bool verbose) { int ret; @@ -690,48 +588,7 @@ int scsi_scan(bool verbose) return 0; } -#else -int scsi_scan(bool verbose) -{ - unsigned char i, lun; - int ret; - - if (verbose) - printf("scanning bus for devices...\n"); - for (i = 0; i < SCSI_MAX_DEVICE; i++) - scsi_init_dev_desc(&scsi_dev_desc[i], i); - - scsi_max_devs = 0; - for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) { - for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) { - struct blk_desc *bdesc = &scsi_dev_desc[scsi_max_devs]; - - ret = scsi_detect_dev(NULL, i, lun, bdesc); - if (ret) - continue; - part_init(bdesc); - - if (verbose) { - printf(" Device %d: ", bdesc->devnum); - dev_print(bdesc); - } - scsi_max_devs++; - } /* next LUN */ - } - if (scsi_max_devs > 0) - scsi_curr_dev = 0; - else - scsi_curr_dev = -1; - - printf("Found %d device(s).\n", scsi_max_devs); -#ifndef CONFIG_SPL_BUILD - env_set_ulong("scsidevs", scsi_max_devs); -#endif - return 0; -} -#endif -#ifdef CONFIG_BLK static const struct blk_ops scsi_blk_ops = { .read = scsi_read, .write = scsi_write, @@ -745,11 +602,3 @@ U_BOOT_DRIVER(scsi_blk) = { .id = UCLASS_BLK, .ops = &scsi_blk_ops, }; -#else -U_BOOT_LEGACY_BLK(scsi) = { - .uclass_idname = "scsi", - .uclass_id = UCLASS_SCSI, - .max_devs = SCSI_MAX_DEVICE, - .desc = scsi_dev_desc, -}; -#endif diff --git a/drivers/serial/serial_msm_geni.c b/drivers/serial/serial_msm_geni.c index 78fd9389c0..b8bc61451a 100644 --- a/drivers/serial/serial_msm_geni.c +++ b/drivers/serial/serial_msm_geni.c @@ -13,14 +13,13 @@ #include <dm.h> #include <errno.h> #include <linux/delay.h> +#include <linux/time.h> #include <misc.h> #include <serial.h> #define UART_OVERSAMPLING 32 #define STALE_TIMEOUT 160 -#define USEC_PER_SEC 1000000L - /* Registers*/ #define GENI_FORCE_DEFAULT_REG 0x20 #define GENI_SER_M_CLK_CFG 0x48 diff --git a/drivers/serial/serial_npcm.c b/drivers/serial/serial_npcm.c index 76ac7cb80d..6bf3a943a2 100644 --- a/drivers/serial/serial_npcm.c +++ b/drivers/serial/serial_npcm.c @@ -83,8 +83,11 @@ static int npcm_serial_setbrg(struct udevice *dev, int baudrate) struct npcm_uart *uart = plat->reg; u16 divisor; + if (IS_ENABLED(CONFIG_SYS_SKIP_UART_INIT)) + return 0; + /* BaudOut = UART Clock / (16 * [Divisor + 2]) */ - divisor = DIV_ROUND_CLOSEST(plat->uart_clk, 16 * baudrate + 2) - 2; + divisor = DIV_ROUND_CLOSEST(plat->uart_clk, 16 * baudrate) - 2; setbits_8(&uart->lcr, LCR_DLAB); writeb(divisor & 0xff, &uart->dll); @@ -97,29 +100,35 @@ static int npcm_serial_setbrg(struct udevice *dev, int baudrate) static int npcm_serial_probe(struct udevice *dev) { struct npcm_serial_plat *plat = dev_get_plat(dev); - struct npcm_uart *uart = plat->reg; + struct npcm_uart *uart; struct clk clk, parent; u32 freq; int ret; plat->reg = dev_read_addr_ptr(dev); - freq = dev_read_u32_default(dev, "clock-frequency", 0); + uart = plat->reg; - ret = clk_get_by_index(dev, 0, &clk); - if (ret < 0) - return ret; + if (!IS_ENABLED(CONFIG_SYS_SKIP_UART_INIT)) { + freq = dev_read_u32_default(dev, "clock-frequency", 24000000); - ret = clk_get_by_index(dev, 1, &parent); - if (!ret) { - ret = clk_set_parent(&clk, &parent); - if (ret) + ret = clk_get_by_index(dev, 0, &clk); + if (ret < 0) return ret; - } - ret = clk_set_rate(&clk, freq); - if (ret < 0) - return ret; - plat->uart_clk = ret; + ret = clk_get_by_index(dev, 1, &parent); + if (!ret) { + ret = clk_set_parent(&clk, &parent); + if (ret) + return ret; + } + + if (freq) { + ret = clk_set_rate(&clk, freq); + if (ret < 0) + return ret; + } + plat->uart_clk = clk_get_rate(&clk); + } /* Disable all interrupt */ writeb(0, &uart->ier); diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c index 23d476fba2..fb039546a4 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -30,7 +30,7 @@ */ #define ONE_BYTE_B115200_US 87 -static void _stm32_serial_setbrg(fdt_addr_t base, +static void _stm32_serial_setbrg(void __iomem *base, struct stm32_uart_info *uart_info, u32 clock_rate, int baudrate) @@ -75,7 +75,7 @@ static int stm32_serial_setconfig(struct udevice *dev, uint serial_config) struct stm32x7_serial_plat *plat = dev_get_plat(dev); bool stm32f4 = plat->uart_info->stm32f4; u8 uart_enable_bit = plat->uart_info->uart_enable_bit; - u32 cr1 = plat->base + CR1_OFFSET(stm32f4); + void __iomem *cr1 = plat->base + CR1_OFFSET(stm32f4); u32 config = 0; uint parity = SERIAL_GET_PARITY(serial_config); uint bits = SERIAL_GET_BITS(serial_config); @@ -122,7 +122,7 @@ static int stm32_serial_getc(struct udevice *dev) { struct stm32x7_serial_plat *plat = dev_get_plat(dev); bool stm32f4 = plat->uart_info->stm32f4; - fdt_addr_t base = plat->base; + void __iomem *base = plat->base; u32 isr = readl(base + ISR_OFFSET(stm32f4)); if ((isr & USART_ISR_RXNE) == 0) @@ -141,7 +141,7 @@ static int stm32_serial_getc(struct udevice *dev) return readl(base + RDR_OFFSET(stm32f4)); } -static int _stm32_serial_putc(fdt_addr_t base, +static int _stm32_serial_putc(void __iomem *base, struct stm32_uart_info *uart_info, const char c) { @@ -166,7 +166,7 @@ static int stm32_serial_pending(struct udevice *dev, bool input) { struct stm32x7_serial_plat *plat = dev_get_plat(dev); bool stm32f4 = plat->uart_info->stm32f4; - fdt_addr_t base = plat->base; + void __iomem *base = plat->base; if (input) return readl(base + ISR_OFFSET(stm32f4)) & @@ -176,7 +176,7 @@ static int stm32_serial_pending(struct udevice *dev, bool input) USART_ISR_TXE ? 0 : 1; } -static void _stm32_serial_init(fdt_addr_t base, +static void _stm32_serial_init(void __iomem *base, struct stm32_uart_info *uart_info) { bool stm32f4 = uart_info->stm32f4; @@ -250,11 +250,14 @@ static const struct udevice_id stm32_serial_id[] = { static int stm32_serial_of_to_plat(struct udevice *dev) { struct stm32x7_serial_plat *plat = dev_get_plat(dev); + fdt_addr_t addr; - plat->base = dev_read_addr(dev); - if (plat->base == FDT_ADDR_T_NONE) + addr = dev_read_addr(dev); + if (addr == FDT_ADDR_T_NONE) return -EINVAL; + plat->base = (void __iomem *)addr; + return 0; } @@ -297,7 +300,7 @@ static inline struct stm32_uart_info *_debug_uart_info(void) static inline void _debug_uart_init(void) { - fdt_addr_t base = CONFIG_VAL(DEBUG_UART_BASE); + void __iomem *base = (void __iomem *)CONFIG_VAL(DEBUG_UART_BASE); struct stm32_uart_info *uart_info = _debug_uart_info(); _stm32_serial_init(base, uart_info); @@ -308,7 +311,7 @@ static inline void _debug_uart_init(void) static inline void _debug_uart_putc(int c) { - fdt_addr_t base = CONFIG_VAL(DEBUG_UART_BASE); + void __iomem *base = (void __iomem *)CONFIG_VAL(DEBUG_UART_BASE); struct stm32_uart_info *uart_info = _debug_uart_info(); while (_stm32_serial_putc(base, uart_info, c) == -EAGAIN) diff --git a/drivers/serial/serial_stm32.h b/drivers/serial/serial_stm32.h index b7e7a90b93..d2c92ba48e 100644 --- a/drivers/serial/serial_stm32.h +++ b/drivers/serial/serial_stm32.h @@ -49,7 +49,7 @@ struct stm32_uart_info stm32h7_info = { /* Information about a serial port */ struct stm32x7_serial_plat { - fdt_addr_t base; /* address of registers in physical memory */ + void __iomem *base; /* address of registers in physical memory */ struct stm32_uart_info *uart_info; unsigned long int clock_rate; }; diff --git a/drivers/soc/ti/keystone_serdes.c b/drivers/soc/ti/keystone_serdes.c index 2ece1a8f64..0e1bf8ff39 100644 --- a/drivers/soc/ti/keystone_serdes.c +++ b/drivers/soc/ti/keystone_serdes.c @@ -8,6 +8,7 @@ #include <errno.h> #include <common.h> +#include <asm/io.h> #include <asm/ti-common/keystone_serdes.h> #include <linux/bitops.h> diff --git a/drivers/spi/cadence_qspi.c b/drivers/spi/cadence_qspi.c index cc3a54f295..2efd626852 100644 --- a/drivers/spi/cadence_qspi.c +++ b/drivers/spi/cadence_qspi.c @@ -7,7 +7,6 @@ #include <common.h> #include <clk.h> #include <log.h> -#include <asm-generic/io.h> #include <dm.h> #include <fdtdec.h> #include <malloc.h> @@ -17,13 +16,13 @@ #include <dm/device_compat.h> #include <linux/err.h> #include <linux/errno.h> +#include <linux/io.h> #include <linux/sizes.h> +#include <linux/time.h> #include <zynqmp_firmware.h> #include "cadence_qspi.h" #include <dt-bindings/power/xlnx-versal-power.h> -#define NSEC_PER_SEC 1000000000L - #define CQSPI_STIG_READ 0 #define CQSPI_STIG_WRITE 1 #define CQSPI_READ 2 diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c index f8ec268812..89907cbbb0 100644 --- a/drivers/spi/fsl_dspi.c +++ b/drivers/spi/fsl_dspi.c @@ -27,9 +27,7 @@ #include <linux/bitops.h> #include <linux/delay.h> #include <linux/printk.h> - -/* linux/include/time.h */ -#define NSEC_PER_SEC 1000000000L +#include <linux/time.h> DECLARE_GLOBAL_DATA_PTR; diff --git a/drivers/spi/meson_spifc_a1.c b/drivers/spi/meson_spifc_a1.c index 099c4c037d..cca4debb41 100644 --- a/drivers/spi/meson_spifc_a1.c +++ b/drivers/spi/meson_spifc_a1.c @@ -16,6 +16,7 @@ #include <spi-mem.h> #include <asm/io.h> #include <linux/log2.h> +#include <linux/time.h> #include <linux/iopoll.h> #include <linux/bitfield.h> @@ -117,7 +118,7 @@ static int amlogic_spifc_a1_request(struct amlogic_spifc_a1 *spifc, bool read) return readl_poll_timeout(spifc->base + SPIFC_A1_USER_CTRL0_REG, val, (val & mask) == mask, - 200 * 1000); + 200 * USEC_PER_MSEC); } static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, @@ -129,7 +130,7 @@ static void amlogic_spifc_a1_drain_buffer(struct amlogic_spifc_a1 *spifc, writel(SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, spifc->base + SPIFC_A1_DBUF_CTRL_REG); - readsl(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); + ioread32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); if (pad) { data = readl(spifc->base + SPIFC_A1_DBUF_DATA_REG); @@ -146,7 +147,7 @@ static void amlogic_spifc_a1_fill_buffer(struct amlogic_spifc_a1 *spifc, writel(SPIFC_A1_DBUF_DIR | SPIFC_A1_DBUF_AUTO_UPDATE_ADDR, spifc->base + SPIFC_A1_DBUF_CTRL_REG); - writesl(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); + iowrite32_rep(spifc->base + SPIFC_A1_DBUF_DATA_REG, buf, count); if (pad) { memcpy(&data, buf + len - pad, pad); diff --git a/drivers/spi/spi-mem-nodm.c b/drivers/spi/spi-mem-nodm.c index 6ee841358b..6d9ab61769 100644 --- a/drivers/spi/spi-mem-nodm.c +++ b/drivers/spi/spi-mem-nodm.c @@ -3,6 +3,7 @@ * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/ */ +#include <errno.h> #include <log.h> #include <malloc.h> #include <spi.h> diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index b58a3f632a..94ddf4967e 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -67,7 +67,7 @@ /* SPI Slave Select Register (spissr), [1] p13, [2] p13 */ #define SPISSR_MASK(cs) (1 << (cs)) #define SPISSR_ACT(cs) ~SPISSR_MASK(cs) -#define SPISSR_OFF ~0UL +#define SPISSR_OFF (~0U) /* SPI Software Reset Register (ssr) */ #define SPISSR_RESET_VALUE 0x0a @@ -109,6 +109,27 @@ struct xilinx_spi_priv { u8 startup; }; +static int xilinx_spi_find_buffer_size(struct xilinx_spi_regs *regs) +{ + u8 sr; + int n_words = 0; + + /* + * Before the buffer_size detection reset the core + * to make sure to start with a clean state. + */ + writel(SPISSR_RESET_VALUE, ®s->srr); + + /* Fill the Tx FIFO with as many words as possible */ + do { + writel(0, ®s->spidtr); + sr = readl(®s->spisr); + n_words++; + } while (!(sr & SPISR_TX_FULL)); + + return n_words; +} + static int xilinx_spi_probe(struct udevice *bus) { struct xilinx_spi_priv *priv = dev_get_priv(bus); @@ -116,6 +137,8 @@ static int xilinx_spi_probe(struct udevice *bus) regs = priv->regs = dev_read_addr_ptr(bus); priv->fifo_depth = dev_read_u32_default(bus, "fifo-size", 0); + if (!priv->fifo_depth) + priv->fifo_depth = xilinx_spi_find_buffer_size(regs); writel(SPISSR_RESET_VALUE, ®s->srr); @@ -217,9 +240,9 @@ static u32 xilinx_spi_read_rxfifo(struct udevice *bus, u8 *rxp, u32 rxbytes) return i; } -static int start_transfer(struct spi_slave *spi, const void *dout, void *din, u32 len) +static int start_transfer(struct udevice *dev, const void *dout, void *din, u32 len) { - struct udevice *bus = spi->dev->parent; + struct udevice *bus = dev->parent; struct xilinx_spi_priv *priv = dev_get_priv(bus); struct xilinx_spi_regs *regs = priv->regs; u32 count, txbytes, rxbytes; @@ -259,10 +282,9 @@ static int start_transfer(struct spi_slave *spi, const void *dout, void *din, u3 return 0; } -static void xilinx_spi_startup_block(struct spi_slave *spi) +static void xilinx_spi_startup_block(struct udevice *dev) { - struct dm_spi_slave_plat *slave_plat = - dev_get_parent_plat(spi->dev); + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); unsigned char txp; unsigned char rxp[8]; @@ -270,13 +292,25 @@ static void xilinx_spi_startup_block(struct spi_slave *spi) * Perform a dummy read as a work around for * the startup block issue. */ - spi_cs_activate(spi->dev, slave_plat->cs); + spi_cs_activate(dev, slave_plat->cs); txp = 0x9f; - start_transfer(spi, (void *)&txp, NULL, 1); + start_transfer(dev, (void *)&txp, NULL, 1); - start_transfer(spi, NULL, (void *)rxp, 6); + start_transfer(dev, NULL, (void *)rxp, 6); - spi_cs_deactivate(spi->dev); + spi_cs_deactivate(dev); +} + +static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) +{ + struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(dev); + int ret; + + spi_cs_activate(dev, slave_plat->cs); + ret = start_transfer(dev, dout, din, bitlen / 8); + spi_cs_deactivate(dev); + return ret; } static int xilinx_spi_mem_exec_op(struct spi_slave *spi, @@ -294,14 +328,15 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi, * as QSPI provides command. So first command fails. */ if (!startup) { - xilinx_spi_startup_block(spi); + xilinx_spi_startup_block(spi->dev); startup++; } spi_cs_activate(spi->dev, slave_plat->cs); if (op->cmd.opcode) { - ret = start_transfer(spi, (void *)&op->cmd.opcode, NULL, 1); + ret = start_transfer(spi->dev, (void *)&op->cmd.opcode, + NULL, 1); if (ret) goto done; } @@ -313,7 +348,7 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi, addr_buf[i] = op->addr.val >> (8 * (op->addr.nbytes - i - 1)); - ret = start_transfer(spi, (void *)addr_buf, NULL, + ret = start_transfer(spi->dev, (void *)addr_buf, NULL, op->addr.nbytes); if (ret) goto done; @@ -322,16 +357,16 @@ static int xilinx_spi_mem_exec_op(struct spi_slave *spi, dummy_len = (op->dummy.nbytes * op->data.buswidth) / op->dummy.buswidth; - ret = start_transfer(spi, NULL, NULL, dummy_len); + ret = start_transfer(spi->dev, NULL, NULL, dummy_len); if (ret) goto done; } if (op->data.nbytes) { if (op->data.dir == SPI_MEM_DATA_IN) { - ret = start_transfer(spi, NULL, + ret = start_transfer(spi->dev, NULL, op->data.buf.in, op->data.nbytes); } else { - ret = start_transfer(spi, op->data.buf.out, + ret = start_transfer(spi->dev, op->data.buf.out, NULL, op->data.nbytes); } if (ret) @@ -427,6 +462,7 @@ static const struct spi_controller_mem_ops xilinx_spi_mem_ops = { static const struct dm_spi_ops xilinx_spi_ops = { .claim_bus = xilinx_spi_claim_bus, .release_bus = xilinx_spi_release_bus, + .xfer = xilinx_spi_xfer, .set_speed = xilinx_spi_set_speed, .set_mode = xilinx_spi_set_mode, .mem_ops = &xilinx_spi_mem_ops, diff --git a/drivers/sysinfo/Kconfig b/drivers/sysinfo/Kconfig index e35f7cb179..2030e4babc 100644 --- a/drivers/sysinfo/Kconfig +++ b/drivers/sysinfo/Kconfig @@ -8,6 +8,13 @@ menuconfig SYSINFO if SYSINFO +config SYSINFO_EXTRA + bool "Show extra information on startup" + help + Enable this to see extra information on startup. Normally only the + model is shown, but with this option the vendor and any prior-stage + firmware's version and date are shown as well. + config SPL_SYSINFO depends on SPL_DM bool "Enable board driver support in SPL" diff --git a/drivers/sysreset/poweroff_gpio.c b/drivers/sysreset/poweroff_gpio.c index a5c24fd85b..ad04e4b1a8 100644 --- a/drivers/sysreset/poweroff_gpio.c +++ b/drivers/sysreset/poweroff_gpio.c @@ -33,7 +33,7 @@ static int poweroff_gpio_request(struct udevice *dev, enum sysreset_t type) int r; if (type != SYSRESET_POWER_OFF) - return -ENOSYS; + return -EPROTONOSUPPORT; debug("GPIO poweroff\n"); diff --git a/drivers/sysreset/sysreset_psci.c b/drivers/sysreset/sysreset_psci.c index a8a41528a8..aa09d0b882 100644 --- a/drivers/sysreset/sysreset_psci.c +++ b/drivers/sysreset/sysreset_psci.c @@ -25,7 +25,7 @@ static int psci_sysreset_request(struct udevice *dev, enum sysreset_t type) psci_sys_poweroff(); break; default: - return -ENOSYS; + return -EPROTONOSUPPORT; } return -EINPROGRESS; diff --git a/drivers/sysreset/sysreset_sandbox.c b/drivers/sysreset/sysreset_sandbox.c index f485a13529..c12eda81d0 100644 --- a/drivers/sysreset/sysreset_sandbox.c +++ b/drivers/sysreset/sysreset_sandbox.c @@ -21,7 +21,7 @@ static int sandbox_warm_sysreset_request(struct udevice *dev, state->last_sysreset = type; break; default: - return -ENOSYS; + return -EPROTONOSUPPORT; } if (!state->sysreset_allowed[type]) return -EACCES; @@ -70,7 +70,7 @@ static int sandbox_sysreset_request(struct udevice *dev, enum sysreset_t type) return -EACCES; sandbox_exit(); default: - return -ENOSYS; + return -EPROTONOSUPPORT; } if (!state->sysreset_allowed[type]) return -EACCES; diff --git a/drivers/sysreset/sysreset_watchdog.c b/drivers/sysreset/sysreset_watchdog.c index ceada2e47b..6db5aa75b5 100644 --- a/drivers/sysreset/sysreset_watchdog.c +++ b/drivers/sysreset/sysreset_watchdog.c @@ -29,7 +29,7 @@ static int wdt_reboot_request(struct udevice *dev, enum sysreset_t type) return ret; break; default: - return -ENOSYS; + return -EPROTONOSUPPORT; } return -EINPROGRESS; diff --git a/drivers/sysreset/sysreset_x86.c b/drivers/sysreset/sysreset_x86.c index 4936fdb76c..dc772b5ff9 100644 --- a/drivers/sysreset/sysreset_x86.c +++ b/drivers/sysreset/sysreset_x86.c @@ -87,7 +87,7 @@ static int x86_sysreset_request(struct udevice *dev, enum sysreset_t type) return ret; return -EINPROGRESS; default: - return -ENOSYS; + return -EPROTONOSUPPORT; } outb(value, IO_PORT_RESET); diff --git a/drivers/timer/timer-uclass.c b/drivers/timer/timer-uclass.c index 0c2018bfe3..60ff65529a 100644 --- a/drivers/timer/timer-uclass.c +++ b/drivers/timer/timer-uclass.c @@ -66,13 +66,13 @@ static int timer_pre_probe(struct udevice *dev) err = clk_get_by_index(dev, 0, &timer_clk); if (!err) { ret = clk_get_rate(&timer_clk); - if (IS_ERR_VALUE(ret)) - return ret; - uc_priv->clock_rate = ret; - } else { - uc_priv->clock_rate = - dev_read_u32_default(dev, "clock-frequency", 0); + if (!IS_ERR_VALUE(ret)) { + uc_priv->clock_rate = ret; + return 0; + } } + + uc_priv->clock_rate = dev_read_u32_default(dev, "clock-frequency", 0); } return 0; diff --git a/drivers/tpm/tpm2_tis_core.c b/drivers/tpm/tpm2_tis_core.c index 985a816219..81b9210056 100644 --- a/drivers/tpm/tpm2_tis_core.c +++ b/drivers/tpm/tpm2_tis_core.c @@ -224,9 +224,6 @@ int tpm_tis_send(struct udevice *dev, const u8 *buf, size_t len) u8 status; int ret; - if (!chip) - return -ENODEV; - ret = tpm_tis_request_locality(dev, 0); if (ret < 0) return -EBUSY; diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig index 0e0cc58e3d..7da46faed6 100644 --- a/drivers/ufs/Kconfig +++ b/drivers/ufs/Kconfig @@ -2,7 +2,7 @@ menu "UFS Host Controller Support" config UFS bool "Support UFS controllers" - depends on DM_SCSI + depends on SCSI select CHARSET help This selects support for Universal Flash Subsystem (UFS). @@ -15,6 +15,17 @@ config CADENCE_UFS This selects the platform driver for the Cadence UFS host controller present on present TI's J721e devices. +config UFS_PCI + bool "PCI bus based UFS Controller support" + depends on PCI && UFS + help + This selects the PCI UFS Host Controller Interface. Select this if + you have UFS Host Controller with PCI Interface. + + If you have a controller with this interface, say Y here. + + If unsure, say N. + config TI_J721E_UFS bool "Glue Layer driver for UFS on TI J721E devices" help diff --git a/drivers/ufs/Makefile b/drivers/ufs/Makefile index 56a4b0776d..67c42621ab 100644 --- a/drivers/ufs/Makefile +++ b/drivers/ufs/Makefile @@ -6,4 +6,5 @@ obj-$(CONFIG_UFS) += ufs.o ufs-uclass.o obj-$(CONFIG_CADENCE_UFS) += cdns-platform.o obj-$(CONFIG_TI_J721E_UFS) += ti-j721e-ufs.o +obj-$(CONFIG_UFS_PCI) += ufs-pci.o obj-$(CONFIG_UFS_RENESAS) += ufs-renesas.o diff --git a/drivers/ufs/cdns-platform.c b/drivers/ufs/cdns-platform.c index 9202b53989..d1f346937c 100644 --- a/drivers/ufs/cdns-platform.c +++ b/drivers/ufs/cdns-platform.c @@ -13,11 +13,10 @@ #include <dm/device_compat.h> #include <linux/bitops.h> #include <linux/err.h> +#include <linux/time.h> #include "ufs.h" -#define USEC_PER_SEC 1000000L - #define CDNS_UFS_REG_HCLKDIV 0xFC #define CDNS_UFS_REG_PHY_XCFGD1 0x113C diff --git a/drivers/ufs/ufs-pci.c b/drivers/ufs/ufs-pci.c new file mode 100644 index 0000000000..ad41358727 --- /dev/null +++ b/drivers/ufs/ufs-pci.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 tinylab.org + * Author: Bin Meng <bmeng@tinylab.org> + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <pci.h> +#include <ufs.h> +#include <dm/device_compat.h> +#include "ufs.h" + +static int ufs_pci_bind(struct udevice *dev) +{ + struct udevice *scsi_dev; + + return ufs_scsi_bind(dev, &scsi_dev); +} + +static int ufs_pci_probe(struct udevice *dev) +{ + int err; + + err = ufshcd_probe(dev, NULL); + if (err) + dev_err(dev, "%s failed (ret=%d)\n", __func__, err); + + return err; +} + +U_BOOT_DRIVER(ufs_pci) = { + .name = "ufs_pci", + .id = UCLASS_UFS, + .bind = ufs_pci_bind, + .probe = ufs_pci_probe, +}; + +static struct pci_device_id ufs_supported[] = { + { PCI_DEVICE(PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_UFS) }, + {}, +}; + +U_BOOT_PCI_DEVICE(ufs_pci, ufs_supported); diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c index e6478a9209..92fcdf4e6c 100644 --- a/drivers/ufs/ufs-uclass.c +++ b/drivers/ufs/ufs-uclass.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /** - * ufs-uclass.c - Universal Flash Subsystem (UFS) Uclass driver + * ufs-uclass.c - Universal Flash Storage (UFS) Uclass driver * * Copyright (C) 2019 Texas Instruments Incorporated - https://www.ti.com */ diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index 346f0fd916..e4400f319a 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /** - * ufs.c - Universal Flash Subsystem (UFS) driver + * ufs.c - Universal Flash Storage (UFS) driver * * Taken from Linux Kernel v5.2 (drivers/scsi/ufs/ufshcd.c) and ported * to u-boot. @@ -320,7 +320,7 @@ static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer) UIC_ARG_MPHY_TX_GEN_SEL_INDEX(i)), 0); if (err) { - dev_err(hba->dev, "%s: TX LCC Disable failed, peer = %d, lane = %d, err = %d", + dev_err(hba->dev, "%s: TX LCC Disable failed, peer = %d, lane = %d, err = %d\n", __func__, peer, i, err); break; } @@ -441,7 +441,7 @@ static int ufshcd_make_hba_operational(struct ufs_hba *hba) ufshcd_enable_run_stop_reg(hba); } else { dev_err(hba->dev, - "Host controller not ready to process requests"); + "Host controller not ready to process requests\n"); err = -EIO; goto out; } @@ -930,7 +930,7 @@ static int ufshcd_copy_query_response(struct ufs_hba *hba) memcpy(hba->dev_cmd.query.descriptor, descp, resp_len); } else { dev_warn(hba->dev, - "%s: Response size is bigger than buffer", + "%s: Response size is bigger than buffer\n", __func__); return -EINVAL; } @@ -1179,11 +1179,11 @@ static int ufshcd_read_desc_length(struct ufs_hba *hba, enum desc_idn desc_id, &header_len); if (ret) { - dev_err(hba->dev, "%s: Failed to get descriptor header id %d", + dev_err(hba->dev, "%s: Failed to get descriptor header id %d\n", __func__, desc_id); return ret; } else if (desc_id != header[QUERY_DESC_DESC_TYPE_OFFSET]) { - dev_warn(hba->dev, "%s: descriptor header id %d and desc_id %d mismatch", + dev_warn(hba->dev, "%s: descriptor header id %d and desc_id %d mismatch\n", __func__, header[QUERY_DESC_DESC_TYPE_OFFSET], desc_id); ret = -EINVAL; @@ -1302,7 +1302,7 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, enum desc_idn desc_id, /* Sanity checks */ if (ret || !buff_len) { - dev_err(hba->dev, "%s: Failed to get full descriptor length", + dev_err(hba->dev, "%s: Failed to get full descriptor length\n", __func__); return ret; } @@ -1323,14 +1323,14 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, enum desc_idn desc_id, &buff_len); if (ret) { - dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d", + dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n", __func__, desc_id, desc_index, param_offset, ret); goto out; } /* Sanity check */ if (desc_buf[QUERY_DESC_DESC_TYPE_OFFSET] != desc_id) { - dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header", + dev_err(hba->dev, "%s: invalid desc_id %d in descriptor header\n", __func__, desc_buf[QUERY_DESC_DESC_TYPE_OFFSET]); ret = -EINVAL; goto out; @@ -1914,6 +1914,7 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) struct ufs_hba *hba = dev_get_uclass_priv(ufs_dev); struct scsi_plat *scsi_plat; struct udevice *scsi_dev; + void __iomem *mmio_base; int err; device_find_first_child(ufs_dev, &scsi_dev); @@ -1927,7 +1928,14 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) hba->dev = ufs_dev; hba->ops = hba_ops; - hba->mmio_base = dev_read_addr_ptr(ufs_dev); + + if (device_is_on_pci_bus(ufs_dev)) { + mmio_base = dm_pci_map_bar(ufs_dev, PCI_BASE_ADDRESS_0, 0, 0, + PCI_REGION_TYPE, PCI_REGION_MEM); + } else { + mmio_base = dev_read_addr_ptr(ufs_dev); + } + hba->mmio_base = mmio_base; /* Set descriptor lengths to specification defaults */ ufshcd_def_desc_sizes(hba); @@ -1945,7 +1953,8 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) hba->version != UFSHCI_VERSION_11 && hba->version != UFSHCI_VERSION_20 && hba->version != UFSHCI_VERSION_21 && - hba->version != UFSHCI_VERSION_30) + hba->version != UFSHCI_VERSION_30 && + hba->version != UFSHCI_VERSION_31) dev_err(hba->dev, "invalid UFS version 0x%x\n", hba->version); diff --git a/drivers/ufs/ufs.h b/drivers/ufs/ufs.h index 9daaf03d22..816a5ce0ca 100644 --- a/drivers/ufs/ufs.h +++ b/drivers/ufs/ufs.h @@ -782,6 +782,7 @@ enum { UFSHCI_VERSION_20 = 0x00000200, /* 2.0 */ UFSHCI_VERSION_21 = 0x00000210, /* 2.1 */ UFSHCI_VERSION_30 = 0x00000300, /* 3.0 */ + UFSHCI_VERSION_31 = 0x00000310, /* 3.1 */ }; /* Interrupt disable masks */ diff --git a/drivers/usb/cdns3/cdns3-ti.c b/drivers/usb/cdns3/cdns3-ti.c index 92a7941ed1..2e44aadea4 100644 --- a/drivers/usb/cdns3/cdns3-ti.c +++ b/drivers/usb/cdns3/cdns3-ti.c @@ -6,7 +6,6 @@ */ #include <common.h> -#include <asm-generic/io.h> #include <clk.h> #include <dm.h> #include <dm/device_compat.h> diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 3aec8b0d94..4b4fcd8a22 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -31,6 +31,7 @@ #include <linux/usb/gadget.h> #include <linux/bitfield.h> #include <linux/math64.h> +#include <linux/time.h> #include "core.h" #include "gadget.h" @@ -38,8 +39,6 @@ #include "linux-compat.h" -#define NSEC_PER_SEC 1000000000L - static LIST_HEAD(dwc3_list); /* -------------------------------------------------------------------------- */ diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c index e0356e653f..196035215a 100644 --- a/drivers/usb/dwc3/dwc3-meson-g12a.c +++ b/drivers/usb/dwc3/dwc3-meson-g12a.c @@ -8,13 +8,13 @@ #include <common.h> #include <log.h> -#include <asm-generic/io.h> #include <dm.h> #include <dm/device-internal.h> #include <dm/lists.h> #include <dwc3-uboot.h> #include <generic-phy.h> #include <linux/delay.h> +#include <linux/io.h> #include <linux/printk.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> diff --git a/drivers/usb/dwc3/dwc3-meson-gxl.c b/drivers/usb/dwc3/dwc3-meson-gxl.c index d56f2747b6..cbe8aaa005 100644 --- a/drivers/usb/dwc3/dwc3-meson-gxl.c +++ b/drivers/usb/dwc3/dwc3-meson-gxl.c @@ -8,12 +8,12 @@ #define DEBUG #include <common.h> -#include <asm-generic/io.h> #include <dm.h> #include <dm/device-internal.h> #include <dm/lists.h> #include <dwc3-uboot.h> #include <generic-phy.h> +#include <linux/io.h> #include <linux/usb/ch9.h> #include <linux/usb/gadget.h> #include <malloc.h> diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 4eccc5e337..c72a804763 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -17,6 +17,7 @@ menuconfig USB_GADGET bool "USB Gadget Support" depends on DM select DM_USB + imply CMD_BIND help USB is a master/slave protocol, organized with one master host (such as a PC) controlling up to 127 peripheral devices. diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 1d17331cb0..c725aed3f6 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -327,6 +327,7 @@ struct fsg_common { unsigned int short_packet_received:1; unsigned int bad_lun_okay:1; unsigned int running:1; + unsigned int eject:1; int thread_wakeup_needed; struct completion thread_notifier; @@ -669,6 +670,10 @@ static int sleep_thread(struct fsg_common *common) } if (k == 10) { + /* Handle START-STOP UNIT */ + if (common->eject) + return -EPIPE; + /* Handle CTRL+C */ if (ctrlc()) return -EPIPE; @@ -1325,6 +1330,8 @@ static int do_start_stop(struct fsg_common *common) return -EINVAL; } + common->eject = 1; + return 0; } diff --git a/drivers/usb/gadget/f_sdp.c b/drivers/usb/gadget/f_sdp.c index ee9384fb37..ca2760c00d 100644 --- a/drivers/usb/gadget/f_sdp.c +++ b/drivers/usb/gadget/f_sdp.c @@ -744,7 +744,7 @@ static ulong sdp_load_read(struct spl_load_info *load, ulong sector, { debug("%s: sector %lx, count %lx, buf %lx\n", __func__, sector, count, (ulong)buf); - memcpy(buf, (void *)(load->dev + sector), count); + memcpy(buf, (void *)(load->priv + sector), count); return count; } @@ -844,8 +844,8 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image, struct spl_load_info load; debug("Found FIT\n"); - load.dev = header; - load.bl_len = 1; + load.priv = header; + spl_set_bl_len(&load, 1); load.read = sdp_load_read; spl_load_simple_fit(spl_image, &load, 0, header); @@ -857,8 +857,8 @@ static int sdp_handle_in_ep(struct spl_image_info *spl_image, valid_container_hdr((void *)header)) { struct spl_load_info load; - load.dev = header; - load.bl_len = 1; + load.priv = header; + spl_set_bl_len(&load, 1); load.read = sdp_load_read; spl_load_imx_container(spl_image, &load, 0); return SDP_EXIT; diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c index eb0b35969c..ba658d9229 100644 --- a/drivers/usb/gadget/udc/udc-core.c +++ b/drivers/usb/gadget/udc/udc-core.c @@ -323,6 +323,7 @@ err1: int usb_gadget_probe_driver(struct usb_gadget_driver *driver) { struct usb_udc *udc = NULL; + unsigned int udc_count = 0; int ret; if (!driver || !driver->bind || !driver->setup) @@ -330,12 +331,22 @@ int usb_gadget_probe_driver(struct usb_gadget_driver *driver) mutex_lock(&udc_lock); list_for_each_entry(udc, &udc_list, list) { + udc_count++; + /* For now we take the first one */ if (!udc->driver) goto found; } - printf("couldn't find an available UDC\n"); + if (!udc_count) + printf("No UDC available in the system\n"); + else + /* When this happens, users should 'unbind <class> <index>' + * using the output of 'dm tree' and looking at the line right + * after the USB peripheral/device controller. + */ + printf("All UDCs in use (%d available), use the unbind command\n", + udc_count); mutex_unlock(&udc_lock); return -ENODEV; found: diff --git a/drivers/usb/musb-new/musb_io.h b/drivers/usb/musb-new/musb_io.h index 72a5365632..19b12f36a5 100644 --- a/drivers/usb/musb-new/musb_io.h +++ b/drivers/usb/musb-new/musb_io.h @@ -14,31 +14,7 @@ #ifndef __MUSB_LINUX_PLATFORM_ARCH_H__ #define __MUSB_LINUX_PLATFORM_ARCH_H__ -#ifndef __UBOOT__ #include <linux/io.h> -#else -#include <asm/io.h> -#endif - -#if !defined(CONFIG_ARM) && !defined(CONFIG_SUPERH) \ - && !defined(CONFIG_PPC32) \ - && !defined(CONFIG_PPC64) && !defined(CONFIG_MIPS) \ - && !defined(CONFIG_M68K) -static inline void readsl(const void __iomem *addr, void *buf, int len) - { insl((unsigned long)addr, buf, len); } -static inline void readsw(const void __iomem *addr, void *buf, int len) - { insw((unsigned long)addr, buf, len); } -static inline void readsb(const void __iomem *addr, void *buf, int len) - { insb((unsigned long)addr, buf, len); } - -static inline void writesl(const void __iomem *addr, const void *buf, int len) - { outsl((unsigned long)addr, buf, len); } -static inline void writesw(const void __iomem *addr, const void *buf, int len) - { outsw((unsigned long)addr, buf, len); } -static inline void writesb(const void __iomem *addr, const void *buf, int len) - { outsb((unsigned long)addr, buf, len); } - -#endif /* NOTE: these offsets are all in bytes */ diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index ab927641bb..6f319ba0d5 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -180,7 +180,6 @@ config CONSOLE_ROTATION config CONSOLE_TRUETYPE bool "Support a console that uses TrueType fonts" - select CMD_SELECT_FONT help TrueTrype fonts can provide outline-drawing capability rather than needing to provide a bitmap for each font and size that is needed. diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c index 22fef7e882..a7e0784596 100644 --- a/drivers/video/dw_mipi_dsi.c +++ b/drivers/video/dw_mipi_dsi.c @@ -22,6 +22,7 @@ #include <linux/bitops.h> #include <linux/delay.h> #include <linux/iopoll.h> +#include <linux/time.h> #include <video_bridge.h> #define HWVER_131 0x31333100 /* IP version 1.31 */ @@ -214,8 +215,6 @@ #define PHY_STATUS_TIMEOUT_US 10000 #define CMD_PKT_STATUS_TIMEOUT_US 20000 -#define MSEC_PER_SEC 1000 - struct dw_mipi_dsi { struct mipi_dsi_host dsi_host; struct mipi_dsi_device *device; diff --git a/drivers/video/rockchip/dw_mipi_dsi_rockchip.c b/drivers/video/rockchip/dw_mipi_dsi_rockchip.c index 1a5ab781e3..5e75b6ec68 100644 --- a/drivers/video/rockchip/dw_mipi_dsi_rockchip.c +++ b/drivers/video/rockchip/dw_mipi_dsi_rockchip.c @@ -30,12 +30,11 @@ #include <asm/io.h> #include <dm/device-internal.h> #include <linux/bitops.h> +#include <linux/time.h> #include <asm/arch-rockchip/clock.h> #include <asm/arch-rockchip/hardware.h> -#define USEC_PER_SEC 1000000L - /* * DSI wrapper registers & bit definitions * Note: registers are named as in the Reference Manual diff --git a/drivers/video/stm32/stm32_ltdc.c b/drivers/video/stm32/stm32_ltdc.c index 6fd90e3391..4f60ba8ebe 100644 --- a/drivers/video/stm32/stm32_ltdc.c +++ b/drivers/video/stm32/stm32_ltdc.c @@ -495,6 +495,33 @@ static void stm32_ltdc_set_layer1(struct stm32_ltdc_priv *priv, ulong fb_addr) setbits_le32(priv->regs + LTDC_L1CR, LXCR_LEN); } +#if IS_ENABLED(CONFIG_TARGET_STM32F469_DISCOVERY) +static int stm32_ltdc_alloc_fb(struct udevice *dev) +{ + u32 sdram_size = gd->ram_size; + struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); + phys_addr_t cpu; + dma_addr_t bus; + u64 dma_size; + int ret; + + ret = dev_get_dma_range(dev, &cpu, &bus, &dma_size); + if (ret) { + dev_err(dev, "failed to get dma address\n"); + return ret; + } + + uc_plat->base = bus + sdram_size - ALIGN(uc_plat->size, uc_plat->align); + return 0; +} +#else +static inline int stm32_ltdc_alloc_fb(struct udevice *dev) +{ + /* Delegate framebuffer allocation to video-uclass */ + return 0; +} +#endif + static int stm32_ltdc_probe(struct udevice *dev) { struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); @@ -605,6 +632,10 @@ static int stm32_ltdc_probe(struct udevice *dev) priv->crop_h = timings.vactive.typ; priv->alpha = 0xFF; + ret = stm32_ltdc_alloc_fb(dev); + if (ret) + return ret; + dev_dbg(dev, "%dx%d %dbpp frame buffer at 0x%lx\n", timings.hactive.typ, timings.vactive.typ, VNBITS(priv->l2bpp), uc_plat->base); diff --git a/drivers/video/tegra20/tegra-dsi.c b/drivers/video/tegra20/tegra-dsi.c index b4cf4fad5e..a48f9c85d0 100644 --- a/drivers/video/tegra20/tegra-dsi.c +++ b/drivers/video/tegra20/tegra-dsi.c @@ -14,6 +14,7 @@ #include <panel.h> #include <linux/delay.h> #include <linux/err.h> +#include <linux/time.h> #include <power/regulator.h> #include <asm/gpio.h> @@ -24,9 +25,6 @@ #include "mipi-phy.h" -#define USEC_PER_SEC 1000000L -#define NSEC_PER_SEC 1000000000L - struct tegra_dsi_priv { struct mipi_dsi_host host; struct mipi_dsi_device device; diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index 852f6735b6..1de68867d5 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -56,7 +56,7 @@ config VIRTIO_SANDBOX config VIRTIO_NET bool "virtio net driver" - depends on VIRTIO + depends on VIRTIO && NETDEVICES help This is the virtual net driver for virtio. It can be used with QEMU based targets. diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index b40a1d29ca..8eeac93576 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c @@ -9,8 +9,7 @@ #include <wdt.h> #include <asm/io.h> #include <linux/delay.h> - -#define MSEC_PER_SEC 1000 +#include <linux/time.h> #define WDT_MAX_TIMEOUT 16 #define WDT_TIMEOUT_MASK 0xf diff --git a/drivers/xen/pvblock.c b/drivers/xen/pvblock.c index 4ad548d599..1df04e239a 100644 --- a/drivers/xen/pvblock.c +++ b/drivers/xen/pvblock.c @@ -632,7 +632,8 @@ static ulong pvblock_iop(struct udevice *udev, lbaint_t blknr, memcpy(blk_dev->bounce_buffer, buffer, desc->blksz); aiocb.aio_nbytes = unaligned ? desc->blksz : - min((size_t)(BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE), + min((size_t)((BLKIF_MAX_SEGMENTS_PER_REQUEST - 1) + * PAGE_SIZE), (size_t)(blocks_todo * desc->blksz)); blkfront_io(&aiocb, write); |