From 6dd18a6568a7272c86f12aec6f657b13fa52a226 Mon Sep 17 00:00:00 2001 From: Vaishnav Achath Date: Fri, 3 Jun 2022 11:32:15 +0530 Subject: [PATCH 01/46] common: spl: spl_spi: add support for dynamic override of sf bus Currently the SPI flash to load from is defined through the compile time config CONFIG_SF_DEFAULT_BUS and CONFIG_SF_DEFAULT_CS, this prevents the loading of binaries from different SPI flash using the same build.E.g. supporting QSPI flash boot and OSPI flash boot on J721E platform is not possible due to this limitation. This commit adds lookup functions spl_spi_boot_bus() and spl_spi_boot_cs for identifying the flash device based on the selected boot device, when not overridden the lookup functions are weakly defined in common/spl/spl_spi.c. Signed-off-by: Vaishnav Achath Reviewed-by: Heiko Schocher --- common/spl/spl_spi.c | 16 +++++++++++++--- include/spl.h | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/common/spl/spl_spi.c b/common/spl/spl_spi.c index cf3f7ef4c0..3eef2f8d68 100644 --- a/common/spl/spl_spi.c +++ b/common/spl/spl_spi.c @@ -71,6 +71,16 @@ unsigned int __weak spl_spi_get_uboot_offs(struct spi_flash *flash) return CONFIG_SYS_SPI_U_BOOT_OFFS; } +u32 __weak spl_spi_boot_bus(void) +{ + return CONFIG_SF_DEFAULT_BUS; +} + +u32 __weak spl_spi_boot_cs(void) +{ + return CONFIG_SF_DEFAULT_CS; +} + /* * The main entry for SPI booting. It's necessary that SDRAM is already * configured and available since this code loads the main U-Boot image @@ -83,15 +93,15 @@ static int spl_spi_load_image(struct spl_image_info *spl_image, unsigned int payload_offs; struct spi_flash *flash; struct image_header *header; + unsigned int sf_bus = spl_spi_boot_bus(); + unsigned int sf_cs = spl_spi_boot_cs(); /* * Load U-Boot image from SPI flash into RAM * In DM mode: defaults speed and mode will be * taken from DT when available */ - - flash = spi_flash_probe(CONFIG_SF_DEFAULT_BUS, - CONFIG_SF_DEFAULT_CS, + flash = spi_flash_probe(sf_bus, sf_cs, CONFIG_SF_DEFAULT_SPEED, CONFIG_SF_DEFAULT_MODE); if (!flash) { diff --git a/include/spl.h b/include/spl.h index 83ac583e0b..cc78bc3e31 100644 --- a/include/spl.h +++ b/include/spl.h @@ -377,6 +377,22 @@ int spl_load_imx_container(struct spl_image_info *spl_image, void preloader_console_init(void); u32 spl_boot_device(void); +/** + * spl_spi_boot_bus() - Lookup function for the SPI boot bus source. + * + * This function returns the SF bus to load from. + * If not overridden, it is weakly defined in common/spl/spl_spi.c. + */ +u32 spl_spi_boot_bus(void); + +/** + * spl_spi_boot_cs() - Lookup function for the SPI boot CS source. + * + * This function returns the SF CS to load from. + * If not overridden, it is weakly defined in common/spl/spl_spi.c. + */ +u32 spl_spi_boot_cs(void); + /** * spl_mmc_boot_mode() - Lookup function for the mode of an MMC boot source. * @boot_device: ID of the device which the MMC driver wants to read From c16b4f14a3f8e8d3d9635caae74cf87a290c53e7 Mon Sep 17 00:00:00 2001 From: Vaishnav Achath Date: Fri, 3 Jun 2022 11:32:16 +0530 Subject: [PATCH 02/46] arm: k3: j721e: add dynamic sf bus override support for j721e implement overrides for spl_spi_boot_bus() and spl_spi_boot_cs() lookup functions according to bootmode selection, so as to support both QSPI and OSPI boot using the same build. Signed-off-by: Vaishnav Achath Reviewed-by: Pratyush Yadav --- arch/arm/mach-k3/j721e_init.c | 11 +++++++++++ arch/arm/mach-k3/sysfw-loader.c | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c index f503f15f19..e56ca6d0f5 100644 --- a/arch/arm/mach-k3/j721e_init.c +++ b/arch/arm/mach-k3/j721e_init.c @@ -355,6 +355,17 @@ static u32 __get_primary_bootmedia(u32 main_devstat, u32 wkup_devstat) return bootmode; } +u32 spl_spi_boot_bus(void) +{ + u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); + u32 main_devstat = readl(CTRLMMR_MAIN_DEVSTAT); + u32 bootmode = ((wkup_devstat & WKUP_DEVSTAT_PRIMARY_BOOTMODE_MASK) >> + WKUP_DEVSTAT_PRIMARY_BOOTMODE_SHIFT) | + ((main_devstat & MAIN_DEVSTAT_BOOT_MODE_B_MASK) << BOOT_MODE_B_SHIFT); + + return (bootmode == BOOT_DEVICE_QSPI) ? 1 : 0; +} + u32 spl_boot_device(void) { u32 wkup_devstat = readl(CTRLMMR_WKUP_DEVSTAT); diff --git a/arch/arm/mach-k3/sysfw-loader.c b/arch/arm/mach-k3/sysfw-loader.c index 988e758629..b3beeca947 100644 --- a/arch/arm/mach-k3/sysfw-loader.c +++ b/arch/arm/mach-k3/sysfw-loader.c @@ -324,9 +324,9 @@ static void *k3_sysfw_get_spi_addr(void) struct udevice *dev; fdt_addr_t addr; int ret; + unsigned int sf_bus = spl_spi_boot_bus(); - ret = uclass_find_device_by_seq(UCLASS_SPI, CONFIG_SF_DEFAULT_BUS, - &dev); + ret = uclass_find_device_by_seq(UCLASS_SPI, sf_bus, &dev); if (ret) return NULL; From e0392596e90488247d4d850168717b6b9f2b90da Mon Sep 17 00:00:00 2001 From: Aswath Govindraju Date: Fri, 10 Jun 2022 18:23:38 +0530 Subject: [PATCH 03/46] board: ti: j721e: Return if there is an error while configuring SerDes While configuring SerDes, errors could be encountered, in these cases, return instead of going ahead. This is will help in booting even if configuration of SerDes fails. Signed-off-by: Aswath Govindraju --- board/ti/j721e/evm.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/board/ti/j721e/evm.c b/board/ti/j721e/evm.c index 105461e1db..5d090048ce 100644 --- a/board/ti/j721e/evm.c +++ b/board/ti/j721e/evm.c @@ -382,19 +382,25 @@ void configure_serdes_torrent(void) ret = uclass_get_device_by_driver(UCLASS_PHY, DM_DRIVER_GET(torrent_phy_provider), &dev); - if (ret) + if (ret) { printf("Torrent init failed:%d\n", ret); + return; + } serdes.dev = dev; serdes.id = 0; ret = generic_phy_init(&serdes); - if (ret) - printf("phy_init failed!!\n"); + if (ret) { + printf("phy_init failed!!: %d\n", ret); + return; + } ret = generic_phy_power_on(&serdes); - if (ret) - printf("phy_power_on failed !!\n"); + if (ret) { + printf("phy_power_on failed!!: %d\n", ret); + return; + } } void configure_serdes_sierra(void) @@ -410,21 +416,27 @@ void configure_serdes_sierra(void) ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(sierra_phy_provider), &dev); - if (ret) + if (ret) { printf("Sierra init failed:%d\n", ret); + return; + } count = device_get_child_count(dev); for (i = 0; i < count; i++) { ret = device_get_child(dev, i, &link_dev); - if (ret) - printf("probe of sierra child node %d failed\n", i); + if (ret) { + printf("probe of sierra child node %d failed: %d\n", i, ret); + return; + } if (link_dev->driver->id == UCLASS_PHY) { link.dev = link_dev; link.id = link_count++; ret = generic_phy_power_on(&link); - if (ret) - printf("phy_power_on failed !!\n"); + if (ret) { + printf("phy_power_on failed!!: %d\n", ret); + return; + } } } } From 39ff0624bc5ad287fced0f60be9b977d07b1813a Mon Sep 17 00:00:00 2001 From: Philippe Schenker Date: Mon, 13 Jun 2022 19:35:21 +0200 Subject: [PATCH 04/46] toradex: tdx-cfg-block: use only snprintf Prevent memory issues that could appear with sprintf. Replace all sprintf occurences with snprintf. Signed-off-by: Philippe Schenker Reviewed-by: Francesco Dolcini Acked-by: Marcel Ziswiler --- board/toradex/common/tdx-common.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/board/toradex/common/tdx-common.c b/board/toradex/common/tdx-common.c index 9db4553e0f..2207818447 100644 --- a/board/toradex/common/tdx-common.c +++ b/board/toradex/common/tdx-common.c @@ -89,11 +89,13 @@ int show_board_info(void) tdx_eth_addr.nic = htonl(tdx_serial << 8); checkboard(); } else { - sprintf(tdx_serial_str, "%08u", tdx_serial); - sprintf(tdx_board_rev_str, "V%1d.%1d%c", - tdx_hw_tag.ver_major, - tdx_hw_tag.ver_minor, - (char)tdx_hw_tag.ver_assembly + 'A'); + snprintf(tdx_serial_str, sizeof(tdx_serial_str), + "%08u", tdx_serial); + snprintf(tdx_board_rev_str, sizeof(tdx_board_rev_str), + "V%1d.%1d%c", + tdx_hw_tag.ver_major, + tdx_hw_tag.ver_minor, + (char)tdx_hw_tag.ver_assembly + 'A'); env_set("serial#", tdx_serial_str); @@ -109,12 +111,13 @@ int show_board_info(void) tdx_carrier_board_name = (char *) toradex_carrier_boards[tdx_car_hw_tag.prodid]; - sprintf(tdx_car_serial_str, "%08u", tdx_car_serial); - sprintf(tdx_car_rev_str, "V%1d.%1d%c", - tdx_car_hw_tag.ver_major, - tdx_car_hw_tag.ver_minor, - (char)tdx_car_hw_tag.ver_assembly + - 'A'); + snprintf(tdx_car_serial_str, sizeof(tdx_car_serial_str), + "%08u", tdx_car_serial); + snprintf(tdx_car_rev_str, sizeof(tdx_car_rev_str), + "V%1d.%1d%c", + tdx_car_hw_tag.ver_major, + tdx_car_hw_tag.ver_minor, + (char)tdx_car_hw_tag.ver_assembly + 'A'); env_set("carrier_serial#", tdx_car_serial_str); printf("Carrier: Toradex %s %s, Serial# %s\n", @@ -170,7 +173,7 @@ int ft_common_board_setup(void *blob, struct bd_info *bd) if (tdx_hw_tag.ver_major) { char prod_id[5]; - sprintf(prod_id, "%04u", tdx_hw_tag.prodid); + snprintf(prod_id, sizeof(prod_id), "%04u", tdx_hw_tag.prodid); fdt_setprop(blob, 0, "toradex,product-id", prod_id, 5); fdt_setprop(blob, 0, "toradex,board-rev", tdx_board_rev_str, From 494ef10c3bf7859e7d21d9e1d608dc0b634451c2 Mon Sep 17 00:00:00 2001 From: Philippe Schenker Date: Mon, 13 Jun 2022 19:35:22 +0200 Subject: [PATCH 05/46] toradex: tdx-cfg-block: use defines for string length With those defines the length can be reused and is in one place extendable. Signed-off-by: Philippe Schenker Reviewed-by: Francesco Dolcini Acked-by: Marcel Ziswiler --- board/toradex/common/tdx-common.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/board/toradex/common/tdx-common.c b/board/toradex/common/tdx-common.c index 2207818447..94e603c14f 100644 --- a/board/toradex/common/tdx-common.c +++ b/board/toradex/common/tdx-common.c @@ -22,13 +22,17 @@ #define TORADEX_OUI 0x00142dUL +#define SERIAL_STR_LEN 8 +#define MODULE_VER_STR_LEN 4 // V1.1 +#define MODULE_REV_STR_LEN 1 // [A-Z] + #ifdef CONFIG_TDX_CFG_BLOCK -static char tdx_serial_str[9]; -static char tdx_board_rev_str[6]; +static char tdx_serial_str[SERIAL_STR_LEN + 1]; +static char tdx_board_rev_str[MODULE_VER_STR_LEN + MODULE_REV_STR_LEN + 1]; #ifdef CONFIG_TDX_CFG_BLOCK_EXTRA -static char tdx_car_serial_str[9]; -static char tdx_car_rev_str[6]; +static char tdx_car_serial_str[SERIAL_STR_LEN + 1]; +static char tdx_car_rev_str[MODULE_VER_STR_LEN + MODULE_REV_STR_LEN + 1]; static char *tdx_carrier_board_name; #endif From 7e27ce16c5d289e5b9712a179e798ea4eb831816 Mon Sep 17 00:00:00 2001 From: Philippe Schenker Date: Mon, 13 Jun 2022 19:35:23 +0200 Subject: [PATCH 06/46] toradex: tdx-cfg-block: extend assembly version There are two decimal digits reserved to encode the module version and revision. This code so far implemented A-Z which used 0-25 of this range. This commit extends the range to make use of all 99 numbers. After capital letters the form with a hashtag and number (e.g. #26) is used. Examples: If the assembly version is between zero and 25 the numbering is as follows, as it also has been before this commit: 0: V0.0A 1: V0.0B ... 25: V0.0Z New numbering of assembly version: If the number is between 26 and 99 the new assembly version name is: 26: V0.0#26 27: V0.0#27 ... 99: V0.0#99 Signed-off-by: Philippe Schenker Reviewed-by: Francesco Dolcini Acked-by: Marcel Ziswiler --- board/toradex/common/tdx-cfg-block.c | 32 ++++++++++++++++++++++++---- board/toradex/common/tdx-common.c | 25 +++++++++++++++++----- 2 files changed, 48 insertions(+), 9 deletions(-) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 6c8cf4592d..678d4e07c2 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -354,6 +354,18 @@ out: return ret; } +static int parse_assembly_string(char *string_to_parse, u16 *assembly) +{ + if (string_to_parse[3] >= 'A' && string_to_parse[3] <= 'Z') + *assembly = string_to_parse[3] - 'A'; + else if (string_to_parse[3] == '#') + *assembly = dectoul(&string_to_parse[4], NULL); + else + return -EINVAL; + + return 0; +} + static int get_cfgblock_interactive(void) { char message[CONFIG_SYS_CBSIZE]; @@ -362,6 +374,7 @@ static int get_cfgblock_interactive(void) char wb = 'n'; char mem8g = 'n'; int len = 0; + int ret = 0; /* Unknown module by default */ tdx_hw_tag.prodid = 0; @@ -545,13 +558,18 @@ static int get_cfgblock_interactive(void) } while (len < 4) { - sprintf(message, "Enter the module version (e.g. V1.1B): V"); + sprintf(message, "Enter the module version (e.g. V1.1B or V1.1#26): V"); len = cli_readline(message); } tdx_hw_tag.ver_major = console_buffer[0] - '0'; tdx_hw_tag.ver_minor = console_buffer[2] - '0'; - tdx_hw_tag.ver_assembly = console_buffer[3] - 'A'; + + ret = parse_assembly_string(console_buffer, &tdx_hw_tag.ver_assembly); + if (ret) { + printf("Parsing module version failed\n"); + return ret; + } while (len < 8) { sprintf(message, "Enter module serial number: "); @@ -754,6 +772,7 @@ static int get_cfgblock_carrier_interactive(void) { char message[CONFIG_SYS_CBSIZE]; int len; + int ret = 0; printf("Supported carrier boards:\n"); printf("CARRIER BOARD NAME\t\t [ID]\n"); @@ -767,13 +786,18 @@ static int get_cfgblock_carrier_interactive(void) tdx_car_hw_tag.prodid = dectoul(console_buffer, NULL); do { - sprintf(message, "Enter carrier board version (e.g. V1.1B): V"); + sprintf(message, "Enter carrier board version (e.g. V1.1B or V1.1#26): V"); len = cli_readline(message); } while (len < 4); tdx_car_hw_tag.ver_major = console_buffer[0] - '0'; tdx_car_hw_tag.ver_minor = console_buffer[2] - '0'; - tdx_car_hw_tag.ver_assembly = console_buffer[3] - 'A'; + + ret = parse_assembly_string(console_buffer, &tdx_car_hw_tag.ver_assembly); + if (ret) { + printf("Parsing module version failed\n"); + return ret; + } while (len < 8) { sprintf(message, "Enter carrier board serial number: "); diff --git a/board/toradex/common/tdx-common.c b/board/toradex/common/tdx-common.c index 94e603c14f..5ad5d00a0d 100644 --- a/board/toradex/common/tdx-common.c +++ b/board/toradex/common/tdx-common.c @@ -24,7 +24,7 @@ #define SERIAL_STR_LEN 8 #define MODULE_VER_STR_LEN 4 // V1.1 -#define MODULE_REV_STR_LEN 1 // [A-Z] +#define MODULE_REV_STR_LEN 3 // [A-Z] or #[26-99] #ifdef CONFIG_TDX_CFG_BLOCK static char tdx_serial_str[SERIAL_STR_LEN + 1]; @@ -83,6 +83,21 @@ void get_board_serial(struct tag_serialnr *serialnr) } #endif /* CONFIG_SERIAL_TAG */ +static const char *get_board_assembly(u16 ver_assembly) +{ + static char ver_name[MODULE_REV_STR_LEN + 1]; + + if (ver_assembly < 26) { + ver_name[0] = (char)ver_assembly + 'A'; + ver_name[1] = '\0'; + } else { + snprintf(ver_name, sizeof(ver_name), + "#%u", ver_assembly); + } + + return ver_name; +} + int show_board_info(void) { unsigned char ethaddr[6]; @@ -96,10 +111,10 @@ int show_board_info(void) snprintf(tdx_serial_str, sizeof(tdx_serial_str), "%08u", tdx_serial); snprintf(tdx_board_rev_str, sizeof(tdx_board_rev_str), - "V%1d.%1d%c", + "V%1d.%1d%s", tdx_hw_tag.ver_major, tdx_hw_tag.ver_minor, - (char)tdx_hw_tag.ver_assembly + 'A'); + get_board_assembly(tdx_hw_tag.ver_assembly)); env_set("serial#", tdx_serial_str); @@ -118,10 +133,10 @@ int show_board_info(void) snprintf(tdx_car_serial_str, sizeof(tdx_car_serial_str), "%08u", tdx_car_serial); snprintf(tdx_car_rev_str, sizeof(tdx_car_rev_str), - "V%1d.%1d%c", + "V%1d.%1d%s", tdx_car_hw_tag.ver_major, tdx_car_hw_tag.ver_minor, - (char)tdx_car_hw_tag.ver_assembly + 'A'); + get_board_assembly(tdx_car_hw_tag.ver_assembly)); env_set("carrier_serial#", tdx_car_serial_str); printf("Carrier: Toradex %s %s, Serial# %s\n", From a04bbb83b4f7d097c28b1ba4a34be950c6fa3fe2 Mon Sep 17 00:00:00 2001 From: Georgi Vlaev Date: Tue, 14 Jun 2022 17:45:30 +0300 Subject: [PATCH 07/46] arm: mach-k3: common: Use ddr_init in spl_enable_dcache The spl_enable_dcache() function calls dram_init_banksize() to get the total memory size. Normally the dram_init_banksize() setups the memory banks, while the total size is reported by ddr_init(). This worked so far for K3 since we set the gd->ram_size in dram_init_banksize() as well. Signed-off-by: Georgi Vlaev Reviewed-by: Tom Rini --- arch/arm/mach-k3/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index b4b75f4e6c..70f6444e79 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -516,7 +516,7 @@ void spl_enable_dcache(void) #if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF)) phys_addr_t ram_top = CONFIG_SYS_SDRAM_BASE; - dram_init_banksize(); + dram_init(); /* reserve TLB table */ gd->arch.tlb_size = PGTABLE_SIZE; From 362b0d2e6eb2fbea8d000f40243e8014d1b4645a Mon Sep 17 00:00:00 2001 From: Georgi Vlaev Date: Tue, 14 Jun 2022 17:45:31 +0300 Subject: [PATCH 08/46] arm: dts: k3-am625-*: Mark memory with u-boot,dm-spl Mark the memory node with u-boot,dm-spl so we can use it from early SPL on both R5 and A53. Signed-off-by: Georgi Vlaev Reviewed-by: Tom Rini --- arch/arm/dts/k3-am625-r5-sk.dts | 1 + arch/arm/dts/k3-am625-sk-u-boot.dtsi | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/arch/arm/dts/k3-am625-r5-sk.dts b/arch/arm/dts/k3-am625-r5-sk.dts index 2691af40a1..5aab858edd 100644 --- a/arch/arm/dts/k3-am625-r5-sk.dts +++ b/arch/arm/dts/k3-am625-r5-sk.dts @@ -28,6 +28,7 @@ /* 2G RAM */ reg = <0x00000000 0x80000000 0x00000000 0x80000000>; + u-boot,dm-spl; }; reserved-memory { diff --git a/arch/arm/dts/k3-am625-sk-u-boot.dtsi b/arch/arm/dts/k3-am625-sk-u-boot.dtsi index e1971ecdfe..159fa36bbe 100644 --- a/arch/arm/dts/k3-am625-sk-u-boot.dtsi +++ b/arch/arm/dts/k3-am625-sk-u-boot.dtsi @@ -13,6 +13,10 @@ aliases { mmc1 = &sdhci1; }; + + memory@80000000 { + u-boot,dm-spl; + }; }; &cbass_main{ From 249e9f3d1966e55a2f3cf56e5b9700990bd72cef Mon Sep 17 00:00:00 2001 From: Georgi Vlaev Date: Tue, 14 Jun 2022 17:45:32 +0300 Subject: [PATCH 09/46] board: ti: am62x: Use fdt functions for ram and bank init Use the appropriate fdtdec_setup_mem_size_base() call in dram_init() and fdtdec_setup_bank_size() in dram_bank_init() to pull these values from DT, where they are already available, instead of hardcoding them. Signed-off-by: Georgi Vlaev Reviewed-by: Tom Rini --- board/ti/am62x/evm.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c index 4dd5e64299..fb5106d1f3 100644 --- a/board/ti/am62x/evm.c +++ b/board/ti/am62x/evm.c @@ -23,17 +23,10 @@ int board_init(void) int dram_init(void) { - gd->ram_size = 0x80000000; - - return 0; + return fdtdec_setup_mem_size_base(); } int dram_init_banksize(void) { - /* Bank 0 declares the memory available in the DDR low region */ - gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; - gd->bd->bi_dram[0].size = 0x80000000; - gd->ram_size = 0x80000000; - - return 0; + return fdtdec_setup_memory_banksize(); } From 4c092bb306b0443a7386fef8d7c20cf3aa52f54c Mon Sep 17 00:00:00 2001 From: Georgi Vlaev Date: Tue, 14 Jun 2022 17:45:33 +0300 Subject: [PATCH 10/46] board: ti: am62x: Account for DDR size fixups if ECC is enabled Call into k3-ddrss driver to fixup device tree and resize the available amount of DDR if ECC is enabled. A second fixup is required from A53 SPL to take the fixup as done from R5 SPL and apply it to DT passed to A53 U-boot, which in turn passes this to the OS. Signed-off-by: Georgi Vlaev Reviewed-by: Tom Rini --- board/ti/am62x/evm.c | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c index fb5106d1f3..d65ee1d696 100644 --- a/board/ti/am62x/evm.c +++ b/board/ti/am62x/evm.c @@ -9,6 +9,8 @@ #include #include +#include +#include #include #include #include @@ -30,3 +32,54 @@ int dram_init_banksize(void) { return fdtdec_setup_memory_banksize(); } + +#if defined(CONFIG_SPL_BUILD) +#if defined(CONFIG_K3_AM64_DDRSS) +static void fixup_ddr_driver_for_ecc(struct spl_image_info *spl_image) +{ + struct udevice *dev; + int ret; + + dram_init_banksize(); + + ret = uclass_get_device(UCLASS_RAM, 0, &dev); + if (ret) + panic("Cannot get RAM device for ddr size fixup: %d\n", ret); + + ret = k3_ddrss_ddr_fdt_fixup(dev, spl_image->fdt_addr, gd->bd); + if (ret) + printf("Error fixing up ddr node for ECC use! %d\n", ret); +} +#else +static void fixup_memory_node(struct spl_image_info *spl_image) +{ + u64 start[CONFIG_NR_DRAM_BANKS]; + u64 size[CONFIG_NR_DRAM_BANKS]; + int bank; + int ret; + + dram_init(); + dram_init_banksize(); + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + start[bank] = gd->bd->bi_dram[bank].start; + size[bank] = gd->bd->bi_dram[bank].size; + } + + /* dram_init functions use SPL fdt, and we must fixup u-boot fdt */ + ret = fdt_fixup_memory_banks(spl_image->fdt_addr, start, size, + CONFIG_NR_DRAM_BANKS); + if (ret) + printf("Error fixing up memory node! %d\n", ret); +} +#endif + +void spl_perform_fixups(struct spl_image_info *spl_image) +{ +#if defined(CONFIG_K3_AM64_DDRSS) + fixup_ddr_driver_for_ecc(spl_image); +#else + fixup_memory_node(spl_image); +#endif +} +#endif From 6ea5bcc4a6a7a594754e7c82fc0e19da5746df2d Mon Sep 17 00:00:00 2001 From: Georgi Vlaev Date: Tue, 14 Jun 2022 17:45:34 +0300 Subject: [PATCH 11/46] configs: am62x_evm_r5: Add CONFIG_NR_DRAM_BANKS as done in a53 defconfig Add CONFIG_NR_DRAM_BANKS from am62x_evm_a53_defconfig as this is needed to calculate the size of DDR that is available. Signed-off-by: Georgi Vlaev Reviewed-by: Tom Rini --- configs/am62x_evm_r5_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/am62x_evm_r5_defconfig b/configs/am62x_evm_r5_defconfig index 2e340cd6f4..deafb92fc1 100644 --- a/configs/am62x_evm_r5_defconfig +++ b/configs/am62x_evm_r5_defconfig @@ -3,6 +3,7 @@ CONFIG_ARCH_K3=y CONFIG_SYS_MALLOC_F_LEN=0x9000 CONFIG_SPL_LIBCOMMON_SUPPORT=y CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_NR_DRAM_BANKS=2 CONFIG_SOC_K3_AM625=y CONFIG_TARGET_AM625_R5_EVM=y CONFIG_DM_GPIO=y From e4b4501edede200df526dd06af0fdbecf836f2ef Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Wed, 15 Jun 2022 19:33:05 +0530 Subject: [PATCH 12/46] firmware: ti_sci_static_data: Make file board agnostic Static DMA channel data for R5 SPL is mostly board agnostic so use SOC configs instead of EVM specific config to ease adding new board support. Drop J7200 EVM specific settings as its same as J721e Signed-off-by: Vignesh Raghavendra Reviewed-by: Nishanth Menon --- drivers/firmware/ti_sci_static_data.h | 42 +++------------------------ 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/drivers/firmware/ti_sci_static_data.h b/drivers/firmware/ti_sci_static_data.h index 8529ef2900..5ae0556a9a 100644 --- a/drivers/firmware/ti_sci_static_data.h +++ b/drivers/firmware/ti_sci_static_data.h @@ -16,7 +16,7 @@ struct ti_sci_resource_static_data { #if IS_ENABLED(CONFIG_K3_DM_FW) -#if IS_ENABLED(CONFIG_TARGET_J721E_R5_EVM) +#if IS_ENABLED(CONFIG_SOC_K3_J721E) static struct ti_sci_resource_static_data rm_static_data[] = { /* Free rings */ { @@ -48,43 +48,9 @@ static struct ti_sci_resource_static_data rm_static_data[] = { }, { }, }; -#endif /* CONFIG_TARGET_J721E_R5_EVM */ +#endif /* CONFIG_SOC_K3_J721E */ -#if IS_ENABLED(CONFIG_TARGET_J7200_R5_EVM) -static struct ti_sci_resource_static_data rm_static_data[] = { - /* Free rings */ - { - .dev_id = 235, - .subtype = 1, - .range_start = 124, - .range_num = 32, - }, - /* TX channels */ - { - .dev_id = 236, - .subtype = 13, - .range_start = 6, - .range_num = 2, - }, - /* RX channels */ - { - .dev_id = 236, - .subtype = 10, - .range_start = 6, - .range_num = 2, - }, - /* RX Free flows */ - { - .dev_id = 236, - .subtype = 0, - .range_start = 60, - .range_num = 8, - }, - { }, -}; -#endif /* CONFIG_TARGET_J7200_R5_EVM */ - -#if IS_ENABLED(CONFIG_TARGET_J721S2_R5_EVM) +#if IS_ENABLED(CONFIG_SOC_K3_J721S2) static struct ti_sci_resource_static_data rm_static_data[] = { /* Free rings */ { @@ -116,7 +82,7 @@ static struct ti_sci_resource_static_data rm_static_data[] = { }, { }, }; -#endif /* CONFIG_TARGET_J721S2_R5_EVM */ +#endif /* CONFIG_SOC_K3_J721S2 */ #if IS_ENABLED(CONFIG_SOC_K3_AM625) static struct ti_sci_resource_static_data rm_static_data[] = { From 8b5218e7cb9ff4223f2825c04e45dabccbd15a48 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 17 Jun 2022 13:26:10 -0500 Subject: [PATCH 13/46] board: ti: common: Optimize boot when detecting consecutive bad records The eeprom data area is much bigger than the data we intend to store, however, with bad programming, we might end up reading bad records over and over till we run out of eeprom space. instead just exit when 10 consecutive records are read. Signed-off-by: Nishanth Menon Reviewed-by: Tom Rini --- board/ti/common/board_detect.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c index de92eb0981..381cddc00a 100644 --- a/board/ti/common/board_detect.c +++ b/board/ti/common/board_detect.c @@ -434,6 +434,7 @@ int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr, struct ti_am6_eeprom_record_board_id board_id; struct ti_am6_eeprom_record record; int rc; + int consecutive_bad_records = 0; /* Initialize with a known bad marker for i2c fails.. */ memset(ep, 0, sizeof(*ep)); @@ -470,7 +471,7 @@ int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr, */ eeprom_addr = sizeof(board_id); - while (true) { + while (consecutive_bad_records < 10) { rc = dm_i2c_read(dev, eeprom_addr, (uint8_t *)&record.header, sizeof(record.header)); if (rc) @@ -506,6 +507,7 @@ int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr, pr_err("%s: EEPROM parsing error!\n", __func__); return rc; } + consecutive_bad_records = 0; } else { /* * We may get here in case of larger records which @@ -513,6 +515,7 @@ int __maybe_unused ti_i2c_eeprom_am6_get(int bus_addr, int dev_addr, */ pr_err("%s: Ignoring record id %u\n", __func__, record.header.id); + consecutive_bad_records++; } eeprom_addr += record.header.len; From bc1de483711c30e32dffdf71574aa878c1087ed0 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 17 Jun 2022 13:26:11 -0500 Subject: [PATCH 14/46] board: ti: common: Handle the legacy eeprom address width properly Due to supply chain issues, we are starting to see a mixture of eeprom usage including the smaller 7-bit addressing eeproms such as 24c04 used for eeproms. These eeproms don't respond well to 2 byte addressing and fail the read operation. We do have a check to ensure that we are reading the alternate addressing size, however the valid failure prevents us from checking at 1 byte anymore. Rectify the same by falling through and depend on header data comparison to ensure that we have valid data. Signed-off-by: Nishanth Menon Reviewed-by: Tom Rini --- board/ti/common/board_detect.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c index 381cddc00a..0806dea11e 100644 --- a/board/ti/common/board_detect.c +++ b/board/ti/common/board_detect.c @@ -86,7 +86,7 @@ __weak void gpi2c_init(void) static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, u32 header, u32 size, uint8_t *ep) { - u32 hdr_read; + u32 hdr_read = 0xdeadbeef; int rc; #if CONFIG_IS_ENABLED(DM_I2C) @@ -107,9 +107,13 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, if (rc) return rc; - rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4); - if (rc) - return rc; + /* + * Skip checking result here since this could be a valid i2c read fail + * on some boards that use 1 byte addressing. + * We must allow for fall through to check the data if 1 byte + * addressing works + */ + (void)dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4); /* Corrupted data??? */ if (hdr_read != header) { @@ -144,9 +148,13 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, */ byte = 2; - rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4); - if (rc) - return rc; + /* + * Skip checking result here since this could be a valid i2c read fail + * on some boards that use 1 byte addressing. + * We must allow for fall through to check the data if 1 byte + * addressing works + */ + (void)i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4); /* Corrupted data??? */ if (hdr_read != header) { From a58147c2dbbfbc436ba84463678e943146bcae7d Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Fri, 17 Jun 2022 13:26:12 -0500 Subject: [PATCH 15/46] board: ti: common: board_detect: Do 1byte address checks first. Do 1 byte address checks first prior to doing 2 byte address checks. When performing 2 byte addressing on 1 byte addressing eeprom, the second byte is taken in as a write operation and ends up erasing the eeprom region we want to preserve. While we could have theoretically handled this by ensuring the write protect of the eeproms are properly managed, this is not true in case where board are updated with 1 byte eeproms to handle supply status. Flipping the checks by checking for 1 byte addressing prior to 2 byte addressing check prevents this problem at the minor cost of additional overhead for boards with 2 byte addressing eeproms. Signed-off-by: Nishanth Menon Reviewed-by: Tom Rini --- board/ti/common/board_detect.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c index 0806dea11e..ed34991377 100644 --- a/board/ti/common/board_detect.c +++ b/board/ti/common/board_detect.c @@ -103,14 +103,14 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, /* * Read the header first then only read the other contents. */ - rc = i2c_set_chip_offset_len(dev, 2); + rc = i2c_set_chip_offset_len(dev, 1); if (rc) return rc; /* * Skip checking result here since this could be a valid i2c read fail - * on some boards that use 1 byte addressing. - * We must allow for fall through to check the data if 1 byte + * on some boards that use 2 byte addressing. + * We must allow for fall through to check the data if 2 byte * addressing works */ (void)dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4); @@ -119,9 +119,9 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, if (hdr_read != header) { /* * read the eeprom header using i2c again, but use only a - * 1 byte address (some legacy boards need this..) + * 2 byte address (some newer boards need this..) */ - rc = i2c_set_chip_offset_len(dev, 1); + rc = i2c_set_chip_offset_len(dev, 2); if (rc) return rc; @@ -146,12 +146,12 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, /* * Read the header first then only read the other contents. */ - byte = 2; + byte = 1; /* * Skip checking result here since this could be a valid i2c read fail - * on some boards that use 1 byte addressing. - * We must allow for fall through to check the data if 1 byte + * on some boards that use 2 byte addressing. + * We must allow for fall through to check the data if 2 byte * addressing works */ (void)i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4); @@ -160,9 +160,9 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr, if (hdr_read != header) { /* * read the eeprom header using i2c again, but use only a - * 1 byte address (some legacy boards need this..) + * 2 byte address (some newer boards need this..) */ - byte = 1; + byte = 2; rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4); if (rc) From 1cf4e79f5776e9cc451b7f4affec7e47db9533f9 Mon Sep 17 00:00:00 2001 From: Philippe Schenker Date: Mon, 20 Jun 2022 16:57:45 +0200 Subject: [PATCH 16/46] toradex: tdx-cfg-block: add new toradex oui range Add new Toradex MAC OUI (8c:06:cb), to the config block. With this change we extend the possible serial-numbers as follows: For serial-numbers 00000000-16777215 OUI 00:14:2d is taken For serial-numbers 16777216-33554431 OUI 8c:06:cb is taken Lower 24-bit of the serial number are used in the NIC part of the MAC address, the complete serial number can be calculated using the OUI. Signed-off-by: Philippe Schenker Reviewed-by: Francesco Dolcini Reviewed-by: Fabio Estevam Acked-by: Marcel Ziswiler --- board/toradex/common/tdx-cfg-block.c | 42 +++++++++++++++++++++++++--- board/toradex/common/tdx-cfg-block.h | 2 ++ board/toradex/common/tdx-common.c | 5 +--- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/board/toradex/common/tdx-cfg-block.c b/board/toradex/common/tdx-cfg-block.c index 678d4e07c2..9305709a3c 100644 --- a/board/toradex/common/tdx-cfg-block.c +++ b/board/toradex/common/tdx-cfg-block.c @@ -159,6 +159,42 @@ const char * const toradex_display_adapters[] = { [159] = "Verdin DSI to LVDS Adapter", }; +const u32 toradex_ouis[] = { + [0] = 0x00142dUL, + [1] = 0x8c06cbUL, +}; + +static u32 get_serial_from_mac(struct toradex_eth_addr *eth_addr) +{ + int i; + u32 oui = ntohl(eth_addr->oui) >> 8; + u32 nic = ntohl(eth_addr->nic) >> 8; + + for (i = 0; i < ARRAY_SIZE(toradex_ouis); i++) { + if (toradex_ouis[i] == oui) + break; + } + + return (u32)((i << 24) + nic); +} + +void get_mac_from_serial(u32 tdx_serial, struct toradex_eth_addr *eth_addr) +{ + u8 oui_index = tdx_serial >> 24; + u32 nic = tdx_serial & GENMASK(23, 0); + u32 oui; + + if (oui_index >= ARRAY_SIZE(toradex_ouis)) { + puts("Can't find OUI for this serial#\n"); + oui_index = 0; + } + + oui = toradex_ouis[oui_index]; + + eth_addr->oui = htonl(oui << 8); + eth_addr->nic = htonl(nic << 8); +} + #ifdef CONFIG_TDX_CFG_BLOCK_IS_IN_MMC static int tdx_cfg_block_mmc_storage(u8 *config_block, int write) { @@ -331,8 +367,7 @@ int read_tdx_cfg_block(void) memcpy(&tdx_eth_addr, config_block + offset, 6); - /* NIC part of MAC address is serial number */ - tdx_serial = ntohl(tdx_eth_addr.nic) >> 8; + tdx_serial = get_serial_from_mac(&tdx_eth_addr); break; case TAG_HW: memcpy(&tdx_hw_tag, config_block + offset, 8); @@ -974,8 +1009,7 @@ static int do_cfgblock_create(struct cmd_tbl *cmdtp, int flag, int argc, } /* Convert serial number to MAC address (the storage format) */ - tdx_eth_addr.oui = htonl(0x00142dUL << 8); - tdx_eth_addr.nic = htonl(tdx_serial << 8); + get_mac_from_serial(tdx_serial, &tdx_eth_addr); /* Valid Tag */ write_tag(config_block, &offset, TAG_VALID, NULL, 0); diff --git a/board/toradex/common/tdx-cfg-block.h b/board/toradex/common/tdx-cfg-block.h index 43e662e41d..1790698486 100644 --- a/board/toradex/common/tdx-cfg-block.h +++ b/board/toradex/common/tdx-cfg-block.h @@ -114,4 +114,6 @@ int read_tdx_cfg_block_carrier(void); int try_migrate_tdx_cfg_block_carrier(void); +void get_mac_from_serial(u32 tdx_serial, struct toradex_eth_addr *eth_addr); + #endif /* _TDX_CFG_BLOCK_H */ diff --git a/board/toradex/common/tdx-common.c b/board/toradex/common/tdx-common.c index 5ad5d00a0d..3798bf9537 100644 --- a/board/toradex/common/tdx-common.c +++ b/board/toradex/common/tdx-common.c @@ -20,8 +20,6 @@ #include #include "tdx-common.h" -#define TORADEX_OUI 0x00142dUL - #define SERIAL_STR_LEN 8 #define MODULE_VER_STR_LEN 4 // V1.1 #define MODULE_REV_STR_LEN 3 // [A-Z] or #[26-99] @@ -104,8 +102,7 @@ int show_board_info(void) if (read_tdx_cfg_block()) { printf("MISSING TORADEX CONFIG BLOCK\n"); - tdx_eth_addr.oui = htonl(TORADEX_OUI << 8); - tdx_eth_addr.nic = htonl(tdx_serial << 8); + get_mac_from_serial(tdx_serial, &tdx_eth_addr); checkboard(); } else { snprintf(tdx_serial_str, sizeof(tdx_serial_str), From fdd08f896bcfc513a4cb7799d0094e4fabc73531 Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Tue, 21 Jun 2022 17:03:38 +0800 Subject: [PATCH 17/46] phy: nuvoton: add NPCM7xx phy control driver add BMC NPCM750 phy control driver Signed-off-by: Jim Liu --- drivers/phy/Kconfig | 7 ++ drivers/phy/Makefile | 1 + drivers/phy/phy-npcm-usb.c | 215 +++++++++++++++++++++++++++++++++++++ 3 files changed, 223 insertions(+) create mode 100644 drivers/phy/phy-npcm-usb.c diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig index c01d9e09b9..4a3856d3c2 100644 --- a/drivers/phy/Kconfig +++ b/drivers/phy/Kconfig @@ -274,6 +274,13 @@ config PHY_MTK_TPHY multi-ports is first version, otherwise is second veriosn, so you can easily distinguish them by banks layout. +config PHY_NPCM_USB + bool "Nuvoton NPCM USB PHY support" + depends on PHY + depends on ARCH_NPCM + help + Support the USB PHY in NPCM SoCs + config PHY_IMX8MQ_USB bool "NXP i.MX8MQ/i.MX8MP USB PHY Driver" depends on PHY diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile index bf9b40932f..d95439c425 100644 --- a/drivers/phy/Makefile +++ b/drivers/phy/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_MT7620_USB_PHY) += mt7620-usb-phy.o obj-$(CONFIG_MT76X8_USB_PHY) += mt76x8-usb-phy.o obj-$(CONFIG_PHY_DA8XX_USB) += phy-da8xx-usb.o obj-$(CONFIG_PHY_MTK_TPHY) += phy-mtk-tphy.o +obj-$(CONFIG_PHY_NPCM_USB) += phy-npcm-usb.o obj-$(CONFIG_PHY_IMX8MQ_USB) += phy-imx8mq-usb.o obj-$(CONFIG_PHY_XILINX_ZYNQMP) += phy-zynqmp.o obj-y += cadence/ diff --git a/drivers/phy/phy-npcm-usb.c b/drivers/phy/phy-npcm-usb.c new file mode 100644 index 0000000000..24eba66554 --- /dev/null +++ b/drivers/phy/phy-npcm-usb.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2021 Nuvoton Technology Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* GCR Register Offsets */ +#define GCR_INTCR3 0x9C +#define GCR_USB1PHYCTL 0x140 +#define GCR_USB2PHYCTL 0x144 +#define GCR_USB3PHYCTL 0x148 + +/* USBnPHYCTL bit fields */ +#define PHYCTL_RS BIT(28) + +#define USBPHY2SW GENMASK(13, 12) +#define USBPHY3SW GENMASK(15, 14) + +#define USBPHY2SW_DEV9_PHY1 FIELD_PREP(USBPHY2SW, 0) +#define USBPHY2SW_HOST1 FIELD_PREP(USBPHY2SW, 1) +#define USBPHY2SW_DEV9_PHY2 FIELD_PREP(USBPHY2SW, 3) +#define USBPHY3SW_DEV8_PHY1 FIELD_PREP(USBPHY3SW, 0) +#define USBPHY3SW_HOST2 FIELD_PREP(USBPHY3SW, 1) +#define USBPHY3SW_DEV8_PHY3 FIELD_PREP(USBPHY3SW, 3) + +enum controller_id { + UDC0_7, + UDC8, + UDC9, + USBH1, + USBH2, +}; + +enum phy_id { + PHY1 = 1, + PHY2, + PHY3, +}; + +/* Phy Switch Settings */ +#define USBDPHY1 ((PHY1 << 8) | UDC0_7) /* Connect UDC0~7 to PHY1 */ +#define USBD8PHY1 ((PHY1 << 8) | UDC8) /* Connect UDC8 to PHY1 */ +#define USBD9PHY1 ((PHY1 << 8) | UDC9) /* Connect UDC9 to PHY1 */ +#define USBD9PHY2 ((PHY2 << 8) | UDC9) /* Connect UDC9 to PHY2 */ +#define USBH1PHY2 ((PHY2 << 8) | USBH1) /* Connect USBH1 to PHY2 */ +#define USBD8PHY3 ((PHY3 << 8) | UDC8) /* Connect UDC8 to PHY3 */ +#define USBH2PHY3 ((PHY3 << 8) | USBH2) /* Connect USBH2 to PHY3 */ + +struct npcm_usbphy { + struct regmap *syscon; + u8 id; + u16 phy_switch; /* (phy_id << 8) | controller_id */ +}; + +static int npcm_usb_phy_init(struct phy *phy) +{ + struct npcm_usbphy *priv = dev_get_priv(phy->dev); + struct reset_ctl reset; + int ret; + + ret = reset_get_by_index(phy->dev, 0, &reset); + if (ret && ret != -ENOENT && ret != -ENOTSUPP) { + dev_err(phy->dev, "can't get phy reset ctrl (err %d)", ret); + return ret; + } + + /* setup PHY switch */ + switch (priv->phy_switch) { + case USBD8PHY1: + regmap_update_bits(priv->syscon, GCR_INTCR3, USBPHY3SW, + USBPHY3SW_DEV8_PHY1); + break; + case USBD8PHY3: + regmap_update_bits(priv->syscon, GCR_INTCR3, USBPHY3SW, + USBPHY3SW_DEV8_PHY3); + break; + case USBD9PHY1: + regmap_update_bits(priv->syscon, GCR_INTCR3, USBPHY2SW, + USBPHY2SW_DEV9_PHY1); + break; + case USBD9PHY2: + regmap_update_bits(priv->syscon, GCR_INTCR3, USBPHY2SW, + USBPHY2SW_DEV9_PHY2); + break; + case USBH1PHY2: + regmap_update_bits(priv->syscon, GCR_INTCR3, USBPHY2SW, + USBPHY2SW_HOST1); + break; + case USBH2PHY3: + regmap_update_bits(priv->syscon, GCR_INTCR3, USBPHY3SW, + USBPHY3SW_HOST2); + break; + default: + break; + } + /* reset phy */ + if (reset_valid(&reset)) + reset_assert(&reset); + + /* Wait for PHY clocks to stablize for 50us or more */ + udelay(100); + + /* release phy from reset */ + if (reset_valid(&reset)) + reset_deassert(&reset); + + /* PHY RS bit should be set after reset */ + switch (priv->id) { + case PHY1: + regmap_update_bits(priv->syscon, GCR_USB1PHYCTL, PHYCTL_RS, PHYCTL_RS); + break; + case PHY2: + regmap_update_bits(priv->syscon, GCR_USB2PHYCTL, PHYCTL_RS, PHYCTL_RS); + break; + case PHY3: + regmap_update_bits(priv->syscon, GCR_USB3PHYCTL, PHYCTL_RS, PHYCTL_RS); + break; + default: + break; + } + + return 0; +} + +static int npcm_usb_phy_exit(struct phy *phy) +{ + struct npcm_usbphy *priv = dev_get_priv(phy->dev); + + /* set PHY switch to default state */ + switch (priv->phy_switch) { + case USBD8PHY1: + case USBD8PHY3: + regmap_update_bits(priv->syscon, GCR_INTCR3, USBPHY3SW, + USBPHY3SW_HOST2); + break; + case USBD9PHY1: + case USBD9PHY2: + regmap_update_bits(priv->syscon, GCR_INTCR3, USBPHY2SW, + USBPHY2SW_HOST1); + break; + default: + break; + } + return 0; +} + +static int npcm_usb_phy_xlate(struct phy *phy, struct ofnode_phandle_args *args) +{ + struct npcm_usbphy *priv = dev_get_priv(phy->dev); + u16 phy_switch; + + if (args->args_count < 1 || args->args[0] > USBH2) + return -EINVAL; + + phy_switch = (priv->id << 8) | args->args[0]; + switch (phy_switch) { + case USBD9PHY1: + case USBH2PHY3: + case USBD8PHY3: + if (!IS_ENABLED(CONFIG_ARCH_NPCM8XX)) + return -EINVAL; + case USBDPHY1: + case USBD8PHY1: + case USBD9PHY2: + case USBH1PHY2: + priv->phy_switch = phy_switch; + return 0; + default: + return -EINVAL; + } +} + +static int npcm_usb_phy_probe(struct udevice *dev) +{ + struct npcm_usbphy *priv = dev_get_priv(dev); + + priv->syscon = syscon_regmap_lookup_by_phandle(dev->parent, "syscon"); + if (IS_ERR(priv->syscon)) { + dev_err(dev, "%s: unable to get syscon\n", __func__); + return PTR_ERR(priv->syscon); + } + priv->id = dev_read_u32_default(dev, "reg", -1); + + return 0; +} + +static const struct udevice_id npcm_phy_ids[] = { + { .compatible = "nuvoton,npcm845-usb-phy",}, + { .compatible = "nuvoton,npcm750-usb-phy",}, + { } +}; + +static struct phy_ops npcm_phy_ops = { + .init = npcm_usb_phy_init, + .exit = npcm_usb_phy_exit, + .of_xlate = npcm_usb_phy_xlate, +}; + +U_BOOT_DRIVER(npcm_phy) = { + .name = "npcm-usb-phy", + .id = UCLASS_PHY, + .of_match = npcm_phy_ids, + .ops = &npcm_phy_ops, + .probe = npcm_usb_phy_probe, + .priv_auto = sizeof(struct npcm_usbphy), +}; From 10c8bafbc3cd9a6434318b82b64444488b7dd677 Mon Sep 17 00:00:00 2001 From: Bryan Brattlof Date: Tue, 21 Jun 2022 16:36:03 -0500 Subject: [PATCH 18/46] soc: soc_ti_k3: identify j7200 SR2.0 SoCs Anytime a new revision of a chip is produced, Texas Instruments will increment the 4 bit VARIANT section of the CTRLMMR_WKUP_JTAGID register by one. Typically this will be decoded as SR1.0 -> SR2.0 ... however a few TI SoCs do not follow this convention. Rather than defining a revision string array for each SoC, use a default revision string array for all TI SoCs that continue to follow the typical 1.0 -> 2.0 revision scheme. Signed-off-by: Bryan Brattlof --- drivers/soc/soc_ti_k3.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/soc/soc_ti_k3.c b/drivers/soc/soc_ti_k3.c index 42344145f9..b1e7c4ae5f 100644 --- a/drivers/soc/soc_ti_k3.c +++ b/drivers/soc/soc_ti_k3.c @@ -64,8 +64,8 @@ static char *j721e_rev_string_map[] = { "1.0", "1.1", }; -static char *am65x_rev_string_map[] = { - "1.0", "2.0", +static char *typical_rev_string_map[] = { + "1.0", "2.0", "3.0", }; static const char *get_rev_string(u32 idreg) @@ -82,16 +82,10 @@ static const char *get_rev_string(u32 idreg) goto bail; return j721e_rev_string_map[rev]; - case AM65X: - if (rev > ARRAY_SIZE(am65x_rev_string_map)) - goto bail; - return am65x_rev_string_map[rev]; - - case AM64X: - case J7200: default: - if (!rev) - return "1.0"; + if (rev > ARRAY_SIZE(typical_rev_string_map)) + goto bail; + return typical_rev_string_map[rev]; }; bail: From 8c3019216edd18297527c3c0926c319eca2a43f5 Mon Sep 17 00:00:00 2001 From: Eddie James Date: Thu, 23 Jun 2022 14:40:31 +0930 Subject: [PATCH 19/46] ARM: dts: ast2600: Add I2C pinctrl Set the pinctrl groups for each I2C bus. These are essential to I2C operating correctly. Signed-off-by: Eddie James Reviewed-by: Ryan Chen Signed-off-by: Joel Stanley --- arch/arm/dts/ast2600.dtsi | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi index 64074309b7..ef5b131ac0 100644 --- a/arch/arm/dts/ast2600.dtsi +++ b/arch/arm/dts/ast2600.dtsi @@ -833,6 +833,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c1_default>; status = "disabled"; }; @@ -846,6 +848,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c2_default>; status = "disabled"; }; @@ -859,6 +863,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c3_default>; }; i2c3: i2c@200 { @@ -871,6 +877,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c4_default>; }; i2c4: i2c@280 { @@ -883,6 +891,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c5_default>; }; i2c5: i2c@300 { @@ -895,6 +905,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c6_default>; }; i2c6: i2c@380 { @@ -907,6 +919,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c7_default>; }; i2c7: i2c@400 { @@ -919,6 +933,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c8_default>; }; i2c8: i2c@480 { @@ -931,6 +947,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c9_default>; }; i2c9: i2c@500 { @@ -943,6 +961,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c10_default>; status = "disabled"; }; @@ -956,6 +976,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c11_default>; status = "disabled"; }; @@ -969,6 +991,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c12_default>; status = "disabled"; }; @@ -982,6 +1006,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c13_default>; status = "disabled"; }; @@ -995,6 +1021,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c14_default>; status = "disabled"; }; @@ -1008,6 +1036,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c15_default>; status = "disabled"; }; @@ -1021,6 +1051,8 @@ bus-frequency = <100000>; interrupts = ; clocks = <&scu ASPEED_CLK_APB2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2c16_default>; status = "disabled"; }; @@ -1246,6 +1278,7 @@ function = "I2C1"; groups = "I2C1"; }; + pinctrl_i2c2_default: i2c2_default { function = "I2C2"; groups = "I2C2"; From a87273bc4085854584a19abb65da7562c0967f9e Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:32 +0930 Subject: [PATCH 20/46] ARM: dts: ast2600: Add I2C reset properties The same as the upstream Linux device tree, each i2c bus has a property specifying the reset line. Signed-off-by: Joel Stanley Reviewed-by: Ryan Chen --- arch/arm/dts/ast2600.dtsi | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi index ef5b131ac0..4b23d25ede 100644 --- a/arch/arm/dts/ast2600.dtsi +++ b/arch/arm/dts/ast2600.dtsi @@ -832,6 +832,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c1_default>; @@ -847,6 +848,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2_default>; @@ -862,6 +864,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3_default>; @@ -876,6 +879,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c4_default>; @@ -890,6 +894,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c5_default>; @@ -904,6 +909,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c6_default>; @@ -918,6 +924,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c7_default>; @@ -932,6 +939,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c8_default>; @@ -946,6 +954,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c9_default>; @@ -960,6 +969,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c10_default>; @@ -975,6 +985,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c11_default>; @@ -990,6 +1001,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c12_default>; @@ -1005,6 +1017,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c13_default>; @@ -1020,6 +1033,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c14_default>; @@ -1035,6 +1049,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c15_default>; @@ -1050,6 +1065,7 @@ compatible = "aspeed,ast2600-i2c-bus"; bus-frequency = <100000>; interrupts = ; + resets = <&rst ASPEED_RESET_I2C>; clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c16_default>; From fc28e02404846954a6d294184adcd4fe3ced7da9 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:33 +0930 Subject: [PATCH 21/46] ARM: dts: ast2600: Disable I2C nodes by default Allow boards to enable the buses they use. Signed-off-by: Joel Stanley Reviewed-by: Ryan Chen --- arch/arm/dts/ast2600.dtsi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi index 4b23d25ede..a37d062bca 100644 --- a/arch/arm/dts/ast2600.dtsi +++ b/arch/arm/dts/ast2600.dtsi @@ -868,6 +868,7 @@ clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3_default>; + status = "disabled"; }; i2c3: i2c@200 { @@ -883,6 +884,7 @@ clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c4_default>; + status = "disabled"; }; i2c4: i2c@280 { @@ -898,6 +900,7 @@ clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c5_default>; + status = "disabled"; }; i2c5: i2c@300 { @@ -913,6 +916,7 @@ clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c6_default>; + status = "disabled"; }; i2c6: i2c@380 { @@ -928,6 +932,7 @@ clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c7_default>; + status = "disabled"; }; i2c7: i2c@400 { @@ -943,6 +948,7 @@ clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c8_default>; + status = "disabled"; }; i2c8: i2c@480 { @@ -958,6 +964,7 @@ clocks = <&scu ASPEED_CLK_APB2>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c9_default>; + status = "disabled"; }; i2c9: i2c@500 { From 3ad1d85d3c2163ec11934c77bc8c9aead37e9680 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:34 +0930 Subject: [PATCH 22/46] ARM: dts: ast2600-evb: Remove redundant pinctrl Now that these are in the dtsi we don't need them in the EVB device tree. Signed-off-by: Joel Stanley --- arch/arm/dts/ast2600-evb.dts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/arch/arm/dts/ast2600-evb.dts b/arch/arm/dts/ast2600-evb.dts index 0d65054313..806b76029a 100644 --- a/arch/arm/dts/ast2600-evb.dts +++ b/arch/arm/dts/ast2600-evb.dts @@ -150,37 +150,22 @@ &i2c4 { status = "okay"; - - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c5_default>; }; &i2c5 { status = "okay"; - - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c6_default>; }; &i2c6 { status = "okay"; - - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c7_default>; }; &i2c7 { status = "okay"; - - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c8_default>; }; &i2c8 { status = "okay"; - - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_i2c9_default>; }; &mdio0 { From 5ff466fade1884501acaa76c6e87b7613f250971 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:35 +0930 Subject: [PATCH 23/46] ARM: dts: ast2500-evb: Add I2C devices The EVB has an EEPROM on bus 3 and a LM75 temp sensor on bus 7. Enable those busses we can test the I2C driver. Signed-off-by: Joel Stanley Reviewed-by: Ryan Chen --- arch/arm/dts/ast2500-evb.dts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts index 4796ed445f..874e042bc4 100644 --- a/arch/arm/dts/ast2500-evb.dts +++ b/arch/arm/dts/ast2500-evb.dts @@ -73,3 +73,22 @@ pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sd2_default>; }; + +&i2c3 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c08"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&i2c7 { + status = "okay"; + + lm75@4d { + compatible = "national,lm75"; + reg = <0x4d>; + }; +}; From b45768ebfe11109b995adc65ea7b5dc7228b7ed4 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:36 +0930 Subject: [PATCH 24/46] ARM: dts: ast2600-evb: Add I2C devices The EVB has an EEPROM and ADT8490 temp sensor/fan controller on bus 7, and a LM75 temp sensor on bus 8. Signed-off-by: Joel Stanley --- arch/arm/dts/ast2600-evb.dts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/arm/dts/ast2600-evb.dts b/arch/arm/dts/ast2600-evb.dts index 806b76029a..bb438d57cb 100644 --- a/arch/arm/dts/ast2600-evb.dts +++ b/arch/arm/dts/ast2600-evb.dts @@ -162,10 +162,26 @@ &i2c7 { status = "okay"; + + temp@2e { + compatible = "adi,adt7490"; + reg = <0x2e>; + }; + + eeprom@50 { + compatible = "atmel,24c08"; + reg = <0x50>; + pagesize = <16>; + }; }; &i2c8 { status = "okay"; + + lm75@4d { + compatible = "national,lm75"; + reg = <0x4d>; + }; }; &mdio0 { From 0a8bd97f883c554a4137b4f3a88d0d638c4d1b31 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:37 +0930 Subject: [PATCH 25/46] reset/aspeed: Implement status callback The I2C driver shares a reset line between buses, so allow it to test the state of the reset line before resetting it. Signed-off-by: Joel Stanley Reviewed-by: Ryan Chen --- drivers/reset/reset-ast2500.c | 19 +++++++++++++++++++ drivers/reset/reset-ast2600.c | 17 +++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/drivers/reset/reset-ast2500.c b/drivers/reset/reset-ast2500.c index 0a1dd236af..d9cecf3a72 100644 --- a/drivers/reset/reset-ast2500.c +++ b/drivers/reset/reset-ast2500.c @@ -48,6 +48,24 @@ static int ast2500_reset_deassert(struct reset_ctl *reset_ctl) return 0; } +static int ast2500_reset_status(struct reset_ctl *reset_ctl) +{ + struct ast2500_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2500_scu *scu = priv->scu; + int status; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + status = BIT(reset_ctl->id) & readl(&scu->sysreset_ctrl1); + else + status = BIT(reset_ctl->id - 32) & readl(&scu->sysreset_ctrl2); + + return !!status; +} + + + static int ast2500_reset_probe(struct udevice *dev) { int rc; @@ -79,6 +97,7 @@ static const struct udevice_id ast2500_reset_ids[] = { struct reset_ops ast2500_reset_ops = { .rst_assert = ast2500_reset_assert, .rst_deassert = ast2500_reset_deassert, + .rst_status = ast2500_reset_status, }; U_BOOT_DRIVER(ast2500_reset) = { diff --git a/drivers/reset/reset-ast2600.c b/drivers/reset/reset-ast2600.c index 985235a3ac..1732a450ef 100644 --- a/drivers/reset/reset-ast2600.c +++ b/drivers/reset/reset-ast2600.c @@ -47,6 +47,22 @@ static int ast2600_reset_deassert(struct reset_ctl *reset_ctl) return 0; } +static int ast2600_reset_status(struct reset_ctl *reset_ctl) +{ + struct ast2600_reset_priv *priv = dev_get_priv(reset_ctl->dev); + struct ast2600_scu *scu = priv->scu; + int status; + + debug("%s: reset_ctl->id: %lu\n", __func__, reset_ctl->id); + + if (reset_ctl->id < 32) + status = BIT(reset_ctl->id) & readl(&scu->modrst_ctrl1); + else + status = BIT(reset_ctl->id - 32) & readl(&scu->modrst_ctrl2); + + return !!status; +} + static int ast2600_reset_probe(struct udevice *dev) { int rc; @@ -78,6 +94,7 @@ static const struct udevice_id ast2600_reset_ids[] = { struct reset_ops ast2600_reset_ops = { .rst_assert = ast2600_reset_assert, .rst_deassert = ast2600_reset_deassert, + .rst_status = ast2600_reset_status, }; U_BOOT_DRIVER(ast2600_reset) = { From 453fe1eece2c9358db3e5e28ff6ca1e9403e5b80 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:38 +0930 Subject: [PATCH 26/46] i2c/aspeed: Fix reset control The reset control was written for the ast2500 and directly programs the clocking register. So we can share the code with other SoC generations use the reset device to deassert the I2C reset line. Signed-off-by: Joel Stanley Reviewed-by: Ryan Chen --- drivers/i2c/ast_i2c.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c index 2d3fecaa14..0a93d7c829 100644 --- a/drivers/i2c/ast_i2c.c +++ b/drivers/i2c/ast_i2c.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "ast_i2c.h" @@ -108,19 +109,26 @@ static int ast_i2c_of_to_plat(struct udevice *dev) static int ast_i2c_probe(struct udevice *dev) { - struct ast2500_scu *scu; + struct reset_ctl reset_ctl; + int rc; debug("Enabling I2C%u\n", dev_seq(dev)); /* * Get all I2C devices out of Reset. - * Only needs to be done once, but doing it for every - * device does not hurt. + * + * Only needs to be done once so test before performing reset. */ - scu = ast_get_scu(); - ast_scu_unlock(scu); - clrbits_le32(&scu->sysreset_ctrl1, SCU_SYSRESET_I2C); - ast_scu_lock(scu); + rc = reset_get_by_index(dev, 0, &reset_ctl); + if (rc) { + printf("%s: Failed to get reset signal\n", __func__); + return rc; + } + + if (reset_status(&reset_ctl) > 0) { + reset_assert(&reset_ctl); + reset_deassert(&reset_ctl); + } ast_i2c_init_bus(dev); From 50b23b1c5bc3bb8c43fd8cd13725d146e7251d1d Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:39 +0930 Subject: [PATCH 27/46] i2c/aspeed: Add AST2600 compatible Signed-off-by: Joel Stanley Reviewed-by: Ryan Chen --- drivers/i2c/ast_i2c.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/i2c/ast_i2c.c b/drivers/i2c/ast_i2c.c index 0a93d7c829..c9ffe2d628 100644 --- a/drivers/i2c/ast_i2c.c +++ b/drivers/i2c/ast_i2c.c @@ -351,6 +351,7 @@ static const struct dm_i2c_ops ast_i2c_ops = { static const struct udevice_id ast_i2c_ids[] = { { .compatible = "aspeed,ast2400-i2c-bus" }, { .compatible = "aspeed,ast2500-i2c-bus" }, + { .compatible = "aspeed,ast2600-i2c-bus" }, { }, }; From 93330f28233c47d010ac0d89182a5fa4cbee4b36 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:40 +0930 Subject: [PATCH 28/46] config/ast2600: Enable I2C driver Signed-off-by: Joel Stanley --- configs/evb-ast2600_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 5c4d842660..6aa61d112f 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -69,6 +69,7 @@ CONFIG_HASH_ASPEED=y CONFIG_ASPEED_ACRY=y CONFIG_ASPEED_GPIO=y CONFIG_DM_I2C=y +CONFIG_SYS_I2C_ASPEED=y CONFIG_MISC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ASPEED=y From f760403f83c40dac72599e22aa6b5f2884a43763 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 14:40:41 +0930 Subject: [PATCH 29/46] config/aspeed: Enable EEPROM options To allow testing of the I2C driver, enable the eprom command and the misc driver. Signed-off-by: Joel Stanley --- configs/evb-ast2500_defconfig | 3 +++ configs/evb-ast2600_defconfig | 2 ++ 2 files changed, 5 insertions(+) diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig index 9d2c4f81c5..e56e3b9b12 100644 --- a/configs/evb-ast2500_defconfig +++ b/configs/evb-ast2500_defconfig @@ -20,6 +20,7 @@ CONFIG_HUSH_PARSER=y # CONFIG_AUTO_COMPLETE is not set CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 +CONFIG_CMD_EEPROM=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y @@ -35,6 +36,8 @@ CONFIG_CLK=y CONFIG_ASPEED_GPIO=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_ASPEED=y +CONFIG_MISC=y +CONFIG_I2C_EEPROM=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ASPEED=y CONFIG_PHY_REALTEK=y diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 6aa61d112f..1629a3a074 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -47,6 +47,7 @@ CONFIG_SPL_RAM_DEVICE=y CONFIG_HUSH_PARSER=y CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 +CONFIG_CMD_EEPROM=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y @@ -71,6 +72,7 @@ CONFIG_ASPEED_GPIO=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_ASPEED=y CONFIG_MISC=y +CONFIG_I2C_EEPROM=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ASPEED=y CONFIG_PHY_REALTEK=y From dedf8e31861d930927f270b9f5d01013fc54466c Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:28 +0930 Subject: [PATCH 30/46] ARM: dts: ast2600: Update SDHCI nodes Match the description used by the Linux kernel, except use scu instead of syscon as the phandle. Signed-off-by: Joel Stanley --- arch/arm/dts/ast2600-evb.dts | 24 +++++++-------- arch/arm/dts/ast2600.dtsi | 57 +++++++++++++++--------------------- 2 files changed, 35 insertions(+), 46 deletions(-) diff --git a/arch/arm/dts/ast2600-evb.dts b/arch/arm/dts/ast2600-evb.dts index bb438d57cb..a9bba96816 100644 --- a/arch/arm/dts/ast2600-evb.dts +++ b/arch/arm/dts/ast2600-evb.dts @@ -15,9 +15,9 @@ }; aliases { - mmc0 = &emmc_slot0; - mmc1 = &sdhci_slot0; - mmc2 = &sdhci_slot1; + mmc0 = &emmc; + mmc1 = &sdhci0; + mmc2 = &sdhci1; spi0 = &fmc; spi1 = &spi1; spi2 = &spi2; @@ -134,18 +134,16 @@ }; }; -&emmc { - u-boot,dm-pre-reloc; - timing-phase = <0x700ff>; + +&emmc_controller { + status = "okay"; }; -&emmc_slot0 { - u-boot,dm-pre-reloc; - status = "okay"; - bus-width = <4>; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_emmc_default>; - sdhci-drive-type = <1>; +&emmc { + non-removable; + bus-width = <4>; + max-frequency = <100000000>; + clk-phase-mmc-hs200 = <9>, <225>; }; &i2c4 { diff --git a/arch/arm/dts/ast2600.dtsi b/arch/arm/dts/ast2600.dtsi index a37d062bca..ac8cd4d67d 100644 --- a/arch/arm/dts/ast2600.dtsi +++ b/arch/arm/dts/ast2600.dtsi @@ -416,60 +416,51 @@ status = "disabled"; }; - sdhci: sdhci@1e740000 { - #interrupt-cells = <1>; - compatible = "aspeed,aspeed-sdhci-irq", "simple-mfd"; - reg = <0x1e740000 0x1000>; - interrupts = ; - interrupt-controller; - clocks = <&scu ASPEED_CLK_GATE_SDCLK>, - <&scu ASPEED_CLK_GATE_SDEXTCLK>; - clock-names = "ctrlclk", "extclk"; + sdc: sdc@1e740000 { + compatible = "aspeed,ast2600-sd-controller"; + reg = <0x1e740000 0x100>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x1e740000 0x1000>; + ranges = <0 0x1e740000 0x10000>; + clocks = <&scu ASPEED_CLK_GATE_SDCLK>; + status = "disabled"; - sdhci_slot0: sdhci_slot0@100 { - compatible = "aspeed,sdhci-ast2600"; + sdhci0: sdhci@1e740100 { + compatible = "aspeed,ast2600-sdhci", "sdhci"; reg = <0x100 0x100>; - interrupts = <0>; - interrupt-parent = <&sdhci>; + interrupts = ; sdhci,auto-cmd12; clocks = <&scu ASPEED_CLK_SDIO>; status = "disabled"; }; - sdhci_slot1: sdhci_slot1@200 { - compatible = "aspeed,sdhci-ast2600"; + sdhci1: sdhci@1e740200 { + compatible = "aspeed,ast2600-sdhci", "sdhci"; reg = <0x200 0x100>; - interrupts = <1>; - interrupt-parent = <&sdhci>; + interrupts = ; sdhci,auto-cmd12; clocks = <&scu ASPEED_CLK_SDIO>; status = "disabled"; }; }; - emmc: emmc@1e750000 { - #interrupt-cells = <1>; - compatible = "aspeed,aspeed-emmc-irq", "simple-mfd"; - reg = <0x1e750000 0x1000>; - interrupts = ; - interrupt-controller; - clocks = <&scu ASPEED_CLK_GATE_EMMCCLK>, - <&scu ASPEED_CLK_GATE_EMMCEXTCLK>; - clock-names = "ctrlclk", "extclk"; + emmc_controller: sdc@1e750000 { + compatible = "aspeed,ast2600-sd-controller"; + reg = <0x1e750000 0x100>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x1e750000 0x1000>; + ranges = <0 0x1e750000 0x10000>; + clocks = <&scu ASPEED_CLK_GATE_EMMCCLK>; + status = "disabled"; - emmc_slot0: emmc_slot0@100 { - compatible = "aspeed,emmc-ast2600"; + emmc: sdhci@1e750100 { + compatible = "aspeed,ast2600-sdhci"; reg = <0x100 0x100>; - interrupts = <0>; - interrupt-parent = <&emmc>; + sdhci,auto-cmd12; + interrupts = ; clocks = <&scu ASPEED_CLK_EMMC>; - status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_emmc_default>; }; }; From 0b2a749bc6573a3e66d339d9d74de30c1ab15c46 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:29 +0930 Subject: [PATCH 31/46] ARM: dts: ast2500: Update SDHCI nodes Match the description used by the Linux kernel, except use scu instead of syscon as the phandle. Signed-off-by: Joel Stanley --- arch/arm/dts/ast2500-evb.dts | 4 ++++ arch/arm/dts/ast2500-u-boot.dtsi | 25 ------------------------- arch/arm/dts/ast2500.dtsi | 28 ++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts index 874e042bc4..cc577761fa 100644 --- a/arch/arm/dts/ast2500-evb.dts +++ b/arch/arm/dts/ast2500-evb.dts @@ -60,6 +60,10 @@ pinctrl-0 = <&pinctrl_mac2link_default &pinctrl_mdio2_default>; }; +&sdmmc { + status = "okay"; +}; + &sdhci0 { status = "okay"; diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi index ea60e4c8db..057390fe70 100644 --- a/arch/arm/dts/ast2500-u-boot.dtsi +++ b/arch/arm/dts/ast2500-u-boot.dtsi @@ -28,31 +28,6 @@ clocks = <&scu ASPEED_CLK_MPLL>; resets = <&rst ASPEED_RESET_SDRAM>; }; - - ahb { - u-boot,dm-pre-reloc; - - apb { - u-boot,dm-pre-reloc; - - sdhci0: sdhci@1e740100 { - compatible = "aspeed,ast2500-sdhci"; - reg = <0x1e740100>; - #reset-cells = <1>; - clocks = <&scu ASPEED_CLK_SDIO>; - resets = <&rst ASPEED_RESET_SDIO>; - }; - - sdhci1: sdhci@1e740200 { - compatible = "aspeed,ast2500-sdhci"; - reg = <0x1e740200>; - #reset-cells = <1>; - clocks = <&scu ASPEED_CLK_SDIO>; - resets = <&rst ASPEED_RESET_SDIO>; - }; - }; - - }; }; &uart1 { diff --git a/arch/arm/dts/ast2500.dtsi b/arch/arm/dts/ast2500.dtsi index ee66ef6704..cea08e6f08 100644 --- a/arch/arm/dts/ast2500.dtsi +++ b/arch/arm/dts/ast2500.dtsi @@ -207,6 +207,34 @@ reg = <0x1e720000 0x9000>; // 36K }; + sdmmc: sd-controller@1e740000 { + compatible = "aspeed,ast2500-sd-controller"; + reg = <0x1e740000 0x100>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x1e740000 0x10000>; + clocks = <&scu ASPEED_CLK_GATE_SDCLK>; + status = "disabled"; + + sdhci0: sdhci@100 { + compatible = "aspeed,ast2500-sdhci"; + reg = <0x100 0x100>; + interrupts = <26>; + sdhci,auto-cmd12; + clocks = <&scu ASPEED_CLK_SDIO>; + status = "disabled"; + }; + + sdhci1: sdhci@200 { + compatible = "aspeed,ast2500-sdhci"; + reg = <0x200 0x100>; + interrupts = <26>; + sdhci,auto-cmd12; + clocks = <&scu ASPEED_CLK_SDIO>; + status = "disabled"; + }; + }; + gpio: gpio@1e780000 { #gpio-cells = <2>; gpio-controller; From 67e20f9d65f1de5bc68753beba6f94c87272629b Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:30 +0930 Subject: [PATCH 32/46] clk/aspeed: Add debug message when clock fails A common message across platforms that prints the clock number. Signed-off-by: Joel Stanley --- drivers/clk/aspeed/clk_ast2500.c | 3 +++ drivers/clk/aspeed/clk_ast2600.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c index a1b4496ca2..dcf299548d 100644 --- a/drivers/clk/aspeed/clk_ast2500.c +++ b/drivers/clk/aspeed/clk_ast2500.c @@ -173,6 +173,7 @@ static ulong ast2500_clk_get_rate(struct clk *clk) rate = ast2500_get_uart_clk_rate(priv->scu, 5); break; default: + debug("%s: unknown clk %ld\n", __func__, clk->id); return -ENOENT; } @@ -438,6 +439,7 @@ static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate) new_rate = ast2500_configure_d2pll(priv->scu, rate); break; default: + debug("%s: unknown clk %ld\n", __func__, clk->id); return -ENOENT; } @@ -480,6 +482,7 @@ static int ast2500_clk_enable(struct clk *clk) ast2500_configure_d2pll(priv->scu, D2PLL_DEFAULT_RATE); break; default: + debug("%s: unknown clk %ld\n", __func__, clk->id); return -ENOENT; } diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index f191b0f317..7d85c7f098 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -471,7 +471,7 @@ static ulong ast2600_clk_get_rate(struct clk *clk) rate = ast2600_get_uart_huxclk_rate(priv->scu); break; default: - debug("can't get clk rate\n"); + debug("%s: unknown clk %ld\n", __func__, clk->id); return -ENOENT; } @@ -1098,7 +1098,7 @@ static int ast2600_clk_enable(struct clk *clk) ast2600_enable_rsaclk(priv->scu); break; default: - pr_err("can't enable clk\n"); + debug("%s: unknown clk %ld\n", __func__, clk->id); return -ENOENT; } From 85bb3a4eee1a9822e4cbcdaa250ec58061bdee79 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:31 +0930 Subject: [PATCH 33/46] clk/ast2600: Adjust eMMC clock names Adjust clock to stay compatible with those used by the Linux kernel device tree. Signed-off-by: Joel Stanley --- drivers/clk/aspeed/clk_ast2600.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/clk/aspeed/clk_ast2600.c b/drivers/clk/aspeed/clk_ast2600.c index 7d85c7f098..0df1dc3718 100644 --- a/drivers/clk/aspeed/clk_ast2600.c +++ b/drivers/clk/aspeed/clk_ast2600.c @@ -1073,13 +1073,13 @@ static int ast2600_clk_enable(struct clk *clk) case ASPEED_CLK_GATE_SDCLK: ast2600_enable_sdclk(priv->scu); break; - case ASPEED_CLK_GATE_SDEXTCLK: + case ASPEED_CLK_SDIO: ast2600_enable_extsdclk(priv->scu); break; case ASPEED_CLK_GATE_EMMCCLK: ast2600_enable_emmcclk(priv->scu); break; - case ASPEED_CLK_GATE_EMMCEXTCLK: + case ASPEED_CLK_EMMC: ast2600_enable_extemmcclk(priv->scu); break; case ASPEED_CLK_GATE_FSICLK: From 50204533dc92b570e46b15e0bf2ab3feb57e8690 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:32 +0930 Subject: [PATCH 34/46] clk/ast2500: Add SD clock In order to use the clock from the sdhci driver, add the SD clock. Signed-off-by: Joel Stanley --- drivers/clk/aspeed/clk_ast2500.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c index dcf299548d..623c6915b8 100644 --- a/drivers/clk/aspeed/clk_ast2500.c +++ b/drivers/clk/aspeed/clk_ast2500.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -426,6 +427,25 @@ static ulong ast2500_configure_d2pll(struct ast2500_scu *scu, ulong rate) return new_rate; } +#define SCU_CLKSTOP_SDIO 27 +static ulong ast2500_enable_sdclk(struct ast2500_scu *scu) +{ + u32 reset_bit; + u32 clkstop_bit; + + reset_bit = BIT(ASPEED_RESET_SDIO); + clkstop_bit = BIT(SCU_CLKSTOP_SDIO); + + setbits_le32(&scu->sysreset_ctrl1, reset_bit); + udelay(100); + //enable clk + clrbits_le32(&scu->clk_stop_ctrl1, clkstop_bit); + mdelay(10); + clrbits_le32(&scu->sysreset_ctrl1, reset_bit); + + return 0; +} + static ulong ast2500_clk_set_rate(struct clk *clk, ulong rate) { struct ast2500_clk_priv *priv = dev_get_priv(clk->dev); @@ -481,6 +501,9 @@ static int ast2500_clk_enable(struct clk *clk) case ASPEED_CLK_D2PLL: ast2500_configure_d2pll(priv->scu, D2PLL_DEFAULT_RATE); break; + case ASPEED_CLK_GATE_SDCLK: + ast2500_enable_sdclk(priv->scu); + break; default: debug("%s: unknown clk %ld\n", __func__, clk->id); return -ENOENT; From f49a7a160d8851d1a22928125d317f8ddfb3157b Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:33 +0930 Subject: [PATCH 35/46] mmc/aspeed: Add debuging for clock probe failures Signed-off-by: Joel Stanley --- drivers/mmc/aspeed_sdhci.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c index 4537315719..c71daae975 100644 --- a/drivers/mmc/aspeed_sdhci.c +++ b/drivers/mmc/aspeed_sdhci.c @@ -26,12 +26,16 @@ static int aspeed_sdhci_probe(struct udevice *dev) int ret; ret = clk_get_by_index(dev, 0, &clk); - if (ret) + if (ret) { + debug("%s: clock get failed %d\n", __func__, ret); return ret; + } ret = clk_enable(&clk); - if (ret) + if (ret) { + debug("%s: clock enable failed %d\n", __func__, ret); goto free; + } host->name = dev->name; host->ioaddr = dev_read_addr_ptr(dev); @@ -39,6 +43,7 @@ static int aspeed_sdhci_probe(struct udevice *dev) max_clk = clk_get_rate(&clk); if (IS_ERR_VALUE(max_clk)) { ret = max_clk; + debug("%s: clock rate get failed %d\n", __func__, ret); goto err; } From 66900bc25432ed0f99d6decbf7b383536b3456aa Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:34 +0930 Subject: [PATCH 36/46] mmc/aspeed: Probe from controller The Aspeed SDHCI controller is arranged with some shared control registers, followed by one or two sets of actual SDHCI registers. Adjust the driver to probe this controller device first. The driver then wants to iterate over the child nodes to probe the SDHCI proper: ofnode node; dev_for_each_subnode(node, parent) { struct udevice *dev; int ret; ret = device_bind_driver_to_node(parent, "aspeed_sdhci", ofnode_get_name(node), node, &dev); if (ret) return ret; } However if we did this the sdhci driver would probe twice; once "naturally" from the device tree and a second time due to this code. Instead of doing this we can rely on the probe order, where the controller will be set up before the sdhci devices. A better solution is preferred. Select MISC as the controller driver is implemented as a misc device. Signed-off-by: Joel Stanley --- drivers/mmc/Kconfig | 1 + drivers/mmc/aspeed_sdhci.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 53a6b0093d..b44cd98150 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -502,6 +502,7 @@ config MMC_SDHCI_ASPEED depends on ARCH_ASPEED depends on DM_MMC depends on MMC_SDHCI + select MISC help Enables support for the Aspeed SDHCI 2.0 controller present on Aspeed SoCs. This device is compatible with SD 3.0 and/or MMC 4.3 diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c index c71daae975..5591fa2b08 100644 --- a/drivers/mmc/aspeed_sdhci.c +++ b/drivers/mmc/aspeed_sdhci.c @@ -10,6 +10,7 @@ #include #include #include +#include struct aspeed_sdhci_plat { struct mmc_config cfg; @@ -94,3 +95,23 @@ U_BOOT_DRIVER(aspeed_sdhci_drv) = { .priv_auto = sizeof(struct sdhci_host), .plat_auto = sizeof(struct aspeed_sdhci_plat), }; + + +static int aspeed_sdc_probe(struct udevice *parent) +{ + return 0; +} + +static const struct udevice_id aspeed_sdc_ids[] = { + { .compatible = "aspeed,ast2400-sd-controller" }, + { .compatible = "aspeed,ast2500-sd-controller" }, + { .compatible = "aspeed,ast2600-sd-controller" }, + { } +}; + +U_BOOT_DRIVER(aspeed_sdc_drv) = { + .name = "aspeed_sdc", + .id = UCLASS_MISC, + .of_match = aspeed_sdc_ids, + .probe = aspeed_sdc_probe, +}; From a7d606ff6156928693e19273f6d2f8153d2c7f27 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:35 +0930 Subject: [PATCH 37/46] mmc/aspeed: Enable controller clocks Request and enable the controller level clocks. Signed-off-by: Joel Stanley --- drivers/mmc/aspeed_sdhci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c index 5591fa2b08..9d79bf58cc 100644 --- a/drivers/mmc/aspeed_sdhci.c +++ b/drivers/mmc/aspeed_sdhci.c @@ -99,6 +99,21 @@ U_BOOT_DRIVER(aspeed_sdhci_drv) = { static int aspeed_sdc_probe(struct udevice *parent) { + struct clk clk; + int ret; + + ret = clk_get_by_index(parent, 0, &clk); + if (ret) { + debug("%s: clock get failed %d\n", __func__, ret); + return ret; + } + + ret = clk_enable(&clk); + if (ret) { + debug("%s: clock enable failed %d\n", __func__, ret); + return ret; + } + return 0; } From dc96a8241dfa40f54f6b184a2fa4106511e7761e Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Thu, 23 Jun 2022 18:35:36 +0930 Subject: [PATCH 38/46] config/ast2600: Enable eMMC related boot options Allow booting zImage from ext4 devices with DOS or UEFI partition layouts. Signed-off-by: Joel Stanley --- configs/evb-ast2600_defconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 1629a3a074..e62abbda04 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -47,6 +47,13 @@ CONFIG_SPL_RAM_DEVICE=y CONFIG_HUSH_PARSER=y CONFIG_SYS_CBSIZE=256 CONFIG_SYS_PBSIZE=276 +CONFIG_CMD_BOOTZ=y +# CONFIG_BOOTM_NETBSD is not set +# CONFIG_BOOTM_PLAN9 is not set +# CONFIG_BOOTM_RTEMS is not set +# CONFIG_BOOTM_VXWORKS is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set CONFIG_CMD_EEPROM=y CONFIG_CMD_GPIO=y CONFIG_CMD_I2C=y @@ -55,6 +62,11 @@ CONFIG_CMD_DHCP=y CONFIG_BOOTP_BOOTFILESIZE=y CONFIG_CMD_MII=y CONFIG_CMD_PING=y +CONFIG_CMD_EXT4=y +CONFIG_DOS_PARTITION=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SPL_EFI_PARTITION is not set CONFIG_SPL_OF_CONTROL=y CONFIG_ENV_OVERWRITE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y From 82010a704e97b29de23e15e4d18dd98341f7bae1 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 29 Jun 2022 16:35:19 +0930 Subject: [PATCH 39/46] config/ast2600: Enable CRC32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Useful for testing images with the default hash type. Reviewed-by: Chia-Wei Wang Reviewed-by: Cédric Le Goater Signed-off-by: Joel Stanley --- configs/evb-ast2600_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index e62abbda04..3dcbcd2e36 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -40,6 +40,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_STACK_R=y CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x2000000 CONFIG_SPL_SEPARATE_BSS=y +CONFIG_SPL_CRC32=y CONFIG_SPL_FIT_IMAGE_TINY=y CONFIG_SPL_DM_RESET=y CONFIG_SPL_RAM_SUPPORT=y From c24129e8b2bb3113d84e30b805e6c689664050c9 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 29 Jun 2022 16:35:20 +0930 Subject: [PATCH 40/46] config/ast2600: Make position independent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allows loading one u-boot from another. Useful for testing on hardware. Reviewed-by: Chia-Wei Wang Reviewed-by: Cédric Le Goater Signed-off-by: Joel Stanley --- configs/evb-ast2600_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 3dcbcd2e36..4788c4f4f7 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_SYS_DCACHE_OFF=y +CONFIG_POSITION_INDEPENDENT=y CONFIG_SPL_SYS_THUMB_BUILD=y CONFIG_ARCH_ASPEED=y CONFIG_SYS_TEXT_BASE=0x80000000 From f78a1f21171ce3d098053318b9238d38206ee595 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 29 Jun 2022 16:35:21 +0930 Subject: [PATCH 41/46] config/ast2600: Disable hash hardware accel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The HACE driver lacks support for all the hash types, causing boot to fail with the default FIT configuration which uses CRC32. Additionally the Qemu model or the u-boot driver is unable to correctly compute the SHA256 hash used in a FIT. Disable HACE by default while the above issues are worked out to enable boot testing in Qemu. Reviewed-by: Chia-Wei Wang Reviewed-by: Cédric Le Goater Signed-off-by: Joel Stanley --- configs/evb-ast2600_defconfig | 3 --- 1 file changed, 3 deletions(-) diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 4788c4f4f7..588d78e6e3 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -79,9 +79,6 @@ CONFIG_REGMAP=y CONFIG_SPL_OF_TRANSLATE=y CONFIG_CLK=y CONFIG_SPL_CLK=y -CONFIG_DM_HASH=y -CONFIG_HASH_ASPEED=y -CONFIG_ASPEED_ACRY=y CONFIG_ASPEED_GPIO=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_ASPEED=y From a16175350c3f1706c9bbfd8458c60ea6429034fc Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 29 Jun 2022 16:35:22 +0930 Subject: [PATCH 42/46] spl: Set SPL_MAX_SIZE default for AST2600 The AST2600 bootrom has a max size of 64KB. This can be overridden if the system is running the SPL from SPI NOR and not using secure boot. Signed-off-by: Joel Stanley --- common/spl/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/common/spl/Kconfig b/common/spl/Kconfig index 3fd5644800..4851834f9b 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -82,6 +82,7 @@ config SPL_MAX_SIZE default 0x7fa0 if SUNXI_SRAM_ADDRESS = 0x20000 && !MACH_SUN50I_H616 default 0x7000 if RCAR_GEN3 default 0x5fa0 if SUNXI_SRAM_ADDRESS = 0x0 + default 0x10000 if ASPEED_AST2600 default 0x0 help Maximum size of the SPL image (text, data, rodata, and linker lists From 154cffa16a7b6647e180ed6cef55342b39580aff Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 29 Jun 2022 16:35:23 +0930 Subject: [PATCH 43/46] ast2600: Configure u-boot-with-spl.bin target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The normal way of loading u-boot is as a FIT, so configure u-boot.img as the SPL playload. The u-boot-with-spl.bin target will add padding according to CONFIG_SPL_MAX_SIZE which defaults to 64KB on the AST2600. With this the following simple steps can be used to build and boot a system: make u-boot-with-spl.bin truncate -s 64M u-boot-with-spl.bin qemu-system-arm -nographic -M ast2600-evb \ -drive file=u-boot-with-spl.bin,if=mtd,format=raw Reviewed-by: Cédric Le Goater Reviewed-by: Chia-Wei Wang Signed-off-by: Joel Stanley --- configs/evb-ast2600_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/evb-ast2600_defconfig b/configs/evb-ast2600_defconfig index 588d78e6e3..970d356945 100644 --- a/configs/evb-ast2600_defconfig +++ b/configs/evb-ast2600_defconfig @@ -21,6 +21,8 @@ CONFIG_SPL_SIZE_LIMIT=0x10000 CONFIG_SPL=y # CONFIG_ARMV7_NONSEC is not set CONFIG_SYS_LOAD_ADDR=0x83000000 +CONFIG_SPL_PAYLOAD="u-boot.img" +CONFIG_BUILD_TARGET="u-boot-with-spl.bin" # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set CONFIG_FIT=y CONFIG_SPL_FIT_SIGNATURE=y From 3045d61c1c8e8a628aac02e841010f7cfcce85c1 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 29 Jun 2022 16:35:24 +0930 Subject: [PATCH 44/46] aspeed/spl: Remove OVERLAY from linker script The generic arm linker script contains this section: .bss __rel_dyn_start (OVERLAY) : { ... } The (OVERLAY) syntax in the description causes the .bss section to be included in the NOR area of the image: $ objdump -t -j .bss spl/u-boot-spl SYMBOL TABLE: 0000c61c l d .bss 00000000 .bss 0000c640 l O .bss 00000040 __value.0 0000c68c g O .bss 00000000 __bss_end 0000c61c g O .bss 00000000 __bss_start 0000c680 g O .bss 0000000c stdio_devices This is what the custom linker script tries to avoid, as the NOR area is read-only. Remove the OVERLAY syntax to fix the BSS location: $ objdump -t -j .bss spl/u-boot-spl SYMBOL TABLE: 83000000 l d .bss 00000000 .bss 83000000 l O .bss 00000040 __value.0 0000c61c g O .bss 00000000 __image_copy_end 8300004c g O .bss 00000000 __bss_end 83000000 g O .bss 00000000 __bss_start 83000040 g O .bss 0000000c stdio_devices This restores the state of the linker script before the patch that fixed the linker lists issue. Fixes: f6810b749f2e ("aspeed/ast2600: Fix SPL linker script") Signed-off-by: Joel Stanley --- arch/arm/mach-aspeed/ast2600/u-boot-spl.lds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-aspeed/ast2600/u-boot-spl.lds b/arch/arm/mach-aspeed/ast2600/u-boot-spl.lds index 95a509ba3f..37f0ccd922 100644 --- a/arch/arm/mach-aspeed/ast2600/u-boot-spl.lds +++ b/arch/arm/mach-aspeed/ast2600/u-boot-spl.lds @@ -68,7 +68,7 @@ SECTIONS _image_binary_end = .; - .bss __rel_dyn_start (OVERLAY) : { + .bss : { __bss_start = .; *(.bss*) . = ALIGN(4); From b24087ae64bee572aa5feae91c1ded5ee92dc774 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Wed, 29 Jun 2022 16:35:25 +0930 Subject: [PATCH 45/46] CI: Add Aspeed AST2600 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AST2600 has a Qemu model that allows testing. Create a SPI NOR image containing the combined SPL and u-boot FIT image. Reviewed-by: Chia-Wei Wang Reviewed-by: Cédric Le Goater Signed-off-by: Joel Stanley --- .azure-pipelines.yml | 3 +++ .gitlab-ci.yml | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index 915d5115b1..bc2b437bd9 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -261,6 +261,9 @@ stages: evb_ast2500: TEST_PY_BD: "evb-ast2500" TEST_PY_ID: "--id qemu" + evb_ast2600: + TEST_PY_BD: "evb-ast2600" + TEST_PY_ID: "--id qemu" vexpress_ca9x4: TEST_PY_BD: "vexpress_ca9x4" TEST_PY_ID: "--id qemu" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c6a608f7e2..f9cd417507 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -272,6 +272,12 @@ evb-ast2500 test.py: TEST_PY_ID: "--id qemu" <<: *buildman_and_testpy_dfn +evb-ast2600 test.py: + variables: + TEST_PY_BD: "evb-ast2600" + TEST_PY_ID: "--id qemu" + <<: *buildman_and_testpy_dfn + sandbox_flattree test.py: variables: TEST_PY_BD: "sandbox_flattree" From 847505a3eefdadf44b4a2cc9325c5dcf7aa1cfa2 Mon Sep 17 00:00:00 2001 From: Jim Liu Date: Fri, 24 Jun 2022 16:24:37 +0800 Subject: [PATCH 46/46] misc: nuvoton: Add host interface configuration driver add nuvoton BMC npcm750 host configuration driver Signed-off-by: Jim Liu --- drivers/misc/Kconfig | 6 ++ drivers/misc/Makefile | 1 + drivers/misc/npcm_host_intf.c | 110 ++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+) create mode 100644 drivers/misc/npcm_host_intf.c diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 92264e5935..e839c08c19 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -326,6 +326,12 @@ config MXC_OCOTP Programmable memory pages that are stored on the some Freescale i.MX processors. +config NPCM_HOST + bool "Enable support espi or LPC for Host" + depends on REGMAP && SYSCON + help + Enable NPCM BMC espi or LPC support for Host reading and writing. + config SPL_MXC_OCOTP bool "Enable MXC OCOTP driver in SPL" depends on SPL_MISC && (ARCH_IMX8M || ARCH_MX6 || ARCH_MX7 || ARCH_MX7ULP || ARCH_VF610) diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 0bf05ca05e..022e54e065 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_$(SPL_TPL_)LS2_SFP) += ls2_sfp.o obj-$(CONFIG_$(SPL_)MXC_OCOTP) += mxc_ocotp.o obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o obj-$(CONFIG_NPCM_OTP) += npcm_otp.o +obj-$(CONFIG_NPCM_HOST) += npcm_host_intf.o obj-$(CONFIG_NUVOTON_NCT6102D) += nuvoton_nct6102d.o obj-$(CONFIG_P2SB) += p2sb-uclass.o obj-$(CONFIG_PCA9551_LED) += pca9551_led.o diff --git a/drivers/misc/npcm_host_intf.c b/drivers/misc/npcm_host_intf.c new file mode 100644 index 0000000000..0244e40457 --- /dev/null +++ b/drivers/misc/npcm_host_intf.c @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Host interface (LPC or eSPI) configuration on Nuvoton BMC + * Copyright (c) 2022 Nuvoton Technology Corp. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define SMC_CTL_REG_ADDR 0xc0001001 +#define SMC_CTL_HOSTWAIT 0x80 + +/* GCR Register Offsets */ +#define HIFCR 0x50 +#define MFSEL1 0x260 +#define MFSEL4 0x26c + +/* ESPI Register offsets */ +#define ESPICFG 0x4 +#define ESPIHINDP 0x80 + +/* MFSEL bit fileds */ +#define MFSEL1_LPCSEL BIT(26) +#define MFSEL4_ESPISEL BIT(8) + +/* ESPICFG bit fileds */ +#define CHSUPP_MASK GENMASK(27, 24) +#define IOMODE_MASK GENMASK(9, 8) +#define IOMODE_SDQ FIELD_PREP(IOMODE_MASK, 3) +#define MAXFREQ_MASK GENMASK(12, 10) +#define MAXFREQ_33MHZ FIELD_PREP(MAXFREQ_MASK, 2) + +/* ESPIHINDP bit fileds */ +#define AUTO_SBLD BIT(4) +#define AUTO_HS1 BIT(8) +#define AUTO_HS2 BIT(12) +#define AUTO_HS3 BIT(16) + +static int npcm_host_intf_bind(struct udevice *dev) +{ + struct regmap *syscon; + void __iomem *base; + u32 ch_supp, val; + u32 ioaddr; + const char *type; + int ret; + + /* Release host wait */ + setbits_8(SMC_CTL_REG_ADDR, SMC_CTL_HOSTWAIT); + + syscon = syscon_regmap_lookup_by_phandle(dev, "syscon"); + if (IS_ERR(syscon)) { + dev_err(dev, "%s: unable to get syscon, dev %s\n", __func__, dev->name); + return PTR_ERR(syscon); + } + + ioaddr = dev_read_u32_default(dev, "ioaddr", 0); + if (ioaddr) + regmap_write(syscon, HIFCR, ioaddr); + + type = dev_read_string(dev, "type"); + if (!type) + return -EINVAL; + + if (!strcmp(type, "espi")) { + base = dev_read_addr_ptr(dev); + if (!base) + return -EINVAL; + + ret = dev_read_u32(dev, "channel-support", &ch_supp); + if (ret) + return ret; + + /* Select eSPI pins function */ + regmap_update_bits(syscon, MFSEL1, MFSEL1_LPCSEL, 0); + regmap_update_bits(syscon, MFSEL4, MFSEL4_ESPISEL, MFSEL4_ESPISEL); + + val = AUTO_SBLD | AUTO_HS1 | AUTO_HS2 | AUTO_HS3 | ch_supp; + writel(val, base + ESPIHINDP); + + val = readl(base + ESPICFG); + val &= ~(CHSUPP_MASK | IOMODE_MASK | MAXFREQ_MASK); + val |= IOMODE_SDQ | MAXFREQ_33MHZ | FIELD_PREP(CHSUPP_MASK, ch_supp); + writel(val, base + ESPICFG); + } else if (!strcmp(type, "lpc")) { + /* Select LPC pin function */ + regmap_update_bits(syscon, MFSEL4, MFSEL4_ESPISEL, 0); + regmap_update_bits(syscon, MFSEL1, MFSEL1_LPCSEL, MFSEL1_LPCSEL); + } + + return 0; +} + +static const struct udevice_id npcm_hostintf_ids[] = { + { .compatible = "nuvoton,npcm750-host-intf" }, + { .compatible = "nuvoton,npcm845-host-intf" }, + { } +}; + +U_BOOT_DRIVER(npcm_host_intf) = { + .name = "npcm_host_intf", + .id = UCLASS_MISC, + .of_match = npcm_hostintf_ids, + .bind = npcm_host_intf_bind, +};