Re: [PATCH 1/2] bootcount: Remove legacy I2C driver
Hi Heiko, Thank you for reviewing. On Fri, Oct 13, 2023 at 01:21:41PM +0200, Heiko Schocher wrote: > [...] > > Hmm.. I find some boards in mainline which still use this driver: > > u-boot [master] $ grep -lr BOOTCOUNT_I2C . > ./configs/sandbox_defconfig > ./configs/mx53ppd_defconfig > ./configs/ge_bx50v3_defconfig > [...] > > So your remove patch will break them ... okay sandbox should be > easy to convert to your DM approach patch from this series. > $ git grep -r BOOTCOUNT_I2C configs/ge_bx50v3_defconfig:CONFIG_DM_BOOTCOUNT_I2C_EEPROM=y configs/mx53ppd_defconfig:CONFIG_DM_BOOTCOUNT_I2C_EEPROM=y configs/sandbox_defconfig:CONFIG_DM_BOOTCOUNT_I2C_EEPROM=y Those boards use CONFIG_DM_BOOTCOUNT_I2C_EEPROM, which is not touched by this removal, is it? Best regards, Philip > bye, > Heiko > -- > DENX Software Engineering GmbH, Managing Director: Erika Unter > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: h...@denx.de
Re: [PATCH 2/2] bootcount: Add driver model I2C driver
Hello Heiko, On Fri, Oct 13, 2023 at 01:28:47PM +0200, Heiko Schocher wrote: > [...] > > > > bootcount { > > compatible = "u-boot,bootcount-i2c"; > > i2c-bus = <&i2c1>; > > address = <0x52>; > > Hmm.. do we really need this here with DTS. Why not using a phandle > to a real i2c device? Something like this for example: > > i2cbcdev = &i2c_rtc; > > with > > &i2c1 { > i2c_rtc: rtc@68 { > [...] > > and so there is no need for knowing the bus and address ... > Yeah I agree that would be much better, but ... > [...] > > when you use a phandle, you can replace the part from reading "offset" > with this: > > uclass_get_device_by_phandle(UCLASS_I2C, dev, "i2cbcdev", &priv->bcdev); > > of course plus error checking... This does not work, UCLASS_I2C is used for the *bus above* the device we actually want. Next thing I thougt about: Why not use the UCLASS_I2C_GENERIC. But this expects a "i2c-chip" compatible string, which our rtc or whatever device obviously does not have. I think using UCLASS_I2C_GENERIC might indeed be the best approach. Maybe using something like 'device_bind_driver()'. But again, this expects the parent device to be there already as far as I can tell. Any suggestions? Best regards, Philip > > > + > > + return 0; > > +} > > + > > +static const struct bootcount_ops bootcount_i2c_ops = { > > + .get = bootcount_i2c_get, > > + .set = bootcount_i2c_set, > > +}; > > + > > +static const struct udevice_id bootcount_i2c_ids[] = { > > + { .compatible = "u-boot,bootcount-i2c" }, > > + { } > > +}; > > + > > +U_BOOT_DRIVER(bootcount_i2c) = { > > + .name = "bootcount-i2c", > > + .id = UCLASS_BOOTCOUNT, > > + .priv_auto = sizeof(struct bootcount_i2c_priv), > > + .probe = bootcount_i2c_probe, > > + .of_match = bootcount_i2c_ids, > > + .ops= &bootcount_i2c_ops, > > +}; > > > > bye, > Heiko > -- > DENX Software Engineering GmbH, Managing Director: Erika Unter > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: h...@denx.de
Re: [PATCH 2/2] bootcount: Add driver model I2C driver
Hi Simon, maybe you can give me a hint on how to implement this cleanly in driver model? To sum it up, I'd like to have a phandle pointing to *any* I2C device, not knowing which UCLASS actually fits. Then the device and the parent bus should be probed/prepared such that dm_i2c_read() can be used. Any ideas on this? Best regards, Philip -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de = On Fri, Oct 13, 2023 at 02:58:04PM +0200, Philip Oberfichtner wrote: > Hello Heiko, > > On Fri, Oct 13, 2023 at 01:28:47PM +0200, Heiko Schocher wrote: > > [...] > > > > > > bootcount { > > > compatible = "u-boot,bootcount-i2c"; > > > i2c-bus = <&i2c1>; > > > address = <0x52>; > > > > Hmm.. do we really need this here with DTS. Why not using a phandle > > to a real i2c device? Something like this for example: > > > > i2cbcdev = &i2c_rtc; > > > > with > > > > &i2c1 { > > i2c_rtc: rtc@68 { > > [...] > > > > and so there is no need for knowing the bus and address ... > > > > Yeah I agree that would be much better, but ... > > > [...] > > > > when you use a phandle, you can replace the part from reading "offset" > > with this: > > > > uclass_get_device_by_phandle(UCLASS_I2C, dev, "i2cbcdev", &priv->bcdev); > > > > of course plus error checking... > > This does not work, UCLASS_I2C is used for the *bus above* the device we > actually want. > > Next thing I thougt about: Why not use the UCLASS_I2C_GENERIC. But this > expects a "i2c-chip" compatible string, which our rtc or whatever device > obviously does not have. > > I think using UCLASS_I2C_GENERIC might indeed be the best approach. > Maybe using something like 'device_bind_driver()'. But again, this > expects the parent device to be there already as far as I can tell. > > Any suggestions? > > Best regards, > Philip > > > > > > > + > > > + return 0; > > > +} > > > + > > > +static const struct bootcount_ops bootcount_i2c_ops = { > > > + .get = bootcount_i2c_get, > > > + .set = bootcount_i2c_set, > > > +}; > > > + > > > +static const struct udevice_id bootcount_i2c_ids[] = { > > > + { .compatible = "u-boot,bootcount-i2c" }, > > > + { } > > > +}; > > > + > > > +U_BOOT_DRIVER(bootcount_i2c) = { > > > + .name = "bootcount-i2c", > > > + .id = UCLASS_BOOTCOUNT, > > > + .priv_auto = sizeof(struct bootcount_i2c_priv), > > > + .probe = bootcount_i2c_probe, > > > + .of_match = bootcount_i2c_ids, > > > + .ops= &bootcount_i2c_ops, > > > +}; > > > > > > > bye, > > Heiko > > -- > > DENX Software Engineering GmbH, Managing Director: Erika Unter > > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > > Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: h...@denx.de
Re: [PATCH 2/2] bootcount: Add driver model I2C driver
Hi Heiko, On Wed, Oct 18, 2023 at 06:31:57AM +0200, Heiko Schocher wrote: > [...] > > May Philip can use uclass_get_device_by_phandle and try a list of > possible UCLASS candidates, like UCLASS_RTC, UCLASS_I2C_EEPROM, > UCLASS_POWER,... and if found, check if parent is UCLASS_I2C... > > may not so expensive ... Looks more cheap and elegant than the other variants indeed. But I'm not sure if we can maintain generality using this approach. What if the specific I2C driver is not included in the build, because the devices "actual" functionality is not required? Or what if a driver for the specific device does not even exist in U-Boot? Wouldn't the device fail to probe then? Please correct me if I'm wrong, I'd give it a shot in that case. Otherwise I'll try it with the aforementioned device_find_global_by_ofnode() followed by device_bind_driver() using UCLASS_I2C_GENERIC (I hope that works). Best regards, Philip > > bye, > Heiko > -- > DENX Software Engineering GmbH, Managing Director: Erika Unter > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: h...@denx.de -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de =
Re: [PATCH v2 3/3] bootcount: Add driver model I2C driver
On Mon, Oct 30, 2023 at 06:17:23AM +0100, Heiko Schocher wrote: > > > Your patch drops an checkpatch error: > """ > ERROR: Do not add common.h to files > #164: FILE: drivers/bootcount/bootcount_dm_i2c.c:10: > +#include > """ > > Could you please check and fix? Oops sorry, V3 is on the way. Regards, Philip > > Thanks! > > bye, > Heiko > -- > DENX Software Engineering GmbH, Managing Director: Erika Unter > HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany > Phone: +49-8142-66989-52 Fax: +49-8142-66989-80 Email: h...@denx.de -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de =
[PATCH] bootcount: pmic: Correct misleading comment
Fix a copy-paste error I did when inserting the comment. Signed-off-by: Philip Oberfichtner --- drivers/bootcount/Kconfig | 2 +- drivers/bootcount/pmic_pfuze100.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig index e918f74694..8d6424c9da 100644 --- a/drivers/bootcount/Kconfig +++ b/drivers/bootcount/Kconfig @@ -132,7 +132,7 @@ config DM_BOOTCOUNT_PMIC_PFUZE100 depends on DM_PMIC_PFUZE100 help Enable support for the bootcounter using PMIC PFUZE100 registers. - This works only, if the PMIC is not connected. + This works only, if the PMIC is not connected to a battery. config DM_BOOTCOUNT_SPI_FLASH bool "Support SPI flash devices as a backing store for bootcount" diff --git a/drivers/bootcount/pmic_pfuze100.c b/drivers/bootcount/pmic_pfuze100.c index ad3bc03829..df046f1b0a 100644 --- a/drivers/bootcount/pmic_pfuze100.c +++ b/drivers/bootcount/pmic_pfuze100.c @@ -5,7 +5,7 @@ * Philip Oberfichtner * * A bootcount driver using the registers MEMA - MEMD on the PFUZE100. - * This works only, if the PMIC is not connected. + * This works only, if the PMIC is not connected to a battery. */ #include -- 2.37.2
[PATCH v3 2/3] ARM: cache: Allow SPL to build cache-pl310.c
Introduce the new Kconfig symbol CONFIG_SPL_SYS_L2_PL310 to allow the SPL to build cache-pl310.c. Before this commit, the SPL could enable the PL310 L2 cache [1], but the cache maintenance functions from cache-pl310.c were only useable for non-SPL builds. After enabling the cache one must be able to flush it, too. Thus this commit allows cache-pl310.c to be included in the SPL build. [1] See for example arch/arm/mach-imx/cache.c: v7_outer_cache_enable() Signed-off-by: Philip Oberfichtner --- Changes in v3: - Introduce CONFIG_SPL_SYS_L2_PL310 arch/arm/Kconfig | 5 + arch/arm/lib/Makefile | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index dde06bdd96..0bc03c921a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -493,6 +493,11 @@ config SYS_L2_PL310 help Enable support for ARM PL310 L2 cache controller in U-Boot +config SPL_SYS_L2_PL310 + bool "ARM PL310 L2 cache controller in SPL" + help + Enable support for ARM PL310 L2 cache controller in SPL + config SYS_L2CACHE_OFF bool "L2cache off" help diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c603fe61bc..d137b4bf0f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o -obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o else obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o @@ -46,6 +45,7 @@ else obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o endif +obj-$(CONFIG_$(SPL_TPL_)SYS_L2_PL310) += cache-pl310.o obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o ifneq ($(filter y,$(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR) $(CONFIG_SAVE_PREV_BL_FDT_ADDR)),) -- 2.37.1
[PATCH v3 3/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
From: Marek Vasut Enable d-cache early in SPL right after DRAM is started up. This reduces U-Boot proper load time by 650ms when loaded from SPI NOR. Signed-off-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- Changes in v3: - Use newly introduced Kconfig symbol for dh_imx6_defconfig Changes in v2: - Add comment to explain the relevance of dcache_disable() board/dhelectronics/dh_imx6/dh_imx6_spl.c | 28 +++ configs/dh_imx6_defconfig | 1 + 2 files changed, 29 insertions(+) diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index e49e97724a..4b0e13493d 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,11 +15,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -610,6 +613,20 @@ static void dhcom_spl_dram_init(void) } } +void dram_bank_mmu_setup(int bank) +{ + int i; + + set_section_dcache(ROMCP_ARB_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + set_section_dcache(IRAM_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + + for (i = MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT; + i < ((MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT) + + (SZ_1G >> MMU_SECTION_SHIFT)); + i++) + set_section_dcache(i, DCACHE_DEFAULT_OPTION); +} + void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ @@ -636,9 +653,20 @@ void board_init_f(ulong dummy) /* DDR3 initialization */ dhcom_spl_dram_init(); + /* Set up early MMU tables at the beginning of DRAM and start d-cache */ + gd->arch.tlb_addr = MMDC0_ARB_BASE_ADDR + SZ_32M; + gd->arch.tlb_size = PGTABLE_SIZE; + enable_caches(); + /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ board_init_r(NULL, 0); } + +void spl_board_prepare_for_boot(void) +{ + /* Flush dcache. Without it U-Boot proper would hang at random locations. */ + dcache_disable(); +} diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index 11db9bac2c..e0075e7e87 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -1,5 +1,6 @@ CONFIG_ARM=y CONFIG_SYS_L2_PL310=y +CONFIG_SPL_SYS_L2_PL310=y CONFIG_ARCH_MX6=y CONFIG_SYS_TEXT_BASE=0x1780 CONFIG_SYS_MALLOC_F_LEN=0x1000 -- 2.37.1
[PATCH v3 0/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
This patch series enables d-cache in SPL for i.MX6 based boards from DH in order to improve boot time. This can only be achieved after migrating the corresponding symbols to Kconfig, which is done in patch 1/3 and 2/3. Changes in v3: - Introduce CONFIG_SPL_SYS_L2_PL310 - Convert CONFIG_SYS_L2_PL310 to Kconfig - Use newly introduced Kconfig symbol for dh_imx6_defconfig Changes in v2: - Add comment to explain the relevance of dcache_disable() Marek Vasut (1): ARM: imx6: dh-imx6: Enable d-cache early in SPL Philip Oberfichtner (2): Convert CONFIG_SYS_L2_PL310 to Kconfig ARM: cache: Allow SPL to build cache-pl310.c README| 2 -- arch/arm/Kconfig | 9 arch/arm/lib/Makefile | 2 +- arch/arm/mach-mvebu/include/mach/config.h | 2 -- board/dhelectronics/dh_imx6/dh_imx6_spl.c | 28 +++ configs/am43xx_evm_defconfig | 1 + configs/am43xx_evm_qspiboot_defconfig | 1 + configs/am43xx_evm_rtconly_defconfig | 1 + configs/am43xx_evm_usbhost_boot_defconfig | 1 + configs/am43xx_hs_evm_defconfig | 1 + configs/am43xx_hs_evm_qspi_defconfig | 1 + configs/apalis_imx6_defconfig | 1 + configs/aristainetos2c_defconfig | 1 + configs/aristainetos2ccslb_defconfig | 1 + configs/clearfog_defconfig| 1 + configs/cm_fx6_defconfig | 1 + configs/cm_t43_defconfig | 1 + configs/colibri_imx6_defconfig| 1 + configs/controlcenterdc_defconfig | 1 + configs/crs305-1g-4s-bit_defconfig| 1 + configs/crs305-1g-4s_defconfig| 1 + configs/crs326-24g-2s-bit_defconfig | 1 + configs/crs326-24g-2s_defconfig | 1 + configs/crs328-4c-20s-4s-bit_defconfig| 1 + configs/crs328-4c-20s-4s_defconfig| 1 + configs/db-88f6720_defconfig | 1 + configs/db-88f6820-amc_defconfig | 1 + configs/db-88f6820-gp_defconfig | 1 + configs/db-mv784mp-gp_defconfig | 1 + configs/db-xc3-24g4xg_defconfig | 1 + configs/dh_imx6_defconfig | 2 ++ configs/display5_defconfig| 1 + configs/display5_factory_defconfig| 1 + configs/ds414_defconfig | 1 + configs/ge_b1x5v2_defconfig | 1 + configs/ge_bx50v3_defconfig | 1 + configs/gwventana_emmc_defconfig | 1 + configs/gwventana_gw5904_defconfig| 1 + configs/gwventana_nand_defconfig | 1 + configs/helios4_defconfig | 1 + configs/imx6dl_icore_nand_defconfig | 1 + configs/imx6dl_mamoj_defconfig| 1 + configs/imx6q_bosch_acc_defconfig | 1 + configs/imx6q_icore_nand_defconfig| 1 + configs/imx6q_logic_defconfig | 1 + configs/imx6qdl_icore_mipi_defconfig | 1 + configs/imx6qdl_icore_mmc_defconfig | 1 + configs/imx6qdl_icore_nand_defconfig | 1 + configs/imx6qdl_icore_rqs_defconfig | 1 + configs/kp_imx6q_tpc_defconfig| 1 + configs/marsboard_defconfig | 1 + configs/maxbcm_defconfig | 1 + configs/mccmon6_nor_defconfig | 1 + configs/mccmon6_sd_defconfig | 1 + configs/mx6cuboxi_defconfig | 1 + configs/mx6memcal_defconfig | 1 + configs/mx6qsabrelite_defconfig | 1 + configs/mx6sabreauto_defconfig| 1 + configs/mx6sabresd_defconfig | 1 + configs/mx6slevk_defconfig| 1 + configs/mx6slevk_spinor_defconfig | 1 + configs/mx6slevk_spl_defconfig| 1 + configs/mx6sllevk_defconfig | 1 + configs/mx6sllevk_plugin_defconfig| 1 + configs/mx6sxsabreauto_defconfig | 1 + configs/mx6sxsabresd_defconfig| 1 + configs/nitrogen6dl2g_defconfig | 1 + configs/nitrogen6dl_defconfig | 1 + configs/nitrogen6q2g_defconfig| 1 + configs/nitrogen6q_defconfig | 1 + configs/nitrogen6s1g_defconfig| 1 + configs/nitrogen6s_defconfig | 1 + configs/novena_defconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/pcm058_defconfig | 1 + configs/pico-imx6_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/riotboard_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig| 1 + configs/socfpga_dbm_soc1_defconfig| 1 + configs/socfpga_de0_nano_soc_defconfig| 1 + configs/socfpga_de10_nano_defconfig | 1
[PATCH v3 1/3] Convert CONFIG_SYS_L2_PL310 to Kconfig
This converts CONFIG_SYS_L2_PL310 to Kconfig. Signed-off-by: Philip Oberfichtner --- Changes in v3: new README| 2 -- arch/arm/Kconfig | 4 arch/arm/mach-mvebu/include/mach/config.h | 2 -- configs/am43xx_evm_defconfig | 1 + configs/am43xx_evm_qspiboot_defconfig | 1 + configs/am43xx_evm_rtconly_defconfig | 1 + configs/am43xx_evm_usbhost_boot_defconfig | 1 + configs/am43xx_hs_evm_defconfig | 1 + configs/am43xx_hs_evm_qspi_defconfig | 1 + configs/apalis_imx6_defconfig | 1 + configs/aristainetos2c_defconfig | 1 + configs/aristainetos2ccslb_defconfig | 1 + configs/clearfog_defconfig| 1 + configs/cm_fx6_defconfig | 1 + configs/cm_t43_defconfig | 1 + configs/colibri_imx6_defconfig| 1 + configs/controlcenterdc_defconfig | 1 + configs/crs305-1g-4s-bit_defconfig| 1 + configs/crs305-1g-4s_defconfig| 1 + configs/crs326-24g-2s-bit_defconfig | 1 + configs/crs326-24g-2s_defconfig | 1 + configs/crs328-4c-20s-4s-bit_defconfig| 1 + configs/crs328-4c-20s-4s_defconfig| 1 + configs/db-88f6720_defconfig | 1 + configs/db-88f6820-amc_defconfig | 1 + configs/db-88f6820-gp_defconfig | 1 + configs/db-mv784mp-gp_defconfig | 1 + configs/db-xc3-24g4xg_defconfig | 1 + configs/dh_imx6_defconfig | 1 + configs/display5_defconfig| 1 + configs/display5_factory_defconfig| 1 + configs/ds414_defconfig | 1 + configs/ge_b1x5v2_defconfig | 1 + configs/ge_bx50v3_defconfig | 1 + configs/gwventana_emmc_defconfig | 1 + configs/gwventana_gw5904_defconfig| 1 + configs/gwventana_nand_defconfig | 1 + configs/helios4_defconfig | 1 + configs/imx6dl_icore_nand_defconfig | 1 + configs/imx6dl_mamoj_defconfig| 1 + configs/imx6q_bosch_acc_defconfig | 1 + configs/imx6q_icore_nand_defconfig| 1 + configs/imx6q_logic_defconfig | 1 + configs/imx6qdl_icore_mipi_defconfig | 1 + configs/imx6qdl_icore_mmc_defconfig | 1 + configs/imx6qdl_icore_nand_defconfig | 1 + configs/imx6qdl_icore_rqs_defconfig | 1 + configs/kp_imx6q_tpc_defconfig| 1 + configs/marsboard_defconfig | 1 + configs/maxbcm_defconfig | 1 + configs/mccmon6_nor_defconfig | 1 + configs/mccmon6_sd_defconfig | 1 + configs/mx6cuboxi_defconfig | 1 + configs/mx6memcal_defconfig | 1 + configs/mx6qsabrelite_defconfig | 1 + configs/mx6sabreauto_defconfig| 1 + configs/mx6sabresd_defconfig | 1 + configs/mx6slevk_defconfig| 1 + configs/mx6slevk_spinor_defconfig | 1 + configs/mx6slevk_spl_defconfig| 1 + configs/mx6sllevk_defconfig | 1 + configs/mx6sllevk_plugin_defconfig| 1 + configs/mx6sxsabreauto_defconfig | 1 + configs/mx6sxsabresd_defconfig| 1 + configs/nitrogen6dl2g_defconfig | 1 + configs/nitrogen6dl_defconfig | 1 + configs/nitrogen6q2g_defconfig| 1 + configs/nitrogen6q_defconfig | 1 + configs/nitrogen6s1g_defconfig| 1 + configs/nitrogen6s_defconfig | 1 + configs/novena_defconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/pcm058_defconfig | 1 + configs/pico-imx6_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/riotboard_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig| 1 + configs/socfpga_dbm_soc1_defconfig| 1 + configs/socfpga_de0_nano_soc_defconfig| 1 + configs/socfpga_de10_nano_defconfig | 1 + configs/socfpga_de10_standard_defconfig | 1 + configs/socfpga_de1_soc_defconfig | 1 + configs/socfpga_is1_defconfig | 1 + configs/socfpga_mcvevk_defconfig | 1 + configs/socfpga_secu1_defconfig | 1 + configs/socfpga_sockit_defconfig | 1 + configs/socfpga_socrates_defconfig| 1 + configs/socfpga_sr1500_defconfig | 1 + configs/socfpga_vining_fpga_defconfig | 1 + configs/stemmy_defconfig | 1 + configs/tbs2910_defconfig | 1 + configs/theadorable_debug_defconfig | 1 + configs/tqma6dl_mba6_mmc_defconfig| 1 + configs/tqma6dl_mba6_spi_defconfig| 1 + configs/tqma6q_mba6_mmc_defconfig | 1 + configs
Re: [PATCH v3 1/3] Convert CONFIG_SYS_L2_PL310 to Kconfig
Hi, following the whole discussion I figured using 'select SYS_l2_PL310 if !SYS_L2CACHE_OFF' is the preferred solution. Now the thing is, if I'd put this line under the ARCH_XXX Kconfig entries, I would change behavior for many boards. Take, for example, ARCH_MVEBU: grep -lr ARCH_MVEBU configs | ./tools/moveconfig.py -d- CONFIG_SYS_L2_PL310 Tells me that there are 30 ARCH_MVEBU defconfigs, of which 19 use CONFIG_SYS_L2_PL310 and 11 don't. Those 11 boards not using it also do not define CONFIG_SYS_L2CACHE_OFF. So using a 'select SYS_L2_PL310' under ARCH_MVEBU would change behavior for those 11 boards. There is a similar picture for other architectures, like SOCFPGA or OMAP2. The only place where selecting based on CONFIG_ARCH does not change behavior is ARCH_MX6, when excluding CONFIG_MX6UL(L). If I didn't miss something here, there's no easy way out. Maybe to define SYS_L2CACHE_OFF for respective boards would be an option, but I don't know if there would be side effects. Any other suggestions? Best regards, Philip
Re: [PATCH v3 1/3] Convert CONFIG_SYS_L2_PL310 to Kconfig
Just for the record: I solved the problem using ./tools/moveconfig.py -i CONFIG_SYS_L2_PL310 Patch V4 coming soon. On Thu, 2022-08-11 at 12:17 +0200, Philip Oberfichtner wrote: > Hi, > > following the whole discussion I figured using 'select SYS_l2_PL310 > if > !SYS_L2CACHE_OFF' is the preferred solution. > > Now the thing is, if I'd put this line under the ARCH_XXX Kconfig > entries, I would change behavior for many boards. Take, for example, > ARCH_MVEBU: > > grep -lr ARCH_MVEBU configs | ./tools/moveconfig.py -d- > CONFIG_SYS_L2_PL310 > > Tells me that there are 30 ARCH_MVEBU defconfigs, of which 19 use > CONFIG_SYS_L2_PL310 and 11 don't. Those 11 boards not using it also > do > not define CONFIG_SYS_L2CACHE_OFF. So using a 'select SYS_L2_PL310' > under ARCH_MVEBU would change behavior for those 11 boards. > > There is a similar picture for other architectures, like SOCFPGA or > OMAP2. The only place where selecting based on CONFIG_ARCH does not > change behavior is ARCH_MX6, when excluding CONFIG_MX6UL(L). > > If I didn't miss something here, there's no easy way out. Maybe to > define SYS_L2CACHE_OFF for respective boards would be an option, but > I > don't know if there would be side effects. > > Any other suggestions? > > Best regards, > Philip
[PATCH v4 1/3] Convert CONFIG_SYS_L2_PL310 to Kconfig
This converts CONFIG_SYS_L2_PL310 to Kconfig. For omap2 and mvebu the 'select SYS_L2_PL310' locations were determined using ./tools/moveconfig -i CONFIG_SYS_L2_PL310. For mx6 I manually chose ARCH_MX6 as 'select' location. The correctness has been verified using $ ./tools/moveconfig.py -f ARCH_MX6 ~SYS_L2_PL310 ~SYS_L2CACHE_OFF 0 matches That means whenever an ARCH_MX6 board had SYS_L2_PL310 disabled, this was correctly reflected in SYS_L2CACHE_OFF. Thus it's safe to insert the 'select' statement under ARCH_MX6. Signed-off-by: Philip Oberfichtner --- I wonder if we could further reduce the diffstat by using 'select' for all the socfpga boards. I did not find an appropriate way - I'm open for suggestions, though. Changes in v4: - Reduce diffstat by using 'select' statements for omap2, mvebu and mx6 based boards Changes in v3: new README| 2 -- arch/arm/Kconfig | 5 + arch/arm/mach-mvebu/Kconfig | 1 + arch/arm/mach-mvebu/include/mach/config.h | 2 -- arch/arm/mach-omap2/Kconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig| 1 + configs/socfpga_dbm_soc1_defconfig| 1 + configs/socfpga_de0_nano_soc_defconfig| 1 + configs/socfpga_de10_nano_defconfig | 1 + configs/socfpga_de10_standard_defconfig | 1 + configs/socfpga_de1_soc_defconfig | 1 + configs/socfpga_is1_defconfig | 1 + configs/socfpga_mcvevk_defconfig | 1 + configs/socfpga_secu1_defconfig | 1 + configs/socfpga_sockit_defconfig | 1 + configs/socfpga_socrates_defconfig| 1 + configs/socfpga_sr1500_defconfig | 1 + configs/socfpga_vining_fpga_defconfig | 1 + configs/stemmy_defconfig | 1 + include/configs/am43xx_evm.h | 1 - include/configs/brppt2.h | 1 - include/configs/cm_t43.h | 1 - include/configs/mx6_common.h | 1 - include/configs/odroid.h | 1 - include/configs/poleg.h | 1 - include/configs/socfpga_common.h | 1 - include/configs/stemmy.h | 1 - include/configs/ti_omap4_common.h | 1 - include/configs/trats.h | 1 - include/configs/trats2.h | 1 - include/configs/zynq-common.h | 1 - scripts/config_whitelist.txt | 1 - 38 files changed, 27 insertions(+), 17 deletions(-) diff --git a/README b/README index 6b6f722733..595f007aaf 100644 --- a/README +++ b/README @@ -496,8 +496,6 @@ The following options need to be configured: the defaults discussed just above. - Cache Configuration for ARM: - CONFIG_SYS_L2_PL310 - Enable support for ARM PL310 L2 cache - controller CONFIG_SYS_PL310_BASE - Physical base address of PL310 controller register space diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 949ebb46ba..b094d2d51f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -488,6 +488,10 @@ config TPL_SYS_THUMB_BUILD density. For ARM architectures that support Thumb2 this flag will result in Thumb2 code generated by GCC. +config SYS_L2_PL310 + bool "ARM PL310 L2 cache controller" + help + Enable support for ARM PL310 L2 cache controller in U-Boot config SYS_L2CACHE_OFF bool "L2cache off" @@ -989,6 +993,7 @@ config ARCH_MX6 select SYS_FSL_HAS_SEC select SYS_FSL_SEC_COMPAT_4 select SYS_FSL_SEC_LE + select SYS_L2_PL310 if !SYS_L2CACHE_OFF imply MXC_GPIO imply SYS_THUMB_BUILD imply SPL_SEPARATE_BSS diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index a81b8e2b0d..2ebe341ed1 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -14,6 +14,7 @@ config ARMADA_32BIT select SPL_SKIP_LOWLEVEL_INIT if SPL select SPL_SIMPLE_BUS if SPL select SUPPORT_SPL + select SYS_L2_PL310 if !SYS_L2CACHE_OFF select TRANSLATION_OFFSET select SPL_SYS_NO_VECTOR_TABLE if SPL select ARCH_VERY_EARLY_INIT diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h index 4add0d9e10..0bba0a4cf9 100644 --- a/arch/arm/mach-mvebu/include/mach/config.h +++ b/arch/arm/mach-mvebu/include/mach/config.h @@ -25,8 +25,6 @@ #define MV88F78X60 /* for the DDR training bin_hdr code */ #endif -#defin
[PATCH v4 2/3] ARM: cache: Allow SPL to build cache-pl310.c
Introduce the new Kconfig symbol CONFIG_SPL_SYS_L2_PL310 to allow the SPL to build cache-pl310.c. Before this commit, the SPL could enable the PL310 L2 cache [1], but the cache maintenance functions from cache-pl310.c were only useable for non-SPL builds. After enabling the cache one must be able to flush it, too. Thus this commit allows cache-pl310.c to be included in the SPL build. [1] See for example arch/arm/mach-imx/cache.c: v7_outer_cache_enable() Signed-off-by: Philip Oberfichtner --- (no changes since v3) Changes in v3: - Introduce CONFIG_SPL_SYS_L2_PL310 arch/arm/Kconfig | 5 + arch/arm/lib/Makefile | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b094d2d51f..318e5e82ea 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -493,6 +493,11 @@ config SYS_L2_PL310 help Enable support for ARM PL310 L2 cache controller in U-Boot +config SPL_SYS_L2_PL310 + bool "ARM PL310 L2 cache controller in SPL" + help + Enable support for ARM PL310 L2 cache controller in SPL + config SYS_L2CACHE_OFF bool "L2cache off" help diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c603fe61bc..d137b4bf0f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o -obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o else obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o @@ -46,6 +45,7 @@ else obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o endif +obj-$(CONFIG_$(SPL_TPL_)SYS_L2_PL310) += cache-pl310.o obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o ifneq ($(filter y,$(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR) $(CONFIG_SAVE_PREV_BL_FDT_ADDR)),) -- 2.37.1
[PATCH v4 3/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
From: Marek Vasut Enable d-cache early in SPL right after DRAM is started up. This reduces U-Boot proper load time by 650ms when loaded from SPI NOR. Signed-off-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- Changes in v4: - Elaborate on dcache_disable() comment Changes in v3: - Use newly introduced Kconfig symbol for dh_imx6_defconfig Changes in v2: - Add comment to explain the relevance of dcache_disable() board/dhelectronics/dh_imx6/dh_imx6_spl.c | 32 +++ configs/dh_imx6_defconfig | 1 + 2 files changed, 33 insertions(+) diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index e49e97724a..580b98811c 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,11 +15,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -610,6 +613,20 @@ static void dhcom_spl_dram_init(void) } } +void dram_bank_mmu_setup(int bank) +{ + int i; + + set_section_dcache(ROMCP_ARB_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + set_section_dcache(IRAM_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + + for (i = MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT; + i < ((MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT) + + (SZ_1G >> MMU_SECTION_SHIFT)); + i++) + set_section_dcache(i, DCACHE_DEFAULT_OPTION); +} + void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ @@ -636,9 +653,24 @@ void board_init_f(ulong dummy) /* DDR3 initialization */ dhcom_spl_dram_init(); + /* Set up early MMU tables at the beginning of DRAM and start d-cache */ + gd->arch.tlb_addr = MMDC0_ARB_BASE_ADDR + SZ_32M; + gd->arch.tlb_size = PGTABLE_SIZE; + enable_caches(); + /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ board_init_r(NULL, 0); } + +void spl_board_prepare_for_boot(void) +{ + /* +* Flush dcache. Without it U-Boot proper would hang at random locations. Presumably this is +* due to dirty cache lines remaining after SPL passes control. When U-Boot proper later on +* calls invalidate_dcache_all(), those dirty cache lines will get lost. +*/ + dcache_disable(); +} diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index 051816f719..1be6ae62ce 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SPL_SYS_L2_PL310=y CONFIG_ARCH_MX6=y CONFIG_SYS_TEXT_BASE=0x1780 CONFIG_SYS_MALLOC_F_LEN=0x1000 -- 2.37.1
Re: [PATCH v4 3/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
Hi, thanks for the feedback. On Wed, 2022-08-17 at 11:24 +0200, Marek Vasut wrote: > On 8/17/22 11:06, Philip Oberfichtner wrote: > > [...] > > > +void spl_board_prepare_for_boot(void) > > +{ > > + /* > > + * Flush dcache. > > The dcache_disable() does not do any cache flushing, it just disables > the Dcache enable C-bit. See the following objdump jumping to flush_dcache_all(). The implementation of dcache_disable() is in arch/arm/lib/cache-cp15.c. $ ${CROSS_COMPILE}objdump spl/u-boot-spl --disassemble=dcache_disable spl/u-boot-spl: file format elf32-littlearm Disassembly of section .text: 0090b498 : 90b498: b510push{r4, lr} 90b49a: ee11 3f10 mrc 15, 0, r3, cr1, cr0, {0} 90b49e: 075blslsr3, r3, #29 90b4a0: d509bpl.n 90b4b6 90b4a2: ee11 4f10 mrc 15, 0, r4, cr1, cr0, {0} 90b4a6: f7ff fbfb bl 90aca0 90b4aa: f024 0405 bic.w r4, r4, #5 90b4ae: ee01 4f10 mcr 15, 0, r4, cr1, cr0, {0} 90b4b2: f3bf 8f6f isb sy 90b4b6: bd10pop {r4, pc} $ I'll add a note to the comment about flush_dcache_all() being called. > > > Without it U-Boot proper would hang at random locations. Presumably > > this is > > + * due to dirty cache lines remaining after SPL passes > > control. When U-Boot proper later on > > + * calls invalidate_dcache_all(), those dirty cache lines > > will get lost. > > + */ > > What about falcon boot mode starting Linux from SPL, could it fail > the > same way ? Yes, assuming my dirty-cache-line hypothesis is correct. I'll generalize the comment in V5. > > > + dcache_disable(); > > +} > > [...]
[PATCH v5 1/3] Convert CONFIG_SYS_L2_PL310 to Kconfig
This converts CONFIG_SYS_L2_PL310 to Kconfig. For omap2 and mvebu the 'select SYS_L2_PL310' locations were determined using ./tools/moveconfig -i CONFIG_SYS_L2_PL310. For mx6 I manually chose ARCH_MX6 as 'select' location. The correctness has been verified using $ ./tools/moveconfig.py -f ARCH_MX6 ~SYS_L2_PL310 ~SYS_L2CACHE_OFF 0 matches That means whenever an ARCH_MX6 board had SYS_L2_PL310 disabled, this was correctly reflected in SYS_L2CACHE_OFF. Thus it's safe to insert the 'select' statement under ARCH_MX6. Signed-off-by: Philip Oberfichtner --- I wonder if we could further reduce the diffstat by using 'select' for all the socfpga boards. I did not find an appropriate way - I'm open for suggestions, though. (no changes since v4) Changes in v4: - Reduce diffstat by using 'select' statements for omap2, mvebu and mx6 based boards Changes in v3: new README| 2 -- arch/arm/Kconfig | 5 + arch/arm/mach-mvebu/Kconfig | 1 + arch/arm/mach-mvebu/include/mach/config.h | 2 -- arch/arm/mach-omap2/Kconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig| 1 + configs/socfpga_dbm_soc1_defconfig| 1 + configs/socfpga_de0_nano_soc_defconfig| 1 + configs/socfpga_de10_nano_defconfig | 1 + configs/socfpga_de10_standard_defconfig | 1 + configs/socfpga_de1_soc_defconfig | 1 + configs/socfpga_is1_defconfig | 1 + configs/socfpga_mcvevk_defconfig | 1 + configs/socfpga_secu1_defconfig | 1 + configs/socfpga_sockit_defconfig | 1 + configs/socfpga_socrates_defconfig| 1 + configs/socfpga_sr1500_defconfig | 1 + configs/socfpga_vining_fpga_defconfig | 1 + configs/stemmy_defconfig | 1 + include/configs/am43xx_evm.h | 1 - include/configs/brppt2.h | 1 - include/configs/cm_t43.h | 1 - include/configs/mx6_common.h | 1 - include/configs/odroid.h | 1 - include/configs/poleg.h | 1 - include/configs/socfpga_common.h | 1 - include/configs/stemmy.h | 1 - include/configs/ti_omap4_common.h | 1 - include/configs/trats.h | 1 - include/configs/trats2.h | 1 - include/configs/zynq-common.h | 1 - scripts/config_whitelist.txt | 1 - 38 files changed, 27 insertions(+), 17 deletions(-) diff --git a/README b/README index 6b6f722733..595f007aaf 100644 --- a/README +++ b/README @@ -496,8 +496,6 @@ The following options need to be configured: the defaults discussed just above. - Cache Configuration for ARM: - CONFIG_SYS_L2_PL310 - Enable support for ARM PL310 L2 cache - controller CONFIG_SYS_PL310_BASE - Physical base address of PL310 controller register space diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 949ebb46ba..b094d2d51f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -488,6 +488,10 @@ config TPL_SYS_THUMB_BUILD density. For ARM architectures that support Thumb2 this flag will result in Thumb2 code generated by GCC. +config SYS_L2_PL310 + bool "ARM PL310 L2 cache controller" + help + Enable support for ARM PL310 L2 cache controller in U-Boot config SYS_L2CACHE_OFF bool "L2cache off" @@ -989,6 +993,7 @@ config ARCH_MX6 select SYS_FSL_HAS_SEC select SYS_FSL_SEC_COMPAT_4 select SYS_FSL_SEC_LE + select SYS_L2_PL310 if !SYS_L2CACHE_OFF imply MXC_GPIO imply SYS_THUMB_BUILD imply SPL_SEPARATE_BSS diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index a81b8e2b0d..2ebe341ed1 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -14,6 +14,7 @@ config ARMADA_32BIT select SPL_SKIP_LOWLEVEL_INIT if SPL select SPL_SIMPLE_BUS if SPL select SUPPORT_SPL + select SYS_L2_PL310 if !SYS_L2CACHE_OFF select TRANSLATION_OFFSET select SPL_SYS_NO_VECTOR_TABLE if SPL select ARCH_VERY_EARLY_INIT diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h index 4add0d9e10..0bba0a4cf9 100644 --- a/arch/arm/mach-mvebu/include/mach/config.h +++ b/arch/arm/mach-mvebu/include/mach/config.h @@ -25,8 +25,6 @@ #define MV88F78X60 /* for the DDR training bin_hd
[PATCH v5 2/3] ARM: cache: Allow SPL to build cache-pl310.c
Introduce the new Kconfig symbol CONFIG_SPL_SYS_L2_PL310 to allow the SPL to build cache-pl310.c. Before this commit, the SPL could enable the PL310 L2 cache [1], but the cache maintenance functions from cache-pl310.c were only useable for non-SPL builds. After enabling the cache one must be able to flush it, too. Thus this commit allows cache-pl310.c to be included in the SPL build. [1] See for example arch/arm/mach-imx/cache.c: v7_outer_cache_enable() Signed-off-by: Philip Oberfichtner --- (no changes since v3) Changes in v3: - Introduce CONFIG_SPL_SYS_L2_PL310 arch/arm/Kconfig | 5 + arch/arm/lib/Makefile | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b094d2d51f..318e5e82ea 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -493,6 +493,11 @@ config SYS_L2_PL310 help Enable support for ARM PL310 L2 cache controller in U-Boot +config SPL_SYS_L2_PL310 + bool "ARM PL310 L2 cache controller in SPL" + help + Enable support for ARM PL310 L2 cache controller in SPL + config SYS_L2CACHE_OFF bool "L2cache off" help diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c603fe61bc..d137b4bf0f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o -obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o else obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o @@ -46,6 +45,7 @@ else obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o endif +obj-$(CONFIG_$(SPL_TPL_)SYS_L2_PL310) += cache-pl310.o obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o ifneq ($(filter y,$(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR) $(CONFIG_SAVE_PREV_BL_FDT_ADDR)),) -- 2.37.1
[PATCH v5 3/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
From: Marek Vasut Enable d-cache early in SPL right after DRAM is started up. This reduces U-Boot proper load time by 650ms when loaded from SPI NOR. Signed-off-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- Changes in v5: - Clarify dcache_disable() comment Changes in v4: - Elaborate on dcache_disable() comment Changes in v3: - Use newly introduced Kconfig symbol for dh_imx6_defconfig Changes in v2: - Add comment to explain the relevance of dcache_disable() board/dhelectronics/dh_imx6/dh_imx6_spl.c | 34 +++ configs/dh_imx6_defconfig | 1 + 2 files changed, 35 insertions(+) diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index e49e97724a..f8512bd32e 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,11 +15,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -610,6 +613,20 @@ static void dhcom_spl_dram_init(void) } } +void dram_bank_mmu_setup(int bank) +{ + int i; + + set_section_dcache(ROMCP_ARB_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + set_section_dcache(IRAM_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + + for (i = MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT; + i < ((MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT) + + (SZ_1G >> MMU_SECTION_SHIFT)); + i++) + set_section_dcache(i, DCACHE_DEFAULT_OPTION); +} + void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ @@ -636,9 +653,26 @@ void board_init_f(ulong dummy) /* DDR3 initialization */ dhcom_spl_dram_init(); + /* Set up early MMU tables at the beginning of DRAM and start d-cache */ + gd->arch.tlb_addr = MMDC0_ARB_BASE_ADDR + SZ_32M; + gd->arch.tlb_size = PGTABLE_SIZE; + enable_caches(); + /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ board_init_r(NULL, 0); } + +void spl_board_prepare_for_boot(void) +{ + /* +* Disable and flush dcache. Without it the next bootstage might fail randomly because of +* dirty cache lines that have not been written back to DRAM. +* +* In my particular case, U-Boot proper calls invalidate_dcache_all() before enabling it. +* At this point, dirty cache lines would get lost, if the SPL had not flushed them. +*/ + dcache_disable(); +} diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index 051816f719..1be6ae62ce 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SPL_SYS_L2_PL310=y CONFIG_ARCH_MX6=y CONFIG_SYS_TEXT_BASE=0x1780 CONFIG_SYS_MALLOC_F_LEN=0x1000 -- 2.37.1
[PATCH v4 0/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
This patch series enables d-cache in SPL for i.MX6 based boards from DH in order to improve boot time. This can only be achieved after migrating the corresponding symbols to Kconfig, which is done in patch 1/3 and 2/3. Changes in v4: - Reduce diffstat by using 'select' statements for omap2, mvebu and mx6 based boards - Elaborate on dcache_disable() comment Changes in v3: - Introduce CONFIG_SPL_SYS_L2_PL310 - Convert CONFIG_SYS_L2_PL310 to Kconfig - Use newly introduced Kconfig symbol for dh_imx6_defconfig Changes in v2: - Add comment to explain the relevance of dcache_disable() Marek Vasut (1): ARM: imx6: dh-imx6: Enable d-cache early in SPL Philip Oberfichtner (2): Convert CONFIG_SYS_L2_PL310 to Kconfig ARM: cache: Allow SPL to build cache-pl310.c README| 2 -- arch/arm/Kconfig | 10 +++ arch/arm/lib/Makefile | 2 +- arch/arm/mach-mvebu/Kconfig | 1 + arch/arm/mach-mvebu/include/mach/config.h | 2 -- arch/arm/mach-omap2/Kconfig | 1 + board/dhelectronics/dh_imx6/dh_imx6_spl.c | 32 +++ configs/dh_imx6_defconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig| 1 + configs/socfpga_dbm_soc1_defconfig| 1 + configs/socfpga_de0_nano_soc_defconfig| 1 + configs/socfpga_de10_nano_defconfig | 1 + configs/socfpga_de10_standard_defconfig | 1 + configs/socfpga_de1_soc_defconfig | 1 + configs/socfpga_is1_defconfig | 1 + configs/socfpga_mcvevk_defconfig | 1 + configs/socfpga_secu1_defconfig | 1 + configs/socfpga_sockit_defconfig | 1 + configs/socfpga_socrates_defconfig| 1 + configs/socfpga_sr1500_defconfig | 1 + configs/socfpga_vining_fpga_defconfig | 1 + configs/stemmy_defconfig | 1 + include/configs/am43xx_evm.h | 1 - include/configs/brppt2.h | 1 - include/configs/cm_t43.h | 1 - include/configs/mx6_common.h | 1 - include/configs/odroid.h | 1 - include/configs/poleg.h | 1 - include/configs/socfpga_common.h | 1 - include/configs/stemmy.h | 1 - include/configs/ti_omap4_common.h | 1 - include/configs/trats.h | 1 - include/configs/trats2.h | 1 - include/configs/zynq-common.h | 1 - scripts/config_whitelist.txt | 1 - 41 files changed, 66 insertions(+), 18 deletions(-) -- 2.37.1
[PATCH v5 0/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
This patch series enables d-cache in SPL for i.MX6 based boards from DH in order to improve boot time. This can only be achieved after migrating the corresponding symbols to Kconfig, which is done in patch 1/3 and 2/3. Changes in v5: - Clarify dcache_disable() comment Changes in v4: - Reduce diffstat by using 'select' statements for omap2, mvebu and mx6 based boards - Elaborate on dcache_disable() comment Changes in v3: - Introduce CONFIG_SPL_SYS_L2_PL310 - Convert CONFIG_SYS_L2_PL310 to Kconfig - Use newly introduced Kconfig symbol for dh_imx6_defconfig Changes in v2: - Add comment to explain the relevance of dcache_disable() Marek Vasut (1): ARM: imx6: dh-imx6: Enable d-cache early in SPL Philip Oberfichtner (2): Convert CONFIG_SYS_L2_PL310 to Kconfig ARM: cache: Allow SPL to build cache-pl310.c README| 2 -- arch/arm/Kconfig | 10 +++ arch/arm/lib/Makefile | 2 +- arch/arm/mach-mvebu/Kconfig | 1 + arch/arm/mach-mvebu/include/mach/config.h | 2 -- arch/arm/mach-omap2/Kconfig | 1 + board/dhelectronics/dh_imx6/dh_imx6_spl.c | 34 +++ configs/dh_imx6_defconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig| 1 + configs/socfpga_dbm_soc1_defconfig| 1 + configs/socfpga_de0_nano_soc_defconfig| 1 + configs/socfpga_de10_nano_defconfig | 1 + configs/socfpga_de10_standard_defconfig | 1 + configs/socfpga_de1_soc_defconfig | 1 + configs/socfpga_is1_defconfig | 1 + configs/socfpga_mcvevk_defconfig | 1 + configs/socfpga_secu1_defconfig | 1 + configs/socfpga_sockit_defconfig | 1 + configs/socfpga_socrates_defconfig| 1 + configs/socfpga_sr1500_defconfig | 1 + configs/socfpga_vining_fpga_defconfig | 1 + configs/stemmy_defconfig | 1 + include/configs/am43xx_evm.h | 1 - include/configs/brppt2.h | 1 - include/configs/cm_t43.h | 1 - include/configs/mx6_common.h | 1 - include/configs/odroid.h | 1 - include/configs/poleg.h | 1 - include/configs/socfpga_common.h | 1 - include/configs/stemmy.h | 1 - include/configs/ti_omap4_common.h | 1 - include/configs/trats.h | 1 - include/configs/trats2.h | 1 - include/configs/zynq-common.h | 1 - scripts/config_whitelist.txt | 1 - 41 files changed, 68 insertions(+), 18 deletions(-) -- 2.37.1
[PATCH v6 1/3] Convert CONFIG_SYS_L2_PL310 to Kconfig
This converts CONFIG_SYS_L2_PL310 to Kconfig. For omap2 and mvebu the 'select SYS_L2_PL310' locations were determined using ./tools/moveconfig -i CONFIG_SYS_L2_PL310. For mx6 I manually chose ARCH_MX6 as 'select' location. The correctness has been verified using $ ./tools/moveconfig.py -f ARCH_MX6 ~SYS_L2_PL310 ~SYS_L2CACHE_OFF 0 matches That means whenever an ARCH_MX6 board had SYS_L2_PL310 disabled, this was correctly reflected in SYS_L2CACHE_OFF. Thus it's safe to insert the 'select' statement under ARCH_MX6. Signed-off-by: Philip Oberfichtner --- I wonder if we could further reduce the diffstat by using 'select' for all the socfpga boards. I did not find an appropriate way - I'm open for suggestions, though. (no changes since v4) Changes in v4: - Reduce diffstat by using 'select' statements for omap2, mvebu and mx6 based boards Changes in v3: new README| 2 -- arch/arm/Kconfig | 5 + arch/arm/mach-mvebu/Kconfig | 1 + arch/arm/mach-mvebu/include/mach/config.h | 2 -- arch/arm/mach-omap2/Kconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig| 1 + configs/socfpga_dbm_soc1_defconfig| 1 + configs/socfpga_de0_nano_soc_defconfig| 1 + configs/socfpga_de10_nano_defconfig | 1 + configs/socfpga_de10_standard_defconfig | 1 + configs/socfpga_de1_soc_defconfig | 1 + configs/socfpga_is1_defconfig | 1 + configs/socfpga_mcvevk_defconfig | 1 + configs/socfpga_secu1_defconfig | 1 + configs/socfpga_sockit_defconfig | 1 + configs/socfpga_socrates_defconfig| 1 + configs/socfpga_sr1500_defconfig | 1 + configs/socfpga_vining_fpga_defconfig | 1 + configs/stemmy_defconfig | 1 + include/configs/am43xx_evm.h | 1 - include/configs/brppt2.h | 1 - include/configs/cm_t43.h | 1 - include/configs/mx6_common.h | 1 - include/configs/odroid.h | 1 - include/configs/poleg.h | 1 - include/configs/socfpga_common.h | 1 - include/configs/stemmy.h | 1 - include/configs/ti_omap4_common.h | 1 - include/configs/trats.h | 1 - include/configs/trats2.h | 1 - include/configs/zynq-common.h | 1 - scripts/config_whitelist.txt | 1 - 38 files changed, 27 insertions(+), 17 deletions(-) diff --git a/README b/README index 6b6f722733..595f007aaf 100644 --- a/README +++ b/README @@ -496,8 +496,6 @@ The following options need to be configured: the defaults discussed just above. - Cache Configuration for ARM: - CONFIG_SYS_L2_PL310 - Enable support for ARM PL310 L2 cache - controller CONFIG_SYS_PL310_BASE - Physical base address of PL310 controller register space diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 949ebb46ba..b094d2d51f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -488,6 +488,10 @@ config TPL_SYS_THUMB_BUILD density. For ARM architectures that support Thumb2 this flag will result in Thumb2 code generated by GCC. +config SYS_L2_PL310 + bool "ARM PL310 L2 cache controller" + help + Enable support for ARM PL310 L2 cache controller in U-Boot config SYS_L2CACHE_OFF bool "L2cache off" @@ -989,6 +993,7 @@ config ARCH_MX6 select SYS_FSL_HAS_SEC select SYS_FSL_SEC_COMPAT_4 select SYS_FSL_SEC_LE + select SYS_L2_PL310 if !SYS_L2CACHE_OFF imply MXC_GPIO imply SYS_THUMB_BUILD imply SPL_SEPARATE_BSS diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index a81b8e2b0d..2ebe341ed1 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -14,6 +14,7 @@ config ARMADA_32BIT select SPL_SKIP_LOWLEVEL_INIT if SPL select SPL_SIMPLE_BUS if SPL select SUPPORT_SPL + select SYS_L2_PL310 if !SYS_L2CACHE_OFF select TRANSLATION_OFFSET select SPL_SYS_NO_VECTOR_TABLE if SPL select ARCH_VERY_EARLY_INIT diff --git a/arch/arm/mach-mvebu/include/mach/config.h b/arch/arm/mach-mvebu/include/mach/config.h index 4add0d9e10..0bba0a4cf9 100644 --- a/arch/arm/mach-mvebu/include/mach/config.h +++ b/arch/arm/mach-mvebu/include/mach/config.h @@ -25,8 +25,6 @@ #define MV88F78X60 /* for the DDR training bin_hd
[PATCH v6 2/3] ARM: cache: Allow SPL to build cache-pl310.c
Introduce the new Kconfig symbol CONFIG_SPL_SYS_L2_PL310 to allow the SPL to build cache-pl310.c. Before this commit, the SPL could enable the PL310 L2 cache [1], but the cache maintenance functions from cache-pl310.c were only useable for non-SPL builds. After enabling the cache one must be able to flush it, too. Thus this commit allows cache-pl310.c to be included in the SPL build. [1] See for example arch/arm/mach-imx/cache.c: v7_outer_cache_enable() Signed-off-by: Philip Oberfichtner --- (no changes since v3) Changes in v3: - Introduce CONFIG_SPL_SYS_L2_PL310 arch/arm/Kconfig | 5 + arch/arm/lib/Makefile | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b094d2d51f..318e5e82ea 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -493,6 +493,11 @@ config SYS_L2_PL310 help Enable support for ARM PL310 L2 cache controller in U-Boot +config SPL_SYS_L2_PL310 + bool "ARM PL310 L2 cache controller in SPL" + help + Enable support for ARM PL310 L2 cache controller in SPL + config SYS_L2CACHE_OFF bool "L2cache off" help diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c603fe61bc..d137b4bf0f 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_OF_LIBFDT) += bootm-fdt.o obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTZ) += bootm.o zimage.o -obj-$(CONFIG_SYS_L2_PL310) += cache-pl310.o else obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o obj-$(CONFIG_SPL_FRAMEWORK) += zimage.o @@ -46,6 +45,7 @@ else obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMSET) += memset.o obj-$(CONFIG_$(SPL_TPL_)USE_ARCH_MEMCPY) += memcpy.o endif +obj-$(CONFIG_$(SPL_TPL_)SYS_L2_PL310) += cache-pl310.o obj-$(CONFIG_$(SPL_TPL_)SEMIHOSTING) += semihosting.o ifneq ($(filter y,$(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR) $(CONFIG_SAVE_PREV_BL_FDT_ADDR)),) -- 2.37.1
[PATCH v6 3/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
From: Marek Vasut Enable d-cache early in SPL right after DRAM is started up. This reduces U-Boot proper load time by 650ms when loaded from SPI NOR. Signed-off-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- Changes in v6: - Once more improve the dcache_disable() comment Changes in v5: - Clarify dcache_disable() comment Changes in v4: - Elaborate on dcache_disable() comment Changes in v3: - Use newly introduced Kconfig symbol for dh_imx6_defconfig Changes in v2: - Add comment to explain the relevance of dcache_disable() board/dhelectronics/dh_imx6/dh_imx6_spl.c | 41 +++ configs/dh_imx6_defconfig | 1 + 2 files changed, 42 insertions(+) diff --git a/board/dhelectronics/dh_imx6/dh_imx6_spl.c b/board/dhelectronics/dh_imx6/dh_imx6_spl.c index e49e97724a..20a330cce6 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6_spl.c +++ b/board/dhelectronics/dh_imx6/dh_imx6_spl.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -14,11 +15,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -610,6 +613,20 @@ static void dhcom_spl_dram_init(void) } } +void dram_bank_mmu_setup(int bank) +{ + int i; + + set_section_dcache(ROMCP_ARB_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + set_section_dcache(IRAM_BASE_ADDR >> MMU_SECTION_SHIFT, DCACHE_DEFAULT_OPTION); + + for (i = MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT; + i < ((MMDC0_ARB_BASE_ADDR >> MMU_SECTION_SHIFT) + + (SZ_1G >> MMU_SECTION_SHIFT)); + i++) + set_section_dcache(i, DCACHE_DEFAULT_OPTION); +} + void board_init_f(ulong dummy) { /* setup AIPS and disable watchdog */ @@ -636,9 +653,33 @@ void board_init_f(ulong dummy) /* DDR3 initialization */ dhcom_spl_dram_init(); + /* Set up early MMU tables at the beginning of DRAM and start d-cache */ + gd->arch.tlb_addr = MMDC0_ARB_BASE_ADDR + SZ_32M; + gd->arch.tlb_size = PGTABLE_SIZE; + enable_caches(); + /* Clear the BSS. */ memset(__bss_start, 0, __bss_end - __bss_start); /* load/boot image from boot device */ board_init_r(NULL, 0); } + +void spl_board_prepare_for_boot(void) +{ + /* +* Flush and disable dcache. Without it, the following bootstage might fail randomly because +* dirty cache lines may not have been written back to DRAM. +* +* If dcache_disable() would be omitted, the following scenario may occur: +* +* The SPL enables dcache and cachelines get populated with data. Then dcache gets disabled +* in U-Boot proper, but still contains dirty data, i.e. the corresponding DRAM locations +* have not yet been updated. When U-Boot reads these locations, it sees an (incorrect) old +* state of the content. +* +* Furthermore, the DRAM contents have likely been modified by U-Boot while dcache was +* disabled. Thus, U-Boot flushing dcache would corrupt DRAM with stale data. +*/ + dcache_disable(); /* implies flush_dcache_all() */ +} diff --git a/configs/dh_imx6_defconfig b/configs/dh_imx6_defconfig index 051816f719..1be6ae62ce 100644 --- a/configs/dh_imx6_defconfig +++ b/configs/dh_imx6_defconfig @@ -1,4 +1,5 @@ CONFIG_ARM=y +CONFIG_SPL_SYS_L2_PL310=y CONFIG_ARCH_MX6=y CONFIG_SYS_TEXT_BASE=0x1780 CONFIG_SYS_MALLOC_F_LEN=0x1000 -- 2.37.1
[PATCH v6 0/3] ARM: imx6: dh-imx6: Enable d-cache early in SPL
This patch series enables d-cache in SPL for i.MX6 based boards from DH in order to improve boot time. This can only be achieved after migrating the corresponding symbols to Kconfig, which is done in patch 1/3 and 2/3. Changes in v6: - Once more improve the dcache_disable() comment Changes in v5: - Clarify dcache_disable() comment Changes in v4: - Reduce diffstat by using 'select' statements for omap2, mvebu and mx6 based boards - Elaborate on dcache_disable() comment Changes in v3: - Introduce CONFIG_SPL_SYS_L2_PL310 - Convert CONFIG_SYS_L2_PL310 to Kconfig - Use newly introduced Kconfig symbol for dh_imx6_defconfig Changes in v2: - Add comment to explain the relevance of dcache_disable() Marek Vasut (1): ARM: imx6: dh-imx6: Enable d-cache early in SPL Philip Oberfichtner (2): Convert CONFIG_SYS_L2_PL310 to Kconfig ARM: cache: Allow SPL to build cache-pl310.c README| 2 -- arch/arm/Kconfig | 10 ++ arch/arm/lib/Makefile | 2 +- arch/arm/mach-mvebu/Kconfig | 1 + arch/arm/mach-mvebu/include/mach/config.h | 2 -- arch/arm/mach-omap2/Kconfig | 1 + board/dhelectronics/dh_imx6/dh_imx6_spl.c | 41 +++ configs/dh_imx6_defconfig | 1 + configs/omap4_panda_defconfig | 1 + configs/omap4_sdp4430_defconfig | 1 + configs/poleg_evb_defconfig | 1 + configs/socfpga_arria10_defconfig | 1 + configs/socfpga_arria5_defconfig | 1 + configs/socfpga_chameleonv3_defconfig | 1 + configs/socfpga_cyclone5_defconfig| 1 + configs/socfpga_dbm_soc1_defconfig| 1 + configs/socfpga_de0_nano_soc_defconfig| 1 + configs/socfpga_de10_nano_defconfig | 1 + configs/socfpga_de10_standard_defconfig | 1 + configs/socfpga_de1_soc_defconfig | 1 + configs/socfpga_is1_defconfig | 1 + configs/socfpga_mcvevk_defconfig | 1 + configs/socfpga_secu1_defconfig | 1 + configs/socfpga_sockit_defconfig | 1 + configs/socfpga_socrates_defconfig| 1 + configs/socfpga_sr1500_defconfig | 1 + configs/socfpga_vining_fpga_defconfig | 1 + configs/stemmy_defconfig | 1 + include/configs/am43xx_evm.h | 1 - include/configs/brppt2.h | 1 - include/configs/cm_t43.h | 1 - include/configs/mx6_common.h | 1 - include/configs/odroid.h | 1 - include/configs/poleg.h | 1 - include/configs/socfpga_common.h | 1 - include/configs/stemmy.h | 1 - include/configs/ti_omap4_common.h | 1 - include/configs/trats.h | 1 - include/configs/trats2.h | 1 - include/configs/zynq-common.h | 1 - scripts/config_whitelist.txt | 1 - 41 files changed, 75 insertions(+), 18 deletions(-) -- 2.37.1
Re: [PATCH 1/1] usb: Assimilate usb_get_descriptor() to linux
Good point. See V2. On Fri, May 17, 2024 at 11:16:19PM +0200, Marek Vasut wrote: > On 5/17/24 11:18 AM, Philip Oberfichtner wrote: > > Before this commit, usb_get_descriptor() failed for some flakey USB > > devices. We hereby adopt the more robust linux implementation [1]. > > Can you include which exact device fails and how? Details of the failure are > valuable for the next person who runs into such a bug. Search engines index > the ML posts too, so they become searchable using those. > > Which kernel version is this imported from ? Commit ID would be good to add. > > [...] -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de =
[PATCH v2 1/1] usb: Assimilate usb_get_descriptor() to linux
Before this commit, usb_get_descriptor() failed for some flakey USB devices. We hereby adopt the more robust linux implementation [1]. For instance, for the "Alcor Micro Corp. Flash Drive" (VID 0x058f, PID 0x6387), the following behavior occurs from time to time: => usb start starting USB... Bus xhci_pci: Register 1840 NbrPorts 16 Starting the controller USB XHCI 1.20 scanning bus xhci_pci for devices... usb_new_device: Cannot read configuration, skipping device 058f:6387 Signed-off-by: Philip Oberfichtner [1] From a38297e3fb012 (Linux 6.9), see https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/usb/core/message.c?h=v6.9#n781 --- Notes: Changes in V2: Adapt commit message to - state kernel version - state which exact USB device is being fixed - include error log common/usb.c | 37 ++--- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/common/usb.c b/common/usb.c index 99e6b857c7..661ec0a9c4 100644 --- a/common/usb.c +++ b/common/usb.c @@ -215,8 +215,9 @@ int usb_int_msg(struct usb_device *dev, unsigned long pipe, * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). - * returns the transferred length if OK or -1 if error. The transferred length - * and the current status are stored in the dev->act_len and dev->status. + * returns the transferred length if OK, otherwise a negative error code. The + * transferred length and the current status are stored in the dev->act_len and + * dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, @@ -258,11 +259,14 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, break; mdelay(1); } + + if (timeout == 0) + return -ETIMEDOUT; + if (dev->status) return -1; return dev->act_len; - } /*--- @@ -563,10 +567,29 @@ int usb_clear_halt(struct usb_device *dev, int pipe) static int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) { - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (type << 8) + index, 0, buf, size, - USB_CNTL_TIMEOUT); + int i; + int result; + + if (size <= 0) /* No point in asking for no data */ + return -EINVAL; + + memset(buf, 0, size); /* Make sure we parse really received data */ + + for (i = 0; i < 3; ++i) { + /* retry on length 0 or error; some devices are flakey */ + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), +USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, +(type << 8) + index, 0, buf, size, +USB_CNTL_TIMEOUT); + if (result <= 0 && result != -ETIMEDOUT) + continue; + if (result > 1 && ((u8 *)buf)[1] != type) { + result = -ENODATA; + continue; + } + break; + } + return result; } /** -- 2.39.2
Re: [RFC PATCH] drivers: bootcount: Add support for FAT filesystem
Hi, On Wed, Jun 05, 2024 at 08:10:41PM +0200, Vasileios Amoiridis wrote: > From: Vasileios Amoiridis > > Add support to save boot count variable in a file in a FAT filesystem. > > Signed-off-by: Vasileios Amoiridis > --- > doc/README.bootcount | 12 > drivers/bootcount/Kconfig | 49 +++ > drivers/bootcount/Makefile| 2 +- > drivers/bootcount/bootcount_ext.c | 18 > 4 files changed, 56 insertions(+), 25 deletions(-) > > diff --git a/doc/README.bootcount b/doc/README.bootcount > index f6c5f82f98..cce66d4d70 100644 > --- a/doc/README.bootcount > +++ b/doc/README.bootcount > @@ -23,15 +23,17 @@ It is the responsibility of some application code > (typically a Linux > application) to reset the variable "bootcount" to 0 when the system booted > successfully, thus allowing for more boot cycles. > > -CONFIG_BOOTCOUNT_EXT > +CONFIG_BOOTCOUNT_FS > > > -This adds support for maintaining boot count in a file on an EXT filesystem. > +This adds support for maintaining boot count in a file on a filesystem. > +Supported filesystems are FAT and EXT. > + > The file to use is defined by: > > -CONFIG_SYS_BOOTCOUNT_EXT_INTERFACE > -CONFIG_SYS_BOOTCOUNT_EXT_DEVPART > -CONFIG_SYS_BOOTCOUNT_EXT_NAME > +CONFIG_SYS_BOOTCOUNT_FS_INTERFACE > +CONFIG_SYS_BOOTCOUNT_FS_DEVPART > +CONFIG_SYS_BOOTCOUNT_FS_NAME > > The format of the file is: > > diff --git a/drivers/bootcount/Kconfig b/drivers/bootcount/Kconfig > index 3c56253b1e..a39a7556bb 100644 > --- a/drivers/bootcount/Kconfig > +++ b/drivers/bootcount/Kconfig > @@ -25,10 +25,9 @@ config BOOTCOUNT_GENERIC > Set to the address where the bootcount and bootcount magic > will be stored. > > -config BOOTCOUNT_EXT > - bool "Boot counter on EXT filesystem" > - depends on FS_EXT4 > - select EXT4_WRITE > +config BOOTCOUNT_FS > + bool "Boot counter on filesystem" > + depends on FS_EXT4 || FS_FAT > help > Add support for maintaining boot count in a file on an EXT > filesystem. The help message refers to EXT only, not mentioning FAT. > @@ -177,6 +176,30 @@ config BOOTCOUNT_BOOTLIMIT > counter being cleared. > If set to 0, do not set a boot limit in the environment. > > +if BOOTCOUNT_FS > +choice > + prompt "Filesystem type" > + default BOOTCOUNT_EXT > + > +config BOOTCOUNT_EXT > + bool "Boot counter on EXT filesystem" > + depends on FS_EXT4 > + select EXT4_WRITE > + help > + Add support for maintaining boot count in a file on an EXT > + filesystem. > + > +config BOOTCOUNT_FAT > + bool "Boot counter on FAT filesystem" > + depends on FS_FAT > + select FAT_WRITE > + help > + Add support for maintaining boot count in a file on a FAT > + filesystem. > + > +endchoice > +endif > + > config SYS_BOOTCOUNT_SINGLEWORD > bool "Use single word to pack boot count and magic value" > depends on BOOTCOUNT_GENERIC > @@ -184,26 +207,26 @@ config SYS_BOOTCOUNT_SINGLEWORD > This option enables packing boot count magic value and boot count > into single word (32 bits). > > -config SYS_BOOTCOUNT_EXT_INTERFACE > +config SYS_BOOTCOUNT_FS_INTERFACE > string "Interface on which to find boot counter EXT filesystem" Same here. > default "mmc" > - depends on BOOTCOUNT_EXT > + depends on BOOTCOUNT_FS > help > Set the interface to use when locating the filesystem to use for the > boot counter. > > -config SYS_BOOTCOUNT_EXT_DEVPART > +config SYS_BOOTCOUNT_FS_DEVPART > string "Partition of the boot counter EXT filesystem" And here. > default "0:1" > - depends on BOOTCOUNT_EXT > + depends on BOOTCOUNT_FS > help > Set the partition to use when locating the filesystem to use for the > boot counter. > > -config SYS_BOOTCOUNT_EXT_NAME > +config SYS_BOOTCOUNT_FS_NAME > string "Path and filename of the EXT filesystem based boot counter" And here. Other than that Reviewed-by: Philip Oberfichtner > default "/boot/failures" > - depends on BOOTCOUNT_EXT > + depends on BOOTCOUNT_FS > help > Set the filename and path of the file used to store the boot counter. > > @@ -211,18 +234,18 @@ config SYS_BOOTCOUNT_ADDR > hex "RAM address used for reading and writing the boot counter" > default 0x44E3E000 if
[PATCH v2 0/5] net: dwc_eth_qos: Add glue driver for Intel MAC
This patch series implements the dwc_eth_qos glue driver for Intel SOCs. Before doing that, a few general adaptions to the dwc_eth_qos.c main driver are required. Most notably, the preparation for PCI based driver instances, which do not necessarily use a device tree. This patch series depends on: "net: dwc_eth_qos: mdio: Implement clause 45": https://patchwork.ozlabs.org/project/uboot/patch/20240507094237.168238-1-...@denx.de/ Changes in V2: Improve coding-style in PATCH 5/5 Philip Oberfichtner (5): x86: provide mb() macro net: dwc_eth_qos: Fix header to be self-contained net: dwc_eth_qos: Adapt probe() for PCI devices net: dwc_eth_qos: Implement bind() for PCI devices net: dwc_eth_qos: Add glue driver for Intel MAC arch/x86/include/asm/io.h | 1 + drivers/net/Kconfig| 7 + drivers/net/Makefile | 1 + drivers/net/dwc_eth_qos.c | 44 ++- drivers/net/dwc_eth_qos.h | 8 +- drivers/net/dwc_eth_qos_imx.c | 1 + drivers/net/dwc_eth_qos_intel.c| 446 + drivers/net/dwc_eth_qos_intel.h| 58 drivers/net/dwc_eth_qos_qcom.c | 1 + drivers/net/dwc_eth_qos_rockchip.c | 1 + drivers/net/dwc_eth_qos_starfive.c | 1 + drivers/net/dwc_eth_qos_stm32.c| 1 + include/pci_ids.h | 9 + 13 files changed, 575 insertions(+), 4 deletions(-) create mode 100644 drivers/net/dwc_eth_qos_intel.c create mode 100644 drivers/net/dwc_eth_qos_intel.h -- 2.39.2
[PATCH v2 1/5] x86: provide mb() macro
Implement memory barrier using mfence. Linux does it equivalently [1]. "The MFENCE instruction establishes a memory fence for both loads and stores" [2]. [1] linux/arch/x86/include/asm/barrier.h [2] Intel® 64 and IA-32 Architectures Software Developer’s Manual Signed-off-by: Philip Oberfichtner --- arch/x86/include/asm/io.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 5efb2e1b21..936ad6f588 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -244,6 +244,7 @@ static inline void sync(void) * have some advantages to use them instead of the simple one here. */ #define dmb() __asm__ __volatile__ ("" : : : "memory") +#define mb() __asm__ __volatile__ ("mfence" : : : "memory") #define __iormb() dmb() #define __iowmb() dmb() -- 2.39.2
[PATCH v2 2/5] net: dwc_eth_qos: Fix header to be self-contained
Before this commit, usage of this header relied on a specific include order. Fix it by including all dependencies. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.h | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index a06390a698..c7d3e23ab7 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -3,8 +3,11 @@ * Copyright 2022 NXP */ -#include +#include +#include #include +#include +#include /* Core registers */ -- 2.39.2
[PATCH v2 3/5] net: dwc_eth_qos: Adapt probe() for PCI devices
PCI devices do not necessarily use a device tree. In that case, the driver currently fails to find eqos->config and eqos->regs. This commit factors out the respective functionality. Device tree usage remains default, but board specific implementations will be possible as well. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.c | 28 +--- drivers/net/dwc_eth_qos.h | 3 +++ drivers/net/dwc_eth_qos_imx.c | 1 + drivers/net/dwc_eth_qos_qcom.c | 1 + drivers/net/dwc_eth_qos_rockchip.c | 1 + drivers/net/dwc_eth_qos_starfive.c | 1 + drivers/net/dwc_eth_qos_stm32.c| 1 + 7 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index b87634f1f5..34e29301cc 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1376,6 +1376,21 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +/* + * Get driver data based on the device tree. Boards not using a device tree can + * overwrite this function. + */ +__weak void *eqos_get_driver_data(struct udevice *dev) +{ + return (void *)dev_get_driver_data(dev); +} + +/* Function to get base address, useable for all boards having a device tree. */ +fdt_addr_t eqos_get_base_addr_dt(struct udevice *dev) +{ + return dev_read_addr(dev); +} + static int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1384,13 +1399,19 @@ static int eqos_probe(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); eqos->dev = dev; - eqos->config = (void *)dev_get_driver_data(dev); - eqos->regs = dev_read_addr(dev); + eqos->config = eqos_get_driver_data(dev); + if (!eqos->config) { + pr_err("Failed to get driver data.\n"); + return -ENODEV; + } + + eqos->regs = eqos->config->ops->eqos_get_base_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("dev_read_addr() failed\n"); + pr_err("Failed to get device address.\n"); return -ENODEV; } + eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); eqos->mtl_regs = (void *)(eqos->regs + EQOS_MTL_REGS_BASE); eqos->dma_regs = (void *)(eqos->regs + EQOS_DMA_REGS_BASE); @@ -1497,6 +1518,7 @@ static struct eqos_ops eqos_tegra186_ops = { .eqos_flush_buffer = eqos_flush_buffer_tegra186, .eqos_probe_resources = eqos_probe_resources_tegra186, .eqos_remove_resources = eqos_remove_resources_tegra186, + .eqos_get_base_addr = eqos_get_base_addr_dt, .eqos_stop_resets = eqos_stop_resets_tegra186, .eqos_start_resets = eqos_start_resets_tegra186, .eqos_stop_clks = eqos_stop_clks_tegra186, diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index c7d3e23ab7..829eb0a565 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -239,6 +239,7 @@ struct eqos_ops { void (*eqos_flush_buffer)(void *buf, size_t size); int (*eqos_probe_resources)(struct udevice *dev); int (*eqos_remove_resources)(struct udevice *dev); + fdt_addr_t (*eqos_get_base_addr)(struct udevice *dev); int (*eqos_stop_resets)(struct udevice *dev); int (*eqos_start_resets)(struct udevice *dev); int (*eqos_stop_clks)(struct udevice *dev); @@ -290,6 +291,8 @@ void eqos_flush_desc_generic(void *desc); void eqos_inval_buffer_generic(void *buf, size_t size); void eqos_flush_buffer_generic(void *buf, size_t size); int eqos_null_ops(struct udevice *dev); +void *eqos_get_driver_data(struct udevice *dev); +fdt_addr_t eqos_get_base_addr_dt(struct udevice *dev); extern struct eqos_config eqos_imx_config; extern struct eqos_config eqos_rockchip_config; diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c index 9c4e390441..21dbf45a22 100644 --- a/drivers/net/dwc_eth_qos_imx.c +++ b/drivers/net/dwc_eth_qos_imx.c @@ -218,6 +218,7 @@ static struct eqos_ops eqos_imx_ops = { .eqos_flush_buffer = eqos_flush_buffer_generic, .eqos_probe_resources = eqos_probe_resources_imx, .eqos_remove_resources = eqos_remove_resources_imx, + .eqos_get_base_addr = eqos_get_base_addr_dt, .eqos_stop_resets = eqos_null_ops, .eqos_start_resets = eqos_null_ops, .eqos_stop_clks = eqos_stop_clks_imx, diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c index 8178138fc6..78213e5ca0 100644 --- a/drivers/net/dwc_eth_qos_qcom.c +++ b/drivers/net/dwc_eth_qos_qcom.c @@ -589,6 +589,7 @@ static struct eqos_ops eqos_qcom_ops = { .eqos_flush_buffer = eqos_flush_buffer_generic, .eqos_probe_resources = eqos_probe_resources_qcom, .eqos_remove_resources = eqos_remove_resources_qcom,
[PATCH v2 4/5] net: dwc_eth_qos: Implement bind() for PCI devices
PCI devices do not necessarily use a device tree. Implement a bind() function to assign unique device names in that case. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 34e29301cc..2eeaccc800 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1376,6 +1376,21 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +static int eqos_bind(struct udevice *dev) +{ + static int dev_num; + const size_t name_sz = 16; + char name[name_sz]; + + /* Device name defaults to DT node name. */ + if (ofnode_valid(dev_ofnode(dev))) + return 0; + + /* Assign unique names in case there is no DT node. */ + snprintf(name, name_sz, "eth_eqos#%d", dev_num++); + return device_set_name(dev, name); +} + /* * Get driver data based on the device tree. Boards not using a device tree can * overwrite this function. @@ -1597,6 +1612,7 @@ U_BOOT_DRIVER(eth_eqos) = { .name = "eth_eqos", .id = UCLASS_ETH, .of_match = of_match_ptr(eqos_ids), + .bind = eqos_bind, .probe = eqos_probe, .remove = eqos_remove, .ops = &eqos_ops, -- 2.39.2
[PATCH v2 5/5] net: dwc_eth_qos: Add glue driver for Intel MAC
Add dwc_eth_qos glue driver for the Intel Elkhart-Lake SOC. Signed-off-by: Philip Oberfichtner --- Notes: Changes in V2: - Remove 'struct eqos_intel_config' from dwc_eth_qos.h - Improve some comments - Remove duplicate MAC reset drivers/net/Kconfig | 7 + drivers/net/Makefile| 1 + drivers/net/dwc_eth_qos_intel.c | 446 drivers/net/dwc_eth_qos_intel.h | 58 + include/pci_ids.h | 9 + 5 files changed, 521 insertions(+) create mode 100644 drivers/net/dwc_eth_qos_intel.c create mode 100644 drivers/net/dwc_eth_qos_intel.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b2d7b49976..b23fe55792 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -225,6 +225,13 @@ config DWC_ETH_QOS_IMX The Synopsys Designware Ethernet QOS IP block with the specific configuration used in IMX soc. +config DWC_ETH_QOS_INTEL + bool "Synopsys DWC Ethernet QOS device support for Intel" + depends on DWC_ETH_QOS + help + The Synopsys Designware Ethernet QOS IP block with the specific + configuration used in the Intel Elkhart-Lake soc. + config DWC_ETH_QOS_ROCKCHIP bool "Synopsys DWC Ethernet QOS device support for Rockchip SoCs" depends on DWC_ETH_QOS diff --git a/drivers/net/Makefile b/drivers/net/Makefile index dc3404519d..bd62c65dd5 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o +obj-$(CONFIG_DWC_ETH_QOS_INTEL) += dwc_eth_qos_intel.o obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o diff --git a/drivers/net/dwc_eth_qos_intel.c b/drivers/net/dwc_eth_qos_intel.c new file mode 100644 index 00..15680187cc --- /dev/null +++ b/drivers/net/dwc_eth_qos_intel.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 DENX Software Engineering GmbH + * Philip Oberfichtner + * + * Based on linux v6.1.38, especially drivers/net/ethernet/stmicro/stmmac + */ + +#include +#include +#include +#include +#include +#include + +#include "dwc_eth_qos.h" +#include "dwc_eth_qos_intel.h" + +static struct pci_device_id intel_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII2G5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5) }, + {} +}; + +static int __pci_config(struct udevice *dev) +{ + u32 val; + + /* Try to enable I/O accesses and bus-mastering */ + dm_pci_read_config32(dev, PCI_COMMAND, &val); + val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + dm_pci_write_config32(dev, PCI_COMMAND, val); + + /* Make sure it worked */ + dm_pci_read_config32(dev, PCI_COMMAND, &val); + if (!(val & PCI_COMMAND_MEMORY)) { + pr_err("%s: Can't enable I/O memory\n", __func__); + return -ENOSPC; + } + + if (!(val & PCI_COMMAND_MASTER)) { + pr_err("%s: Can't enable bus-mastering\n", __func__); + return -EPERM; + } + + return 0; +} + +static void __limit_fifo_size(struct udevice *dev) +{ + /* +* As described in Intel Erratum EHL22, Document Number: 636674-2.1, +* the PSE GbE Controllers advertise a wrong RX and TX fifo size. +* Software should limit this value to 64KB. +*/ + struct eqos_priv *eqos = dev_get_priv(dev); + + eqos->tx_fifo_sz = 0x8000; + eqos->rx_fifo_sz = 0x8000; +} + +static int __serdes_status_poll(struct udevice *dev, + unsigned char phyaddr, unsigned char phyreg, + unsigned short mask, unsigned short val) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + unsigned int retries = 10; + unsigned short val_rd; + + do { + miiphy_read(eqos->mii->name, phyaddr, phyreg, &val_rd); + if ((val_rd & mask) == (val & mask)) +
[RESEND PATCH v2 0/5] net: dwc_eth_qos: Add glue driver for Intel MAC
This patch series implements the dwc_eth_qos glue driver for Intel SOCs. Before doing that, a few general adaptions to the dwc_eth_qos.c main driver are required. Most notably, the preparation for PCI based driver instances, which do not necessarily use a device tree. This patch series depends on: "net: dwc_eth_qos: mdio: Implement clause 45": https://patchwork.ozlabs.org/project/uboot/patch/20240507094237.168238-1-...@denx.de/ Changes in V2: Improve coding-style in PATCH 5/5 Philip Oberfichtner (5): x86: provide mb() macro net: dwc_eth_qos: Fix header to be self-contained net: dwc_eth_qos: Adapt probe() for PCI devices net: dwc_eth_qos: Implement bind() for PCI devices net: dwc_eth_qos: Add glue driver for Intel MAC arch/x86/include/asm/io.h | 1 + drivers/net/Kconfig| 7 + drivers/net/Makefile | 1 + drivers/net/dwc_eth_qos.c | 44 ++- drivers/net/dwc_eth_qos.h | 8 +- drivers/net/dwc_eth_qos_imx.c | 1 + drivers/net/dwc_eth_qos_intel.c| 446 + drivers/net/dwc_eth_qos_intel.h| 58 drivers/net/dwc_eth_qos_qcom.c | 1 + drivers/net/dwc_eth_qos_rockchip.c | 1 + drivers/net/dwc_eth_qos_starfive.c | 1 + drivers/net/dwc_eth_qos_stm32.c| 1 + include/pci_ids.h | 9 + 13 files changed, 575 insertions(+), 4 deletions(-) create mode 100644 drivers/net/dwc_eth_qos_intel.c create mode 100644 drivers/net/dwc_eth_qos_intel.h -- 2.39.2
[RESEND PATCH v2 1/5] x86: provide mb() macro
Implement memory barrier using mfence. Linux does it equivalently [1]. "The MFENCE instruction establishes a memory fence for both loads and stores" [2]. [1] linux/arch/x86/include/asm/barrier.h [2] Intel® 64 and IA-32 Architectures Software Developer’s Manual Signed-off-by: Philip Oberfichtner --- arch/x86/include/asm/io.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 5efb2e1b21..936ad6f588 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -244,6 +244,7 @@ static inline void sync(void) * have some advantages to use them instead of the simple one here. */ #define dmb() __asm__ __volatile__ ("" : : : "memory") +#define mb() __asm__ __volatile__ ("mfence" : : : "memory") #define __iormb() dmb() #define __iowmb() dmb() -- 2.39.2
[RESEND PATCH v2 2/5] net: dwc_eth_qos: Fix header to be self-contained
Before this commit, usage of this header relied on a specific include order. Fix it by including all dependencies. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.h | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index a06390a698..c7d3e23ab7 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -3,8 +3,11 @@ * Copyright 2022 NXP */ -#include +#include +#include #include +#include +#include /* Core registers */ -- 2.39.2
[RESEND PATCH v2 3/5] net: dwc_eth_qos: Adapt probe() for PCI devices
PCI devices do not necessarily use a device tree. In that case, the driver currently fails to find eqos->config and eqos->regs. This commit factors out the respective functionality. Device tree usage remains default, but board specific implementations will be possible as well. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.c | 28 +--- drivers/net/dwc_eth_qos.h | 3 +++ drivers/net/dwc_eth_qos_imx.c | 1 + drivers/net/dwc_eth_qos_qcom.c | 1 + drivers/net/dwc_eth_qos_rockchip.c | 1 + drivers/net/dwc_eth_qos_starfive.c | 1 + drivers/net/dwc_eth_qos_stm32.c| 1 + 7 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index b87634f1f5..34e29301cc 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1376,6 +1376,21 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +/* + * Get driver data based on the device tree. Boards not using a device tree can + * overwrite this function. + */ +__weak void *eqos_get_driver_data(struct udevice *dev) +{ + return (void *)dev_get_driver_data(dev); +} + +/* Function to get base address, useable for all boards having a device tree. */ +fdt_addr_t eqos_get_base_addr_dt(struct udevice *dev) +{ + return dev_read_addr(dev); +} + static int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1384,13 +1399,19 @@ static int eqos_probe(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); eqos->dev = dev; - eqos->config = (void *)dev_get_driver_data(dev); - eqos->regs = dev_read_addr(dev); + eqos->config = eqos_get_driver_data(dev); + if (!eqos->config) { + pr_err("Failed to get driver data.\n"); + return -ENODEV; + } + + eqos->regs = eqos->config->ops->eqos_get_base_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("dev_read_addr() failed\n"); + pr_err("Failed to get device address.\n"); return -ENODEV; } + eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); eqos->mtl_regs = (void *)(eqos->regs + EQOS_MTL_REGS_BASE); eqos->dma_regs = (void *)(eqos->regs + EQOS_DMA_REGS_BASE); @@ -1497,6 +1518,7 @@ static struct eqos_ops eqos_tegra186_ops = { .eqos_flush_buffer = eqos_flush_buffer_tegra186, .eqos_probe_resources = eqos_probe_resources_tegra186, .eqos_remove_resources = eqos_remove_resources_tegra186, + .eqos_get_base_addr = eqos_get_base_addr_dt, .eqos_stop_resets = eqos_stop_resets_tegra186, .eqos_start_resets = eqos_start_resets_tegra186, .eqos_stop_clks = eqos_stop_clks_tegra186, diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index c7d3e23ab7..829eb0a565 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -239,6 +239,7 @@ struct eqos_ops { void (*eqos_flush_buffer)(void *buf, size_t size); int (*eqos_probe_resources)(struct udevice *dev); int (*eqos_remove_resources)(struct udevice *dev); + fdt_addr_t (*eqos_get_base_addr)(struct udevice *dev); int (*eqos_stop_resets)(struct udevice *dev); int (*eqos_start_resets)(struct udevice *dev); int (*eqos_stop_clks)(struct udevice *dev); @@ -290,6 +291,8 @@ void eqos_flush_desc_generic(void *desc); void eqos_inval_buffer_generic(void *buf, size_t size); void eqos_flush_buffer_generic(void *buf, size_t size); int eqos_null_ops(struct udevice *dev); +void *eqos_get_driver_data(struct udevice *dev); +fdt_addr_t eqos_get_base_addr_dt(struct udevice *dev); extern struct eqos_config eqos_imx_config; extern struct eqos_config eqos_rockchip_config; diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c index 9c4e390441..21dbf45a22 100644 --- a/drivers/net/dwc_eth_qos_imx.c +++ b/drivers/net/dwc_eth_qos_imx.c @@ -218,6 +218,7 @@ static struct eqos_ops eqos_imx_ops = { .eqos_flush_buffer = eqos_flush_buffer_generic, .eqos_probe_resources = eqos_probe_resources_imx, .eqos_remove_resources = eqos_remove_resources_imx, + .eqos_get_base_addr = eqos_get_base_addr_dt, .eqos_stop_resets = eqos_null_ops, .eqos_start_resets = eqos_null_ops, .eqos_stop_clks = eqos_stop_clks_imx, diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c index 8178138fc6..78213e5ca0 100644 --- a/drivers/net/dwc_eth_qos_qcom.c +++ b/drivers/net/dwc_eth_qos_qcom.c @@ -589,6 +589,7 @@ static struct eqos_ops eqos_qcom_ops = { .eqos_flush_buffer = eqos_flush_buffer_generic, .eqos_probe_resources = eqos_probe_resources_qcom, .eqos_remove_resources = eqos_remove_resources_qcom,
[RESEND PATCH v2 4/5] net: dwc_eth_qos: Implement bind() for PCI devices
PCI devices do not necessarily use a device tree. Implement a bind() function to assign unique device names in that case. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 34e29301cc..2eeaccc800 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1376,6 +1376,21 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +static int eqos_bind(struct udevice *dev) +{ + static int dev_num; + const size_t name_sz = 16; + char name[name_sz]; + + /* Device name defaults to DT node name. */ + if (ofnode_valid(dev_ofnode(dev))) + return 0; + + /* Assign unique names in case there is no DT node. */ + snprintf(name, name_sz, "eth_eqos#%d", dev_num++); + return device_set_name(dev, name); +} + /* * Get driver data based on the device tree. Boards not using a device tree can * overwrite this function. @@ -1597,6 +1612,7 @@ U_BOOT_DRIVER(eth_eqos) = { .name = "eth_eqos", .id = UCLASS_ETH, .of_match = of_match_ptr(eqos_ids), + .bind = eqos_bind, .probe = eqos_probe, .remove = eqos_remove, .ops = &eqos_ops, -- 2.39.2
[RESEND PATCH v2 5/5] net: dwc_eth_qos: Add glue driver for Intel MAC
Add dwc_eth_qos glue driver for the Intel Elkhart-Lake SOC. Signed-off-by: Philip Oberfichtner --- Notes: Changes in V2: - Remove 'struct eqos_intel_config' from dwc_eth_qos.h - Improve some comments - Remove duplicate MAC reset drivers/net/Kconfig | 7 + drivers/net/Makefile| 1 + drivers/net/dwc_eth_qos_intel.c | 446 drivers/net/dwc_eth_qos_intel.h | 58 + include/pci_ids.h | 9 + 5 files changed, 521 insertions(+) create mode 100644 drivers/net/dwc_eth_qos_intel.c create mode 100644 drivers/net/dwc_eth_qos_intel.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b2d7b49976..b23fe55792 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -225,6 +225,13 @@ config DWC_ETH_QOS_IMX The Synopsys Designware Ethernet QOS IP block with the specific configuration used in IMX soc. +config DWC_ETH_QOS_INTEL + bool "Synopsys DWC Ethernet QOS device support for Intel" + depends on DWC_ETH_QOS + help + The Synopsys Designware Ethernet QOS IP block with the specific + configuration used in the Intel Elkhart-Lake soc. + config DWC_ETH_QOS_ROCKCHIP bool "Synopsys DWC Ethernet QOS device support for Rockchip SoCs" depends on DWC_ETH_QOS diff --git a/drivers/net/Makefile b/drivers/net/Makefile index dc3404519d..bd62c65dd5 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o +obj-$(CONFIG_DWC_ETH_QOS_INTEL) += dwc_eth_qos_intel.o obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o diff --git a/drivers/net/dwc_eth_qos_intel.c b/drivers/net/dwc_eth_qos_intel.c new file mode 100644 index 00..15680187cc --- /dev/null +++ b/drivers/net/dwc_eth_qos_intel.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 DENX Software Engineering GmbH + * Philip Oberfichtner + * + * Based on linux v6.1.38, especially drivers/net/ethernet/stmicro/stmmac + */ + +#include +#include +#include +#include +#include +#include + +#include "dwc_eth_qos.h" +#include "dwc_eth_qos_intel.h" + +static struct pci_device_id intel_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII2G5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5) }, + {} +}; + +static int __pci_config(struct udevice *dev) +{ + u32 val; + + /* Try to enable I/O accesses and bus-mastering */ + dm_pci_read_config32(dev, PCI_COMMAND, &val); + val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + dm_pci_write_config32(dev, PCI_COMMAND, val); + + /* Make sure it worked */ + dm_pci_read_config32(dev, PCI_COMMAND, &val); + if (!(val & PCI_COMMAND_MEMORY)) { + pr_err("%s: Can't enable I/O memory\n", __func__); + return -ENOSPC; + } + + if (!(val & PCI_COMMAND_MASTER)) { + pr_err("%s: Can't enable bus-mastering\n", __func__); + return -EPERM; + } + + return 0; +} + +static void __limit_fifo_size(struct udevice *dev) +{ + /* +* As described in Intel Erratum EHL22, Document Number: 636674-2.1, +* the PSE GbE Controllers advertise a wrong RX and TX fifo size. +* Software should limit this value to 64KB. +*/ + struct eqos_priv *eqos = dev_get_priv(dev); + + eqos->tx_fifo_sz = 0x8000; + eqos->rx_fifo_sz = 0x8000; +} + +static int __serdes_status_poll(struct udevice *dev, + unsigned char phyaddr, unsigned char phyreg, + unsigned short mask, unsigned short val) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + unsigned int retries = 10; + unsigned short val_rd; + + do { + miiphy_read(eqos->mii->name, phyaddr, phyreg, &val_rd); + if ((val_rd & mask) == (val & mask)) +
Re: [RESEND PATCH v2 1/5] x86: provide mb() macro
Hi Simon, On Tue, Jun 25, 2024 at 01:30:18PM +0100, Simon Glass wrote: > Hi Philip, > > On Mon, 24 Jun 2024 at 02:35, Philip Oberfichtner wrote: > > > > Implement memory barrier using mfence. Linux does it equivalently [1]. > > > > "The MFENCE instruction establishes a memory fence for both loads and > > stores" [2]. > > > > [1] linux/arch/x86/include/asm/barrier.h > > [2] Intel® 64 and IA-32 Architectures Software Developer’s Manual > > > > Signed-off-by: Philip Oberfichtner > > --- > > arch/x86/include/asm/io.h | 1 + > > 1 file changed, 1 insertion(+) > > > > diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h > > index 5efb2e1b21..936ad6f588 100644 > > --- a/arch/x86/include/asm/io.h > > +++ b/arch/x86/include/asm/io.h > > @@ -244,6 +244,7 @@ static inline void sync(void) > > * have some advantages to use them instead of the simple one here. > > */ > > #define dmb() __asm__ __volatile__ ("" : : : "memory") > > +#define mb() __asm__ __volatile__ ("mfence" : : : "memory") > > #define __iormb() dmb() > > #define __iowmb() dmb() > > > > -- > > This exists in arch/x86/include/asm/cpu.h so can you please remove > that one as well, in this patch? Thanks for the hint. I'll include it in V3. (Assuming I got you correctly, to remove mfence() occurrences and replace them with the new mb() macro). Best regards, Philip > > Regards, > Simon > > > 2.39.2 > > -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de =
Re: [RESEND PATCH v2 3/5] net: dwc_eth_qos: Adapt probe() for PCI devices
Hi Marek, Thank you for the review! On Sun, Jun 30, 2024 at 07:33:33AM +0200, Marek Vasut wrote: > On 6/24/24 10:34 AM, Philip Oberfichtner wrote: > > PCI devices do not necessarily use a device tree. In that case, the > > driver currently fails to find eqos->config and eqos->regs. > > > > This commit factors out the respective functionality. Device tree usage > > remains default, but board specific implementations will be possible as > > well. > > > > Signed-off-by: Philip Oberfichtner > > --- > > drivers/net/dwc_eth_qos.c | 28 +--- > > drivers/net/dwc_eth_qos.h | 3 +++ > > drivers/net/dwc_eth_qos_imx.c | 1 + > > drivers/net/dwc_eth_qos_qcom.c | 1 + > > drivers/net/dwc_eth_qos_rockchip.c | 1 + > > drivers/net/dwc_eth_qos_starfive.c | 1 + > > drivers/net/dwc_eth_qos_stm32.c| 1 + > > 7 files changed, 33 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c > > index b87634f1f5..34e29301cc 100644 > > --- a/drivers/net/dwc_eth_qos.c > > +++ b/drivers/net/dwc_eth_qos.c > > @@ -1376,6 +1376,21 @@ static int eqos_remove_resources_tegra186(struct > > udevice *dev) > > return 0; > > } > > +/* > > + * Get driver data based on the device tree. Boards not using a device > > tree can > > + * overwrite this function. > > + */ > > +__weak void *eqos_get_driver_data(struct udevice *dev) > > +{ > > + return (void *)dev_get_driver_data(dev); > > +} > > + > > +/* Function to get base address, useable for all boards having a device > > tree. */ > > +fdt_addr_t eqos_get_base_addr_dt(struct udevice *dev) > > +{ > > + return dev_read_addr(dev); > > +} > > + > > static int eqos_probe(struct udevice *dev) > > { > > struct eqos_priv *eqos = dev_get_priv(dev); > > @@ -1384,13 +1399,19 @@ static int eqos_probe(struct udevice *dev) > > debug("%s(dev=%p):\n", __func__, dev); > > eqos->dev = dev; > > - eqos->config = (void *)dev_get_driver_data(dev); > > - eqos->regs = dev_read_addr(dev); > > + eqos->config = eqos_get_driver_data(dev); > > + if (!eqos->config) { > > + pr_err("Failed to get driver data.\n"); > > + return -ENODEV; > > + } > > + > > + eqos->regs = eqos->config->ops->eqos_get_base_addr(dev); > > if (eqos->regs == FDT_ADDR_T_NONE) { > > - pr_err("dev_read_addr() failed\n"); > > + pr_err("Failed to get device address.\n"); > > return -ENODEV; > > } > > + > > eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); > > eqos->mtl_regs = (void *)(eqos->regs + EQOS_MTL_REGS_BASE); > > eqos->dma_regs = (void *)(eqos->regs + EQOS_DMA_REGS_BASE); > > Could you factor out the entirety of: > > eqos->regs = dev_read_addr(dev); > if (eqos->regs == FDT_ADDR_T_NONE) { > pr_err("dev_read_addr() failed\n"); > return -ENODEV; > } > eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); > eqos->mtl_regs = (void *)(eqos->regs + EQOS_MTL_REGS_BASE); > eqos->dma_regs = (void *)(eqos->regs + EQOS_DMA_REGS_BASE); > eqos->tegra186_regs = (void *)(eqos->regs + > EQOS_TEGRA186_REGS_BASE); > > into some common function, like eqos_get_base_addr_dt() , and call it from > .eqos_probe_resources callback instead ? That way you wouldn't have to add > new callback specifically for register address. Good point. I'll include it in V3. Best regards, Philip -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de =
Re: [RESEND PATCH v2 5/5] net: dwc_eth_qos: Add glue driver for Intel MAC
Hi Marek, On Sun, Jun 30, 2024 at 07:38:43AM +0200, Marek Vasut wrote: > On 6/24/24 10:34 AM, Philip Oberfichtner wrote: > > > +++ b/drivers/net/dwc_eth_qos_intel.c > > @@ -0,0 +1,446 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > +/* > > + * Copyright (c) 2023 DENX Software Engineering GmbH > > + * Philip Oberfichtner > > + * > > + * Based on linux v6.1.38, especially drivers/net/ethernet/stmicro/stmmac > > It is 2024 now , also you might want to update this to match Linux 6.6.y > which is the current LTS . > Ack for V3. > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#include "dwc_eth_qos.h" > > +#include "dwc_eth_qos_intel.h" > > + > > +static struct pci_device_id intel_pci_ids[] = { > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_RGMII1G) }, > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII1) }, > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII2G5) }, > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G) > > }, > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G) > > }, > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, > > PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5) }, > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G) > > }, > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G) > > }, > > + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, > > PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5) }, > > + {} > > +}; > > + > > +static int __pci_config(struct udevice *dev) > > +{ > > + u32 val; > > + > > + /* Try to enable I/O accesses and bus-mastering */ > > + dm_pci_read_config32(dev, PCI_COMMAND, &val); > > + val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; > > + dm_pci_write_config32(dev, PCI_COMMAND, val); > > + > > + /* Make sure it worked */ > > + dm_pci_read_config32(dev, PCI_COMMAND, &val); > > + if (!(val & PCI_COMMAND_MEMORY)) { > > + pr_err("%s: Can't enable I/O memory\n", __func__); > > dev_err() please > > > + return -ENOSPC; > > + } > > + > > + if (!(val & PCI_COMMAND_MASTER)) { > > + pr_err("%s: Can't enable bus-mastering\n", __func__); > > dev_err() , fix globally. > Ack for V3. > > + return -EPERM; > > + } > > + > > + return 0; > > +} > > + > > +static void __limit_fifo_size(struct udevice *dev) > > Please drop the leading __ from function names . > Ack for V3. > > +{ > > + /* > > +* As described in Intel Erratum EHL22, Document Number: 636674-2.1, > > +* the PSE GbE Controllers advertise a wrong RX and TX fifo size. > > +* Software should limit this value to 64KB. > > +*/ > > + struct eqos_priv *eqos = dev_get_priv(dev); > > + > > + eqos->tx_fifo_sz = 0x8000; > > + eqos->rx_fifo_sz = 0x8000; > > +} > > + > > +static int __serdes_status_poll(struct udevice *dev, > > + unsigned char phyaddr, unsigned char phyreg, > > + unsigned short mask, unsigned short val) > > +{ > > + struct eqos_priv *eqos = dev_get_priv(dev); > > + unsigned int retries = 10; > > + unsigned short val_rd; > > + > > + do { > > + miiphy_read(eqos->mii->name, phyaddr, phyreg, &val_rd); > > + if ((val_rd & mask) == (val & mask)) > > + return 0; > > + udelay(POLL_DELAY_US); > > + } while (--retries); > > Is this some implementation of phy_read_mmd_poll_timeout() ? > Well ... sort of, but see below. > > + return -ETIMEDOUT; > > +} > > + > > + /* Returns -ve if MAC is unknown and 0 on success */ > > +static int __mac_check_pse(const struct udevice *dev, bool *is_pse) > > +{ > > + struct pci_child_plat *plat = dev_get_parent_plat(dev); > > + > > + if (!plat || plat->vendor != PCI_VENDOR_ID_INTEL) > > + return -ENXIO; > > + > > + switch (plat->device) { > > + case PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G: > > + case PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G: > > + case PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G: > > + case PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G: > > + case PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5:
[PATCH v3 0/5] net: dwc_eth_qos: Add glue driver for Intel MAC
This patch series implements the dwc_eth_qos glue driver for Intel SOCs. Before doing that, a few general adaptions to the dwc_eth_qos.c main driver are required. Most notably, the preparation for PCI based driver instances, which do not necessarily use a device tree. This patch series depends on: "net: dwc_eth_qos: mdio: Implement clause 45": https://patchwork.ozlabs.org/project/uboot/patch/20240507094237.168238-1-...@denx.de/ Changes in V3: - Replace mfence() with mb() - Clean-up eqos_get_base_addr() - Several style fixes for dwc_eth_qos_intel Philip Oberfichtner (5): x86: provide mb() macro net: dwc_eth_qos: Fix header to be self-contained net: dwc_eth_qos: Adapt probe() for PCI devices net: dwc_eth_qos: Implement bind() for PCI devices net: dwc_eth_qos: Add glue driver for Intel MAC arch/x86/cpu/mp_init.c | 10 +- arch/x86/include/asm/cpu.h | 5 - arch/x86/include/asm/io.h | 1 + drivers/net/Kconfig| 7 + drivers/net/Makefile | 1 + drivers/net/dwc_eth_qos.c | 79 - drivers/net/dwc_eth_qos.h | 8 +- drivers/net/dwc_eth_qos_imx.c | 6 + drivers/net/dwc_eth_qos_intel.c| 449 + drivers/net/dwc_eth_qos_intel.h| 57 drivers/net/dwc_eth_qos_qcom.c | 6 + drivers/net/dwc_eth_qos_rockchip.c | 6 + drivers/net/dwc_eth_qos_starfive.c | 6 + drivers/net/dwc_eth_qos_stm32.c| 6 + include/pci_ids.h | 9 + 15 files changed, 637 insertions(+), 19 deletions(-) create mode 100644 drivers/net/dwc_eth_qos_intel.c create mode 100644 drivers/net/dwc_eth_qos_intel.h -- 2.39.2
[PATCH v3 1/5] x86: provide mb() macro
Implement a x86 memory barrier mb(). Furthermore, remove the previously used mfence() function, which does the same thing. The mb() macro is now equivalent to Linux (v6.9): linux/arch/x86/include/asm/barrier.h Signed-off-by: Philip Oberfichtner --- Notes: Changes in V3: - Remove mfence() function arch/x86/cpu/mp_init.c | 10 +- arch/x86/include/asm/cpu.h | 5 - arch/x86/include/asm/io.h | 1 + 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/arch/x86/cpu/mp_init.c b/arch/x86/cpu/mp_init.c index aa1f47d7227..e2e1849c065 100644 --- a/arch/x86/cpu/mp_init.c +++ b/arch/x86/cpu/mp_init.c @@ -164,12 +164,12 @@ static inline void barrier_wait(atomic_t *b) { while (atomic_read(b) == 0) asm("pause"); - mfence(); + mb(); } static inline void release_barrier(atomic_t *b) { - mfence(); + mb(); atomic_set(b, 1); } @@ -631,7 +631,7 @@ static int run_ap_work(struct mp_callback *callback, struct udevice *bsp, if (cur_cpu != i) store_callback(&ap_callbacks[i], callback); } - mfence(); + mb(); /* Wait for all the APs to signal back that call has been accepted. */ start = get_timer(0); @@ -656,7 +656,7 @@ static int run_ap_work(struct mp_callback *callback, struct udevice *bsp, } while (cpus_accepted != num_aps); /* Make sure we can see any data written by the APs */ - mfence(); + mb(); return 0; } @@ -692,7 +692,7 @@ static int ap_wait_for_instruction(struct udevice *cpu, void *unused) /* Copy to local variable before using the value */ memcpy(&lcb, cb, sizeof(lcb)); - mfence(); + mb(); if (lcb.logical_cpu_number == MP_SELECT_ALL || lcb.logical_cpu_number == MP_SELECT_APS || dev_seq(cpu) == lcb.logical_cpu_number) diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 073f80b07f1..87e0c6f12b6 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -185,11 +185,6 @@ static inline int flag_is_changeable_p(uint32_t flag) } #endif -static inline void mfence(void) -{ - __asm__ __volatile__("mfence" : : : "memory"); -} - /** * cpu_enable_paging_pae() - Enable PAE-paging * diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index c6d90eb794a..1390193f09c 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -240,6 +240,7 @@ static inline void sync(void) * have some advantages to use them instead of the simple one here. */ #define dmb() __asm__ __volatile__ ("" : : : "memory") +#define mb() __asm__ __volatile__ ("mfence" : : : "memory") #define __iormb() dmb() #define __iowmb() dmb() -- 2.39.2
[PATCH v3 2/5] net: dwc_eth_qos: Fix header to be self-contained
Before this commit, usage of this header relied on a specific include order. Fix it by including all dependencies. Signed-off-by: Philip Oberfichtner Reviewed-by: Marek Vasut --- drivers/net/dwc_eth_qos.h | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 8b3d0d464d3..6372ba9f35c 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -3,8 +3,11 @@ * Copyright 2022 NXP */ -#include +#include +#include #include +#include +#include /* Core registers */ -- 2.39.2
[PATCH v3 3/5] net: dwc_eth_qos: Adapt probe() for PCI devices
PCI devices do not necessarily use a device tree. In that case, the driver currently fails to find eqos->config and eqos->regs. This commit factors out the respective functionality. Device tree usage remains default, but board specific implementations will be possible as well. Signed-off-by: Philip Oberfichtner --- Notes: Changes in V3: Factor out eqos_get_base_addr_common() in order to avoid introducing a new callback function. drivers/net/dwc_eth_qos.c | 51 +- drivers/net/dwc_eth_qos.h | 2 ++ drivers/net/dwc_eth_qos_imx.c | 6 drivers/net/dwc_eth_qos_qcom.c | 6 drivers/net/dwc_eth_qos_rockchip.c | 6 drivers/net/dwc_eth_qos_starfive.c | 6 drivers/net/dwc_eth_qos_stm32.c| 6 7 files changed, 75 insertions(+), 8 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 67ac86f82bc..039d7d409e3 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -1279,6 +1280,13 @@ static int eqos_probe_resources_tegra186(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); + ret = eqos_get_base_addr_dt(dev); + if (ret) { + pr_err("eqos_get_base_addr_dt failed: %d\n", ret); + return ret; + } + eqos->tegra186_regs = (void *)(eqos->regs + EQOS_TEGRA186_REGS_BASE); + ret = reset_get_by_name(dev, "eqos", &eqos->reset_ctl); if (ret) { pr_err("reset_get_by_name(rst) failed: %d\n", ret); @@ -1353,6 +1361,38 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +/* + * Get driver data based on the device tree. Boards not using a device tree can + * overwrite this function. + */ +__weak void *eqos_get_driver_data(struct udevice *dev) +{ + return (void *)dev_get_driver_data(dev); +} + +static fdt_addr_t eqos_get_base_addr_common(struct udevice *dev, fdt_addr_t addr) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + + if (addr == FDT_ADDR_T_NONE) { + dev_err(dev, "addr=0x%llx is invalid.\n", addr); + return -EINVAL; + } + + eqos->regs = addr; + eqos->mac_regs = (void *)(addr + EQOS_MAC_REGS_BASE); + eqos->mtl_regs = (void *)(addr + EQOS_MTL_REGS_BASE); + eqos->dma_regs = (void *)(addr + EQOS_DMA_REGS_BASE); + + return 0; +} + +int eqos_get_base_addr_dt(struct udevice *dev) +{ + fdt_addr_t addr = dev_read_addr(dev); + return eqos_get_base_addr_common(dev, addr); +} + static int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1361,17 +1401,12 @@ static int eqos_probe(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); eqos->dev = dev; - eqos->config = (void *)dev_get_driver_data(dev); - eqos->regs = dev_read_addr(dev); - if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("dev_read_addr() failed\n"); + eqos->config = eqos_get_driver_data(dev); + if (!eqos->config) { + pr_err("Failed to get driver data.\n"); return -ENODEV; } - eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); - eqos->mtl_regs = (void *)(eqos->regs + EQOS_MTL_REGS_BASE); - eqos->dma_regs = (void *)(eqos->regs + EQOS_DMA_REGS_BASE); - eqos->tegra186_regs = (void *)(eqos->regs + EQOS_TEGRA186_REGS_BASE); eqos->max_speed = dev_read_u32_default(dev, "max-speed", 0); diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 6372ba9f35c..1121d242ca6 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -288,7 +288,9 @@ void eqos_inval_desc_generic(void *desc); void eqos_flush_desc_generic(void *desc); void eqos_inval_buffer_generic(void *buf, size_t size); void eqos_flush_buffer_generic(void *buf, size_t size); +int eqos_get_base_addr_dt(struct udevice *dev); int eqos_null_ops(struct udevice *dev); +void *eqos_get_driver_data(struct udevice *dev); extern struct eqos_config eqos_imx_config; extern struct eqos_config eqos_rockchip_config; diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c index d6bed278ca7..642432834f5 100644 --- a/drivers/net/dwc_eth_qos_imx.c +++ b/drivers/net/dwc_eth_qos_imx.c @@ -47,6 +47,12 @@ static int eqos_probe_resources_imx(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); + ret = eqos_get_base_addr_dt(dev); + if (ret) { + dev_dbg(dev, "eqos_get_base_addr_dt failed: %d", ret); + goto err_probe; + } + interface = eqos->config->interfac
[PATCH v3 4/5] net: dwc_eth_qos: Implement bind() for PCI devices
PCI devices do not necessarily use a device tree. Implement a bind() function to assign unique device names in that case. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 039d7d409e3..b7aef751866 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1361,6 +1361,21 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +static int eqos_bind(struct udevice *dev) +{ + static int dev_num; + const size_t name_sz = 16; + char name[name_sz]; + + /* Device name defaults to DT node name. */ + if (ofnode_valid(dev_ofnode(dev))) + return 0; + + /* Assign unique names in case there is no DT node. */ + snprintf(name, name_sz, "eth_eqos#%d", dev_num++); + return device_set_name(dev, name); +} + /* * Get driver data based on the device tree. Boards not using a device tree can * overwrite this function. @@ -1587,6 +1602,7 @@ U_BOOT_DRIVER(eth_eqos) = { .name = "eth_eqos", .id = UCLASS_ETH, .of_match = of_match_ptr(eqos_ids), + .bind = eqos_bind, .probe = eqos_probe, .remove = eqos_remove, .ops = &eqos_ops, -- 2.39.2
[PATCH v3 5/5] net: dwc_eth_qos: Add glue driver for Intel MAC
Add dwc_eth_qos glue driver for the Intel Elkhart-Lake SOC. Signed-off-by: Philip Oberfichtner --- Notes: Changes in V3: - update linux reference to current stable - replace pr_err by dev_err - drop __prefix from local function names - use FIELD_PREP to simplify bitfield extraction drivers/net/Kconfig | 7 + drivers/net/Makefile| 1 + drivers/net/dwc_eth_qos.c | 12 + drivers/net/dwc_eth_qos.h | 1 + drivers/net/dwc_eth_qos_intel.c | 449 drivers/net/dwc_eth_qos_intel.h | 57 include/pci_ids.h | 9 + 7 files changed, 536 insertions(+) create mode 100644 drivers/net/dwc_eth_qos_intel.c create mode 100644 drivers/net/dwc_eth_qos_intel.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b4ff033afa9..6f5618918f6 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -243,6 +243,13 @@ config DWC_ETH_QOS_IMX The Synopsys Designware Ethernet QOS IP block with the specific configuration used in IMX soc. +config DWC_ETH_QOS_INTEL + bool "Synopsys DWC Ethernet QOS device support for Intel" + depends on DWC_ETH_QOS + help + The Synopsys Designware Ethernet QOS IP block with the specific + configuration used in the Intel Elkhart-Lake soc. + config DWC_ETH_QOS_ROCKCHIP bool "Synopsys DWC Ethernet QOS device support for Rockchip SoCs" depends on DWC_ETH_QOS diff --git a/drivers/net/Makefile b/drivers/net/Makefile index dce71685c3d..685dda5a584 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o +obj-$(CONFIG_DWC_ETH_QOS_INTEL) += dwc_eth_qos_intel.o obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o obj-$(CONFIG_DWC_ETH_XGMAC) += dwc_eth_xgmac.o diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index b7aef751866..19f0e9eb5b4 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1408,6 +1408,18 @@ int eqos_get_base_addr_dt(struct udevice *dev) return eqos_get_base_addr_common(dev, addr); } +int eqos_get_base_addr_pci(struct udevice *dev) +{ + fdt_addr_t addr; + void *paddr; + + paddr = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE, + PCI_REGION_MEM); + addr = paddr ? (fdt_addr_t)paddr : FDT_ADDR_T_NONE; + + return eqos_get_base_addr_common(dev, addr); +} + static int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 1121d242ca6..0987bdd0b81 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -289,6 +289,7 @@ void eqos_flush_desc_generic(void *desc); void eqos_inval_buffer_generic(void *buf, size_t size); void eqos_flush_buffer_generic(void *buf, size_t size); int eqos_get_base_addr_dt(struct udevice *dev); +int eqos_get_base_addr_pci(struct udevice *dev); int eqos_null_ops(struct udevice *dev); void *eqos_get_driver_data(struct udevice *dev); diff --git a/drivers/net/dwc_eth_qos_intel.c b/drivers/net/dwc_eth_qos_intel.c new file mode 100644 index 000..a2c68257329 --- /dev/null +++ b/drivers/net/dwc_eth_qos_intel.c @@ -0,0 +1,449 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023-2024 DENX Software Engineering GmbH + * Philip Oberfichtner + * + * Based on linux v6.6.39, especially drivers/net/ethernet/stmicro/stmmac + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dwc_eth_qos.h" +#include "dwc_eth_qos_intel.h" + +static struct pci_device_id intel_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII2G5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5) }, + {} +}; + +static int pci_config(struct udevice *dev) +{ + u32 val; + + /* Try to enable I/O accesses and bus-mastering */ + dm_pci_read_config32(dev, PCI_COMMAND, &val); + val |= PCI_COMMAND_MEMORY | PCI_COMMA
Re: [PATCH v3 0/5] net: dwc_eth_qos: Add glue driver for Intel MAC
Hi Ramon, Any comments on this series? On Wed, Jul 17, 2024 at 02:29:01PM +0200, Philip Oberfichtner wrote: > This patch series implements the dwc_eth_qos glue driver for Intel SOCs. > Before doing that, a few general adaptions to the dwc_eth_qos.c main > driver are required. Most notably, the preparation for PCI based driver > instances, which do not necessarily use a device tree. > > This patch series depends on: "net: dwc_eth_qos: mdio: Implement clause 45": > https://patchwork.ozlabs.org/project/uboot/patch/20240507094237.168238-1-...@denx.de/ > > Changes in V3: > - Replace mfence() with mb() > - Clean-up eqos_get_base_addr() > - Several style fixes for dwc_eth_qos_intel > > Philip Oberfichtner (5): > x86: provide mb() macro > net: dwc_eth_qos: Fix header to be self-contained > net: dwc_eth_qos: Adapt probe() for PCI devices > net: dwc_eth_qos: Implement bind() for PCI devices > net: dwc_eth_qos: Add glue driver for Intel MAC > > arch/x86/cpu/mp_init.c | 10 +- > arch/x86/include/asm/cpu.h | 5 - > arch/x86/include/asm/io.h | 1 + > drivers/net/Kconfig| 7 + > drivers/net/Makefile | 1 + > drivers/net/dwc_eth_qos.c | 79 - > drivers/net/dwc_eth_qos.h | 8 +- > drivers/net/dwc_eth_qos_imx.c | 6 + > drivers/net/dwc_eth_qos_intel.c| 449 + > drivers/net/dwc_eth_qos_intel.h| 57 > drivers/net/dwc_eth_qos_qcom.c | 6 + > drivers/net/dwc_eth_qos_rockchip.c | 6 + > drivers/net/dwc_eth_qos_starfive.c | 6 + > drivers/net/dwc_eth_qos_stm32.c| 6 + > include/pci_ids.h | 9 + > 15 files changed, 637 insertions(+), 19 deletions(-) > create mode 100644 drivers/net/dwc_eth_qos_intel.c > create mode 100644 drivers/net/dwc_eth_qos_intel.h > > -- > 2.39.2 > -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de =
Re: [PATCH] pci: Enable dm_pci_map_bar() for 64-bit BARs
Hi, On Fri, Nov 24, 2023 at 10:15:20AM +, Moritz Fischer wrote: > Allow dm_pci_map_bar() usage on systems with CONFIG_PCI_SYS_64BIT. > > + /* > + * This assumes that dm_pciauto_setup_device() will allocate > + * a 64-bit address if CONFIG_SYS_PCI_64BIT is enabled and > + * the device advertises that it supports it. > + */ This patch is also useful if the previous bootstage, e.g. coreboot, allocated a 64-bit address. In fact I recently did something very similar (downstream), so Reviewed-by: Philip Oberfichtner -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de = > + if (IS_ENABLED(CONFIG_SYS_PCI_64BIT) && > + (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_64)) { > + dm_pci_read_config32(udev, bar + 4, &bar_response); > + pci_bus_addr |= (pci_addr_t)bar_response << 32; > + } > + > if (~((pci_addr_t)0) - pci_bus_addr < offset) > return NULL; > > diff --git a/include/pci.h b/include/pci.h > index 2f5eb30b83..0d1ac7b015 100644 > --- a/include/pci.h > +++ b/include/pci.h > @@ -1350,8 +1350,8 @@ pci_addr_t dm_pci_phys_to_bus(struct udevice *dev, > phys_addr_t addr, size_t len, > * > * Looks up a base address register and finds the physical memory address > * that corresponds to it. > - * Can be used for 32b BARs 0-5 on type 0 functions and for 32b BARs 0-1 on > - * type 1 functions. > + * Can be used for 32b/64b BARs 0-5 on type 0 functions and for 32b BARs 0-1 > + * on type 1 functions. > * Can also be used on type 0 functions that support Enhanced Allocation for > * 32b/64b BARs. Note that duplicate BEI entries are not supported. > * > -- > 2.43.0.rc1.413.gea7ed67945-goog >
[PATCH 1/1] i2c: Bugfix in i2c_get_chip_by_phandle()
The "i2cbcdev" sneaked in when implementing this function for the bootcounter use case. Obviously the intention was to use prop_name instead. Fixes: b483552773 (i2c: Implement i2c_get_chip_by_phandle()) Signed-off-by: Philip Oberfichtner --- drivers/i2c/i2c-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c index d0db25dcc0..3cbd4a81a5 100644 --- a/drivers/i2c/i2c-uclass.c +++ b/drivers/i2c/i2c-uclass.c @@ -428,7 +428,7 @@ int i2c_get_chip_by_phandle(const struct udevice *parent, const char *prop_name, goto err_exit; } - ret = dev_read_u32(parent, "i2cbcdev", &phandle); + ret = dev_read_u32(parent, prop_name, &phandle); if (ret) goto err_exit; -- 2.39.2
[PATCH 0/5] net: dwc_eth_qos: Add glue driver for Intel MAC
This patch series implements the dwc_eth_qos glue driver for Intel SOCs. Before doing that, a few general adaptions to the dwc_eth_qos.c main driver are required. Most notably, the preparation for PCI based driver instances, which do not necessarily use a device tree. This patch series depends on: "net: dwc_eth_qos: mdio: Implement clause 45": https://patchwork.ozlabs.org/project/uboot/patch/20240423085158.29246-1-...@denx.de/ Philip Oberfichtner (5): x86: provide mb() macro net: dwc_eth_qos: Fix header to be self-contained net: dwc_eth_qos: Adapt probe() for PCI devices net: dwc_eth_qos: Implement bind() for PCI devices net: dwc_eth_qos: Add glue driver for Intel MAC arch/x86/include/asm/io.h | 1 + drivers/net/Kconfig| 7 + drivers/net/Makefile | 1 + drivers/net/dwc_eth_qos.c | 44 ++- drivers/net/dwc_eth_qos.h | 9 +- drivers/net/dwc_eth_qos_imx.c | 1 + drivers/net/dwc_eth_qos_intel.c| 446 + drivers/net/dwc_eth_qos_intel.h| 58 drivers/net/dwc_eth_qos_qcom.c | 1 + drivers/net/dwc_eth_qos_rockchip.c | 1 + drivers/net/dwc_eth_qos_starfive.c | 1 + drivers/net/dwc_eth_qos_stm32.c| 1 + include/pci_ids.h | 9 + 13 files changed, 576 insertions(+), 4 deletions(-) create mode 100644 drivers/net/dwc_eth_qos_intel.c create mode 100644 drivers/net/dwc_eth_qos_intel.h -- 2.39.2
[PATCH 1/5] x86: provide mb() macro
Implement memory barrier using mfence. Linux does it equivalently [1]. "The MFENCE instruction establishes a memory fence for both loads and stores" [2]. [1] linux/arch/x86/include/asm/barrier.h [2] Intel® 64 and IA-32 Architectures Software Developer’s Manual Signed-off-by: Philip Oberfichtner --- arch/x86/include/asm/io.h | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/include/asm/io.h b/arch/x86/include/asm/io.h index 5efb2e1b21..936ad6f588 100644 --- a/arch/x86/include/asm/io.h +++ b/arch/x86/include/asm/io.h @@ -244,6 +244,7 @@ static inline void sync(void) * have some advantages to use them instead of the simple one here. */ #define dmb() __asm__ __volatile__ ("" : : : "memory") +#define mb() __asm__ __volatile__ ("mfence" : : : "memory") #define __iormb() dmb() #define __iowmb() dmb() -- 2.39.2
[PATCH 2/5] net: dwc_eth_qos: Fix header to be self-contained
Before this commit, usage of this header relied on a specific include order. Fix it by including all dependencies. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.h | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index d6ed3830be..c6e1f76caf 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -3,8 +3,11 @@ * Copyright 2022 NXP */ -#include +#include +#include #include +#include +#include /* Core registers */ -- 2.39.2
[PATCH 3/5] net: dwc_eth_qos: Adapt probe() for PCI devices
PCI devices do not necessarily use a device tree. In that case, the driver currently fails to find eqos->config and eqos->regs. This commit factors out the respective functionality. Device tree usage remains default, but board specific implementations will be possible as well. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.c | 28 +--- drivers/net/dwc_eth_qos.h | 3 +++ drivers/net/dwc_eth_qos_imx.c | 1 + drivers/net/dwc_eth_qos_qcom.c | 1 + drivers/net/dwc_eth_qos_rockchip.c | 1 + drivers/net/dwc_eth_qos_starfive.c | 1 + drivers/net/dwc_eth_qos_stm32.c| 1 + 7 files changed, 33 insertions(+), 3 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 4dd532b671..36412d1c83 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1376,6 +1376,21 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +/* + * Get driver data based on the device tree. Boards not using a device tree can + * overwrite this function. + */ +__weak void *eqos_get_driver_data(struct udevice *dev) +{ + return (void *)dev_get_driver_data(dev); +} + +/* Function to get base address, useable for all boards having a device tree. */ +fdt_addr_t eqos_get_base_addr_dt(struct udevice *dev) +{ + return dev_read_addr(dev); +} + static int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1384,13 +1399,19 @@ static int eqos_probe(struct udevice *dev) debug("%s(dev=%p):\n", __func__, dev); eqos->dev = dev; - eqos->config = (void *)dev_get_driver_data(dev); - eqos->regs = dev_read_addr(dev); + eqos->config = eqos_get_driver_data(dev); + if (!eqos->config) { + pr_err("Failed to get driver data.\n"); + return -ENODEV; + } + + eqos->regs = eqos->config->ops->eqos_get_base_addr(dev); if (eqos->regs == FDT_ADDR_T_NONE) { - pr_err("dev_read_addr() failed\n"); + pr_err("Failed to get device address.\n"); return -ENODEV; } + eqos->mac_regs = (void *)(eqos->regs + EQOS_MAC_REGS_BASE); eqos->mtl_regs = (void *)(eqos->regs + EQOS_MTL_REGS_BASE); eqos->dma_regs = (void *)(eqos->regs + EQOS_DMA_REGS_BASE); @@ -1497,6 +1518,7 @@ static struct eqos_ops eqos_tegra186_ops = { .eqos_flush_buffer = eqos_flush_buffer_tegra186, .eqos_probe_resources = eqos_probe_resources_tegra186, .eqos_remove_resources = eqos_remove_resources_tegra186, + .eqos_get_base_addr = eqos_get_base_addr_dt, .eqos_stop_resets = eqos_stop_resets_tegra186, .eqos_start_resets = eqos_start_resets_tegra186, .eqos_stop_clks = eqos_stop_clks_tegra186, diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index c6e1f76caf..7984582c49 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -239,6 +239,7 @@ struct eqos_ops { void (*eqos_flush_buffer)(void *buf, size_t size); int (*eqos_probe_resources)(struct udevice *dev); int (*eqos_remove_resources)(struct udevice *dev); + fdt_addr_t (*eqos_get_base_addr)(struct udevice *dev); int (*eqos_stop_resets)(struct udevice *dev); int (*eqos_start_resets)(struct udevice *dev); int (*eqos_stop_clks)(struct udevice *dev); @@ -290,6 +291,8 @@ void eqos_flush_desc_generic(void *desc); void eqos_inval_buffer_generic(void *buf, size_t size); void eqos_flush_buffer_generic(void *buf, size_t size); int eqos_null_ops(struct udevice *dev); +void *eqos_get_driver_data(struct udevice *dev); +fdt_addr_t eqos_get_base_addr_dt(struct udevice *dev); extern struct eqos_config eqos_imx_config; extern struct eqos_config eqos_rockchip_config; diff --git a/drivers/net/dwc_eth_qos_imx.c b/drivers/net/dwc_eth_qos_imx.c index 9c4e390441..21dbf45a22 100644 --- a/drivers/net/dwc_eth_qos_imx.c +++ b/drivers/net/dwc_eth_qos_imx.c @@ -218,6 +218,7 @@ static struct eqos_ops eqos_imx_ops = { .eqos_flush_buffer = eqos_flush_buffer_generic, .eqos_probe_resources = eqos_probe_resources_imx, .eqos_remove_resources = eqos_remove_resources_imx, + .eqos_get_base_addr = eqos_get_base_addr_dt, .eqos_stop_resets = eqos_null_ops, .eqos_start_resets = eqos_null_ops, .eqos_stop_clks = eqos_stop_clks_imx, diff --git a/drivers/net/dwc_eth_qos_qcom.c b/drivers/net/dwc_eth_qos_qcom.c index 8178138fc6..78213e5ca0 100644 --- a/drivers/net/dwc_eth_qos_qcom.c +++ b/drivers/net/dwc_eth_qos_qcom.c @@ -589,6 +589,7 @@ static struct eqos_ops eqos_qcom_ops = { .eqos_flush_buffer = eqos_flush_buffer_generic, .eqos_probe_resources = eqos_probe_resources_qcom, .eqos_remove_resources = eqos_remove_resources_qcom,
[PATCH 4/5] net: dwc_eth_qos: Implement bind() for PCI devices
PCI devices do not necessarily use a device tree. Implement a bind() function to assign unique device names in that case. Signed-off-by: Philip Oberfichtner --- drivers/net/dwc_eth_qos.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 36412d1c83..fdd64f074a 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1376,6 +1376,21 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) return 0; } +static int eqos_bind(struct udevice *dev) +{ + static int dev_num; + const size_t name_sz = 16; + char name[name_sz]; + + /* Device name defaults to DT node name. */ + if (ofnode_valid(dev_ofnode(dev))) + return 0; + + /* Assign unique names in case there is no DT node. */ + snprintf(name, name_sz, "eth_eqos#%d", dev_num++); + return device_set_name(dev, name); +} + /* * Get driver data based on the device tree. Boards not using a device tree can * overwrite this function. @@ -1597,6 +1612,7 @@ U_BOOT_DRIVER(eth_eqos) = { .name = "eth_eqos", .id = UCLASS_ETH, .of_match = of_match_ptr(eqos_ids), + .bind = eqos_bind, .probe = eqos_probe, .remove = eqos_remove, .ops = &eqos_ops, -- 2.39.2
[PATCH 5/5] net: dwc_eth_qos: Add glue driver for Intel MAC
Add dwc_eth_qos glue driver for the Intel Elkhart-Lake SOC. Signed-off-by: Philip Oberfichtner --- drivers/net/Kconfig | 7 + drivers/net/Makefile| 1 + drivers/net/dwc_eth_qos.h | 1 + drivers/net/dwc_eth_qos_intel.c | 446 drivers/net/dwc_eth_qos_intel.h | 58 + include/pci_ids.h | 9 + 6 files changed, 522 insertions(+) create mode 100644 drivers/net/dwc_eth_qos_intel.c create mode 100644 drivers/net/dwc_eth_qos_intel.h diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index b2d7b49976..b23fe55792 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -225,6 +225,13 @@ config DWC_ETH_QOS_IMX The Synopsys Designware Ethernet QOS IP block with the specific configuration used in IMX soc. +config DWC_ETH_QOS_INTEL + bool "Synopsys DWC Ethernet QOS device support for Intel" + depends on DWC_ETH_QOS + help + The Synopsys Designware Ethernet QOS IP block with the specific + configuration used in the Intel Elkhart-Lake soc. + config DWC_ETH_QOS_ROCKCHIP bool "Synopsys DWC Ethernet QOS device support for Rockchip SoCs" depends on DWC_ETH_QOS diff --git a/drivers/net/Makefile b/drivers/net/Makefile index dc3404519d..bd62c65dd5 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o +obj-$(CONFIG_DWC_ETH_QOS_INTEL) += dwc_eth_qos_intel.o obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h index 7984582c49..f8ce7a41a2 100644 --- a/drivers/net/dwc_eth_qos.h +++ b/drivers/net/dwc_eth_qos.h @@ -295,6 +295,7 @@ void *eqos_get_driver_data(struct udevice *dev); fdt_addr_t eqos_get_base_addr_dt(struct udevice *dev); extern struct eqos_config eqos_imx_config; +extern struct eqos_config eqos_intel_config; extern struct eqos_config eqos_rockchip_config; extern struct eqos_config eqos_qcom_config; extern struct eqos_config eqos_stm32mp13_config; diff --git a/drivers/net/dwc_eth_qos_intel.c b/drivers/net/dwc_eth_qos_intel.c new file mode 100644 index 00..39952ef52a --- /dev/null +++ b/drivers/net/dwc_eth_qos_intel.c @@ -0,0 +1,446 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 DENX Software Engineering GmbH + * Philip Oberfichtner + * + * Based on linux v6.1.38, especially drivers/net/ethernet/stmicro/stmmac + */ + +#include +#include +#include +#include +#include +#include + +#include "dwc_eth_qos.h" +#include "dwc_eth_qos_intel.h" + +static struct pci_device_id intel_pci_ids[] = { + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII1) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_SGMII2G5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE0_SGMII2G5) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_RGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII1G) }, + { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_EHL_PSE1_SGMII2G5) }, + {} +}; + +static int __pci_config(struct udevice *dev) +{ + u32 val; + + /* Try to enable I/O accesses and bus-mastering */ + dm_pci_read_config32(dev, PCI_COMMAND, &val); + val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + dm_pci_write_config32(dev, PCI_COMMAND, val); + + /* Make sure it worked */ + dm_pci_read_config32(dev, PCI_COMMAND, &val); + if (!(val & PCI_COMMAND_MEMORY)) { + pr_err("%s: Can't enable I/O memory\n", __func__); + return -ENOSPC; + } + if (!(val & PCI_COMMAND_MASTER)) { + pr_err("%s: Can't enable bus-mastering\n", __func__); + return -EPERM; + } + + return 0; +} + +static void __limit_fifo_size(struct udevice *dev) +{ + /* +* As described in Intel Erratum EHL22, Document Number: 636674-2.1, +* the PSE GbE Controllers advertise a wrong RX and TX fifo size. +* Software should limit this value to 64KB. +*/ + struct eqos_priv *eqos = dev_get_priv(dev); + + eqos->tx_fifo_sz = 0x8000; + eqos->rx_fifo_sz = 0x8000; +} + +static int __serdes_status_poll(struct udevice *dev, + unsigned char
[PATCH v2 1/1] net: dwc_eth_qos: mdio: Implement clause 45
Bevor this commit, only clause 22 access was possible. After this commit, clause 45 direct access will available as well. Note that there is a slight change of behavior: Before this commit, the C45E bit was set to whatever value was left in the register from the previous access. After this commit, we adopt the common practice of discerning C45 from C22 using the devad argument. Signed-off-by: Philip Oberfichtner --- Notes: Attention: There is a slight change of behavior introduced by this commit (see commit message). Please test and review if this works for everybody. My implementation is tested on an Intel Elkhart lake SOC, patch submitted here: https://patchwork.ozlabs.org/project/uboot/list/?series=405358 Changes in V2: - Use FIELD_PREP() instead of manual '<<' shifting - Fix whitespace errors drivers/net/dwc_eth_qos.c | 66 ++- drivers/net/dwc_eth_qos.h | 9 +++--- 2 files changed, 49 insertions(+), 26 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index cb329e0cef..6bc9b8fca4 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -51,6 +51,7 @@ #include #include #endif +#include #include #include @@ -184,6 +185,25 @@ static int eqos_mdio_wait_idle(struct eqos_priv *eqos) 100, true); } +/* Bitmask common for mdio_read and mdio_write */ +#define EQOS_MDIO_BITFIELD(pa, rda, cr) \ + FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_PA_MASK, pa) | \ + FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_RDA_MASK, rda) | \ + FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_CR_MASK, cr) | \ + EQOS_MAC_MDIO_ADDRESS_GB + +static u32 eqos_mdio_bitfield(struct eqos_priv *eqos, int addr, int devad, int reg) +{ + int cr = eqos->config->config_mac_mdio; + bool c22 = devad == MDIO_DEVAD_NONE ? true : false; + + if (c22) + return EQOS_MDIO_BITFIELD(addr, reg, cr); + else + return EQOS_MDIO_BITFIELD(addr, devad, cr) | + EQOS_MAC_MDIO_ADDRESS_C45E; +} + static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad, int mdio_reg) { @@ -201,15 +221,17 @@ static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad, } val = readl(&eqos->mac_regs->mdio_address); - val &= EQOS_MAC_MDIO_ADDRESS_SKAP | - EQOS_MAC_MDIO_ADDRESS_C45E; - val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) | - (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) | - (eqos->config->config_mac_mdio << -EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) | - (EQOS_MAC_MDIO_ADDRESS_GOC_READ << -EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) | - EQOS_MAC_MDIO_ADDRESS_GB; + val &= EQOS_MAC_MDIO_ADDRESS_SKAP; + + val |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) | + FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_GOC_MASK, + EQOS_MAC_MDIO_ADDRESS_GOC_READ); + + if (val & EQOS_MAC_MDIO_ADDRESS_C45E) { + writel(FIELD_PREP(EQOS_MAC_MDIO_DATA_RA_MASK, mdio_reg), + &eqos->mac_regs->mdio_data); + } + writel(val, &eqos->mac_regs->mdio_address); udelay(eqos->config->mdio_wait); @@ -232,7 +254,8 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, int mdio_reg, u16 mdio_val) { struct eqos_priv *eqos = bus->priv; - u32 val; + u32 v_addr; + u32 v_data; int ret; debug("%s(dev=%p, addr=%x, reg=%d, val=%x):\n", __func__, eqos->dev, @@ -244,20 +267,19 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, return ret; } - writel(mdio_val, &eqos->mac_regs->mdio_data); + v_addr = readl(&eqos->mac_regs->mdio_address); + v_addr &= EQOS_MAC_MDIO_ADDRESS_SKAP; - val = readl(&eqos->mac_regs->mdio_address); - val &= EQOS_MAC_MDIO_ADDRESS_SKAP | - EQOS_MAC_MDIO_ADDRESS_C45E; - val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) | - (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) | - (eqos->config->config_mac_mdio << -EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) | - (EQOS_MAC_MDIO_ADDRESS_GOC_WRITE << -EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) | - EQOS_MAC_MDIO_ADDRESS_GB; - writel(val, &eqos->mac_regs->mdio_address); + v_addr |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) | + FIELD_PREP(EQOS_MAC_MDIO_ADDRESS_GOC_MASK, + EQOS_MAC_MDIO_ADDRESS_GO
[PATCH 1/1] usb: Assimilate usb_get_descriptor() to linux
Before this commit, usb_get_descriptor() failed for some flakey USB devices. We hereby adopt the more robust linux implementation [1]. Signed-off-by: Philip Oberfichtner [1] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/usb/core/message.c?h=v6.9#n781 --- common/usb.c | 37 ++--- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/common/usb.c b/common/usb.c index 84b10f5c7d..f5b21c883f 100644 --- a/common/usb.c +++ b/common/usb.c @@ -214,8 +214,9 @@ int usb_int_msg(struct usb_device *dev, unsigned long pipe, * clear keyboards LEDs). For data transfers, (storage transfers) we don't * allow control messages with 0 timeout, by previousely resetting the flag * asynch_allowed (usb_disable_asynch(1)). - * returns the transferred length if OK or -1 if error. The transferred length - * and the current status are stored in the dev->act_len and dev->status. + * returns the transferred length if OK, otherwise a negative error code. The + * transferred length and the current status are stored in the dev->act_len and + * dev->status. */ int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, @@ -257,11 +258,14 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe, break; mdelay(1); } + + if (timeout == 0) + return -ETIMEDOUT; + if (dev->status) return -1; return dev->act_len; - } /*--- @@ -562,10 +566,29 @@ int usb_clear_halt(struct usb_device *dev, int pipe) static int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char index, void *buf, int size) { - return usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), - USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, - (type << 8) + index, 0, buf, size, - USB_CNTL_TIMEOUT); + int i; + int result; + + if (size <= 0) /* No point in asking for no data */ + return -EINVAL; + + memset(buf, 0, size); /* Make sure we parse really received data */ + + for (i = 0; i < 3; ++i) { + /* retry on length 0 or error; some devices are flakey */ + result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), +USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, +(type << 8) + index, 0, buf, size, +USB_CNTL_TIMEOUT); + if (result <= 0 && result != -ETIMEDOUT) + continue; + if (result > 1 && ((u8 *)buf)[1] != type) { + result = -ENODATA; + continue; + } + break; + } + return result; } /** -- 2.39.2
[RFC PATCH 1/1] net: dwc_eth_qos: mdio: Implement clause 45
Bevor this commit, only clause 22 access was possible. After this commit, clause 45 direct access will available as well. Note that there is a slight change of behavior: Before this commit, the C45E bit was set to whatever value was left in the register from the previous access. After this commit, we adopt the common practice of discerning C45 from C22 using the devad argument. Signed-off-by: Philip Oberfichtner --- Notes: This patch is labeled RFC as there is a slight change of behavior (see commit message). I'm not sure in fact if this solution works for everybody - this is up for discussion! My implementation is tested on an Intel Elkhart lake SOC. Driver code for dwc_eth_qos_intel coming soon in a separate patch series. drivers/net/dwc_eth_qos.c | 66 ++- drivers/net/dwc_eth_qos.h | 1 + 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 86d989e244..64a9bff6bb 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -162,6 +162,25 @@ static int eqos_mdio_wait_idle(struct eqos_priv *eqos) 100, true); } +/* Bitmask common for mdio_read and mdio_write */ +#define EQOS_MDIO_BITFIELD(pa, rda, cr) \ + (pa << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) | \ + (rda << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) | \ + (cr << EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) | \ +EQOS_MAC_MDIO_ADDRESS_GB + +static u32 eqos_mdio_bitfield(struct eqos_priv *eqos, int addr, int devad, int reg) +{ + int cr = eqos->config->config_mac_mdio; + bool c22 = devad == MDIO_DEVAD_NONE ? true : false; + + if (c22) + return EQOS_MDIO_BITFIELD(addr, reg, cr); + else + return EQOS_MDIO_BITFIELD(addr, devad, cr) | + EQOS_MAC_MDIO_ADDRESS_C45E; +} + static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad, int mdio_reg) { @@ -179,15 +198,17 @@ static int eqos_mdio_read(struct mii_dev *bus, int mdio_addr, int mdio_devad, } val = readl(&eqos->mac_regs->mdio_address); - val &= EQOS_MAC_MDIO_ADDRESS_SKAP | - EQOS_MAC_MDIO_ADDRESS_C45E; - val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) | - (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) | - (eqos->config->config_mac_mdio << -EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) | - (EQOS_MAC_MDIO_ADDRESS_GOC_READ << -EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) | - EQOS_MAC_MDIO_ADDRESS_GB; + val &= EQOS_MAC_MDIO_ADDRESS_SKAP; + + val |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) | + EQOS_MAC_MDIO_ADDRESS_GOC_READ << + EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT; + + if (val & EQOS_MAC_MDIO_ADDRESS_C45E) { + writel(mdio_reg << EQOS_MAC_MDIO_DATA_RA_SHIFT, + &eqos->mac_regs->mdio_data); + } + writel(val, &eqos->mac_regs->mdio_address); udelay(eqos->config->mdio_wait); @@ -210,7 +231,8 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, int mdio_reg, u16 mdio_val) { struct eqos_priv *eqos = bus->priv; - u32 val; + u32 v_addr; + u32 v_data; int ret; debug("%s(dev=%p, addr=%x, reg=%d, val=%x):\n", __func__, eqos->dev, @@ -222,20 +244,20 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, return ret; } - writel(mdio_val, &eqos->mac_regs->mdio_data); + v_addr = readl(&eqos->mac_regs->mdio_address); + v_addr &= EQOS_MAC_MDIO_ADDRESS_SKAP; + + v_addr |= eqos_mdio_bitfield(eqos, mdio_addr, mdio_devad, mdio_reg) | + EQOS_MAC_MDIO_ADDRESS_GOC_WRITE << + EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT; + + v_data = mdio_val; + if (v_addr & EQOS_MAC_MDIO_ADDRESS_C45E) + v_data |= mdio_reg << EQOS_MAC_MDIO_DATA_RA_SHIFT; - val = readl(&eqos->mac_regs->mdio_address); - val &= EQOS_MAC_MDIO_ADDRESS_SKAP | - EQOS_MAC_MDIO_ADDRESS_C45E; - val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) | - (mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) | - (eqos->config->config_mac_mdio << -EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) | - (EQOS_MAC_MDIO_ADDRESS_GOC_WRITE << -EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) | - EQOS_MAC_MDIO_ADDRESS_GB; - writel(val, &eqos->mac_regs->mdio_address); + writel(v_data, &eqos->mac_regs->mdio_data); +
EFI payload in 64 bit mode?
Hi, I'm wondering if it is currently possible to have U-Boot run in 64-bit mode as EFI payload. TARGET_EFI_APP64 selects X86_64 to achieve this. TARGET_EFI_PAYLOAD does currently always switch 32-bit mode. Any hints what would have to be done to get it to run in 64-bit mode? Thanks in advance, Philip -- = DENX Software Engineering GmbH,Managing Director: Erika Unter HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-22 Fax: +49-8142-66989-80 Email: p...@denx.de =
[PATCH 0/4] Deduplicate dhelectronics board files
This series unifies common mac address code for imx6, imx8 and stm32 based boards by DH. It is thought of as a starting point for more deduplication in the future. Philip Oberfichtner (4): board: dhelectronics: Implement common mac address functions ARM: imx6: DH: Use common mac address functions ARM: imx8: DH: Use common mac address functions ARM: stm32: DH: Use common mac address functions board/dhelectronics/common/Makefile | 10 ++ board/dhelectronics/common/dh_common.c| 64 + board/dhelectronics/common/dh_common.h| 28 board/dhelectronics/common/dh_imx.c | 24 board/dhelectronics/common/dh_imx.h | 12 ++ board/dhelectronics/dh_imx6/dh_imx6.c | 47 ++- .../dh_imx8mp/imx8mp_dhcom_pdk2.c | 121 +++--- board/dhelectronics/dh_stm32mp1/board.c | 104 +++ 8 files changed, 247 insertions(+), 163 deletions(-) create mode 100644 board/dhelectronics/common/Makefile create mode 100644 board/dhelectronics/common/dh_common.c create mode 100644 board/dhelectronics/common/dh_common.h create mode 100644 board/dhelectronics/common/dh_imx.c create mode 100644 board/dhelectronics/common/dh_imx.h -- 2.35.3
[PATCH 1/4] board: dhelectronics: Implement common mac address functions
This is a starting point for unifying duplicate code in the DH board files. The functions for setting up the mac address are very similar for the i.MX6, i.MX8 and stm32mp1 based boards. All pre-existing implementations follow the same logic: (1) Check if ethaddr is already set in the environment (2) If not, try to get it from a board specific location (e.g. fuse) (3) If not, try to get it from eeprom After this commit, (1) and (3) are implemented as common functions, ready to be used by board specific files. Furthermore there is an implementation of (2) for imx based boards. Signed-off-by: Philip Oberfichtner --- board/dhelectronics/common/Makefile| 10 board/dhelectronics/common/dh_common.c | 64 ++ board/dhelectronics/common/dh_common.h | 28 +++ board/dhelectronics/common/dh_imx.c| 24 ++ board/dhelectronics/common/dh_imx.h| 12 + 5 files changed, 138 insertions(+) create mode 100644 board/dhelectronics/common/Makefile create mode 100644 board/dhelectronics/common/dh_common.c create mode 100644 board/dhelectronics/common/dh_common.h create mode 100644 board/dhelectronics/common/dh_imx.c create mode 100644 board/dhelectronics/common/dh_imx.h diff --git a/board/dhelectronics/common/Makefile b/board/dhelectronics/common/Makefile new file mode 100644 index 00..a472ea8d51 --- /dev/null +++ b/board/dhelectronics/common/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2022 DENX Software Engineering GmbH, Philip Oberfichtner +# + +obj-y += dh_common.o + +ifneq (,$(CONFIG_ARCH_MX6)$(CONFIG_ARCH_IMX8M)) +obj-y += dh_imx.o +endif diff --git a/board/dhelectronics/common/dh_common.c b/board/dhelectronics/common/dh_common.c new file mode 100644 index 00..4f089d91ce --- /dev/null +++ b/board/dhelectronics/common/dh_common.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 Marek Vasut + * Copyright 2022 DENX Software Engineering GmbH, Philip Oberfichtner + */ + +#include +#include +#include +#include + +#include "dh_common.h" + +bool dh_mac_is_in_env(const char *env) +{ + unsigned char enetaddr[6]; + + return eth_env_get_enetaddr(env, enetaddr); +} + +int dh_get_mac_from_eeprom(unsigned char *enetaddr, const char *alias) +{ + struct udevice *dev; + int ret, offset; + + offset = fdt_path_offset(gd->fdt_blob, alias); + if (offset < 0) { + printf("%s: Path offset for %s not found! Error %d\n", __func__, alias, offset); + return offset; + } + + ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, offset, &dev); + if (ret) { + printf("%s: Cannot find EEPROM! ret = %d\n", __func__, ret); + return ret; + } + + ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); + if (ret) { + printf("%s: Error reading EEPROM! ret = %d\n", __func__, ret); + return ret; + } + + if (!is_valid_ethaddr(enetaddr)) { + printf("%s: Address read from EEPROM is invalid!\n", __func__); + return -EINVAL; + } + + return 0; +} + +__weak int dh_setup_mac_address(void) +{ + unsigned char enetaddr[6]; + + if (dh_mac_is_in_env("ethaddr")) + return 0; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + return eth_env_set_enetaddr("ethaddr", enetaddr); + + printf("%s: Unable to set mac address!\n", __func__); + return -ENXIO; +} diff --git a/board/dhelectronics/common/dh_common.h b/board/dhelectronics/common/dh_common.h new file mode 100644 index 00..2b24637d96 --- /dev/null +++ b/board/dhelectronics/common/dh_common.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * Copyright 2022 DENX Software Engineering GmbH, Philip Oberfichtner + */ + +/* + * dh_mac_is_in_env - Check if MAC address is already set + * + * @env: name of environment variable + * Return: true if MAC is set, false otherwise + */ +bool dh_mac_is_in_env(const char *env); + +/* + * dh_get_mac_from_eeprom - Get MAC address from eeprom and write it to enetaddr + * + * @enetaddr: buffer where address is to be stored + * @alias: alias for EEPROM device tree node + * Return: 0 if OK, other value on error + */ +int dh_get_mac_from_eeprom(unsigned char *enetaddr, const char *alias); + +/* + * dh_setup_mac_address - Try to get MAC address from various locations and write it to env + * + * Return: 0 if OK, other value on error + */ +int dh_setup_mac_address(void); diff --git a/board/dhelectronics/common/dh_imx.c b/board/dhelectronics/common/dh_imx.c new file mode 100644 index 00..7f451bad59 --- /dev/null +++ b/board/dhelectronics/common/dh_imx.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 Marek Vasut + * Copyrig
[PATCH 2/4] ARM: imx6: DH: Use common mac address functions
To reduce code duplication, let the imx6 based DH boards use the common code for setting up their mac addresses. Signed-off-by: Philip Oberfichtner --- board/dhelectronics/dh_imx6/dh_imx6.c | 47 --- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c index e8aba83e1a..cd153c2c8d 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6.c +++ b/board/dhelectronics/dh_imx6/dh_imx6.c @@ -36,6 +36,9 @@ #include #include +#include "../common/dh_common.h" +#include "../common/dh_imx.h" + DECLARE_GLOBAL_DATA_PTR; int dram_init(void) @@ -82,46 +85,24 @@ int board_usb_phy_mode(int port) } #endif -static int setup_dhcom_mac_from_fuse(void) +int dh_setup_mac_address(void) { - struct udevice *dev; - ofnode eeprom; unsigned char enetaddr[6]; - int ret; - ret = eth_env_get_enetaddr("ethaddr", enetaddr); - if (ret)/* ethaddr is already set */ + if (dh_mac_is_in_env("ethaddr")) return 0; - imx_get_mac_from_fuse(0, enetaddr); - - if (is_valid_ethaddr(enetaddr)) { - eth_env_set_enetaddr("ethaddr", enetaddr); - return 0; - } - - eeprom = ofnode_get_aliases_node("eeprom0"); - if (!ofnode_valid(eeprom)) { - printf("Can't find eeprom0 alias!\n"); - return -ENODEV; - } + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto out; - ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev); - if (ret) { - printf("Cannot find EEPROM!\n"); - return ret; - } + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto out; - ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); - if (ret) { - printf("Error reading configuration EEPROM!\n"); - return ret; - } + printf("%s: Unable to get mac address!\n", __func__); + return -ENXIO; - if (is_valid_ethaddr(enetaddr)) - eth_env_set_enetaddr("ethaddr", enetaddr); - - return 0; +out: + return eth_env_set_enetaddr("ethaddr", enetaddr); } int board_early_init_f(void) @@ -188,7 +169,7 @@ int board_late_init(void) u32 hw_code; char buf[16]; - setup_dhcom_mac_from_fuse(); + dh_setup_mac_address(); hw_code = board_get_hwcode(); -- 2.35.3
[PATCH 3/4] ARM: imx8: DH: Use common mac address functions
To reduce code duplication, let the imx8 based DH boards use the common code for setting up their mac addresses. Signed-off-by: Philip Oberfichtner --- .../dh_imx8mp/imx8mp_dhcom_pdk2.c | 121 +++--- 1 file changed, 48 insertions(+), 73 deletions(-) diff --git a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c index 8676c44d0d..6f06daf86f 100644 --- a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c +++ b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c @@ -16,6 +16,8 @@ #include #include "lpddr4_timing.h" +#include "../common/dh_common.h" +#include "../common/dh_imx.h" DECLARE_GLOBAL_DATA_PTR; @@ -75,95 +77,68 @@ static void setup_fec(void) set_clk_enet(ENET_125MHZ); } -static int setup_mac_address_from_eeprom(char *alias, char *env, bool odd) +static int dh_imx8_setup_ethaddr(void) { unsigned char enetaddr[6]; - struct udevice *dev; - int ret, offset; - - offset = fdt_path_offset(gd->fdt_blob, alias); - if (offset < 0) { - printf("%s: No eeprom0 path offset\n", __func__); - return offset; - } - - ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, offset, &dev); - if (ret) { - printf("Cannot find EEPROM!\n"); - return ret; - } - - ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); - if (ret) { - printf("Error reading configuration EEPROM!\n"); - return ret; - } + + if (dh_mac_is_in_env("ethaddr")) + return 0; + + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto out; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto out; + + return -ENXIO; + +out: + return eth_env_set_enetaddr("ethaddr", enetaddr); +} + +static int dh_imx8_setup_eth1addr(void) +{ + unsigned char enetaddr[6]; + + if (dh_mac_is_in_env("eth1addr")) + return 0; + + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto increment_out; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom1")) + goto out; /* * Populate second ethernet MAC from first ethernet EEPROM with MAC * address LSByte incremented by 1. This is only used on SoMs without * second ethernet EEPROM, i.e. early prototypes. */ - if (odd) - enetaddr[5]++; + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto increment_out; - eth_env_set_enetaddr(env, enetaddr); + return -ENXIO; - return 0; +increment_out: + enetaddr[5]++; + +out: + return eth_env_set_enetaddr("eth1addr", enetaddr); } -static void setup_mac_address(void) +int dh_setup_mac_address(void) { - unsigned char enetaddr[6]; - bool skip_eth0 = false; - bool skip_eth1 = false; int ret; - ret = eth_env_get_enetaddr("ethaddr", enetaddr); - if (ret)/* ethaddr is already set */ - skip_eth0 = true; - - ret = eth_env_get_enetaddr("eth1addr", enetaddr); - if (ret)/* eth1addr is already set */ - skip_eth1 = true; + ret = dh_imx8_setup_ethaddr(); + if (ret) + printf("%s: Unable to setup ethaddr! ret = %d\n", __func__, ret); - /* Both MAC addresses are already set in U-Boot environment. */ - if (skip_eth0 && skip_eth1) - return; + ret = dh_imx8_setup_eth1addr(); + if (ret) + printf("%s: Unable to setup eth1addr! ret = %d\n", __func__, ret); - /* -* If IIM fuses contain valid MAC address, use it. -* The IIM MAC address fuses are NOT programmed by default. -*/ - imx_get_mac_from_fuse(0, enetaddr); - if (is_valid_ethaddr(enetaddr)) { - if (!skip_eth0) - eth_env_set_enetaddr("ethaddr", enetaddr); - /* -* The LSbit of MAC address in fuses is always 0, use the -* next consecutive MAC address for the second ethernet. -*/ - enetaddr[5]++; - if (!skip_eth1) - eth_env_set_enetaddr("eth1addr", enetaddr); - return; - } - - /* Use on-SoM EEPROMs with pre-programmed MAC address. */ - if (!skip_eth0) { - /* We cannot do much more if this returns -ve . */ - setup_mac_address_from_eeprom("eeprom0", "ethaddr", false); - } - - if (!skip_eth1) { - ret = setup_mac_address_from_eeprom("eeprom1", "eth1addr", -
[PATCH 4/4] ARM: stm32: DH: Use common mac address functions
To reduce code duplication, let the stm32 based DH boards use the common code for setting up their mac addresses. Signed-off-by: Philip Oberfichtner --- board/dhelectronics/dh_stm32mp1/board.c | 104 +++- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index d407f0bf59..5d83d9cd3f 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -43,6 +43,7 @@ #include #include #include +#include "../common/dh_common.h" #include "../../st/common/stpmic1.h" /* SYSCFG registers */ @@ -90,35 +91,18 @@ DECLARE_GLOBAL_DATA_PTR; #define KS_CIDER 0xC0 #define CIDER_ID 0x8870 -int setup_mac_address(void) -{ - unsigned char enetaddr[6]; - bool skip_eth0 = false; - bool skip_eth1 = false; - struct udevice *dev; - int off, ret; - ret = eth_env_get_enetaddr("ethaddr", enetaddr); - if (ret)/* ethaddr is already set */ - skip_eth0 = true; +static bool dh_stm32_mac_is_in_ks8851(void) +{ + int off; + u32 reg, cider, ccr; off = fdt_path_offset(gd->fdt_blob, "ethernet1"); - if (off < 0) { - /* ethernet1 is not present in the system */ - skip_eth1 = true; - goto out_set_ethaddr; - } + if (off < 0) + return false; - ret = eth_env_get_enetaddr("eth1addr", enetaddr); - if (ret) { - /* eth1addr is already set */ - skip_eth1 = true; - goto out_set_ethaddr; - } - - ret = fdt_node_check_compatible(gd->fdt_blob, off, "micrel,ks8851-mll"); - if (ret) - goto out_set_ethaddr; + if (fdt_node_check_compatible(gd->fdt_blob, off, "micrel,ks8851-mll")) + return false; /* * KS8851 with EEPROM may use custom MAC from EEPROM, read @@ -126,56 +110,62 @@ int setup_mac_address(void) * is present. If EEPROM is present, it must contain valid * MAC address. */ - u32 reg, cider, ccr; reg = fdt_get_base_address(gd->fdt_blob, off); if (!reg) - goto out_set_ethaddr; + return false; writew(KS_BE0 | KS_BE1 | KS_CIDER, reg + 2); cider = readw(reg); - if ((cider & 0xfff0) != CIDER_ID) { - skip_eth1 = true; - goto out_set_ethaddr; - } + if ((cider & 0xfff0) != CIDER_ID) + return true; writew(KS_BE0 | KS_BE1 | KS_CCR, reg + 2); ccr = readw(reg); - if (ccr & KS_CCR_EEPROM) { - skip_eth1 = true; - goto out_set_ethaddr; - } + if (ccr & KS_CCR_EEPROM) + return true; + + return false; +} + +static int dh_stm32_setup_ethaddr(void) +{ + unsigned char enetaddr[6]; -out_set_ethaddr: - if (skip_eth0 && skip_eth1) + if (dh_mac_is_in_env("ethaddr")) return 0; - off = fdt_path_offset(gd->fdt_blob, "eeprom0"); - if (off < 0) { - printf("%s: No eeprom0 path offset\n", __func__); - return off; - } + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + return eth_env_set_enetaddr("ethaddr", enetaddr); - ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, off, &dev); - if (ret) { - printf("Cannot find EEPROM!\n"); - return ret; - } + return -ENXIO; +} - ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); - if (ret) { - printf("Error reading configuration EEPROM!\n"); - return ret; - } +static int dh_stm32_setup_eth1addr(void) +{ + unsigned char enetaddr[6]; - if (is_valid_ethaddr(enetaddr)) { - if (!skip_eth0) - eth_env_set_enetaddr("ethaddr", enetaddr); + if (dh_mac_is_in_env("eth1addr")) + return 0; + + if (dh_stm32_mac_is_in_ks8851()) + return 0; + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) { enetaddr[5]++; - if (!skip_eth1) - eth_env_set_enetaddr("eth1addr", enetaddr); + return eth_env_set_enetaddr("eth1addr", enetaddr); } + return -ENXIO; +} + +int setup_mac_address(void) +{ + if (dh_stm32_setup_ethaddr()) + printf("%s: Unable to setup ethaddr!\n", __func__); + + if (dh_stm32_setup_eth1addr()) + printf("%s: Unable to setup eth1addr!\n", __func__); + return 0; } -- 2.35.3
Re: [PATCH] bosch: Add inital board support for ACC
Hi Stefano, On Mon, 2022-04-11 at 17:45 +0200, Stefano Babic wrote: > Hi Philipp, > > On 02.03.22 10:39, Philip Oberfichtner wrote: > > The Bosch ACC (Air Center Control) Board is based on the i.MX6D. > > [snip] > > > diff --git a/include/configs/imx6q-acc.h b/include/configs/imx6q- > > acc.h > > new file mode 100644 > > index 00..caa11df49f > > --- /dev/null > > +++ b/include/configs/imx6q-acc.h > > @@ -0,0 +1,165 @@ > > +/* SPDX-License-Identifier: GPL-2.0+ > > + * > > + * Copyright (c) 2017 DENX Software Engineering GmbH, Heiko > > Schocher > > + * Copyright (c) 2019 Bosch Thermotechnik GmbH > > + */ > > + > > +#ifndef __IMX6Q_ACC_H > > +#define __IMX6Q_ACC_H > > + > > +#include > > +#include "mx6_common.h" > > + > > +/* Environment settings */ > > +#define CONFIG_ENV_ACCESS_IGNORE_FORCE > > + > > +#ifdef CONFIG_SYS_BOOT_EMMC > > +#define MMC_ROOTFS_DEV 0 > > +#define MMC_ROOTFS_PART 2 > > +#endif > > + > > +/* Allow to overwrite serial and ethaddr */ > > +#define CONFIG_ENV_OVERWRITE > > + > > +#ifdef CONFIG_SYS_BOOT_EMMC > > +/* eMMC Boot */ > > +#define ENV_EXTRA \ > > + "mmcdev=" __stringify(MMC_ROOTFS_DEV) "\0" \ > > + "mmcpart=" __stringify(MMC_ROOTFS_PART) "\0" \ > > + "fitpart=1\0" \ > > + "optargs=ro quiet systemd.gpt_auto=false\0" \ > > + "production=1\0" \ > > + "mmcautodetect=yes\0" \ > > + "mmcrootfstype=ext4\0" \ > > + "finduuid=part uuid mmc ${mmcdev}:${mmcpart} uuid\0" \ > > + "mmcargs=run finduuid; setenv bootargs " \ > > + "root=PARTUUID=${uuid} ${optargs} > > rootfstype=${mmcrootfstype}\0" \ > > + "mmc_mmc_fit=run env_persist; run setbm; run mmcloadfit; " > > \ > > + "run auth_fit_or_reset; run mmcargs addcon; " \ > > + "bootm ${fit_addr}#${bootconf}\0" \ > > + "bootset=0\0" \ > > + "setbm=if test ${bootset} -eq 1; " \ > > + "then setenv mmcpart 4; setenv fitpart 3; " \ > > + "else; setenv mmcpart 2; setenv fitpart 1; fi\0" \ > > + "handle_ustate=if test ${ustate} -eq 2; then setenv ustate > > 3; fi\0" \ > > + "switch_bootset=if test ${bootset} -eq 1; then setenv > > bootset 0; " \ > > + "else; setenv bootset 1;fi\0" \ > > + "env_persisted=0\0" \ > > + "env_persist=if test ${env_persisted} != 1; " \ > > + "then env set env_persisted 1; run save_env; fi;\0" > > \ > > + "save_env=env save; env save\0" \ > > + "altbootcmd=run handle_ustate; run switch_bootset; run > > save_env; run bootcmd\0" > > + > > +#define CONFIG_ENV_FLAGS_LIST_STATIC \ > > > > + "addcon:so," \ > > + "altbootcmd:so," \ > > + "auth_fit_or_reset:so," \ > > + "baudrate:do," \ > > + "bootcmd:so," \ > > + "bootcount:da," \ > > + "bootdelay:do," \ > > + "bootlimit:do," \ > > + "bootset:ba," \ > > + "clone_pending:ba," \ > > + "console:so," \ > > + "endurance_test:ba," \ > > + "env_persist:so," \ > > + "env_persisted:ba," \ > > + "ethaddr:so," \ > > + "factory_reset:ba," \ > > + "fdtcontroladdr:xa," \ > > + "finduuid:so," \ > > + "fit_addr:do," \ > > + "fitpart:da," \ > > + "handle_ustate:so," \ > > + "loadaddr:xo," \ > > + "mmc_mmc_fit:so," \ > > + "mmcargs:so," \ > > + "mmcautodetect:so," \ > > + "mmcdev:do," \ > > + "mmcfit_name:so," \ > > + "mmcloadfit:so," \ > > + "mmcpart:da," \ > > + "mmcrootfstype:so," \ > > + "optargs:so," \ > > + "production:ba," \ > > + "save_env:so," \ > > + "setbm:so," \ > > + "silent:so," \ > > + "switc
[PATCH v2] bosch: Add initial board support for ACC
The Bosch ACC (Air Center Control) Board is based on the i.MX6D. Signed-off-by: Philip Oberfichtner --- Changes in v2: - Adapt defconfig and device tree to new bootcount driver - Clean up CONFIG_ENV_FLAGS_LIST_STATIC - Fix style issues in device trees - Migrate CONFIG options to Kconfig This board supports depends on: - "Add pmic bootcount driver", patchwork id 291027 - "crypto/fsl: Fallback to SW sha1/256 is misaligned buffers", patchwork id 270524 --- arch/arm/dts/Makefile | 1 + arch/arm/dts/imx6q-acc-common.dtsi | 893 + arch/arm/dts/imx6q-acc-u-boot.dtsi | 76 +++ arch/arm/dts/imx6q-acc.dts | 280 + arch/arm/mach-imx/mx6/Kconfig | 15 + board/bosch/acc/Kconfig| 19 + board/bosch/acc/MAINTAINERS| 10 + board/bosch/acc/Makefile | 6 + board/bosch/acc/acc.c | 755 configs/imx6q_acc_defconfig| 110 include/configs/imx6q-acc.h| 128 + 11 files changed, 2293 insertions(+) create mode 100644 arch/arm/dts/imx6q-acc-common.dtsi create mode 100644 arch/arm/dts/imx6q-acc-u-boot.dtsi create mode 100644 arch/arm/dts/imx6q-acc.dts create mode 100644 board/bosch/acc/Kconfig create mode 100644 board/bosch/acc/MAINTAINERS create mode 100644 board/bosch/acc/Makefile create mode 100644 board/bosch/acc/acc.c create mode 100644 configs/imx6q_acc_defconfig create mode 100644 include/configs/imx6q-acc.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 644ba961a2..e39abda3b2 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -811,6 +811,7 @@ dtb-y += \ imx6q-sabreauto.dtb \ imx6q-sabrelite.dtb \ imx6q-sabresd.dtb \ + imx6q-acc.dtb \ imx6q-tbs2910.dtb \ imx6q-wandboard-revd1.dtb \ imx6qp-sabreauto.dtb \ diff --git a/arch/arm/dts/imx6q-acc-common.dtsi b/arch/arm/dts/imx6q-acc-common.dtsi new file mode 100644 index 00..8359ad61b5 --- /dev/null +++ b/arch/arm/dts/imx6q-acc-common.dtsi @@ -0,0 +1,893 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* Support for the i.MX6-based Bosch ACC board. + * + * Copyright (c) 2016 Garz & Fricke GmbH + * Copyright (c) 2018 DENX Software Engineering GmbH + * Heiko Schocher + * Niel Fourie + * Copyright (c) 2019,2020 Bosch Thermotechnik GmbH + * + * Based on work from: + * Copyright 2013 Freescale Semiconductor, Inc. + * + * Author: Fabio Estevam + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include + +/ { + soc { + bus@200 { + usbphy_nop1: usbphy_nop1 { + compatible = "usb-nop-xceiv"; + clocks = <&clks IMX6QDL_CLK_USBPHY1>; + clock-names = "main_clk"; + }; + }; + }; + + wdt-reboot { + compatible = "wdt-reboot"; + wdt = <&wdog1>; + }; + + backlight: backlight { + status = "okay"; + + compatible = "pwm-backlight"; + pwms = <&pwm1 0 5>; + brightness-levels = <0 63 95 159 255 383 543 735 959 1215 1503>; + num-interpolated-steps = <10>; + default-brightness-level = <100>; + power-supply = <®_lcd0_pwr>; + }; + + clk_12mhz_ref:clk_12mhz_ref { + compatible = "fixed-factor-clock"; + + clocks = <&clks 201>; + clock-names = "cko"; + clock-div = <1>; + clock-mult = <1>; + + #clock-cells = <0>; + clock-output-names = "ck12mhzref"; + }; + + leds { + compatible = "pwm-leds"; + + led_red: red { + label = "red"; + max-brightness = <248>; + default-state = "off"; + pwms = <&pwm2 0 50>; + }; + + led_white: white { + label = "white"; + max-brightness = <248>; + default-state = "off"; + pwms = <&pwm3 0 50>; + linux,default-trigger = "heartbeat"; + }; + }; + + /* Third gpio option are the flags, with custom meaning. */ + /* bit 1 act-low*/ + /* bit 2 init high */ + + gpio_export_keypad_fixed_in { + compatible = "gpio-export-of";
[PATCH v3] bosch: Add initial board support for ACC
The Bosch ACC (Air Center Control) Board is based on the i.MX6D. Signed-off-by: Philip Oberfichtner --- Changes in v3: - Rename acc to bosch-acc - Sync device tree with Linux Changes in v2: - Adapt defconfig and device tree to new bootcount driver - Clean up CONFIG_ENV_FLAGS_LIST_STATIC - Fix style issues in device trees - Migrate CONFIG options to Kconfig This board supports depends on: - "Add pmic bootcount driver", patchwork id 291027 - "crypto/fsl: Fallback to SW sha1/256 is misaligned buffers", patchwork id 270524 - Linux Device Tree patch, see below The Device Tree is currently being mainlined into Linux. The DT in this board support patch will be kept in sync as the DT patch for Linux evolves. The Linux patch is tracked under http://patchwork.ozlabs.org/project/devicetree-bindings/list/?series=294727 The only difference compared to the Linux DT is the removal of usbphynop properties. They are defined in the Linux version of imx6qdl.dtsi, but not in the u-boot version. --- arch/arm/dts/Makefile|1 + arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi | 80 ++ arch/arm/dts/imx6q-bosch-acc.dts | 1036 ++ arch/arm/mach-imx/mx6/Kconfig| 15 + board/bosch/acc/Kconfig | 19 + board/bosch/acc/MAINTAINERS |9 + board/bosch/acc/Makefile |6 + board/bosch/acc/acc.c| 755 configs/imx6q_bosch_acc_defconfig| 110 +++ include/configs/imx6q-bosch-acc.h| 128 +++ 10 files changed, 2159 insertions(+) create mode 100644 arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi create mode 100644 arch/arm/dts/imx6q-bosch-acc.dts create mode 100644 board/bosch/acc/Kconfig create mode 100644 board/bosch/acc/MAINTAINERS create mode 100644 board/bosch/acc/Makefile create mode 100644 board/bosch/acc/acc.c create mode 100644 configs/imx6q_bosch_acc_defconfig create mode 100644 include/configs/imx6q-bosch-acc.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 644ba961a2..418e0ee655 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -768,6 +768,7 @@ endif ifneq ($(CONFIG_MX6Q)$(CONFIG_MX6QDL),) dtb-y += \ imx6-apalis.dtb \ + imx6q-bosch-acc.dtb \ imx6q-cm-fx6.dtb \ imx6q-cubox-i.dtb \ imx6q-cubox-i-emmc-som-v15.dtb \ diff --git a/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi b/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi new file mode 100644 index 00..37c182d318 --- /dev/null +++ b/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* Copyright (C) 2022 Denx Software Engineering GmbH + * Philip Oberfichtner + */ + +/ { + chosen { + stdout-path = &uart2; + }; + + soc { + u-boot,dm-spl; + + bus@200 { + u-boot,dm-spl; + + spba-bus@200 { + u-boot,dm-spl; + }; + }; + + bus@210 { + u-boot,dm-spl; + }; + }; + + bootcount { + compatible = "u-boot,bootcount-pmic"; + pmic = <&pmic>; + }; +}; + +&uart1 { + u-boot,dm-spl; +}; + +&uart2 { + u-boot,dm-spl; +}; + +&usdhc2 { + u-boot,dm-spl; +}; + +&usdhc4 { + u-boot,dm-spl; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&gpio5 { + u-boot,dm-spl; +}; + +&gpio6 { + u-boot,dm-spl; +}; + +&gpio7 { + u-boot,dm-spl; +}; + +&wdog1 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/imx6q-bosch-acc.dts b/arch/arm/dts/imx6q-bosch-acc.dts new file mode 100644 index 00..d0f6ba0cc4 --- /dev/null +++ b/arch/arm/dts/imx6q-bosch-acc.dts @@ -0,0 +1,1036 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for the i.MX6-based Bosch ACC board. + * + * Copyright (C) 2016 Garz & Fricke GmbH + * Copyright (C) 2018 DENX Software Engineering GmbH, Heiko Schocher + * Copyright (C) 2018 DENX Software Engineering GmbH, Niel Fourie + * Copyright (C) 2019-2021 Bosch Thermotechnik GmbH, Matthias Winker + */ + +/dts-v1/; + +#include +#include "imx6q.dtsi" + +/ { + model = "Bosch ACC"; + compatible = "bosch,imx6q-acc", "fsl,imx6q"; + + aliases { + serial0 = &uart2; + serial1 = &uart1; + + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; + /* eMMC is connected to USDHC interface 4, but shall get the name 0 */ + mmc0 = &usdhc4; + /* SC-Cards is connected to USDHC interface 2, but shall ge
[PATCH v4] bosch: Add initial board support for ACC
The Bosch ACC (Air Center Control) Board is based on the i.MX6D. Signed-off-by: Philip Oberfichtner --- Changes in v4: - Remove obsolete CONFIG_FEC #defines - Sync device tree with Linux Changes in v3: - Rename acc to bosch-acc - Sync device tree with Linux Changes in v2: - Adapt defconfig and device tree to new bootcount driver - Clean up CONFIG_ENV_FLAGS_LIST_STATIC - Fix style issues in device trees - Migrate CONFIG options to Kconfig This board supports depends on: - "Add pmic bootcount driver", patchwork id 291027 - "crypto/fsl: Fallback to SW sha1/256 is misaligned buffers", patchwork id 270524 - Linux Device Tree patch, see below The Device Tree is currently being mainlined into Linux. The DT in this board support patch will be kept in sync as the DT patch for Linux evolves. The Linux patch is tracked under https://lore.kernel.org/linux-devicetree/20220421122619.1913496-2-...@denx.de/ The only difference compared to the Linux DT is the removal of usbphynop properties. They are defined in the Linux version of imx6qdl.dtsi, but not in the u-boot version. --- arch/arm/dts/Makefile| 1 + arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi | 80 ++ arch/arm/dts/imx6q-bosch-acc.dts | 967 +++ arch/arm/mach-imx/mx6/Kconfig| 15 + board/bosch/acc/Kconfig | 19 + board/bosch/acc/MAINTAINERS | 9 + board/bosch/acc/Makefile | 6 + board/bosch/acc/acc.c| 755 ++ configs/imx6q_bosch_acc_defconfig| 110 +++ include/configs/imx6q-bosch-acc.h| 122 +++ 10 files changed, 2084 insertions(+) create mode 100644 arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi create mode 100644 arch/arm/dts/imx6q-bosch-acc.dts create mode 100644 board/bosch/acc/Kconfig create mode 100644 board/bosch/acc/MAINTAINERS create mode 100644 board/bosch/acc/Makefile create mode 100644 board/bosch/acc/acc.c create mode 100644 configs/imx6q_bosch_acc_defconfig create mode 100644 include/configs/imx6q-bosch-acc.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 644ba961a2..418e0ee655 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -768,6 +768,7 @@ endif ifneq ($(CONFIG_MX6Q)$(CONFIG_MX6QDL),) dtb-y += \ imx6-apalis.dtb \ + imx6q-bosch-acc.dtb \ imx6q-cm-fx6.dtb \ imx6q-cubox-i.dtb \ imx6q-cubox-i-emmc-som-v15.dtb \ diff --git a/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi b/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi new file mode 100644 index 00..37c182d318 --- /dev/null +++ b/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* Copyright (C) 2022 Denx Software Engineering GmbH + * Philip Oberfichtner + */ + +/ { + chosen { + stdout-path = &uart2; + }; + + soc { + u-boot,dm-spl; + + bus@200 { + u-boot,dm-spl; + + spba-bus@200 { + u-boot,dm-spl; + }; + }; + + bus@210 { + u-boot,dm-spl; + }; + }; + + bootcount { + compatible = "u-boot,bootcount-pmic"; + pmic = <&pmic>; + }; +}; + +&uart1 { + u-boot,dm-spl; +}; + +&uart2 { + u-boot,dm-spl; +}; + +&usdhc2 { + u-boot,dm-spl; +}; + +&usdhc4 { + u-boot,dm-spl; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&gpio5 { + u-boot,dm-spl; +}; + +&gpio6 { + u-boot,dm-spl; +}; + +&gpio7 { + u-boot,dm-spl; +}; + +&wdog1 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/imx6q-bosch-acc.dts b/arch/arm/dts/imx6q-bosch-acc.dts new file mode 100644 index 00..9a05175536 --- /dev/null +++ b/arch/arm/dts/imx6q-bosch-acc.dts @@ -0,0 +1,967 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for the i.MX6-based Bosch ACC board. + * + * Copyright (C) 2016 Garz & Fricke GmbH + * Copyright (C) 2018 DENX Software Engineering GmbH, Heiko Schocher + * Copyright (C) 2018 DENX Software Engineering GmbH, Niel Fourie + * Copyright (C) 2019-2021 Bosch Thermotechnik GmbH, Matthias Winker + * Copyright (C) 2022 DENX Software Engineering GmbH, Philip Oberfichtner + */ + +/dts-v1/; + +#include +#include +#include "imx6q.dtsi" + +/ { + model = "Bosch ACC"; + compatible = "bosch,imx6q-acc", "fsl,imx6q"; + + aliases { + serial0 = &uart2; + serial1 = &uart1; + + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; + /* eMMC is connected to USDHC
[PATCH v5] bosch: Add initial board support for ACC
The Bosch ACC (Air Center Control) Board is based on the i.MX6D. Signed-off-by: Philip Oberfichtner --- Changes in v5: - Rebase on v2022.07-rc1 - Sync device tree with Linux Changes in v4: - Remove obsolete CONFIG_FEC #defines - Sync device tree with Linux Changes in v3: - Rename acc to bosch-acc - Sync device tree with Linux Changes in v2: - Adapt defconfig and device tree to new bootcount driver - Clean up CONFIG_ENV_FLAGS_LIST_STATIC - Fix style issues in device trees - Migrate CONFIG options to Kconfig This board supports depends on: - "crypto/fsl: Fallback to SW sha1/256 is misaligned buffers", patchwork id 270524 - Linux Device Tree patch, see below The Device Tree is currently being mainlined into Linux. The DT in this board support patch will be kept in sync as the DT patch for Linux evolves. The Linux patch is tracked under https://lore.kernel.org/linux-devicetree/20220427135229.2339865-4-...@denx.de/ The only difference compared to the Linux DT is the removal of usbphynop properties. They are defined in the Linux version of imx6qdl.dtsi, but not in the u-boot version. --- arch/arm/dts/Makefile| 1 + arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi | 80 +++ arch/arm/dts/imx6q-bosch-acc.dts | 773 +++ arch/arm/mach-imx/mx6/Kconfig| 15 + board/bosch/acc/Kconfig | 19 + board/bosch/acc/MAINTAINERS | 9 + board/bosch/acc/Makefile | 6 + board/bosch/acc/acc.c| 755 ++ configs/imx6q_bosch_acc_defconfig| 110 include/configs/imx6q-bosch-acc.h| 122 10 files changed, 1890 insertions(+) create mode 100644 arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi create mode 100644 arch/arm/dts/imx6q-bosch-acc.dts create mode 100644 board/bosch/acc/Kconfig create mode 100644 board/bosch/acc/MAINTAINERS create mode 100644 board/bosch/acc/Makefile create mode 100644 board/bosch/acc/acc.c create mode 100644 configs/imx6q_bosch_acc_defconfig create mode 100644 include/configs/imx6q-bosch-acc.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 1032ce4c85..a24ac93258 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -777,6 +777,7 @@ endif ifneq ($(CONFIG_MX6Q)$(CONFIG_MX6QDL),) dtb-y += \ imx6-apalis.dtb \ + imx6q-bosch-acc.dtb \ imx6q-cm-fx6.dtb \ imx6q-cubox-i.dtb \ imx6q-cubox-i-emmc-som-v15.dtb \ diff --git a/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi b/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi new file mode 100644 index 00..37c182d318 --- /dev/null +++ b/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* Copyright (C) 2022 Denx Software Engineering GmbH + * Philip Oberfichtner + */ + +/ { + chosen { + stdout-path = &uart2; + }; + + soc { + u-boot,dm-spl; + + bus@200 { + u-boot,dm-spl; + + spba-bus@200 { + u-boot,dm-spl; + }; + }; + + bus@210 { + u-boot,dm-spl; + }; + }; + + bootcount { + compatible = "u-boot,bootcount-pmic"; + pmic = <&pmic>; + }; +}; + +&uart1 { + u-boot,dm-spl; +}; + +&uart2 { + u-boot,dm-spl; +}; + +&usdhc2 { + u-boot,dm-spl; +}; + +&usdhc4 { + u-boot,dm-spl; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&gpio5 { + u-boot,dm-spl; +}; + +&gpio6 { + u-boot,dm-spl; +}; + +&gpio7 { + u-boot,dm-spl; +}; + +&wdog1 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/imx6q-bosch-acc.dts b/arch/arm/dts/imx6q-bosch-acc.dts new file mode 100644 index 00..103a64f331 --- /dev/null +++ b/arch/arm/dts/imx6q-bosch-acc.dts @@ -0,0 +1,773 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for the i.MX6-based Bosch ACC board. + * + * Copyright (C) 2016 Garz & Fricke GmbH + * Copyright (C) 2018 DENX Software Engineering GmbH, Heiko Schocher + * Copyright (C) 2018 DENX Software Engineering GmbH, Niel Fourie + * Copyright (C) 2019-2021 Bosch Thermotechnik GmbH, Matthias Winker + * Copyright (C) 2022 DENX Software Engineering GmbH, Philip Oberfichtner + */ + +/dts-v1/; + +#include +#include +#include "imx6q.dtsi" + +/ { + model = "Bosch ACC"; + compatible = "bosch,imx6q-acc", "fsl,imx6q"; + + aliases { + serial0 = &uart2; + serial1 = &uart1; + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; + mmc0 = &us
Changing eMMC boot partition size
Hi everybody, I have a question regarding changing the eMMC boot partition size. According the the JEDEC eMMC spec it is read-only (BOOT_SIZE_MULT register). But we still have mmc_boot_partition_size_change() in drivers/mmc/mmc_boot.c. It contains the comment /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */ What is moviNAND? My research pointed me to Samsung products only. So is changing the boot partition size vendor specific or can it be used more generally? To be specific, I use the Kioxia THGBMJG6C1LBAB7 eMMC chip. Thanks and best regards, Philip Oberfichtner
[PATCH 0/8] ARM: imx: Add support for iMX6QDL DHCOM DRC02 and DH picoITX
This patch series adds support for the DHCOM DRC02 and DH picoITX baseboards by DH electronics. The two boards can be equipped with different SoMs. The STM32MP15xx based versions are already mainlined. This patch adds support for the iMX6QDL based variants. Philip Oberfichtner (8): ARM: imx6: Fix broken DT path in DH board file ARM: dts: imx: Migrate iMX6QDL DRC02 DTs from Linux ARM: dts: imx: Migrate iMX6QDL picoITX DTs from Linux ARM: imx6: Remove CONFIG_FEC_MXC_PHYADDR from DH header ARM: dts: imx: Simplify fec node for iMX6QDL DHCOM boards ARM: dts: imx: Configure FEC for iMX6QDL picoITX ARM: dts: imx: Configure FEC for iMX6QDL DRC02 ARM: imx6: Adapt device tree selection in DH board file arch/arm/dts/Makefile | 2 + arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi | 10 ++ arch/arm/dts/imx6dl-dhcom-picoitx.dts | 20 +++ arch/arm/dts/imx6qdl-dhcom-drc02.dtsi | 143 ++ arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi | 13 -- arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi | 69 + arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi| 18 +++ arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi| 10 ++ arch/arm/dts/imx6s-dhcom-drc02.dts| 30 board/dhelectronics/dh_imx6/dh_imx6.c | 26 ++-- configs/dh_imx6_defconfig | 2 +- include/configs/dh_imx6.h | 3 - 12 files changed, 319 insertions(+), 27 deletions(-) create mode 100644 arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi create mode 100644 arch/arm/dts/imx6dl-dhcom-picoitx.dts create mode 100644 arch/arm/dts/imx6qdl-dhcom-drc02.dtsi create mode 100644 arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi create mode 100644 arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi create mode 100644 arch/arm/dts/imx6s-dhcom-drc02.dts -- 2.34.1
[PATCH 1/8] ARM: imx6: Fix broken DT path in DH board file
In the dhelectronics iMX6 board file fix the outdated eeprom path by using a DT label instead. The label has been newly created for all iMX6QDL DHCOM boards. Signed-off-by: Philip Oberfichtner --- arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi | 11 +++ board/dhelectronics/dh_imx6/dh_imx6.c | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi index 4c3b5e82d6..91545ab6e9 100644 --- a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi @@ -3,6 +3,17 @@ * Copyright (C) 2020 Harald Seiler */ +/ { + aliases { + eeprom0 = &eeprom0; + }; +}; + +&i2c3 { + eeprom0: eeprom@50 { + }; +}; + ®_usb_otg_vbus { gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>; enable-active-high; diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c index 2969e90a70..6059f96e80 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6.c +++ b/board/dhelectronics/dh_imx6/dh_imx6.c @@ -100,9 +100,9 @@ static int setup_dhcom_mac_from_fuse(void) return 0; } - eeprom = ofnode_path("/soc/aips-bus@210/i2c@21a8000/eeprom@50"); + eeprom = ofnode_get_aliases_node("eeprom0"); if (!ofnode_valid(eeprom)) { - printf("Invalid hardware path to EEPROM!\n"); + printf("Can't find eeprom0 alias!\n"); return -ENODEV; } -- 2.34.1
[PATCH 2/8] ARM: dts: imx: Migrate iMX6QDL DRC02 DTs from Linux
Migrate DH DRC02 device trees from Linux commit 42226c989789 (tag v5.18-rc7). No changes have been made, the DTs are exact copies. Furthermore add the DTB to dh_imx6_defconfig. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- arch/arm/dts/Makefile | 1 + arch/arm/dts/imx6qdl-dhcom-drc02.dtsi | 143 ++ arch/arm/dts/imx6s-dhcom-drc02.dts| 30 ++ configs/dh_imx6_defconfig | 2 +- 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/imx6qdl-dhcom-drc02.dtsi create mode 100644 arch/arm/dts/imx6s-dhcom-drc02.dts diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 83630af4f6..7bfdfb5313 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -771,6 +771,7 @@ dtb-y += \ imx6dl-sabreauto.dtb \ imx6dl-sabresd.dtb \ imx6dl-wandboard-revd1.dtb \ + imx6s-dhcom-drc02.dtb endif diff --git a/arch/arm/dts/imx6qdl-dhcom-drc02.dtsi b/arch/arm/dts/imx6qdl-dhcom-drc02.dtsi new file mode 100644 index 00..702cd4a1b2 --- /dev/null +++ b/arch/arm/dts/imx6qdl-dhcom-drc02.dtsi @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 DH electronics GmbH + */ + +/ { + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +/* + * Special SoM hardware required which uses the pins from micro SD card. The + * pins SD3_DAT0 and SD3_DAT1 are muxed as can2 Tx and Rx. The signals for can2 + * Tx and Rx are routed to the DHCOM UART1 rts/cts pins. Therefore the micro SD + * card must be disabled and the uart1 rts/cts must be output on other DHCOM + * pins, see uart1 and usdhc3 node below. + */ +&can2 { + status = "okay"; +}; + +&gpio1 { + /* +* NOTE: On DRC02, the RS485_RX_En is controlled by a separate +* GPIO line, however the i.MX6 UART driver assumes RX happens +* during TX anyway and that it only controls drive enable DE +* line. Hence, the RX is always enabled here. +*/ + rs485-rx-en-hog { + gpio-hog; + gpios = <18 0>; /* GPIO Q */ + line-name = "rs485-rx-en"; + output-low; + }; +}; + +&gpio3 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "DRC02-In1", "", "", "", ""; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", "DHCOM-E", "DRC02-In2", "DHCOM-H", + "DHCOM-I", "DRC02-HW0", "", "", "", "", "", "", + "", "", "", "", "DRC02-Out1", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio6 { + gpio-line-names = + "", "", "", "DRC02-Out2", "", "", "SOM-HW1", "", + "", "", "", "", "", "", "DRC02-HW2", "DRC02-HW1", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&i2c1 { + eeprom@50 { + compatible = "atmel,24c04"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&uart1 { + /* +* Due to the use of can2 the signals for can2 Tx and Rx are routed to +* DHCOM UART1 rts/cts pins. Therefore this UART have to use DHCOM GPIOs +* for rts/cts. So configure DHCOM GPIO I as rts and GPIO M as cts. +*/ + /delete-property/ uart-has-rtscts; + cts-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>; /* GPIO M */ + pinctrl-0 = <&pinctrl_uart1 &pinctrl_dhcom_i &pinctrl_dhcom_m>; + pinctrl-names = "default"; + rts-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */ +}; + +&uart5 { + /* +* On DRC02 this UART is used as RS485 interface and RS485_TX_En is +* controlled by DHCOM GPIO P.
[PATCH 4/8] ARM: imx6: Remove CONFIG_FEC_MXC_PHYADDR from DH header
Use phy address from device tree instead of CONFIG_FEC_MXC_PHYADDR from board header. This is required, because the DH picoITX and DRC02 boards require different settings than PDK2. The corresponding 'phy-handle' device tree properties are already there. I tested this change on picoITX and DRC02, but on PDK2 it is untested. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- include/configs/dh_imx6.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/configs/dh_imx6.h b/include/configs/dh_imx6.h index 2b14464dff..178f5a6e7d 100644 --- a/include/configs/dh_imx6.h +++ b/include/configs/dh_imx6.h @@ -30,9 +30,6 @@ /* Bootcounter */ #define CONFIG_SYS_BOOTCOUNT_BE -/* FEC ethernet */ -#define CONFIG_FEC_MXC_PHYADDR 7 - /* MMC Configs */ #define CONFIG_SYS_FSL_ESDHC_ADDR 0 #define CONFIG_SYS_FSL_USDHC_NUM 3 -- 2.34.1
[PATCH 3/8] ARM: dts: imx: Migrate iMX6QDL picoITX DTs from Linux
Migrate DH picoITX device trees from Linux commit 42226c989789 (tag v5.18-rc7). No changes have been made, the DTs are exact copies. Furthermore add the DTB to dh_imx6_defconfig. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- arch/arm/dts/Makefile | 1 + arch/arm/dts/imx6dl-dhcom-picoitx.dts | 20 +++ arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi | 69 + configs/dh_imx6_defconfig | 2 +- 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/imx6dl-dhcom-picoitx.dts create mode 100644 arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7bfdfb5313..f7601afd9c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -738,6 +738,7 @@ dtb-y += \ imx6dl-cubox-i-emmc-som-v15.dtb \ imx6dl-cubox-i-som-v15.dtb \ imx6dl-dhcom-pdk2.dtb \ + imx6dl-dhcom-picoitx.dts \ imx6dl-gw51xx.dtb \ imx6dl-gw52xx.dtb \ imx6dl-gw53xx.dtb \ diff --git a/arch/arm/dts/imx6dl-dhcom-picoitx.dts b/arch/arm/dts/imx6dl-dhcom-picoitx.dts new file mode 100644 index 00..038bb00255 --- /dev/null +++ b/arch/arm/dts/imx6dl-dhcom-picoitx.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 DH electronics GmbH + * + * DHCOM iMX6 variant: + * DHCM-iMX6DL-C0800-R102-F0819-E-SD-RTC-T-HS-I-01D2 + * DHCOM PCB number: 493-300 or newer + * PicoITX PCB number: 487-600 or newer + */ +/dts-v1/; + +#include "imx6dl.dtsi" +#include "imx6qdl-dhcom-som.dtsi" +#include "imx6qdl-dhcom-picoitx.dtsi" + +/ { + model = "DH electronics i.MX6DL DHCOM on PicoITX"; + compatible = "dh,imx6dl-dhcom-picoitx", "dh,imx6dl-dhcom-som", +"fsl,imx6dl"; +}; diff --git a/arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi b/arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi new file mode 100644 index 00..4cd4cb9543 --- /dev/null +++ b/arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 DH electronics GmbH + */ + +#include + +/ { + chosen { + stdout-path = "serial0:115200n8"; + }; + + led { + compatible = "gpio-leds"; + + led-0 { + color = ; + default-state = "off"; + function = LED_FUNCTION_INDICATOR; + gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */ + pinctrl-0 = <&pinctrl_dhcom_i>; + pinctrl-names = "default"; + }; + }; +}; + +&gpio1 { + gpio-line-names = + "", "", "DHCOM-A", "", "DHCOM-B", "PicoITX-In2", "", "", + "", "", "", "", "", "", "", "", + "DHCOM-R", "DHCOM-S", "DHCOM-Q", "DHCOM-T", "DHCOM-U", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", "PicoITX-In1", "DHCOM-INT", "DHCOM-H", + "DHCOM-I", "PicoITX-HW2", "", "", "", "", "", "", + "", "", "", "", "PicoITX-Out1", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio6 { + gpio-line-names = + "", "", "", "PicoITX-Out2", "", "", "SOM-HW1", "", + "", "", "", "", "", "", "PicoITX-HW0", "PicoITX-HW1", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&iomuxc { + pinctrl-0 = < + /* +* The following DHCOM GPIOs are used on this board. +* Therefore, they have been removed from the list below. +* I: yellow led +*/ + &pinctrl_hog_base +
[PATCH 5/8] ARM: dts: imx: Simplify fec node for iMX6QDL DHCOM boards
Firstly the fec can now use the regulator reg_eth_vio from imx6qdl-dhcom-som.dtsi instead of defining its own. Secondly the &fec node is moved to the more generic SoM device tree file, because it can be used by multiple boards. Signed-off-by: Philip Oberfichtner --- arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi | 13 - arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi | 7 +++ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi b/arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi index a1ffb1d6fc..0673c21e3c 100644 --- a/arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi @@ -5,19 +5,6 @@ #include "imx6qdl-dhcom-u-boot.dtsi" -/ { - fec_vio: regulator-fec { - compatible = "regulator-fixed"; - - regulator-name = "fec-vio"; - gpio = <&gpio1 7 GPIO_ACTIVE_LOW>; - }; -}; - &fec { phy-reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>; - phy-reset-duration = <1>; - phy-reset-post-delay = <10>; - - phy-supply = <&fec_vio>; }; diff --git a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi index 91545ab6e9..190567ab7b 100644 --- a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi @@ -1,6 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+) /* * Copyright (C) 2020 Harald Seiler + * Copyright (C) 2022 Philip Oberfichtner */ / { @@ -9,6 +10,12 @@ }; }; +&fec { + phy-reset-duration = <1>; + phy-reset-post-delay = <10>; + phy-supply = <®_eth_vio>; +}; + &i2c3 { eeprom0: eeprom@50 { }; -- 2.34.1
[PATCH 6/8] ARM: dts: imx: Configure FEC for iMX6QDL picoITX
Add a u-boot dtsi for configuring the fec node of the DH picoITX. Signed-off-by: Philip Oberfichtner --- arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi | 10 ++ 1 file changed, 10 insertions(+) create mode 100644 arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi diff --git a/arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi b/arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi new file mode 100644 index 00..16669b2533 --- /dev/null +++ b/arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0+) +/* + * Copyright (C) 2022 Philip Oberfichtner + */ + +#include "imx6qdl-dhcom-u-boot.dtsi" + +&fec { + phy-reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; +}; -- 2.34.1
[PATCH 8/8] ARM: imx6: Adapt device tree selection in DH board file
Before this commit device tree selection could rely solely on differentiating the iMX6 processor variant Q and DL. After adding two new carrier boards, the DRC02 and the picoITX, the interchangeability of SoMs makes this approach infeasible. It is now required to specify the carrier board (dhcom-drc02, dhcom-picoitx or dhcom-pdk2) at compile time using CONFIG_DEFAULT_DEVICETREE. The SoM is determined at runtime as before. Signed-off-by: Philip Oberfichtner --- board/dhelectronics/dh_imx6/dh_imx6.c | 22 ++ 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c index 6059f96e80..c63fc1dd8a 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6.c +++ b/board/dhelectronics/dh_imx6/dh_imx6.c @@ -227,14 +227,20 @@ int checkboard(void) #ifdef CONFIG_MULTI_DTB_FIT int board_fit_config_name_match(const char *name) { - if (is_mx6dq()) { - if (!strcmp(name, "imx6q-dhcom-pdk2")) - return 0; - } else if (is_mx6sdl()) { - if (!strcmp(name, "imx6dl-dhcom-pdk2")) - return 0; - } + /* Determine carrier board at compile time and SoM at runtime */ + const size_t size = 32; + char *car, *som, dt[size]; + + car = strchr(CONFIG_DEFAULT_DEVICE_TREE, '-'); /* i.e. -dhcom-drc02 */ + + som = is_mx6dq() ? "imx6q" : + is_mx6dl() ? "imx6dl" : + is_mx6solo() ? "imx6s" : NULL; + + if (!(car && som)) + return -1; - return -1; + snprintf(dt, size, "%s%s", som, car); + return strcmp(name, dt); } #endif -- 2.34.1
[PATCH 7/8] ARM: dts: imx: Configure FEC for iMX6QDL DRC02
Add a u-boot dtsi for configuring the fec node of the DH DRC02. Signed-off-by: Philip Oberfichtner --- arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi | 10 ++ 1 file changed, 10 insertions(+) create mode 100644 arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi diff --git a/arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi b/arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi new file mode 100644 index 00..16669b2533 --- /dev/null +++ b/arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0+) +/* + * Copyright (C) 2022 Philip Oberfichtner + */ + +#include "imx6qdl-dhcom-u-boot.dtsi" + +&fec { + phy-reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; +}; -- 2.34.1
[PATCH v6] bosch: Add initial board support for ACC
The Bosch ACC (Air Center Control) Board is based on the i.MX6D. The device tree is copied from Linux, see [1]. The only difference compared to the Linux DT is the removal of usbphynop properties. They are defined in the Linux version of imx6qdl.dtsi, but not in the u-boot version. [1] Commit 6192cf8ac082 from git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git Signed-off-by: Philip Oberfichtner --- Changes in v6: - Sync device tree with Linux (now accepted mainline) - Update commit description - Rebase on v2022.07-rc2 Changes in v5: - Rebase on v2022.07-rc1 - Sync device tree with Linux Changes in v4: - Remove obsolete CONFIG_FEC #defines - Sync device tree with Linux Changes in v3: - Rename acc to bosch-acc - Sync device tree with Linux Changes in v2: - Adapt defconfig and device tree to new bootcount driver - Clean up CONFIG_ENV_FLAGS_LIST_STATIC - Fix style issues in device trees - Migrate CONFIG options to Kconfig --- arch/arm/dts/Makefile| 1 + arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi | 80 +++ arch/arm/dts/imx6q-bosch-acc.dts | 769 +++ arch/arm/mach-imx/mx6/Kconfig| 15 + board/bosch/acc/Kconfig | 19 + board/bosch/acc/MAINTAINERS | 9 + board/bosch/acc/Makefile | 6 + board/bosch/acc/acc.c| 755 ++ configs/imx6q_bosch_acc_defconfig| 110 include/configs/imx6q-bosch-acc.h| 122 10 files changed, 1886 insertions(+) create mode 100644 arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi create mode 100644 arch/arm/dts/imx6q-bosch-acc.dts create mode 100644 board/bosch/acc/Kconfig create mode 100644 board/bosch/acc/MAINTAINERS create mode 100644 board/bosch/acc/Makefile create mode 100644 board/bosch/acc/acc.c create mode 100644 configs/imx6q_bosch_acc_defconfig create mode 100644 include/configs/imx6q-bosch-acc.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 83630af4f6..4cfa86dada 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -777,6 +777,7 @@ endif ifneq ($(CONFIG_MX6Q)$(CONFIG_MX6QDL),) dtb-y += \ imx6-apalis.dtb \ + imx6q-bosch-acc.dtb \ imx6q-cm-fx6.dtb \ imx6q-cubox-i.dtb \ imx6q-cubox-i-emmc-som-v15.dtb \ diff --git a/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi b/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi new file mode 100644 index 00..37c182d318 --- /dev/null +++ b/arch/arm/dts/imx6q-bosch-acc-u-boot.dtsi @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* Copyright (C) 2022 Denx Software Engineering GmbH + * Philip Oberfichtner + */ + +/ { + chosen { + stdout-path = &uart2; + }; + + soc { + u-boot,dm-spl; + + bus@200 { + u-boot,dm-spl; + + spba-bus@200 { + u-boot,dm-spl; + }; + }; + + bus@210 { + u-boot,dm-spl; + }; + }; + + bootcount { + compatible = "u-boot,bootcount-pmic"; + pmic = <&pmic>; + }; +}; + +&uart1 { + u-boot,dm-spl; +}; + +&uart2 { + u-boot,dm-spl; +}; + +&usdhc2 { + u-boot,dm-spl; +}; + +&usdhc4 { + u-boot,dm-spl; +}; + +&gpio1 { + u-boot,dm-spl; +}; + +&gpio2 { + u-boot,dm-spl; +}; + +&gpio3 { + u-boot,dm-spl; +}; + +&gpio4 { + u-boot,dm-spl; +}; + +&gpio5 { + u-boot,dm-spl; +}; + +&gpio6 { + u-boot,dm-spl; +}; + +&gpio7 { + u-boot,dm-spl; +}; + +&wdog1 { + u-boot,dm-spl; +}; diff --git a/arch/arm/dts/imx6q-bosch-acc.dts b/arch/arm/dts/imx6q-bosch-acc.dts new file mode 100644 index 00..1bd4ef2fe4 --- /dev/null +++ b/arch/arm/dts/imx6q-bosch-acc.dts @@ -0,0 +1,769 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for the i.MX6-based Bosch ACC board. + * + * Copyright (C) 2016 Garz & Fricke GmbH + * Copyright (C) 2018 DENX Software Engineering GmbH, Heiko Schocher + * Copyright (C) 2018 DENX Software Engineering GmbH, Niel Fourie + * Copyright (C) 2019-2021 Bosch Thermotechnik GmbH, Matthias Winker + * Copyright (C) 2022 DENX Software Engineering GmbH, Philip Oberfichtner + */ + +/dts-v1/; + +#include +#include +#include "imx6q.dtsi" + +/ { + model = "Bosch ACC"; + compatible = "bosch,imx6q-acc", "fsl,imx6q"; + + aliases { + i2c0 = &i2c1; + i2c1 = &i2c2; + i2c2 = &i2c3; + mmc0 = &usdhc4; + mmc1 = &usdhc2; + serial0 = &uart2; + serial1 = &uart1; + }; + + memory@1000 { + device_type = "memory"; + reg = <0x100
[PATCH v2 0/8] ARM: imx: Add support for iMX6QDL DHCOM DRC02 and DH picoITX
This patch series adds support for the DHCOM DRC02 and DH picoITX baseboards by DH electronics. The two boards can be equipped with different SoMs. The STM32MP15xx based versions are already mainlined. This patch adds support for the iMX6QDL based variants. Changes in v2: - Rewrite board_fit_config_name_match - Return -EINVAL instead of -1 - Reviewed-by Marek - Fix spelling Philip Oberfichtner (8): ARM: imx6: Fix broken DT path in DH board file ARM: dts: imx: Migrate iMX6QDL DRC02 DTs from Linux ARM: dts: imx: Migrate iMX6QDL picoITX DTs from Linux ARM: imx6: Remove CONFIG_FEC_MXC_PHYADDR from DH header ARM: dts: imx: Simplify fec node for iMX6QDL DHCOM boards ARM: dts: imx: Configure FEC for iMX6QDL picoITX ARM: dts: imx: Configure FEC for iMX6QDL DRC02 ARM: imx6: Adapt device tree selection in DH board file arch/arm/dts/Makefile | 2 + arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi | 10 ++ arch/arm/dts/imx6dl-dhcom-picoitx.dts | 20 +++ arch/arm/dts/imx6qdl-dhcom-drc02.dtsi | 143 ++ arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi | 13 -- arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi | 69 + arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi| 18 +++ arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi| 10 ++ arch/arm/dts/imx6s-dhcom-drc02.dts| 30 board/dhelectronics/dh_imx6/dh_imx6.c | 35 - configs/dh_imx6_defconfig | 2 +- include/configs/dh_imx6.h | 3 - 12 files changed, 330 insertions(+), 25 deletions(-) create mode 100644 arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi create mode 100644 arch/arm/dts/imx6dl-dhcom-picoitx.dts create mode 100644 arch/arm/dts/imx6qdl-dhcom-drc02.dtsi create mode 100644 arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi create mode 100644 arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi create mode 100644 arch/arm/dts/imx6s-dhcom-drc02.dts -- 2.34.1
[PATCH v2 1/8] ARM: imx6: Fix broken DT path in DH board file
In the DH electronics iMX6 board file fix the outdated eeprom path by using a DT label instead. The label has been newly created for all iMX6QDL DHCOM boards. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- Changes in v2: - Reviewed-by Marek arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi | 11 +++ board/dhelectronics/dh_imx6/dh_imx6.c | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi index 4c3b5e82d6..91545ab6e9 100644 --- a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi @@ -3,6 +3,17 @@ * Copyright (C) 2020 Harald Seiler */ +/ { + aliases { + eeprom0 = &eeprom0; + }; +}; + +&i2c3 { + eeprom0: eeprom@50 { + }; +}; + ®_usb_otg_vbus { gpio = <&gpio3 31 GPIO_ACTIVE_HIGH>; enable-active-high; diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c index 2969e90a70..6059f96e80 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6.c +++ b/board/dhelectronics/dh_imx6/dh_imx6.c @@ -100,9 +100,9 @@ static int setup_dhcom_mac_from_fuse(void) return 0; } - eeprom = ofnode_path("/soc/aips-bus@210/i2c@21a8000/eeprom@50"); + eeprom = ofnode_get_aliases_node("eeprom0"); if (!ofnode_valid(eeprom)) { - printf("Invalid hardware path to EEPROM!\n"); + printf("Can't find eeprom0 alias!\n"); return -ENODEV; } -- 2.34.1
[PATCH v2 2/8] ARM: dts: imx: Migrate iMX6QDL DRC02 DTs from Linux
Migrate DH DRC02 device trees from Linux commit 42226c989789 (tag v5.18-rc7). No changes have been made, the DTs are exact copies. Furthermore add the DTB to dh_imx6_defconfig. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- (no changes since v1) arch/arm/dts/Makefile | 1 + arch/arm/dts/imx6qdl-dhcom-drc02.dtsi | 143 ++ arch/arm/dts/imx6s-dhcom-drc02.dts| 30 ++ configs/dh_imx6_defconfig | 2 +- 4 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/imx6qdl-dhcom-drc02.dtsi create mode 100644 arch/arm/dts/imx6s-dhcom-drc02.dts diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 83630af4f6..7bfdfb5313 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -771,6 +771,7 @@ dtb-y += \ imx6dl-sabreauto.dtb \ imx6dl-sabresd.dtb \ imx6dl-wandboard-revd1.dtb \ + imx6s-dhcom-drc02.dtb endif diff --git a/arch/arm/dts/imx6qdl-dhcom-drc02.dtsi b/arch/arm/dts/imx6qdl-dhcom-drc02.dtsi new file mode 100644 index 00..702cd4a1b2 --- /dev/null +++ b/arch/arm/dts/imx6qdl-dhcom-drc02.dtsi @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 DH electronics GmbH + */ + +/ { + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +/* + * Special SoM hardware required which uses the pins from micro SD card. The + * pins SD3_DAT0 and SD3_DAT1 are muxed as can2 Tx and Rx. The signals for can2 + * Tx and Rx are routed to the DHCOM UART1 rts/cts pins. Therefore the micro SD + * card must be disabled and the uart1 rts/cts must be output on other DHCOM + * pins, see uart1 and usdhc3 node below. + */ +&can2 { + status = "okay"; +}; + +&gpio1 { + /* +* NOTE: On DRC02, the RS485_RX_En is controlled by a separate +* GPIO line, however the i.MX6 UART driver assumes RX happens +* during TX anyway and that it only controls drive enable DE +* line. Hence, the RX is always enabled here. +*/ + rs485-rx-en-hog { + gpio-hog; + gpios = <18 0>; /* GPIO Q */ + line-name = "rs485-rx-en"; + output-low; + }; +}; + +&gpio3 { + gpio-line-names = + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "DRC02-In1", "", "", "", ""; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", "DHCOM-E", "DRC02-In2", "DHCOM-H", + "DHCOM-I", "DRC02-HW0", "", "", "", "", "", "", + "", "", "", "", "DRC02-Out1", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio6 { + gpio-line-names = + "", "", "", "DRC02-Out2", "", "", "SOM-HW1", "", + "", "", "", "", "", "", "DRC02-HW2", "DRC02-HW1", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&i2c1 { + eeprom@50 { + compatible = "atmel,24c04"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&uart1 { + /* +* Due to the use of can2 the signals for can2 Tx and Rx are routed to +* DHCOM UART1 rts/cts pins. Therefore this UART have to use DHCOM GPIOs +* for rts/cts. So configure DHCOM GPIO I as rts and GPIO M as cts. +*/ + /delete-property/ uart-has-rtscts; + cts-gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>; /* GPIO M */ + pinctrl-0 = <&pinctrl_uart1 &pinctrl_dhcom_i &pinctrl_dhcom_m>; + pinctrl-names = "default"; + rts-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */ +}; + +&uart5 { + /* +* On DRC02 this UART is used as RS485 interface and RS485_TX_En is +* controlled by DHCOM GPIO P.
[PATCH v2 3/8] ARM: dts: imx: Migrate iMX6QDL picoITX DTs from Linux
Migrate DH picoITX device trees from Linux commit 42226c989789 (tag v5.18-rc7). No changes have been made, the DTs are exact copies. Furthermore add the DTB to dh_imx6_defconfig. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- (no changes since v1) arch/arm/dts/Makefile | 1 + arch/arm/dts/imx6dl-dhcom-picoitx.dts | 20 +++ arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi | 69 + configs/dh_imx6_defconfig | 2 +- 4 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 arch/arm/dts/imx6dl-dhcom-picoitx.dts create mode 100644 arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 7bfdfb5313..f7601afd9c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -738,6 +738,7 @@ dtb-y += \ imx6dl-cubox-i-emmc-som-v15.dtb \ imx6dl-cubox-i-som-v15.dtb \ imx6dl-dhcom-pdk2.dtb \ + imx6dl-dhcom-picoitx.dts \ imx6dl-gw51xx.dtb \ imx6dl-gw52xx.dtb \ imx6dl-gw53xx.dtb \ diff --git a/arch/arm/dts/imx6dl-dhcom-picoitx.dts b/arch/arm/dts/imx6dl-dhcom-picoitx.dts new file mode 100644 index 00..038bb00255 --- /dev/null +++ b/arch/arm/dts/imx6dl-dhcom-picoitx.dts @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 DH electronics GmbH + * + * DHCOM iMX6 variant: + * DHCM-iMX6DL-C0800-R102-F0819-E-SD-RTC-T-HS-I-01D2 + * DHCOM PCB number: 493-300 or newer + * PicoITX PCB number: 487-600 or newer + */ +/dts-v1/; + +#include "imx6dl.dtsi" +#include "imx6qdl-dhcom-som.dtsi" +#include "imx6qdl-dhcom-picoitx.dtsi" + +/ { + model = "DH electronics i.MX6DL DHCOM on PicoITX"; + compatible = "dh,imx6dl-dhcom-picoitx", "dh,imx6dl-dhcom-som", +"fsl,imx6dl"; +}; diff --git a/arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi b/arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi new file mode 100644 index 00..4cd4cb9543 --- /dev/null +++ b/arch/arm/dts/imx6qdl-dhcom-picoitx.dtsi @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 DH electronics GmbH + */ + +#include + +/ { + chosen { + stdout-path = "serial0:115200n8"; + }; + + led { + compatible = "gpio-leds"; + + led-0 { + color = ; + default-state = "off"; + function = LED_FUNCTION_INDICATOR; + gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* GPIO I */ + pinctrl-0 = <&pinctrl_dhcom_i>; + pinctrl-names = "default"; + }; + }; +}; + +&gpio1 { + gpio-line-names = + "", "", "DHCOM-A", "", "DHCOM-B", "PicoITX-In2", "", "", + "", "", "", "", "", "", "", "", + "DHCOM-R", "DHCOM-S", "DHCOM-Q", "DHCOM-T", "DHCOM-U", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio4 { + gpio-line-names = + "", "", "", "", "", "PicoITX-In1", "DHCOM-INT", "DHCOM-H", + "DHCOM-I", "PicoITX-HW2", "", "", "", "", "", "", + "", "", "", "", "PicoITX-Out1", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&gpio6 { + gpio-line-names = + "", "", "", "PicoITX-Out2", "", "", "SOM-HW1", "", + "", "", "", "", "", "", "PicoITX-HW0", "PicoITX-HW1", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", ""; +}; + +&iomuxc { + pinctrl-0 = < + /* +* The following DHCOM GPIOs are used on this board. +* Therefore, they have been removed from the list below. +* I: yellow led +*/ + &pinctrl_hog_base +
[PATCH v2 5/8] ARM: dts: imx: Simplify fec node for iMX6QDL DHCOM boards
Firstly the FEC can now use the regulator reg_eth_vio from imx6qdl-dhcom-som.dtsi instead of defining its own. Secondly the &fec node is moved to the more generic SoM device tree file, because it can be used by multiple boards. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- Changes in v2: - Reviewed-by Marek arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi | 13 - arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi | 7 +++ 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi b/arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi index a1ffb1d6fc..0673c21e3c 100644 --- a/arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-dhcom-pdk2-u-boot.dtsi @@ -5,19 +5,6 @@ #include "imx6qdl-dhcom-u-boot.dtsi" -/ { - fec_vio: regulator-fec { - compatible = "regulator-fixed"; - - regulator-name = "fec-vio"; - gpio = <&gpio1 7 GPIO_ACTIVE_LOW>; - }; -}; - &fec { phy-reset-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>; - phy-reset-duration = <1>; - phy-reset-post-delay = <10>; - - phy-supply = <&fec_vio>; }; diff --git a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi index 91545ab6e9..190567ab7b 100644 --- a/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi +++ b/arch/arm/dts/imx6qdl-dhcom-u-boot.dtsi @@ -1,6 +1,7 @@ // SPDX-License-Identifier: (GPL-2.0+) /* * Copyright (C) 2020 Harald Seiler + * Copyright (C) 2022 Philip Oberfichtner */ / { @@ -9,6 +10,12 @@ }; }; +&fec { + phy-reset-duration = <1>; + phy-reset-post-delay = <10>; + phy-supply = <®_eth_vio>; +}; + &i2c3 { eeprom0: eeprom@50 { }; -- 2.34.1
[PATCH v2 4/8] ARM: imx6: Remove CONFIG_FEC_MXC_PHYADDR from DH header
Use phy address from device tree instead of CONFIG_FEC_MXC_PHYADDR from board header. This is required, because the DH picoITX and DRC02 boards require different settings than PDK2. The corresponding 'phy-handle' device tree properties are already there. I tested this change on picoITX and DRC02, but on PDK2 it is untested. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- (no changes since v1) include/configs/dh_imx6.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/configs/dh_imx6.h b/include/configs/dh_imx6.h index 2b14464dff..178f5a6e7d 100644 --- a/include/configs/dh_imx6.h +++ b/include/configs/dh_imx6.h @@ -30,9 +30,6 @@ /* Bootcounter */ #define CONFIG_SYS_BOOTCOUNT_BE -/* FEC ethernet */ -#define CONFIG_FEC_MXC_PHYADDR 7 - /* MMC Configs */ #define CONFIG_SYS_FSL_ESDHC_ADDR 0 #define CONFIG_SYS_FSL_USDHC_NUM 3 -- 2.34.1
[PATCH v2 7/8] ARM: dts: imx: Configure FEC for iMX6QDL DRC02
Add a u-boot dtsi for configuring the FEC node of the DH DRC02. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- Changes in v2: - Reviewed-by Marek arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi | 10 ++ 1 file changed, 10 insertions(+) create mode 100644 arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi diff --git a/arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi b/arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi new file mode 100644 index 00..16669b2533 --- /dev/null +++ b/arch/arm/dts/imx6s-dhcom-drc02-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0+) +/* + * Copyright (C) 2022 Philip Oberfichtner + */ + +#include "imx6qdl-dhcom-u-boot.dtsi" + +&fec { + phy-reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; +}; -- 2.34.1
[PATCH v2 6/8] ARM: dts: imx: Configure FEC for iMX6QDL picoITX
Add a u-boot dtsi for configuring the FEC node of the DH picoITX. Reviewed-by: Marek Vasut Signed-off-by: Philip Oberfichtner --- Changes in v2: - Reviewed-by Marek arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi | 10 ++ 1 file changed, 10 insertions(+) create mode 100644 arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi diff --git a/arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi b/arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi new file mode 100644 index 00..16669b2533 --- /dev/null +++ b/arch/arm/dts/imx6dl-dhcom-picoitx-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0+) +/* + * Copyright (C) 2022 Philip Oberfichtner + */ + +#include "imx6qdl-dhcom-u-boot.dtsi" + +&fec { + phy-reset-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; +}; -- 2.34.1
[PATCH v2 8/8] ARM: imx6: Adapt device tree selection in DH board file
Before this commit device tree selection could rely solely on differentiating the iMX6 processor variant Q and DL. After adding two new carrier boards, the DRC02 and the picoITX, the interchangeability of SoMs makes this approach infeasible. It is now required to specify the carrier board (dhcom-drc02, dhcom-picoitx or dhcom-pdk2) at compile time using CONFIG_DEFAULT_DEVICETREE. The SoM is determined at runtime as before. Signed-off-by: Philip Oberfichtner --- Changes in v2: - Rewrite board_fit_config_name_match - Return -EINVAL instead of -1 board/dhelectronics/dh_imx6/dh_imx6.c | 31 +-- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c index 6059f96e80..e8aba83e1a 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6.c +++ b/board/dhelectronics/dh_imx6/dh_imx6.c @@ -225,16 +225,35 @@ int checkboard(void) } #ifdef CONFIG_MULTI_DTB_FIT +static int strcmp_prefix(const char *s1, const char *s2) +{ + size_t n; + + n = min(strlen(s1), strlen(s2)); + return strncmp(s1, s2, n); +} + int board_fit_config_name_match(const char *name) { - if (is_mx6dq()) { - if (!strcmp(name, "imx6q-dhcom-pdk2")) - return 0; - } else if (is_mx6sdl()) { - if (!strcmp(name, "imx6dl-dhcom-pdk2")) + char *want; + char *have; + + /* Test Board suffix, e.g. -dhcom-drc02 */ + want = strchr(CONFIG_DEFAULT_DEVICE_TREE, '-'); + have = strchr(name, '-'); + + if (!want || !have || strcmp(want, have)) + return -EINVAL; + + /* Test SoC prefix */ + if (is_mx6dq() && !strcmp_prefix(name, "imx6q-")) + return 0; + + if (is_mx6sdl()) { + if (!strcmp_prefix(name, "imx6s-") || !strcmp_prefix(name, "imx6dl-")) return 0; } - return -1; + return -EINVAL; } #endif -- 2.34.1
[PATCH v2 0/4] Deduplicate dhelectronics board files
This series unifies common MAC address code for imx6, imx8 and stm32 based boards by DH. It is thought of as a starting point for more deduplication in the future. Changes in v2: - Tested-by Marek - convert to livetree (rebase on commit 5a605b7c86152) - Fix spelling Philip Oberfichtner (4): board: dhelectronics: Implement common MAC address functions ARM: imx6: DH: Use common MAC address functions ARM: imx8: DH: Use common MAC address functions ARM: stm32: DH: Use common MAC address functions board/dhelectronics/common/Makefile | 10 ++ board/dhelectronics/common/dh_common.c| 65 ++ board/dhelectronics/common/dh_common.h| 28 board/dhelectronics/common/dh_imx.c | 24 board/dhelectronics/common/dh_imx.h | 12 ++ board/dhelectronics/dh_imx6/dh_imx6.c | 47 ++- .../dh_imx8mp/imx8mp_dhcom_pdk2.c | 121 +++--- board/dhelectronics/dh_stm32mp1/board.c | 102 +++ 8 files changed, 246 insertions(+), 163 deletions(-) create mode 100644 board/dhelectronics/common/Makefile create mode 100644 board/dhelectronics/common/dh_common.c create mode 100644 board/dhelectronics/common/dh_common.h create mode 100644 board/dhelectronics/common/dh_imx.c create mode 100644 board/dhelectronics/common/dh_imx.h -- 2.35.3
[PATCH v2 1/4] board: dhelectronics: Implement common MAC address functions
This is a starting point for unifying duplicate code in the DH board files. The functions for setting up MAC addresses are very similar for the i.MX6, i.MX8 and stm32mp1 based boards. All pre-existing implementations follow the same logic: (1) Check if ethaddr is already set in the environment (2) If not, try to get it from a board specific location (e.g. fuse) (3) If not, try to get it from eeprom After this commit, (1) and (3) are implemented as common functions, ready to be used by board specific files. Furthermore there is an implementation of (2) for imx based boards. Signed-off-by: Philip Oberfichtner --- Changes in v2: - convert to livetree (rebase on commit 5a605b7c86152) board/dhelectronics/common/Makefile| 10 board/dhelectronics/common/dh_common.c | 65 ++ board/dhelectronics/common/dh_common.h | 28 +++ board/dhelectronics/common/dh_imx.c| 24 ++ board/dhelectronics/common/dh_imx.h| 12 + 5 files changed, 139 insertions(+) create mode 100644 board/dhelectronics/common/Makefile create mode 100644 board/dhelectronics/common/dh_common.c create mode 100644 board/dhelectronics/common/dh_common.h create mode 100644 board/dhelectronics/common/dh_imx.c create mode 100644 board/dhelectronics/common/dh_imx.h diff --git a/board/dhelectronics/common/Makefile b/board/dhelectronics/common/Makefile new file mode 100644 index 00..a472ea8d51 --- /dev/null +++ b/board/dhelectronics/common/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright 2022 DENX Software Engineering GmbH, Philip Oberfichtner +# + +obj-y += dh_common.o + +ifneq (,$(CONFIG_ARCH_MX6)$(CONFIG_ARCH_IMX8M)) +obj-y += dh_imx.o +endif diff --git a/board/dhelectronics/common/dh_common.c b/board/dhelectronics/common/dh_common.c new file mode 100644 index 00..67e3d59b1f --- /dev/null +++ b/board/dhelectronics/common/dh_common.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2022 Marek Vasut + * Copyright 2022 DENX Software Engineering GmbH, Philip Oberfichtner + */ + +#include +#include +#include +#include + +#include "dh_common.h" + +bool dh_mac_is_in_env(const char *env) +{ + unsigned char enetaddr[6]; + + return eth_env_get_enetaddr(env, enetaddr); +} + +int dh_get_mac_from_eeprom(unsigned char *enetaddr, const char *alias) +{ + struct udevice *dev; + int ret; + ofnode node; + + node = ofnode_path(alias); + if (!ofnode_valid(node)) { + printf("%s: ofnode for %s not found!", __func__, alias); + return -ENOENT; + } + + ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, node, &dev); + if (ret) { + printf("%s: Cannot find EEPROM! ret = %d\n", __func__, ret); + return ret; + } + + ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); + if (ret) { + printf("%s: Error reading EEPROM! ret = %d\n", __func__, ret); + return ret; + } + + if (!is_valid_ethaddr(enetaddr)) { + printf("%s: Address read from EEPROM is invalid!\n", __func__); + return -EINVAL; + } + + return 0; +} + +__weak int dh_setup_mac_address(void) +{ + unsigned char enetaddr[6]; + + if (dh_mac_is_in_env("ethaddr")) + return 0; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + return eth_env_set_enetaddr("ethaddr", enetaddr); + + printf("%s: Unable to set mac address!\n", __func__); + return -ENXIO; +} diff --git a/board/dhelectronics/common/dh_common.h b/board/dhelectronics/common/dh_common.h new file mode 100644 index 00..2b24637d96 --- /dev/null +++ b/board/dhelectronics/common/dh_common.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * Copyright 2022 DENX Software Engineering GmbH, Philip Oberfichtner + */ + +/* + * dh_mac_is_in_env - Check if MAC address is already set + * + * @env: name of environment variable + * Return: true if MAC is set, false otherwise + */ +bool dh_mac_is_in_env(const char *env); + +/* + * dh_get_mac_from_eeprom - Get MAC address from eeprom and write it to enetaddr + * + * @enetaddr: buffer where address is to be stored + * @alias: alias for EEPROM device tree node + * Return: 0 if OK, other value on error + */ +int dh_get_mac_from_eeprom(unsigned char *enetaddr, const char *alias); + +/* + * dh_setup_mac_address - Try to get MAC address from various locations and write it to env + * + * Return: 0 if OK, other value on error + */ +int dh_setup_mac_address(void); diff --git a/board/dhelectronics/common/dh_imx.c b/board/dhelectronics/common/dh_imx.c new file mode 100644 index 00..7f451bad59 --- /dev/null +++ b/board/dhelectronics/common/dh_imx.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0+
[PATCH v2 2/4] ARM: imx6: DH: Use common MAC address functions
To reduce code duplication, let the imx6 based DH boards use the common code for setting up their MAC addresses. Signed-off-by: Philip Oberfichtner Tested-by: Marek Vasut --- Changes in v2: - Tested-by Marek board/dhelectronics/dh_imx6/dh_imx6.c | 47 --- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c index e8aba83e1a..07fc9b1fe6 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6.c +++ b/board/dhelectronics/dh_imx6/dh_imx6.c @@ -36,6 +36,9 @@ #include #include +#include "../common/dh_common.h" +#include "../common/dh_imx.h" + DECLARE_GLOBAL_DATA_PTR; int dram_init(void) @@ -82,46 +85,24 @@ int board_usb_phy_mode(int port) } #endif -static int setup_dhcom_mac_from_fuse(void) +int dh_setup_mac_address(void) { - struct udevice *dev; - ofnode eeprom; unsigned char enetaddr[6]; - int ret; - ret = eth_env_get_enetaddr("ethaddr", enetaddr); - if (ret)/* ethaddr is already set */ + if (dh_mac_is_in_env("ethaddr")) return 0; - imx_get_mac_from_fuse(0, enetaddr); - - if (is_valid_ethaddr(enetaddr)) { - eth_env_set_enetaddr("ethaddr", enetaddr); - return 0; - } - - eeprom = ofnode_get_aliases_node("eeprom0"); - if (!ofnode_valid(eeprom)) { - printf("Can't find eeprom0 alias!\n"); - return -ENODEV; - } + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto out; - ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev); - if (ret) { - printf("Cannot find EEPROM!\n"); - return ret; - } + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto out; - ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); - if (ret) { - printf("Error reading configuration EEPROM!\n"); - return ret; - } + printf("%s: Unable to get MAC address!\n", __func__); + return -ENXIO; - if (is_valid_ethaddr(enetaddr)) - eth_env_set_enetaddr("ethaddr", enetaddr); - - return 0; +out: + return eth_env_set_enetaddr("ethaddr", enetaddr); } int board_early_init_f(void) @@ -188,7 +169,7 @@ int board_late_init(void) u32 hw_code; char buf[16]; - setup_dhcom_mac_from_fuse(); + dh_setup_mac_address(); hw_code = board_get_hwcode(); -- 2.35.3
[PATCH v2 3/4] ARM: imx8: DH: Use common MAC address functions
To reduce code duplication, let the imx8 based DH boards use the common code for setting up their MAC addresses. Signed-off-by: Philip Oberfichtner Tested-by: Marek Vasut --- Changes in v2: - Tested-by Marek .../dh_imx8mp/imx8mp_dhcom_pdk2.c | 121 +++--- 1 file changed, 48 insertions(+), 73 deletions(-) diff --git a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c index 8676c44d0d..6f06daf86f 100644 --- a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c +++ b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c @@ -16,6 +16,8 @@ #include #include "lpddr4_timing.h" +#include "../common/dh_common.h" +#include "../common/dh_imx.h" DECLARE_GLOBAL_DATA_PTR; @@ -75,95 +77,68 @@ static void setup_fec(void) set_clk_enet(ENET_125MHZ); } -static int setup_mac_address_from_eeprom(char *alias, char *env, bool odd) +static int dh_imx8_setup_ethaddr(void) { unsigned char enetaddr[6]; - struct udevice *dev; - int ret, offset; - - offset = fdt_path_offset(gd->fdt_blob, alias); - if (offset < 0) { - printf("%s: No eeprom0 path offset\n", __func__); - return offset; - } - - ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, offset, &dev); - if (ret) { - printf("Cannot find EEPROM!\n"); - return ret; - } - - ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); - if (ret) { - printf("Error reading configuration EEPROM!\n"); - return ret; - } + + if (dh_mac_is_in_env("ethaddr")) + return 0; + + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto out; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto out; + + return -ENXIO; + +out: + return eth_env_set_enetaddr("ethaddr", enetaddr); +} + +static int dh_imx8_setup_eth1addr(void) +{ + unsigned char enetaddr[6]; + + if (dh_mac_is_in_env("eth1addr")) + return 0; + + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto increment_out; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom1")) + goto out; /* * Populate second ethernet MAC from first ethernet EEPROM with MAC * address LSByte incremented by 1. This is only used on SoMs without * second ethernet EEPROM, i.e. early prototypes. */ - if (odd) - enetaddr[5]++; + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto increment_out; - eth_env_set_enetaddr(env, enetaddr); + return -ENXIO; - return 0; +increment_out: + enetaddr[5]++; + +out: + return eth_env_set_enetaddr("eth1addr", enetaddr); } -static void setup_mac_address(void) +int dh_setup_mac_address(void) { - unsigned char enetaddr[6]; - bool skip_eth0 = false; - bool skip_eth1 = false; int ret; - ret = eth_env_get_enetaddr("ethaddr", enetaddr); - if (ret)/* ethaddr is already set */ - skip_eth0 = true; - - ret = eth_env_get_enetaddr("eth1addr", enetaddr); - if (ret)/* eth1addr is already set */ - skip_eth1 = true; + ret = dh_imx8_setup_ethaddr(); + if (ret) + printf("%s: Unable to setup ethaddr! ret = %d\n", __func__, ret); - /* Both MAC addresses are already set in U-Boot environment. */ - if (skip_eth0 && skip_eth1) - return; + ret = dh_imx8_setup_eth1addr(); + if (ret) + printf("%s: Unable to setup eth1addr! ret = %d\n", __func__, ret); - /* -* If IIM fuses contain valid MAC address, use it. -* The IIM MAC address fuses are NOT programmed by default. -*/ - imx_get_mac_from_fuse(0, enetaddr); - if (is_valid_ethaddr(enetaddr)) { - if (!skip_eth0) - eth_env_set_enetaddr("ethaddr", enetaddr); - /* -* The LSbit of MAC address in fuses is always 0, use the -* next consecutive MAC address for the second ethernet. -*/ - enetaddr[5]++; - if (!skip_eth1) - eth_env_set_enetaddr("eth1addr", enetaddr); - return; - } - - /* Use on-SoM EEPROMs with pre-programmed MAC address. */ - if (!skip_eth0) { - /* We cannot do much more if this returns -ve . */ - setup_mac_address_from_eeprom("eeprom0", "ethaddr", false); - } - - if (!skip_eth1) { - ret = setup_mac_address_from_eeprom(
[PATCH v2 4/4] ARM: stm32: DH: Use common MAC address functions
To reduce code duplication, let the stm32 based DH boards use the common code for setting up their MAC addresses. Signed-off-by: Philip Oberfichtner Tested-by: Marek Vasut --- Changes in v2: - convert to livetree (rebase on commit 5a605b7c86152) - Tested-by Marek board/dhelectronics/dh_stm32mp1/board.c | 102 +++- 1 file changed, 45 insertions(+), 57 deletions(-) diff --git a/board/dhelectronics/dh_stm32mp1/board.c b/board/dhelectronics/dh_stm32mp1/board.c index 7a4c08cb7f..ab354e3e33 100644 --- a/board/dhelectronics/dh_stm32mp1/board.c +++ b/board/dhelectronics/dh_stm32mp1/board.c @@ -42,6 +42,7 @@ #include #include #include +#include "../common/dh_common.h" #include "../../st/common/stpmic1.h" /* SYSCFG registers */ @@ -84,36 +85,17 @@ #define KS_CIDER 0xC0 #define CIDER_ID 0x8870 -int setup_mac_address(void) +static bool dh_stm32_mac_is_in_ks8851(void) { - unsigned char enetaddr[6]; - bool skip_eth0 = false; - bool skip_eth1 = false; - struct udevice *dev; - int ret; ofnode node; - - ret = eth_env_get_enetaddr("ethaddr", enetaddr); - if (ret)/* ethaddr is already set */ - skip_eth0 = true; + u32 reg, cider, ccr; node = ofnode_path("ethernet1"); - if (!ofnode_valid(node)) { - /* ethernet1 is not present in the system */ - skip_eth1 = true; - goto out_set_ethaddr; - } + if (!ofnode_valid(node)) + return false; - ret = eth_env_get_enetaddr("eth1addr", enetaddr); - if (ret) { - /* eth1addr is already set */ - skip_eth1 = true; - goto out_set_ethaddr; - } - - ret = ofnode_device_is_compatible(node, "micrel,ks8851-mll"); - if (ret) - goto out_set_ethaddr; + if (ofnode_device_is_compatible(node, "micrel,ks8851-mll")) + return false; /* * KS8851 with EEPROM may use custom MAC from EEPROM, read @@ -121,56 +103,62 @@ int setup_mac_address(void) * is present. If EEPROM is present, it must contain valid * MAC address. */ - u32 reg, cider, ccr; reg = ofnode_get_addr(node); if (!reg) - goto out_set_ethaddr; + return false; writew(KS_BE0 | KS_BE1 | KS_CIDER, reg + 2); cider = readw(reg); - if ((cider & 0xfff0) != CIDER_ID) { - skip_eth1 = true; - goto out_set_ethaddr; - } + if ((cider & 0xfff0) != CIDER_ID) + return true; writew(KS_BE0 | KS_BE1 | KS_CCR, reg + 2); ccr = readw(reg); - if (ccr & KS_CCR_EEPROM) { - skip_eth1 = true; - goto out_set_ethaddr; - } + if (ccr & KS_CCR_EEPROM) + return true; + + return false; +} -out_set_ethaddr: - if (skip_eth0 && skip_eth1) +static int dh_stm32_setup_ethaddr(void) +{ + unsigned char enetaddr[6]; + + if (dh_mac_is_in_env("ethaddr")) return 0; - node = ofnode_path("eeprom0"); - if (!ofnode_valid(node)) { - printf("%s: No eeprom0 path offset\n", __func__); - return -ENOENT; - } + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + return eth_env_set_enetaddr("ethaddr", enetaddr); - ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, node, &dev); - if (ret) { - printf("Cannot find EEPROM!\n"); - return ret; - } + return -ENXIO; +} - ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); - if (ret) { - printf("Error reading configuration EEPROM!\n"); - return ret; - } +static int dh_stm32_setup_eth1addr(void) +{ + unsigned char enetaddr[6]; - if (is_valid_ethaddr(enetaddr)) { - if (!skip_eth0) - eth_env_set_enetaddr("ethaddr", enetaddr); + if (dh_mac_is_in_env("eth1addr")) + return 0; + if (dh_stm32_mac_is_in_ks8851()) + return 0; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) { enetaddr[5]++; - if (!skip_eth1) - eth_env_set_enetaddr("eth1addr", enetaddr); + return eth_env_set_enetaddr("eth1addr", enetaddr); } + return -ENXIO; +} + +int setup_mac_address(void) +{ + if (dh_stm32_setup_ethaddr()) + printf("%s: Unable to setup ethaddr!\n", __func__); + + if (dh_stm32_setup_eth1addr()) + printf("%s: Unable to setup eth1addr!\n", __func__); + return 0; } -- 2.35.3
[PATCH v3 0/4] Deduplicate dhelectronics board files
This series unifies common MAC address code for imx6, imx8 and stm32 based boards by DH. It is thought of as a starting point for more deduplication in the future. Changes in v3: - Entire series reviewed by Marek Changes in v2: - Tested-by Marek - convert to livetree (rebase on commit 5a605b7c86152) - Fix spelling Philip Oberfichtner (4): board: dhelectronics: Implement common MAC address functions ARM: imx6: DH: Use common MAC address functions ARM: imx8: DH: Use common MAC address functions ARM: stm32: DH: Use common MAC address functions board/dhelectronics/common/Makefile | 10 ++ board/dhelectronics/common/dh_common.c| 65 ++ board/dhelectronics/common/dh_common.h| 28 board/dhelectronics/common/dh_imx.c | 24 board/dhelectronics/common/dh_imx.h | 12 ++ board/dhelectronics/dh_imx6/dh_imx6.c | 47 ++- .../dh_imx8mp/imx8mp_dhcom_pdk2.c | 121 +++--- board/dhelectronics/dh_stm32mp1/board.c | 102 +++ 8 files changed, 246 insertions(+), 163 deletions(-) create mode 100644 board/dhelectronics/common/Makefile create mode 100644 board/dhelectronics/common/dh_common.c create mode 100644 board/dhelectronics/common/dh_common.h create mode 100644 board/dhelectronics/common/dh_imx.c create mode 100644 board/dhelectronics/common/dh_imx.h -- 2.37.1
[PATCH v3 2/4] ARM: imx6: DH: Use common MAC address functions
To reduce code duplication, let the imx6 based DH boards use the common code for setting up their MAC addresses. Signed-off-by: Philip Oberfichtner Tested-by: Marek Vasut Reviewed-by: Marek Vasut --- Changes in v3: - Reviewed by Marek Changes in v2: - Tested-by Marek board/dhelectronics/dh_imx6/dh_imx6.c | 47 --- 1 file changed, 14 insertions(+), 33 deletions(-) diff --git a/board/dhelectronics/dh_imx6/dh_imx6.c b/board/dhelectronics/dh_imx6/dh_imx6.c index e8aba83e1a..07fc9b1fe6 100644 --- a/board/dhelectronics/dh_imx6/dh_imx6.c +++ b/board/dhelectronics/dh_imx6/dh_imx6.c @@ -36,6 +36,9 @@ #include #include +#include "../common/dh_common.h" +#include "../common/dh_imx.h" + DECLARE_GLOBAL_DATA_PTR; int dram_init(void) @@ -82,46 +85,24 @@ int board_usb_phy_mode(int port) } #endif -static int setup_dhcom_mac_from_fuse(void) +int dh_setup_mac_address(void) { - struct udevice *dev; - ofnode eeprom; unsigned char enetaddr[6]; - int ret; - ret = eth_env_get_enetaddr("ethaddr", enetaddr); - if (ret)/* ethaddr is already set */ + if (dh_mac_is_in_env("ethaddr")) return 0; - imx_get_mac_from_fuse(0, enetaddr); - - if (is_valid_ethaddr(enetaddr)) { - eth_env_set_enetaddr("ethaddr", enetaddr); - return 0; - } - - eeprom = ofnode_get_aliases_node("eeprom0"); - if (!ofnode_valid(eeprom)) { - printf("Can't find eeprom0 alias!\n"); - return -ENODEV; - } + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto out; - ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev); - if (ret) { - printf("Cannot find EEPROM!\n"); - return ret; - } + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto out; - ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); - if (ret) { - printf("Error reading configuration EEPROM!\n"); - return ret; - } + printf("%s: Unable to get MAC address!\n", __func__); + return -ENXIO; - if (is_valid_ethaddr(enetaddr)) - eth_env_set_enetaddr("ethaddr", enetaddr); - - return 0; +out: + return eth_env_set_enetaddr("ethaddr", enetaddr); } int board_early_init_f(void) @@ -188,7 +169,7 @@ int board_late_init(void) u32 hw_code; char buf[16]; - setup_dhcom_mac_from_fuse(); + dh_setup_mac_address(); hw_code = board_get_hwcode(); -- 2.37.1
[PATCH v3 3/4] ARM: imx8: DH: Use common MAC address functions
To reduce code duplication, let the imx8 based DH boards use the common code for setting up their MAC addresses. Signed-off-by: Philip Oberfichtner Tested-by: Marek Vasut Reviewed-by: Marek Vasut --- Changes in v3: - Reviewed by Marek Changes in v2: - Tested-by Marek .../dh_imx8mp/imx8mp_dhcom_pdk2.c | 121 +++--- 1 file changed, 48 insertions(+), 73 deletions(-) diff --git a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c index 8676c44d0d..6f06daf86f 100644 --- a/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c +++ b/board/dhelectronics/dh_imx8mp/imx8mp_dhcom_pdk2.c @@ -16,6 +16,8 @@ #include #include "lpddr4_timing.h" +#include "../common/dh_common.h" +#include "../common/dh_imx.h" DECLARE_GLOBAL_DATA_PTR; @@ -75,95 +77,68 @@ static void setup_fec(void) set_clk_enet(ENET_125MHZ); } -static int setup_mac_address_from_eeprom(char *alias, char *env, bool odd) +static int dh_imx8_setup_ethaddr(void) { unsigned char enetaddr[6]; - struct udevice *dev; - int ret, offset; - - offset = fdt_path_offset(gd->fdt_blob, alias); - if (offset < 0) { - printf("%s: No eeprom0 path offset\n", __func__); - return offset; - } - - ret = uclass_get_device_by_of_offset(UCLASS_I2C_EEPROM, offset, &dev); - if (ret) { - printf("Cannot find EEPROM!\n"); - return ret; - } - - ret = i2c_eeprom_read(dev, 0xfa, enetaddr, 0x6); - if (ret) { - printf("Error reading configuration EEPROM!\n"); - return ret; - } + + if (dh_mac_is_in_env("ethaddr")) + return 0; + + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto out; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto out; + + return -ENXIO; + +out: + return eth_env_set_enetaddr("ethaddr", enetaddr); +} + +static int dh_imx8_setup_eth1addr(void) +{ + unsigned char enetaddr[6]; + + if (dh_mac_is_in_env("eth1addr")) + return 0; + + if (!dh_imx_get_mac_from_fuse(enetaddr)) + goto increment_out; + + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom1")) + goto out; /* * Populate second ethernet MAC from first ethernet EEPROM with MAC * address LSByte incremented by 1. This is only used on SoMs without * second ethernet EEPROM, i.e. early prototypes. */ - if (odd) - enetaddr[5]++; + if (!dh_get_mac_from_eeprom(enetaddr, "eeprom0")) + goto increment_out; - eth_env_set_enetaddr(env, enetaddr); + return -ENXIO; - return 0; +increment_out: + enetaddr[5]++; + +out: + return eth_env_set_enetaddr("eth1addr", enetaddr); } -static void setup_mac_address(void) +int dh_setup_mac_address(void) { - unsigned char enetaddr[6]; - bool skip_eth0 = false; - bool skip_eth1 = false; int ret; - ret = eth_env_get_enetaddr("ethaddr", enetaddr); - if (ret)/* ethaddr is already set */ - skip_eth0 = true; - - ret = eth_env_get_enetaddr("eth1addr", enetaddr); - if (ret)/* eth1addr is already set */ - skip_eth1 = true; + ret = dh_imx8_setup_ethaddr(); + if (ret) + printf("%s: Unable to setup ethaddr! ret = %d\n", __func__, ret); - /* Both MAC addresses are already set in U-Boot environment. */ - if (skip_eth0 && skip_eth1) - return; + ret = dh_imx8_setup_eth1addr(); + if (ret) + printf("%s: Unable to setup eth1addr! ret = %d\n", __func__, ret); - /* -* If IIM fuses contain valid MAC address, use it. -* The IIM MAC address fuses are NOT programmed by default. -*/ - imx_get_mac_from_fuse(0, enetaddr); - if (is_valid_ethaddr(enetaddr)) { - if (!skip_eth0) - eth_env_set_enetaddr("ethaddr", enetaddr); - /* -* The LSbit of MAC address in fuses is always 0, use the -* next consecutive MAC address for the second ethernet. -*/ - enetaddr[5]++; - if (!skip_eth1) - eth_env_set_enetaddr("eth1addr", enetaddr); - return; - } - - /* Use on-SoM EEPROMs with pre-programmed MAC address. */ - if (!skip_eth0) { - /* We cannot do much more if this returns -ve . */ - setup_mac_address_from_eeprom("eeprom0", "ethaddr", false); - } - -