[U-Boot] [PATCH v3 001/108] binman: Correct symbol calculation with non-zero image base

At present binman adds the image base address to the symbol value before it writes it to the binary. This is not correct since the symbol value itself (e.g. image position) has no relationship to the image base.
Fix this and update the tests to cover this case.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
tools/binman/elf.py | 4 +--- tools/binman/test/u_boot_binman_syms.lds | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 7bc7cf61b5d..0c1a5b44b66 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -135,9 +135,7 @@ def LookupAndWriteSymbols(elf_fname, entry, section):
# Look up the symbol in our entry tables. value = section.LookupSymbol(name, sym.weak, msg) - if value is not None: - value += base.address - else: + if value is None: value = -1 pack_string = pack_string.lower() value_bytes = struct.pack(pack_string, value) diff --git a/tools/binman/test/u_boot_binman_syms.lds b/tools/binman/test/u_boot_binman_syms.lds index 926df873cb7..825fc3f649f 100644 --- a/tools/binman/test/u_boot_binman_syms.lds +++ b/tools/binman/test/u_boot_binman_syms.lds @@ -9,7 +9,7 @@ ENTRY(_start)
SECTIONS { - . = 0x00000000; + . = 0x00000010; _start = .;
. = ALIGN(4);

This entry is used to hold an Intel FSP-S (Firmware Support Package Silicon init) binary. Add support for this in binman.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
tools/binman/README.entries | 17 +++++++++++++++++ tools/binman/etype/intel_fsp_s.py | 27 +++++++++++++++++++++++++++ tools/binman/ftest.py | 6 ++++++ tools/binman/test/153_intel_fsp_s.dts | 14 ++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_s.py create mode 100644 tools/binman/test/153_intel_fsp_s.dts
diff --git a/tools/binman/README.entries b/tools/binman/README.entries index bce22445969..0c0c9675b08 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -444,6 +444,23 @@ See README.x86 for information about x86 binary blobs.
+Entry: intel-fsp-s: Entry containing Intel Firmware Support Package (FSP) silicon init +-------------------------------------------------------------------------------------- + +Properties / Entry arguments: + - filename: Filename of file to read into entry + +This file contains a binary blob which is used on some devices to set up +the silicon. U-Boot executes this code in U-Boot proper after SDRAM is +running, so that it can make full use of memory. Documentation is typically +not available in sufficient detail to allow U-Boot do this this itself. + +An example filename is 'fsp_s.bin' + +See README.x86 for information about x86 binary blobs. + + + Entry: intel-ifwi: Entry containing an Intel Integrated Firmware Image (IFWI) file ----------------------------------------------------------------------------------
diff --git a/tools/binman/etype/intel_fsp_s.py b/tools/binman/etype/intel_fsp_s.py new file mode 100644 index 00000000000..3d6900d1fba --- /dev/null +++ b/tools/binman/etype/intel_fsp_s.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2019 Google LLC +# Written by Simon Glass sjg@chromium.org +# +# Entry-type module for Intel Firmware Support Package binary blob (S section) +# + +from entry import Entry +from blob import Entry_blob + +class Entry_intel_fsp_s(Entry_blob): + """Entry containing Intel Firmware Support Package (FSP) silicon init + + Properties / Entry arguments: + - filename: Filename of file to read into entry + + This file contains a binary blob which is used on some devices to set up + the silicon. U-Boot executes this code in U-Boot proper after SDRAM is + running, so that it can make full use of memory. Documentation is typically + not available in sufficient detail to allow U-Boot do this this itself. + + An example filename is 'fsp_s.bin' + + See README.x86 for information about x86 binary blobs. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index 7000de9d420..eb9aec61cc2 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -73,6 +73,7 @@ FILES_DATA = (b"sorry I'm late\nOh, don't bother apologising, I'm " + COMPRESS_DATA = b'compress xxxxxxxxxxxxxxxxxxxxxx data' REFCODE_DATA = b'refcode' FSP_M_DATA = b'fsp_m' +FSP_S_DATA = b'fsp_s'
# The expected size for the device tree in some tests EXTRACT_DTB_SIZE = 0x3c9 @@ -149,6 +150,7 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('bmpblk.bin', BMPBLK_DATA) TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA) TestFunctional._MakeInputFile('fsp_m.bin', FSP_M_DATA) + TestFunctional._MakeInputFile('fsp_s.bin', FSP_S_DATA)
cls._elf_testdir = os.path.join(cls._indir, 'elftest') elf_test.BuildElfTestFiles(cls._elf_testdir) @@ -3332,6 +3334,10 @@ class TestFunctional(unittest.TestCase): data = self._DoReadFile('152_intel_fsp_m.dts') self.assertEqual(FSP_M_DATA, data[:len(FSP_M_DATA)])
+ def testPackFspS(self): + """Test that an image with a FSP silicon-init binary can be created""" + data = self._DoReadFile('153_intel_fsp_s.dts') + self.assertEqual(FSP_S_DATA, data[:len(FSP_S_DATA)])
if __name__ == "__main__": diff --git a/tools/binman/test/153_intel_fsp_s.dts b/tools/binman/test/153_intel_fsp_s.dts new file mode 100644 index 00000000000..579618a8fa3 --- /dev/null +++ b/tools/binman/test/153_intel_fsp_s.dts @@ -0,0 +1,14 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + intel-fsp-s { + filename = "fsp_s.bin"; + }; + }; +};

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This entry is used to hold an Intel FSP-S (Firmware Support Package Silicon init) binary. Add support for this in binman.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
tools/binman/README.entries | 17 +++++++++++++++++ tools/binman/etype/intel_fsp_s.py | 27 +++++++++++++++++++++++++++ tools/binman/ftest.py | 6 ++++++ tools/binman/test/153_intel_fsp_s.dts | 14 ++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_s.py create mode 100644 tools/binman/test/153_intel_fsp_s.dts
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 11:27 AM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This entry is used to hold an Intel FSP-S (Firmware Support Package Silicon init) binary. Add support for this in binman.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
tools/binman/README.entries | 17 +++++++++++++++++ tools/binman/etype/intel_fsp_s.py | 27 +++++++++++++++++++++++++++ tools/binman/ftest.py | 6 ++++++ tools/binman/test/153_intel_fsp_s.dts | 14 ++++++++++++++ 4 files changed, 64 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_s.py create mode 100644 tools/binman/test/153_intel_fsp_s.dts
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

This entry is used to hold an Intel FSP-T (Firmware Support Package Temp-RAM init) binary. Add support for this in binman.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
tools/binman/README.entries | 16 ++++++++++++++++ tools/binman/etype/intel_fsp_t.py | 26 ++++++++++++++++++++++++++ tools/binman/ftest.py | 7 +++++++ tools/binman/test/154_intel_fsp_t.dts | 14 ++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_t.py create mode 100644 tools/binman/test/154_intel_fsp_t.dts
diff --git a/tools/binman/README.entries b/tools/binman/README.entries index 0c0c9675b08..10994335217 100644 --- a/tools/binman/README.entries +++ b/tools/binman/README.entries @@ -461,6 +461,22 @@ See README.x86 for information about x86 binary blobs.
+Entry: intel-fsp-t: Entry containing Intel Firmware Support Package (FSP) temp ram init +--------------------------------------------------------------------------------------- + +Properties / Entry arguments: + - filename: Filename of file to read into entry + +This file contains a binary blob which is used on some devices to set up +temporary memory (Cache-as-RAM or CAR). U-Boot executes this code in TPL so +that it has access to memory for its stack and initial storage. + +An example filename is 'fsp_t.bin' + +See README.x86 for information about x86 binary blobs. + + + Entry: intel-ifwi: Entry containing an Intel Integrated Firmware Image (IFWI) file ----------------------------------------------------------------------------------
diff --git a/tools/binman/etype/intel_fsp_t.py b/tools/binman/etype/intel_fsp_t.py new file mode 100644 index 00000000000..813a81f2e66 --- /dev/null +++ b/tools/binman/etype/intel_fsp_t.py @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0+ +# Copyright 2019 Google LLC +# Written by Simon Glass sjg@chromium.org +# +# Entry-type module for Intel Firmware Support Package binary blob (T section) +# + +from entry import Entry +from blob import Entry_blob + +class Entry_intel_fsp_t(Entry_blob): + """Entry containing Intel Firmware Support Package (FSP) temp ram init + + Properties / Entry arguments: + - filename: Filename of file to read into entry + + This file contains a binary blob which is used on some devices to set up + temporary memory (Cache-as-RAM or CAR). U-Boot executes this code in TPL so + that it has access to memory for its stack and initial storage. + + An example filename is 'fsp_t.bin' + + See README.x86 for information about x86 binary blobs. + """ + def __init__(self, section, etype, node): + Entry_blob.__init__(self, section, etype, node) diff --git a/tools/binman/ftest.py b/tools/binman/ftest.py index eb9aec61cc2..494e218cbc3 100644 --- a/tools/binman/ftest.py +++ b/tools/binman/ftest.py @@ -74,6 +74,7 @@ COMPRESS_DATA = b'compress xxxxxxxxxxxxxxxxxxxxxx data' REFCODE_DATA = b'refcode' FSP_M_DATA = b'fsp_m' FSP_S_DATA = b'fsp_s' +FSP_T_DATA = b'fsp_t'
# The expected size for the device tree in some tests EXTRACT_DTB_SIZE = 0x3c9 @@ -151,6 +152,7 @@ class TestFunctional(unittest.TestCase): TestFunctional._MakeInputFile('refcode.bin', REFCODE_DATA) TestFunctional._MakeInputFile('fsp_m.bin', FSP_M_DATA) TestFunctional._MakeInputFile('fsp_s.bin', FSP_S_DATA) + TestFunctional._MakeInputFile('fsp_t.bin', FSP_T_DATA)
cls._elf_testdir = os.path.join(cls._indir, 'elftest') elf_test.BuildElfTestFiles(cls._elf_testdir) @@ -3339,6 +3341,11 @@ class TestFunctional(unittest.TestCase): data = self._DoReadFile('153_intel_fsp_s.dts') self.assertEqual(FSP_S_DATA, data[:len(FSP_S_DATA)])
+ def testPackFspT(self): + """Test that an image with a FSP temp-ram-init binary can be created""" + data = self._DoReadFile('154_intel_fsp_t.dts') + self.assertEqual(FSP_T_DATA, data[:len(FSP_T_DATA)]) +
if __name__ == "__main__": unittest.main() diff --git a/tools/binman/test/154_intel_fsp_t.dts b/tools/binman/test/154_intel_fsp_t.dts new file mode 100644 index 00000000000..8da749c1574 --- /dev/null +++ b/tools/binman/test/154_intel_fsp_t.dts @@ -0,0 +1,14 @@ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + binman { + size = <16>; + + intel-fsp-t { + filename = "fsp_t.bin"; + }; + }; +};

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This entry is used to hold an Intel FSP-T (Firmware Support Package Temp-RAM init) binary. Add support for this in binman.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
tools/binman/README.entries | 16 ++++++++++++++++ tools/binman/etype/intel_fsp_t.py | 26 ++++++++++++++++++++++++++ tools/binman/ftest.py | 7 +++++++ tools/binman/test/154_intel_fsp_t.dts | 14 ++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_t.py create mode 100644 tools/binman/test/154_intel_fsp_t.dts
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 11:27 AM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This entry is used to hold an Intel FSP-T (Firmware Support Package Temp-RAM init) binary. Add support for this in binman.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
tools/binman/README.entries | 16 ++++++++++++++++ tools/binman/etype/intel_fsp_t.py | 26 ++++++++++++++++++++++++++ tools/binman/ftest.py | 7 +++++++ tools/binman/test/154_intel_fsp_t.dts | 14 ++++++++++++++ 4 files changed, 63 insertions(+) create mode 100644 tools/binman/etype/intel_fsp_t.py create mode 100644 tools/binman/test/154_intel_fsp_t.dts
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

This comment references the wrong FSP component. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
tools/binman/etype/intel_fsp_m.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/binman/etype/intel_fsp_m.py b/tools/binman/etype/intel_fsp_m.py index 2d6b2b6621b..bb1de73e414 100644 --- a/tools/binman/etype/intel_fsp_m.py +++ b/tools/binman/etype/intel_fsp_m.py @@ -2,7 +2,7 @@ # Copyright 2019 Google LLC # Written by Simon Glass sjg@chromium.org # -# Entry-type module for Intel Firmware Support Package binary blob (T section) +# Entry-type module for Intel Firmware Support Package binary blob (M section) #
from entry import Entry

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This comment references the wrong FSP component. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
tools/binman/etype/intel_fsp_m.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 11:27 AM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This comment references the wrong FSP component. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
tools/binman/etype/intel_fsp_m.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

SPL and TPL can access information about binman entries using link-time symbols but this is not available in U-Boot proper. Of course it could be made available, but the intention is to just read the device tree.
Add support for this, so that U-Boot can locate entries.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
common/board_r.c | 10 ++++++++++ include/binman.h | 27 +++++++++++++++++++++++++++ lib/Kconfig | 10 ++++++++++ lib/Makefile | 1 + lib/binman.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+) create mode 100644 include/binman.h create mode 100644 lib/binman.c
diff --git a/common/board_r.c b/common/board_r.c index d6fb5047a26..e0f3eb325aa 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -15,6 +15,7 @@ #if defined(CONFIG_CMD_BEDBUG) #include <bedbug/type.h> #endif +#include <binman.h> #include <command.h> #include <console.h> #include <dm.h> @@ -342,6 +343,14 @@ static int initr_manual_reloc_cmdtable(void) } #endif
+static int initr_binman(void) +{ + if (!CONFIG_IS_ENABLED(BINMAN_FDT)) + return 0; + + return binman_init(); +} + #if defined(CONFIG_MTD_NOR_FLASH) static int initr_flash(void) { @@ -693,6 +702,7 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_EFI_LOADER efi_memory_init, #endif + initr_binman, stdio_init_tables, initr_serial, initr_announce, diff --git a/include/binman.h b/include/binman.h new file mode 100644 index 00000000000..cc9ec77797f --- /dev/null +++ b/include/binman.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: Intel */ +/* + * Access to binman information at runtime + * + * Copyright 2019 Google LLC + * Written by Simon Glass sjg@chromium.org + */ + +#ifndef _BINMAN_H_ +#define _BINMAN_H_ + +/** + *struct binman_entry - information about a binman entry + * + * @image_pos: Position of entry in the image + * @size: Size of entry + */ +struct binman_entry { + u32 image_pos; + u32 size; +}; + +int binman_entry_find(const char *name, struct binman_entry *entry); + +int binman_init(void); + +#endif diff --git a/lib/Kconfig b/lib/Kconfig index 135f0b372b0..291d42324d1 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -7,6 +7,16 @@ config BCH This is used by SoC platforms which do not have built-in ELM hardware engine required for BCH ECC correction.
+config BINMAN_FDT + bool "Allow access to binman information in the device tree" + depends on BINMAN + default y + help + This enables U-Boot to access information about binman entries, + stored in the device tree in a binman node. Typical uses are to + locate entries in the firmware image. See binman.h for the available + functionality. + config CC_OPTIMIZE_LIBS_FOR_SPEED bool "Optimize libraries for speed" help diff --git a/lib/Makefile b/lib/Makefile index d248d8626ce..0c89b4896fe 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_AT91) += at91/ obj-$(CONFIG_OPTEE) += optee/
obj-$(CONFIG_AES) += aes.o +obj-$(CONFIG_$(SPL_TPL_)BINMAN_FDT) += binman.o
ifndef API_BUILD ifneq ($(CONFIG_UT_UNICODE)$(CONFIG_EFI_LOADER),) diff --git a/lib/binman.c b/lib/binman.c new file mode 100644 index 00000000000..1774bdf2e5c --- /dev/null +++ b/lib/binman.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Intel +/* + * Access to binman information at runtime + * + * Copyright 2019 Google LLC + * Written by Simon Glass sjg@chromium.org + */ + +#include <common.h> +#include <binman.h> +#include <dm.h> + +struct binman_info { + ofnode image; +}; + +static struct binman_info *binman; + +int binman_entry_find(const char *name, struct binman_entry *entry) +{ + ofnode node; + int ret; + + node = ofnode_find_subnode(binman->image, name); + if (!ofnode_valid(node)) + return log_msg_ret("no binman node", -ENOENT); + + ret = ofnode_read_u32(node, "image-pos", &entry->image_pos); + if (ret) + return log_msg_ret("bad binman node1", ret); + ret = ofnode_read_u32(node, "size", &entry->size); + if (ret) + return log_msg_ret("bad binman node2", ret); + + return 0; +} + +int binman_init(void) +{ + binman = malloc(sizeof(struct binman_info)); + if (!binman) + return log_msg_ret("space for binman", -ENOMEM); + binman->image = ofnode_path("/binman"); + if (!ofnode_valid(binman->image)) + return log_msg_ret("binman node", -EINVAL); + + return 0; +}

Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
SPL and TPL can access information about binman entries using link-time symbols but this is not available in U-Boot proper. Of course it could be made available, but the intention is to just read the device tree.
Add support for this, so that U-Boot can locate entries.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
common/board_r.c | 10 ++++++++++ include/binman.h | 27 +++++++++++++++++++++++++++ lib/Kconfig | 10 ++++++++++ lib/Makefile | 1 + lib/binman.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 96 insertions(+) create mode 100644 include/binman.h create mode 100644 lib/binman.c
diff --git a/common/board_r.c b/common/board_r.c index d6fb5047a26..e0f3eb325aa 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -15,6 +15,7 @@ #if defined(CONFIG_CMD_BEDBUG) #include <bedbug/type.h> #endif +#include <binman.h> #include <command.h> #include <console.h> #include <dm.h> @@ -342,6 +343,14 @@ static int initr_manual_reloc_cmdtable(void) } #endif
+static int initr_binman(void) +{
if (!CONFIG_IS_ENABLED(BINMAN_FDT))
return 0;
return binman_init();
+}
#if defined(CONFIG_MTD_NOR_FLASH) static int initr_flash(void) { @@ -693,6 +702,7 @@ static init_fnc_t init_sequence_r[] = { #ifdef CONFIG_EFI_LOADER efi_memory_init, #endif
initr_binman, stdio_init_tables, initr_serial, initr_announce,
diff --git a/include/binman.h b/include/binman.h new file mode 100644 index 00000000000..cc9ec77797f --- /dev/null +++ b/include/binman.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: Intel */ +/*
- Access to binman information at runtime
- Copyright 2019 Google LLC
- Written by Simon Glass sjg@chromium.org
- */
+#ifndef _BINMAN_H_ +#define _BINMAN_H_
+/**
- *struct binman_entry - information about a binman entry
- @image_pos: Position of entry in the image
- @size: Size of entry
- */
+struct binman_entry {
u32 image_pos;
u32 size;
+};
+int binman_entry_find(const char *name, struct binman_entry *entry);
+int binman_init(void);
Please add the comment block with parameters/return value for the above 2 functions.
+#endif diff --git a/lib/Kconfig b/lib/Kconfig index 135f0b372b0..291d42324d1 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -7,6 +7,16 @@ config BCH This is used by SoC platforms which do not have built-in ELM hardware engine required for BCH ECC correction.
+config BINMAN_FDT
bool "Allow access to binman information in the device tree"
depends on BINMAN
default y
help
This enables U-Boot to access information about binman entries,
stored in the device tree in a binman node. Typical uses are to
locate entries in the firmware image. See binman.h for the available
functionality.
config CC_OPTIMIZE_LIBS_FOR_SPEED bool "Optimize libraries for speed" help diff --git a/lib/Makefile b/lib/Makefile index d248d8626ce..0c89b4896fe 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_AT91) += at91/ obj-$(CONFIG_OPTEE) += optee/
obj-$(CONFIG_AES) += aes.o +obj-$(CONFIG_$(SPL_TPL_)BINMAN_FDT) += binman.o
ifndef API_BUILD ifneq ($(CONFIG_UT_UNICODE)$(CONFIG_EFI_LOADER),) diff --git a/lib/binman.c b/lib/binman.c new file mode 100644 index 00000000000..1774bdf2e5c --- /dev/null +++ b/lib/binman.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: Intel +/*
- Access to binman information at runtime
- Copyright 2019 Google LLC
- Written by Simon Glass sjg@chromium.org
- */
+#include <common.h> +#include <binman.h> +#include <dm.h>
+struct binman_info {
ofnode image;
+};
+static struct binman_info *binman;
+int binman_entry_find(const char *name, struct binman_entry *entry) +{
ofnode node;
int ret;
node = ofnode_find_subnode(binman->image, name);
if (!ofnode_valid(node))
return log_msg_ret("no binman node", -ENOENT);
ret = ofnode_read_u32(node, "image-pos", &entry->image_pos);
if (ret)
return log_msg_ret("bad binman node1", ret);
ret = ofnode_read_u32(node, "size", &entry->size);
if (ret)
return log_msg_ret("bad binman node2", ret);
return 0;
+}
+int binman_init(void) +{
binman = malloc(sizeof(struct binman_info));
if (!binman)
return log_msg_ret("space for binman", -ENOMEM);
binman->image = ofnode_path("/binman");
if (!ofnode_valid(binman->image))
return log_msg_ret("binman node", -EINVAL);
return 0;
+}
Regards, Bin

