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
 | 
			
		||||
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
 | 
			
		||||
M:	Jagan Teki <jagan@amarulasolutions.com>
 | 
			
		||||
S:	Maintained
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								Makefile
								
								
								
								
							
							
						
						
									
										2
									
								
								Makefile
								
								
								
								
							| 
						 | 
				
			
			@ -1411,7 +1411,7 @@ MKIMAGEFLAGS_u-boot-spl.kwb = -n $(KWD_CONFIG_FILE) \
 | 
			
		|||
	$(if $(KEYDIR),-k $(KEYDIR))
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
UBOOT_BIN := u-boot-with-dtb.bin
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,7 @@
 | 
			
		|||
		fit {
 | 
			
		||||
			offset = <CONFIG_SPL_PAD_TO>;
 | 
			
		||||
			description = "FIT image with multiple configurations";
 | 
			
		||||
			fit,fdt-list = "of-list";
 | 
			
		||||
 | 
			
		||||
			images {
 | 
			
		||||
				uboot {
 | 
			
		||||
| 
						 | 
				
			
			@ -41,95 +42,20 @@
 | 
			
		|||
					};
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				fdt-1 {
 | 
			
		||||
					description = "fsl-ls1028a-kontron-sl28";
 | 
			
		||||
				@fdt-SEQ {
 | 
			
		||||
					description = "NAME";
 | 
			
		||||
					type = "flat_dt";
 | 
			
		||||
					arch = "arm";
 | 
			
		||||
					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 {
 | 
			
		||||
				default = "conf-1";
 | 
			
		||||
				default = "@config-DEFAULT-SEQ";
 | 
			
		||||
 | 
			
		||||
				conf-1 {
 | 
			
		||||
					description = "fsl-ls1028a-kontron-sl28";
 | 
			
		||||
				@config-SEQ {
 | 
			
		||||
					description = "NAME";
 | 
			
		||||
					firmware = "uboot";
 | 
			
		||||
					fdt = "fdt-1";
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
				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";
 | 
			
		||||
					fdt = "fdt-SEQ";
 | 
			
		||||
				};
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
| 
						 | 
				
			
			@ -189,27 +115,7 @@
 | 
			
		|||
		};
 | 
			
		||||
 | 
			
		||||
		configurations {
 | 
			
		||||
			conf-1 {
 | 
			
		||||
				firmware = "bl31";
 | 
			
		||||
				loadables = "uboot";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			conf-2 {
 | 
			
		||||
				firmware = "bl31";
 | 
			
		||||
				loadables = "uboot";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			conf-3 {
 | 
			
		||||
				firmware = "bl31";
 | 
			
		||||
				loadables = "uboot";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			conf-4 {
 | 
			
		||||
				firmware = "bl31";
 | 
			
		||||
				loadables = "uboot";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			conf-5 {
 | 
			
		||||
			@config-SEQ {
 | 
			
		||||
				firmware = "bl31";
 | 
			
		||||
				loadables = "uboot";
 | 
			
		||||
			};
 | 
			
		||||
| 
						 | 
				
			
			@ -238,23 +144,7 @@
 | 
			
		|||
		};
 | 
			
		||||
 | 
			
		||||
		configurations {
 | 
			
		||||
			conf-1 {
 | 
			
		||||
				loadables = "uboot", "bl32";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			conf-2 {
 | 
			
		||||
				loadables = "uboot", "bl32";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			conf-3 {
 | 
			
		||||
				loadables = "uboot", "bl32";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			conf-4 {
 | 
			
		||||
				loadables = "uboot", "bl32";
 | 
			
		||||
			};
 | 
			
		||||
 | 
			
		||||
			conf-5 {
 | 
			
		||||
			@config-SEQ {
 | 
			
		||||
				loadables = "uboot", "bl32";
 | 
			
		||||
			};
 | 
			
		||||
		};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
// SPDX-License-Identifier: GPL-2.0+
 | 
			
		||||
 | 
			
		||||
#include <common.h>
 | 
			
		||||
#include <dm.h>
 | 
			
		||||
#include <malloc.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fsl_ddr.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +15,9 @@
 | 
			
		|||
#include <asm/arch/soc.h>
 | 
			
		||||
#include <fsl_immap.h>
 | 
			
		||||
#include <netdev.h>
 | 
			
		||||
#include <wdt.h>
 | 
			
		||||
 | 
			
		||||
#include <sl28cpld.h>
 | 
			
		||||
#include <fdtdec.h>
 | 
			
		||||
#include <miiphy.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -39,16 +42,68 @@ int board_eth_init(struct bd_info *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)
 | 
			
		||||
{
 | 
			
		||||
	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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,23 +42,23 @@ CONFIG_CMD_GREPENV=y
 | 
			
		|||
CONFIG_CMD_NVEDIT_EFI=y
 | 
			
		||||
CONFIG_CMD_DFU=y
 | 
			
		||||
CONFIG_CMD_DM=y
 | 
			
		||||
CONFIG_CMD_GPIO=y
 | 
			
		||||
CONFIG_CMD_GPT=y
 | 
			
		||||
CONFIG_CMD_I2C=y
 | 
			
		||||
CONFIG_CMD_MMC=y
 | 
			
		||||
CONFIG_CMD_PCI=y
 | 
			
		||||
CONFIG_CMD_USB=y
 | 
			
		||||
CONFIG_CMD_USB_MASS_STORAGE=y
 | 
			
		||||
CONFIG_CMD_WDT=y
 | 
			
		||||
CONFIG_CMD_CACHE=y
 | 
			
		||||
CONFIG_CMD_EFIDEBUG=y
 | 
			
		||||
CONFIG_CMD_RNG=y
 | 
			
		||||
CONFIG_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_IS_IN_SPI_FLASH=y
 | 
			
		||||
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
 | 
			
		||||
CONFIG_NET_RANDOM_ETHADDR=y
 | 
			
		||||
CONFIG_NETCONSOLE=y
 | 
			
		||||
CONFIG_SPL_DM_SEQ_ALIAS=y
 | 
			
		||||
CONFIG_SATA=y
 | 
			
		||||
CONFIG_SCSI_AHCI=y
 | 
			
		||||
| 
						 | 
				
			
			@ -69,8 +69,10 @@ CONFIG_DDR_ECC=y
 | 
			
		|||
CONFIG_ECC_INIT_VIA_DDRCONTROLLER=y
 | 
			
		||||
CONFIG_DFU_MMC=y
 | 
			
		||||
CONFIG_DFU_SF=y
 | 
			
		||||
CONFIG_SL28CPLD_GPIO=y
 | 
			
		||||
CONFIG_I2C_SET_DEFAULT_BUS_NUM=y
 | 
			
		||||
CONFIG_I2C_MUX=y
 | 
			
		||||
CONFIG_SL28CPLD=y
 | 
			
		||||
CONFIG_MMC_HS400_SUPPORT=y
 | 
			
		||||
CONFIG_FSL_ESDHC=y
 | 
			
		||||
CONFIG_FSL_ESDHC_SUPPORT_ADMA2=y
 | 
			
		||||
| 
						 | 
				
			
			@ -102,6 +104,11 @@ CONFIG_USB_DWC3=y
 | 
			
		|||
CONFIG_USB_DWC3_LAYERSCAPE=y
 | 
			
		||||
CONFIG_USB_GADGET=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_OVERLAY=y
 | 
			
		||||
CONFIG_EFI_SET_TIME=y
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,34 +23,17 @@ Copy u-boot.rom to a TFTP server.
 | 
			
		|||
Install the bootloader on the board
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
Please note, this bootloader doesn't support the builtin watchdog (yet),
 | 
			
		||||
therefore you have to disable it, see below. Otherwise you'll end up in
 | 
			
		||||
the failsafe bootloader on every reset::
 | 
			
		||||
To install the bootloader binary use the following command::
 | 
			
		||||
 | 
			
		||||
 > tftp path/to/u-boot.rom
 | 
			
		||||
 > sf probe 0
 | 
			
		||||
 > sf update $fileaddr 0x210000 $filesize
 | 
			
		||||
 | 
			
		||||
The board is fully failsafe, you can't break anything. But because you've
 | 
			
		||||
disabled the builtin watchdog you might have to manually enter failsafe
 | 
			
		||||
mode by asserting the ``FORCE_RECOV#`` line during board reset.
 | 
			
		||||
 | 
			
		||||
Disable the builtin watchdog
 | 
			
		||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 | 
			
		||||
 | 
			
		||||
- 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
 | 
			
		||||
 | 
			
		||||
The board is fully failsafe, you can't break anything. If builtin watchdog
 | 
			
		||||
is enabled, you'll automatically end up in the failsafe bootloader if
 | 
			
		||||
something goes wrong. If the watchdog is disabled, you have to manually
 | 
			
		||||
enter failsafe mode by asserting the ``FORCE_RECOV#`` line during board
 | 
			
		||||
reset.
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
bootloader.
 | 
			
		||||
 | 
			
		||||
Useful I2C tricks
 | 
			
		||||
-----------------
 | 
			
		||||
Builtin watchdog
 | 
			
		||||
----------------
 | 
			
		||||
 | 
			
		||||
The board has a board management controller which is not supported in
 | 
			
		||||
u-boot (yet). But you can use the i2c command to access it.
 | 
			
		||||
The builtin watchdog will supervise the bootloader startup. If anything
 | 
			
		||||
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
 | 
			
		||||
-------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -544,4 +544,10 @@ config ZYNQMP_GPIO_MODEPIN
 | 
			
		|||
	  are accessed using xilinx firmware. In modepin register, [3:0] bits
 | 
			
		||||
	  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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,4 +70,5 @@ obj-$(CONFIG_NX_GPIO)		+= nx_gpio.o
 | 
			
		|||
obj-$(CONFIG_SIFIVE_GPIO)	+= sifive-gpio.o
 | 
			
		||||
obj-$(CONFIG_NOMADIK_GPIO)	+= nmk_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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
	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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,3 +82,4 @@ obj-$(CONFIG_MICROCHIP_FLEXCOM) += microchip_flexcom.o
 | 
			
		|||
obj-$(CONFIG_K3_AVS0) += k3_avs.o
 | 
			
		||||
obj-$(CONFIG_ESM_K3) += k3_esm.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
 | 
			
		||||
	   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
 | 
			
		||||
	bool "SP805 watchdog timer support"
 | 
			
		||||
	depends on WDT
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,6 +35,7 @@ obj-$(CONFIG_WDT_OCTEONTX) += octeontx_wdt.o
 | 
			
		|||
obj-$(CONFIG_WDT_OMAP3) += omap_wdt.o
 | 
			
		||||
obj-$(CONFIG_WDT_SBSA) += sbsa_gwdt.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_STM32MP) += stm32mp_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;"		\
 | 
			
		||||
		"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) \
 | 
			
		||||
	func(USB, usb, 0) \
 | 
			
		||||
	func(MMC, mmc, 0) \
 | 
			
		||||
	func(MMC, mmc, 1) \
 | 
			
		||||
	func(SCSI, scsi, 0) \
 | 
			
		||||
	func(DHCP, dhcp, na)
 | 
			
		||||
	BOOT_TARGET_DEVICES_USB(func) \
 | 
			
		||||
	BOOT_TARGET_DEVICES_MMC(func, 0) \
 | 
			
		||||
	BOOT_TARGET_DEVICES_MMC(func, 1) \
 | 
			
		||||
	BOOT_TARGET_DEVICES_SCSI(func) \
 | 
			
		||||
	BOOT_TARGET_DEVICES_DHCP(func)
 | 
			
		||||
#include <config_distro_bootcmd.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 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 */
 | 
			
		||||
	if (ENDIANNESS == 'l') {
 | 
			
		||||
		if (pbl_hdr->preamble != reverse_byte(RCW_PREAMBLE))
 | 
			
		||||
			return -FDT_ERR_BADSTRUCTURE;
 | 
			
		||||
 | 
			
		||||
		if (pbl_hdr->rcwheader != reverse_byte(RCW_HEADER))
 | 
			
		||||
		if (pbl_hdr->rcwheader != reverse_byte(rcwheader))
 | 
			
		||||
			return -FDT_ERR_BADSTRUCTURE;
 | 
			
		||||
	} else {
 | 
			
		||||
		if (pbl_hdr->preamble != RCW_PREAMBLE)
 | 
			
		||||
			return -FDT_ERR_BADSTRUCTURE;
 | 
			
		||||
 | 
			
		||||
		if (pbl_hdr->rcwheader != RCW_HEADER)
 | 
			
		||||
		if (pbl_hdr->rcwheader != rcwheader)
 | 
			
		||||
			return -FDT_ERR_BADSTRUCTURE;
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,8 @@
 | 
			
		|||
 | 
			
		||||
#define RCW_BYTES	64
 | 
			
		||||
#define RCW_PREAMBLE	0xaa55aa55
 | 
			
		||||
#define RCW_HEADER	0x010e0100
 | 
			
		||||
#define RCW_ARM_HEADER	0x01ee0100
 | 
			
		||||
#define RCW_PPC_HEADER	0x010e0100
 | 
			
		||||
 | 
			
		||||
struct pbl_header {
 | 
			
		||||
	uint32_t preamble;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue