summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/dts/da850-lcdk-u-boot.dtsi13
-rw-r--r--arch/arm/dts/da850-lcdk.dts339
-rw-r--r--arch/arm/dts/da850.dtsi15
-rw-r--r--arch/arm/mach-davinci/Kconfig1
-rw-r--r--cmd/sf.c2
-rw-r--r--configs/am335x_evm_defconfig1
-rw-r--r--configs/am335x_hs_evm_defconfig1
-rw-r--r--configs/omapl138_lcdk_defconfig9
-rw-r--r--drivers/gpio/omap_gpio.c1
-rw-r--r--drivers/mtd/spi/spi_flash.c2
-rw-r--r--include/configs/omapl138_lcdk.h15
-rwxr-xr-xscripts/check-config.sh3
-rw-r--r--test/py/README.md6
-rw-r--r--test/py/tests/test_sf.py218
-rw-r--r--test/py/u_boot_utils.py24
-rw-r--r--tools/Makefile1
16 files changed, 637 insertions, 14 deletions
diff --git a/arch/arm/dts/da850-lcdk-u-boot.dtsi b/arch/arm/dts/da850-lcdk-u-boot.dtsi
new file mode 100644
index 0000000000..c67c3ddbf7
--- /dev/null
+++ b/arch/arm/dts/da850-lcdk-u-boot.dtsi
@@ -0,0 +1,13 @@
+/*
+ * da850-lcdk U-Boot Additions
+ *
+ * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/ {
+ aliases {
+ i2c0 = &i2c0;
+ };
+};
diff --git a/arch/arm/dts/da850-lcdk.dts b/arch/arm/dts/da850-lcdk.dts
new file mode 100644
index 0000000000..a1f4d6d5a5
--- /dev/null
+++ b/arch/arm/dts/da850-lcdk.dts
@@ -0,0 +1,339 @@
+/*
+ * Copyright (c) 2016 BayLibre, Inc.
+ *
+ * Licensed under GPLv2.
+ */
+/dts-v1/;
+#include "da850.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+ model = "DA850/AM1808/OMAP-L138 LCDK";
+ compatible = "ti,da850-lcdk", "ti,da850";
+
+ aliases {
+ serial2 = &serial2;
+ ethernet0 = &eth0;
+ };
+
+ chosen {
+ stdout-path = "serial2:115200n8";
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0xc0000000 0x08000000>;
+ };
+
+ reserved-memory {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ dsp_memory_region: dsp-memory@c3000000 {
+ compatible = "shared-dma-pool";
+ reg = <0xc3000000 0x1000000>;
+ reusable;
+ status = "okay";
+ };
+ };
+
+ sound {
+ compatible = "simple-audio-card";
+ simple-audio-card,name = "DA850/OMAP-L138 LCDK";
+ simple-audio-card,widgets =
+ "Line", "Line In",
+ "Line", "Line Out";
+ simple-audio-card,routing =
+ "LINE1L", "Line In",
+ "LINE1R", "Line In",
+ "Line Out", "LLOUT",
+ "Line Out", "RLOUT";
+ simple-audio-card,format = "dsp_b";
+ simple-audio-card,bitclock-master = <&link0_codec>;
+ simple-audio-card,frame-master = <&link0_codec>;
+ simple-audio-card,bitclock-inversion;
+
+ simple-audio-card,cpu {
+ sound-dai = <&mcasp0>;
+ system-clock-frequency = <24576000>;
+ };
+
+ link0_codec: simple-audio-card,codec {
+ sound-dai = <&tlv320aic3106>;
+ system-clock-frequency = <24576000>;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ autorepeat;
+
+ user1 {
+ label = "GPIO Key USER1";
+ linux,code = <BTN_0>;
+ gpios = <&gpio 36 GPIO_ACTIVE_LOW>;
+ };
+
+ user2 {
+ label = "GPIO Key USER2";
+ linux,code = <BTN_1>;
+ gpios = <&gpio 37 GPIO_ACTIVE_LOW>;
+ };
+ };
+
+ vga-bridge {
+ compatible = "ti,ths8135";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+
+ vga_bridge_in: endpoint {
+ remote-endpoint = <&lcdc_out_vga>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+
+ vga_bridge_out: endpoint {
+ remote-endpoint = <&vga_con_in>;
+ };
+ };
+ };
+ };
+
+ vga {
+ compatible = "vga-connector";
+
+ ddc-i2c-bus = <&i2c0>;
+
+ port {
+ vga_con_in: endpoint {
+ remote-endpoint = <&vga_bridge_out>;
+ };
+ };
+ };
+};
+
+&pmx_core {
+ status = "okay";
+
+ mcasp0_pins: pinmux_mcasp0_pins {
+ pinctrl-single,bits = <
+ /* AHCLKX AFSX ACLKX */
+ 0x00 0x00101010 0x00f0f0f0
+ /* ARX13 ARX14 */
+ 0x04 0x00000110 0x00000ff0
+ >;
+ };
+
+ nand_pins: nand_pins {
+ pinctrl-single,bits = <
+ /* EMA_WAIT[0], EMA_OE, EMA_WE, EMA_CS[3] */
+ 0x1c 0x10110010 0xf0ff00f0
+ /*
+ * EMA_D[0], EMA_D[1], EMA_D[2],
+ * EMA_D[3], EMA_D[4], EMA_D[5],
+ * EMA_D[6], EMA_D[7]
+ */
+ 0x24 0x11111111 0xffffffff
+ /*
+ * EMA_D[8], EMA_D[9], EMA_D[10],
+ * EMA_D[11], EMA_D[12], EMA_D[13],
+ * EMA_D[14], EMA_D[15]
+ */
+ 0x20 0x11111111 0xffffffff
+ /* EMA_A[1], EMA_A[2] */
+ 0x30 0x01100000 0x0ff00000
+ >;
+ };
+};
+
+&serial2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&serial2_rxtx_pins>;
+ status = "okay";
+};
+
+&wdt {
+ status = "okay";
+};
+
+&rtc0 {
+ status = "okay";
+};
+
+&gpio {
+ status = "okay";
+};
+
+&sata {
+ status = "okay";
+};
+
+&mdio {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mdio_pins>;
+ bus_freq = <2200000>;
+ status = "okay";
+};
+
+&eth0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mii_pins>;
+ status = "okay";
+};
+
+&mmc0 {
+ max-frequency = <50000000>;
+ bus-width = <4>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mmc0_pins>;
+ cd-gpios = <&gpio 64 GPIO_ACTIVE_LOW>;
+ status = "okay";
+};
+
+&i2c0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&i2c0_pins>;
+ clock-frequency = <100000>;
+ status = "okay";
+
+ tlv320aic3106: tlv320aic3106@18 {
+ #sound-dai-cells = <0>;
+ compatible = "ti,tlv320aic3106";
+ reg = <0x18>;
+ status = "okay";
+ };
+};
+
+&mcasp0 {
+ #sound-dai-cells = <0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcasp0_pins>;
+ status = "okay";
+
+ op-mode = <0>; /* DAVINCI_MCASP_IIS_MODE */
+ tdm-slots = <2>;
+ serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
+ 0 0 0 0
+ 0 0 0 0
+ 0 0 0 0
+ 0 1 2 0
+ >;
+ tx-num-evt = <32>;
+ rx-num-evt = <32>;
+};
+
+&usb_phy {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+};
+
+&aemif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&nand_pins>;
+ status = "okay";
+ cs3 {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ clock-ranges;
+ ranges;
+
+ ti,cs-chipselect = <3>;
+
+ nand@2000000,0 {
+ compatible = "ti,davinci-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0 0x02000000 0x02000000
+ 1 0x00000000 0x00008000>;
+
+ ti,davinci-chipselect = <1>;
+ ti,davinci-mask-ale = <0>;
+ ti,davinci-mask-cle = <0>;
+ ti,davinci-mask-chipsel = <0>;
+
+ ti,davinci-nand-buswidth = <16>;
+ ti,davinci-ecc-mode = "hw";
+ ti,davinci-ecc-bits = <4>;
+ ti,davinci-nand-use-bbt;
+
+ /*
+ * The OMAP-L132/L138 Bootloader doc SPRAB41E reads:
+ * "To boot from NAND Flash, the AIS should be written
+ * to NAND block 1 (NAND block 0 is not used by default)".
+ * The same doc mentions that for ROM "Silicon Revision 2.1",
+ * "Updated NAND boot mode to offer boot from block 0 or block 1".
+ * However the limitaion is left here by default for compatibility
+ * with older silicon and because it needs new boot pin settings
+ * not possible in stock LCDK.
+ */
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "u-boot env";
+ reg = <0 0x020000>;
+ };
+ partition@20000 {
+ /* The LCDK defaults to booting from this partition */
+ label = "u-boot";
+ reg = <0x020000 0x080000>;
+ };
+ partition@a0000 {
+ label = "free space";
+ reg = <0x0a0000 0>;
+ };
+ };
+ };
+ };
+};
+
+&prictrl {
+ status = "okay";
+};
+
+&memctrl {
+ status = "okay";
+};
+
+&lcdc {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&lcd_pins>;
+
+ port {
+ lcdc_out_vga: endpoint {
+ remote-endpoint = <&vga_bridge_in>;
+ };
+ };
+};
+
+&vpif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&vpif_capture_pins>;
+ status = "okay";
+};
+
+&dsp {
+ memory-region = <&dsp_memory_region>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/da850.dtsi b/arch/arm/dts/da850.dtsi
index 02e2f8f258..c66cf78953 100644
--- a/arch/arm/dts/da850.dtsi
+++ b/arch/arm/dts/da850.dtsi
@@ -23,11 +23,18 @@
reg = <0xfffee000 0x2000>;
};
};
-
- aliases {
- spi0 = &spi0;
+ dsp: dsp@11800000 {
+ compatible = "ti,da850-dsp";
+ reg = <0x11800000 0x40000>,
+ <0x11e00000 0x8000>,
+ <0x11f00000 0x8000>,
+ <0x01c14044 0x4>,
+ <0x01c14174 0x8>;
+ reg-names = "l2sram", "l1pram", "l1dram", "host1cfg", "chipsig";
+ interrupt-parent = <&intc>;
+ interrupts = <28>;
+ status = "disabled";
};
-
soc@1c00000 {
compatible = "simple-bus";
model = "da850";
diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
index 30752839a3..5e7baba3fe 100644
--- a/arch/arm/mach-davinci/Kconfig
+++ b/arch/arm/mach-davinci/Kconfig
@@ -58,6 +58,7 @@ config SOC_DA850
config SOC_DA8XX
bool
select SYS_DA850_PLL_INIT if SUPPORT_SPL || DA850_LOWLEVEL
+ select SYS_DA850_DDR_INIT if SUPPORT_SPL || DA850_LOWLEVEL
config MACH_DAVINCI_DA850_EVM
bool
diff --git a/cmd/sf.c b/cmd/sf.c
index f971eec781..e7ff9a6462 100644
--- a/cmd/sf.c
+++ b/cmd/sf.c
@@ -287,7 +287,7 @@ static int do_spi_flash_read_write(int argc, char * const argv[])
}
buf = map_physmem(addr, len, MAP_WRBACK);
- if (!buf) {
+ if (!buf && addr) {
puts("Failed to map physical memory\n");
return 1;
}
diff --git a/configs/am335x_evm_defconfig b/configs/am335x_evm_defconfig
index 60120bf163..d1c78fa489 100644
--- a/configs/am335x_evm_defconfig
+++ b/configs/am335x_evm_defconfig
@@ -4,6 +4,7 @@ CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_AM33XX=y
CONFIG_DEFAULT_DEVICE_TREE="am335x-evm"
CONFIG_DISTRO_DEFAULTS=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x1000
CONFIG_SPL_LOAD_FIT=y
CONFIG_BOOTCOMMAND="if test ${boot_fit} -eq 1; then run update_to_fit; fi; run findfdt; run init_console; run envboot; run distro_bootcmd"
CONFIG_SYS_CONSOLE_INFO_QUIET=y
diff --git a/configs/am335x_hs_evm_defconfig b/configs/am335x_hs_evm_defconfig
index c903cc780d..a8ab3e6206 100644
--- a/configs/am335x_hs_evm_defconfig
+++ b/configs/am335x_hs_evm_defconfig
@@ -9,6 +9,7 @@ CONFIG_ISW_ENTRY_ADDR=0x40300350
# CONFIG_SPL_NAND_SUPPORT is not set
CONFIG_DEFAULT_DEVICE_TREE="am335x-evm"
CONFIG_DISTRO_DEFAULTS=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x1000
CONFIG_ANDROID_BOOT_IMAGE=y
CONFIG_FIT_IMAGE_POST_PROCESS=y
CONFIG_SPL_LOAD_FIT=y
diff --git a/configs/omapl138_lcdk_defconfig b/configs/omapl138_lcdk_defconfig
index ccb308bf01..2c1bdb2e29 100644
--- a/configs/omapl138_lcdk_defconfig
+++ b/configs/omapl138_lcdk_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_DAVINCI=y
CONFIG_SYS_TEXT_BASE=0xc1080000
CONFIG_TARGET_OMAPL138_LCDK=y
+CONFIG_SYS_DA850_PLL0_POSTDIV=0
CONFIG_SYS_DA850_PLL1_PLLDIV3=0x8003
CONFIG_TI_COMMON_CMD_OPTIONS=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
@@ -9,11 +10,11 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_NAND_SUPPORT=y
+CONFIG_DEFAULT_DEVICE_TREE="da850-lcdk"
CONFIG_BOOTDELAY=3
CONFIG_LOGLEVEL=3
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL=y
CONFIG_SPL_BOARD_INIT=y
@@ -27,9 +28,13 @@ CONFIG_CMD_NAND=y
# CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_DIAG=y
CONFIG_CMD_UBI=y
+CONFIG_OF_CONTROL=y
CONFIG_ENV_IS_IN_NAND=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_BOOTP_DNS=y
+CONFIG_DM=y
+CONFIG_DM_I2C=y
+CONFIG_DM_I2C_COMPAT=y
CONFIG_NAND=y
CONFIG_SYS_NAND_BUSWIDTH_16BIT=y
CONFIG_SYS_NAND_U_BOOT_LOCATIONS=y
@@ -38,6 +43,6 @@ CONFIG_SPL_NAND_SIMPLE=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
CONFIG_DAVINCI_SPI=y
-CONFIG_OF_LIBFDT=y
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index 7243100219..559f29b801 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -345,6 +345,7 @@ U_BOOT_DRIVER(gpio_omap) = {
.bind = omap_gpio_bind,
.probe = omap_gpio_probe,
.priv_auto_alloc_size = sizeof(struct gpio_bank),
+ .flags = DM_FLAG_PRE_RELOC,
};
#endif /* CONFIG_DM_GPIO */
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 294d9f9d79..2e61685d3e 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -320,7 +320,7 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
erase_size = flash->erase_size;
if (offset % erase_size || len % erase_size) {
- debug("SF: Erase offset/length not multiple of erase size\n");
+ printf("SF: Erase offset/length not multiple of erase size\n");
return -1;
}
diff --git a/include/configs/omapl138_lcdk.h b/include/configs/omapl138_lcdk.h
index 12b266e515..77b89bc7a0 100644
--- a/include/configs/omapl138_lcdk.h
+++ b/include/configs/omapl138_lcdk.h
@@ -20,6 +20,14 @@
#define CONFIG_USE_NAND
/*
+* Disable DM_* for SPL build and can be re-enabled after adding
+* DM support in SPL
+*/
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_DM_I2C
+#undef CONFIG_DM_I2C_COMPAT
+#endif
+/*
* SoC Configuration
*/
#define CONFIG_MACH_OMAPL138_LCDK
@@ -57,7 +65,8 @@
* PLL configuration
*/
-#define CONFIG_SYS_DA850_PLL0_PLLM 37
+/* Requires CONFIG_SYS_DA850_PLL0_POSTDIV=0, set in Kconfig */
+#define CONFIG_SYS_DA850_PLL0_PLLM 18
#define CONFIG_SYS_DA850_PLL1_PLLM 21
/*
@@ -104,11 +113,14 @@
/*
* Serial Driver info
*/
+#define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART2_CLKID)
+#if !defined(CONFIG_DM_SERIAL)
#define CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550_REG_SIZE -4 /* NS16550 register size */
#define CONFIG_SYS_NS16550_COM1 DAVINCI_UART2_BASE /* Base address of UART2 */
#define CONFIG_SYS_NS16550_CLK clk_get(DAVINCI_UART2_CLKID)
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+#endif
#define CONFIG_SPI
#define CONFIG_SYS_SPI_BASE DAVINCI_SPI1_BASE
@@ -125,7 +137,6 @@
/*
* I2C Configuration
*/
-#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_DAVINCI
#define CONFIG_SYS_DAVINCI_I2C_SPEED 25000
#define CONFIG_SYS_DAVINCI_I2C_SLAVE 10 /* Bogus, master-only in U-Boot */
diff --git a/scripts/check-config.sh b/scripts/check-config.sh
index 267758498b..4848ca6e25 100755
--- a/scripts/check-config.sh
+++ b/scripts/check-config.sh
@@ -14,6 +14,9 @@
# For example:
# scripts/check-config.sh b/chromebook_link/u-boot.cfg kconfig_whitelist.txt .
+set -e
+set -u
+
path="$1"
whitelist="$2"
srctree="$3"
diff --git a/test/py/README.md b/test/py/README.md
index eefac37756..aed2fd063a 100644
--- a/test/py/README.md
+++ b/test/py/README.md
@@ -150,7 +150,7 @@ processing.
option takes a single argument which is used to filter test names. Simple
logical operators are supported. For example:
- `'ums'` runs only tests with "ums" in their name.
- - ``ut_dm'` runs only tests with "ut_dm" in their name. Note that in this
+ - `'ut_dm'` runs only tests with "ut_dm" in their name. Note that in this
case, "ut_dm" is a parameter to a test rather than the test name. The full
test name is e.g. "test_ut[ut_dm_leak]".
- `'not reset'` runs everything except tests with "reset" in their name.
@@ -320,7 +320,7 @@ If U-Boot has already been built:
```bash
PATH=$HOME/ubtest/bin:$PATH \
- PYTHONPATH=${HOME}/ubtest/py:${PYTHONPATH} \
+ PYTHONPATH=${HOME}/ubtest/py/${HOSTNAME}:${PYTHONPATH} \
./test/py/test.py --bd seaboard
```
@@ -331,7 +331,7 @@ follow:
```bash
CROSS_COMPILE=arm-none-eabi- \
PATH=$HOME/ubtest/bin:$PATH \
- PYTHONPATH=${HOME}/ubtest/py:${PYTHONPATH} \
+ PYTHONPATH=${HOME}/ubtest/py/${HOSTNAME}:${PYTHONPATH} \
./test/py/test.py --bd seaboard --build
```
diff --git a/test/py/tests/test_sf.py b/test/py/tests/test_sf.py
new file mode 100644
index 0000000000..95a7564907
--- /dev/null
+++ b/test/py/tests/test_sf.py
@@ -0,0 +1,218 @@
+# Copyright (c) 2016, Xilinx Inc. Michal Simek
+# Copyright (c) 2017, Xiphos Systems Corp. All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0
+
+import re
+import pytest
+import random
+import u_boot_utils
+
+"""
+Note: This test relies on boardenv_* containing configuration values to define
+which SPI Flash areas are available for testing. Without this, this test will
+be automatically skipped.
+For example:
+
+# A list of sections of Flash memory to be tested.
+env__sf_configs = (
+ {
+ # Where in SPI Flash should the test operate.
+ 'offset': 0x00000000,
+ # This value is optional.
+ # If present, specifies the [[bus:]cs] argument used in `sf probe`
+ # If missing, defaults to 0.
+ 'id': '0:1',
+ # This value is optional.
+ # If set as a number, specifies the speed of the SPI Flash.
+ # If set as an array of 2, specifies a range for a random speed.
+ # If missing, defaults to 0.
+ 'speed': 1000000,
+ # This value is optional.
+ # If present, specifies the size to use for read/write operations.
+ # If missing, the SPI Flash page size is used as a default (based on
+ # the `sf probe` output).
+ 'len': 0x10000,
+ # This value is optional.
+ # If present, specifies if the test can write to Flash offset
+ # If missing, defaults to False.
+ 'writeable': False,
+ # This value is optional.
+ # If present, specifies the expected CRC32 value of the flash area.
+ # If missing, extra check is ignored.
+ 'crc32': 0xCAFECAFE,
+ },
+)
+"""
+
+def sf_prepare(u_boot_console, env__sf_config):
+ """Check global state of the SPI Flash before running any test.
+
+ Args:
+ u_boot_console: A U-Boot console connection.
+ env__sf_config: The single SPI Flash device configuration on which to
+ run the tests.
+
+ Returns:
+ sf_params: a dictionary of SPI Flash parameters.
+ """
+
+ sf_params = {}
+ sf_params['ram_base'] = u_boot_utils.find_ram_base(u_boot_console)
+
+ probe_id = env__sf_config.get('id', 0)
+ speed = env__sf_config.get('speed', 0)
+ if isinstance(speed, int):
+ sf_params['speed'] = speed
+ else:
+ assert len(speed) == 2, "If speed is a list, it must have 2 entries"
+ sf_params['speed'] = random.randint(speed[0], speed[1])
+
+ cmd = 'sf probe %d %d' % (probe_id, sf_params['speed'])
+
+ output = u_boot_console.run_command(cmd)
+ assert 'SF: Detected' in output, 'No Flash device available'
+
+ m = re.search('page size (.+?) Bytes', output)
+ assert m, 'SPI Flash page size not recognized'
+ sf_params['page_size'] = int(m.group(1))
+
+ m = re.search('erase size (.+?) KiB', output)
+ assert m, 'SPI Flash erase size not recognized'
+ sf_params['erase_size'] = int(m.group(1))
+ sf_params['erase_size'] *= 1024
+
+ m = re.search('total (.+?) MiB', output)
+ assert m, 'SPI Flash total size not recognized'
+ sf_params['total_size'] = int(m.group(1))
+ sf_params['total_size'] *= 1024 * 1024
+
+ assert 'offset' in env__sf_config, \
+ '\'offset\' is required for this test.'
+ sf_params['len'] = env__sf_config.get('len', sf_params['erase_size'])
+
+ assert not env__sf_config['offset'] % sf_params['erase_size'], \
+ 'offset not multiple of erase size.'
+ assert not sf_params['len'] % sf_params['erase_size'], \
+ 'erase length not multiple of erase size.'
+
+ assert not (env__sf_config.get('writeable', False) and
+ 'crc32' in env__sf_config), \
+ 'Cannot check crc32 on writeable sections'
+
+ return sf_params
+
+def sf_read(u_boot_console, env__sf_config, sf_params):
+ """Helper function used to read and compute the CRC32 value of a section of
+ SPI Flash memory.
+
+ Args:
+ u_boot_console: A U-Boot console connection.
+ env__sf_config: The single SPI Flash device configuration on which to
+ run the tests.
+ sf_params: SPI Flash parameters.
+
+ Returns:
+ CRC32 value of SPI Flash section
+ """
+
+ addr = sf_params['ram_base']
+ offset = env__sf_config['offset']
+ count = sf_params['len']
+ pattern = random.randint(0, 0xFF)
+ crc_expected = env__sf_config.get('crc32', None)
+
+ cmd = 'mw.b %08x %02x %x' % (addr, pattern, count)
+ u_boot_console.run_command(cmd)
+ crc_pattern = u_boot_utils.crc32(u_boot_console, addr, count)
+ if crc_expected:
+ assert crc_pattern != crc_expected
+
+ cmd = 'sf read %08x %08x %x' % (addr, offset, count)
+ response = u_boot_console.run_command(cmd)
+ assert 'Read: OK' in response, 'Read operation failed'
+ crc_readback = u_boot_utils.crc32(u_boot_console, addr, count)
+ assert crc_pattern != crc_readback, 'sf read did not update RAM content.'
+ if crc_expected:
+ assert crc_readback == crc_expected
+
+ return crc_readback
+
+def sf_update(u_boot_console, env__sf_config, sf_params):
+ """Helper function used to update a section of SPI Flash memory.
+
+ Args:
+ u_boot_console: A U-Boot console connection.
+ env__sf_config: The single SPI Flash device configuration on which to
+ run the tests.
+
+ Returns:
+ CRC32 value of SPI Flash section
+ """
+
+ addr = sf_params['ram_base']
+ offset = env__sf_config['offset']
+ count = sf_params['len']
+ pattern = int(random.random() * 0xFF)
+
+ cmd = 'mw.b %08x %02x %x' % (addr, pattern, count)
+ u_boot_console.run_command(cmd)
+ crc_pattern = u_boot_utils.crc32(u_boot_console, addr, count)
+
+ cmd = 'sf update %08x %08x %x' % (addr, offset, count)
+ u_boot_console.run_command(cmd)
+ crc_readback = sf_read(u_boot_console, env__sf_config, sf_params)
+
+ assert crc_readback == crc_pattern
+
+@pytest.mark.buildconfigspec('cmd_sf')
+@pytest.mark.buildconfigspec('cmd_crc32')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_sf_read(u_boot_console, env__sf_config):
+ sf_params = sf_prepare(u_boot_console, env__sf_config)
+ sf_read(u_boot_console, env__sf_config, sf_params)
+
+@pytest.mark.buildconfigspec('cmd_sf')
+@pytest.mark.buildconfigspec('cmd_crc32')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_sf_read_twice(u_boot_console, env__sf_config):
+ sf_params = sf_prepare(u_boot_console, env__sf_config)
+
+ crc1 = sf_read(u_boot_console, env__sf_config, sf_params)
+ sf_params['ram_base'] += 0x100
+ crc2 = sf_read(u_boot_console, env__sf_config, sf_params)
+
+ assert crc1 == crc2, 'CRC32 of two successive read operation do not match'
+
+@pytest.mark.buildconfigspec('cmd_sf')
+@pytest.mark.buildconfigspec('cmd_crc32')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_sf_erase(u_boot_console, env__sf_config):
+ if not env__sf_config.get('writeable', False):
+ pytest.skip('Flash config is tagged as not writeable')
+
+ sf_params = sf_prepare(u_boot_console, env__sf_config)
+ addr = sf_params['ram_base']
+ offset = env__sf_config['offset']
+ count = sf_params['len']
+
+ cmd = 'sf erase %08x %x' % (offset, count)
+ output = u_boot_console.run_command(cmd)
+ assert 'Erased: OK' in output, 'Erase operation failed'
+
+ cmd = 'mw.b %08x ff %x' % (addr, count)
+ u_boot_console.run_command(cmd)
+ crc_ffs = u_boot_utils.crc32(u_boot_console, addr, count)
+
+ crc_read = sf_read(u_boot_console, env__sf_config, sf_params)
+ assert crc_ffs == crc_read, 'Unexpected CRC32 after erase operation.'
+
+@pytest.mark.buildconfigspec('cmd_sf')
+@pytest.mark.buildconfigspec('cmd_crc32')
+@pytest.mark.buildconfigspec('cmd_memory')
+def test_sf_update(u_boot_console, env__sf_config):
+ if not env__sf_config.get('writeable', False):
+ pytest.skip('Flash config is tagged as not writeable')
+
+ sf_params = sf_prepare(u_boot_console, env__sf_config)
+ sf_update(u_boot_console, env__sf_config, sf_params)
diff --git a/test/py/u_boot_utils.py b/test/py/u_boot_utils.py
index 9acb92ddc4..de9ee2643f 100644
--- a/test/py/u_boot_utils.py
+++ b/test/py/u_boot_utils.py
@@ -11,7 +11,7 @@ import os.path
import pytest
import sys
import time
-import pytest
+import re
def md5sum_data(data):
"""Calculate the MD5 hash of some data.
@@ -311,3 +311,25 @@ def persistent_file_helper(u_boot_log, filename):
"""
return PersistentFileHelperCtxMgr(u_boot_log, filename)
+
+def crc32(u_boot_console, address, count):
+ """Helper function used to compute the CRC32 value of a section of RAM.
+
+ Args:
+ u_boot_console: A U-Boot console connection.
+ address: Address where data starts.
+ count: Amount of data to use for calculation.
+
+ Returns:
+ CRC32 value
+ """
+
+ bcfg = u_boot_console.config.buildconfig
+ has_cmd_crc32 = bcfg.get('config_cmd_crc32', 'n') == 'y'
+ assert has_cmd_crc32, 'Cannot compute crc32 without CONFIG_CMD_CRC32.'
+ output = u_boot_console.run_command('crc32 %08x %x' % (address, count))
+
+ m = re.search('==> ([0-9a-fA-F]{8})$', output)
+ assert m, 'CRC32 operation failed.'
+
+ return m.group(1)
diff --git a/tools/Makefile b/tools/Makefile
index 55efb740b8..8143c25666 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -7,6 +7,7 @@
# Enable all the config-independent tools
ifneq ($(HOST_TOOLS_ALL),)
+CONFIG_KIRKWOOD = y
CONFIG_LCD_LOGO = y
CONFIG_CMD_LOADS = y
CONFIG_CMD_NET = y