At present if CONFIG_SPL_GPIO_SUPPORT is enabled then the GPIO uclass is included in SPL/TPL without any control for boards. Some boards may want to disable this to reduce code size where GPIOs are not needed in SPL or TPL.
Add a new Kconfig option to permit this. Default it to 'y' so that existing boards work correctly.
Change existing uses of CONFIG_DM_GPIO to CONFIG_IS_ENABLED(DM_GPIO) to preserve the current behaviour. Also update the 74x164 GPIO driver since it cannot build with SPL.
This allows us to remove the hacks in config_uncmd_spl.h and Makefile.uncmd_spl (eventually those files should be removed).
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: - Fix the Kconfig condition to avoid build errors on snow
arch/arm/include/asm/omap_gpio.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-davinci/include/mach/gpio.h | 2 +- arch/arm/mach-omap2/am33xx/board.c | 4 ++-- arch/arm/mach-omap2/omap3/board.c | 2 +- arch/arm/mach-omap2/omap5/hwinit.c | 2 +- board/freescale/imx8qm_mek/imx8qm_mek.c | 2 +- board/freescale/imx8qxp_mek/imx8qxp_mek.c | 2 +- board/gateworks/gw_ventana/Kconfig | 3 +++ board/toradex/apalis-imx8/apalis-imx8.c | 2 +- drivers/gpio/Kconfig | 22 +++++++++++++++++++ drivers/gpio/Makefile | 4 +++- drivers/gpio/at91_gpio.c | 6 ++--- drivers/gpio/atmel_pio4.c | 2 +- drivers/gpio/da8xx_gpio.c | 6 ++--- drivers/gpio/da8xx_gpio.h | 2 +- drivers/gpio/mxc_gpio.c | 4 ++-- drivers/gpio/mxs_gpio.c | 4 ++-- drivers/gpio/omap_gpio.c | 6 ++--- drivers/gpio/sunxi_gpio.c | 8 +++---- drivers/i2c/i2c-uclass.c | 6 ++--- drivers/i2c/muxes/pca954x.c | 4 ++-- drivers/mmc/fsl_esdhc_imx.c | 13 ++++++----- drivers/mmc/omap_hsmmc.c | 2 +- drivers/net/designware.c | 10 ++++----- drivers/net/designware.h | 4 ++-- drivers/net/fec_mxc.c | 6 ++--- drivers/net/fec_mxc.h | 2 +- drivers/net/mvneta.c | 4 ++-- drivers/net/mvpp2.c | 8 +++---- drivers/net/sun8i_emac.c | 12 +++++----- drivers/pci/pci-aardvark.c | 4 ++-- drivers/pci/pcie_dw_mvebu.c | 4 ++-- drivers/spi/atmel_spi.c | 10 ++++----- drivers/spi/designware_spi.c | 4 ++-- drivers/tpm/tpm2_tis_spi.c | 2 +- include/config_uncmd_spl.h | 1 - include/configs/at91-sama5_common.h | 5 +++-- include/configs/gw_ventana.h | 1 - include/configs/mx6ul_14x14_evk.h | 1 + scripts/Makefile.uncmd_spl | 1 - 41 files changed, 109 insertions(+), 82 deletions(-)
diff --git a/arch/arm/include/asm/omap_gpio.h b/arch/arm/include/asm/omap_gpio.h index 20268fa084e..151afa8f44c 100644 --- a/arch/arm/include/asm/omap_gpio.h +++ b/arch/arm/include/asm/omap_gpio.h @@ -22,7 +22,7 @@
#include <asm/arch/cpu.h>
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO)
/* Information about a GPIO bank */ struct omap_gpio_platdata { diff --git a/arch/arm/mach-at91/include/mach/at91sam9260.h b/arch/arm/mach-at91/include/mach/at91sam9260.h index 91faf729ae0..2daeb4fef8f 100644 --- a/arch/arm/mach-at91/include/mach/at91sam9260.h +++ b/arch/arm/mach-at91/include/mach/at91sam9260.h @@ -133,7 +133,7 @@ /* * Other misc defines */ -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #define ATMEL_PIO_PORTS 3 /* these SoCs have 3 PIO */ #define ATMEL_BASE_PIO ATMEL_BASE_PIOA #endif diff --git a/arch/arm/mach-davinci/include/mach/gpio.h b/arch/arm/mach-davinci/include/mach/gpio.h index c1502409626..e5a40534141 100644 --- a/arch/arm/mach-davinci/include/mach/gpio.h +++ b/arch/arm/mach-davinci/include/mach/gpio.h @@ -18,7 +18,7 @@ #define davinci_gpio_bank67 ((struct davinci_gpio *)DAVINCI_GPIO_BANK67) #define davinci_gpio_bank8 ((struct davinci_gpio *)DAVINCI_GPIO_BANK8)
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #define gpio_status() gpio_info() #endif #define GPIO_NAME_SIZE 20 diff --git a/arch/arm/mach-omap2/am33xx/board.c b/arch/arm/mach-omap2/am33xx/board.c index 03460c3eb7e..e64942b7167 100644 --- a/arch/arm/mach-omap2/am33xx/board.c +++ b/arch/arm/mach-omap2/am33xx/board.c @@ -116,7 +116,7 @@ U_BOOT_DEVICES(am33xx_i2c) = { }; #endif
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) static const struct omap_gpio_platdata am33xx_gpio[] = { { 0, AM33XX_GPIO0_BASE }, { 1, AM33XX_GPIO1_BASE }, @@ -141,7 +141,7 @@ U_BOOT_DEVICES(am33xx_gpios) = { #endif #endif
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) static const struct gpio_bank gpio_bank_am33xx[] = { { (void *)AM33XX_GPIO0_BASE }, { (void *)AM33XX_GPIO1_BASE }, diff --git a/arch/arm/mach-omap2/omap3/board.c b/arch/arm/mach-omap2/omap3/board.c index 658ef8c1f11..60de0d60521 100644 --- a/arch/arm/mach-omap2/omap3/board.c +++ b/arch/arm/mach-omap2/omap3/board.c @@ -33,7 +33,7 @@ extern omap3_sysinfo sysinfo; static void omap3_invalidate_l2_cache_secure(void); #endif
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #if !CONFIG_IS_ENABLED(OF_CONTROL) /* Manually initialize GPIO banks when OF_CONTROL doesn't */ static const struct omap_gpio_platdata omap34xx_gpio[] = { diff --git a/arch/arm/mach-omap2/omap5/hwinit.c b/arch/arm/mach-omap2/omap5/hwinit.c index eba21647d96..56458ce4957 100644 --- a/arch/arm/mach-omap2/omap5/hwinit.c +++ b/arch/arm/mach-omap2/omap5/hwinit.c @@ -25,7 +25,7 @@
u32 *const omap_si_rev = (u32 *)OMAP_SRAM_SCRATCH_OMAP_REV;
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) static struct gpio_bank gpio_bank_54xx[8] = { { (void *)OMAP54XX_GPIO1_BASE }, { (void *)OMAP54XX_GPIO2_BASE }, diff --git a/board/freescale/imx8qm_mek/imx8qm_mek.c b/board/freescale/imx8qm_mek/imx8qm_mek.c index 76634a3a28a..a1143024286 100644 --- a/board/freescale/imx8qm_mek/imx8qm_mek.c +++ b/board/freescale/imx8qm_mek/imx8qm_mek.c @@ -49,7 +49,7 @@ int board_early_init_f(void) return 0; }
-#if IS_ENABLED(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) static void board_gpio_init(void) { /* TODO */ diff --git a/board/freescale/imx8qxp_mek/imx8qxp_mek.c b/board/freescale/imx8qxp_mek/imx8qxp_mek.c index 4ba83142841..2ba5879d578 100644 --- a/board/freescale/imx8qxp_mek/imx8qxp_mek.c +++ b/board/freescale/imx8qxp_mek/imx8qxp_mek.c @@ -53,7 +53,7 @@ int board_early_init_f(void) return 0; }
-#if IS_ENABLED(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) static void board_gpio_init(void) { struct gpio_desc desc; diff --git a/board/gateworks/gw_ventana/Kconfig b/board/gateworks/gw_ventana/Kconfig index 5d1bae41ac5..fee910ca837 100644 --- a/board/gateworks/gw_ventana/Kconfig +++ b/board/gateworks/gw_ventana/Kconfig @@ -1,5 +1,8 @@ if TARGET_GW_VENTANA
+config DM_GPIO + default y + config SYS_BOARD default "gw_ventana"
diff --git a/board/toradex/apalis-imx8/apalis-imx8.c b/board/toradex/apalis-imx8/apalis-imx8.c index af48b560952..0e597011ae6 100644 --- a/board/toradex/apalis-imx8/apalis-imx8.c +++ b/board/toradex/apalis-imx8/apalis-imx8.c @@ -50,7 +50,7 @@ int board_early_init_f(void) return 0; }
-#if IS_ENABLED(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) static void board_gpio_init(void) { /* TODO */ diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 39f2c7e3283..1ab01038838 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -14,6 +14,28 @@ config DM_GPIO particular GPIOs that they provide. The uclass interface is defined in include/asm-generic/gpio.h.
+config SPL_DM_GPIO + bool "Enable Driver Model for GPIO drivers in SPL" + depends on DM_GPIO && SPL_DM && SPL_GPIO_SUPPORT + default y + help + Enable driver model for GPIO access in SPL. The standard GPIO + interface (gpio_get_value(), etc.) is then implemented by + the GPIO uclass. Drivers provide methods to query the + particular GPIOs that they provide. The uclass interface + is defined in include/asm-generic/gpio.h. + +config TPL_DM_GPIO + bool "Enable Driver Model for GPIO drivers in TPL" + depends on DM_GPIO && TPL_DM && TPL_GPIO_SUPPORT + default y + help + Enable driver model for GPIO access in TPL. The standard GPIO + interface (gpio_get_value(), etc.) is then implemented by + the GPIO uclass. Drivers provide methods to query the + particular GPIOs that they provide. The uclass interface + is defined in include/asm-generic/gpio.h. + config GPIO_HOG bool "Enable GPIO hog support" depends on DM_GPIO diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index ccc49e2eb02..3612e66786a 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -7,10 +7,12 @@ ifndef CONFIG_SPL_BUILD obj-$(CONFIG_DWAPB_GPIO) += dwapb_gpio.o obj-$(CONFIG_AXP_GPIO) += axp_gpio.o endif -obj-$(CONFIG_DM_GPIO) += gpio-uclass.o +obj-$(CONFIG_$(SPL_TPL_)DM_GPIO) += gpio-uclass.o
obj-$(CONFIG_$(SPL_)DM_PCA953X) += pca953x_gpio.o +ifdef CONFIG_$(SPL_TPL_)GPIO obj-$(CONFIG_DM_74X164) += 74x164_gpio.o +endif
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c index 965becf77ab..8d36d48fc86 100644 --- a/drivers/gpio/at91_gpio.c +++ b/drivers/gpio/at91_gpio.c @@ -210,7 +210,7 @@ int at91_pio3_set_d_periph(unsigned port, unsigned pin, int use_pullup) return 0; }
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) static bool at91_get_port_output(struct at91_port *at91_port, int offset) { u32 mask, val; @@ -457,7 +457,7 @@ int at91_get_pio_value(unsigned port, unsigned pin) return 0; }
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) /* Common GPIO API */
int gpio_request(unsigned gpio, const char *label) @@ -499,7 +499,7 @@ int gpio_set_value(unsigned gpio, int value) } #endif
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO)
struct at91_port_priv { struct at91_port *regs; diff --git a/drivers/gpio/atmel_pio4.c b/drivers/gpio/atmel_pio4.c index 95a189a50f6..8e6f32de1f3 100644 --- a/drivers/gpio/atmel_pio4.c +++ b/drivers/gpio/atmel_pio4.c @@ -168,7 +168,7 @@ int atmel_pio4_get_pio_input(u32 port, u32 pin) return (readl(&port_base->pdsr) & mask) ? 1 : 0; }
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO)
struct atmel_pioctrl_data { u32 nbanks; diff --git a/drivers/gpio/da8xx_gpio.c b/drivers/gpio/da8xx_gpio.c index bd794481648..e4c68336af7 100644 --- a/drivers/gpio/da8xx_gpio.c +++ b/drivers/gpio/da8xx_gpio.c @@ -15,7 +15,7 @@
#include "da8xx_gpio.h"
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #include <asm/arch/hardware.h> #include <asm/arch/davinci_misc.h>
@@ -377,7 +377,7 @@ static int _gpio_get_dir(struct davinci_gpio *bank, unsigned int gpio) return in_le32(&bank->dir) & (1U << GPIO_BIT(gpio)); }
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO)
void gpio_info(void) { @@ -428,7 +428,7 @@ int gpio_set_value(unsigned int gpio, int value) return _gpio_set_value(bank, gpio, value); }
-#else /* CONFIG_DM_GPIO */ +#else /* DM_GPIO */
static struct davinci_gpio *davinci_get_gpio_bank(struct udevice *dev, unsigned int offset) { diff --git a/drivers/gpio/da8xx_gpio.h b/drivers/gpio/da8xx_gpio.h index 1de9ec7f6fb..849e8d2dcf3 100644 --- a/drivers/gpio/da8xx_gpio.h +++ b/drivers/gpio/da8xx_gpio.h @@ -28,7 +28,7 @@ struct davinci_gpio_bank { #define MAX_NUM_GPIOS 144 #define GPIO_BIT(gp) ((gp) & 0x1F)
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO)
/* Information about a GPIO bank */ struct davinci_gpio_platdata { diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c index 64ab7a303f1..6592d141d3e 100644 --- a/drivers/gpio/mxc_gpio.c +++ b/drivers/gpio/mxc_gpio.c @@ -30,7 +30,7 @@ struct mxc_bank_info { struct gpio_regs *regs; };
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #define GPIO_TO_PORT(n) ((n) / 32)
/* GPIO port description */ @@ -161,7 +161,7 @@ int gpio_direction_output(unsigned gpio, int value) } #endif
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <fdtdec.h> static int mxc_gpio_is_output(struct gpio_regs *regs, int offset) { diff --git a/drivers/gpio/mxs_gpio.c b/drivers/gpio/mxs_gpio.c index 5795155e3ed..77778e9ce57 100644 --- a/drivers/gpio/mxs_gpio.c +++ b/drivers/gpio/mxs_gpio.c @@ -128,7 +128,7 @@ int name_to_gpio(const char *name)
return (bank << MXS_PAD_BANK_SHIFT) | (pin << MXS_PAD_PIN_SHIFT); } -#else /* CONFIG_DM_GPIO */ +#else /* DM_GPIO */ #include <dm.h> #include <asm/gpio.h> #include <dt-structs.h> @@ -312,4 +312,4 @@ U_BOOT_DRIVER(gpio_mxs) = { .ofdata_to_platdata = mxs_ofdata_to_platdata, #endif }; -#endif /* CONFIG_DM_GPIO */ +#endif /* DM_GPIO */ diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c index 0031415d03e..4249850f4bf 100644 --- a/drivers/gpio/omap_gpio.c +++ b/drivers/gpio/omap_gpio.c @@ -30,7 +30,7 @@ DECLARE_GLOBAL_DATA_PTR; #define OMAP_GPIO_DIR_OUT 0 #define OMAP_GPIO_DIR_IN 1
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO)
#define GPIO_PER_BANK 32
@@ -121,7 +121,7 @@ static int _get_gpio_value(const struct gpio_bank *bank, int gpio) return (__raw_readl(reg) & (1 << gpio)) != 0; }
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO)
static inline const struct gpio_bank *get_gpio_bank(int gpio) { @@ -377,4 +377,4 @@ U_BOOT_DRIVER(gpio_omap) = { #endif };
-#endif /* CONFIG_DM_GPIO */ +#endif /* !DM_GPIO */ diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index 719efc2cef0..9c3a4428e11 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -28,7 +28,7 @@ struct sunxi_gpio_platdata { int gpio_count; };
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) static int sunxi_gpio_output(u32 pin, u32 val) { u32 dat; @@ -116,7 +116,7 @@ int sunxi_name_to_gpio(const char *name) return -1; return group * 32 + pin; } -#endif +#endif /* DM_GPIO */
int sunxi_name_to_gpio_bank(const char *name) { @@ -132,7 +132,7 @@ int sunxi_name_to_gpio_bank(const char *name) return -1; }
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) /* TODO(sjg@chromium.org): Remove this function and use device tree */ int sunxi_name_to_gpio(const char *name) { @@ -373,4 +373,4 @@ U_BOOT_DRIVER(gpio_sunxi) = { .bind = gpio_sunxi_bind, .probe = gpio_sunxi_probe, }; -#endif +#endif /* DM_GPIO */ diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index e47abf18333..88c13e76cb7 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -11,7 +11,7 @@ #include <dm/device-internal.h> #include <dm/lists.h> #include <dm/pinctrl.h> -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <asm/gpio.h> #endif
@@ -465,7 +465,7 @@ int i2c_get_chip_offset_len(struct udevice *dev) return chip->offset_len; }
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) static void i2c_gpio_set_pin(struct gpio_desc *pin, int bit) { if (bit) @@ -561,7 +561,7 @@ static int i2c_deblock_gpio(struct udevice *bus) { return -ENOSYS; } -#endif // CONFIG_DM_GPIO +#endif /* DM_GPIO */
int i2c_deblock(struct udevice *bus) { diff --git a/drivers/i2c/muxes/pca954x.c b/drivers/i2c/muxes/pca954x.c index a630ce991d0..bb2935f8ec0 100644 --- a/drivers/i2c/muxes/pca954x.c +++ b/drivers/i2c/muxes/pca954x.c @@ -125,7 +125,7 @@ static int pca954x_ofdata_to_platdata(struct udevice *dev)
static int pca954x_probe(struct udevice *dev) { - if (IS_ENABLED(CONFIG_DM_GPIO)) { + if (CONFIG_IS_ENABLED(DM_GPIO)) { struct pca954x_priv *priv = dev_get_priv(dev); int err;
@@ -146,7 +146,7 @@ static int pca954x_probe(struct udevice *dev)
static int pca954x_remove(struct udevice *dev) { - if (IS_ENABLED(CONFIG_DM_GPIO)) { + if (CONFIG_IS_ENABLED(DM_GPIO)) { struct pca954x_priv *priv = dev_get_priv(dev);
if (dm_gpio_is_valid(&priv->gpio_mux_reset)) diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index 43106dec756..6b4921a01d6 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -149,7 +149,7 @@ struct fsl_esdhc_priv { struct udevice *vqmmc_dev; struct udevice *vmmc_dev; #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc cd_gpio; struct gpio_desc wp_gpio; #endif @@ -302,8 +302,9 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc, return -ETIMEDOUT; } } else { -#ifdef CONFIG_DM_GPIO - if (dm_gpio_is_valid(&priv->wp_gpio) && dm_gpio_get_value(&priv->wp_gpio)) { +#if CONFIG_IS_ENABLED(DM_GPIO) + if (dm_gpio_is_valid(&priv->wp_gpio) && + dm_gpio_get_value(&priv->wp_gpio)) { printf("\nThe SD card is locked. Can not write to a locked card.\n\n"); return -ETIMEDOUT; } @@ -1089,7 +1090,7 @@ static int esdhc_getcd_common(struct fsl_esdhc_priv *priv) #if CONFIG_IS_ENABLED(DM_MMC) if (priv->non_removable) return 1; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) if (dm_gpio_is_valid(&priv->cd_gpio)) return dm_gpio_get_value(&priv->cd_gpio); #endif @@ -1451,7 +1452,7 @@ static int fsl_esdhc_probe(struct udevice *dev) priv->non_removable = 1; } else { priv->non_removable = 0; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); #endif @@ -1461,7 +1462,7 @@ static int fsl_esdhc_probe(struct udevice *dev) priv->wp_enable = 1; } else { priv->wp_enable = 0; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); #endif diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index bade129aea9..8eecaafe477 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -183,7 +183,7 @@ static int omap_mmc_setup_gpio_in(int gpio, const char *label) { int ret;
-#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) if (!gpio_is_valid(gpio)) return -1; #endif diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 00313700858..8a2171a716e 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -81,7 +81,7 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, return ret; }
-#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO) +#if defined(CONFIG_DM_ETH) && CONFIG_IS_ENABLED(DM_GPIO) static int dw_mdio_reset(struct mii_dev *bus) { struct udevice *dev = bus->priv; @@ -127,7 +127,7 @@ static int dw_mdio_init(const char *name, void *priv) bus->read = dw_mdio_read; bus->write = dw_mdio_write; snprintf(bus->name, sizeof(bus->name), "%s", name); -#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO) +#if defined(CONFIG_DM_ETH) && CONFIG_IS_ENABLED(DM_GPIO) bus->reset = dw_mdio_reset; #endif
@@ -806,12 +806,12 @@ const struct eth_ops designware_eth_ops = { int designware_eth_ofdata_to_platdata(struct udevice *dev) { struct dw_eth_pdata *dw_pdata = dev_get_platdata(dev); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct dw_eth_dev *priv = dev_get_priv(dev); #endif struct eth_pdata *pdata = &dw_pdata->eth_pdata; const char *phy_mode; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) int reset_flags = GPIOD_IS_OUT; #endif int ret = 0; @@ -828,7 +828,7 @@ int designware_eth_ofdata_to_platdata(struct udevice *dev)
pdata->max_speed = dev_read_u32_default(dev, "max-speed", 0);
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) if (dev_read_bool(dev, "snps,reset-active-low")) reset_flags |= GPIOD_ACTIVE_LOW;
diff --git a/drivers/net/designware.h b/drivers/net/designware.h index dea12b7048c..3519a4167a7 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -7,7 +7,7 @@ #ifndef _DW_ETH_H #define _DW_ETH_H
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <asm-generic/gpio.h> #endif
@@ -235,7 +235,7 @@ struct dw_eth_dev { #ifndef CONFIG_DM_ETH struct eth_device *dev; #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio; #endif #ifdef CONFIG_CLK diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c index 080dbcf7db4..ef90d029441 100644 --- a/drivers/net/fec_mxc.c +++ b/drivers/net/fec_mxc.c @@ -1300,7 +1300,7 @@ static int fec_phy_init(struct fec_priv *priv, struct udevice *dev) return 0; }
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) /* FEC GPIO reset */ static void fec_gpio_reset(struct fec_priv *priv) { @@ -1352,7 +1352,7 @@ static int fecmxc_probe(struct udevice *dev) } #endif
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) fec_gpio_reset(priv); #endif /* Reset chip. */ @@ -1458,7 +1458,7 @@ static int fecmxc_ofdata_to_platdata(struct udevice *dev) device_get_supply_regulator(dev, "phy-supply", &priv->phy_supply); #endif
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) ret = gpio_request_by_name(dev, "phy-reset-gpios", 0, &priv->phy_reset_gpio, GPIOD_IS_OUT); if (ret < 0) diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h index e5f2dd75c59..179d96e654e 100644 --- a/drivers/net/fec_mxc.h +++ b/drivers/net/fec_mxc.h @@ -255,7 +255,7 @@ struct fec_priv { #ifdef CONFIG_DM_REGULATOR struct udevice *phy_supply; #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc phy_reset_gpio; uint32_t reset_delay; uint32_t reset_post_delay; diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c index 333be8ff28b..5a39d333a06 100644 --- a/drivers/net/mvneta.c +++ b/drivers/net/mvneta.c @@ -275,7 +275,7 @@ struct mvneta_port { int init; int phyaddr; struct phy_device *phydev; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc phy_reset_gpio; #endif struct mii_dev *bus; @@ -1753,7 +1753,7 @@ static int mvneta_probe(struct udevice *dev) if (ret) return ret;
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) gpio_request_by_name(dev, "phy-reset-gpios", 0, &pp->phy_reset_gpio, GPIOD_IS_OUT);
diff --git a/drivers/net/mvpp2.c b/drivers/net/mvpp2.c index bd89725e777..dc81732ff09 100644 --- a/drivers/net/mvpp2.c +++ b/drivers/net/mvpp2.c @@ -976,7 +976,7 @@ struct mvpp2_port { int phy_node; int phyaddr; struct mii_dev *bus; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc phy_reset_gpio; struct gpio_desc phy_tx_disable_gpio; #endif @@ -4753,7 +4753,7 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) return -EINVAL; }
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) gpio_request_by_name(dev, "phy-reset-gpios", 0, &port->phy_reset_gpio, GPIOD_IS_OUT); gpio_request_by_name(dev, "marvell,sfp-tx-disable-gpio", 0, @@ -4781,7 +4781,7 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port) return 0; }
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) /* Port GPIO initialization */ static void mvpp2_gpio_init(struct mvpp2_port *port) { @@ -4814,7 +4814,7 @@ static int mvpp2_port_probe(struct udevice *dev, } mvpp2_port_power_up(port);
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) mvpp2_gpio_init(port); #endif
diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c index 0629b16e57c..0b46044337e 100644 --- a/drivers/net/sun8i_emac.c +++ b/drivers/net/sun8i_emac.c @@ -23,7 +23,7 @@ #include <net.h> #include <reset.h> #include <dt-bindings/pinctrl/sun4i-a10.h> -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <asm-generic/gpio.h> #endif
@@ -141,7 +141,7 @@ struct emac_eth_dev { struct clk ephy_clk; struct reset_ctl tx_rst; struct reset_ctl ephy_rst; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio; #endif }; @@ -695,7 +695,7 @@ err_tx_clk: return ret; }
-#if defined(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) static int sun8i_mdio_reset(struct mii_dev *bus) { struct udevice *dev = bus->priv; @@ -742,7 +742,7 @@ static int sun8i_mdio_init(const char *name, struct udevice *priv) bus->write = sun8i_mdio_write; snprintf(bus->name, sizeof(bus->name), name); bus->priv = (void *)priv; -#if defined(CONFIG_DM_GPIO) +#if CONFIG_IS_ENABLED(DM_GPIO) bus->reset = sun8i_mdio_reset; #endif
@@ -904,7 +904,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) const fdt32_t *reg; int node = dev_of_offset(dev); int offset = 0; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) int reset_flags = GPIOD_IS_OUT; #endif int ret; @@ -998,7 +998,7 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct udevice *dev) printf("%s: Invalid RX delay value %d\n", __func__, sun8i_pdata->rx_delay_ps);
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), "snps,reset-active-low")) reset_flags |= GPIOD_ACTIVE_LOW; diff --git a/drivers/pci/pci-aardvark.c b/drivers/pci/pci-aardvark.c index 864ac16f572..aa0b4bc8456 100644 --- a/drivers/pci/pci-aardvark.c +++ b/drivers/pci/pci-aardvark.c @@ -610,7 +610,7 @@ static int pcie_advk_probe(struct udevice *dev) { struct pcie_advk *pcie = dev_get_priv(dev);
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio;
gpio_request_by_name(dev, "reset-gpio", 0, &reset_gpio, @@ -636,7 +636,7 @@ static int pcie_advk_probe(struct udevice *dev) } #else dev_dbg(pcie->dev, "PCIE Reset on GPIO support is missing\n"); -#endif /* CONFIG_DM_GPIO */ +#endif /* DM_GPIO */
pcie->first_busno = dev->seq; pcie->dev = pci_get_controller(dev); diff --git a/drivers/pci/pcie_dw_mvebu.c b/drivers/pci/pcie_dw_mvebu.c index 95fb41966fd..693591e3750 100644 --- a/drivers/pci/pcie_dw_mvebu.c +++ b/drivers/pci/pcie_dw_mvebu.c @@ -476,7 +476,7 @@ static int pcie_dw_mvebu_probe(struct udevice *dev) struct pcie_dw_mvebu *pcie = dev_get_priv(dev); struct udevice *ctlr = pci_get_controller(dev); struct pci_controller *hose = dev_get_uclass_priv(ctlr); -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc reset_gpio;
gpio_request_by_name(dev, "marvell,reset-gpio", 0, &reset_gpio, @@ -496,7 +496,7 @@ static int pcie_dw_mvebu_probe(struct udevice *dev) } #else debug("PCIE Reset on GPIO support is missing\n"); -#endif /* CONFIG_DM_GPIO */ +#endif /* DM_GPIO */
pcie->first_busno = dev->seq;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index cf4de9ee1aa..f076e92a93c 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -17,7 +17,7 @@ #ifdef CONFIG_DM_SPI #include <asm/arch/at91_spi.h> #endif -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) #include <asm/gpio.h> #endif
@@ -228,7 +228,7 @@ struct atmel_spi_priv { unsigned int freq; /* Default frequency */ unsigned int mode; ulong bus_clk_rate; -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct gpio_desc cs_gpios[MAX_CS_COUNT]; #endif }; @@ -285,7 +285,7 @@ static int atmel_spi_release_bus(struct udevice *dev)
static void atmel_spi_cs_activate(struct udevice *dev) { -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct udevice *bus = dev_get_parent(dev); struct atmel_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); @@ -300,7 +300,7 @@ static void atmel_spi_cs_activate(struct udevice *dev)
static void atmel_spi_cs_deactivate(struct udevice *dev) { -#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct udevice *bus = dev_get_parent(dev); struct atmel_spi_priv *priv = dev_get_priv(bus); struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); @@ -468,7 +468,7 @@ static int atmel_spi_probe(struct udevice *bus)
bus_plat->regs = (struct at91_spi *)devfdt_get_addr(bus);
-#ifdef CONFIG_DM_GPIO +#if CONFIG_IS_ENABLED(DM_GPIO) struct atmel_spi_priv *priv = dev_get_priv(bus); int i;
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c index 7d58cfae55e..1543573b34a 100644 --- a/drivers/spi/designware_spi.c +++ b/drivers/spi/designware_spi.c @@ -126,7 +126,7 @@ static inline void dw_write(struct dw_spi_priv *priv, u32 offset, u32 val)
static int request_gpio_cs(struct udevice *bus) { -#if defined(CONFIG_DM_GPIO) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(DM_GPIO) && !defined(CONFIG_SPL_BUILD) struct dw_spi_priv *priv = dev_get_priv(bus); int ret;
@@ -373,7 +373,7 @@ static int poll_transfer(struct dw_spi_priv *priv) */ __weak void external_cs_manage(struct udevice *dev, bool on) { -#if defined(CONFIG_DM_GPIO) && !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(DM_GPIO) && !defined(CONFIG_SPL_BUILD) struct dw_spi_priv *priv = dev_get_priv(dev->parent);
if (!dm_gpio_is_valid(&priv->cs_gpio)) diff --git a/drivers/tpm/tpm2_tis_spi.c b/drivers/tpm/tpm2_tis_spi.c index 3d105fddba1..713111f6c3e 100644 --- a/drivers/tpm/tpm2_tis_spi.c +++ b/drivers/tpm/tpm2_tis_spi.c @@ -587,7 +587,7 @@ static int tpm_tis_spi_probe(struct udevice *dev) /* Use the TPM v2 stack */ priv->version = TPM_V2;
- if (IS_ENABLED(CONFIG_DM_GPIO)) { + if (CONFIG_IS_ENABLED(DM_GPIO)) { struct gpio_desc reset_gpio;
ret = gpio_request_by_name(dev, "gpio-reset", 0, diff --git a/include/config_uncmd_spl.h b/include/config_uncmd_spl.h index c2f9735ce79..31da6215b3a 100644 --- a/include/config_uncmd_spl.h +++ b/include/config_uncmd_spl.h @@ -12,7 +12,6 @@
#ifndef CONFIG_SPL_DM #undef CONFIG_DM_SERIAL -#undef CONFIG_DM_GPIO #undef CONFIG_DM_I2C #undef CONFIG_DM_SPI #endif diff --git a/include/configs/at91-sama5_common.h b/include/configs/at91-sama5_common.h index 61312773671..acd9e1ed62b 100644 --- a/include/configs/at91-sama5_common.h +++ b/include/configs/at91-sama5_common.h @@ -9,6 +9,8 @@ #ifndef __AT91_SAMA5_COMMON_H #define __AT91_SAMA5_COMMON_H
+#include <linux/kconfig.h> + /* ARM asynchronous clock */ #define CONFIG_SYS_AT91_SLOW_CLOCK 32768 #define CONFIG_SYS_AT91_MAIN_CLOCK 12000000 /* from 12 MHz crystal */ @@ -18,11 +20,10 @@ #endif
/* general purpose I/O */ -#ifndef CONFIG_DM_GPIO +#if !CONFIG_IS_ENABLED(DM_GPIO) #define CONFIG_AT91_GPIO #endif
- /* * BOOTP options */ diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h index a27627e7219..48433f4ff8a 100644 --- a/include/configs/gw_ventana.h +++ b/include/configs/gw_ventana.h @@ -36,7 +36,6 @@
/* Driver Model */ #ifndef CONFIG_SPL_BUILD -#define CONFIG_DM_GPIO #define CONFIG_DM_THERMAL #endif
diff --git a/include/configs/mx6ul_14x14_evk.h b/include/configs/mx6ul_14x14_evk.h index 87f88693c5a..0faad0a4919 100644 --- a/include/configs/mx6ul_14x14_evk.h +++ b/include/configs/mx6ul_14x14_evk.h @@ -44,6 +44,7 @@ #define CONFIG_SYS_I2C_SPEED 100000 #endif
+/* Note: This is incorrect and should move to Kconfig / defconfig */ #ifdef CONFIG_DM_GPIO #define CONFIG_DM_74X164 #endif diff --git a/scripts/Makefile.uncmd_spl b/scripts/Makefile.uncmd_spl index ba267d9ac6e..6ea097d36dd 100644 --- a/scripts/Makefile.uncmd_spl +++ b/scripts/Makefile.uncmd_spl @@ -6,7 +6,6 @@ ifdef CONFIG_SPL_BUILD
ifndef CONFIG_SPL_DM CONFIG_DM_SERIAL= -CONFIG_DM_GPIO= CONFIG_DM_I2C= CONFIG_DM_SPI= CONFIG_DM_SPI_FLASH=

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
At present if CONFIG_SPL_GPIO_SUPPORT is enabled then the GPIO uclass is included in SPL/TPL without any control for boards. Some boards may want to disable this to reduce code size where GPIOs are not needed in SPL or TPL.
Add a new Kconfig option to permit this. Default it to 'y' so that existing boards work correctly.
Change existing uses of CONFIG_DM_GPIO to CONFIG_IS_ENABLED(DM_GPIO) to preserve the current behaviour. Also update the 74x164 GPIO driver since it cannot build with SPL.
This allows us to remove the hacks in config_uncmd_spl.h and Makefile.uncmd_spl (eventually those files should be removed).
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Fix the Kconfig condition to avoid build errors on snow
arch/arm/include/asm/omap_gpio.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-davinci/include/mach/gpio.h | 2 +- arch/arm/mach-omap2/am33xx/board.c | 4 ++-- arch/arm/mach-omap2/omap3/board.c | 2 +- arch/arm/mach-omap2/omap5/hwinit.c | 2 +- board/freescale/imx8qm_mek/imx8qm_mek.c | 2 +- board/freescale/imx8qxp_mek/imx8qxp_mek.c | 2 +- board/gateworks/gw_ventana/Kconfig | 3 +++ board/toradex/apalis-imx8/apalis-imx8.c | 2 +- drivers/gpio/Kconfig | 22 +++++++++++++++++++ drivers/gpio/Makefile | 4 +++- drivers/gpio/at91_gpio.c | 6 ++--- drivers/gpio/atmel_pio4.c | 2 +- drivers/gpio/da8xx_gpio.c | 6 ++--- drivers/gpio/da8xx_gpio.h | 2 +- drivers/gpio/mxc_gpio.c | 4 ++-- drivers/gpio/mxs_gpio.c | 4 ++-- drivers/gpio/omap_gpio.c | 6 ++--- drivers/gpio/sunxi_gpio.c | 8 +++---- drivers/i2c/i2c-uclass.c | 6 ++--- drivers/i2c/muxes/pca954x.c | 4 ++-- drivers/mmc/fsl_esdhc_imx.c | 13 ++++++----- drivers/mmc/omap_hsmmc.c | 2 +- drivers/net/designware.c | 10 ++++----- drivers/net/designware.h | 4 ++-- drivers/net/fec_mxc.c | 6 ++--- drivers/net/fec_mxc.h | 2 +- drivers/net/mvneta.c | 4 ++-- drivers/net/mvpp2.c | 8 +++---- drivers/net/sun8i_emac.c | 12 +++++----- drivers/pci/pci-aardvark.c | 4 ++-- drivers/pci/pcie_dw_mvebu.c | 4 ++-- drivers/spi/atmel_spi.c | 10 ++++----- drivers/spi/designware_spi.c | 4 ++-- drivers/tpm/tpm2_tis_spi.c | 2 +- include/config_uncmd_spl.h | 1 - include/configs/at91-sama5_common.h | 5 +++-- include/configs/gw_ventana.h | 1 - include/configs/mx6ul_14x14_evk.h | 1 + scripts/Makefile.uncmd_spl | 1 - 41 files changed, 109 insertions(+), 82 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 12:45 PM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
At present if CONFIG_SPL_GPIO_SUPPORT is enabled then the GPIO uclass is included in SPL/TPL without any control for boards. Some boards may want to disable this to reduce code size where GPIOs are not needed in SPL or TPL.
Add a new Kconfig option to permit this. Default it to 'y' so that existing boards work correctly.
Change existing uses of CONFIG_DM_GPIO to CONFIG_IS_ENABLED(DM_GPIO) to preserve the current behaviour. Also update the 74x164 GPIO driver since it cannot build with SPL.
This allows us to remove the hacks in config_uncmd_spl.h and Makefile.uncmd_spl (eventually those files should be removed).
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Fix the Kconfig condition to avoid build errors on snow
arch/arm/include/asm/omap_gpio.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-davinci/include/mach/gpio.h | 2 +- arch/arm/mach-omap2/am33xx/board.c | 4 ++-- arch/arm/mach-omap2/omap3/board.c | 2 +- arch/arm/mach-omap2/omap5/hwinit.c | 2 +- board/freescale/imx8qm_mek/imx8qm_mek.c | 2 +- board/freescale/imx8qxp_mek/imx8qxp_mek.c | 2 +- board/gateworks/gw_ventana/Kconfig | 3 +++ board/toradex/apalis-imx8/apalis-imx8.c | 2 +- drivers/gpio/Kconfig | 22 +++++++++++++++++++ drivers/gpio/Makefile | 4 +++- drivers/gpio/at91_gpio.c | 6 ++--- drivers/gpio/atmel_pio4.c | 2 +- drivers/gpio/da8xx_gpio.c | 6 ++--- drivers/gpio/da8xx_gpio.h | 2 +- drivers/gpio/mxc_gpio.c | 4 ++-- drivers/gpio/mxs_gpio.c | 4 ++-- drivers/gpio/omap_gpio.c | 6 ++--- drivers/gpio/sunxi_gpio.c | 8 +++---- drivers/i2c/i2c-uclass.c | 6 ++--- drivers/i2c/muxes/pca954x.c | 4 ++-- drivers/mmc/fsl_esdhc_imx.c | 13 ++++++----- drivers/mmc/omap_hsmmc.c | 2 +- drivers/net/designware.c | 10 ++++----- drivers/net/designware.h | 4 ++-- drivers/net/fec_mxc.c | 6 ++--- drivers/net/fec_mxc.h | 2 +- drivers/net/mvneta.c | 4 ++-- drivers/net/mvpp2.c | 8 +++---- drivers/net/sun8i_emac.c | 12 +++++----- drivers/pci/pci-aardvark.c | 4 ++-- drivers/pci/pcie_dw_mvebu.c | 4 ++-- drivers/spi/atmel_spi.c | 10 ++++----- drivers/spi/designware_spi.c | 4 ++-- drivers/tpm/tpm2_tis_spi.c | 2 +- include/config_uncmd_spl.h | 1 - include/configs/at91-sama5_common.h | 5 +++-- include/configs/gw_ventana.h | 1 - include/configs/mx6ul_14x14_evk.h | 1 + scripts/Makefile.uncmd_spl | 1 - 41 files changed, 109 insertions(+), 82 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

Hi Simon,
On Sat, Nov 2, 2019 at 5:38 PM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 28, 2019 at 12:45 PM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
At present if CONFIG_SPL_GPIO_SUPPORT is enabled then the GPIO uclass is included in SPL/TPL without any control for boards. Some boards may want to disable this to reduce code size where GPIOs are not needed in SPL or TPL.
Add a new Kconfig option to permit this. Default it to 'y' so that existing boards work correctly.
Change existing uses of CONFIG_DM_GPIO to CONFIG_IS_ENABLED(DM_GPIO) to preserve the current behaviour. Also update the 74x164 GPIO driver since it cannot build with SPL.
This allows us to remove the hacks in config_uncmd_spl.h and Makefile.uncmd_spl (eventually those files should be removed).
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- Fix the Kconfig condition to avoid build errors on snow
arch/arm/include/asm/omap_gpio.h | 2 +- arch/arm/mach-at91/include/mach/at91sam9260.h | 2 +- arch/arm/mach-davinci/include/mach/gpio.h | 2 +- arch/arm/mach-omap2/am33xx/board.c | 4 ++-- arch/arm/mach-omap2/omap3/board.c | 2 +- arch/arm/mach-omap2/omap5/hwinit.c | 2 +- board/freescale/imx8qm_mek/imx8qm_mek.c | 2 +- board/freescale/imx8qxp_mek/imx8qxp_mek.c | 2 +- board/gateworks/gw_ventana/Kconfig | 3 +++ board/toradex/apalis-imx8/apalis-imx8.c | 2 +- drivers/gpio/Kconfig | 22 +++++++++++++++++++ drivers/gpio/Makefile | 4 +++- drivers/gpio/at91_gpio.c | 6 ++--- drivers/gpio/atmel_pio4.c | 2 +- drivers/gpio/da8xx_gpio.c | 6 ++--- drivers/gpio/da8xx_gpio.h | 2 +- drivers/gpio/mxc_gpio.c | 4 ++-- drivers/gpio/mxs_gpio.c | 4 ++-- drivers/gpio/omap_gpio.c | 6 ++--- drivers/gpio/sunxi_gpio.c | 8 +++---- drivers/i2c/i2c-uclass.c | 6 ++--- drivers/i2c/muxes/pca954x.c | 4 ++-- drivers/mmc/fsl_esdhc_imx.c | 13 ++++++----- drivers/mmc/omap_hsmmc.c | 2 +- drivers/net/designware.c | 10 ++++----- drivers/net/designware.h | 4 ++-- drivers/net/fec_mxc.c | 6 ++--- drivers/net/fec_mxc.h | 2 +- drivers/net/mvneta.c | 4 ++-- drivers/net/mvpp2.c | 8 +++---- drivers/net/sun8i_emac.c | 12 +++++----- drivers/pci/pci-aardvark.c | 4 ++-- drivers/pci/pcie_dw_mvebu.c | 4 ++-- drivers/spi/atmel_spi.c | 10 ++++----- drivers/spi/designware_spi.c | 4 ++-- drivers/tpm/tpm2_tis_spi.c | 2 +- include/config_uncmd_spl.h | 1 - include/configs/at91-sama5_common.h | 5 +++-- include/configs/gw_ventana.h | 1 - include/configs/mx6ul_14x14_evk.h | 1 + scripts/Makefile.uncmd_spl | 1 - 41 files changed, 109 insertions(+), 82 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!
Unfortunately this patch still breaks one board. See the log below:
The failed build: https://dev.azure.com/bmeng/GitHub/_build/results?buildId=135
arm: + omap35_logic +arm-linux-gnueabi-ld.bfd: u-boot-spl section `.u_boot_list' will not fit in region `.sram' +arm-linux-gnueabi-ld.bfd: region `.sram' overflowed by 844 bytes +make[2]: *** [spl/u-boot-spl] Error 1 +make[1]: *** [spl/u-boot-spl] Error 2 +make: *** [sub-make] Error 2
0 12 1 /34 0:09:42 : omap35_logic
The passed build with this commit reverted: https://dev.azure.com/bmeng/GitHub/_build/results?buildId=136
I will have to drop this patch from the queue.
Regards, Bin

If the offset is -1 this function correct sets up a null ofnode. But if the offset is any other negative number (e.g. an FDT_ERR) then it does the wrong thing.
Fix it.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
include/dm/ofnode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 5c4cbf09986..4282169706c 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -118,7 +118,7 @@ static inline ofnode offset_to_ofnode(int of_offset) if (of_live_active()) node.np = NULL; else - node.of_offset = of_offset; + node.of_offset = of_offset >= 0 ? of_offset : -1;
return node; }

Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
If the offset is -1 this function correct sets up a null ofnode. But if
correctly?
the offset is any other negative number (e.g. an FDT_ERR) then it does the
FDT_ERR is -1. So probably another error number?
wrong thing.
Fix it.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
include/dm/ofnode.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h index 5c4cbf09986..4282169706c 100644 --- a/include/dm/ofnode.h +++ b/include/dm/ofnode.h @@ -118,7 +118,7 @@ static inline ofnode offset_to_ofnode(int of_offset) if (of_live_active()) node.np = NULL; else
node.of_offset = of_offset;
node.of_offset = of_offset >= 0 ? of_offset : -1; return node;
}
Regards, Bin

At present PCI auto-configuration happens in U-Boot both before and after relocation. This is a waste of time and may mess up static addresses used in board_init_f(). Adjust the code to do auto-configuration once, after relocation.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
drivers/pci/pci-uclass.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 896cb6b23a1..e77445cea33 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -983,11 +983,11 @@ static int pci_uclass_post_probe(struct udevice *bus) if (ret) return ret;
-#if CONFIG_IS_ENABLED(PCI_PNP) - ret = pci_auto_config_devices(bus); - if (ret < 0) - return ret; -#endif + if (CONFIG_IS_ENABLED(PCI_PNP) && (gd->flags & GD_FLG_RELOC)) { + ret = pci_auto_config_devices(bus); + if (ret < 0) + return log_msg_ret("pci auto-config", ret); + }
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) /*

Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
At present PCI auto-configuration happens in U-Boot both before and after relocation. This is a waste of time and may mess up static addresses used in board_init_f(). Adjust the code to do auto-configuration once, after relocation.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
drivers/pci/pci-uclass.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 896cb6b23a1..e77445cea33 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -983,11 +983,11 @@ static int pci_uclass_post_probe(struct udevice *bus) if (ret) return ret;
-#if CONFIG_IS_ENABLED(PCI_PNP)
ret = pci_auto_config_devices(bus);
if (ret < 0)
return ret;
-#endif
if (CONFIG_IS_ENABLED(PCI_PNP) && (gd->flags & GD_FLG_RELOC)) {
This breaks boards that use PCI before relocation, eg: PCI UART.
ret = pci_auto_config_devices(bus);
if (ret < 0)
return log_msg_ret("pci auto-config", ret);
}
#if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) /* --
Regards, Bin

Early in boot it is necessary to decode the PCI device/function values for particular peripherals in the device tree or of-platdata. This is needed in TPL where CONFIG_PCI is not defined.
To handle this, move pci_get_devfn() into a file that is built even when CONFIG_PCI is not defined.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Move the function to a common file instead of duplicating it - Update device type to pci_dev_t
Changes in v2: None
arch/x86/include/asm/pci.h | 11 +++++++++++ drivers/core/util.c | 20 ++++++++++++++++++++ drivers/pci/pci-uclass.c | 16 ---------------- include/dm/pci.h | 21 +++++++++++++++++++++ include/pci.h | 12 ++---------- 5 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 include/dm/pci.h
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 2a720735728..66f1515cefa 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -60,6 +60,17 @@ int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value, int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set, enum pci_size_t size);
+/** + * pci_x86_ofplat_get_devfn() - Get the PCI dev/fn from ofplat reg data + * + * @reg: reg value from dt-platdata.c array (first member) + * @return device/function for that device + */ +static inline pci_dev_t pci_x86_ofplat_get_devfn(u32 reg) +{ + return reg & 0xff00; +} + /** * Assign IRQ number to a PCI device * diff --git a/drivers/core/util.c b/drivers/core/util.c index 7dc1a2af028..69f83755f05 100644 --- a/drivers/core/util.c +++ b/drivers/core/util.c @@ -4,7 +4,9 @@ */
#include <common.h> +#include <dm/device.h> #include <dm/ofnode.h> +#include <dm/read.h> #include <dm/util.h> #include <linux/libfdt.h> #include <vsprintf.h> @@ -58,3 +60,21 @@ bool dm_ofnode_pre_reloc(ofnode node) #endif } #endif + +#if !CONFIG_IS_ENABLED(OF_PLATDATA) +int pci_get_devfn(struct udevice *dev) +{ + struct fdt_pci_addr addr; + int ret; + + /* Extract the devfn from fdt_pci_addr */ + ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG, + "reg", &addr); + if (ret) { + if (ret != -ENOENT) + return -EINVAL; + } + + return addr.phys_hi & 0xff00; +} +#endif diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index e77445cea33..95d36d91564 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1013,22 +1013,6 @@ static int pci_uclass_post_probe(struct udevice *bus) return 0; }
-int pci_get_devfn(struct udevice *dev) -{ - struct fdt_pci_addr addr; - int ret; - - /* Extract the devfn from fdt_pci_addr */ - ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG, - "reg", &addr); - if (ret) { - if (ret != -ENOENT) - return -EINVAL; - } - - return addr.phys_hi & 0xff00; -} - static int pci_uclass_child_post_bind(struct udevice *dev) { struct pci_child_platdata *pplat; diff --git a/include/dm/pci.h b/include/dm/pci.h new file mode 100644 index 00000000000..6147696d825 --- /dev/null +++ b/include/dm/pci.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2019 Google, Inc + */ + +#ifndef __DM_PCI_H +#define __DM_PCI_H + +struct udevice; + +/** + * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device + * + * Get devfn from fdt_pci_addr of the specified device + * + * @dev: PCI device + * @return devfn in bits 15...8 if found, -ENODEV if not found + */ +int pci_get_devfn(struct udevice *dev); + +#endif diff --git a/include/pci.h b/include/pci.h index ff59ac0e695..083f4ee2e90 100644 --- a/include/pci.h +++ b/include/pci.h @@ -482,6 +482,8 @@
#ifndef __ASSEMBLY__
+#include <dm/pci.h> + #ifdef CONFIG_SYS_PCI_64BIT typedef u64 pci_addr_t; typedef u64 pci_size_t; @@ -1612,16 +1614,6 @@ int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, */ int sandbox_pci_get_client(struct udevice *emul, struct udevice **devp);
-/** - * pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device - * - * Get devfn from fdt_pci_addr of the specified device - * - * @dev: PCI device - * @return devfn in bits 15...8 if found, -ENODEV if not found - */ -int pci_get_devfn(struct udevice *dev); - #endif /* CONFIG_DM_PCI */
/**

Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
Early in boot it is necessary to decode the PCI device/function values for particular peripherals in the device tree or of-platdata. This is needed in TPL where CONFIG_PCI is not defined.
To handle this, move pci_get_devfn() into a file that is built even when CONFIG_PCI is not defined.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Move the function to a common file instead of duplicating it
- Update device type to pci_dev_t
Changes in v2: None
arch/x86/include/asm/pci.h | 11 +++++++++++ drivers/core/util.c | 20 ++++++++++++++++++++ drivers/pci/pci-uclass.c | 16 ---------------- include/dm/pci.h | 21 +++++++++++++++++++++ include/pci.h | 12 ++---------- 5 files changed, 54 insertions(+), 26 deletions(-) create mode 100644 include/dm/pci.h
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h index 2a720735728..66f1515cefa 100644 --- a/arch/x86/include/asm/pci.h +++ b/arch/x86/include/asm/pci.h @@ -60,6 +60,17 @@ int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value, int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set, enum pci_size_t size);
+/**
- pci_x86_ofplat_get_devfn() - Get the PCI dev/fn from ofplat reg data
- @reg: reg value from dt-platdata.c array (first member)
- @return device/function for that device
- */
+static inline pci_dev_t pci_x86_ofplat_get_devfn(u32 reg) +{
return reg & 0xff00;
+}
What is this function for?
/**
- Assign IRQ number to a PCI device
diff --git a/drivers/core/util.c b/drivers/core/util.c index 7dc1a2af028..69f83755f05 100644 --- a/drivers/core/util.c +++ b/drivers/core/util.c @@ -4,7 +4,9 @@ */
#include <common.h> +#include <dm/device.h> #include <dm/ofnode.h> +#include <dm/read.h> #include <dm/util.h> #include <linux/libfdt.h> #include <vsprintf.h> @@ -58,3 +60,21 @@ bool dm_ofnode_pre_reloc(ofnode node) #endif } #endif
+#if !CONFIG_IS_ENABLED(OF_PLATDATA) +int pci_get_devfn(struct udevice *dev) +{
struct fdt_pci_addr addr;
int ret;
/* Extract the devfn from fdt_pci_addr */
ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
"reg", &addr);
if (ret) {
if (ret != -ENOENT)
return -EINVAL;
}
return addr.phys_hi & 0xff00;
+} +#endif diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index e77445cea33..95d36d91564 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1013,22 +1013,6 @@ static int pci_uclass_post_probe(struct udevice *bus) return 0; }
-int pci_get_devfn(struct udevice *dev) -{
struct fdt_pci_addr addr;
int ret;
/* Extract the devfn from fdt_pci_addr */
ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
"reg", &addr);
if (ret) {
if (ret != -ENOENT)
return -EINVAL;
}
return addr.phys_hi & 0xff00;
-}
static int pci_uclass_child_post_bind(struct udevice *dev) { struct pci_child_platdata *pplat; diff --git a/include/dm/pci.h b/include/dm/pci.h new file mode 100644 index 00000000000..6147696d825 --- /dev/null +++ b/include/dm/pci.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (c) 2019 Google, Inc
- */
+#ifndef __DM_PCI_H +#define __DM_PCI_H
+struct udevice;
+/**
- pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device
- Get devfn from fdt_pci_addr of the specified device
- @dev: PCI device
- @return devfn in bits 15...8 if found, -ENODEV if not found
- */
+int pci_get_devfn(struct udevice *dev);
+#endif diff --git a/include/pci.h b/include/pci.h index ff59ac0e695..083f4ee2e90 100644 --- a/include/pci.h +++ b/include/pci.h @@ -482,6 +482,8 @@
#ifndef __ASSEMBLY__
+#include <dm/pci.h>
#ifdef CONFIG_SYS_PCI_64BIT typedef u64 pci_addr_t; typedef u64 pci_size_t; @@ -1612,16 +1614,6 @@ int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn, */ int sandbox_pci_get_client(struct udevice *emul, struct udevice **devp);
-/**
- pci_get_devfn() - Extract the devfn from fdt_pci_addr of the device
- Get devfn from fdt_pci_addr of the specified device
- @dev: PCI device
- @return devfn in bits 15...8 if found, -ENODEV if not found
- */
-int pci_get_devfn(struct udevice *dev);
#endif /* CONFIG_DM_PCI */
/**
Regards, Bin

These functions are used by code outside the network support, so move them to lib/ to be more accessible.
Fix up a few code-style nits while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
lib/Makefile | 2 +- lib/net_utils.c | 48 ++++++++++++++++++++++++++++++++++++++++ net/Makefile | 1 - net/checksum.c | 59 ------------------------------------------------- 4 files changed, 49 insertions(+), 61 deletions(-) delete mode 100644 net/checksum.c
diff --git a/lib/Makefile b/lib/Makefile index 0c89b4896fe..505527d58aa 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -76,7 +76,7 @@ endif ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o -obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o +obj-y += net_utils.o endif obj-$(CONFIG_ADDR_MAP) += addr_map.o obj-y += qsort.o diff --git a/lib/net_utils.c b/lib/net_utils.c index 9fb9d4a4b05..252290210f1 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -41,3 +41,51 @@ struct in_addr string_to_ip(const char *s) addr.s_addr = htonl(addr.s_addr); return addr; } + +uint compute_ip_checksum(const void *vptr, uint nbytes) +{ + int sum, oddbyte; + const unsigned short *ptr = vptr; + + sum = 0; + while (nbytes > 1) { + sum += *ptr++; + nbytes -= 2; + } + if (nbytes == 1) { + oddbyte = 0; + ((u8 *)&oddbyte)[0] = *(u8 *)ptr; + ((u8 *)&oddbyte)[1] = 0; + sum += oddbyte; + } + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + sum = ~sum & 0xffff; + + return sum; +} + +uint add_ip_checksums(uint offset, uint sum, uint new) +{ + ulong checksum; + + sum = ~sum & 0xffff; + new = ~new & 0xffff; + if (offset & 1) { + /* + * byte-swap the sum if it came from an odd offset; since the + * computation is endian-independent this works. + */ + new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); + } + checksum = sum + new; + if (checksum > 0xffff) + checksum -= 0xffff; + + return (~checksum) & 0xffff; +} + +int ip_checksum_ok(const void *addr, uint nbytes) +{ + return !(compute_ip_checksum(addr, nbytes) & 0xfffe); +} diff --git a/net/Makefile b/net/Makefile index 2a700c8401c..fef71b940a0 100644 --- a/net/Makefile +++ b/net/Makefile @@ -5,7 +5,6 @@
#ccflags-y += -DDEBUG
-obj-y += checksum.o obj-$(CONFIG_NET) += arp.o obj-$(CONFIG_CMD_BOOTP) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o diff --git a/net/checksum.c b/net/checksum.c deleted file mode 100644 index 16ef4163567..00000000000 --- a/net/checksum.c +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/* - * This file was originally taken from the FreeBSD project. - * - * Copyright (c) 2001 Charles Mott cm@linktel.net - * Copyright (c) 2008 coresystems GmbH - * All rights reserved. - */ - -#include <common.h> -#include <net.h> - -unsigned compute_ip_checksum(const void *vptr, unsigned nbytes) -{ - int sum, oddbyte; - const unsigned short *ptr = vptr; - - sum = 0; - while (nbytes > 1) { - sum += *ptr++; - nbytes -= 2; - } - if (nbytes == 1) { - oddbyte = 0; - ((u8 *)&oddbyte)[0] = *(u8 *)ptr; - ((u8 *)&oddbyte)[1] = 0; - sum += oddbyte; - } - sum = (sum >> 16) + (sum & 0xffff); - sum += (sum >> 16); - sum = ~sum & 0xffff; - - return sum; -} - -unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new) -{ - unsigned long checksum; - - sum = ~sum & 0xffff; - new = ~new & 0xffff; - if (offset & 1) { - /* - * byte-swap the sum if it came from an odd offset; since the - * computation is endian independant this works. - */ - new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00); - } - checksum = sum + new; - if (checksum > 0xffff) - checksum -= 0xffff; - - return (~checksum) & 0xffff; -} - -int ip_checksum_ok(const void *addr, unsigned nbytes) -{ - return !(compute_ip_checksum(addr, nbytes) & 0xfffe); -}

Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
These functions are used by code outside the network support, so move them to lib/ to be more accessible.
Fix up a few code-style nits while we are here.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
lib/Makefile | 2 +- lib/net_utils.c | 48 ++++++++++++++++++++++++++++++++++++++++ net/Makefile | 1 - net/checksum.c | 59 ------------------------------------------------- 4 files changed, 49 insertions(+), 61 deletions(-) delete mode 100644 net/checksum.c
diff --git a/lib/Makefile b/lib/Makefile index 0c89b4896fe..505527d58aa 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -76,7 +76,7 @@ endif ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_YMODEM_SUPPORT) += crc16.o obj-$(CONFIG_$(SPL_TPL_)HASH_SUPPORT) += crc16.o -obj-$(CONFIG_SPL_NET_SUPPORT) += net_utils.o +obj-y += net_utils.o endif obj-$(CONFIG_ADDR_MAP) += addr_map.o obj-y += qsort.o diff --git a/lib/net_utils.c b/lib/net_utils.c index 9fb9d4a4b05..252290210f1 100644 --- a/lib/net_utils.c +++ b/lib/net_utils.c @@ -41,3 +41,51 @@ struct in_addr string_to_ip(const char *s) addr.s_addr = htonl(addr.s_addr); return addr; }
+uint compute_ip_checksum(const void *vptr, uint nbytes) +{
int sum, oddbyte;
const unsigned short *ptr = vptr;
sum = 0;
while (nbytes > 1) {
sum += *ptr++;
nbytes -= 2;
}
if (nbytes == 1) {
oddbyte = 0;
((u8 *)&oddbyte)[0] = *(u8 *)ptr;
((u8 *)&oddbyte)[1] = 0;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
sum = ~sum & 0xffff;
return sum;
+}
+uint add_ip_checksums(uint offset, uint sum, uint new) +{
ulong checksum;
sum = ~sum & 0xffff;
new = ~new & 0xffff;
if (offset & 1) {
/*
* byte-swap the sum if it came from an odd offset; since the
* computation is endian-independent this works.
*/
new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
}
checksum = sum + new;
if (checksum > 0xffff)
checksum -= 0xffff;
return (~checksum) & 0xffff;
+}
+int ip_checksum_ok(const void *addr, uint nbytes) +{
return !(compute_ip_checksum(addr, nbytes) & 0xfffe);
+} diff --git a/net/Makefile b/net/Makefile index 2a700c8401c..fef71b940a0 100644 --- a/net/Makefile +++ b/net/Makefile @@ -5,7 +5,6 @@
#ccflags-y += -DDEBUG
-obj-y += checksum.o
So I don't get it. checksum.o is built unconditionally here, why do we move it to another file?
obj-$(CONFIG_NET) += arp.o obj-$(CONFIG_CMD_BOOTP) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o diff --git a/net/checksum.c b/net/checksum.c deleted file mode 100644 index 16ef4163567..00000000000 --- a/net/checksum.c +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-License-Identifier: BSD-2-Clause -/*
- This file was originally taken from the FreeBSD project.
- Copyright (c) 2001 Charles Mott cm@linktel.net
- Copyright (c) 2008 coresystems GmbH
- All rights reserved.
- */
-#include <common.h> -#include <net.h>
-unsigned compute_ip_checksum(const void *vptr, unsigned nbytes) -{
int sum, oddbyte;
const unsigned short *ptr = vptr;
sum = 0;
while (nbytes > 1) {
sum += *ptr++;
nbytes -= 2;
}
if (nbytes == 1) {
oddbyte = 0;
((u8 *)&oddbyte)[0] = *(u8 *)ptr;
((u8 *)&oddbyte)[1] = 0;
sum += oddbyte;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
sum = ~sum & 0xffff;
return sum;
-}
-unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new) -{
unsigned long checksum;
sum = ~sum & 0xffff;
new = ~new & 0xffff;
if (offset & 1) {
/*
* byte-swap the sum if it came from an odd offset; since the
* computation is endian independant this works.
*/
new = ((new >> 8) & 0xff) | ((new << 8) & 0xff00);
}
checksum = sum + new;
if (checksum > 0xffff)
checksum -= 0xffff;
return (~checksum) & 0xffff;
-}
-int ip_checksum_ok(const void *addr, unsigned nbytes) -{
return !(compute_ip_checksum(addr, nbytes) & 0xfffe);
-}
Regards, Bin

This is hacked into the driver at present. It seems better to have it as a separate driver that uses the base driver. Create a new file and put the X86 code into it.
Actually the Baytrail settings should really come from the device tree.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
drivers/i2c/Makefile | 3 + drivers/i2c/designware_i2c.c | 104 ++++++----------------------------- drivers/i2c/designware_i2c.h | 35 ++++++++++++ drivers/i2c/dw_i2c_pci.c | 78 ++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 88 deletions(-) create mode 100644 drivers/i2c/dw_i2c_pci.c
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index c2f75d87559..a7fa38b8dcf 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -14,6 +14,9 @@ obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o +ifdef CONFIG_DM_PCI +obj-$(CONFIG_SYS_I2C_DW) += dw_i2c_pci.o +endif obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o obj-$(CONFIG_SYS_I2C_INTEL) += intel_i2c.o diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 6daa90e7442..54e4a70c74c 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -13,34 +13,6 @@ #include <asm/io.h> #include "designware_i2c.h"
-struct dw_scl_sda_cfg { - u32 ss_hcnt; - u32 fs_hcnt; - u32 ss_lcnt; - u32 fs_lcnt; - u32 sda_hold; -}; - -#ifdef CONFIG_X86 -/* BayTrail HCNT/LCNT/SDA hold time */ -static struct dw_scl_sda_cfg byt_config = { - .ss_hcnt = 0x200, - .fs_hcnt = 0x55, - .ss_lcnt = 0x200, - .fs_lcnt = 0x99, - .sda_hold = 0x6, -}; -#endif - -struct dw_i2c { - struct i2c_regs *regs; - struct dw_scl_sda_cfg *scl_sda_cfg; - struct reset_ctl_bulk resets; -#if CONFIG_IS_ENABLED(CLK) - struct clk clk; -#endif -}; - #ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable) { @@ -90,7 +62,8 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, unsigned int ena; int i2c_spd;
- if (speed >= I2C_MAX_SPEED) + if (speed >= I2C_MAX_SPEED && + (!scl_sda_cfg || scl_sda_cfg->has_max_speed)) i2c_spd = IC_SPEED_MODE_MAX; else if (speed >= I2C_FAST_SPEED) i2c_spd = IC_SPEED_MODE_FAST; @@ -106,7 +79,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK));
switch (i2c_spd) { -#ifndef CONFIG_X86 /* No High-speed for BayTrail yet */ case IC_SPEED_MODE_MAX: cntl |= IC_CON_SPD_SS; if (scl_sda_cfg) { @@ -119,7 +91,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, writel(hcnt, &i2c_base->ic_hs_scl_hcnt); writel(lcnt, &i2c_base->ic_hs_scl_lcnt); break; -#endif
case IC_SPEED_MODE_STANDARD: cntl |= IC_CON_SPD_SS; @@ -565,24 +536,20 @@ static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr, return ret; }
-static int designware_i2c_probe(struct udevice *bus) +static int designware_i2c_ofdata_to_platdata(struct udevice *bus) { struct dw_i2c *priv = dev_get_priv(bus); - int ret;
- if (device_is_on_pci_bus(bus)) { -#ifdef CONFIG_DM_PCI - /* Save base address from PCI BAR */ - priv->regs = (struct i2c_regs *) - dm_pci_map_bar(bus, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); -#ifdef CONFIG_X86 - /* Use BayTrail specific timing values */ - priv->scl_sda_cfg = &byt_config; -#endif -#endif - } else { - priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus); - } + printf("bad\n"); + priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus); + + return 0; +} + +int designware_i2c_probe(struct udevice *bus) +{ + struct dw_i2c *priv = dev_get_priv(bus); + int ret;
ret = reset_get_bulk(bus, &priv->resets); if (ret) @@ -606,7 +573,7 @@ static int designware_i2c_probe(struct udevice *bus) return __dw_i2c_init(priv->regs, 0, 0); }
-static int designware_i2c_remove(struct udevice *dev) +int designware_i2c_remove(struct udevice *dev) { struct dw_i2c *priv = dev_get_priv(dev);
@@ -618,30 +585,7 @@ static int designware_i2c_remove(struct udevice *dev) return reset_release_bulk(&priv->resets); }
-static int designware_i2c_bind(struct udevice *dev) -{ - static int num_cards; - char name[20]; - - /* Create a unique device name for PCI type devices */ - if (device_is_on_pci_bus(dev)) { - /* - * ToDo: - * Setting req_seq in the driver is probably not recommended. - * But without a DT alias the number is not configured. And - * using this driver is impossible for PCIe I2C devices. - * This can be removed, once a better (correct) way for this - * is found and implemented. - */ - dev->req_seq = num_cards; - sprintf(name, "i2c_designware#%u", num_cards++); - device_set_name(dev, name); - } - - return 0; -} - -static const struct dm_i2c_ops designware_i2c_ops = { +const struct dm_i2c_ops designware_i2c_ops = { .xfer = designware_i2c_xfer, .probe_chip = designware_i2c_probe_chip, .set_bus_speed = designware_i2c_set_bus_speed, @@ -656,7 +600,7 @@ U_BOOT_DRIVER(i2c_designware) = { .name = "i2c_designware", .id = UCLASS_I2C, .of_match = designware_i2c_ids, - .bind = designware_i2c_bind, + .ofdata_to_platdata = designware_i2c_ofdata_to_platdata, .probe = designware_i2c_probe, .priv_auto_alloc_size = sizeof(struct dw_i2c), .remove = designware_i2c_remove, @@ -664,20 +608,4 @@ U_BOOT_DRIVER(i2c_designware) = { .ops = &designware_i2c_ops, };
-#ifdef CONFIG_X86 -static struct pci_device_id designware_pci_supported[] = { - /* Intel BayTrail has 7 I2C controller located on the PCI bus */ - { PCI_VDEVICE(INTEL, 0x0f41) }, - { PCI_VDEVICE(INTEL, 0x0f42) }, - { PCI_VDEVICE(INTEL, 0x0f43) }, - { PCI_VDEVICE(INTEL, 0x0f44) }, - { PCI_VDEVICE(INTEL, 0x0f45) }, - { PCI_VDEVICE(INTEL, 0x0f46) }, - { PCI_VDEVICE(INTEL, 0x0f47) }, - {}, -}; - -U_BOOT_PCI_DEVICE(i2c_designware, designware_pci_supported); -#endif - #endif /* CONFIG_DM_I2C */ diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h index 20ff20d9b83..48766d08067 100644 --- a/drivers/i2c/designware_i2c.h +++ b/drivers/i2c/designware_i2c.h @@ -7,6 +7,8 @@ #ifndef __DW_I2C_H_ #define __DW_I2C_H_
+#include <reset.h> + struct i2c_regs { u32 ic_con; /* 0x00 */ u32 ic_tar; /* 0x04 */ @@ -131,4 +133,37 @@ struct i2c_regs { #define I2C_FAST_SPEED 400000 #define I2C_STANDARD_SPEED 100000
+/** + * struct dw_scl_sda_cfg - I2C timing configuration + * + * @has_max_speed: Support maximum speed (1Mbps) + * @ss_hcnt: Standard speed high time in ns + * @fs_hcnt: Fast speed high time in ns + * @ss_lcnt: Standard speed low time in ns + * @fs_lcnt: Fast speed low time in ns + * @sda_hold: SDA hold time + */ +struct dw_scl_sda_cfg { + bool has_max_speed; + u32 ss_hcnt; + u32 fs_hcnt; + u32 ss_lcnt; + u32 fs_lcnt; + u32 sda_hold; +}; + +struct dw_i2c { + struct i2c_regs *regs; + struct dw_scl_sda_cfg *scl_sda_cfg; + struct reset_ctl_bulk resets; +#if CONFIG_IS_ENABLED(CLK) + struct clk clk; +#endif +}; + +extern const struct dm_i2c_ops designware_i2c_ops; + +int designware_i2c_probe(struct udevice *bus); +int designware_i2c_remove(struct udevice *dev); + #endif /* __DW_I2C_H_ */ diff --git a/drivers/i2c/dw_i2c_pci.c b/drivers/i2c/dw_i2c_pci.c new file mode 100644 index 00000000000..065c0aa5994 --- /dev/null +++ b/drivers/i2c/dw_i2c_pci.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * Copyright 2019 Google Inc + */ + +#include <dm.h> +#include "designware_i2c.h" + +/* BayTrail HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg byt_config = { + .ss_hcnt = 0x200, + .fs_hcnt = 0x55, + .ss_lcnt = 0x200, + .fs_lcnt = 0x99, + .sda_hold = 0x6, +}; + +static int designware_i2c_pci_probe(struct udevice *dev) +{ + struct dw_i2c *priv = dev_get_priv(dev); + + /* Save base address from PCI BAR */ + priv->regs = (struct i2c_regs *) + dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM); + if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL)) + /* Use BayTrail specific timing values */ + priv->scl_sda_cfg = &byt_config; + + return designware_i2c_probe(dev); +} + +static int designware_i2c_pci_bind(struct udevice *dev) +{ + static int num_cards; + char name[20]; + + /* + * Create a unique device name for PCI type devices + * ToDo: + * Setting req_seq in the driver is probably not recommended. + * But without a DT alias the number is not configured. And + * using this driver is impossible for PCIe I2C devices. + * This can be removed, once a better (correct) way for this + * is found and implemented. + */ + dev->req_seq = num_cards; + sprintf(name, "i2c_designware#%u", num_cards++); + device_set_name(dev, name); + + return 0; +} + +U_BOOT_DRIVER(i2c_designware_pci) = { + .name = "i2c_designware_pci", + .id = UCLASS_I2C, + .bind = designware_i2c_pci_bind, + .probe = designware_i2c_pci_probe, + .priv_auto_alloc_size = sizeof(struct dw_i2c), + .remove = designware_i2c_remove, + .flags = DM_FLAG_OS_PREPARE, + .ops = &designware_i2c_ops, +}; + +static struct pci_device_id designware_pci_supported[] = { + /* Intel BayTrail has 7 I2C controller located on the PCI bus */ + { PCI_VDEVICE(INTEL, 0x0f41) }, + { PCI_VDEVICE(INTEL, 0x0f42) }, + { PCI_VDEVICE(INTEL, 0x0f43) }, + { PCI_VDEVICE(INTEL, 0x0f44) }, + { PCI_VDEVICE(INTEL, 0x0f45) }, + { PCI_VDEVICE(INTEL, 0x0f46) }, + { PCI_VDEVICE(INTEL, 0x0f47) }, + {}, +}; + +U_BOOT_PCI_DEVICE(i2c_designware_pci, designware_pci_supported);

Hello Simon,
Am 21.10.2019 um 05:31 schrieb Simon Glass:
This is hacked into the driver at present. It seems better to have it as a separate driver that uses the base driver. Create a new file and put the X86 code into it.
Actually the Baytrail settings should really come from the device tree.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
drivers/i2c/Makefile | 3 + drivers/i2c/designware_i2c.c | 104 ++++++----------------------------- drivers/i2c/designware_i2c.h | 35 ++++++++++++ drivers/i2c/dw_i2c_pci.c | 78 ++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 88 deletions(-) create mode 100644 drivers/i2c/dw_i2c_pci.c
Reviewed-by: Heiko Schocher hs@denx.de
Thanks!
bye, Heiko

+Stefan
Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This is hacked into the driver at present. It seems better to have it as a separate driver that uses the base driver. Create a new file and put the X86 code into it.
Actually the Baytrail settings should really come from the device tree.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
drivers/i2c/Makefile | 3 + drivers/i2c/designware_i2c.c | 104 ++++++----------------------------- drivers/i2c/designware_i2c.h | 35 ++++++++++++ drivers/i2c/dw_i2c_pci.c | 78 ++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 88 deletions(-) create mode 100644 drivers/i2c/dw_i2c_pci.c
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index c2f75d87559..a7fa38b8dcf 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -14,6 +14,9 @@ obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o +ifdef CONFIG_DM_PCI +obj-$(CONFIG_SYS_I2C_DW) += dw_i2c_pci.o
nits: designware_i2c_pci.o for consistency?
+endif obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o obj-$(CONFIG_SYS_I2C_INTEL) += intel_i2c.o diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 6daa90e7442..54e4a70c74c 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -13,34 +13,6 @@ #include <asm/io.h> #include "designware_i2c.h"
-struct dw_scl_sda_cfg {
u32 ss_hcnt;
u32 fs_hcnt;
u32 ss_lcnt;
u32 fs_lcnt;
u32 sda_hold;
-};
-#ifdef CONFIG_X86 -/* BayTrail HCNT/LCNT/SDA hold time */ -static struct dw_scl_sda_cfg byt_config = {
.ss_hcnt = 0x200,
.fs_hcnt = 0x55,
.ss_lcnt = 0x200,
.fs_lcnt = 0x99,
.sda_hold = 0x6,
-}; -#endif
-struct dw_i2c {
struct i2c_regs *regs;
struct dw_scl_sda_cfg *scl_sda_cfg;
struct reset_ctl_bulk resets;
-#if CONFIG_IS_ENABLED(CLK)
struct clk clk;
-#endif -};
#ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable) { @@ -90,7 +62,8 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, unsigned int ena; int i2c_spd;
if (speed >= I2C_MAX_SPEED)
if (speed >= I2C_MAX_SPEED &&
(!scl_sda_cfg || scl_sda_cfg->has_max_speed))
I think the logic should be && not ||
And I don't see scl_sda_cfg->has_max_speed in the original driver. Is this new functionality?
i2c_spd = IC_SPEED_MODE_MAX; else if (speed >= I2C_FAST_SPEED) i2c_spd = IC_SPEED_MODE_FAST;
@@ -106,7 +79,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK));
switch (i2c_spd) {
-#ifndef CONFIG_X86 /* No High-speed for BayTrail yet */ case IC_SPEED_MODE_MAX: cntl |= IC_CON_SPD_SS; if (scl_sda_cfg) { @@ -119,7 +91,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, writel(hcnt, &i2c_base->ic_hs_scl_hcnt); writel(lcnt, &i2c_base->ic_hs_scl_lcnt); break; -#endif
case IC_SPEED_MODE_STANDARD: cntl |= IC_CON_SPD_SS;
@@ -565,24 +536,20 @@ static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr, return ret; }
-static int designware_i2c_probe(struct udevice *bus) +static int designware_i2c_ofdata_to_platdata(struct udevice *bus) { struct dw_i2c *priv = dev_get_priv(bus);
int ret;
if (device_is_on_pci_bus(bus)) {
-#ifdef CONFIG_DM_PCI
/* Save base address from PCI BAR */
priv->regs = (struct i2c_regs *)
dm_pci_map_bar(bus, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-#ifdef CONFIG_X86
/* Use BayTrail specific timing values */
priv->scl_sda_cfg = &byt_config;
-#endif -#endif
} else {
priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
}
printf("bad\n");
What's this?
priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
return 0;
+}
+int designware_i2c_probe(struct udevice *bus) +{
struct dw_i2c *priv = dev_get_priv(bus);
int ret; ret = reset_get_bulk(bus, &priv->resets); if (ret)
@@ -606,7 +573,7 @@ static int designware_i2c_probe(struct udevice *bus) return __dw_i2c_init(priv->regs, 0, 0); }
-static int designware_i2c_remove(struct udevice *dev) +int designware_i2c_remove(struct udevice *dev) { struct dw_i2c *priv = dev_get_priv(dev);
@@ -618,30 +585,7 @@ static int designware_i2c_remove(struct udevice *dev) return reset_release_bulk(&priv->resets); }
-static int designware_i2c_bind(struct udevice *dev) -{
static int num_cards;
char name[20];
/* Create a unique device name for PCI type devices */
if (device_is_on_pci_bus(dev)) {
/*
* ToDo:
* Setting req_seq in the driver is probably not recommended.
* But without a DT alias the number is not configured. And
* using this driver is impossible for PCIe I2C devices.
* This can be removed, once a better (correct) way for this
* is found and implemented.
*/
dev->req_seq = num_cards;
sprintf(name, "i2c_designware#%u", num_cards++);
device_set_name(dev, name);
}
return 0;
-}
-static const struct dm_i2c_ops designware_i2c_ops = { +const struct dm_i2c_ops designware_i2c_ops = { .xfer = designware_i2c_xfer, .probe_chip = designware_i2c_probe_chip, .set_bus_speed = designware_i2c_set_bus_speed, @@ -656,7 +600,7 @@ U_BOOT_DRIVER(i2c_designware) = { .name = "i2c_designware", .id = UCLASS_I2C, .of_match = designware_i2c_ids,
.bind = designware_i2c_bind,
.ofdata_to_platdata = designware_i2c_ofdata_to_platdata, .probe = designware_i2c_probe, .priv_auto_alloc_size = sizeof(struct dw_i2c), .remove = designware_i2c_remove,
@@ -664,20 +608,4 @@ U_BOOT_DRIVER(i2c_designware) = { .ops = &designware_i2c_ops, };
-#ifdef CONFIG_X86 -static struct pci_device_id designware_pci_supported[] = {
/* Intel BayTrail has 7 I2C controller located on the PCI bus */
{ PCI_VDEVICE(INTEL, 0x0f41) },
{ PCI_VDEVICE(INTEL, 0x0f42) },
{ PCI_VDEVICE(INTEL, 0x0f43) },
{ PCI_VDEVICE(INTEL, 0x0f44) },
{ PCI_VDEVICE(INTEL, 0x0f45) },
{ PCI_VDEVICE(INTEL, 0x0f46) },
{ PCI_VDEVICE(INTEL, 0x0f47) },
{},
-};
-U_BOOT_PCI_DEVICE(i2c_designware, designware_pci_supported); -#endif
#endif /* CONFIG_DM_I2C */ diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h index 20ff20d9b83..48766d08067 100644 --- a/drivers/i2c/designware_i2c.h +++ b/drivers/i2c/designware_i2c.h @@ -7,6 +7,8 @@ #ifndef __DW_I2C_H_ #define __DW_I2C_H_
+#include <reset.h>
struct i2c_regs { u32 ic_con; /* 0x00 */ u32 ic_tar; /* 0x04 */ @@ -131,4 +133,37 @@ struct i2c_regs { #define I2C_FAST_SPEED 400000 #define I2C_STANDARD_SPEED 100000
+/**
- struct dw_scl_sda_cfg - I2C timing configuration
- @has_max_speed: Support maximum speed (1Mbps)
- @ss_hcnt: Standard speed high time in ns
- @fs_hcnt: Fast speed high time in ns
- @ss_lcnt: Standard speed low time in ns
- @fs_lcnt: Fast speed low time in ns
- @sda_hold: SDA hold time
- */
+struct dw_scl_sda_cfg {
bool has_max_speed;
u32 ss_hcnt;
u32 fs_hcnt;
u32 ss_lcnt;
u32 fs_lcnt;
u32 sda_hold;
+};
+struct dw_i2c {
struct i2c_regs *regs;
struct dw_scl_sda_cfg *scl_sda_cfg;
struct reset_ctl_bulk resets;
+#if CONFIG_IS_ENABLED(CLK)
struct clk clk;
+#endif +};
+extern const struct dm_i2c_ops designware_i2c_ops;
+int designware_i2c_probe(struct udevice *bus); +int designware_i2c_remove(struct udevice *dev);
#endif /* __DW_I2C_H_ */ diff --git a/drivers/i2c/dw_i2c_pci.c b/drivers/i2c/dw_i2c_pci.c new file mode 100644 index 00000000000..065c0aa5994 --- /dev/null +++ b/drivers/i2c/dw_i2c_pci.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2009
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- Copyright 2019 Google Inc
- */
+#include <dm.h> +#include "designware_i2c.h"
+/* BayTrail HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg byt_config = {
.ss_hcnt = 0x200,
.fs_hcnt = 0x55,
.ss_lcnt = 0x200,
.fs_lcnt = 0x99,
.sda_hold = 0x6,
+};
+static int designware_i2c_pci_probe(struct udevice *dev) +{
struct dw_i2c *priv = dev_get_priv(dev);
/* Save base address from PCI BAR */
priv->regs = (struct i2c_regs *)
dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL))
/* Use BayTrail specific timing values */
priv->scl_sda_cfg = &byt_config;
return designware_i2c_probe(dev);
+}
+static int designware_i2c_pci_bind(struct udevice *dev) +{
static int num_cards;
char name[20];
/*
* Create a unique device name for PCI type devices
* ToDo:
* Setting req_seq in the driver is probably not recommended.
* But without a DT alias the number is not configured. And
* using this driver is impossible for PCIe I2C devices.
* This can be removed, once a better (correct) way for this
* is found and implemented.
*/
dev->req_seq = num_cards;
sprintf(name, "i2c_designware#%u", num_cards++);
device_set_name(dev, name);
return 0;
+}
+U_BOOT_DRIVER(i2c_designware_pci) = {
.name = "i2c_designware_pci",
.id = UCLASS_I2C,
.bind = designware_i2c_pci_bind,
.probe = designware_i2c_pci_probe,
.priv_auto_alloc_size = sizeof(struct dw_i2c),
.remove = designware_i2c_remove,
.flags = DM_FLAG_OS_PREPARE,
.ops = &designware_i2c_ops,
+};
+static struct pci_device_id designware_pci_supported[] = {
/* Intel BayTrail has 7 I2C controller located on the PCI bus */
{ PCI_VDEVICE(INTEL, 0x0f41) },
{ PCI_VDEVICE(INTEL, 0x0f42) },
{ PCI_VDEVICE(INTEL, 0x0f43) },
{ PCI_VDEVICE(INTEL, 0x0f44) },
{ PCI_VDEVICE(INTEL, 0x0f45) },
{ PCI_VDEVICE(INTEL, 0x0f46) },
{ PCI_VDEVICE(INTEL, 0x0f47) },
{},
+};
+U_BOOT_PCI_DEVICE(i2c_designware_pci, designware_pci_supported);
Regards, Bin

On 21.10.19 05:31, Simon Glass wrote:
This is hacked into the driver at present. It seems better to have it as a separate driver that uses the base driver. Create a new file and put the X86 code into it.
Actually the Baytrail settings should really come from the device tree.
Signed-off-by: Simon Glass sjg@chromium.org
Apart from the comments from Bin, I only have one nitpicking comments below...
Changes in v3: None Changes in v2: None
drivers/i2c/Makefile | 3 + drivers/i2c/designware_i2c.c | 104 ++++++----------------------------- drivers/i2c/designware_i2c.h | 35 ++++++++++++ drivers/i2c/dw_i2c_pci.c | 78 ++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 88 deletions(-) create mode 100644 drivers/i2c/dw_i2c_pci.c
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index c2f75d87559..a7fa38b8dcf 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -14,6 +14,9 @@ obj-$(CONFIG_SYS_I2C_AT91) += at91_i2c.o obj-$(CONFIG_SYS_I2C_CADENCE) += i2c-cdns.o obj-$(CONFIG_SYS_I2C_DAVINCI) += davinci_i2c.o obj-$(CONFIG_SYS_I2C_DW) += designware_i2c.o +ifdef CONFIG_DM_PCI +obj-$(CONFIG_SYS_I2C_DW) += dw_i2c_pci.o +endif obj-$(CONFIG_SYS_I2C_FSL) += fsl_i2c.o obj-$(CONFIG_SYS_I2C_IHS) += ihs_i2c.o obj-$(CONFIG_SYS_I2C_INTEL) += intel_i2c.o diff --git a/drivers/i2c/designware_i2c.c b/drivers/i2c/designware_i2c.c index 6daa90e7442..54e4a70c74c 100644 --- a/drivers/i2c/designware_i2c.c +++ b/drivers/i2c/designware_i2c.c @@ -13,34 +13,6 @@ #include <asm/io.h> #include "designware_i2c.h"
-struct dw_scl_sda_cfg {
- u32 ss_hcnt;
- u32 fs_hcnt;
- u32 ss_lcnt;
- u32 fs_lcnt;
- u32 sda_hold;
-};
-#ifdef CONFIG_X86 -/* BayTrail HCNT/LCNT/SDA hold time */ -static struct dw_scl_sda_cfg byt_config = {
- .ss_hcnt = 0x200,
- .fs_hcnt = 0x55,
- .ss_lcnt = 0x200,
- .fs_lcnt = 0x99,
- .sda_hold = 0x6,
-}; -#endif
-struct dw_i2c {
- struct i2c_regs *regs;
- struct dw_scl_sda_cfg *scl_sda_cfg;
- struct reset_ctl_bulk resets;
-#if CONFIG_IS_ENABLED(CLK)
- struct clk clk;
-#endif -};
- #ifdef CONFIG_SYS_I2C_DW_ENABLE_STATUS_UNSUPPORTED static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable) {
@@ -90,7 +62,8 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, unsigned int ena; int i2c_spd;
- if (speed >= I2C_MAX_SPEED)
- if (speed >= I2C_MAX_SPEED &&
i2c_spd = IC_SPEED_MODE_MAX; else if (speed >= I2C_FAST_SPEED) i2c_spd = IC_SPEED_MODE_FAST;(!scl_sda_cfg || scl_sda_cfg->has_max_speed))
@@ -106,7 +79,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, cntl = (readl(&i2c_base->ic_con) & (~IC_CON_SPD_MSK));
switch (i2c_spd) { -#ifndef CONFIG_X86 /* No High-speed for BayTrail yet */ case IC_SPEED_MODE_MAX: cntl |= IC_CON_SPD_SS; if (scl_sda_cfg) { @@ -119,7 +91,6 @@ static unsigned int __dw_i2c_set_bus_speed(struct i2c_regs *i2c_base, writel(hcnt, &i2c_base->ic_hs_scl_hcnt); writel(lcnt, &i2c_base->ic_hs_scl_lcnt); break; -#endif
case IC_SPEED_MODE_STANDARD: cntl |= IC_CON_SPD_SS; @@ -565,24 +536,20 @@ static int designware_i2c_probe_chip(struct udevice *bus, uint chip_addr, return ret; }
-static int designware_i2c_probe(struct udevice *bus) +static int designware_i2c_ofdata_to_platdata(struct udevice *bus) { struct dw_i2c *priv = dev_get_priv(bus);
int ret;
if (device_is_on_pci_bus(bus)) {
-#ifdef CONFIG_DM_PCI
/* Save base address from PCI BAR */
priv->regs = (struct i2c_regs *)
dm_pci_map_bar(bus, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
-#ifdef CONFIG_X86
/* Use BayTrail specific timing values */
priv->scl_sda_cfg = &byt_config;
-#endif -#endif
- } else {
priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
- }
- printf("bad\n");
- priv->regs = (struct i2c_regs *)devfdt_get_addr_ptr(bus);
- return 0;
+}
+int designware_i2c_probe(struct udevice *bus) +{
struct dw_i2c *priv = dev_get_priv(bus);
int ret;
ret = reset_get_bulk(bus, &priv->resets); if (ret)
@@ -606,7 +573,7 @@ static int designware_i2c_probe(struct udevice *bus) return __dw_i2c_init(priv->regs, 0, 0); }
-static int designware_i2c_remove(struct udevice *dev) +int designware_i2c_remove(struct udevice *dev) { struct dw_i2c *priv = dev_get_priv(dev);
@@ -618,30 +585,7 @@ static int designware_i2c_remove(struct udevice *dev) return reset_release_bulk(&priv->resets); }
-static int designware_i2c_bind(struct udevice *dev) -{
- static int num_cards;
- char name[20];
- /* Create a unique device name for PCI type devices */
- if (device_is_on_pci_bus(dev)) {
/*
* ToDo:
* Setting req_seq in the driver is probably not recommended.
* But without a DT alias the number is not configured. And
* using this driver is impossible for PCIe I2C devices.
* This can be removed, once a better (correct) way for this
* is found and implemented.
*/
dev->req_seq = num_cards;
sprintf(name, "i2c_designware#%u", num_cards++);
device_set_name(dev, name);
- }
- return 0;
-}
-static const struct dm_i2c_ops designware_i2c_ops = { +const struct dm_i2c_ops designware_i2c_ops = { .xfer = designware_i2c_xfer, .probe_chip = designware_i2c_probe_chip, .set_bus_speed = designware_i2c_set_bus_speed, @@ -656,7 +600,7 @@ U_BOOT_DRIVER(i2c_designware) = { .name = "i2c_designware", .id = UCLASS_I2C, .of_match = designware_i2c_ids,
- .bind = designware_i2c_bind,
- .ofdata_to_platdata = designware_i2c_ofdata_to_platdata, .probe = designware_i2c_probe, .priv_auto_alloc_size = sizeof(struct dw_i2c), .remove = designware_i2c_remove,
@@ -664,20 +608,4 @@ U_BOOT_DRIVER(i2c_designware) = { .ops = &designware_i2c_ops, };
-#ifdef CONFIG_X86 -static struct pci_device_id designware_pci_supported[] = {
- /* Intel BayTrail has 7 I2C controller located on the PCI bus */
- { PCI_VDEVICE(INTEL, 0x0f41) },
- { PCI_VDEVICE(INTEL, 0x0f42) },
- { PCI_VDEVICE(INTEL, 0x0f43) },
- { PCI_VDEVICE(INTEL, 0x0f44) },
- { PCI_VDEVICE(INTEL, 0x0f45) },
- { PCI_VDEVICE(INTEL, 0x0f46) },
- { PCI_VDEVICE(INTEL, 0x0f47) },
- {},
-};
-U_BOOT_PCI_DEVICE(i2c_designware, designware_pci_supported); -#endif
- #endif /* CONFIG_DM_I2C */
diff --git a/drivers/i2c/designware_i2c.h b/drivers/i2c/designware_i2c.h index 20ff20d9b83..48766d08067 100644 --- a/drivers/i2c/designware_i2c.h +++ b/drivers/i2c/designware_i2c.h @@ -7,6 +7,8 @@ #ifndef __DW_I2C_H_ #define __DW_I2C_H_
+#include <reset.h>
- struct i2c_regs { u32 ic_con; /* 0x00 */ u32 ic_tar; /* 0x04 */
@@ -131,4 +133,37 @@ struct i2c_regs { #define I2C_FAST_SPEED 400000 #define I2C_STANDARD_SPEED 100000
+/**
- struct dw_scl_sda_cfg - I2C timing configuration
- @has_max_speed: Support maximum speed (1Mbps)
- @ss_hcnt: Standard speed high time in ns
- @fs_hcnt: Fast speed high time in ns
- @ss_lcnt: Standard speed low time in ns
- @fs_lcnt: Fast speed low time in ns
- @sda_hold: SDA hold time
- */
+struct dw_scl_sda_cfg {
- bool has_max_speed;
- u32 ss_hcnt;
- u32 fs_hcnt;
- u32 ss_lcnt;
- u32 fs_lcnt;
- u32 sda_hold;
+};
+struct dw_i2c {
- struct i2c_regs *regs;
- struct dw_scl_sda_cfg *scl_sda_cfg;
- struct reset_ctl_bulk resets;
+#if CONFIG_IS_ENABLED(CLK)
- struct clk clk;
+#endif +};
+extern const struct dm_i2c_ops designware_i2c_ops;
+int designware_i2c_probe(struct udevice *bus); +int designware_i2c_remove(struct udevice *dev);
- #endif /* __DW_I2C_H_ */
diff --git a/drivers/i2c/dw_i2c_pci.c b/drivers/i2c/dw_i2c_pci.c new file mode 100644 index 00000000000..065c0aa5994 --- /dev/null +++ b/drivers/i2c/dw_i2c_pci.c @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: GPL-2.0+ +/*
- (C) Copyright 2009
- Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
- Copyright 2019 Google Inc
- */
+#include <dm.h> +#include "designware_i2c.h"
+/* BayTrail HCNT/LCNT/SDA hold time */ +static struct dw_scl_sda_cfg byt_config = {
- .ss_hcnt = 0x200,
- .fs_hcnt = 0x55,
- .ss_lcnt = 0x200,
- .fs_lcnt = 0x99,
- .sda_hold = 0x6,
+};
+static int designware_i2c_pci_probe(struct udevice *dev) +{
- struct dw_i2c *priv = dev_get_priv(dev);
- /* Save base address from PCI BAR */
- priv->regs = (struct i2c_regs *)
dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
- if (IS_ENABLED(CONFIG_INTEL_BAYTRAIL))
/* Use BayTrail specific timing values */
priv->scl_sda_cfg = &byt_config;
- return designware_i2c_probe(dev);
+}
+static int designware_i2c_pci_bind(struct udevice *dev) +{
- static int num_cards;
- char name[20];
- /*
* Create a unique device name for PCI type devices
* ToDo:
* Setting req_seq in the driver is probably not recommended.
* But without a DT alias the number is not configured. And
* using this driver is impossible for PCIe I2C devices.
* This can be removed, once a better (correct) way for this
* is found and implemented.
*/
- dev->req_seq = num_cards;
- sprintf(name, "i2c_designware#%u", num_cards++);
- device_set_name(dev, name);
- return 0;
+}
+U_BOOT_DRIVER(i2c_designware_pci) = {
- .name = "i2c_designware_pci",
- .id = UCLASS_I2C,
- .bind = designware_i2c_pci_bind,
- .probe = designware_i2c_pci_probe,
- .priv_auto_alloc_size = sizeof(struct dw_i2c),
- .remove = designware_i2c_remove,
- .flags = DM_FLAG_OS_PREPARE,
Indentation seems wrong in the line above.
Thanks, Stefan

At present the name of the image comes first in the linker-list symbol used. This means that the name of the function sets the sort order, which is not the intention.
Update it to put the boot-device type first, then the priority. This produces the expected behaviour.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: - s/board device/boot device/
include/spl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/spl.h b/include/spl.h index b5387ef273d..08ffddac29f 100644 --- a/include/spl.h +++ b/include/spl.h @@ -332,14 +332,14 @@ struct spl_image_loader { */ #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT #define SPL_LOAD_IMAGE_METHOD(_name, _priority, _boot_device, _method) \ - SPL_LOAD_IMAGE(_method ## _priority ## _boot_device) = { \ + SPL_LOAD_IMAGE(_boot_device ## _priority ## _method) = { \ .name = _name, \ .boot_device = _boot_device, \ .load_image = _method, \ } #else #define SPL_LOAD_IMAGE_METHOD(_name, _priority, _boot_device, _method) \ - SPL_LOAD_IMAGE(_method ## _priority ## _boot_device) = { \ + SPL_LOAD_IMAGE(_boot_device ## _priority ## _method) = { \ .boot_device = _boot_device, \ .load_image = _method, \ }

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
At present the name of the image comes first in the linker-list symbol used. This means that the name of the function sets the sort order, which is not the intention.
Update it to put the boot-device type first, then the priority. This produces the expected behaviour.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- s/board device/boot device/
include/spl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 1:54 PM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
At present the name of the image comes first in the linker-list symbol used. This means that the name of the function sets the sort order, which is not the intention.
Update it to put the boot-device type first, then the priority. This produces the expected behaviour.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2:
- s/board device/boot device/
include/spl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

Most x86 CPUs use a mechanism where the SPI flash is mapped into the very top of 32-bit address space, so that it can be executed in place and read simply by copying from memory. For an 8MB ROM the mapping starts at 0xff800000.
However some recent Intel CPUs do not use a simple 1:1 memory map. Instead the map starts at a different address and not all of the SPI flash is accessible through the map. This 'Fast SPI' feature requires that U-Boot check the location of the map. It is also possible (optionally) to read from the SPI flash using a driver.
Add support for booting from Fast SPI. The memory-mapped version is used by both TPL and SPL on apollolake.
In respect of a SPI flash driver, the actual SPI driver is ich.c - this just adds a few helper functions and definitions.
This is used by Apollolake.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Add support for of-platdata for TPL - Add the missing header file - Change Fast-SPI driver into a helper file used by ICH SPI - Don't include write() and erase() in TPL - Merge in patch "x86: Add support for booting from Fast SPI" - Reorder file so that write() and erase() are together - Use pci_get_devfn()
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/fast_spi.c | 73 ++++++++++++++++++++++++++++ arch/x86/include/asm/fast_spi.h | 68 ++++++++++++++++++++++++++ arch/x86/include/asm/spl.h | 1 + 4 files changed, 143 insertions(+) create mode 100644 arch/x86/cpu/intel_common/fast_spi.c create mode 100644 arch/x86/include/asm/fast_spi.h
diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index 07f27c29ec7..dfbc29f0475 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += report_platform.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += mrc.o endif obj-y += cpu.o +obj-y += fast_spi.o obj-y += lpc.o ifndef CONFIG_TARGET_EFI_APP obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += microcode.o diff --git a/arch/x86/cpu/intel_common/fast_spi.c b/arch/x86/cpu/intel_common/fast_spi.c new file mode 100644 index 00000000000..a6e3d0a5bfc --- /dev/null +++ b/arch/x86/cpu/intel_common/fast_spi.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2019 Google LLC + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/cpu_common.h> +#include <asm/fast_spi.h> +#include <asm/pci.h> + +/* + * Returns bios_start and fills in size of the BIOS region. + */ +static ulong fast_spi_get_bios_region(struct fast_spi_regs *regs, + uint *bios_size) +{ + ulong bios_start, bios_end; + + /* + * BIOS_BFPREG provides info about BIOS-Flash Primary Region Base and + * Limit. Base and Limit fields are in units of 4K. + */ + u32 val = readl(®s->bfp); + + bios_start = (val & SPIBAR_BFPREG_PRB_MASK) << 12; + bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >> + SPIBAR_BFPREG_PRL_SHIFT) + 1) << 12; + *bios_size = bios_end - bios_start; + + return bios_start; +} + +int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, + uint *offsetp) +{ + struct fast_spi_regs *regs; + ulong bar, base, mmio_base; + + /* Special case to find mapping without probing the device */ + pci_x86_read_config(pdev, PCI_BASE_ADDRESS_0, &bar, PCI_SIZE_32); + mmio_base = bar & PCI_BASE_ADDRESS_MEM_MASK; + regs = (struct fast_spi_regs *)mmio_base; + base = fast_spi_get_bios_region(regs, map_sizep); + *map_basep = (u32)-*map_sizep - base; + *offsetp = base; + + return 0; +} + +int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base) +{ + /* Program Temporary BAR for SPI */ + pci_x86_write_config(pdev, PCI_BASE_ADDRESS_0, + mmio_base | PCI_BASE_ADDRESS_SPACE_MEMORY, + PCI_SIZE_32); + + /* Enable Bus Master and MMIO Space */ + pci_x86_clrset_config(pdev, PCI_COMMAND, 0, PCI_COMMAND_MASTER | + PCI_COMMAND_MEMORY, PCI_SIZE_8); + + /* + * Disable the BIOS write protect so write commands are allowed. + * Enable Prefetching and caching. + */ + pci_x86_clrset_config(pdev, SPIBAR_BIOS_CONTROL, + SPIBAR_BIOS_CONTROL_EISS | + SPIBAR_BIOS_CONTROL_CACHE_DISABLE, + SPIBAR_BIOS_CONTROL_WPD | + SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE, PCI_SIZE_8); + + return 0; +} diff --git a/arch/x86/include/asm/fast_spi.h b/arch/x86/include/asm/fast_spi.h new file mode 100644 index 00000000000..6c1bda2184f --- /dev/null +++ b/arch/x86/include/asm/fast_spi.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2017 Intel Corporation. + */ + +#ifndef ASM_FAST_SPI_H +#define ASM_FAST_SPI_H + +/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +struct fast_spi_regs { + u32 bfp; + u32 hsfsts_ctl; + u32 faddr; + u32 dlock; + + u32 fdata[0x10]; + + u32 fracc; + u32 freg[12]; + u32 fpr[5]; + u32 gpr0; + u32 spare2; + u32 sts_ctl; + u16 preop; /* a4 */ + u16 optype; + u8 opmenu[8]; + + u32 spare3; + u32 fdoc; + u32 fdod; + u32 spare4; + u32 afc; + u32 vscc[2]; + u32 ptinx; + u32 ptdata; +}; +check_member(fast_spi_regs, ptdata, 0xd0); + +/* Bit definitions for BFPREG (0x00) register */ +#define SPIBAR_BFPREG_PRB_MASK 0x7fff +#define SPIBAR_BFPREG_PRL_SHIFT 16 +#define SPIBAR_BFPREG_PRL_MASK (0x7fff << SPIBAR_BFPREG_PRL_SHIFT) + +/* PCI configuration registers */ +#define SPIBAR_BIOS_CONTROL 0xdc +#define SPIBAR_BIOS_CONTROL_WPD BIT(0) +#define SPIBAR_BIOS_CONTROL_LOCK_ENABLE BIT(1) +#define SPIBAR_BIOS_CONTROL_CACHE_DISABLE BIT(2) +#define SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE BIT(3) +#define SPIBAR_BIOS_CONTROL_EISS BIT(5) +#define SPIBAR_BIOS_CONTROL_BILD BIT(7) + +/** + * fast_spi_get_bios_mmap() - Get memory map for SPI flash + * + * @pdev: PCI device to use (this is the Fast SPI device) + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 (always) + */ +int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep, + uint *offsetp); + +int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base); + +#endif /* ASM_FAST_SPI_H */ diff --git a/arch/x86/include/asm/spl.h b/arch/x86/include/asm/spl.h index 1bef4877eb3..cc6cac08f23 100644 --- a/arch/x86/include/asm/spl.h +++ b/arch/x86/include/asm/spl.h @@ -11,6 +11,7 @@
enum { BOOT_DEVICE_SPI_MMAP = 10, + BOOT_DEVICE_FAST_SPI, BOOT_DEVICE_CROS_VBOOT, };

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
Most x86 CPUs use a mechanism where the SPI flash is mapped into the very top of 32-bit address space, so that it can be executed in place and read simply by copying from memory. For an 8MB ROM the mapping starts at 0xff800000.
However some recent Intel CPUs do not use a simple 1:1 memory map. Instead the map starts at a different address and not all of the SPI flash is accessible through the map. This 'Fast SPI' feature requires that U-Boot check the location of the map. It is also possible (optionally) to read from the SPI flash using a driver.
Add support for booting from Fast SPI. The memory-mapped version is used by both TPL and SPL on apollolake.
In respect of a SPI flash driver, the actual SPI driver is ich.c - this just adds a few helper functions and definitions.
This is used by Apollolake.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add support for of-platdata for TPL
- Add the missing header file
- Change Fast-SPI driver into a helper file used by ICH SPI
- Don't include write() and erase() in TPL
- Merge in patch "x86: Add support for booting from Fast SPI"
- Reorder file so that write() and erase() are together
- Use pci_get_devfn()
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/fast_spi.c | 73 ++++++++++++++++++++++++++++ arch/x86/include/asm/fast_spi.h | 68 ++++++++++++++++++++++++++ arch/x86/include/asm/spl.h | 1 + 4 files changed, 143 insertions(+) create mode 100644 arch/x86/cpu/intel_common/fast_spi.c create mode 100644 arch/x86/include/asm/fast_spi.h
diff --git a/arch/x86/cpu/intel_common/Makefile b/arch/x86/cpu/intel_common/Makefile index 07f27c29ec7..dfbc29f0475 100644 --- a/arch/x86/cpu/intel_common/Makefile +++ b/arch/x86/cpu/intel_common/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += report_platform.o obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += mrc.o endif obj-y += cpu.o +obj-y += fast_spi.o obj-y += lpc.o ifndef CONFIG_TARGET_EFI_APP obj-$(CONFIG_$(SPL_TPL_)X86_32BIT_INIT) += microcode.o diff --git a/arch/x86/cpu/intel_common/fast_spi.c b/arch/x86/cpu/intel_common/fast_spi.c new file mode 100644 index 00000000000..a6e3d0a5bfc --- /dev/null +++ b/arch/x86/cpu/intel_common/fast_spi.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- Copyright 2019 Google LLC
- */
+#include <common.h> +#include <asm/io.h> +#include <asm/cpu_common.h> +#include <asm/fast_spi.h> +#include <asm/pci.h>
+/*
- Returns bios_start and fills in size of the BIOS region.
- */
+static ulong fast_spi_get_bios_region(struct fast_spi_regs *regs,
uint *bios_size)
+{
ulong bios_start, bios_end;
/*
* BIOS_BFPREG provides info about BIOS-Flash Primary Region Base and
* Limit. Base and Limit fields are in units of 4K.
*/
u32 val = readl(®s->bfp);
bios_start = (val & SPIBAR_BFPREG_PRB_MASK) << 12;
bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
SPIBAR_BFPREG_PRL_SHIFT) + 1) << 12;
*bios_size = bios_end - bios_start;
return bios_start;
+}
+int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep,
uint *offsetp)
+{
struct fast_spi_regs *regs;
ulong bar, base, mmio_base;
/* Special case to find mapping without probing the device */
pci_x86_read_config(pdev, PCI_BASE_ADDRESS_0, &bar, PCI_SIZE_32);
mmio_base = bar & PCI_BASE_ADDRESS_MEM_MASK;
regs = (struct fast_spi_regs *)mmio_base;
base = fast_spi_get_bios_region(regs, map_sizep);
*map_basep = (u32)-*map_sizep - base;
*offsetp = base;
return 0;
+}
+int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base) +{
/* Program Temporary BAR for SPI */
pci_x86_write_config(pdev, PCI_BASE_ADDRESS_0,
mmio_base | PCI_BASE_ADDRESS_SPACE_MEMORY,
PCI_SIZE_32);
/* Enable Bus Master and MMIO Space */
pci_x86_clrset_config(pdev, PCI_COMMAND, 0, PCI_COMMAND_MASTER |
PCI_COMMAND_MEMORY, PCI_SIZE_8);
/*
* Disable the BIOS write protect so write commands are allowed.
* Enable Prefetching and caching.
*/
pci_x86_clrset_config(pdev, SPIBAR_BIOS_CONTROL,
SPIBAR_BIOS_CONTROL_EISS |
SPIBAR_BIOS_CONTROL_CACHE_DISABLE,
SPIBAR_BIOS_CONTROL_WPD |
SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE, PCI_SIZE_8);
return 0;
+} diff --git a/arch/x86/include/asm/fast_spi.h b/arch/x86/include/asm/fast_spi.h new file mode 100644 index 00000000000..6c1bda2184f --- /dev/null +++ b/arch/x86/include/asm/fast_spi.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/*
- Copyright (C) 2017 Intel Corporation.
- */
+#ifndef ASM_FAST_SPI_H +#define ASM_FAST_SPI_H
+/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +struct fast_spi_regs {
u32 bfp;
u32 hsfsts_ctl;
u32 faddr;
u32 dlock;
u32 fdata[0x10];
u32 fracc;
u32 freg[12];
u32 fpr[5];
u32 gpr0;
u32 spare2;
u32 sts_ctl;
u16 preop; /* a4 */
I assume a4 is the offset of preop? Leaving it causes confusion and it can be dropped, I think.
u16 optype;
u8 opmenu[8];
u32 spare3;
u32 fdoc;
u32 fdod;
u32 spare4;
u32 afc;
u32 vscc[2];
u32 ptinx;
u32 ptdata;
+}; +check_member(fast_spi_regs, ptdata, 0xd0);
+/* Bit definitions for BFPREG (0x00) register */ +#define SPIBAR_BFPREG_PRB_MASK 0x7fff +#define SPIBAR_BFPREG_PRL_SHIFT 16 +#define SPIBAR_BFPREG_PRL_MASK (0x7fff << SPIBAR_BFPREG_PRL_SHIFT)
+/* PCI configuration registers */ +#define SPIBAR_BIOS_CONTROL 0xdc +#define SPIBAR_BIOS_CONTROL_WPD BIT(0) +#define SPIBAR_BIOS_CONTROL_LOCK_ENABLE BIT(1) +#define SPIBAR_BIOS_CONTROL_CACHE_DISABLE BIT(2) +#define SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE BIT(3) +#define SPIBAR_BIOS_CONTROL_EISS BIT(5) +#define SPIBAR_BIOS_CONTROL_BILD BIT(7)
+/**
- fast_spi_get_bios_mmap() - Get memory map for SPI flash
- @pdev: PCI device to use (this is the Fast SPI device)
- @map_basep: Returns base memory address for mapped SPI
- @map_sizep: Returns size of mapped SPI
- @offsetp: Returns start offset of SPI flash where the map works
correctly (offsets before this are not visible)
- @return 0 (always)
- */
+int fast_spi_get_bios_mmap(pci_dev_t pdev, ulong *map_basep, uint *map_sizep,
uint *offsetp);
+int fast_spi_early_init(pci_dev_t pdev, ulong mmio_base);
+#endif /* ASM_FAST_SPI_H */ diff --git a/arch/x86/include/asm/spl.h b/arch/x86/include/asm/spl.h index 1bef4877eb3..cc6cac08f23 100644 --- a/arch/x86/include/asm/spl.h +++ b/arch/x86/include/asm/spl.h @@ -11,6 +11,7 @@
enum { BOOT_DEVICE_SPI_MMAP = 10,
BOOT_DEVICE_FAST_SPI, BOOT_DEVICE_CROS_VBOOT,
};
--
Regards, Bin

Hi Bin,
On Fri, 1 Nov 2019 at 22:14, Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
Most x86 CPUs use a mechanism where the SPI flash is mapped into the very top of 32-bit address space, so that it can be executed in place and read simply by copying from memory. For an 8MB ROM the mapping starts at 0xff800000.
However some recent Intel CPUs do not use a simple 1:1 memory map. Instead the map starts at a different address and not all of the SPI flash is accessible through the map. This 'Fast SPI' feature requires that U-Boot check the location of the map. It is also possible (optionally) to read from the SPI flash using a driver.
Add support for booting from Fast SPI. The memory-mapped version is used by both TPL and SPL on apollolake.
In respect of a SPI flash driver, the actual SPI driver is ich.c - this just adds a few helper functions and definitions.
This is used by Apollolake.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add support for of-platdata for TPL
- Add the missing header file
- Change Fast-SPI driver into a helper file used by ICH SPI
- Don't include write() and erase() in TPL
- Merge in patch "x86: Add support for booting from Fast SPI"
- Reorder file so that write() and erase() are together
- Use pci_get_devfn()
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/fast_spi.c | 73 ++++++++++++++++++++++++++++ arch/x86/include/asm/fast_spi.h | 68 ++++++++++++++++++++++++++ arch/x86/include/asm/spl.h | 1 + 4 files changed, 143 insertions(+) create mode 100644 arch/x86/cpu/intel_common/fast_spi.c create mode 100644 arch/x86/include/asm/fast_spi.h
[..]
+/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +struct fast_spi_regs {
u32 bfp;
u32 hsfsts_ctl;
u32 faddr;
u32 dlock;
u32 fdata[0x10];
u32 fracc;
u32 freg[12];
u32 fpr[5];
u32 gpr0;
u32 spare2;
u32 sts_ctl;
u16 preop; /* a4 */
I assume a4 is the offset of preop? Leaving it causes confusion and it can be dropped, I think.
Will do.
I'm rebasing on your applied patches and moving the code around to address Andy's comments. I'll send a new version v4 by Monday.
Regards, Simon

Hi Simon,
On Sun, Nov 3, 2019 at 5:04 AM Simon Glass sjg@chromium.org wrote:
Hi Bin,
On Fri, 1 Nov 2019 at 22:14, Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
Most x86 CPUs use a mechanism where the SPI flash is mapped into the very top of 32-bit address space, so that it can be executed in place and read simply by copying from memory. For an 8MB ROM the mapping starts at 0xff800000.
However some recent Intel CPUs do not use a simple 1:1 memory map. Instead the map starts at a different address and not all of the SPI flash is accessible through the map. This 'Fast SPI' feature requires that U-Boot check the location of the map. It is also possible (optionally) to read from the SPI flash using a driver.
Add support for booting from Fast SPI. The memory-mapped version is used by both TPL and SPL on apollolake.
In respect of a SPI flash driver, the actual SPI driver is ich.c - this just adds a few helper functions and definitions.
This is used by Apollolake.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add support for of-platdata for TPL
- Add the missing header file
- Change Fast-SPI driver into a helper file used by ICH SPI
- Don't include write() and erase() in TPL
- Merge in patch "x86: Add support for booting from Fast SPI"
- Reorder file so that write() and erase() are together
- Use pci_get_devfn()
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/fast_spi.c | 73 ++++++++++++++++++++++++++++ arch/x86/include/asm/fast_spi.h | 68 ++++++++++++++++++++++++++ arch/x86/include/asm/spl.h | 1 + 4 files changed, 143 insertions(+) create mode 100644 arch/x86/cpu/intel_common/fast_spi.c create mode 100644 arch/x86/include/asm/fast_spi.h
[..]
+/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +struct fast_spi_regs {
u32 bfp;
u32 hsfsts_ctl;
u32 faddr;
u32 dlock;
u32 fdata[0x10];
u32 fracc;
u32 freg[12];
u32 fpr[5];
u32 gpr0;
u32 spare2;
u32 sts_ctl;
u16 preop; /* a4 */
I assume a4 is the offset of preop? Leaving it causes confusion and it can be dropped, I think.
Will do.
I'm rebasing on your applied patches and moving the code around to address Andy's comments. I'll send a new version v4 by Monday.
Or maybe you can wait until I looked at all v3 patches. I just wanted to send a PR for a collection of good patches so far, instead of giving Tom a huge list :)
Regards, Bin

Hi Bin,
On Sat, 2 Nov 2019 at 17:18, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Sun, Nov 3, 2019 at 5:04 AM Simon Glass sjg@chromium.org wrote:
Hi Bin,
On Fri, 1 Nov 2019 at 22:14, Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
Most x86 CPUs use a mechanism where the SPI flash is mapped into the very top of 32-bit address space, so that it can be executed in place and read simply by copying from memory. For an 8MB ROM the mapping starts at 0xff800000.
However some recent Intel CPUs do not use a simple 1:1 memory map. Instead the map starts at a different address and not all of the SPI flash is accessible through the map. This 'Fast SPI' feature requires that U-Boot check the location of the map. It is also possible (optionally) to read from the SPI flash using a driver.
Add support for booting from Fast SPI. The memory-mapped version is used by both TPL and SPL on apollolake.
In respect of a SPI flash driver, the actual SPI driver is ich.c - this just adds a few helper functions and definitions.
This is used by Apollolake.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add support for of-platdata for TPL
- Add the missing header file
- Change Fast-SPI driver into a helper file used by ICH SPI
- Don't include write() and erase() in TPL
- Merge in patch "x86: Add support for booting from Fast SPI"
- Reorder file so that write() and erase() are together
- Use pci_get_devfn()
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/fast_spi.c | 73 ++++++++++++++++++++++++++++ arch/x86/include/asm/fast_spi.h | 68 ++++++++++++++++++++++++++ arch/x86/include/asm/spl.h | 1 + 4 files changed, 143 insertions(+) create mode 100644 arch/x86/cpu/intel_common/fast_spi.c create mode 100644 arch/x86/include/asm/fast_spi.h
[..]
+/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +struct fast_spi_regs {
u32 bfp;
u32 hsfsts_ctl;
u32 faddr;
u32 dlock;
u32 fdata[0x10];
u32 fracc;
u32 freg[12];
u32 fpr[5];
u32 gpr0;
u32 spare2;
u32 sts_ctl;
u16 preop; /* a4 */
I assume a4 is the offset of preop? Leaving it causes confusion and it can be dropped, I think.
Will do.
I'm rebasing on your applied patches and moving the code around to address Andy's comments. I'll send a new version v4 by Monday.
Or maybe you can wait until I looked at all v3 patches. I just wanted to send a PR for a collection of good patches so far, instead of giving Tom a huge list :)
OK that's fine with me.
Regards, Simon

Hi Bin,
On Sun, 3 Nov 2019 at 07:36, Simon Glass sjg@chromium.org wrote:
Hi Bin,
On Sat, 2 Nov 2019 at 17:18, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Sun, Nov 3, 2019 at 5:04 AM Simon Glass sjg@chromium.org wrote:
Hi Bin,
On Fri, 1 Nov 2019 at 22:14, Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
Most x86 CPUs use a mechanism where the SPI flash is mapped into the very top of 32-bit address space, so that it can be executed in place and read simply by copying from memory. For an 8MB ROM the mapping starts at 0xff800000.
However some recent Intel CPUs do not use a simple 1:1 memory map. Instead the map starts at a different address and not all of the SPI flash is accessible through the map. This 'Fast SPI' feature requires that U-Boot check the location of the map. It is also possible (optionally) to read from the SPI flash using a driver.
Add support for booting from Fast SPI. The memory-mapped version is used by both TPL and SPL on apollolake.
In respect of a SPI flash driver, the actual SPI driver is ich.c - this just adds a few helper functions and definitions.
This is used by Apollolake.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Add support for of-platdata for TPL
- Add the missing header file
- Change Fast-SPI driver into a helper file used by ICH SPI
- Don't include write() and erase() in TPL
- Merge in patch "x86: Add support for booting from Fast SPI"
- Reorder file so that write() and erase() are together
- Use pci_get_devfn()
Changes in v2: None
arch/x86/cpu/intel_common/Makefile | 1 + arch/x86/cpu/intel_common/fast_spi.c | 73 ++++++++++++++++++++++++++++ arch/x86/include/asm/fast_spi.h | 68 ++++++++++++++++++++++++++ arch/x86/include/asm/spl.h | 1 + 4 files changed, 143 insertions(+) create mode 100644 arch/x86/cpu/intel_common/fast_spi.c create mode 100644 arch/x86/include/asm/fast_spi.h
[..]
+/* Register offsets from the MMIO region base (PCI_BASE_ADDRESS_0) */ +struct fast_spi_regs {
u32 bfp;
u32 hsfsts_ctl;
u32 faddr;
u32 dlock;
u32 fdata[0x10];
u32 fracc;
u32 freg[12];
u32 fpr[5];
u32 gpr0;
u32 spare2;
u32 sts_ctl;
u16 preop; /* a4 */
I assume a4 is the offset of preop? Leaving it causes confusion and it can be dropped, I think.
Will do.
I'm rebasing on your applied patches and moving the code around to address Andy's comments. I'll send a new version v4 by Monday.
Or maybe you can wait until I looked at all v3 patches. I just wanted to send a PR for a collection of good patches so far, instead of giving Tom a huge list :)
OK that's fine with me.
I've completed the update and there are quite a few changes in perhaps 1/3 of the patches. You can see it at u-boot-dm/coral-working - but let me know if I should send v4.
Regards, Simon

On x86 platforms the SPI flash can be mapped into memory so that the contents can be read with normal memory accesses.
Add a new SPI method to find the location of the SPI flash in memory. This differs from the existing device-tree "memory-map" mechanism in that the location can be discovered at run-time.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Move the get_mmap() method from the SPI_FLASH to the SPI uclass
Changes in v2: None
drivers/spi/sandbox_spi.c | 11 +++++++++++ drivers/spi/spi-uclass.c | 14 ++++++++++++++ include/spi.h | 27 +++++++++++++++++++++++++++ test/dm/sf.c | 9 +++++++++ 4 files changed, 61 insertions(+)
diff --git a/drivers/spi/sandbox_spi.c b/drivers/spi/sandbox_spi.c index 906401ec8ab..cefe2ed9a37 100644 --- a/drivers/spi/sandbox_spi.c +++ b/drivers/spi/sandbox_spi.c @@ -122,11 +122,22 @@ static int sandbox_cs_info(struct udevice *bus, uint cs, return 0; }
+static int sandbox_spi_get_mmap(struct udevice *dev, ulong *map_basep, + uint *map_sizep, uint *offsetp) +{ + *map_basep = 0x1000; + *map_sizep = 0x2000; + *offsetp = 0x100; + + return 0; +} + static const struct dm_spi_ops sandbox_spi_ops = { .xfer = sandbox_spi_xfer, .set_speed = sandbox_spi_set_speed, .set_mode = sandbox_spi_set_mode, .cs_info = sandbox_cs_info, + .get_mmap = sandbox_spi_get_mmap, };
static const struct udevice_id sandbox_spi_ids[] = { diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c index a4d1b65682d..9f5ff2a31d1 100644 --- a/drivers/spi/spi-uclass.c +++ b/drivers/spi/spi-uclass.c @@ -92,6 +92,20 @@ int dm_spi_xfer(struct udevice *dev, unsigned int bitlen, return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags); }
+int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep, + uint *offsetp) +{ + struct udevice *bus = dev->parent; + struct dm_spi_ops *ops = spi_get_ops(bus); + + if (bus->uclass->uc_drv->id != UCLASS_SPI) + return -EOPNOTSUPP; + if (!ops->get_mmap) + return -ENOSYS; + + return ops->get_mmap(dev, map_basep, map_sizep, offsetp); +} + int spi_claim_bus(struct spi_slave *slave) { return log_ret(dm_spi_claim_bus(slave->dev)); diff --git a/include/spi.h b/include/spi.h index 5eec0c4775e..a12727e6361 100644 --- a/include/spi.h +++ b/include/spi.h @@ -462,6 +462,19 @@ struct dm_spi_ops { * is invalid, other -ve value on error */ int (*cs_info)(struct udevice *bus, uint cs, struct spi_cs_info *info); + + /** + * get_mmap() - Get memory-mapped SPI + * + * @dev: The SPI flash slave device + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 if OK, -EFAULT if memory mapping is not available + */ + int (*get_mmap)(struct udevice *dev, ulong *map_basep, + uint *map_sizep, uint *offsetp); };
struct dm_spi_emul_ops { @@ -650,6 +663,20 @@ void dm_spi_release_bus(struct udevice *dev); int dm_spi_xfer(struct udevice *dev, unsigned int bitlen, const void *dout, void *din, unsigned long flags);
+/** + * spi_get_mmap() - Get memory-mapped SPI + * + * @dev: SPI slave device to check + * @map_basep: Returns base memory address for mapped SPI + * @map_sizep: Returns size of mapped SPI + * @offsetp: Returns start offset of SPI flash where the map works + * correctly (offsets before this are not visible) + * @return 0 if OK, -ENOSYS if no operation, -EFAULT if memory mapping is not + * available + */ +int dm_spi_get_mmap(struct udevice *dev, ulong *map_basep, uint *map_sizep, + uint *offsetp); + /* Access the operations for a SPI device */ #define spi_get_ops(dev) ((struct dm_spi_ops *)(dev)->driver->ops) #define spi_emul_get_ops(dev) ((struct dm_spi_emul_ops *)(dev)->driver->ops) diff --git a/test/dm/sf.c b/test/dm/sf.c index 3788d59052e..65aab4f2e9c 100644 --- a/test/dm/sf.c +++ b/test/dm/sf.c @@ -23,6 +23,9 @@ static int dm_test_spi_flash(struct unit_test_state *uts) int full_size = 0x200000; int size = 0x10000; u8 *src, *dst; + uint map_size; + ulong map_base; + uint offset; int i;
src = map_sysmem(0x20000, full_size); @@ -54,6 +57,12 @@ static int dm_test_spi_flash(struct unit_test_state *uts) sandbox_sf_set_block_protect(emul, 0); ut_asserteq(0, spl_flash_get_sw_write_prot(dev));
+ /* Check mapping */ + ut_assertok(dm_spi_get_mmap(dev, &map_base, &map_size, &offset)); + ut_asserteq(0x1000, map_base); + ut_asserteq(0x2000, map_size); + ut_asserteq(0x100, offset); + /* * Since we are about to destroy all devices, we must tell sandbox * to forget the emulation device

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
On x86 platforms the SPI flash can be mapped into memory so that the contents can be read with normal memory accesses.
Add a new SPI method to find the location of the SPI flash in memory. This differs from the existing device-tree "memory-map" mechanism in that the location can be discovered at run-time.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Move the get_mmap() method from the SPI_FLASH to the SPI uclass
Changes in v2: None
drivers/spi/sandbox_spi.c | 11 +++++++++++ drivers/spi/spi-uclass.c | 14 ++++++++++++++ include/spi.h | 27 +++++++++++++++++++++++++++ test/dm/sf.c | 9 +++++++++ 4 files changed, 61 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Sat, Nov 2, 2019 at 12:13 PM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
On x86 platforms the SPI flash can be mapped into memory so that the contents can be read with normal memory accesses.
Add a new SPI method to find the location of the SPI flash in memory. This differs from the existing device-tree "memory-map" mechanism in that the location can be discovered at run-time.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Move the get_mmap() method from the SPI_FLASH to the SPI uclass
Changes in v2: None
drivers/spi/sandbox_spi.c | 11 +++++++++++ drivers/spi/spi-uclass.c | 14 ++++++++++++++ include/spi.h | 27 +++++++++++++++++++++++++++ test/dm/sf.c | 9 +++++++++ 4 files changed, 61 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

Add a note about the driver name in the of-platdata documentation since the naming must follow the compatible string.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Rework patch now that the original CONFIG_IS_ENABLED() problems is fixed
Changes in v2: None
doc/driver-model/of-plat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/driver-model/of-plat.rst b/doc/driver-model/of-plat.rst index a38e58e4d29..557957d2a16 100644 --- a/doc/driver-model/of-plat.rst +++ b/doc/driver-model/of-plat.rst @@ -269,7 +269,7 @@ For example: };
U_BOOT_DRIVER(mmc_drv) = { - .name = "mmc", + .name = "vendor_mmc", /* matches compatible string */ .id = UCLASS_MMC, .of_match = mmc_ids, .ofdata_to_platdata = mmc_ofdata_to_platdata,

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
Add a note about the driver name in the of-platdata documentation since the naming must follow the compatible string.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Rework patch now that the original CONFIG_IS_ENABLED() problems is fixed
Changes in v2: None
doc/driver-model/of-plat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 1:59 PM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
Add a note about the driver name in the of-platdata documentation since the naming must follow the compatible string.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Rework patch now that the original CONFIG_IS_ENABLED() problems is fixed
Changes in v2: None
doc/driver-model/of-plat.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

When device-tree compilation fails it is sometimes tricky to see which line is broken, since the input file to dtc is a pre-processed version of the device tree.
Add a line that points to the file that needs to be checked:
Output is something like this:
Error: arch/x86/dts/u-boot.dtsi:137.14-15 syntax error FATAL ERROR: Unable to parse input tree Check /tmp/b/chromebook_coral/arch/x86/dts/.chromebook_coral.dtb.pre.tmp for errors
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Update example error message to better show the intended purpose
Changes in v2: None
scripts/Makefile.lib | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index ef116e0e0ae..c10cd83a0a3 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -300,7 +300,9 @@ cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $(pre-tmp) ; \ $(DTC) -O dtb -o $@ -b 0 \ -i $(dir $<) $(DTC_FLAGS) \ - -d $(depfile).dtc.tmp $(dtc-tmp) ; \ + -d $(depfile).dtc.tmp $(dtc-tmp) || \ + (echo "Check $(shell pwd)/$(pre-tmp) for errors" && false) \ + ; \ cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile) ; \ sed -i "s:$(pre-tmp):$(<):" $(depfile)

Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
When device-tree compilation fails it is sometimes tricky to see which line is broken, since the input file to dtc is a pre-processed version of the device tree.
Add a line that points to the file that needs to be checked:
Output is something like this:
Error: arch/x86/dts/u-boot.dtsi:137.14-15 syntax error
To me this already provides enough information for people to look at. I don't think we need another line to duplicate the report.
FATAL ERROR: Unable to parse input tree Check /tmp/b/chromebook_coral/arch/x86/dts/.chromebook_coral.dtb.pre.tmp
Another reason is that if the error does not happen in the dtsi file but the main dts file, the line you added here is a duplicates of the error message coming from the dtc.
for errors
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Update example error message to better show the intended purpose
Changes in v2: None
scripts/Makefile.lib | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
Regards, Bin

Hi Bin,
On Mon, 28 Oct 2019 at 00:47, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
When device-tree compilation fails it is sometimes tricky to see which line is broken, since the input file to dtc is a pre-processed version of the device tree.
Add a line that points to the file that needs to be checked:
Output is something like this:
Error: arch/x86/dts/u-boot.dtsi:137.14-15 syntax error
To me this already provides enough information for people to look at. I don't think we need another line to duplicate the report.
FATAL ERROR: Unable to parse input tree Check /tmp/b/chromebook_coral/arch/x86/dts/.chromebook_coral.dtb.pre.tmp
Another reason is that if the error does not happen in the dtsi file but the main dts file, the line you added here is a duplicates of the error message coming from the dtc.
Part of the problem here is that the commit shows the un-preprocessed filename. I'll fix that and add a longer description.
This commit has saved my bacon quite a few times and I think it has value. Hopefully you agree once you try it out, but if not, I'm going to drop it.
for errors
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Update example error message to better show the intended purpose
Changes in v2: None
scripts/Makefile.lib | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
Regards, Simon

Hi Simon,
On Sun, Nov 3, 2019 at 2:02 AM Simon Glass sjg@chromium.org wrote:
Hi Bin,
On Mon, 28 Oct 2019 at 00:47, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
When device-tree compilation fails it is sometimes tricky to see which line is broken, since the input file to dtc is a pre-processed version of the device tree.
Add a line that points to the file that needs to be checked:
Output is something like this:
Error: arch/x86/dts/u-boot.dtsi:137.14-15 syntax error
To me this already provides enough information for people to look at. I don't think we need another line to duplicate the report.
FATAL ERROR: Unable to parse input tree Check /tmp/b/chromebook_coral/arch/x86/dts/.chromebook_coral.dtb.pre.tmp
Another reason is that if the error does not happen in the dtsi file but the main dts file, the line you added here is a duplicates of the error message coming from the dtc.
Part of the problem here is that the commit shows the un-preprocessed filename. I'll fix that and add a longer description.
This commit has saved my bacon quite a few times and I think it has value. Hopefully you agree once you try it out, but if not, I'm going to drop it.
OK, then please fix the issue you mentioned.
for errors
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Update example error message to better show the intended purpose
Changes in v2: None
scripts/Makefile.lib | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
Regards, Bin

These warnings appear every thing sandbox is run (see below) and dwarf the actual useful output. Suppress them in two ways:
1. For the mismatch warnings, only set the eth<x>addr environment variables when running tests.
2. For the 'MAC address from ROM' warning, never print this on sandbox.
Signed-off-by: Simon Glass sjg@chromium.org --- Unfortunately this breaks the tests so is not applicable as is:
$ /tmp/b/sandbox/u-boot -T -c "ut dm eth_prime"
U-Boot 2019.10-00508-g95f6257285-dirty (Oct 13 2019 - 09:21:34 -0600)
Model: sandbox DRAM: 128 MiB WDT: Started with servicing (60s timeout) MMC: mmc2: 2 (SD), mmc1: 1 (SD), mmc0: 0 (SD) In: serial Out: vidconsole Err: vidconsole Model: sandbox SCSI: Net: Error: eth@10002000 address not set. eth-1: eth@10002000 Error: eth@10003000 address not set. , eth-1: eth@10003000 Error: sbe5 address not set. , eth-1: sbe5 Error: eth@10004000 address not set. , eth-1: eth@10004000 Test: dm_test_eth_prime: eth.c Test: dm_test_eth_prime: eth.c (flat tree) Failures: 0
Old output:
U-Boot 2019.10-rc2
Model: sandbox DRAM: 128 MiB
Warning: host_lo MAC addresses don't match: Address in ROM is a6:28:b7:47:28:93 Address in environment is 00:00:11:22:33:44
Warning: host_enp5s0 MAC addresses don't match: Address in ROM is a6:28:b7:47:28:93 Address in environment is 00:00:11:22:33:45
Warning: host_eth6 using MAC address from ROM
Warning: host_docker0 MAC addresses don't match: Address in ROM is a6:28:b7:47:28:93 Address in environment is 00:00:11:22:33:46
Warning: host_docker_gwbridge using MAC address from ROM
Warning: host_veth1118e68 MAC addresses don't match: Address in ROM is a6:28:b7:47:28:93 Address in environment is 00:00:11:22:33:47 WDT: Not found! MMC: In: cros-ec-keyb Out: vidconsole Err: vidconsole Model: sandbox SCSI: Net: eth0: host_lo, eth1: host_enp5s0, eth2: host_eth6, eth3: host_docker0, eth4: host_docker_gwbridge, eth5: host_veth1118e68 Error: eth@10002000 address not set. , eth-1: eth@10002000 Test 'pmc_base' not found
Warning: host_lo MAC addresses don't match: Address in ROM is 2a:24:9a:31:90:f8 Address in environment is 00:00:11:22:33:44
Warning: host_enp5s0 MAC addresses don't match: Address in ROM is ce:23:d9:74:6f:6c Address in environment is 00:00:11:22:33:45
Warning: host_eth6 using MAC address from ROM
Warning: host_docker0 MAC addresses don't match: Address in ROM is ee:22:1c:3b:be:bc Address in environment is 00:00:11:22:33:46
Warning: host_docker_gwbridge using MAC address from ROM
Warning: host_veth1118e68 MAC addresses don't match: Address in ROM is ae:20:9e:3d:a4:9f Address in environment is 00:00:11:22:33:47
New output: U-Boot 2019.10
Model: sandbox DRAM: 128 MiB WDT: Not found! MMC: In: cros-ec-keyb Out: vidconsole Err: vidconsole Model: sandbox SCSI: Net: eth0: host_lo, eth1: host_enp5s0, eth2: host_eth6, eth3: host_docker0, eth4: host_docker_gwbridge, eth5: host_vethc7e1b9e Error: eth@10002000 address not set. , eth-1: eth@10002000 Hit any key to stop autoboot: 0 =>
Changes in v3: - Only supress the 'MAC address from ROM' warning on sandbox - Set the environment variables at runtime to avoid other warnings
Changes in v2: None
arch/sandbox/cpu/state.c | 12 ++++++++++-- arch/sandbox/include/asm/state.h | 5 ++++- cmd/nvedit.c | 8 ++++++++ include/configs/sandbox.h | 7 ++----- include/env.h | 12 ++++++++++++ net/eth-uclass.c | 11 +++++++++-- test/dm/test-main.c | 2 +- 7 files changed, 46 insertions(+), 11 deletions(-)
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index dee5fde4f73..70b278e4e27 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -351,7 +351,7 @@ bool state_get_skip_delays(void) return state->skip_delays; }
-void state_reset_for_test(struct sandbox_state *state) +void state_reset_for_test(struct sandbox_state *state, bool eth_vars) { /* No reset yet, so mark it as such. Always allow power reset */ state->last_sysreset = SYSRESET_COUNT; @@ -367,6 +367,14 @@ void state_reset_for_test(struct sandbox_state *state) */ INIT_LIST_HEAD(&state->mapmem_head); state->next_tag = state->ram_size; + + if (eth_vars) { + /* set up some environment variables needed by the eth tests */ + env_set_for_test("ethaddr", "00:00:11:22:33:44"); + env_set_for_test("eth1addr", "00:00:11:22:33:45"); + env_set_for_test("eth3addr", "00:00:11:22:33:46"); + env_set_for_test("eth5addr", "00:00:11:22:33:47"); + } }
int state_init(void) @@ -377,7 +385,7 @@ int state_init(void) state->ram_buf = os_malloc(state->ram_size); assert(state->ram_buf);
- state_reset_for_test(state); + state_reset_for_test(state, false); /* * Example of how to use GPIOs: * diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index ad3e94beb9a..4fa3b094a97 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -251,8 +251,11 @@ bool state_get_skip_delays(void); * state_reset_for_test() - Reset ready to re-run tests * * This clears out any test state ready for another test run. + * + * @param state Sandbox state to update + * @param eth_vars Set environment variables for eth tests */ -void state_reset_for_test(struct sandbox_state *state); +void state_reset_for_test(struct sandbox_state *state, bool eth_vars);
/** * state_show() - Show information about the sandbox state diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 1cb0bc1460b..5eef44eb5ff 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -299,6 +299,14 @@ static int _do_env_set(int flag, int argc, char * const argv[], int env_flag) return 0; }
+int env_set_for_test(const char *varname, const char *value) +{ + const char * const argv[4] = { "setenv", varname, value, NULL }; + + assert(value); + return _do_env_set(0, 3, (char * const *)argv, 0); +} + int env_set(const char *varname, const char *varvalue) { const char * const argv[4] = { "setenv", varname, varvalue, NULL }; diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 5d75021ed6b..02e553c4b12 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -98,11 +98,8 @@ "stderr=serial,vidconsole\0" #endif
-#define SANDBOX_ETH_SETTINGS "ethaddr=00:00:11:22:33:44\0" \ - "eth1addr=00:00:11:22:33:45\0" \ - "eth3addr=00:00:11:22:33:46\0" \ - "eth5addr=00:00:11:22:33:47\0" \ - "ipaddr=1.2.3.4\0" +/* Note that some ethernet variables are set in state_reset_for_test() */ +#define SANDBOX_ETH_SETTINGS "ipaddr=1.2.3.4\0"
#define MEM_LAYOUT_ENV_SETTINGS \ "bootm_size=0x10000000\0" \ diff --git a/include/env.h b/include/env.h index b72239f6a58..bc48a72cde9 100644 --- a/include/env.h +++ b/include/env.h @@ -145,6 +145,18 @@ int env_get_yesno(const char *var); */ int env_set(const char *varname, const char *value);
+/** + * env_set_for_test() - Set the value of a variable for testing + * + * This works as if the variable value was defined in the built-in environment, + * so uses a flags value of 0. This should only be used in tests. + * + * @varname: Variable to adjust + * @value: Value to set for the variable (cannot be NULL) + * @return 0 if OK, 1 on error + */ +int env_set_for_test(const char *varname, const char *value); + /** * env_get_ulong() - Return an environment variable as an integer value * diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 3bd98b01ad3..6c195361385 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -485,6 +485,12 @@ static int eth_post_probe(struct udevice *dev) struct eth_device_priv *priv = dev->uclass_priv; struct eth_pdata *pdata = dev->platdata; unsigned char env_enetaddr[ARP_HLEN]; + /* + * These warnings always appear on sandbox and are not useful. They have + * been here for some time and the issue has not been resolved. So for + * now, disable them. + */ + bool show_warnings = !IS_ENABLED(CONFIG_SANDBOX);
#if defined(CONFIG_NEEDS_MANUAL_RELOC) struct eth_ops *ops = eth_get_ops(dev); @@ -538,8 +544,9 @@ static int eth_post_probe(struct udevice *dev) memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN); } else if (is_valid_ethaddr(pdata->enetaddr)) { eth_env_set_enetaddr_by_index("eth", dev->seq, pdata->enetaddr); - printf("\nWarning: %s using MAC address from ROM\n", - dev->name); + if (show_warnings) + printf("\nWarning: %s using MAC address from ROM\n", + dev->name); } else if (is_zero_ethaddr(pdata->enetaddr) || !is_valid_ethaddr(pdata->enetaddr)) { #ifdef CONFIG_NET_RANDOM_ETHADDR diff --git a/test/dm/test-main.c b/test/dm/test-main.c index 72648162a91..14a520944e8 100644 --- a/test/dm/test-main.c +++ b/test/dm/test-main.c @@ -28,7 +28,7 @@ static int dm_test_init(struct unit_test_state *uts, bool of_live) memset(dms, '\0', sizeof(*dms)); gd->dm_root = NULL; memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); - state_reset_for_test(state_get_current()); + state_reset_for_test(state_get_current(), true);
#ifdef CONFIG_OF_LIVE /* Determine whether to make the live tree available */

This reverts commit 96ac4def8b6686de8566b91419ce98cd5765079b.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
arch/sandbox/cpu/state.c | 12 ++---------- arch/sandbox/include/asm/state.h | 5 +---- cmd/nvedit.c | 8 -------- include/configs/sandbox.h | 7 +++++-- include/env.h | 12 ------------ net/eth-uclass.c | 11 ++--------- test/dm/test-main.c | 2 +- 7 files changed, 11 insertions(+), 46 deletions(-)
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c index 70b278e4e27..dee5fde4f73 100644 --- a/arch/sandbox/cpu/state.c +++ b/arch/sandbox/cpu/state.c @@ -351,7 +351,7 @@ bool state_get_skip_delays(void) return state->skip_delays; }
-void state_reset_for_test(struct sandbox_state *state, bool eth_vars) +void state_reset_for_test(struct sandbox_state *state) { /* No reset yet, so mark it as such. Always allow power reset */ state->last_sysreset = SYSRESET_COUNT; @@ -367,14 +367,6 @@ void state_reset_for_test(struct sandbox_state *state, bool eth_vars) */ INIT_LIST_HEAD(&state->mapmem_head); state->next_tag = state->ram_size; - - if (eth_vars) { - /* set up some environment variables needed by the eth tests */ - env_set_for_test("ethaddr", "00:00:11:22:33:44"); - env_set_for_test("eth1addr", "00:00:11:22:33:45"); - env_set_for_test("eth3addr", "00:00:11:22:33:46"); - env_set_for_test("eth5addr", "00:00:11:22:33:47"); - } }
int state_init(void) @@ -385,7 +377,7 @@ int state_init(void) state->ram_buf = os_malloc(state->ram_size); assert(state->ram_buf);
- state_reset_for_test(state, false); + state_reset_for_test(state); /* * Example of how to use GPIOs: * diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 4fa3b094a97..ad3e94beb9a 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -251,11 +251,8 @@ bool state_get_skip_delays(void); * state_reset_for_test() - Reset ready to re-run tests * * This clears out any test state ready for another test run. - * - * @param state Sandbox state to update - * @param eth_vars Set environment variables for eth tests */ -void state_reset_for_test(struct sandbox_state *state, bool eth_vars); +void state_reset_for_test(struct sandbox_state *state);
/** * state_show() - Show information about the sandbox state diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 5eef44eb5ff..1cb0bc1460b 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -299,14 +299,6 @@ static int _do_env_set(int flag, int argc, char * const argv[], int env_flag) return 0; }
-int env_set_for_test(const char *varname, const char *value) -{ - const char * const argv[4] = { "setenv", varname, value, NULL }; - - assert(value); - return _do_env_set(0, 3, (char * const *)argv, 0); -} - int env_set(const char *varname, const char *varvalue) { const char * const argv[4] = { "setenv", varname, varvalue, NULL }; diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 02e553c4b12..5d75021ed6b 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -98,8 +98,11 @@ "stderr=serial,vidconsole\0" #endif
-/* Note that some ethernet variables are set in state_reset_for_test() */ -#define SANDBOX_ETH_SETTINGS "ipaddr=1.2.3.4\0" +#define SANDBOX_ETH_SETTINGS "ethaddr=00:00:11:22:33:44\0" \ + "eth1addr=00:00:11:22:33:45\0" \ + "eth3addr=00:00:11:22:33:46\0" \ + "eth5addr=00:00:11:22:33:47\0" \ + "ipaddr=1.2.3.4\0"
#define MEM_LAYOUT_ENV_SETTINGS \ "bootm_size=0x10000000\0" \ diff --git a/include/env.h b/include/env.h index bc48a72cde9..b72239f6a58 100644 --- a/include/env.h +++ b/include/env.h @@ -145,18 +145,6 @@ int env_get_yesno(const char *var); */ int env_set(const char *varname, const char *value);
-/** - * env_set_for_test() - Set the value of a variable for testing - * - * This works as if the variable value was defined in the built-in environment, - * so uses a flags value of 0. This should only be used in tests. - * - * @varname: Variable to adjust - * @value: Value to set for the variable (cannot be NULL) - * @return 0 if OK, 1 on error - */ -int env_set_for_test(const char *varname, const char *value); - /** * env_get_ulong() - Return an environment variable as an integer value * diff --git a/net/eth-uclass.c b/net/eth-uclass.c index 6c195361385..3bd98b01ad3 100644 --- a/net/eth-uclass.c +++ b/net/eth-uclass.c @@ -485,12 +485,6 @@ static int eth_post_probe(struct udevice *dev) struct eth_device_priv *priv = dev->uclass_priv; struct eth_pdata *pdata = dev->platdata; unsigned char env_enetaddr[ARP_HLEN]; - /* - * These warnings always appear on sandbox and are not useful. They have - * been here for some time and the issue has not been resolved. So for - * now, disable them. - */ - bool show_warnings = !IS_ENABLED(CONFIG_SANDBOX);
#if defined(CONFIG_NEEDS_MANUAL_RELOC) struct eth_ops *ops = eth_get_ops(dev); @@ -544,9 +538,8 @@ static int eth_post_probe(struct udevice *dev) memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN); } else if (is_valid_ethaddr(pdata->enetaddr)) { eth_env_set_enetaddr_by_index("eth", dev->seq, pdata->enetaddr); - if (show_warnings) - printf("\nWarning: %s using MAC address from ROM\n", - dev->name); + printf("\nWarning: %s using MAC address from ROM\n", + dev->name); } else if (is_zero_ethaddr(pdata->enetaddr) || !is_valid_ethaddr(pdata->enetaddr)) { #ifdef CONFIG_NET_RANDOM_ETHADDR diff --git a/test/dm/test-main.c b/test/dm/test-main.c index 14a520944e8..72648162a91 100644 --- a/test/dm/test-main.c +++ b/test/dm/test-main.c @@ -28,7 +28,7 @@ static int dm_test_init(struct unit_test_state *uts, bool of_live) memset(dms, '\0', sizeof(*dms)); gd->dm_root = NULL; memset(dm_testdrv_op_count, '\0', sizeof(dm_testdrv_op_count)); - state_reset_for_test(state_get_current(), true); + state_reset_for_test(state_get_current());
#ifdef CONFIG_OF_LIVE /* Determine whether to make the live tree available */

Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This reverts commit 96ac4def8b6686de8566b91419ce98cd5765079b.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/sandbox/cpu/state.c | 12 ++---------- arch/sandbox/include/asm/state.h | 5 +---- cmd/nvedit.c | 8 -------- include/configs/sandbox.h | 7 +++++-- include/env.h | 12 ------------ net/eth-uclass.c | 11 ++--------- test/dm/test-main.c | 2 +- 7 files changed, 11 insertions(+), 46 deletions(-)
I don't understand the revert. Is this because the previous patch will break the following patches in this series?
Regards, Bin

Hi Bin,
On Mon, 28 Oct 2019 at 00:16, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This reverts commit 96ac4def8b6686de8566b91419ce98cd5765079b.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
arch/sandbox/cpu/state.c | 12 ++---------- arch/sandbox/include/asm/state.h | 5 +---- cmd/nvedit.c | 8 -------- include/configs/sandbox.h | 7 +++++-- include/env.h | 12 ------------ net/eth-uclass.c | 11 ++--------- test/dm/test-main.c | 2 +- 7 files changed, 11 insertions(+), 46 deletions(-)
I don't understand the revert. Is this because the previous patch will break the following patches in this series?
Yes...despite my efforts the env variables seem to be protected from being changed...so tests fail.
Regards, Simon

We have the ability to enforce a maximum size for SPL but not yet for TPL. Add a new option for this.
Document the size check macro while we are here.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
Makefile | 7 +++++++ common/spl/Kconfig | 8 ++++++++ 2 files changed, 15 insertions(+)
diff --git a/Makefile b/Makefile index cbacf1cfe2c..3a29b5a90f9 100644 --- a/Makefile +++ b/Makefile @@ -806,6 +806,12 @@ else SPL_SIZE_CHECK = endif
+ifneq ($(CONFIG_TPL_SIZE_LIMIT),0) +TPL_SIZE_CHECK = @$(call size_check,$@,$(CONFIG_TPL_SIZE_LIMIT)) +else +TPL_SIZE_CHECK = +endif + # Statically apply RELA-style relocations (currently arm64 only) # This is useful for arm64 where static relocation needs to be performed on # the raw binary, but certain simulators only accept an ELF file (but don't @@ -1795,6 +1801,7 @@ spl/boot.bin: spl/u-boot-spl tpl/u-boot-tpl.bin: tools prepare \ $(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_SPL_OF_PLATDATA),dts/dt.dtb) $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all + $(TPL_SIZE_CHECK)
TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include)
diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 86d7edfee1b..c661809923a 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -1232,6 +1232,14 @@ config TPL
if TPL
+config TPL_SIZE_LIMIT + hex "Maximum size of TPL image" + depends on TPL + default 0 + help + Specifies the maximum length of the U-Boot TPL image. + If this value is zero, it is ignored. + config TPL_HANDOFF bool "Pass hand-off information from TPL to SPL and U-Boot proper" depends on HANDOFF && TPL_BLOBLIST

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
We have the ability to enforce a maximum size for SPL but not yet for TPL. Add a new option for this.
Document the size check macro while we are here.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
Makefile | 7 +++++++ common/spl/Kconfig | 8 ++++++++ 2 files changed, 15 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 2:34 PM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
We have the ability to enforce a maximum size for SPL but not yet for TPL. Add a new option for this.
Document the size check macro while we are here.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
Makefile | 7 +++++++ common/spl/Kconfig | 8 ++++++++ 2 files changed, 15 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

The code in swapcase can be used by other sandbox drivers. Move it into a common place to allow this.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: None Changes in v2: None
drivers/pci/pci_sandbox.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/pci/pci_sandbox.c b/drivers/pci/pci_sandbox.c index 2af2b79c05d..2a38d104a09 100644 --- a/drivers/pci/pci_sandbox.c +++ b/drivers/pci/pci_sandbox.c @@ -8,6 +8,7 @@ #include <dm.h> #include <fdtdec.h> #include <pci.h> +#include <asm/test.h>
#define FDT_DEV_INFO_CELLS 4 #define FDT_DEV_INFO_SIZE (FDT_DEV_INFO_CELLS * sizeof(u32))

Hi Simon,
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
The code in swapcase can be used by other sandbox drivers. Move it into a common place to allow this.
sandbox_pci_read_bar() is already merged in. What's this patch for?
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
drivers/pci/pci_sandbox.c | 1 + 1 file changed, 1 insertion(+)
Regards, Bin

This function can be called before the timer is set up. Make sure that the init function is called so that it works correctly.
This is needed so that bootstage can work correctly in TPL.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v3: - Update commit message
Changes in v2: None
drivers/timer/tsc_timer.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/timer/tsc_timer.c b/drivers/timer/tsc_timer.c index 919caba8a14..f19d2237e4f 100644 --- a/drivers/timer/tsc_timer.c +++ b/drivers/timer/tsc_timer.c @@ -461,6 +461,8 @@ unsigned long notrace timer_early_get_rate(void)
u64 notrace timer_early_get_count(void) { + tsc_timer_ensure_setup(true); + return rdtsc() - gd->arch.tsc_base; }

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This function can be called before the timer is set up. Make sure that the init function is called so that it works correctly.
This is needed so that bootstage can work correctly in TPL.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Update commit message
Changes in v2: None
drivers/timer/tsc_timer.c | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 3:12 PM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
This function can be called before the timer is set up. Make sure that the init function is called so that it works correctly.
This is needed so that bootstage can work correctly in TPL.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3:
- Update commit message
Changes in v2: None
drivers/timer/tsc_timer.c | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
At present binman adds the image base address to the symbol value before it writes it to the binary. This is not correct since the symbol value itself (e.g. image position) has no relationship to the image base.
Fix this and update the tests to cover this case.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
tools/binman/elf.py | 4 +--- tools/binman/test/u_boot_binman_syms.lds | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Mon, Oct 28, 2019 at 11:27 AM Bin Meng bmeng.cn@gmail.com wrote:
On Mon, Oct 21, 2019 at 11:33 AM Simon Glass sjg@chromium.org wrote:
At present binman adds the image base address to the symbol value before it writes it to the binary. This is not correct since the symbol value itself (e.g. image position) has no relationship to the image base.
Fix this and update the tests to cover this case.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v3: None Changes in v2: None
tools/binman/elf.py | 4 +--- tools/binman/test/u_boot_binman_syms.lds | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!
participants (4)
-
Bin Meng
-
Heiko Schocher
-
Simon Glass
-
Stefan Roese