diff options
-rw-r--r-- | arch/arm/dts/armada-37xx.dtsi | 15 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/armada3700/cpu.c | 78 | ||||
-rw-r--r-- | arch/sandbox/cpu/start.c | 5 | ||||
-rw-r--r-- | board/BuR/brxre1/board.c | 9 | ||||
-rw-r--r-- | board/CZ.NIC/turris_omnia/turris_omnia.c | 48 | ||||
-rw-r--r-- | configs/brxre1_defconfig | 4 | ||||
-rw-r--r-- | configs/mx28evk_auart_console_defconfig | 6 | ||||
-rw-r--r-- | configs/mx28evk_defconfig | 6 | ||||
-rw-r--r-- | configs/mx28evk_nand_defconfig | 6 | ||||
-rw-r--r-- | configs/mx28evk_spi_defconfig | 6 | ||||
-rw-r--r-- | configs/pico-dwarf-imx6ul_defconfig | 4 | ||||
-rw-r--r-- | configs/pico-hobbit-imx6ul_defconfig | 4 | ||||
-rw-r--r-- | configs/pico-pi-imx6ul_defconfig | 4 | ||||
-rw-r--r-- | configs/pxm2_defconfig | 4 | ||||
-rw-r--r-- | configs/rut_defconfig | 5 | ||||
-rw-r--r-- | drivers/core/of_addr.c | 12 | ||||
-rw-r--r-- | drivers/net/mscc_eswitch/luton_switch.c | 5 | ||||
-rw-r--r-- | drivers/pci/pci-aardvark.c | 169 | ||||
-rw-r--r-- | drivers/pwm/cros_ec_pwm.c | 2 | ||||
-rw-r--r-- | include/configs/turris_omnia.h | 23 | ||||
-rw-r--r-- | lib/image-sparse.c | 17 | ||||
-rw-r--r-- | test/dm/test-fdt.c | 33 |
22 files changed, 373 insertions, 92 deletions
diff --git a/arch/arm/dts/armada-37xx.dtsi b/arch/arm/dts/armada-37xx.dtsi index a1052add0cc..2615b8c748c 100644 --- a/arch/arm/dts/armada-37xx.dtsi +++ b/arch/arm/dts/armada-37xx.dtsi @@ -323,7 +323,7 @@ }; pcie0: pcie@d0070000 { - compatible = "marvell,armada-37xx-pcie"; + compatible = "marvell,armada-3700-pcie"; reg = <0 0xd0070000 0 0x20000>; #address-cells = <3>; #size-cells = <2>; @@ -332,10 +332,17 @@ status = "disabled"; bus-range = <0 0xff>; + /* + * The 128 MiB address range [0xe8000000-0xf0000000] is + * dedicated for PCIe and can be assigned to 8 windows + * with size a power of two. Use one 64 KiB window for + * IO at the end and the remaining seven windows + * (totaling 127 MiB) for MEM. + */ ranges = <0x82000000 0 0xe8000000 - 0 0xe8000000 0 0x1000000 /* Port 0 MEM */ - 0x81000000 0 0xe9000000 - 0 0xe9000000 0 0x10000>; /* Port 0 IO*/ + 0 0xe8000000 0 0x7f00000 /* Port 0 MEM */ + 0x81000000 0 0xefff0000 + 0 0xefff0000 0 0x10000>; /* Port 0 IO*/ }; }; }; diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c index 0cf60d7cdd7..9aec0ce9a43 100644 --- a/arch/arm/mach-mvebu/armada3700/cpu.c +++ b/arch/arm/mach-mvebu/armada3700/cpu.c @@ -8,6 +8,7 @@ #include <cpu_func.h> #include <dm.h> #include <fdtdec.h> +#include <fdt_support.h> #include <init.h> #include <asm/global_data.h> #include <linux/bitops.h> @@ -53,8 +54,6 @@ #define A3700_PTE_BLOCK_DEVICE \ (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE) -#define PCIE_PATH "/soc/pcie@d0070000" - DECLARE_GLOBAL_DATA_PTR; static struct mm_region mvebu_mem_map[MAX_MEM_MAP_REGIONS] = { @@ -282,36 +281,81 @@ static u32 find_pcie_window_base(void) return -1; } +static int fdt_setprop_inplace_u32_partial(void *blob, int node, + const char *name, + u32 idx, u32 val) +{ + val = cpu_to_fdt32(val); + + return fdt_setprop_inplace_namelen_partial(blob, node, name, + strlen(name), + idx * sizeof(u32), + &val, sizeof(u32)); +} + int a3700_fdt_fix_pcie_regions(void *blob) { - u32 new_ranges[14], base; + int acells, pacells, scells; + u32 base, fix_offset; const u32 *ranges; - int node, len; + int node, pnode; + int ret, i, len; + + base = find_pcie_window_base(); + if (base == -1) + return -ENOENT; - node = fdt_path_offset(blob, PCIE_PATH); + node = fdt_node_offset_by_compatible(blob, -1, "marvell,armada-3700-pcie"); if (node < 0) return node; ranges = fdt_getprop(blob, node, "ranges", &len); - if (!ranges) + if (!ranges || len % sizeof(u32)) return -ENOENT; - if (len != sizeof(new_ranges)) - return -EINVAL; - - memcpy(new_ranges, ranges, len); + /* + * The "ranges" property is an array of + * { <child address> <parent address> <size in child address space> } + * + * All 3 elements can span a diffent number of cells. Fetch their sizes. + */ + pnode = fdt_parent_offset(blob, node); + acells = fdt_address_cells(blob, node); + pacells = fdt_address_cells(blob, pnode); + scells = fdt_size_cells(blob, node); - base = find_pcie_window_base(); - if (base == -1) + /* Child PCI addresses always use 3 cells */ + if (acells != 3) return -ENOENT; - new_ranges[2] = cpu_to_fdt32(base); - new_ranges[4] = new_ranges[2]; + /* Calculate fixup offset from first child address (in last cell) */ + fix_offset = base - fdt32_to_cpu(ranges[2]); - new_ranges[9] = cpu_to_fdt32(base + 0x1000000); - new_ranges[11] = new_ranges[9]; + /* + * Fix address (last cell) of each child address and each parent + * address + */ + for (i = 0; i < len / sizeof(u32); i += acells + pacells + scells) { + int idx; + + /* fix child address */ + idx = i + acells - 1; + ret = fdt_setprop_inplace_u32_partial(blob, node, "ranges", idx, + fdt32_to_cpu(ranges[idx]) + + fix_offset); + if (ret) + return ret; + + /* fix parent address */ + idx = i + acells + pacells - 1; + ret = fdt_setprop_inplace_u32_partial(blob, node, "ranges", idx, + fdt32_to_cpu(ranges[idx]) + + fix_offset); + if (ret) + return ret; + } - return fdt_setprop_inplace(blob, node, "ranges", new_ranges, len); + return 0; } void reset_cpu(void) diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 63ca514ebd5..6bb94473f19 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -436,10 +436,13 @@ void sandbox_reset(void) int main(int argc, char *argv[]) { struct sandbox_state *state; + void * text_base; gd_t data; int size; int ret; + text_base = os_find_text_base(); + /* * Copy argv[] so that we can pass the arguments in the original * sequence when resetting the sandbox. @@ -452,7 +455,7 @@ int main(int argc, char *argv[]) memset(&data, '\0', sizeof(data)); gd = &data; - gd->arch.text_base = os_find_text_base(); + gd->arch.text_base = text_base; ret = state_init(); if (ret) diff --git a/board/BuR/brxre1/board.c b/board/BuR/brxre1/board.c index ef692b006d5..544e09f447c 100644 --- a/board/BuR/brxre1/board.c +++ b/board/BuR/brxre1/board.c @@ -164,12 +164,21 @@ int board_late_init(void) br_resetc_bmode(); /* setup othbootargs for bootvx-command (vxWorks bootline) */ +#ifdef CONFIG_LCD snprintf(othbootargs, sizeof(othbootargs), "u=vxWorksFTP pw=vxWorks o=0x%08x;0x%08x;0x%08x;0x%08x", (u32)gd->fb_base - 0x20, (u32)env_get_ulong("vx_memtop", 16, gd->fb_base - 0x20), (u32)env_get_ulong("vx_romfsbase", 16, 0), (u32)env_get_ulong("vx_romfssize", 16, 0)); +#else + snprintf(othbootargs, sizeof(othbootargs), + "u=vxWorksFTP pw=vxWorks o=0x%08x;0x%08x;0x%08x;0x%08x", + (u32)gd->relocaddr, + (u32)env_get_ulong("vx_memtop", 16, gd->relocaddr), + (u32)env_get_ulong("vx_romfsbase", 16, 0), + (u32)env_get_ulong("vx_romfssize", 16, 0)); +#endif env_set("othbootargs", othbootargs); /* * reset VBAR registers to its reset location, VxWorks 6.9.3.2 does diff --git a/board/CZ.NIC/turris_omnia/turris_omnia.c b/board/CZ.NIC/turris_omnia/turris_omnia.c index 1d3cefe703b..ade923f5994 100644 --- a/board/CZ.NIC/turris_omnia/turris_omnia.c +++ b/board/CZ.NIC/turris_omnia/turris_omnia.c @@ -337,24 +337,6 @@ static int set_regdomain(void) return env_set("regdomain", rd); } -/* - * default factory reset bootcommand on Omnia first sets all the front LEDs - * to green and then tries to load the rescue image from SPI flash memory and - * boot it - */ -#define OMNIA_FACTORY_RESET_BOOTCMD \ - "i2c dev 2; " \ - "i2c mw 0x2a.1 0x3 0x1c 1; " \ - "i2c mw 0x2a.1 0x4 0x1c 1; " \ - "mw.l 0x01000000 0x00ff000c; " \ - "i2c write 0x01000000 0x2a.1 0x5 4 -s; " \ - "setenv bootargs \"earlyprintk console=ttyS0,115200" \ - " omniarescue=$omnia_reset\"; " \ - "sf probe; " \ - "sf read 0x1000000 0x100000 0x700000; " \ - "bootm 0x1000000; " \ - "bootz 0x1000000" - static void handle_reset_button(void) { int ret; @@ -370,8 +352,36 @@ static void handle_reset_button(void) env_set_ulong("omnia_reset", reset_status); if (reset_status) { + const char * const vars[3] = { + "bootcmd", + "bootcmd_rescue", + "distro_bootcmd", + }; + + /* + * Set the above envs to their default values, in case the user + * managed to break them. + */ + env_set_default_vars(3, (char * const *)vars, 0); + + /* Ensure bootcmd_rescue is used by distroboot */ + env_set("boot_targets", "rescue"); + printf("RESET button was pressed, overwriting bootcmd!\n"); - env_set("bootcmd", OMNIA_FACTORY_RESET_BOOTCMD); + } else { + /* + * In case the user somehow managed to save environment with + * boot_targets=rescue, reset boot_targets to default value. + * This could happen in subsequent commands if bootcmd_rescue + * failed. + */ + if (!strcmp(env_get("boot_targets"), "rescue")) { + const char * const vars[1] = { + "boot_targets", + }; + + env_set_default_vars(1, (char * const *)vars, 0); + } } } #endif diff --git a/configs/brxre1_defconfig b/configs/brxre1_defconfig index 57f3f437d91..6d9f24314f2 100644 --- a/configs/brxre1_defconfig +++ b/configs/brxre1_defconfig @@ -92,8 +92,8 @@ CONFIG_USB_MUSB_TI=y CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y CONFIG_SYS_WHITE_ON_BLACK=y -CONFIG_AM335X_LCD=y -CONFIG_LCD=y +# CONFIG_AM335X_LCD is not set +# CONFIG_LCD is not set CONFIG_SPL_TINY_MEMSET=y # CONFIG_OF_LIBFDT_OVERLAY is not set # CONFIG_EFI_LOADER is not set diff --git a/configs/mx28evk_auart_console_defconfig b/configs/mx28evk_auart_console_defconfig index ec4fd6585ee..60b9f3999ed 100644 --- a/configs/mx28evk_auart_console_defconfig +++ b/configs/mx28evk_auart_console_defconfig @@ -56,8 +56,8 @@ CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_SMSC95XX=y -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set CONFIG_SPLASH_SCREEN=y -CONFIG_VIDEO_BMP_GZIP=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_GZIP is not set +# CONFIG_VIDEO_BMP_RLE8 is not set CONFIG_OF_LIBFDT=y diff --git a/configs/mx28evk_defconfig b/configs/mx28evk_defconfig index 4f0ed83bc1f..abc0c48d216 100644 --- a/configs/mx28evk_defconfig +++ b/configs/mx28evk_defconfig @@ -56,8 +56,8 @@ CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_SMSC95XX=y -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set CONFIG_SPLASH_SCREEN=y -CONFIG_VIDEO_BMP_GZIP=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_GZIP is not set +# CONFIG_VIDEO_BMP_RLE8 is not set CONFIG_OF_LIBFDT=y diff --git a/configs/mx28evk_nand_defconfig b/configs/mx28evk_nand_defconfig index 7d95b8fc52d..0a376a2f803 100644 --- a/configs/mx28evk_nand_defconfig +++ b/configs/mx28evk_nand_defconfig @@ -57,8 +57,8 @@ CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_SMSC95XX=y -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set CONFIG_SPLASH_SCREEN=y -CONFIG_VIDEO_BMP_GZIP=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_GZIP is not set +# CONFIG_VIDEO_BMP_RLE8 is not set CONFIG_OF_LIBFDT=y diff --git a/configs/mx28evk_spi_defconfig b/configs/mx28evk_spi_defconfig index e969d50af7f..a6b00c29f55 100644 --- a/configs/mx28evk_spi_defconfig +++ b/configs/mx28evk_spi_defconfig @@ -53,8 +53,8 @@ CONFIG_USB_STORAGE=y CONFIG_USB_HOST_ETHER=y CONFIG_USB_ETHER_ASIX=y CONFIG_USB_ETHER_SMSC95XX=y -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set CONFIG_SPLASH_SCREEN=y -CONFIG_VIDEO_BMP_GZIP=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_GZIP is not set +# CONFIG_VIDEO_BMP_RLE8 is not set CONFIG_OF_LIBFDT=y diff --git a/configs/pico-dwarf-imx6ul_defconfig b/configs/pico-dwarf-imx6ul_defconfig index 9695eb26576..bf016f80ed2 100644 --- a/configs/pico-dwarf-imx6ul_defconfig +++ b/configs/pico-dwarf-imx6ul_defconfig @@ -68,7 +68,7 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL" CONFIG_USB_GADGET_VENDOR_NUM=0x0525 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_CI_UDC=y -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set CONFIG_SPLASH_SCREEN=y CONFIG_SPLASH_SCREEN_ALIGN=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_RLE8 is not set diff --git a/configs/pico-hobbit-imx6ul_defconfig b/configs/pico-hobbit-imx6ul_defconfig index 5c1ca0b8d7f..14d36c5e6a0 100644 --- a/configs/pico-hobbit-imx6ul_defconfig +++ b/configs/pico-hobbit-imx6ul_defconfig @@ -71,7 +71,7 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL" CONFIG_USB_GADGET_VENDOR_NUM=0x0525 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_CI_UDC=y -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set CONFIG_SPLASH_SCREEN=y CONFIG_SPLASH_SCREEN_ALIGN=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_RLE8 is not set diff --git a/configs/pico-pi-imx6ul_defconfig b/configs/pico-pi-imx6ul_defconfig index 51b71a77e5e..ba8b1a1e8e8 100644 --- a/configs/pico-pi-imx6ul_defconfig +++ b/configs/pico-pi-imx6ul_defconfig @@ -71,7 +71,7 @@ CONFIG_USB_GADGET_MANUFACTURER="FSL" CONFIG_USB_GADGET_VENDOR_NUM=0x0525 CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5 CONFIG_CI_UDC=y -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set CONFIG_SPLASH_SCREEN=y CONFIG_SPLASH_SCREEN_ALIGN=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_RLE8 is not set diff --git a/configs/pxm2_defconfig b/configs/pxm2_defconfig index 90ef4c8d99a..da6b1bb0e36 100644 --- a/configs/pxm2_defconfig +++ b/configs/pxm2_defconfig @@ -101,10 +101,10 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x02d2 CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_USB_ETHER=y CONFIG_USBNET_HOST_ADDR="de:ad:be:af:00:00" -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set # CONFIG_VIDEO_SW_CURSOR is not set CONFIG_SYS_CONSOLE_BG_COL=0xff CONFIG_SYS_CONSOLE_FG_COL=0x00 CONFIG_SPLASH_SCREEN=y CONFIG_SPLASH_SCREEN_ALIGN=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_RLE8 is not set diff --git a/configs/rut_defconfig b/configs/rut_defconfig index 6fc06f1ed97..2ddf0e63dd5 100644 --- a/configs/rut_defconfig +++ b/configs/rut_defconfig @@ -31,7 +31,6 @@ CONFIG_USE_PREBOOT=y CONFIG_SYS_CONSOLE_INFO_QUIET=y # CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_BOARDINFO is not set -CONFIG_ARCH_EARLY_INIT_R=y CONFIG_ARCH_MISC_INIT=y CONFIG_SPL_I2C_SUPPORT=y CONFIG_SPL_NAND_DRIVERS=y @@ -101,10 +100,10 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0908 CONFIG_USB_GADGET_PRODUCT_NUM=0x02d2 CONFIG_USB_GADGET_DOWNLOAD=y CONFIG_USB_ETHER=y -CONFIG_VIDEO=y +# CONFIG_VIDEO is not set # CONFIG_VIDEO_SW_CURSOR is not set CONFIG_SYS_CONSOLE_BG_COL=0xff CONFIG_SYS_CONSOLE_FG_COL=0x00 CONFIG_SPLASH_SCREEN=y CONFIG_SPLASH_SCREEN_ALIGN=y -CONFIG_VIDEO_BMP_RLE8=y +# CONFIG_VIDEO_BMP_RLE8 is not set diff --git a/drivers/core/of_addr.c b/drivers/core/of_addr.c index 9b77308182d..3fbc0a7afa6 100644 --- a/drivers/core/of_addr.c +++ b/drivers/core/of_addr.c @@ -118,11 +118,6 @@ static struct of_bus *of_match_bus(struct device_node *np) return NULL; } -static void dev_count_cells(const struct device_node *np, int *nap, int *nsp) -{ - of_bus_default_count_cells(np, nap, nsp); -} - const __be32 *of_get_address(const struct device_node *dev, int index, u64 *size, unsigned int *flags) { @@ -136,7 +131,6 @@ const __be32 *of_get_address(const struct device_node *dev, int index, parent = of_get_parent(dev); if (parent == NULL) return NULL; - dev_count_cells(dev, &na, &ns); bus = of_match_bus(parent); bus->count_cells(dev, &na, &ns); of_node_put(parent); @@ -192,9 +186,13 @@ static int of_translate_one(const struct device_node *parent, * * As far as we know, this damage only exists on Apple machines, so * This code is only enabled on powerpc. --gcl + * + * This quirk also applies for 'dma-ranges' which frequently exist in + * child nodes without 'dma-ranges' in the parent nodes. --RobH */ ranges = of_get_property(parent, rprop, &rlen); - if (ranges == NULL && !of_empty_ranges_quirk(parent)) { + if (ranges == NULL && !of_empty_ranges_quirk(parent) && + strcmp(rprop, "dma-ranges")) { debug("no ranges; cannot translate\n"); return 1; } diff --git a/drivers/net/mscc_eswitch/luton_switch.c b/drivers/net/mscc_eswitch/luton_switch.c index 54afa14c9dd..73c950d118f 100644 --- a/drivers/net/mscc_eswitch/luton_switch.c +++ b/drivers/net/mscc_eswitch/luton_switch.c @@ -588,7 +588,6 @@ static int luton_probe(struct udevice *dev) struct luton_private *priv = dev_get_priv(dev); int i, ret; struct resource res; - fdt32_t faddr; phys_addr_t addr_base; unsigned long addr_size; ofnode eth_node, node, mdio_node; @@ -658,9 +657,7 @@ static int luton_probe(struct udevice *dev) if (ofnode_read_resource(mdio_node, 0, &res)) return -ENOMEM; - faddr = cpu_to_fdt32(res.start); - - addr_base = ofnode_translate_address(mdio_node, &faddr); + addr_base = res.start; addr_size = res.end - res.start; /* If the bus is new then create a new bus */ diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c index c43d4f309b1..96aa039bdc2 100644 --- a/drivers/pci/pci-aardvark.c +++ b/drivers/pci/pci-aardvark.c @@ -99,6 +99,46 @@ #define PCIE_CORE_CTRL2_STRICT_ORDER_ENABLE BIT(5) #define PCIE_CORE_CTRL2_ADDRWIN_MAP_ENABLE BIT(6) +/* PCIe window configuration */ +#define OB_WIN_BASE_ADDR 0x4c00 +#define OB_WIN_BLOCK_SIZE 0x20 +#define OB_WIN_COUNT 8 +#define OB_WIN_REG_ADDR(win, offset) (OB_WIN_BASE_ADDR + \ + OB_WIN_BLOCK_SIZE * (win) + \ + (offset)) +#define OB_WIN_MATCH_LS(win) OB_WIN_REG_ADDR(win, 0x00) +#define OB_WIN_ENABLE BIT(0) +#define OB_WIN_MATCH_MS(win) OB_WIN_REG_ADDR(win, 0x04) +#define OB_WIN_REMAP_LS(win) OB_WIN_REG_ADDR(win, 0x08) +#define OB_WIN_REMAP_MS(win) OB_WIN_REG_ADDR(win, 0x0c) +#define OB_WIN_MASK_LS(win) OB_WIN_REG_ADDR(win, 0x10) +#define OB_WIN_MASK_MS(win) OB_WIN_REG_ADDR(win, 0x14) +#define OB_WIN_ACTIONS(win) OB_WIN_REG_ADDR(win, 0x18) +#define OB_WIN_DEFAULT_ACTIONS (OB_WIN_ACTIONS(OB_WIN_COUNT-1) + 0x4) +#define OB_WIN_FUNC_NUM_MASK GENMASK(31, 24) +#define OB_WIN_FUNC_NUM_SHIFT 24 +#define OB_WIN_FUNC_NUM_ENABLE BIT(23) +#define OB_WIN_BUS_NUM_BITS_MASK GENMASK(22, 20) +#define OB_WIN_BUS_NUM_BITS_SHIFT 20 +#define OB_WIN_MSG_CODE_ENABLE BIT(22) +#define OB_WIN_MSG_CODE_MASK GENMASK(21, 14) +#define OB_WIN_MSG_CODE_SHIFT 14 +#define OB_WIN_MSG_PAYLOAD_LEN BIT(12) +#define OB_WIN_ATTR_ENABLE BIT(11) +#define OB_WIN_ATTR_TC_MASK GENMASK(10, 8) +#define OB_WIN_ATTR_TC_SHIFT 8 +#define OB_WIN_ATTR_RELAXED BIT(7) +#define OB_WIN_ATTR_NOSNOOP BIT(6) +#define OB_WIN_ATTR_POISON BIT(5) +#define OB_WIN_ATTR_IDO BIT(4) +#define OB_WIN_TYPE_MASK GENMASK(3, 0) +#define OB_WIN_TYPE_SHIFT 0 +#define OB_WIN_TYPE_MEM 0x0 +#define OB_WIN_TYPE_IO 0x4 +#define OB_WIN_TYPE_CONFIG_TYPE0 0x8 +#define OB_WIN_TYPE_CONFIG_TYPE1 0x9 +#define OB_WIN_TYPE_MSG 0xc + /* LMI registers base address and register offsets */ #define LMI_BASE_ADDR 0x6000 #define CFG_REG (LMI_BASE_ADDR + 0x0) @@ -522,6 +562,86 @@ static int pcie_advk_wait_for_link(struct pcie_advk *pcie) return -ETIMEDOUT; } +/* + * Set PCIe address window register which could be used for memory + * mapping. + */ +static void pcie_advk_set_ob_win(struct pcie_advk *pcie, u8 win_num, + phys_addr_t match, phys_addr_t remap, + phys_addr_t mask, u32 actions) +{ + advk_writel(pcie, OB_WIN_ENABLE | + lower_32_bits(match), OB_WIN_MATCH_LS(win_num)); + advk_writel(pcie, upper_32_bits(match), OB_WIN_MATCH_MS(win_num)); + advk_writel(pcie, lower_32_bits(remap), OB_WIN_REMAP_LS(win_num)); + advk_writel(pcie, upper_32_bits(remap), OB_WIN_REMAP_MS(win_num)); + advk_writel(pcie, lower_32_bits(mask), OB_WIN_MASK_LS(win_num)); + advk_writel(pcie, upper_32_bits(mask), OB_WIN_MASK_MS(win_num)); + advk_writel(pcie, actions, OB_WIN_ACTIONS(win_num)); +} + +static void pcie_advk_disable_ob_win(struct pcie_advk *pcie, u8 win_num) +{ + advk_writel(pcie, 0, OB_WIN_MATCH_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_MATCH_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_REMAP_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_REMAP_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_MASK_LS(win_num)); + advk_writel(pcie, 0, OB_WIN_MASK_MS(win_num)); + advk_writel(pcie, 0, OB_WIN_ACTIONS(win_num)); +} + +static void pcie_advk_set_ob_region(struct pcie_advk *pcie, int *wins, + struct pci_region *region, u32 actions) +{ + phys_addr_t phys_start = region->phys_start; + pci_addr_t bus_start = region->bus_start; + pci_size_t size = region->size; + phys_addr_t win_mask; + u64 win_size; + + if (*wins == -1) + return; + + /* + * The n-th PCIe window is configured by tuple (match, remap, mask) + * and an access to address A uses this window it if A matches the + * match with given mask. + * So every PCIe window size must be a power of two and every start + * address must be aligned to window size. Minimal size is 64 KiB + * because lower 16 bits of mask must be zero. + */ + while (*wins < OB_WIN_COUNT && size > 0) { + /* Calculate the largest aligned window size */ + win_size = (1ULL << (fls64(size) - 1)) | + (phys_start ? (1ULL << __ffs64(phys_start)) : 0); + win_size = 1ULL << __ffs64(win_size); + if (win_size < 0x10000) + break; + + dev_dbg(pcie->dev, + "Configuring PCIe window %d: [0x%llx-0x%llx] as 0x%x\n", + *wins, (u64)phys_start, (u64)phys_start + win_size, + actions); + win_mask = ~(win_size - 1) & ~0xffff; + pcie_advk_set_ob_win(pcie, *wins, phys_start, bus_start, + win_mask, actions); + + phys_start += win_size; + bus_start += win_size; + size -= win_size; + (*wins)++; + } + + if (size > 0) { + *wins = -1; + dev_err(pcie->dev, + "Invalid PCIe region [0x%llx-0x%llx]\n", + (u64)region->phys_start, + (u64)region->phys_start + region->size); + } +} + /** * pcie_advk_setup_hw() - PCIe initailzation * @@ -531,6 +651,8 @@ static int pcie_advk_wait_for_link(struct pcie_advk *pcie) */ static int pcie_advk_setup_hw(struct pcie_advk *pcie) { + struct pci_region *io, *mem, *pref; + int i, wins; u32 reg; /* Set to Direct mode */ @@ -597,7 +719,9 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie) * configurations (Default User Field: 0xD0074CFC) * are used to transparent address translation for * the outbound transactions. Thus, PCIe address - * windows are not required. + * windows are not required for transparent memory + * access when default outbound window configuration + * is set for memory access. */ reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG); reg |= PCIE_CORE_CTRL2_ADDRWIN_MAP_ENABLE; @@ -613,10 +737,33 @@ static int pcie_advk_setup_hw(struct pcie_advk *pcie) reg |= PIO_CTRL_ADDR_WIN_DISABLE; advk_writel(pcie, reg, PIO_CTRL); - /* Start link training */ - reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG); - reg |= PCIE_CORE_LINK_TRAINING; - advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG); + /* + * Set memory access in Default User Field so it + * is not required to configure PCIe address for + * transparent memory access. + */ + advk_writel(pcie, OB_WIN_TYPE_MEM, OB_WIN_DEFAULT_ACTIONS); + + /* + * Configure PCIe address windows for non-memory or + * non-transparent access as by default PCIe uses + * transparent memory access. + */ + wins = 0; + pci_get_regions(pcie->dev, &io, &mem, &pref); + if (io) + pcie_advk_set_ob_region(pcie, &wins, io, OB_WIN_TYPE_IO); + if (mem && mem->phys_start != mem->bus_start) + pcie_advk_set_ob_region(pcie, &wins, mem, OB_WIN_TYPE_MEM); + if (pref && pref->phys_start != pref->bus_start) + pcie_advk_set_ob_region(pcie, &wins, pref, OB_WIN_TYPE_MEM); + + /* Disable remaining PCIe outbound windows */ + for (i = ((wins >= 0) ? wins : 0); i < OB_WIN_COUNT; i++) + pcie_advk_disable_ob_win(pcie, i); + + if (wins == -1) + return -EINVAL; /* Wait for PCIe link up */ if (pcie_advk_wait_for_link(pcie)) @@ -679,6 +826,16 @@ static int pcie_advk_remove(struct udevice *dev) { struct pcie_advk *pcie = dev_get_priv(dev); u32 reg; + int i; + + for (i = 0; i < OB_WIN_COUNT; i++) + pcie_advk_disable_ob_win(pcie, i); + + reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG); + reg &= ~(PCIE_CORE_CMD_MEM_ACCESS_EN | + PCIE_CORE_CMD_IO_ACCESS_EN | + PCIE_CORE_CMD_MEM_IO_REQ_EN); + advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG); reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG); reg &= ~LINK_TRAINING_EN; @@ -716,7 +873,7 @@ static const struct dm_pci_ops pcie_advk_ops = { }; static const struct udevice_id pcie_advk_ids[] = { - { .compatible = "marvell,armada-37xx-pcie" }, + { .compatible = "marvell,armada-3700-pcie" }, { } }; diff --git a/drivers/pwm/cros_ec_pwm.c b/drivers/pwm/cros_ec_pwm.c index 44f4105dfd5..4a39c319aa2 100644 --- a/drivers/pwm/cros_ec_pwm.c +++ b/drivers/pwm/cros_ec_pwm.c @@ -80,5 +80,5 @@ U_BOOT_DRIVER(cros_ec_pwm) = { .id = UCLASS_PWM, .of_match = cros_ec_pwm_ids, .ops = &cros_ec_pwm_ops, - .priv_auto_alloc_size = sizeof(struct cros_ec_pwm_priv), + .priv_auto = sizeof(struct cros_ec_pwm_priv), }; diff --git a/include/configs/turris_omnia.h b/include/configs/turris_omnia.h index 0b55c14d8bf..7da18f97db8 100644 --- a/include/configs/turris_omnia.h +++ b/include/configs/turris_omnia.h @@ -108,12 +108,35 @@ #include <config_distro_bootcmd.h> +/* + * The factory reset bootcommand on Omnia first sets all the front LEDs to green + * and then tries to load the rescue image from SPI flash memory and boot it + */ +#define TURRIS_OMNIA_BOOTCMD_RESCUE \ + "i2c dev 2; " \ + "i2c mw 0x2a.1 0x3 0x1c 1; " \ + "i2c mw 0x2a.1 0x4 0x1c 1; " \ + "mw.l 0x01000000 0x00ff000c; " \ + "i2c write 0x01000000 0x2a.1 0x5 4 -s; " \ + "setenv bootargs \"earlyprintk console=ttyS0,115200" \ + " omniarescue=$omnia_reset rescue_mode=$omnia_reset\"; " \ + "sf probe; " \ + "sf read 0x1000000 0x100000 0x700000; " \ + "lzmadec 0x1000000 0x1700000; " \ + "if gpio input gpio@71_4; then " \ + "bootm 0x1700000#sfp; " \ + "else " \ + "bootm 0x1700000; " \ + "fi; " \ + "bootz 0x1000000" + #define CONFIG_EXTRA_ENV_SETTINGS \ RELOCATION_LIMITS_ENV_SETTINGS \ LOAD_ADDRESS_ENV_SETTINGS \ "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ "console=ttyS0,115200\0" \ "ethact=ethernet@34000\0" \ + "bootcmd_rescue=" TURRIS_OMNIA_BOOTCMD_RESCUE "\0" \ BOOTENV #endif /* CONFIG_SPL_BUILD */ diff --git a/lib/image-sparse.c b/lib/image-sparse.c index 187ac28cd36..d80fdbbf58e 100644 --- a/lib/image-sparse.c +++ b/lib/image-sparse.c @@ -55,10 +55,10 @@ int write_sparse_image(struct sparse_storage *info, lbaint_t blk; lbaint_t blkcnt; lbaint_t blks; - uint32_t bytes_written = 0; + uint64_t bytes_written = 0; unsigned int chunk; unsigned int offset; - unsigned int chunk_data_sz; + uint64_t chunk_data_sz; uint32_t *fill_buf = NULL; uint32_t fill_val; sparse_header_t *sparse_header; @@ -132,8 +132,8 @@ int write_sparse_image(struct sparse_storage *info, sizeof(chunk_header_t)); } - chunk_data_sz = sparse_header->blk_sz * chunk_header->chunk_sz; - blkcnt = chunk_data_sz / info->blksz; + chunk_data_sz = ((u64)sparse_header->blk_sz) * chunk_header->chunk_sz; + blkcnt = DIV_ROUND_UP_ULL(chunk_data_sz, info->blksz); switch (chunk_header->chunk_type) { case CHUNK_TYPE_RAW: if (chunk_header->total_sz != @@ -162,7 +162,7 @@ int write_sparse_image(struct sparse_storage *info, return -1; } blk += blks; - bytes_written += blkcnt * info->blksz; + bytes_written += ((u64)blkcnt) * info->blksz; total_blocks += chunk_header->chunk_sz; data += chunk_data_sz; break; @@ -222,8 +222,9 @@ int write_sparse_image(struct sparse_storage *info, blk += blks; i += j; } - bytes_written += blkcnt * info->blksz; - total_blocks += chunk_data_sz / sparse_header->blk_sz; + bytes_written += ((u64)blkcnt) * info->blksz; + total_blocks += DIV_ROUND_UP_ULL(chunk_data_sz, + sparse_header->blk_sz); free(fill_buf); break; @@ -253,7 +254,7 @@ int write_sparse_image(struct sparse_storage *info, debug("Wrote %d blocks, expected to write %d blocks\n", total_blocks, sparse_header->total_blks); - printf("........ wrote %u bytes to '%s'\n", bytes_written, part_name); + printf("........ wrote %llu bytes to '%s'\n", bytes_written, part_name); if (total_blocks != sparse_header->total_blks) { info->mssg("sparse image write failure", response); diff --git a/test/dm/test-fdt.c b/test/dm/test-fdt.c index 9b771fdf193..d273e218530 100644 --- a/test/dm/test-fdt.c +++ b/test/dm/test-fdt.c @@ -19,6 +19,7 @@ #include <dm/util.h> #include <dm/lists.h> #include <dm/of_access.h> +#include <linux/ioport.h> #include <test/test.h> #include <test/ut.h> @@ -1165,3 +1166,35 @@ static int dm_test_decode_display_timing(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_decode_display_timing, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); + +/* Test read_resourcee() */ +static int dm_test_read_resource(struct unit_test_state *uts) +{ + struct udevice *dev; + struct resource res; + + /* test resource without translation */ + ut_assertok(uclass_find_device_by_name(UCLASS_SIMPLE_BUS, "syscon@2", &dev)); + ut_assertok(dev_read_resource(dev, 0, &res)); + ut_asserteq(0x40, res.start); + ut_asserteq(0x44, res.end); + ut_assertok(dev_read_resource(dev, 1, &res)); + ut_asserteq(0x48, res.start); + ut_asserteq(0x4d, res.end); + + /* test resource with translation */ + ut_assertok(uclass_find_device_by_name(UCLASS_TEST_DUMMY, "dev@1,100", &dev)); + ut_assertok(dev_read_resource(dev, 0, &res)); + ut_asserteq(0x9000, res.start); + ut_asserteq(0x9fff, res.end); + + /* test named resource */ + ut_assertok(uclass_find_device_by_name(UCLASS_TEST_DUMMY, "dev@0,0", &dev)); + ut_assertok(dev_read_resource_byname(dev, "sandbox-dummy-0", &res)); + ut_asserteq(0x8000, res.start); + ut_asserteq(0x8fff, res.end); + + return 0; +} + +DM_TEST(dm_test_read_resource, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT); |