Update and fixes for sl28, lx2, pblimage generation for some powerpc products
This commit is contained in:
		
						commit
						705b5840cd
					
				| 
						 | 
					@ -1161,6 +1161,13 @@ S:	Maintained
 | 
				
			||||||
T:	git https://source.denx.de/u-boot/custodians/u-boot-sh.git
 | 
					T:	git https://source.denx.de/u-boot/custodians/u-boot-sh.git
 | 
				
			||||||
F:	arch/sh/
 | 
					F:	arch/sh/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SL28CLPD
 | 
				
			||||||
 | 
					M:	Michael Walle <michael@walle.cc>
 | 
				
			||||||
 | 
					S:	Maintained
 | 
				
			||||||
 | 
					F:	drivers/gpio/sl28cpld-gpio.c
 | 
				
			||||||
 | 
					F:	drivers/misc/sl28cpld.c
 | 
				
			||||||
 | 
					F:	drivers/watchdog/sl28cpld-wdt.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SPI
 | 
					SPI
 | 
				
			||||||
M:	Jagan Teki <jagan@amarulasolutions.com>
 | 
					M:	Jagan Teki <jagan@amarulasolutions.com>
 | 
				
			||||||
S:	Maintained
 | 
					S:	Maintained
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								Makefile
								
								
								
								
							| 
						 | 
					@ -1411,7 +1411,7 @@ MKIMAGEFLAGS_u-boot-spl.kwb = -n $(KWD_CONFIG_FILE) \
 | 
				
			||||||
	$(if $(KEYDIR),-k $(KEYDIR))
 | 
						$(if $(KEYDIR),-k $(KEYDIR))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
 | 
					MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
 | 
				
			||||||
		-R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage
 | 
							-R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -A $(ARCH) -T pblimage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(CONFIG_MPC85xx)$(CONFIG_OF_SEPARATE),yy)
 | 
					ifeq ($(CONFIG_MPC85xx)$(CONFIG_OF_SEPARATE),yy)
 | 
				
			||||||
UBOOT_BIN := u-boot-with-dtb.bin
 | 
					UBOOT_BIN := u-boot-with-dtb.bin
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@
 | 
				
			||||||
		fit {
 | 
							fit {
 | 
				
			||||||
			offset = <CONFIG_SPL_PAD_TO>;
 | 
								offset = <CONFIG_SPL_PAD_TO>;
 | 
				
			||||||
			description = "FIT image with multiple configurations";
 | 
								description = "FIT image with multiple configurations";
 | 
				
			||||||
 | 
								fit,fdt-list = "of-list";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			images {
 | 
								images {
 | 
				
			||||||
				uboot {
 | 
									uboot {
 | 
				
			||||||
| 
						 | 
					@ -41,95 +42,20 @@
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				fdt-1 {
 | 
									@fdt-SEQ {
 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28";
 | 
										description = "NAME";
 | 
				
			||||||
					type = "flat_dt";
 | 
										type = "flat_dt";
 | 
				
			||||||
					arch = "arm";
 | 
					 | 
				
			||||||
					compression = "none";
 | 
										compression = "none";
 | 
				
			||||||
 | 
					 | 
				
			||||||
					blob {
 | 
					 | 
				
			||||||
						filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28.dtb";
 | 
					 | 
				
			||||||
					};
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				fdt-2 {
 | 
					 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28-var1";
 | 
					 | 
				
			||||||
					type = "flat_dt";
 | 
					 | 
				
			||||||
					arch = "arm";
 | 
					 | 
				
			||||||
					compression = "none";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					blob {
 | 
					 | 
				
			||||||
						filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28-var1.dtb";
 | 
					 | 
				
			||||||
					};
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				fdt-3 {
 | 
					 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28-var2";
 | 
					 | 
				
			||||||
					type = "flat_dt";
 | 
					 | 
				
			||||||
					arch = "arm";
 | 
					 | 
				
			||||||
					compression = "none";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					blob {
 | 
					 | 
				
			||||||
						filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28-var2.dtb";
 | 
					 | 
				
			||||||
					};
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				fdt-4 {
 | 
					 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28-var3";
 | 
					 | 
				
			||||||
					type = "flat_dt";
 | 
					 | 
				
			||||||
					arch = "arm";
 | 
					 | 
				
			||||||
					compression = "none";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					blob {
 | 
					 | 
				
			||||||
						filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28-var3.dtb";
 | 
					 | 
				
			||||||
					};
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				fdt-5 {
 | 
					 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28-var4";
 | 
					 | 
				
			||||||
					type = "flat_dt";
 | 
					 | 
				
			||||||
					arch = "arm";
 | 
					 | 
				
			||||||
					compression = "none";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					blob {
 | 
					 | 
				
			||||||
						filename = "arch/arm/dts/fsl-ls1028a-kontron-sl28-var4.dtb";
 | 
					 | 
				
			||||||
					};
 | 
					 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			configurations {
 | 
								configurations {
 | 
				
			||||||
				default = "conf-1";
 | 
									default = "@config-DEFAULT-SEQ";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				conf-1 {
 | 
									@config-SEQ {
 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28";
 | 
										description = "NAME";
 | 
				
			||||||
					firmware = "uboot";
 | 
										firmware = "uboot";
 | 
				
			||||||
					fdt = "fdt-1";
 | 
										fdt = "fdt-SEQ";
 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				conf-2 {
 | 
					 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28-var1";
 | 
					 | 
				
			||||||
					firmware = "uboot";
 | 
					 | 
				
			||||||
					fdt = "fdt-2";
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				conf-3 {
 | 
					 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28-var2";
 | 
					 | 
				
			||||||
					firmware = "uboot";
 | 
					 | 
				
			||||||
					fdt = "fdt-3";
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				conf-4 {
 | 
					 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28-var3";
 | 
					 | 
				
			||||||
					firmware = "uboot";
 | 
					 | 
				
			||||||
					loadables = "uboot";
 | 
					 | 
				
			||||||
					fdt = "fdt-4";
 | 
					 | 
				
			||||||
				};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				conf-5 {
 | 
					 | 
				
			||||||
					description = "fsl-ls1028a-kontron-sl28-var4";
 | 
					 | 
				
			||||||
					firmware = "uboot";
 | 
					 | 
				
			||||||
					loadables = "uboot";
 | 
					 | 
				
			||||||
					fdt = "fdt-5";
 | 
					 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
| 
						 | 
					@ -189,27 +115,7 @@
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		configurations {
 | 
							configurations {
 | 
				
			||||||
			conf-1 {
 | 
								@config-SEQ {
 | 
				
			||||||
				firmware = "bl31";
 | 
					 | 
				
			||||||
				loadables = "uboot";
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			conf-2 {
 | 
					 | 
				
			||||||
				firmware = "bl31";
 | 
					 | 
				
			||||||
				loadables = "uboot";
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			conf-3 {
 | 
					 | 
				
			||||||
				firmware = "bl31";
 | 
					 | 
				
			||||||
				loadables = "uboot";
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			conf-4 {
 | 
					 | 
				
			||||||
				firmware = "bl31";
 | 
					 | 
				
			||||||
				loadables = "uboot";
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			conf-5 {
 | 
					 | 
				
			||||||
				firmware = "bl31";
 | 
									firmware = "bl31";
 | 
				
			||||||
				loadables = "uboot";
 | 
									loadables = "uboot";
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
| 
						 | 
					@ -238,23 +144,7 @@
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		configurations {
 | 
							configurations {
 | 
				
			||||||
			conf-1 {
 | 
								@config-SEQ {
 | 
				
			||||||
				loadables = "uboot", "bl32";
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			conf-2 {
 | 
					 | 
				
			||||||
				loadables = "uboot", "bl32";
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			conf-3 {
 | 
					 | 
				
			||||||
				loadables = "uboot", "bl32";
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			conf-4 {
 | 
					 | 
				
			||||||
				loadables = "uboot", "bl32";
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			conf-5 {
 | 
					 | 
				
			||||||
				loadables = "uboot", "bl32";
 | 
									loadables = "uboot", "bl32";
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
// SPDX-License-Identifier: GPL-2.0+
 | 
					// SPDX-License-Identifier: GPL-2.0+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <common.h>
 | 
					#include <common.h>
 | 
				
			||||||
 | 
					#include <dm.h>
 | 
				
			||||||
#include <malloc.h>
 | 
					#include <malloc.h>
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <fsl_ddr.h>
 | 
					#include <fsl_ddr.h>
 | 
				
			||||||
| 
						 | 
					@ -14,7 +15,9 @@
 | 
				
			||||||
#include <asm/arch/soc.h>
 | 
					#include <asm/arch/soc.h>
 | 
				
			||||||
#include <fsl_immap.h>
 | 
					#include <fsl_immap.h>
 | 
				
			||||||
#include <netdev.h>
 | 
					#include <netdev.h>
 | 
				
			||||||
 | 
					#include <wdt.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <sl28cpld.h>
 | 
				
			||||||
#include <fdtdec.h>
 | 
					#include <fdtdec.h>
 | 
				
			||||||
#include <miiphy.h>
 | 
					#include <miiphy.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,16 +42,68 @@ int board_eth_init(struct bd_info *bis)
 | 
				
			||||||
	return pci_eth_init(bis);
 | 
						return pci_eth_init(bis);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int __sl28cpld_read(uint reg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct udevice *dev;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = uclass_get_device_by_driver(UCLASS_NOP,
 | 
				
			||||||
 | 
										  DM_DRIVER_GET(sl28cpld), &dev);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sl28cpld_read(dev, reg);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void print_cpld_version(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int version = __sl28cpld_read(SL28CPLD_VERSION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (version < 0)
 | 
				
			||||||
 | 
							printf("CPLD:  error reading version (%d)\n", version);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							printf("CPLD:  v%d\n", version);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int checkboard(void)
 | 
					int checkboard(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	printf("EL:    %d\n", current_el());
 | 
						printf("EL:    %d\n", current_el());
 | 
				
			||||||
 | 
						if (CONFIG_IS_ENABLED(SL28CPLD))
 | 
				
			||||||
 | 
							print_cpld_version();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void stop_recovery_watchdog(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct udevice *dev;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = uclass_get_device_by_driver(UCLASS_WDT,
 | 
				
			||||||
 | 
										  DM_DRIVER_GET(sl28cpld_wdt), &dev);
 | 
				
			||||||
 | 
						if (!ret)
 | 
				
			||||||
 | 
							wdt_stop(dev);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int fsl_board_late_init(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Usually, the after a board reset, the watchdog is enabled by
 | 
				
			||||||
 | 
						 * default. This is to supervise the bootloader boot-up. Therefore,
 | 
				
			||||||
 | 
						 * to prevent a watchdog reset if we don't actively kick it, we have
 | 
				
			||||||
 | 
						 * to disable it.
 | 
				
			||||||
 | 
						 *
 | 
				
			||||||
 | 
						 * If the watchdog isn't enabled at reset (which is a configuration
 | 
				
			||||||
 | 
						 * option) disabling it doesn't hurt either.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (!CONFIG_IS_ENABLED(WATCHDOG_AUTOSTART))
 | 
				
			||||||
 | 
							stop_recovery_watchdog();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void detail_board_ddr_info(void)
 | 
					void detail_board_ddr_info(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	puts("\nDDR    ");
 | 
					 | 
				
			||||||
	print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
 | 
					 | 
				
			||||||
	print_ddr_info(0);
 | 
						print_ddr_info(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,23 +42,23 @@ CONFIG_CMD_GREPENV=y
 | 
				
			||||||
CONFIG_CMD_NVEDIT_EFI=y
 | 
					CONFIG_CMD_NVEDIT_EFI=y
 | 
				
			||||||
CONFIG_CMD_DFU=y
 | 
					CONFIG_CMD_DFU=y
 | 
				
			||||||
CONFIG_CMD_DM=y
 | 
					CONFIG_CMD_DM=y
 | 
				
			||||||
 | 
					CONFIG_CMD_GPIO=y
 | 
				
			||||||
CONFIG_CMD_GPT=y
 | 
					CONFIG_CMD_GPT=y
 | 
				
			||||||
CONFIG_CMD_I2C=y
 | 
					CONFIG_CMD_I2C=y
 | 
				
			||||||
CONFIG_CMD_MMC=y
 | 
					CONFIG_CMD_MMC=y
 | 
				
			||||||
CONFIG_CMD_PCI=y
 | 
					CONFIG_CMD_PCI=y
 | 
				
			||||||
CONFIG_CMD_USB=y
 | 
					CONFIG_CMD_USB=y
 | 
				
			||||||
CONFIG_CMD_USB_MASS_STORAGE=y
 | 
					CONFIG_CMD_USB_MASS_STORAGE=y
 | 
				
			||||||
 | 
					CONFIG_CMD_WDT=y
 | 
				
			||||||
CONFIG_CMD_CACHE=y
 | 
					CONFIG_CMD_CACHE=y
 | 
				
			||||||
CONFIG_CMD_EFIDEBUG=y
 | 
					CONFIG_CMD_EFIDEBUG=y
 | 
				
			||||||
CONFIG_CMD_RNG=y
 | 
					CONFIG_CMD_RNG=y
 | 
				
			||||||
CONFIG_OF_CONTROL=y
 | 
					CONFIG_OF_CONTROL=y
 | 
				
			||||||
CONFIG_SPL_OF_CONTROL=y
 | 
					CONFIG_SPL_OF_CONTROL=y
 | 
				
			||||||
CONFIG_OF_LIST=""
 | 
					CONFIG_OF_LIST="fsl-ls1028a-kontron-sl28 fsl-ls1028a-kontron-sl28-var1 fsl-ls1028a-kontron-sl28-var2 fsl-ls1028a-kontron-sl28-var3 fsl-ls1028a-kontron-sl28-var4"
 | 
				
			||||||
CONFIG_ENV_OVERWRITE=y
 | 
					CONFIG_ENV_OVERWRITE=y
 | 
				
			||||||
CONFIG_ENV_IS_IN_SPI_FLASH=y
 | 
					CONFIG_ENV_IS_IN_SPI_FLASH=y
 | 
				
			||||||
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 | 
					CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 | 
				
			||||||
CONFIG_NET_RANDOM_ETHADDR=y
 | 
					 | 
				
			||||||
CONFIG_NETCONSOLE=y
 | 
					 | 
				
			||||||
CONFIG_SPL_DM_SEQ_ALIAS=y
 | 
					CONFIG_SPL_DM_SEQ_ALIAS=y
 | 
				
			||||||
CONFIG_SATA=y
 | 
					CONFIG_SATA=y
 | 
				
			||||||
CONFIG_SCSI_AHCI=y
 | 
					CONFIG_SCSI_AHCI=y
 | 
				
			||||||
| 
						 | 
					@ -69,8 +69,10 @@ CONFIG_DDR_ECC=y
 | 
				
			||||||
CONFIG_ECC_INIT_VIA_DDRCONTROLLER=y
 | 
					CONFIG_ECC_INIT_VIA_DDRCONTROLLER=y
 | 
				
			||||||
CONFIG_DFU_MMC=y
 | 
					CONFIG_DFU_MMC=y
 | 
				
			||||||
CONFIG_DFU_SF=y
 | 
					CONFIG_DFU_SF=y
 | 
				
			||||||
 | 
					CONFIG_SL28CPLD_GPIO=y
 | 
				
			||||||
CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 | 
					CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 | 
				
			||||||
CONFIG_I2C_MUX=y
 | 
					CONFIG_I2C_MUX=y
 | 
				
			||||||
 | 
					CONFIG_SL28CPLD=y
 | 
				
			||||||
CONFIG_MMC_HS400_SUPPORT=y
 | 
					CONFIG_MMC_HS400_SUPPORT=y
 | 
				
			||||||
CONFIG_FSL_ESDHC=y
 | 
					CONFIG_FSL_ESDHC=y
 | 
				
			||||||
CONFIG_FSL_ESDHC_SUPPORT_ADMA2=y
 | 
					CONFIG_FSL_ESDHC_SUPPORT_ADMA2=y
 | 
				
			||||||
| 
						 | 
					@ -102,6 +104,11 @@ CONFIG_USB_DWC3=y
 | 
				
			||||||
CONFIG_USB_DWC3_LAYERSCAPE=y
 | 
					CONFIG_USB_DWC3_LAYERSCAPE=y
 | 
				
			||||||
CONFIG_USB_GADGET=y
 | 
					CONFIG_USB_GADGET=y
 | 
				
			||||||
CONFIG_USB_GADGET_DOWNLOAD=y
 | 
					CONFIG_USB_GADGET_DOWNLOAD=y
 | 
				
			||||||
 | 
					# CONFIG_WATCHDOG is not set
 | 
				
			||||||
 | 
					# CONFIG_WATCHDOG_AUTOSTART is not set
 | 
				
			||||||
 | 
					CONFIG_WDT=y
 | 
				
			||||||
 | 
					CONFIG_WDT_SL28CPLD=y
 | 
				
			||||||
 | 
					CONFIG_WDT_SP805=y
 | 
				
			||||||
CONFIG_OF_LIBFDT_ASSUME_MASK=0x0
 | 
					CONFIG_OF_LIBFDT_ASSUME_MASK=0x0
 | 
				
			||||||
CONFIG_OF_LIBFDT_OVERLAY=y
 | 
					CONFIG_OF_LIBFDT_OVERLAY=y
 | 
				
			||||||
CONFIG_EFI_SET_TIME=y
 | 
					CONFIG_EFI_SET_TIME=y
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,34 +23,17 @@ Copy u-boot.rom to a TFTP server.
 | 
				
			||||||
Install the bootloader on the board
 | 
					Install the bootloader on the board
 | 
				
			||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
					^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Please note, this bootloader doesn't support the builtin watchdog (yet),
 | 
					To install the bootloader binary use the following command::
 | 
				
			||||||
therefore you have to disable it, see below. Otherwise you'll end up in
 | 
					 | 
				
			||||||
the failsafe bootloader on every reset::
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 > tftp path/to/u-boot.rom
 | 
					 > tftp path/to/u-boot.rom
 | 
				
			||||||
 > sf probe 0
 | 
					 > sf probe 0
 | 
				
			||||||
 > sf update $fileaddr 0x210000 $filesize
 | 
					 > sf update $fileaddr 0x210000 $filesize
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The board is fully failsafe, you can't break anything. But because you've
 | 
					The board is fully failsafe, you can't break anything. If builtin watchdog
 | 
				
			||||||
disabled the builtin watchdog you might have to manually enter failsafe
 | 
					is enabled, you'll automatically end up in the failsafe bootloader if
 | 
				
			||||||
mode by asserting the ``FORCE_RECOV#`` line during board reset.
 | 
					something goes wrong. If the watchdog is disabled, you have to manually
 | 
				
			||||||
 | 
					enter failsafe mode by asserting the ``FORCE_RECOV#`` line during board
 | 
				
			||||||
Disable the builtin watchdog
 | 
					reset.
 | 
				
			||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- boot into the failsafe bootloader, either by asserting the
 | 
					 | 
				
			||||||
  ``FORCE_RECOV#`` line or if you still have the original bootloader
 | 
					 | 
				
			||||||
  installed you can use the command::
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  > wdt dev cpld_watchdog@4a; wdt expire 1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- in the failsafe bootloader use the "sl28 nvm" command to disable
 | 
					 | 
				
			||||||
  the automatic start of the builtin watchdog::
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  > sl28 nvm 0008
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
- power-cycle the board
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Update image
 | 
					Update image
 | 
				
			||||||
------------
 | 
					------------
 | 
				
			||||||
| 
						 | 
					@ -67,20 +50,41 @@ Afterward you can copy this file to your ESP into the /EFI/UpdateCapsule/
 | 
				
			||||||
folder. On the next EFI boot this will automatically update your
 | 
					folder. On the next EFI boot this will automatically update your
 | 
				
			||||||
bootloader.
 | 
					bootloader.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Useful I2C tricks
 | 
					Builtin watchdog
 | 
				
			||||||
-----------------
 | 
					----------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The board has a board management controller which is not supported in
 | 
					The builtin watchdog will supervise the bootloader startup. If anything
 | 
				
			||||||
u-boot (yet). But you can use the i2c command to access it.
 | 
					goes wrong it will reset the board and boot into the failsafe bootloader.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- reset into failsafe bootloader::
 | 
					Once the bootloader is started successfully, it will disable the watchdog
 | 
				
			||||||
 | 
					timer.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  > i2c mw 4a 5.1 0; i2c mw 4a 6.1 6b; i2c mw 4a 4.1 42
 | 
					wdt command flags
 | 
				
			||||||
 | 
					^^^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- read board management controller version::
 | 
					The `wdt start` as well as the `wdt expire` command take a flags argument.
 | 
				
			||||||
 | 
					The supported bitmask is as follows.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  > i2c md 4a 3.1 1
 | 
					| Bit | Description                   |
 | 
				
			||||||
 | 
					| --- | ----------------------------- |
 | 
				
			||||||
 | 
					|   0 | Enable failsafe mode          |
 | 
				
			||||||
 | 
					|   1 | Lock the control register     |
 | 
				
			||||||
 | 
					|   2 | Disable board reset           |
 | 
				
			||||||
 | 
					|   3 | Enable WDT_TIME_OUT# line     |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, you can use `wdt expire 1` to issue a reset and boot into the
 | 
				
			||||||
 | 
					failsafe bootloader.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Disable the builtin watchdog
 | 
				
			||||||
 | 
					^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If for some reason, this isn't a desired behavior, the watchdog can also
 | 
				
			||||||
 | 
					be configured to not be enabled on board reset. It's configuration is saved
 | 
				
			||||||
 | 
					in the non-volatile board configuration bits. To change these you can use
 | 
				
			||||||
 | 
					the `sl28 nvm` command.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For more information on the non-volatile board configuration bits, see the
 | 
				
			||||||
 | 
					following section.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Non-volatile Board Configuration Bits
 | 
					Non-volatile Board Configuration Bits
 | 
				
			||||||
-------------------------------------
 | 
					-------------------------------------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -544,4 +544,10 @@ config ZYNQMP_GPIO_MODEPIN
 | 
				
			||||||
	  are accessed using xilinx firmware. In modepin register, [3:0] bits
 | 
						  are accessed using xilinx firmware. In modepin register, [3:0] bits
 | 
				
			||||||
	  set direction, [7:4] bits read IO, [11:8] bits set/clear IO.
 | 
						  set direction, [7:4] bits read IO, [11:8] bits set/clear IO.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config SL28CPLD_GPIO
 | 
				
			||||||
 | 
						bool "Kontron sl28cpld GPIO driver"
 | 
				
			||||||
 | 
						depends on DM_GPIO && SL28CPLD
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Support GPIO access on Kontron sl28cpld board management controllers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,4 +70,5 @@ obj-$(CONFIG_NX_GPIO)		+= nx_gpio.o
 | 
				
			||||||
obj-$(CONFIG_SIFIVE_GPIO)	+= sifive-gpio.o
 | 
					obj-$(CONFIG_SIFIVE_GPIO)	+= sifive-gpio.o
 | 
				
			||||||
obj-$(CONFIG_NOMADIK_GPIO)	+= nmk_gpio.o
 | 
					obj-$(CONFIG_NOMADIK_GPIO)	+= nmk_gpio.o
 | 
				
			||||||
obj-$(CONFIG_MAX7320_GPIO)	+= max7320_gpio.o
 | 
					obj-$(CONFIG_MAX7320_GPIO)	+= max7320_gpio.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_SL28CPLD_GPIO)	+= sl28cpld-gpio.o
 | 
				
			||||||
obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN)	+= zynqmp_gpio_modepin.o
 | 
					obj-$(CONFIG_ZYNQMP_GPIO_MODEPIN)	+= zynqmp_gpio_modepin.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,165 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0+
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * GPIO driver for the sl28cpld
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (c) 2021 Michael Walle <michael@walle.cc>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <common.h>
 | 
				
			||||||
 | 
					#include <dm.h>
 | 
				
			||||||
 | 
					#include <asm/gpio.h>
 | 
				
			||||||
 | 
					#include <sl28cpld.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* GPIO flavor */
 | 
				
			||||||
 | 
					#define SL28CPLD_GPIO_DIR	0x00
 | 
				
			||||||
 | 
					#define SL28CPLD_GPIO_OUT	0x01
 | 
				
			||||||
 | 
					#define SL28CPLD_GPIO_IN	0x02
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* input-only flavor */
 | 
				
			||||||
 | 
					#define SL28CPLD_GPI_IN		0x00
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* output-only flavor */
 | 
				
			||||||
 | 
					#define SL28CPLD_GPO_OUT	0x00
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum {
 | 
				
			||||||
 | 
						SL28CPLD_GPIO,
 | 
				
			||||||
 | 
						SL28CPLD_GPI,
 | 
				
			||||||
 | 
						SL28CPLD_GPO,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_gpio_get_value(struct udevice *dev, unsigned int gpio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ulong type = dev_get_driver_data(dev);
 | 
				
			||||||
 | 
						int val, reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case SL28CPLD_GPIO:
 | 
				
			||||||
 | 
							reg = SL28CPLD_GPIO_IN;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SL28CPLD_GPI:
 | 
				
			||||||
 | 
							reg = SL28CPLD_GPI_IN;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SL28CPLD_GPO:
 | 
				
			||||||
 | 
							/* we are output only, thus just return the output value */
 | 
				
			||||||
 | 
							reg = SL28CPLD_GPO_OUT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = sl28cpld_read(dev, reg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return val < 0 ? val : !!(val & BIT(gpio));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_gpio_set_value(struct udevice *dev, unsigned int gpio,
 | 
				
			||||||
 | 
									   int value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ulong type = dev_get_driver_data(dev);
 | 
				
			||||||
 | 
						uint reg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case SL28CPLD_GPIO:
 | 
				
			||||||
 | 
							reg = SL28CPLD_GPIO_OUT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SL28CPLD_GPO:
 | 
				
			||||||
 | 
							reg = SL28CPLD_GPO_OUT;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case SL28CPLD_GPI:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (value)
 | 
				
			||||||
 | 
							return sl28cpld_update(dev, reg, 0, BIT(gpio));
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return sl28cpld_update(dev, reg, BIT(gpio), 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_gpio_direction_input(struct udevice *dev, unsigned int gpio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ulong type = dev_get_driver_data(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case SL28CPLD_GPI:
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
						case SL28CPLD_GPIO:
 | 
				
			||||||
 | 
							return sl28cpld_update(dev, SL28CPLD_GPIO_DIR, BIT(gpio), 0);
 | 
				
			||||||
 | 
						case SL28CPLD_GPO:
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_gpio_direction_output(struct udevice *dev,
 | 
				
			||||||
 | 
										  unsigned int gpio, int value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ulong type = dev_get_driver_data(dev);
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* set_value() will report an error if we are input-only */
 | 
				
			||||||
 | 
						ret = sl28cpld_gpio_set_value(dev, gpio, value);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (type == SL28CPLD_GPIO)
 | 
				
			||||||
 | 
							return sl28cpld_update(dev, SL28CPLD_GPIO_DIR, 0, BIT(gpio));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_gpio_get_function(struct udevice *dev, unsigned int gpio)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ulong type = dev_get_driver_data(dev);
 | 
				
			||||||
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						switch (type) {
 | 
				
			||||||
 | 
						case SL28CPLD_GPIO:
 | 
				
			||||||
 | 
							val = sl28cpld_read(dev, SL28CPLD_GPIO_DIR);
 | 
				
			||||||
 | 
							if (val < 0)
 | 
				
			||||||
 | 
								return val;
 | 
				
			||||||
 | 
							if (val & BIT(gpio))
 | 
				
			||||||
 | 
								return GPIOF_OUTPUT;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return GPIOF_INPUT;
 | 
				
			||||||
 | 
						case SL28CPLD_GPI:
 | 
				
			||||||
 | 
							return GPIOF_INPUT;
 | 
				
			||||||
 | 
						case SL28CPLD_GPO:
 | 
				
			||||||
 | 
							return GPIOF_OUTPUT;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct dm_gpio_ops sl28cpld_gpio_ops = {
 | 
				
			||||||
 | 
						.direction_input = sl28cpld_gpio_direction_input,
 | 
				
			||||||
 | 
						.direction_output = sl28cpld_gpio_direction_output,
 | 
				
			||||||
 | 
						.get_value = sl28cpld_gpio_get_value,
 | 
				
			||||||
 | 
						.set_value = sl28cpld_gpio_set_value,
 | 
				
			||||||
 | 
						.get_function = sl28cpld_gpio_get_function,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_gpio_probe(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						uc_priv->gpio_count = 8;
 | 
				
			||||||
 | 
						uc_priv->bank_name = dev_read_name(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct udevice_id sl28cpld_gpio_ids[] = {
 | 
				
			||||||
 | 
						{ .compatible = "kontron,sl28cpld-gpio", .data = SL28CPLD_GPIO},
 | 
				
			||||||
 | 
						{ .compatible = "kontron,sl28cpld-gpo", .data = SL28CPLD_GPO},
 | 
				
			||||||
 | 
						{ .compatible = "kontron,sl28cpld-gpi", .data = SL28CPLD_GPI},
 | 
				
			||||||
 | 
						{ }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					U_BOOT_DRIVER(sl28cpld_gpio) = {
 | 
				
			||||||
 | 
						.name	= "sl28cpld_gpio",
 | 
				
			||||||
 | 
						.id	= UCLASS_GPIO,
 | 
				
			||||||
 | 
						.of_match = sl28cpld_gpio_ids,
 | 
				
			||||||
 | 
						.probe	= sl28cpld_gpio_probe,
 | 
				
			||||||
 | 
						.ops	= &sl28cpld_gpio_ops,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -512,4 +512,12 @@ config ESM_PMIC
 | 
				
			||||||
config FSL_IFC
 | 
					config FSL_IFC
 | 
				
			||||||
	bool
 | 
						bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config SL28CPLD
 | 
				
			||||||
 | 
						bool "Enable Kontron sl28cpld multi-function driver"
 | 
				
			||||||
 | 
						depends on DM_I2C
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Support for the Kontron sl28cpld management controller. This is
 | 
				
			||||||
 | 
						  the base driver which provides common access methods for the
 | 
				
			||||||
 | 
						  sub-drivers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endmenu
 | 
					endmenu
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,3 +82,4 @@ obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o
 | 
				
			||||||
obj-$(CONFIG_K3_AVS0) += k3_avs.o
 | 
					obj-$(CONFIG_K3_AVS0) += k3_avs.o
 | 
				
			||||||
obj-$(CONFIG_ESM_K3) += k3_esm.o
 | 
					obj-$(CONFIG_ESM_K3) += k3_esm.o
 | 
				
			||||||
obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
 | 
					obj-$(CONFIG_ESM_PMIC) += esm_pmic.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_SL28CPLD) += sl28cpld.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,105 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0+
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2021 Michael Walle <michael@walle.cc>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <common.h>
 | 
				
			||||||
 | 
					#include <dm.h>
 | 
				
			||||||
 | 
					#include <i2c.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sl28cpld_child_plat {
 | 
				
			||||||
 | 
						uint offset;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The access methods works either with the first argument being a child
 | 
				
			||||||
 | 
					 * device or with the MFD device itself.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					static int sl28cpld_read_child(struct udevice *dev, uint offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sl28cpld_child_plat *plat = dev_get_parent_plat(dev);
 | 
				
			||||||
 | 
						struct udevice *mfd = dev_get_parent(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dm_i2c_reg_read(mfd, offset + plat->offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sl28cpld_read(struct udevice *dev, uint offset)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dev->driver == DM_DRIVER_GET(sl28cpld))
 | 
				
			||||||
 | 
							return dm_i2c_reg_read(dev, offset);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return sl28cpld_read_child(dev, offset);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_write_child(struct udevice *dev, uint offset,
 | 
				
			||||||
 | 
									uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sl28cpld_child_plat *plat = dev_get_parent_plat(dev);
 | 
				
			||||||
 | 
						struct udevice *mfd = dev_get_parent(dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dm_i2c_reg_write(mfd, offset + plat->offset, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sl28cpld_write(struct udevice *dev, uint offset, uint8_t value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (dev->driver == DM_DRIVER_GET(sl28cpld))
 | 
				
			||||||
 | 
							return dm_i2c_reg_write(dev, offset, value);
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							return sl28cpld_write_child(dev, offset, value);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sl28cpld_update(struct udevice *dev, uint offset, uint8_t clear,
 | 
				
			||||||
 | 
							    uint8_t set)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = sl28cpld_read(dev, offset);
 | 
				
			||||||
 | 
						if (val < 0)
 | 
				
			||||||
 | 
							return val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val &= ~clear;
 | 
				
			||||||
 | 
						val |= set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sl28cpld_write(dev, offset, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_probe(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS |
 | 
				
			||||||
 | 
								   DM_I2C_CHIP_WR_ADDRESS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_child_post_bind(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sl28cpld_child_plat *plat = dev_get_parent_plat(dev);
 | 
				
			||||||
 | 
						int offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!dev_has_ofnode(dev))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						offset = dev_read_u32_default(dev, "reg", -1);
 | 
				
			||||||
 | 
						if (offset == -1)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						plat->offset = offset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct udevice_id sl28cpld_ids[] = {
 | 
				
			||||||
 | 
						{ .compatible = "kontron,sl28cpld" },
 | 
				
			||||||
 | 
						{}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					U_BOOT_DRIVER(sl28cpld) = {
 | 
				
			||||||
 | 
						.name		= "sl28cpld",
 | 
				
			||||||
 | 
						.id		= UCLASS_NOP,
 | 
				
			||||||
 | 
						.of_match	= sl28cpld_ids,
 | 
				
			||||||
 | 
						.probe		= sl28cpld_probe,
 | 
				
			||||||
 | 
						.bind		= dm_scan_fdt_dev,
 | 
				
			||||||
 | 
						.flags		= DM_FLAG_PRE_RELOC,
 | 
				
			||||||
 | 
						.per_child_plat_auto = sizeof(struct sl28cpld_child_plat),
 | 
				
			||||||
 | 
						.child_post_bind = sl28cpld_child_post_bind,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -266,6 +266,13 @@ config WDT_SBSA
 | 
				
			||||||
	   In the single stage mode, when the timeout is reached, your system
 | 
						   In the single stage mode, when the timeout is reached, your system
 | 
				
			||||||
	   will be reset by WS1. The first signal (WS0) is ignored.
 | 
						   will be reset by WS1. The first signal (WS0) is ignored.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config WDT_SL28CPLD
 | 
				
			||||||
 | 
						bool "sl28cpld watchdog timer support"
 | 
				
			||||||
 | 
						depends on WDT && SL28CPLD
 | 
				
			||||||
 | 
						help
 | 
				
			||||||
 | 
						  Enable support for the watchdog timer in the Kontron sl28cpld
 | 
				
			||||||
 | 
						  management controller.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
config WDT_SP805
 | 
					config WDT_SP805
 | 
				
			||||||
	bool "SP805 watchdog timer support"
 | 
						bool "SP805 watchdog timer support"
 | 
				
			||||||
	depends on WDT
 | 
						depends on WDT
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@ obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
 | 
				
			||||||
obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
 | 
					obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
 | 
				
			||||||
obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o
 | 
					obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.o
 | 
				
			||||||
obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o
 | 
					obj-$(CONFIG_WDT_K3_RTI) += rti_wdt.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_WDT_SL28CPLD) += sl28cpld-wdt.o
 | 
				
			||||||
obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
 | 
					obj-$(CONFIG_WDT_SP805) += sp805_wdt.o
 | 
				
			||||||
obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
 | 
					obj-$(CONFIG_WDT_STM32MP) += stm32mp_wdt.o
 | 
				
			||||||
obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o
 | 
					obj-$(CONFIG_WDT_SUNXI) += sunxi_wdt.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,109 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0+
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Watchdog driver for the sl28cpld
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * Copyright (c) 2021 Michael Walle <michael@walle.cc>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <common.h>
 | 
				
			||||||
 | 
					#include <dm.h>
 | 
				
			||||||
 | 
					#include <wdt.h>
 | 
				
			||||||
 | 
					#include <sl28cpld.h>
 | 
				
			||||||
 | 
					#include <div64.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SL28CPLD_WDT_CTRL		0x00
 | 
				
			||||||
 | 
					#define  WDT_CTRL_EN0			BIT(0)
 | 
				
			||||||
 | 
					#define  WDT_CTRL_EN1			BIT(1)
 | 
				
			||||||
 | 
					#define  WDT_CTRL_EN_MASK		GENMASK(1, 0)
 | 
				
			||||||
 | 
					#define  WDT_CTRL_LOCK			BIT(2)
 | 
				
			||||||
 | 
					#define  WDT_CTRL_ASSERT_SYS_RESET	BIT(6)
 | 
				
			||||||
 | 
					#define  WDT_CTRL_ASSERT_WDT_TIMEOUT	BIT(7)
 | 
				
			||||||
 | 
					#define SL28CPLD_WDT_TIMEOUT		0x01
 | 
				
			||||||
 | 
					#define SL28CPLD_WDT_KICK		0x02
 | 
				
			||||||
 | 
					#define  WDT_KICK_VALUE			0x6b
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_wdt_reset(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return sl28cpld_write(dev, SL28CPLD_WDT_KICK, WDT_KICK_VALUE);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret, val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = sl28cpld_read(dev, SL28CPLD_WDT_CTRL);
 | 
				
			||||||
 | 
						if (val < 0)
 | 
				
			||||||
 | 
							return val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* (1) disable watchdog */
 | 
				
			||||||
 | 
						val &= ~WDT_CTRL_EN_MASK;
 | 
				
			||||||
 | 
						ret = sl28cpld_write(dev, SL28CPLD_WDT_CTRL, val);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* (2) set timeout */
 | 
				
			||||||
 | 
						ret = sl28cpld_write(dev, SL28CPLD_WDT_TIMEOUT, lldiv(timeout, 1000));
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* (3) kick it, will reset timer to the timeout value */
 | 
				
			||||||
 | 
						ret = sl28cpld_wdt_reset(dev);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* (4) enable either recovery or normal one */
 | 
				
			||||||
 | 
						if (flags & BIT(0))
 | 
				
			||||||
 | 
							val |= WDT_CTRL_EN1;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							val |= WDT_CTRL_EN0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & BIT(1))
 | 
				
			||||||
 | 
							val |= WDT_CTRL_LOCK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & BIT(2))
 | 
				
			||||||
 | 
							val &= ~WDT_CTRL_ASSERT_SYS_RESET;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							val |= WDT_CTRL_ASSERT_SYS_RESET;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (flags & BIT(3))
 | 
				
			||||||
 | 
							val |= WDT_CTRL_ASSERT_WDT_TIMEOUT;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							val &= ~WDT_CTRL_ASSERT_WDT_TIMEOUT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sl28cpld_write(dev, SL28CPLD_WDT_CTRL, val);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_wdt_stop(struct udevice *dev)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = sl28cpld_read(dev, SL28CPLD_WDT_CTRL);
 | 
				
			||||||
 | 
						if (val < 0)
 | 
				
			||||||
 | 
							return val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sl28cpld_write(dev, SL28CPLD_WDT_CTRL, val & ~WDT_CTRL_EN_MASK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int sl28cpld_wdt_expire_now(struct udevice *dev, ulong flags)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return sl28cpld_wdt_start(dev, 0, flags);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct wdt_ops sl28cpld_wdt_ops = {
 | 
				
			||||||
 | 
						.start = sl28cpld_wdt_start,
 | 
				
			||||||
 | 
						.reset = sl28cpld_wdt_reset,
 | 
				
			||||||
 | 
						.stop = sl28cpld_wdt_stop,
 | 
				
			||||||
 | 
						.expire_now = sl28cpld_wdt_expire_now,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static const struct udevice_id sl28cpld_wdt_ids[] = {
 | 
				
			||||||
 | 
						{ .compatible = "kontron,sl28cpld-wdt", },
 | 
				
			||||||
 | 
						{}
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					U_BOOT_DRIVER(sl28cpld_wdt) = {
 | 
				
			||||||
 | 
						.name = "sl28cpld-wdt",
 | 
				
			||||||
 | 
						.id = UCLASS_WDT,
 | 
				
			||||||
 | 
						.of_match = sl28cpld_wdt_ids,
 | 
				
			||||||
 | 
						.ops = &sl28cpld_wdt_ops,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -244,12 +244,36 @@
 | 
				
			||||||
		"run distro_bootcmd;run sd2_bootcmd;"		\
 | 
							"run distro_bootcmd;run sd2_bootcmd;"		\
 | 
				
			||||||
		"env exists secureboot && esbc_halt;"
 | 
							"env exists secureboot && esbc_halt;"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_CMD_USB
 | 
				
			||||||
 | 
					#define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define BOOT_TARGET_DEVICES_USB(func)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_MMC
 | 
				
			||||||
 | 
					#define BOOT_TARGET_DEVICES_MMC(func, instance) func(MMC, mmc, instance)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define BOOT_TARGET_DEVICES_MMC(func)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_SCSI
 | 
				
			||||||
 | 
					#define BOOT_TARGET_DEVICES_SCSI(func) func(SCSI, scsi, 0)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define BOOT_TARGET_DEVICES_SCSI(func)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_CMD_DHCP
 | 
				
			||||||
 | 
					#define BOOT_TARGET_DEVICES_DHCP(func) func(DHCP, dhcp, na)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define BOOT_TARGET_DEVICES_DHCP(func)
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define BOOT_TARGET_DEVICES(func) \
 | 
					#define BOOT_TARGET_DEVICES(func) \
 | 
				
			||||||
	func(USB, usb, 0) \
 | 
						BOOT_TARGET_DEVICES_USB(func) \
 | 
				
			||||||
	func(MMC, mmc, 0) \
 | 
						BOOT_TARGET_DEVICES_MMC(func, 0) \
 | 
				
			||||||
	func(MMC, mmc, 1) \
 | 
						BOOT_TARGET_DEVICES_MMC(func, 1) \
 | 
				
			||||||
	func(SCSI, scsi, 0) \
 | 
						BOOT_TARGET_DEVICES_SCSI(func) \
 | 
				
			||||||
	func(DHCP, dhcp, na)
 | 
						BOOT_TARGET_DEVICES_DHCP(func)
 | 
				
			||||||
#include <config_distro_bootcmd.h>
 | 
					#include <config_distro_bootcmd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __LX2_COMMON_H */
 | 
					#endif /* __LX2_COMMON_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,16 @@
 | 
				
			||||||
 | 
					/* SPDX-License-Identifier: GPL-2.0+ */
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2021 Michael Walle <michael@walle.cc>
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __SL28CPLD_H
 | 
				
			||||||
 | 
					#define __SL28CPLD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SL28CPLD_VERSION	0x03
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int sl28cpld_read(struct udevice *dev, uint offset);
 | 
				
			||||||
 | 
					int sl28cpld_write(struct udevice *dev, uint offset, uint8_t value);
 | 
				
			||||||
 | 
					int sl28cpld_update(struct udevice *dev, uint offset, uint8_t clear,
 | 
				
			||||||
 | 
							    uint8_t set);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -230,19 +230,25 @@ static int pblimage_verify_header(unsigned char *ptr, int image_size,
 | 
				
			||||||
			struct image_tool_params *params)
 | 
								struct image_tool_params *params)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct pbl_header *pbl_hdr = (struct pbl_header *) ptr;
 | 
						struct pbl_header *pbl_hdr = (struct pbl_header *) ptr;
 | 
				
			||||||
 | 
						uint32_t rcwheader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (params->arch == IH_ARCH_ARM)
 | 
				
			||||||
 | 
							rcwheader = RCW_ARM_HEADER;
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							rcwheader = RCW_PPC_HEADER;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Only a few checks can be done: search for magic numbers */
 | 
						/* Only a few checks can be done: search for magic numbers */
 | 
				
			||||||
	if (ENDIANNESS == 'l') {
 | 
						if (ENDIANNESS == 'l') {
 | 
				
			||||||
		if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE))
 | 
							if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE))
 | 
				
			||||||
			return -FDT_ERR_BADSTRUCTURE;
 | 
								return -FDT_ERR_BADSTRUCTURE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (pbl_hdr->rcwheader != reverse_byte(RCW_HEADER))
 | 
							if (pbl_hdr->rcwheader != reverse_byte(rcwheader))
 | 
				
			||||||
			return -FDT_ERR_BADSTRUCTURE;
 | 
								return -FDT_ERR_BADSTRUCTURE;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (pbl_hdr->preamble != RCW_PREAMBLE)
 | 
							if (pbl_hdr->preamble != RCW_PREAMBLE)
 | 
				
			||||||
			return -FDT_ERR_BADSTRUCTURE;
 | 
								return -FDT_ERR_BADSTRUCTURE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (pbl_hdr->rcwheader != RCW_HEADER)
 | 
							if (pbl_hdr->rcwheader != rcwheader)
 | 
				
			||||||
			return -FDT_ERR_BADSTRUCTURE;
 | 
								return -FDT_ERR_BADSTRUCTURE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,7 +8,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define RCW_BYTES	64
 | 
					#define RCW_BYTES	64
 | 
				
			||||||
#define RCW_PREAMBLE	0xaa55aa55
 | 
					#define RCW_PREAMBLE	0xaa55aa55
 | 
				
			||||||
#define RCW_HEADER	0x010e0100
 | 
					#define RCW_ARM_HEADER	0x01ee0100
 | 
				
			||||||
 | 
					#define RCW_PPC_HEADER	0x010e0100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct pbl_header {
 | 
					struct pbl_header {
 | 
				
			||||||
	uint32_t preamble;
 | 
						uint32_t preamble;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue