diff options
25 files changed, 390 insertions, 103 deletions
diff --git a/arch/arm/dts/r8a7792-blanche-u-boot.dts b/arch/arm/dts/r8a7792-blanche-u-boot.dts index 3555663d647..30b27040f5a 100644 --- a/arch/arm/dts/r8a7792-blanche-u-boot.dts +++ b/arch/arm/dts/r8a7792-blanche-u-boot.dts @@ -8,6 +8,10 @@ #include "r8a7792-blanche.dts" #include "r8a7792-u-boot.dtsi" +&iic3 { + status = "okay"; +}; + &scif0 { u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/r8a7792.dtsi b/arch/arm/dts/r8a7792.dtsi index 8e9eb4b704d..6fd80e35415 100644 --- a/arch/arm/dts/r8a7792.dtsi +++ b/arch/arm/dts/r8a7792.dtsi @@ -444,6 +444,23 @@ status = "disabled"; }; + iic3: i2c@e60b0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "renesas,iic-r8a7792", + "renesas,rcar-gen2-iic", + "renesas,rmobile-iic"; + reg = <0 0xe60b0000 0 0x425>; + interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 926>; + dmas = <&dmac0 0x77>, <&dmac0 0x78>, + <&dmac1 0x77>, <&dmac1 0x78>; + dma-names = "tx", "rx", "tx", "rx"; + power-domains = <&sysc R8A7792_PD_ALWAYS_ON>; + resets = <&cpg 926>; + status = "disabled"; + }; + dmac0: dma-controller@e6700000 { compatible = "renesas,dmac-r8a7792", "renesas,rcar-dmac"; diff --git a/arch/arm/dts/socfpga_agilex_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_agilex_socdk-u-boot.dtsi index 1908be4b8b2..debeb8b239a 100644 --- a/arch/arm/dts/socfpga_agilex_socdk-u-boot.dtsi +++ b/arch/arm/dts/socfpga_agilex_socdk-u-boot.dtsi @@ -37,3 +37,6 @@ u-boot,dm-pre-reloc; }; +&qspi { + status = "okay"; +}; diff --git a/arch/arm/mach-socfpga/include/mach/base_addr_a10.h b/arch/arm/mach-socfpga/include/mach/base_addr_a10.h index 929c413e039..b947cc07291 100644 --- a/arch/arm/mach-socfpga/include/mach/base_addr_a10.h +++ b/arch/arm/mach-socfpga/include/mach/base_addr_a10.h @@ -47,4 +47,6 @@ #define SOCFPGA_SDR_FIREWALL_L3_ADDRESS 0xffd13400 #define SOCFPGA_NOC_FW_H2F_SCR_OFST 0xffd13500 +#define SOCFPGA_PHYS_OCRAM_SIZE 0x40000 + #endif /* _SOCFPGA_A10_BASE_HARDWARE_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/base_addr_ac5.h b/arch/arm/mach-socfpga/include/mach/base_addr_ac5.h index 2725e9fcc34..da966fb4583 100644 --- a/arch/arm/mach-socfpga/include/mach/base_addr_ac5.h +++ b/arch/arm/mach-socfpga/include/mach/base_addr_ac5.h @@ -59,4 +59,6 @@ #define SOCFPGA_DMANONSECURE_ADDRESS 0xffe00000 #define SOCFPGA_DMASECURE_ADDRESS 0xffe01000 +#define SOCFPGA_PHYS_OCRAM_SIZE 0x10000 + #endif /* _SOCFPGA_BASE_ADDRS_H_ */ diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c index d9ef851054d..b10be332680 100644 --- a/arch/arm/mach-socfpga/spl_a10.c +++ b/arch/arm/mach-socfpga/spl_a10.c @@ -33,6 +33,38 @@ DECLARE_GLOBAL_DATA_PTR; +#define BOOTROM_SHARED_MEM_SIZE 0x800 /* 2KB */ +#define BOOTROM_SHARED_MEM_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ + SOCFPGA_PHYS_OCRAM_SIZE - \ + BOOTROM_SHARED_MEM_SIZE) +#define RST_STATUS_SHARED_ADDR (BOOTROM_SHARED_MEM_ADDR + 0x438) +static u32 rst_mgr_status __section(.data); + +/* + * Bootrom will clear the status register in reset manager and stores the + * reset status value in shared memory. Bootrom stores shared data at last + * 2KB of onchip RAM. + * This function save reset status provided by BootROM to rst_mgr_status. + * More information about reset status register value can be found in reset + * manager register description. + * When running in debugger without Bootrom, r0 to r3 are random values. + * So, skip save the value when r0 is not BootROM shared data address. + * + * r0 - Contains the pointer to the shared memory block. The shared + * memory block is located in the top 2 KB of on-chip RAM. + * r1 - contains the length of the shared memory. + * r2 - unused and set to 0x0. + * r3 - points to the version block. + */ +void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2, + unsigned long r3) +{ + if (r0 == BOOTROM_SHARED_MEM_ADDR) + rst_mgr_status = readl(RST_STATUS_SHARED_ADDR); + + save_boot_params_ret(); +} + u32 spl_boot_device(void) { const u32 bsel = readl(socfpga_get_sysmgr_addr() + SYSMGR_A10_BOOTINFO); diff --git a/arch/powerpc/dts/gdsys/mpc8308.dtsi b/arch/powerpc/dts/gdsys/mpc8308.dtsi index 23e7403d911..1a319e23287 100644 --- a/arch/powerpc/dts/gdsys/mpc8308.dtsi +++ b/arch/powerpc/dts/gdsys/mpc8308.dtsi @@ -17,6 +17,7 @@ /dts-v1/; #include <dt-bindings/memory/mpc83xx-sdram.h> +#include <dt-bindings/clk/mpc83xx-clk.h> / { compatible = "fsl,mpc8308rdb"; @@ -50,6 +51,11 @@ }; }; + socclocks: clocks { + compatible = "fsl,mpc8308-clk"; + #clock-cells = <1>; + }; + board_lbc: localbus@e0005000 { #address-cells = <2>; #size-cells = <1>; @@ -173,6 +179,7 @@ reg = <0x7000 0x1000>; interrupts = <16 0x8>; interrupt-parent = <&ipic>; + clocks = <&socclocks MPC83XX_CLK_CSB>; mode = "cpu"; }; diff --git a/board/renesas/blanche/blanche.c b/board/renesas/blanche/blanche.c index 7232370d6f4..c15387366c7 100644 --- a/board/renesas/blanche/blanche.c +++ b/board/renesas/blanche/blanche.c @@ -20,6 +20,7 @@ #include <dm.h> #include <dm/platform_data/serial_sh.h> #include <env.h> +#include <hang.h> #include <i2c.h> #include <linux/errno.h> #include <malloc.h> @@ -313,6 +314,7 @@ int board_init(void) } /* Added for BLANCHE(R-CarV2H board) */ +#ifndef CONFIG_DM_ETH int board_eth_init(bd_t *bis) { int rc = 0; @@ -337,6 +339,7 @@ int board_eth_init(bd_t *bis) return rc; } +#endif int dram_init(void) { @@ -355,4 +358,23 @@ int dram_init_banksize(void) void reset_cpu(ulong addr) { + struct udevice *dev; + const u8 pmic_bus = 6; + const u8 pmic_addr = 0x58; + u8 data; + int ret; + + ret = i2c_get_chip_for_busnum(pmic_bus, pmic_addr, 1, &dev); + if (ret) + hang(); + + ret = dm_i2c_read(dev, 0x13, &data, 1); + if (ret) + hang(); + + data |= BIT(1); + + ret = dm_i2c_write(dev, 0x13, &data, 1); + if (ret) + hang(); } diff --git a/cmd/bootefi.c b/cmd/bootefi.c index 3bbe2d6a1a4..aaed5755059 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -199,7 +199,8 @@ static void efi_carve_out_dt_rsv(void *fdt) * The /reserved-memory node may have children with * a size instead of a reg property. */ - if (addr != FDT_ADDR_T_NONE) + if (addr != FDT_ADDR_T_NONE && + fdtdec_get_is_enabled(fdt, subnode)) efi_reserve_memory(addr, size); subnode = fdt_next_subnode(fdt, subnode); } diff --git a/cmd/efidebug.c b/cmd/efidebug.c index bb7c13d6a1c..c1bb76477a6 100644 --- a/cmd/efidebug.c +++ b/cmd/efidebug.c @@ -489,10 +489,12 @@ static int do_efi_show_memmap(cmd_tbl_t *cmdtp, int flag, printf("%-16s %.*llx-%.*llx", type, EFI_PHYS_ADDR_WIDTH, - (u64)map_to_sysmem((void *)map->physical_start), + (u64)map_to_sysmem((void *)(uintptr_t) + map->physical_start), EFI_PHYS_ADDR_WIDTH, - (u64)map_to_sysmem((void *)map->physical_start + - map->num_pages * EFI_PAGE_SIZE)); + (u64)map_to_sysmem((void *)(uintptr_t) + (map->physical_start + + map->num_pages * EFI_PAGE_SIZE))); print_memory_attributes(map->attribute); putc('\n'); diff --git a/cmd/mmc.c b/cmd/mmc.c index 6f3cb85cc04..1860a3f2e5d 100644 --- a/cmd/mmc.c +++ b/cmd/mmc.c @@ -264,7 +264,7 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; if (!(mmc->version & MMC_VERSION_MMC)) { - printf("It is not a EMMC device\n"); + printf("It is not an eMMC device\n"); return CMD_RET_FAILURE; } if (mmc->version < MMC_VERSION_4_41) { @@ -718,7 +718,7 @@ static int do_mmc_boot_resize(cmd_tbl_t *cmdtp, int flag, return CMD_RET_FAILURE; if (IS_SD(mmc)) { - printf("It is not a EMMC device\n"); + printf("It is not an eMMC device\n"); return CMD_RET_FAILURE; } diff --git a/common/image-fit.c b/common/image-fit.c index 4435bc4f1d9..6da69d25ffe 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -2007,7 +2007,8 @@ int fit_image_load(bootm_headers_t *images, ulong addr, fit_image_check_os(fit, noffset, IH_OS_LINUX) || fit_image_check_os(fit, noffset, IH_OS_U_BOOT) || fit_image_check_os(fit, noffset, IH_OS_OPENRTOS) || - fit_image_check_os(fit, noffset, IH_OS_EFI); + fit_image_check_os(fit, noffset, IH_OS_EFI) || + fit_image_check_os(fit, noffset, IH_OS_VXWORKS); /* * If either of the checks fail, we should report an error, but diff --git a/configs/blanche_defconfig b/configs/blanche_defconfig index 5c7b517e7c8..64b7bccfb45 100644 --- a/configs/blanche_defconfig +++ b/configs/blanche_defconfig @@ -24,7 +24,6 @@ CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_PCI=y CONFIG_CMD_SDRAM=y -CONFIG_CMD_SF=y CONFIG_CMD_SPI=y CONFIG_CMD_USB=y CONFIG_CMD_DHCP=y @@ -53,7 +52,7 @@ CONFIG_MTD=y CONFIG_MTD_NOR_FLASH=y CONFIG_FLASH_CFI_DRIVER=y CONFIG_SYS_FLASH_CFI=y -CONFIG_SPI_FLASH=y +CONFIG_DM_SPI_FLASH=y CONFIG_SPI_FLASH_SPANSION=y CONFIG_SMC911X=y CONFIG_SMC911X_BASE=0x18000000 @@ -68,6 +67,7 @@ CONFIG_DM_REGULATOR_FIXED=y CONFIG_DM_REGULATOR_GPIO=y CONFIG_SCIF_CONSOLE=y CONFIG_SPI=y +CONFIG_DM_SPI=y CONFIG_SH_QSPI=y CONFIG_USB=y CONFIG_DM_USB=y diff --git a/configs/vexpress_ca9x4_defconfig b/configs/vexpress_ca9x4_defconfig index 2119df6b10e..6bd1f253b6a 100644 --- a/configs/vexpress_ca9x4_defconfig +++ b/configs/vexpress_ca9x4_defconfig @@ -34,4 +34,4 @@ CONFIG_SMC911X_32_BIT=y CONFIG_BAUDRATE=38400 CONFIG_CONS_INDEX=0 CONFIG_OF_LIBFDT=y -# CONFIG_EFI_LOADER is not set +CONFIG_DEFAULT_FDT_FILE="vexpress-v2p-ca9.dtb" diff --git a/doc/device-tree-bindings/gpio/fsl,mpc83xx-spisel-boot.txt b/doc/device-tree-bindings/gpio/fsl,mpc83xx-spisel-boot.txt new file mode 100644 index 00000000000..52d8bb0a5cb --- /dev/null +++ b/doc/device-tree-bindings/gpio/fsl,mpc83xx-spisel-boot.txt @@ -0,0 +1,22 @@ +MPC83xx SPISEL_BOOT gpio controller + +Provide access to MPC83xx SPISEL_BOOT signal as a gpio to allow it to be +easily bound as a SPI controller chip select. + +The SPISEL_BOOT signal is always an output. + +Required properties: + +- compatible: must be "fsl,mpc83xx-spisel-boot" or "fsl,mpc8309-spisel-boot". +- reg: must point to the SPI_CS register in the SoC register map. +- ngpios: number of gpios provided by driver, normally 1. + +Example: + + spisel_boot: spisel_boot@14c { + compatible = "fsl,mpc8309-spisel-boot"; + reg = <0x14c 0x04>; + #gpio-cells = <2>; + device_type = "gpio"; + ngpios = <1>; + }; diff --git a/drivers/clk/renesas/clk-rcar-gen2.c b/drivers/clk/renesas/clk-rcar-gen2.c index 13111b341af..bfd7620dae1 100644 --- a/drivers/clk/renesas/clk-rcar-gen2.c +++ b/drivers/clk/renesas/clk-rcar-gen2.c @@ -291,7 +291,8 @@ int gen2_clk_probe(struct udevice *dev) if (ret < 0) return ret; - rst_base = fdtdec_get_addr(gd->fdt_blob, ret, "reg"); + rst_base = fdtdec_get_addr_size_auto_noparent(gd->fdt_blob, ret, "reg", + 0, NULL, false); if (rst_base == FDT_ADDR_T_NONE) return -EINVAL; diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index f751a8b9ea8..2081520f42e 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -423,6 +423,14 @@ config MPC8XXX_GPIO value setting, the open-drain feature, which can configure individual GPIOs to work as open-drain outputs, is supported. +config MPC83XX_SPISEL_BOOT + bool "Freescale MPC83XX SPISEL_BOOT driver" + depends on DM_GPIO && ARCH_MPC830X + help + GPIO driver to set/clear dedicated SPISEL_BOOT output on MPC83XX. + + This pin is typically used as spi chip select to a spi nor flash. + config MT7621_GPIO bool "MediaTek MT7621 GPIO driver" depends on DM_GPIO && SOC_MT7628 diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 9dd5a583898..7638259007a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_DM644X_GPIO) += da8xx_gpio.o obj-$(CONFIG_ALTERA_PIO) += altera_pio.o obj-$(CONFIG_MPC83XX_GPIO) += mpc83xx_gpio.o obj-$(CONFIG_MPC8XXX_GPIO) += mpc8xxx_gpio.o +obj-$(CONFIG_MPC83XX_SPISEL_BOOT) += mpc83xx_spisel_boot.o obj-$(CONFIG_SH_GPIO_PFC) += sh_pfc.o obj-$(CONFIG_OMAP_GPIO) += omap_gpio.o obj-$(CONFIG_DB8500_GPIO) += db8500_gpio.o diff --git a/drivers/gpio/mpc83xx_spisel_boot.c b/drivers/gpio/mpc83xx_spisel_boot.c new file mode 100644 index 00000000000..c7b08404d93 --- /dev/null +++ b/drivers/gpio/mpc83xx_spisel_boot.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2019 DEIF A/S + * + * GPIO driver to set/clear SPISEL_BOOT pin on mpc83xx. + */ + +#include <common.h> +#include <dm.h> +#include <mapmem.h> +#include <asm/gpio.h> + +struct mpc83xx_spisel_boot { + u32 __iomem *spi_cs; + ulong addr; + uint gpio_count; + ulong type; +}; + +static u32 gpio_mask(uint gpio) +{ + return (1U << (31 - (gpio))); +} + +static int mpc83xx_spisel_boot_direction_input(struct udevice *dev, uint gpio) +{ + return -EINVAL; +} + +static int mpc83xx_spisel_boot_set_value(struct udevice *dev, uint gpio, int value) +{ + struct mpc83xx_spisel_boot *data = dev_get_priv(dev); + + debug("%s: gpio=%d, value=%u, gpio_mask=0x%08x\n", __func__, + gpio, value, gpio_mask(gpio)); + + if (value) + setbits_be32(data->spi_cs, gpio_mask(gpio)); + else + clrbits_be32(data->spi_cs, gpio_mask(gpio)); + + return 0; +} + +static int mpc83xx_spisel_boot_direction_output(struct udevice *dev, uint gpio, int value) +{ + return 0; +} + +static int mpc83xx_spisel_boot_get_value(struct udevice *dev, uint gpio) +{ + struct mpc83xx_spisel_boot *data = dev_get_priv(dev); + + return !!(in_be32(data->spi_cs) & gpio_mask(gpio)); +} + +static int mpc83xx_spisel_boot_get_function(struct udevice *dev, uint gpio) +{ + return GPIOF_OUTPUT; +} + +#if CONFIG_IS_ENABLED(OF_CONTROL) +static int mpc83xx_spisel_boot_ofdata_to_platdata(struct udevice *dev) +{ + struct mpc8xxx_gpio_plat *plat = dev_get_platdata(dev); + fdt_addr_t addr; + u32 reg[2]; + + dev_read_u32_array(dev, "reg", reg, 2); + addr = dev_translate_address(dev, reg); + + plat->addr = addr; + plat->size = reg[1]; + plat->ngpios = dev_read_u32_default(dev, "ngpios", 1); + + return 0; +} +#endif + +static int mpc83xx_spisel_boot_platdata_to_priv(struct udevice *dev) +{ + struct mpc83xx_spisel_boot *priv = dev_get_priv(dev); + struct mpc8xxx_gpio_plat *plat = dev_get_platdata(dev); + unsigned long size = plat->size; + ulong driver_data = dev_get_driver_data(dev); + + if (size == 0) + size = 0x04; + + priv->addr = plat->addr; + priv->spi_cs = map_sysmem(plat->addr, size); + + if (!priv->spi_cs) + return -ENOMEM; + + priv->gpio_count = plat->ngpios; + + priv->type = driver_data; + + return 0; +} + +static int mpc83xx_spisel_boot_probe(struct udevice *dev) +{ + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + struct mpc83xx_spisel_boot *data = dev_get_priv(dev); + char name[32], *str; + + mpc83xx_spisel_boot_platdata_to_priv(dev); + + snprintf(name, sizeof(name), "MPC@%lx_", data->addr); + str = strdup(name); + + if (!str) + return -ENOMEM; + + uc_priv->bank_name = str; + uc_priv->gpio_count = data->gpio_count; + + return 0; +} + +static const struct dm_gpio_ops mpc83xx_spisel_boot_ops = { + .direction_input = mpc83xx_spisel_boot_direction_input, + .direction_output = mpc83xx_spisel_boot_direction_output, + .get_value = mpc83xx_spisel_boot_get_value, + .set_value = mpc83xx_spisel_boot_set_value, + .get_function = mpc83xx_spisel_boot_get_function, +}; + +static const struct udevice_id mpc83xx_spisel_boot_ids[] = { + { .compatible = "fsl,mpc8309-spisel-boot" }, + { .compatible = "fsl,mpc83xx-spisel-boot" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(spisel_boot_mpc83xx) = { + .name = "spisel_boot_mpc83xx", + .id = UCLASS_GPIO, + .ops = &mpc83xx_spisel_boot_ops, +#if CONFIG_IS_ENABLED(OF_CONTROL) + .ofdata_to_platdata = mpc83xx_spisel_boot_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct mpc8xxx_gpio_plat), + .of_match = mpc83xx_spisel_boot_ids, +#endif + .probe = mpc83xx_spisel_boot_probe, + .priv_auto_alloc_size = sizeof(struct mpc83xx_spisel_boot), +}; diff --git a/drivers/gpio/mpc8xxx_gpio.c b/drivers/gpio/mpc8xxx_gpio.c index c273c2c8a40..4b385b8b395 100644 --- a/drivers/gpio/mpc8xxx_gpio.c +++ b/drivers/gpio/mpc8xxx_gpio.c @@ -57,27 +57,6 @@ static inline u32 mpc8xxx_gpio_get_dir(struct ccsr_gpio *base, u32 mask) return in_be32(&base->gpdir) & mask; } -static inline void mpc8xxx_gpio_set_in(struct ccsr_gpio *base, u32 gpios) -{ - clrbits_be32(&base->gpdat, gpios); - /* GPDIR register 0 -> input */ - clrbits_be32(&base->gpdir, gpios); -} - -static inline void mpc8xxx_gpio_set_low(struct ccsr_gpio *base, u32 gpios) -{ - clrbits_be32(&base->gpdat, gpios); - /* GPDIR register 1 -> output */ - setbits_be32(&base->gpdir, gpios); -} - -static inline void mpc8xxx_gpio_set_high(struct ccsr_gpio *base, u32 gpios) -{ - setbits_be32(&base->gpdat, gpios); - /* GPDIR register 1 -> output */ - setbits_be32(&base->gpdir, gpios); -} - static inline int mpc8xxx_gpio_open_drain_val(struct ccsr_gpio *base, u32 mask) { return in_be32(&base->gpodr) & mask; @@ -100,22 +79,32 @@ static inline void mpc8xxx_gpio_open_drain_off(struct ccsr_gpio *base, static int mpc8xxx_gpio_direction_input(struct udevice *dev, uint gpio) { struct mpc8xxx_gpio_data *data = dev_get_priv(dev); + u32 mask = gpio_mask(gpio); + + /* GPDIR register 0 -> input */ + clrbits_be32(&data->base->gpdir, mask); - mpc8xxx_gpio_set_in(data->base, gpio_mask(gpio)); return 0; } static int mpc8xxx_gpio_set_value(struct udevice *dev, uint gpio, int value) { struct mpc8xxx_gpio_data *data = dev_get_priv(dev); + struct ccsr_gpio *base = data->base; + u32 mask = gpio_mask(gpio); + u32 gpdir; if (value) { - data->dat_shadow |= gpio_mask(gpio); - mpc8xxx_gpio_set_high(data->base, gpio_mask(gpio)); + data->dat_shadow |= mask; } else { - data->dat_shadow &= ~gpio_mask(gpio); - mpc8xxx_gpio_set_low(data->base, gpio_mask(gpio)); + data->dat_shadow &= ~mask; } + + gpdir = in_be32(&base->gpdir); + gpdir |= gpio_mask(gpio); + out_be32(&base->gpdat, gpdir & data->dat_shadow); + out_be32(&base->gpdir, gpdir); + return 0; } diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 631b53b0930..bd588cab06b 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -807,7 +807,7 @@ static int _macb_init(struct macb_device *macb, const char *name) macb->next_rx_tail = 0; #ifdef CONFIG_MACB_ZYNQ - macb_writel(macb, DMACFG, MACB_ZYNQ_GEM_DMACR_INIT); + gem_writel(macb, DMACFG, MACB_ZYNQ_GEM_DMACR_INIT); #endif macb_writel(macb, RBQP, macb->rx_ring_dma); diff --git a/drivers/spi/mpc8xxx_spi.c b/drivers/spi/mpc8xxx_spi.c index 1c7bf10f91e..1bde31ad349 100644 --- a/drivers/spi/mpc8xxx_spi.c +++ b/drivers/spi/mpc8xxx_spi.c @@ -5,6 +5,7 @@ */ #include <common.h> +#include <clk.h> #include <dm.h> #include <errno.h> #include <malloc.h> @@ -27,6 +28,8 @@ enum { SPI_MODE_EN = BIT(31 - 7), /* Enable interface */ SPI_MODE_LEN_MASK = 0xf00000, + SPI_MODE_LEN_SHIFT = 20, + SPI_MODE_PM_SHIFT = 16, SPI_MODE_PM_MASK = 0xf0000, SPI_COM_LST = BIT(31 - 9), @@ -35,46 +38,38 @@ enum { struct mpc8xxx_priv { spi8xxx_t *spi; struct gpio_desc gpios[16]; - int max_cs; + int cs_count; + ulong clk_rate; }; -static inline u32 to_prescale_mod(u32 val) -{ - return (min(val, (u32)15) << 16); -} - -static void set_char_len(spi8xxx_t *spi, u32 val) -{ - clrsetbits_be32(&spi->mode, SPI_MODE_LEN_MASK, (val << 20)); -} - #define SPI_TIMEOUT 1000 -static int __spi_set_speed(spi8xxx_t *spi, uint speed) -{ - /* TODO(mario.six@gdsys.cc): This only ever sets one fixed speed */ - - /* Use SYSCLK / 8 (16.67MHz typ.) */ - clrsetbits_be32(&spi->mode, SPI_MODE_PM_MASK, to_prescale_mod(1)); - - return 0; -} - static int mpc8xxx_spi_ofdata_to_platdata(struct udevice *dev) { struct mpc8xxx_priv *priv = dev_get_priv(dev); + struct clk clk; int ret; priv->spi = (spi8xxx_t *)dev_read_addr(dev); - /* TODO(mario.six@gdsys.cc): Read clock and save the value */ - ret = gpio_request_list_by_name(dev, "gpios", priv->gpios, ARRAY_SIZE(priv->gpios), GPIOD_IS_OUT | GPIOD_ACTIVE_LOW); if (ret < 0) return -EINVAL; - priv->max_cs = ret; + priv->cs_count = ret; + + ret = clk_get_by_index(dev, 0, &clk); + if (ret) { + dev_err(dev, "%s: clock not defined\n", __func__); + return ret; + } + + priv->clk_rate = clk_get_rate(&clk); + if (!priv->clk_rate) { + dev_err(dev, "%s: failed to get clock rate\n", __func__); + return -EINVAL; + } return 0; } @@ -82,14 +77,18 @@ static int mpc8xxx_spi_ofdata_to_platdata(struct udevice *dev) static int mpc8xxx_spi_probe(struct udevice *dev) { struct mpc8xxx_priv *priv = dev_get_priv(dev); + spi8xxx_t *spi = priv->spi; /* * SPI pins on the MPC83xx are not muxed, so all we do is initialize * some registers */ - out_be32(&priv->spi->mode, SPI_MODE_REV | SPI_MODE_MS | SPI_MODE_EN); + out_be32(&priv->spi->mode, SPI_MODE_REV | SPI_MODE_MS); + + /* set len to 8 bits */ + setbits_be32(&spi->mode, (8 - 1) << SPI_MODE_LEN_SHIFT); - __spi_set_speed(priv->spi, 16666667); + setbits_be32(&spi->mode, SPI_MODE_EN); /* Clear all SPI events */ setbits_be32(&priv->spi->event, 0xffffffff); @@ -126,45 +125,35 @@ static int mpc8xxx_spi_xfer(struct udevice *dev, uint bitlen, struct mpc8xxx_priv *priv = dev_get_priv(bus); spi8xxx_t *spi = priv->spi; struct dm_spi_slave_platdata *platdata = dev_get_parent_platdata(dev); - u32 tmpdin = 0; - int num_blks = DIV_ROUND_UP(bitlen, 32); + u32 tmpdin = 0, tmpdout = 0, n; + const u8 *cout = dout; + u8 *cin = din; debug("%s: slave %s:%u dout %08X din %08X bitlen %u\n", __func__, - bus->name, platdata->cs, *(uint *)dout, *(uint *)din, bitlen); + bus->name, platdata->cs, (uint)dout, (uint)din, bitlen); + if (platdata->cs >= priv->cs_count) { + dev_err(dev, "chip select index %d too large (cs_count=%d)\n", + platdata->cs, priv->cs_count); + return -EINVAL; + } + if (bitlen % 8) { + printf("*** spi_xfer: bitlen must be multiple of 8\n"); + return -ENOTSUPP; + } if (flags & SPI_XFER_BEGIN) mpc8xxx_spi_cs_activate(dev); /* Clear all SPI events */ setbits_be32(&spi->event, 0xffffffff); + n = bitlen / 8; - /* Handle data in 32-bit chunks */ - while (num_blks--) { - u32 tmpdout = 0; - uchar xfer_bitlen = (bitlen >= 32 ? 32 : bitlen); + /* Handle data in 8-bit chunks */ + while (n--) { ulong start; - clrbits_be32(&spi->mode, SPI_MODE_EN); - - /* Set up length for this transfer */ - - if (bitlen <= 4) /* 4 bits or less */ - set_char_len(spi, 3); - else if (bitlen <= 16) /* at most 16 bits */ - set_char_len(spi, bitlen - 1); - else /* more than 16 bits -> full 32 bit transfer */ - set_char_len(spi, 0); - - setbits_be32(&spi->mode, SPI_MODE_EN); - - /* Shift data so it's msb-justified */ - tmpdout = *(u32 *)dout >> (32 - xfer_bitlen); - - if (bitlen > 32) { - /* Set up the next iteration if sending > 32 bits */ - bitlen -= 32; - dout += 4; - } + if (cout) + tmpdout = *cout++; /* Write the data out */ out_be32(&spi->tx, tmpdout); @@ -188,11 +177,8 @@ static int mpc8xxx_spi_xfer(struct udevice *dev, uint bitlen, tmpdin = in_be32(&spi->rx); setbits_be32(&spi->event, SPI_EV_NE); - *(u32 *)din = (tmpdin << (32 - xfer_bitlen)); - if (xfer_bitlen == 32) { - /* Advance output buffer by 32 bits */ - din += 4; - } + if (cin) + *cin++ = tmpdin; /* * Only bail when we've had both NE and NF events. @@ -224,8 +210,43 @@ static int mpc8xxx_spi_xfer(struct udevice *dev, uint bitlen, static int mpc8xxx_spi_set_speed(struct udevice *dev, uint speed) { struct mpc8xxx_priv *priv = dev_get_priv(dev); + spi8xxx_t *spi = priv->spi; + u32 bits, mask, div16, pm; + u32 mode; + ulong clk; + + clk = priv->clk_rate; + if (clk / 64 > speed) { + div16 = SPI_MODE_DIV16; + clk /= 16; + } else { + div16 = 0; + } + pm = (clk - 1)/(4*speed) + 1; + if (pm > 16) { + dev_err(dev, "requested speed %u too small\n", speed); + return -EINVAL; + } + pm--; + + bits = div16 | (pm << SPI_MODE_PM_SHIFT); + mask = SPI_MODE_DIV16 | SPI_MODE_PM_MASK; + mode = in_be32(&spi->mode); + if ((mode & mask) != bits) { + /* Must clear mode[EN] while changing speed. */ + mode &= ~(mask | SPI_MODE_EN); + out_be32(&spi->mode, mode); + mode |= bits; + out_be32(&spi->mode, mode); + mode |= SPI_MODE_EN; + out_be32(&spi->mode, mode); + } - return __spi_set_speed(priv->spi, speed); + debug("requested speed %u, set speed to %lu/(%s4*%u) == %lu\n", + speed, priv->clk_rate, div16 ? "16*" : "", pm + 1, + clk/(4*(pm + 1))); + + return 0; } static int mpc8xxx_spi_set_mode(struct udevice *dev, uint mode) diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h index ec418436953..410ec80618f 100644 --- a/include/configs/socfpga_common.h +++ b/include/configs/socfpga_common.h @@ -21,14 +21,15 @@ #define CONFIG_SYS_MEMTEST_END PHYS_SDRAM_1_SIZE #if defined(CONFIG_TARGET_SOCFPGA_GEN5) #define CONFIG_SYS_INIT_RAM_ADDR 0xFFFF0000 -#define CONFIG_SYS_INIT_RAM_SIZE 0x10000 +#define CONFIG_SYS_INIT_RAM_SIZE SOCFPGA_PHYS_OCRAM_SIZE #elif defined(CONFIG_TARGET_SOCFPGA_ARRIA10) #define CONFIG_SYS_INIT_RAM_ADDR 0xFFE00000 /* SPL memory allocation configuration, this is for FAT implementation */ #ifndef CONFIG_SYS_SPL_MALLOC_SIZE #define CONFIG_SYS_SPL_MALLOC_SIZE 0x10000 #endif -#define CONFIG_SYS_INIT_RAM_SIZE (0x40000 - CONFIG_SYS_SPL_MALLOC_SIZE) +#define CONFIG_SYS_INIT_RAM_SIZE (SOCFPGA_PHYS_OCRAM_SIZE - \ + CONFIG_SYS_SPL_MALLOC_SIZE) #define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SYS_INIT_RAM_ADDR + \ CONFIG_SYS_INIT_RAM_SIZE) #endif diff --git a/include/configs/vexpress_common.h b/include/configs/vexpress_common.h index 7f215a67077..e73658a9e6e 100644 --- a/include/configs/vexpress_common.h +++ b/include/configs/vexpress_common.h @@ -207,7 +207,8 @@ "devtmpfs.mount=0 vmalloc=256M\0" \ "bootflash=run flashargs; " \ "cp ${ramdisk_addr} ${ramdisk_addr_r} ${maxramdisk}; " \ - "bootm ${kernel_addr} ${ramdisk_addr_r}\0" + "bootm ${kernel_addr} ${ramdisk_addr_r}\0" \ + "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" /* FLASH and environment organization */ #define PHYS_FLASH_SIZE 0x04000000 /* 64MB */ diff --git a/test/py/tests/test_efi_loader.py b/test/py/tests/test_efi_loader.py index adf9d774529..9465c28fbc5 100644 --- a/test/py/tests/test_efi_loader.py +++ b/test/py/tests/test_efi_loader.py @@ -141,12 +141,13 @@ def fetch_tftp_file(u_boot_console, env_conf): return addr +@pytest.mark.buildconfigspec('of_control') @pytest.mark.buildconfigspec('cmd_bootefi_hello_compile') def test_efi_helloworld_net(u_boot_console): """Run the helloworld.efi binary via TFTP. - The helloworld.efi file is downloaded from the TFTP server and gets - executed. + The helloworld.efi file is downloaded from the TFTP server and is executed + using the fallback device tree at $fdtcontroladdr. """ addr = fetch_tftp_file(u_boot_console, 'env__efi_loader_helloworld_file') @@ -169,6 +170,7 @@ def test_efi_helloworld_builtin(u_boot_console): expected_text = 'Hello, world' assert expected_text in output +@pytest.mark.buildconfigspec('of_control') @pytest.mark.buildconfigspec('cmd_bootefi') def test_efi_grub_net(u_boot_console): """Run the grub.efi binary via TFTP. |