From fe3eb7a88720fc33d92ed712c56c62cfcdffc0ca Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Fri, 8 Jun 2018 17:58:23 +0300 Subject: [PATCH 1/7] GPIO: CREG: improve flexibility of hsdk-creg-gpio driver CREG GPIO is a driver for weird soc-specific output ports, which are controlled by some fields in memory mapped register. Example: 31 9 7 5 0 < bit number | | | | | [ not used | gpio-1 | gpio-0 | <-shift-> ] < 32 bit register ^ ^ | | write 0x2 == set output to "1" (activate) write 0x3 == set output to "0" (deactivate) As of tooday we only support fixed (hardcoded) bit per gpio line, activate / deactivatei and shift values. Fix that by read them from device tree to be able to use this driver for other boards. Remove "hsdk" prefix from compatible string as this driver can be used with different boards like HSDK, AXS101, AXS103, etc. Signed-off-by: Eugeniy Paltsev Signed-off-by: Alexey Brodkin --- arch/arc/dts/hsdk.dts | 7 ++- drivers/gpio/hsdk-creg-gpio.c | 103 ++++++++++++++++++++++++++-------- 2 files changed, 87 insertions(+), 23 deletions(-) diff --git a/arch/arc/dts/hsdk.dts b/arch/arc/dts/hsdk.dts index 264512877e..e41e4ce84b 100644 --- a/arch/arc/dts/hsdk.dts +++ b/arch/arc/dts/hsdk.dts @@ -101,11 +101,16 @@ }; cs_gpio: gpio@f00014b0 { - compatible = "snps,hsdk-creg-gpio"; + compatible = "snps,creg-gpio"; reg = <0xf00014b0 0x4>; gpio-controller; #gpio-cells = <1>; gpio-bank-name = "hsdk-spi-cs"; gpio-count = <1>; + gpio-first-shift = <0>; + gpio-bit-per-line = <2>; + gpio-activate-val = <2>; + gpio-deactivate-val = <3>; + gpio-default-val = <1>; }; }; diff --git a/drivers/gpio/hsdk-creg-gpio.c b/drivers/gpio/hsdk-creg-gpio.c index 084a2da652..800027f18e 100644 --- a/drivers/gpio/hsdk-creg-gpio.c +++ b/drivers/gpio/hsdk-creg-gpio.c @@ -16,25 +16,24 @@ #include #include -#define HSDK_CREG_MAX_GPIO 8 - -#define GPIO_ACTIVATE 0x2 -#define GPIO_DEACTIVATE 0x3 -#define GPIO_PIN_MASK 0x3 -#define BIT_PER_GPIO 2 +#define DRV_NAME "gpio_creg" struct hsdk_creg_gpio { - uint32_t *regs; + u32 *regs; + u8 shift; + u8 activate; + u8 deactivate; + u8 bit_per_gpio; }; static int hsdk_creg_gpio_set_value(struct udevice *dev, unsigned oft, int val) { struct hsdk_creg_gpio *hcg = dev_get_priv(dev); - uint32_t reg = readl(hcg->regs); - uint32_t cmd = val ? GPIO_DEACTIVATE : GPIO_ACTIVATE; + u8 reg_shift = oft * hcg->bit_per_gpio + hcg->shift; + u32 reg = readl(hcg->regs); - reg &= ~(GPIO_PIN_MASK << (oft * BIT_PER_GPIO)); - reg |= (cmd << (oft * BIT_PER_GPIO)); + reg &= ~(GENMASK(hcg->bit_per_gpio - 1, 0) << reg_shift); + reg |= ((val ? hcg->deactivate : hcg->activate) << reg_shift); writel(reg, hcg->regs); @@ -51,7 +50,9 @@ static int hsdk_creg_gpio_direction_output(struct udevice *dev, unsigned oft, static int hsdk_creg_gpio_direction_input(struct udevice *dev, unsigned oft) { - pr_err("hsdk-creg-gpio can't be used as input!\n"); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + pr_err("%s can't be used as input!\n", uc_priv->bank_name); return -ENOTSUPP; } @@ -59,10 +60,11 @@ static int hsdk_creg_gpio_direction_input(struct udevice *dev, unsigned oft) static int hsdk_creg_gpio_get_value(struct udevice *dev, unsigned int oft) { struct hsdk_creg_gpio *hcg = dev_get_priv(dev); - uint32_t val = readl(hcg->regs); + u32 val = readl(hcg->regs); - val = (val >> (oft * BIT_PER_GPIO)) & GPIO_PIN_MASK; - return (val == GPIO_DEACTIVATE) ? 1 : 0; + val >>= oft * hcg->bit_per_gpio + hcg->shift; + val &= GENMASK(hcg->bit_per_gpio - 1, 0); + return (val == hcg->deactivate) ? 1 : 0; } static const struct dm_gpio_ops hsdk_creg_gpio_ops = { @@ -76,17 +78,74 @@ static int hsdk_creg_gpio_probe(struct udevice *dev) { struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct hsdk_creg_gpio *hcg = dev_get_priv(dev); + u32 shift, bit_per_gpio, activate, deactivate, gpio_count; + const u8 *defaults; - hcg->regs = (uint32_t *)devfdt_get_addr_ptr(dev); - - uc_priv->gpio_count = dev_read_u32_default(dev, "gpio-count", 1); - if (uc_priv->gpio_count > HSDK_CREG_MAX_GPIO) - uc_priv->gpio_count = HSDK_CREG_MAX_GPIO; + hcg->regs = (u32 *)devfdt_get_addr_ptr(dev); + gpio_count = dev_read_u32_default(dev, "gpio-count", 1); + shift = dev_read_u32_default(dev, "gpio-first-shift", 0); + bit_per_gpio = dev_read_u32_default(dev, "gpio-bit-per-line", 1); + activate = dev_read_u32_default(dev, "gpio-activate-val", 1); + deactivate = dev_read_u32_default(dev, "gpio-deactivate-val", 0); + defaults = dev_read_u8_array_ptr(dev, "gpio-default-val", gpio_count); uc_priv->bank_name = dev_read_string(dev, "gpio-bank-name"); if (!uc_priv->bank_name) uc_priv->bank_name = dev_read_name(dev); + if (!bit_per_gpio) { + pr_err("%s: 'gpio-bit-per-line' can't be 0\n", + uc_priv->bank_name); + + return -EINVAL; + } + + if (!gpio_count) { + pr_err("%s: 'gpio-count' can't be 0\n", + uc_priv->bank_name); + + return -EINVAL; + } + + if ((gpio_count * bit_per_gpio + shift) > 32) { + pr_err("%s: u32 io register overflow: try to use %u bits\n", + uc_priv->bank_name, gpio_count * bit_per_gpio + shift); + + return -EINVAL; + } + + if (GENMASK(31, bit_per_gpio) & activate) { + pr_err("%s: 'gpio-activate-val' can't be more than %lu\n", + uc_priv->bank_name, GENMASK(bit_per_gpio - 1, 0)); + + return -EINVAL; + } + + if (GENMASK(31, bit_per_gpio) & deactivate) { + pr_err("%s: 'gpio-deactivate-val' can't be more than %lu\n", + uc_priv->bank_name, GENMASK(bit_per_gpio - 1, 0)); + + return -EINVAL; + } + + if (activate == deactivate) { + pr_err("%s: 'gpio-deactivate-val' and 'gpio-activate-val' can't be equal\n", + uc_priv->bank_name); + + return -EINVAL; + } + + hcg->shift = (u8)shift; + hcg->bit_per_gpio = (u8)bit_per_gpio; + hcg->activate = (u8)activate; + hcg->deactivate = (u8)deactivate; + uc_priv->gpio_count = gpio_count; + + /* Setup default GPIO value if we have "gpio-default-val" array */ + if (defaults) + for (u8 i = 0; i < gpio_count; i++) + hsdk_creg_gpio_set_value(dev, i, defaults[i]); + pr_debug("%s GPIO [0x%p] controller with %d gpios probed\n", uc_priv->bank_name, hcg->regs, uc_priv->gpio_count); @@ -94,12 +153,12 @@ static int hsdk_creg_gpio_probe(struct udevice *dev) } static const struct udevice_id hsdk_creg_gpio_ids[] = { - { .compatible = "snps,hsdk-creg-gpio" }, + { .compatible = "snps,creg-gpio" }, { } }; U_BOOT_DRIVER(gpio_hsdk_creg) = { - .name = "gpio_hsdk_creg", + .name = DRV_NAME, .id = UCLASS_GPIO, .ops = &hsdk_creg_gpio_ops, .probe = hsdk_creg_gpio_probe, From 7620ec4df65d6d2148e7476fbaff6619556acb13 Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Fri, 8 Jun 2018 17:58:24 +0300 Subject: [PATCH 2/7] CREG GPIO: add device tree bindings Signed-off-by: Eugeniy Paltsev Signed-off-by: Alexey Brodkin --- MAINTAINERS | 1 + .../gpio/snps,creg-gpio.txt | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 doc/device-tree-bindings/gpio/snps,creg-gpio.txt diff --git a/MAINTAINERS b/MAINTAINERS index fe8423530c..1bd583c975 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -74,6 +74,7 @@ ARC HSDK CREG GPIO M: Eugeniy Paltsev S: Maintained L: uboot-snps-arc@synopsys.com +F: doc/device-tree-bindings/gpio/snps,creg-gpio.txt F: drivers/gpio/hsdk-creg-gpio.c ARM diff --git a/doc/device-tree-bindings/gpio/snps,creg-gpio.txt b/doc/device-tree-bindings/gpio/snps,creg-gpio.txt new file mode 100644 index 0000000000..46ceb65c53 --- /dev/null +++ b/doc/device-tree-bindings/gpio/snps,creg-gpio.txt @@ -0,0 +1,43 @@ +GPIO via CREG (control registers) driver + +31 9 7 5 0 < bit number +| | | | | +[ not used | gpio-1 | gpio-0 | <-shift-> ] < 32 bit register + ^ ^ + | | + write 0x2 == set output to "1" (activate) + write 0x3 == set output to "0" (deactivate) + +Required properties: +- compatible : "snps,creg-gpio" +- reg : Exactly one register range with length 0x4. +- #gpio-cells : Should be one - the pin number. +- gpio-controller : Marks the device node as a GPIO controller. +- gpio-count: Number of GPIO pins. +- gpio-bit-per-line: Number of bits per gpio line (see picture). +- gpio-first-shift: Shift (in bits) of the first GPIO field in register + (see picture). +- gpio-activate-val: Value should be set in corresponding field to set + output to "1" (see picture). Applied to all GPIO ports. +- gpio-deactivate-val: Value should be set in corresponding field to set + output to "0" (see picture). Applied to all GPIO ports. + +Optional properties: +- gpio-bank-name: name of bank (as default driver name is used is used) +- gpio-default-val: array of default output values (must me 0 or 1) + +Example (see picture): + +gpio: gpio@f00014b0 { + compatible = "snps,creg-gpio"; + reg = <0xf00014b0 0x4>; + gpio-controller; + #gpio-cells = <1>; + gpio-bank-name = "hsdk-spi-cs"; + gpio-count = <2>; + gpio-first-shift = <5>; + gpio-bit-per-line = <2>; + gpio-activate-val = <2>; + gpio-deactivate-val = <3>; + gpio-default-val = <1 1>; +}; From cdfe6913c113ced9a0aa0a7dc48d037046c980e3 Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Fri, 8 Jun 2018 18:52:14 +0300 Subject: [PATCH 3/7] AXS10x: add spi flash support AXS10x boards have n25q512 spi flash IC, so add corresponding nodes to device tree and enaple corresponding options in defconfig. Signed-off-by: Eugeniy Paltsev Signed-off-by: Alexey Brodkin --- arch/arc/dts/axs10x_mb.dtsi | 34 ++++++++++++++++++++++++++++++++++ configs/axs101_defconfig | 12 ++++++++++++ configs/axs103_defconfig | 12 ++++++++++++ 3 files changed, 58 insertions(+) diff --git a/arch/arc/dts/axs10x_mb.dtsi b/arch/arc/dts/axs10x_mb.dtsi index 3855a34dc2..dfc03810ca 100644 --- a/arch/arc/dts/axs10x_mb.dtsi +++ b/arch/arc/dts/axs10x_mb.dtsi @@ -4,6 +4,10 @@ */ / { + aliases { + spi0 = &spi0; + }; + axs10x_mb@e0000000 { compatible = "simple-bus"; #address-cells = <1>; @@ -56,5 +60,35 @@ reg-shift = <2>; reg-io-width = <4>; }; + + spi0: spi@0 { + compatible = "snps,dw-apb-ssi"; + reg = <0x0 0x100>; + #address-cells = <1>; + #size-cells = <0>; + spi-max-frequency = <4000000>; + clocks = <&apbclk>; + clock-names = "spi_clk"; + cs-gpio = <&cs_gpio 0>; + spi_flash@0 { + compatible = "spi-flash"; + reg = <0>; + spi-max-frequency = <4000000>; + }; + }; + + cs_gpio: gpio@11218 { + compatible = "snps,creg-gpio"; + reg = <0x11218 0x4>; + gpio-controller; + #gpio-cells = <1>; + gpio-bank-name = "axs-spi-cs"; + gpio-count = <1>; + gpio-first-shift = <0>; + gpio-bit-per-line = <2>; + gpio-activate-val = <1>; + gpio-deactivate-val = <3>; + gpio-default-val = <1>; + }; }; }; diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig index d056719e14..a981398cb5 100644 --- a/configs/axs101_defconfig +++ b/configs/axs101_defconfig @@ -15,6 +15,8 @@ CONFIG_SYS_PROMPT="AXS# " # CONFIG_CMD_FLASH is not set CONFIG_CMD_MMC=y CONFIG_CMD_NAND=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y CONFIG_CMD_USB=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_DHCP=y @@ -30,8 +32,15 @@ CONFIG_ENV_FAT_INTERFACE="mmc" CONFIG_ENV_FAT_DEVICE_AND_PART="0:1" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_HSDK_CREG_GPIO=y CONFIG_MMC=y CONFIG_MMC_DW=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_MTD=y CONFIG_DM_ETH=y CONFIG_PHY_GIGE=y CONFIG_ETH_DESIGNWARE=y @@ -39,6 +48,9 @@ CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART_SHIFT=2 CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_DESIGNWARE_SPI=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_EHCI_HCD=y diff --git a/configs/axs103_defconfig b/configs/axs103_defconfig index f0fccf4d9f..e524e6a9c6 100644 --- a/configs/axs103_defconfig +++ b/configs/axs103_defconfig @@ -15,6 +15,8 @@ CONFIG_SYS_PROMPT="AXS# " # CONFIG_CMD_FLASH is not set CONFIG_CMD_MMC=y CONFIG_CMD_NAND=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y CONFIG_CMD_USB=y # CONFIG_CMD_SETEXPR is not set CONFIG_CMD_DHCP=y @@ -30,8 +32,15 @@ CONFIG_ENV_FAT_INTERFACE="mmc" CONFIG_ENV_FAT_DEVICE_AND_PART="0:1" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_DM=y +CONFIG_DM_GPIO=y +CONFIG_HSDK_CREG_GPIO=y CONFIG_MMC=y CONFIG_MMC_DW=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_MTD=y CONFIG_DM_ETH=y CONFIG_PHY_GIGE=y CONFIG_ETH_DESIGNWARE=y @@ -39,6 +48,9 @@ CONFIG_DM_SERIAL=y CONFIG_DEBUG_UART_SHIFT=2 CONFIG_DEBUG_UART_ANNOUNCE=y CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_DESIGNWARE_SPI=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_OHCI_HCD=y From 817cd83435eca9161dd8ad49537b65b84caaaf2d Mon Sep 17 00:00:00 2001 From: Eugeniy Paltsev Date: Wed, 27 Jun 2018 15:20:48 +0300 Subject: [PATCH 4/7] ARC: AXS10x: add tool and make target to generate bsp AXS10x boards have preloader that reads SPI flash pages and searches special image header to fetch and load binary. Add tool, make target (bsp-generate) to generate update script and u-boot binary image with header for preloader. Also add script to default environment to apply updates. Signed-off-by: Eugeniy Paltsev Signed-off-by: Alexey Brodkin --- board/synopsys/axs10x/config.mk | 23 ++++ board/synopsys/axs10x/headerize-axs.py | 176 +++++++++++++++++++++++++ include/configs/axs10x.h | 7 + 3 files changed, 206 insertions(+) create mode 100644 board/synopsys/axs10x/config.mk create mode 100644 board/synopsys/axs10x/headerize-axs.py diff --git a/board/synopsys/axs10x/config.mk b/board/synopsys/axs10x/config.mk new file mode 100644 index 0000000000..db04b986d1 --- /dev/null +++ b/board/synopsys/axs10x/config.mk @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2018 Synopsys, Inc. All rights reserved. + +bsp-generate: u-boot u-boot.bin +ifdef CONFIG_ISA_ARCV2 + $(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-axs.py \ + --header-type v2 \ + --arc-id 0x53 \ + --spi-flash-offset 0x200000 \ + --image $(srctree)/u-boot.bin \ + --elf $(srctree)/u-boot +else + $(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-axs.py \ + --header-type v1 \ + --arc-id 0x434 \ + --spi-flash-offset 0x0 \ + --image $(srctree)/u-boot.bin \ + --elf $(srctree)/u-boot +endif + $(Q)mkimage -T script -C none -n 'uboot update script' \ + -d $(srctree)/u-boot-update.txt \ + $(srctree)/u-boot-update.img &> /dev/null diff --git a/board/synopsys/axs10x/headerize-axs.py b/board/synopsys/axs10x/headerize-axs.py new file mode 100644 index 0000000000..fa6aaf350c --- /dev/null +++ b/board/synopsys/axs10x/headerize-axs.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python3 + +#we can use binascii instead of zlib +import os, getopt, sys, zlib +from elftools.elf.elffile import ELFFile + + +def usage(exit_code): + print("typical usage:") + print("AXS101:") + print(sys.argv[0] + \ + " --header-type v1 --arc-id 0x434 --spi-flash-offset 0x0 --image u-boot.bin --elf u-boot") + print("AXS103:") + print(sys.argv[0] + \ + " --header-type v2 --arc-id 0x53 --spi-flash-offset 0x200000 --image u-boot.bin --elf u-boot") + sys.exit(exit_code) + + +def elf_get_entry(filename): + with open(filename, 'rb') as f: + elffile = ELFFile(f) + return elffile.header['e_entry'] + + +def calc_check_sum(filename): + # Calculate u-boot image check_sum: it is sum of all u-boot binary bytes + with open(filename, "rb") as file: + ba = bytearray(file.read()) + return sum(ba) & 0xFF + + +def arg_verify(uboot_bin_filename, uboot_elf_filename, header_type): + if not os.path.isfile(uboot_bin_filename): + print("uboot bin file not exists: " + uboot_bin_filename) + sys.exit(2) + + if not os.path.isfile(uboot_elf_filename): + print("uboot elf file not exists: " + uboot_elf_filename) + sys.exit(2) + + if header_type not in ("v1", "v2"): + print("unknown header type: " + header_type) + print("choose between 'v1' (most likely AXS101) and 'v2' (most likely AXS103)") + sys.exit(2) + + +def main(): + try: + opts, args = getopt.getopt(sys.argv[1:], + "ht:a:s:i:l:e:", + ["help", "header-type=", "arc-id=", "spi-flash-offset=", "image=", "elf="]) + except getopt.GetoptError as err: + print(err) + usage(2) + + # default filenames + uboot_elf_filename = "u-boot" + uboot_bin_filename = "u-boot.bin" + headerised_filename = "u-boot.head" + uboot_scrypt_file = "u-boot-update.txt" + + # default values + spi_flash_offset = 0x200000 + header_type = "v2" + arc_id = 0x53 + + # initial header values: place where preloader will store u-boot binary, + # should be equal to CONFIG_SYS_TEXT_BASE + image_copy_adr = 0x81000000 + + # initial constant header values, do not change these values + magic1 = 0xdeadbeafaf # big endian byte order + magic2 = [ # big endian byte order + 0x20202a2020202020202020202a20202020207c5c2e20202020202e2f7c20202020207c2d, + 0x2e5c2020202f2e2d7c20202020205c2020602d2d2d6020202f20202020202f205f202020, + 0x205f20205c20202020207c205f60712070205f207c2020202020272e5f3d2f205c3d5f2e, + 0x272020202020202020605c202f60202020202020202020202020206f2020202020202020] + + for opt, arg in opts: + if opt in ('-h', "--help"): usage(0) + if opt in ('-t', "--header-type"): header_type = arg + if opt in ('-a', "--arc-id"): arc_id = int(arg, 16) + if opt in ('-s', "--spi-flash-offset"): spi_flash_offset = int(arg, 16) + if opt in ('-i', "--image"): uboot_bin_filename = arg + if opt in ('-e', "--elf"): uboot_elf_filename = arg + + arg_verify(uboot_bin_filename, uboot_elf_filename, header_type) + + uboot_img_size = os.path.getsize(uboot_bin_filename) + jump_address = elf_get_entry(uboot_elf_filename) + check_sum = calc_check_sum(uboot_bin_filename) + + # Calculate header adresses depend on header type + if header_type == "v2": + image_copy_adr -= 0x4 + uboot_img_size += 0x4 + # we append image so we need to append checksum + jmpchk_sum = sum(jump_address.to_bytes(4, byteorder='big')) + check_sum = (check_sum + jmpchk_sum) & 0xFF + imade_jump_append = True + else: + imade_jump_append = False + + # write header to file + with open(headerised_filename, "wb") as file: + file.write(arc_id.to_bytes(2, byteorder='little')) + file.write(uboot_img_size.to_bytes(4, byteorder='little')) + file.write(check_sum.to_bytes(1, byteorder='little')) + file.write(image_copy_adr.to_bytes(4, byteorder='little')) + file.write(magic1.to_bytes(5, byteorder='big')) + for i in range(16): file.write(0x00.to_bytes(1, byteorder='little')) + for byte in magic2: file.write(byte.to_bytes(36, byteorder='big')) + for i in range(224 - len(magic2) * 36): + file.write(0x00.to_bytes(1, byteorder='little')) + if imade_jump_append: + file.write(jump_address.to_bytes(4, byteorder='little')) + + # append u-boot image to header + with open(headerised_filename, "ab") as fo: + with open(uboot_bin_filename,'rb') as fi: + fo.write(fi.read()) + + # calc u-boot headerised image CRC32 (will be used by uboot update + # command for check) + headerised_image_crc = "" + with open(headerised_filename, "rb") as fi: + headerised_image_crc = hex(zlib.crc32(fi.read()) & 0xffffffff) + + load_addr = 0x81000000 + crc_store_adr = load_addr - 0x8 + crc_calc_adr = crc_store_adr - 0x4 + load_size = os.path.getsize(headerised_filename) + crc_calc_cmd = \ + "crc32 " + hex(load_addr) + " " + hex(load_size) + " " + hex(crc_calc_adr) + crc_check_cmd = \ + "mw.l " + hex(crc_store_adr) + " " + headerised_image_crc + " && " + \ + crc_calc_cmd + " && " + \ + "cmp.l " + hex(crc_store_adr) + " " + hex(crc_calc_adr) + " 1" + + # make errase size to be allighned by 64K + if load_size & 0xFFFF == 0: + errase_size = load_size + else: + errase_size = load_size - (load_size & 0xFFFF) + 0x10000 + + # Hack to handle n25*** flash protect ops weirdness: + # protect unlock return fail status is region is already unlock (entire or + # partially). Same for lock ops. + # As there is no possibility to check current flash status pretend + # unlock & lock always success. + sf_unlock_cmd = \ + "if sf protect unlock 0x0 0x4000000 ; then true ; else true ; fi" + sf_lock_cmd = \ + "if sf protect lock 0x0 0x4000000 ; then true ; else true ; fi" + + # u-bood CMD to load u-bood with header to SPI flash + sf_load_image_cmd = \ + "fatload mmc 0:1 " + hex(load_addr) + " " + headerised_filename + " && " + \ + "sf probe 0:0 && " + \ + sf_unlock_cmd + " && " + \ + "sf erase " + hex(spi_flash_offset) + " " + hex(errase_size) + " && " + \ + "sf write " + hex(load_addr) + " " + hex(spi_flash_offset) + " " + hex(load_size) + " && " + \ + sf_lock_cmd + + update_uboot_cmd = sf_load_image_cmd + " && echo \"u-boot update: OK\"" + + with open(uboot_scrypt_file, "wb") as fo: + fo.write(update_uboot_cmd.encode('ascii')) + + +if __name__ == "__main__": + try: + main() + except Exception as err: + print(err) + sys.exit(2) diff --git a/include/configs/axs10x.h b/include/configs/axs10x.h index f044158265..f78e1573b6 100644 --- a/include/configs/axs10x.h +++ b/include/configs/axs10x.h @@ -65,6 +65,13 @@ * Environment settings */ #define CONFIG_ENV_SIZE SZ_16K +#define CONFIG_EXTRA_ENV_SETTINGS \ + "upgrade=if mmc rescan && " \ + "fatload mmc 0:1 ${loadaddr} u-boot-update.img && " \ + "iminfo ${loadaddr} && source ${loadaddr}; then; else echo " \ + "\"Fail to upgrade.\n" \ + "Do you have u-boot-update.img and u-boot.head on first (FAT) SD card partition?\"" \ + "; fi\0" /* * Environment configuration From 0552e104a53c32a3720a841481d4a69646048eb6 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 11 Jul 2018 18:24:44 +0300 Subject: [PATCH 5/7] ARC: AXS10x/HSDK: Use our own version of mkimage Since U-Boot tools are being built anyways it's much nicer to use them instead of relying on some of them bein installed on build host (which might easily not be the case). Signed-off-by: Alexey Brodkin --- board/synopsys/axs10x/config.mk | 2 +- board/synopsys/hsdk/config.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/board/synopsys/axs10x/config.mk b/board/synopsys/axs10x/config.mk index db04b986d1..81ff498f81 100644 --- a/board/synopsys/axs10x/config.mk +++ b/board/synopsys/axs10x/config.mk @@ -18,6 +18,6 @@ else --image $(srctree)/u-boot.bin \ --elf $(srctree)/u-boot endif - $(Q)mkimage -T script -C none -n 'uboot update script' \ + $(Q)tools/mkimage -T script -C none -n 'uboot update script' \ -d $(srctree)/u-boot-update.txt \ $(srctree)/u-boot-update.img &> /dev/null diff --git a/board/synopsys/hsdk/config.mk b/board/synopsys/hsdk/config.mk index 16fb59c438..9e280f921a 100644 --- a/board/synopsys/hsdk/config.mk +++ b/board/synopsys/hsdk/config.mk @@ -6,6 +6,6 @@ bsp-generate: u-boot u-boot.bin $(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-hsdk.py \ --arc-id 0x52 --image $(srctree)/u-boot.bin \ --elf $(srctree)/u-boot - $(Q)mkimage -T script -C none -n 'uboot update script' \ + $(Q)tools/mkimage -T script -C none -n 'uboot update script' \ -d $(srctree)/u-boot-update.txt \ $(srctree)/u-boot-update.scr &> /dev/null From 164abd1775a97ae271d5499f69abf1e06754952c Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 11 Jul 2018 18:54:48 +0300 Subject: [PATCH 6/7] HSDK: Fixes and improvements in README 1. Explained prerequisites for "make bsp-generate" command. 2. Cleaned-up duplicates Signed-off-by: Alexey Brodkin --- board/synopsys/hsdk/README | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/board/synopsys/hsdk/README b/board/synopsys/hsdk/README index e3793e4829..e29a6a1727 100644 --- a/board/synopsys/hsdk/README +++ b/board/synopsys/hsdk/README @@ -82,6 +82,12 @@ Useful notes on bulding and using of U-Boot on ARC HS Development Kit (AKA HSDK) be put on the first FAT partition of micro SD-card to be inserted in the HSDK board. + Note that Python3 script is used for generation of a header, thus + to get that done it's required to have Python3 with elftools installed. + On CentOS/RHEL/Fedora this could be installed with: + ------------------------->8---------------------- + sudo dnf install python3-pyelftools + ------------------------->8---------------------- EXECUTING U-BOOT @@ -104,8 +110,8 @@ Useful notes on bulding and using of U-Boot on ARC HS Development Kit (AKA HSDK) 1. Create `u-boot.head` and `u-boot-update.scr` as discribed above with `make bsp-generate` command. - 2. Copy `u-boot.head` and `u-boot-update.scr` to the first the first FAT - partition of micro SD-card. + 2. Copy `u-boot.head` and `u-boot-update.scr` to the first FAT partition + of micro SD-card. 3. Connect USB cable from the HSDK board to the developemnt host and fire-up serial terminal. From 8f590063ba635264303b1713c421df331743fd46 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Sun, 29 Jul 2018 09:47:52 +0300 Subject: [PATCH 7/7] ARC: Enable unaligned access in hardware if compiler uses it Even if ARC core might handle unaligned access to data this hardware feature by default is disabled. But GCC starting from 8.1.0 unconditionally uses it for ARC HS cores. Which leads to quite strange and fatal run-time failures like the one below if HW is not configured properly: | hsdk# sf probe | Misaligned data access exception @ 0xbff794d4 | ECR: 0x000d0000 | RET: 0xbff794d4 | BLINK: 0xbff79644 | STAT32: 0x00000800 | GP: 0x1003e000 r25: 0xbfd58f08 | BTA: 0xbff794a4 SP: 0xbfd58cd4 FP: 0xbfd58ef0 | LPS: 0xbff90240 LPE: 0xbff90244 LPC: 0x00000000 | r00: 0x00000000 r01: 0x00000003 r02: 0x000026bf | r03: 0x00000000 r04: 0x00000100 r05: 0x00000000 | r06: 0x00000001 r07: 0x00000000 r08: 0x1dcd6500 | r09: 0x00000000 r10: 0x00200000 r11: 0x00000000 | r12: 0x1b3d4440 r13: 0xbff9eca4 r14: 0xbfd59d68 | r15: 0xbfd60cd0 r16: 0x00000000 r17: 0x00000000 | r18: 0xbff9ed14 r19: 0xbfd59c78 r20: 0xbfd58d40 | r21: 0xbfd58d44 r22: 0x00000000 r23: 0x00000000 | r24: 0xbfd59ba8 | Resetting CPU ... Now we're checking for __ARC_UNALIGNED__ define emitted by the compiler if it's going to use unaligned access and then we force-enable it in hardware too. Signed-off-by: Alexey Brodkin --- arch/arc/include/asm/arcregs.h | 3 +++ arch/arc/lib/start.S | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 56ec11f789..9920d2e719 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -19,6 +19,9 @@ #define ARC_AUX_IDENTITY 0x04 #define ARC_AUX_STATUS32 0x0a +/* STATUS32 Bits Positions */ +#define STATUS_AD_BIT 19 /* Enable unaligned access */ + /* Instruction cache related auxiliary registers */ #define ARC_AUX_IC_IVIC 0x10 #define ARC_AUX_IC_CTRL 0x11 diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index e573ce7718..84959b41bd 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -61,6 +61,15 @@ ENTRY(_start) 1: #endif +#ifdef __ARC_UNALIGNED__ + /* + * Enable handling of unaligned access in the CPU as by default + * this HW feature is disabled while GCC starting from 8.1.0 + * unconditionally uses it for ARC HS cores. + */ + flag 1 << STATUS_AD_BIT +#endif + /* Establish C runtime stack and frame */ mov %sp, CONFIG_SYS_INIT_SP_ADDR mov %fp, %sp