generic-offsets-file := include/generated/generic-asm-offsets.h
always := $(generic-offsets-file)
-targets := $(generic-offsets-file) lib/asm-offsets.s
+targets := lib/asm-offsets.s
# We use internal kbuild rules to avoid the "is up to date" message from make
lib/asm-offsets.s: lib/asm-offsets.c FORCE
endif
always += $(offsets-file)
-targets += $(offsets-file)
targets += arch/$(ARCH)/lib/asm-offsets.s
CFLAGS_asm-offsets.o := -DDO_DEPS_ONLY
new boards should not use this option.
config SYS_TEXT_BASE
- depends on SPARC || ARC || X86 || ARCH_UNIPHIER
+ depends on SPARC || ARC || X86 || ARCH_UNIPHIER || ARCH_ZYNQMP
hex "Text Base"
help
TODO: Move CONFIG_SYS_TEXT_BASE for all the architecture
# Comments in this file are targeted only to the developer, do not
# expect to learn how to build the kernel reading this file.
-# Do not use make's built-in rules and variables
-# (this increases performance and avoids hard-to-debug behaviour);
-MAKEFLAGS += -rR
+# o Do not use make's built-in rules and variables
+# (this increases performance and avoids hard-to-debug behaviour);
+# o Look for make include files relative to root of kernel src
+MAKEFLAGS += -rR --include-dir=$(CURDIR)
# Avoid funny character set dependencies
unexport LC_ALL
export KBUILD_MODULES KBUILD_BUILTIN
export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
-# Look for make include files relative to root of kernel src
-MAKEFLAGS += --include-dir=$(srctree)
-
# We need some generic definitions (do not try to remake the file).
-$(srctree)/scripts/Kbuild.include: ;
-include $(srctree)/scripts/Kbuild.include
+scripts/Kbuild.include: ;
+include scripts/Kbuild.include
# Make variables (CC, etc...)
ifeq ($(KBUILD_EXTMOD),)
ifneq ($(filter config %config,$(MAKECMDGOALS)),)
config-targets := 1
- ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
+ ifneq ($(words $(MAKECMDGOALS)),1)
mixed-targets := 1
endif
endif
autoconf_is_old := $(shell find . -path ./$(KCONFIG_CONFIG) -newer \
include/config/auto.conf)
ifeq ($(autoconf_is_old),)
-include $(srctree)/config.mk
-include $(srctree)/arch/$(ARCH)/Makefile
+include config.mk
+include arch/$(ARCH)/Makefile
endif
endif
endif
export CONFIG_SYS_TEXT_BASE
-include $(srctree)/scripts/Makefile.extrawarn
+include scripts/Makefile.extrawarn
# Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments
KBUILD_CPPFLAGS += $(KCPPFLAGS)
ifeq ($(CONFIG_SPL_FSL_PBL),y)
ALL-$(CONFIG_RAMBOOT_PBL) += u-boot-with-spl-pbl.bin
else
+ifneq ($(CONFIG_SECURE_BOOT), y)
+# For Secure Boot The Image needs to be signed and Header must also
+# be included. So The image has to be built explicitly
ALL-$(CONFIG_RAMBOOT_PBL) += u-boot.pbl
endif
+endif
ALL-$(CONFIG_SPL) += spl/u-boot-spl.bin
ALL-$(CONFIG_SPL_FRAMEWORK) += u-boot.img
ALL-$(CONFIG_TPL) += tpl/u-boot-tpl.bin
-T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)
MKIMAGEFLAGS_u-boot-spl.kwb = -n $(srctree)/$(CONFIG_SYS_KWD_CONFIG:"%"=%) \
- -T kwbimage -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE)
+ -T kwbimage -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE)
MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
-R $(srctree)/$(CONFIG_SYS_FSL_PBL_PBI:"%"=%) -T pblimage
endef
define filechk_timestamp.h
- (LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \
- LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \
- LC_ALL=C date +'#define U_BOOT_TZ "%z"')
+ (SOURCE_DATE="$${SOURCE_DATE_EPOCH:+@$$SOURCE_DATE_EPOCH}"; \
+ LC_ALL=C date -u -d "$${SOURCE_DATE:-now}" +'#define U_BOOT_DATE "%b %d %C%y"'; \
+ LC_ALL=C date -u -d "$${SOURCE_DATE:-now}" +'#define U_BOOT_TIME "%T"'; \
+ LC_ALL=C date -u -d "$${SOURCE_DATE:-now}" +'#define U_BOOT_TZ "%z"' )
endef
$(version_h): include/config/uboot.release FORCE
$(timestamp_h): $(srctree)/Makefile FORCE
$(call filechk,timestamp.h)
-# ---------------------------------------------------------------------------
-
-PHONY += depend dep
-depend dep:
- @echo '*** Warning: make $@ is unnecessary now.'
-
# ---------------------------------------------------------------------------
quiet_cmd_cpp_lds = LDS $@
cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
spl/u-boot-spl.bin: spl/u-boot-spl
@:
-spl/u-boot-spl: tools prepare
+spl/u-boot-spl: tools prepare $(if $(CONFIG_OF_SEPARATE),dts/dt.dtb)
$(Q)$(MAKE) obj=spl -f $(srctree)/scripts/Makefile.spl all
spl/sunxi-spl.bin: spl/u-boot-spl
include $(cmd_files)
endif
-# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
-# Usage:
-# $(Q)$(MAKE) $(clean)=dir
-clean := -f $(srctree)/scripts/Makefile.clean obj
-
endif # skip-makefile
PHONY += FORCE
key for the Replay Protection Memory Block partition in eMMC.
- USB Device Firmware Update (DFU) class support:
- CONFIG_DFU_FUNCTION
+ CONFIG_USB_FUNCTION_DFU
This enables the USB portion of the DFU USB class
CONFIG_CMD_DFU
sending again an USB request to the device.
- USB Device Android Fastboot support:
+ CONFIG_USB_FUNCTION_FASTBOOT
+ This enables the USB part of the fastboot gadget
+
CONFIG_CMD_FASTBOOT
This enables the command "fastboot" which enables the Android
fastboot mode for the platform's USB device. Fastboot is a USB
This enables support for booting images which use the Android
image format header.
- CONFIG_USB_FASTBOOT_BUF_ADDR
+ CONFIG_FASTBOOT_BUF_ADDR
The fastboot protocol requires a large memory buffer for
downloads. Define this to the starting RAM address to use for
downloaded images.
- CONFIG_USB_FASTBOOT_BUF_SIZE
+ CONFIG_FASTBOOT_BUF_SIZE
The fastboot protocol requires a large memory buffer for
downloads. This buffer should be as large as possible for a
platform. Define this to the size available RAM for fastboot.
normal addressable memory via the LBC. CONFIG_SYS_LS_MC_FW_ADDR is the
virtual address in NOR flash.
+Freescale Layerscape Debug Server Support:
+-------------------------------------------
+The Freescale Layerscape Debug Server Support supports the loading of
+"Debug Server firmware" and triggering SP boot-rom.
+This firmware often needs to be loaded during U-Boot booting.
+
+- CONFIG_FSL_DEBUG_SERVER
+ Enable the Debug Server for Layerscape SoCs.
+
+- CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE
+ Define minimum DDR size required for debug server image
+
+- CONFIG_SYS_MEM_TOP_HIDE_MIN
+ Define minimum DDR size to be hided from top of the DDR memory
+
+Reproducible builds
+-------------------
+
+In order to achieve reproducible builds, timestamps used in the U-Boot build
+process have to be set to a fixed value.
+
+This is done using the SOURCE_DATE_EPOCH environment variable.
+SOURCE_DATE_EPOCH is to be set on the build host's shell, not as a configuration
+option for U-Boot or an environment variable in U-Boot.
+
+SOURCE_DATE_EPOCH should be set to a number of seconds since the epoch, in UTC.
+
Building the Software:
======================
+config CREATE_ARCH_SYMLINK
+ bool
+
config HAVE_GENERIC_BOARD
bool
config ARM
bool "ARM architecture"
+ select CREATE_ARCH_SYMLINK
select HAVE_PRIVATE_LIBGCC if !ARM64
select HAVE_GENERIC_BOARD
select SUPPORT_OF_CONTROL
config AVR32
bool "AVR32 architecture"
+ select CREATE_ARCH_SYMLINK
select HAVE_GENERIC_BOARD
select SYS_GENERIC_BOARD
config SPARC
bool "SPARC architecture"
+ select CREATE_ARCH_SYMLINK
config X86
bool "x86 architecture"
+ select CREATE_ARCH_SYMLINK
select HAVE_PRIVATE_LIBGCC
select HAVE_GENERIC_BOARD
select SYS_GENERIC_BOARD
config ARCH_SUNXI
bool "Support sunxi (Allwinner) SoCs"
+ select CMD_USB
select DM
select DM_GPIO
+ select DM_ETH
+ select DM_SERIAL
+ select DM_USB
select OF_CONTROL
select OF_SEPARATE
select SPL_DISABLE_OF_CONTROL
+ select USB
+ select USB_STORAGE
config TARGET_SNOWBALL
bool "Support snowball"
select DM_SPI
select DM_SPI_FLASH
-config TARGET_XILINX_ZYNQMP
+config ARCH_ZYNQMP
bool "Support Xilinx ZynqMP Platform"
select ARM64
config TEGRA
bool "NVIDIA Tegra"
- select SUPPORT_SPL
- select SPL
- select OF_CONTROL
- select SPL_DISABLE_OF_CONTROL
- select CPU_V7
- select DM
- select DM_SPI_FLASH
- select DM_SERIAL
- select DM_I2C
- select DM_SPI
- select DM_GPIO
config TARGET_VEXPRESS64_AEMV8A
bool "Support vexpress_aemv8a"
source "arch/arm/cpu/armv7/Kconfig"
+source "arch/arm/cpu/armv8/zynqmp/Kconfig"
+
source "arch/arm/cpu/armv8/Kconfig"
source "arch/arm/imx-common/Kconfig"
source "board/woodburn/Kconfig"
source "board/work-microwave/work_92105/Kconfig"
source "board/xaeniax/Kconfig"
-source "board/xilinx/zynqmp/Kconfig"
source "board/zipitz2/Kconfig"
source "arch/arm/Kconfig.debug"
return partnum;
}
-/**
- * get_board_rev() - setup to pass kernel board revision information
- * returns: 0 for the ATAG REVISION tag value.
- */
-u32 __weak get_board_rev(void)
-{
- return 0;
-}
-
/**
* get_device_type(): tell if GP/HS/EMU/TST
*/
obj-$(CONFIG_OF_LIBFDT) += fdt.o
obj-$(CONFIG_SYS_HAS_SERDES) += fsl_ls1_serdes.o ls102xa_serdes.o
obj-$(CONFIG_SPL) += spl.o
+
+ifdef CONFIG_ARMV7_PSCI
+obj-y += psci.o
+endif
char phy[16];
int phy_node;
int i = 0;
- int enet_id = 0;
uint32_t ph;
while ((dev = eth_get_dev_by_index(i++)) != NULL) {
- if (strstr(dev->name, "eTSEC1"))
- enet_id = 0;
- else if (strstr(dev->name, "eTSEC2"))
- enet_id = 1;
- else if (strstr(dev->name, "eTSEC3"))
- enet_id = 2;
- else
+ if (strstr(dev->name, "eTSEC1")) {
+ strcpy(enet, "ethernet0");
+ strcpy(phy, "enet0_rgmii_phy");
+ } else if (strstr(dev->name, "eTSEC2")) {
+ strcpy(enet, "ethernet1");
+ strcpy(phy, "enet1_rgmii_phy");
+ } else if (strstr(dev->name, "eTSEC3")) {
+ strcpy(enet, "ethernet2");
+ strcpy(phy, "enet2_rgmii_phy");
+ } else {
continue;
+ }
priv = dev->priv;
if (priv->flags & TSEC_SGMII)
continue;
- sprintf(enet, "ethernet%d", enet_id);
enet_path = fdt_get_alias(fdt, enet);
if (!enet_path)
continue;
- sprintf(phy, "enet%d_rgmii_phy", enet_id);
phy_path = fdt_get_alias(fdt, phy);
if (!phy_path)
continue;
--- /dev/null
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ * Author: Wang Dongsheng <dongsheng.wang@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+
+#include <asm/armv7.h>
+#include <asm/arch-armv7/generictimer.h>
+#include <asm/psci.h>
+
+#define SCFG_CORE0_SFT_RST 0x130
+#define SCFG_CORESRENCR 0x204
+
+#define DCFG_CCSR_BRR 0x0E4
+#define DCFG_CCSR_SCRATCHRW1 0x200
+
+ .pushsection ._secure.text, "ax"
+
+ .arch_extension sec
+
+#define ONE_MS (GENERIC_TIMER_CLK / 1000)
+#define RESET_WAIT (30 * ONE_MS)
+
+ @ r1 = target CPU
+ @ r2 = target PC
+.globl psci_cpu_on
+psci_cpu_on:
+ push {lr}
+
+ @ Clear and Get the correct CPU number
+ @ r1 = 0xf01
+ and r1, r1, #0xff
+
+ mov r0, r1
+ bl psci_get_cpu_stack_top
+ str r2, [r0]
+ dsb
+
+ @ Get DCFG base address
+ movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
+ movt r4, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
+
+ @ Detect target CPU state
+ ldr r2, [r4, #DCFG_CCSR_BRR]
+ rev r2, r2
+ lsr r2, r2, r1
+ ands r2, r2, #1
+ beq holdoff_release
+
+ @ Reset target CPU
+ @ Get SCFG base address
+ movw r0, #(CONFIG_SYS_FSL_SCFG_ADDR & 0xffff)
+ movt r0, #(CONFIG_SYS_FSL_SCFG_ADDR >> 16)
+
+ @ Enable CORE Soft Reset
+ movw r5, #0
+ movt r5, #(1 << 15)
+ rev r5, r5
+ str r5, [r0, #SCFG_CORESRENCR]
+
+ @ Get CPUx offset register
+ mov r6, #0x4
+ mul r6, r6, r1
+ add r2, r0, r6
+
+ @ Do reset on target CPU
+ movw r5, #0
+ movt r5, #(1 << 15)
+ rev r5, r5
+ str r5, [r2, #SCFG_CORE0_SFT_RST]
+
+ @ Wait target CPU up
+ timer_wait r2, RESET_WAIT
+
+ @ Disable CORE soft reset
+ mov r5, #0
+ str r5, [r0, #SCFG_CORESRENCR]
+
+holdoff_release:
+ @ Release on target CPU
+ ldr r2, [r4, #DCFG_CCSR_BRR]
+ mov r6, #1
+ lsl r6, r6, r1 @ 32 bytes per CPU
+
+ rev r6, r6
+ orr r2, r2, r6
+ str r2, [r4, #DCFG_CCSR_BRR]
+
+ @ Set secondary boot entry
+ ldr r6, =psci_cpu_entry
+ rev r6, r6
+ str r6, [r4, #DCFG_CCSR_SCRATCHRW1]
+
+ isb
+ dsb
+
+ @ Return
+ mov r0, #ARM_PSCI_RET_SUCCESS
+
+ pop {lr}
+ bx lr
+
+.globl psci_cpu_off
+psci_cpu_off:
+ bl psci_cpu_off_common
+
+1: wfi
+ b 1b
+
+.globl psci_arch_init
+psci_arch_init:
+ mov r6, lr
+
+ bl psci_get_cpu_id
+ bl psci_get_cpu_stack_top
+ mov sp, r0
+
+ bx r6
+
+ .globl psci_text_end
+psci_text_end:
+ .popsection
obj-y += omap-cache.o
endif
-ifeq ($(CONFIG_OMAP34XX),)
obj-y += boot-common.o
-endif
obj-y += lowlevel_init.o
obj-y += mem-common.o
#include <asm/arch/sys_proto.h>
#include <watchdog.h>
#include <scsi.h>
+#include <i2c.h>
DECLARE_GLOBAL_DATA_PTR;
+__weak u32 omap_sys_boot_device(void)
+{
+ return BOOT_DEVICE_NONE;
+}
+
void save_omap_boot_params(void)
{
- u32 rom_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
- u8 boot_device;
- u32 dev_desc, dev_data;
+ u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
+ struct omap_boot_parameters *omap_boot_params;
+ u32 boot_device;
+ u32 boot_mode;
- if ((rom_params < NON_SECURE_SRAM_START) ||
- (rom_params > NON_SECURE_SRAM_END))
+ if ((boot_params < NON_SECURE_SRAM_START) ||
+ (boot_params > NON_SECURE_SRAM_END))
return;
- /*
- * rom_params can be type casted to omap_boot_parameters and
- * used. But it not correct to assume that romcode structure
- * encoding would be same as u-boot. So use the defined offsets.
- */
- boot_device = *((u8 *)(rom_params + BOOT_DEVICE_OFFSET));
+ omap_boot_params = (struct omap_boot_parameters *)boot_params;
+
+ boot_device = omap_boot_params->boot_device;
+ boot_mode = MMCSD_MODE_UNDEFINED;
+
+ /* Boot device */
-#if defined(BOOT_DEVICE_NAND_I2C)
+#ifdef BOOT_DEVICE_NAND_I2C
/*
* Re-map NAND&I2C boot-device to the "normal" NAND boot-device.
* Otherwise the SPL boot IF can't handle this device correctly.
if (boot_device == BOOT_DEVICE_NAND_I2C)
boot_device = BOOT_DEVICE_NAND;
#endif
- gd->arch.omap_boot_params.omap_bootdevice = boot_device;
+#ifdef BOOT_DEVICE_QSPI_4
+ /*
+ * We get different values for QSPI_1 and QSPI_4 being used, but
+ * don't actually care about this difference. Rather than
+ * mangle the later code, if we're coming in as QSPI_4 just
+ * change to the QSPI_1 value.
+ */
+ if (boot_device == BOOT_DEVICE_QSPI_4)
+ boot_device = BOOT_DEVICE_SPI;
+#endif
+#if (defined(BOOT_DEVICE_UART) && !defined(CONFIG_SPL_YMODEM_SUPPORT)) || \
+ (defined(BOOT_DEVICE_USB) && !defined(CONFIG_SPL_USB_SUPPORT)) || \
+ (defined(BOOT_DEVICE_USBETH) && !defined(CONFIG_SPL_USBETH_SUPPORT))
+ /*
+ * When booting from peripheral booting, the boot device is not usable
+ * as-is (unless there is support for it), so the boot device is instead
+ * figured out using the SYS_BOOT pins.
+ */
+ switch (boot_device) {
+#ifdef BOOT_DEVICE_UART
+ case BOOT_DEVICE_UART:
+#endif
+#ifdef BOOT_DEVICE_USB
+ case BOOT_DEVICE_USB:
+#endif
+ boot_device = omap_sys_boot_device();
+
+ /* MMC raw mode will fallback to FS mode. */
+ if ((boot_device >= MMC_BOOT_DEVICES_START) &&
+ (boot_device <= MMC_BOOT_DEVICES_END))
+ boot_mode = MMCSD_MODE_RAW;
- gd->arch.omap_boot_params.ch_flags =
- *((u8 *)(rom_params + CH_FLAGS_OFFSET));
+ break;
+ }
+#endif
+ gd->arch.omap_boot_device = boot_device;
+
+ /* Boot mode */
+
+#ifdef CONFIG_OMAP34XX
if ((boot_device >= MMC_BOOT_DEVICES_START) &&
(boot_device <= MMC_BOOT_DEVICES_END)) {
-#if !defined(CONFIG_AM33XX) && !defined(CONFIG_TI81XX) && \
- !defined(CONFIG_AM43XX)
- if ((omap_hw_init_context() ==
- OMAP_INIT_CONTEXT_UBOOT_AFTER_SPL)) {
- gd->arch.omap_boot_params.omap_bootmode =
- *((u8 *)(rom_params + BOOT_MODE_OFFSET));
- } else
-#endif
- {
- dev_desc = *((u32 *)(rom_params + DEV_DESC_PTR_OFFSET));
- dev_data = *((u32 *)(dev_desc + DEV_DATA_PTR_OFFSET));
- gd->arch.omap_boot_params.omap_bootmode =
- *((u32 *)(dev_data + BOOT_MODE_OFFSET));
+ switch (boot_device) {
+ case BOOT_DEVICE_MMC1:
+ boot_mode = MMCSD_MODE_FS;
+ break;
+ case BOOT_DEVICE_MMC2:
+ boot_mode = MMCSD_MODE_RAW;
+ break;
}
}
-
-#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
+#else
/*
- * We get different values for QSPI_1 and QSPI_4 being used, but
- * don't actually care about this difference. Rather than
- * mangle the later code, if we're coming in as QSPI_4 just
- * change to the QSPI_1 value.
+ * If the boot device was dynamically changed and doesn't match what
+ * the bootrom initially booted, we cannot use the boot device
+ * descriptor to figure out the boot mode.
*/
- if (gd->arch.omap_boot_params.omap_bootdevice == 11)
- gd->arch.omap_boot_params.omap_bootdevice = BOOT_DEVICE_SPI;
+ if ((boot_device == omap_boot_params->boot_device) &&
+ (boot_device >= MMC_BOOT_DEVICES_START) &&
+ (boot_device <= MMC_BOOT_DEVICES_END)) {
+ boot_params = omap_boot_params->boot_device_descriptor;
+ if ((boot_params < NON_SECURE_SRAM_START) ||
+ (boot_params > NON_SECURE_SRAM_END))
+ return;
+
+ boot_params = *((u32 *)(boot_params + DEVICE_DATA_OFFSET));
+ if ((boot_params < NON_SECURE_SRAM_START) ||
+ (boot_params > NON_SECURE_SRAM_END))
+ return;
+
+ boot_mode = *((u32 *)(boot_params + BOOT_MODE_OFFSET));
+
+ if (boot_mode != MMCSD_MODE_FS &&
+ boot_mode != MMCSD_MODE_RAW)
+#ifdef CONFIG_SUPPORT_EMMC_BOOT
+ boot_mode = MMCSD_MODE_EMMCBOOT;
+#else
+ boot_mode = MMCSD_MODE_UNDEFINED;
+#endif
+ }
+#endif
+
+ gd->arch.omap_boot_mode = boot_mode;
+
+#if !defined(CONFIG_TI814X) && !defined(CONFIG_TI816X) && \
+ !defined(CONFIG_AM33XX) && !defined(CONFIG_AM43XX)
+
+ /* CH flags */
+
+ gd->arch.omap_ch_flags = omap_boot_params->ch_flags;
#endif
}
#ifdef CONFIG_SPL_BUILD
u32 spl_boot_device(void)
{
- return (u32) (gd->arch.omap_boot_params.omap_bootdevice);
+ return gd->arch.omap_boot_device;
}
u32 spl_boot_mode(void)
{
- u32 val = gd->arch.omap_boot_params.omap_bootmode;
-
- if (val == MMCSD_MODE_RAW)
- return MMCSD_MODE_RAW;
- else if (val == MMCSD_MODE_FS)
- return MMCSD_MODE_FS;
- else
-#ifdef CONFIG_SUPPORT_EMMC_BOOT
- return MMCSD_MODE_EMMCBOOT;
-#else
- return MMCSD_MODE_UNDEFINED;
-#endif
+ return gd->arch.omap_boot_mode;
}
void spl_board_init(void)
/* Prepare console output */
preloader_console_init();
-#ifdef CONFIG_SPL_NAND_SUPPORT
+#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
gpmc_init();
#endif
+#ifdef CONFIG_SPL_I2C_SUPPORT
+ i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
+#endif
#if defined(CONFIG_AM33XX) && defined(CONFIG_SPL_MUSB_NEW_SUPPORT)
arch_misc_init();
#endif
image_entry_noargs_t image_entry =
(image_entry_noargs_t) spl_image->entry_point;
+ u32 boot_params = *((u32 *)OMAP_SRAM_SCRATCH_BOOT_PARAMS);
+
debug("image entry point: 0x%X\n", spl_image->entry_point);
/* Pass the saved boot_params from rom code */
- image_entry((u32 *)&gd->arch.omap_boot_params);
+ image_entry((u32 *)boot_params);
}
#endif
}
#endif
-#if defined(CONFIG_CMD_FASTBOOT) && !defined(CONFIG_ENV_IS_NOWHERE)
+#if defined(CONFIG_USB_FUNCTION_FASTBOOT) && !defined(CONFIG_ENV_IS_NOWHERE)
int fb_set_reboot_flag(void)
{
printf("Setting reboot to fastboot flag ...\n");
*/
int arch_cpu_init(void)
{
+#ifdef CONFIG_SPL
save_omap_boot_params();
+#endif
return 0;
}
#endif /* CONFIG_ARCH_CPU_INIT */
#include <asm/arch/spl.h>
#include <linux/linkage.h>
-#ifndef CONFIG_OMAP34XX
+#ifdef CONFIG_SPL
ENTRY(save_boot_params)
+
ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS
str r0, [r1]
b save_boot_params_ret
obj-y := lowlevel_init.o
obj-y += board.o
+obj-y += boot.o
obj-y += clock.o
obj-y += sys_info.o
ifdef CONFIG_SPL_BUILD
*/
#include <common.h>
#include <dm.h>
-#include <mmc.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
#include <asm/armv7.h>
#include <asm/gpio.h>
#include <asm/omap_common.h>
-#include <asm/arch/mmc_host_def.h>
-#include <i2c.h>
#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
#endif
-#ifdef CONFIG_SPL_BUILD
-/*
-* We use static variables because global data is not ready yet.
-* Initialized data is available in SPL right from the beginning.
-* We would not typically need to save these parameters in regular
-* U-Boot. This is needed only in SPL at the moment.
-*/
-u32 omap3_boot_device = BOOT_DEVICE_NAND;
-
-/* auto boot mode detection is not possible for OMAP3 - hard code */
-u32 spl_boot_mode(void)
-{
- switch (spl_boot_device()) {
- case BOOT_DEVICE_MMC2:
- return MMCSD_MODE_RAW;
- case BOOT_DEVICE_MMC1:
- return MMCSD_MODE_FS;
- break;
- default:
- puts("spl: ERROR: unknown device - can't select boot mode\n");
- hang();
- }
-}
-
-u32 spl_boot_device(void)
-{
- return omap3_boot_device;
-}
-
-int board_mmc_init(bd_t *bis)
-{
- switch (spl_boot_device()) {
- case BOOT_DEVICE_MMC1:
- omap_mmc_init(0, 0, 0, -1, -1);
- break;
- case BOOT_DEVICE_MMC2:
- case BOOT_DEVICE_MMC2_2:
- omap_mmc_init(1, 0, 0, -1, -1);
- break;
- }
- return 0;
-}
-
-void spl_board_init(void)
-{
- preloader_console_init();
-#if defined(CONFIG_SPL_NAND_SUPPORT) || defined(CONFIG_SPL_ONENAND_SUPPORT)
- gpmc_init();
-#endif
-#ifdef CONFIG_SPL_I2C_SUPPORT
- i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
-#endif
-}
-#endif /* CONFIG_SPL_BUILD */
-
-
/******************************************************************************
* Routine: secure_unlock
* Description: Setup security registers for access
--- /dev/null
+/*
+ * OMAP3 boot
+ *
+ * Copyright (C) 2015 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <spl.h>
+
+static u32 boot_devices[] = {
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_MMC2_2,
+};
+
+u32 omap_sys_boot_device(void)
+{
+ struct ctrl *ctrl_base = (struct ctrl *)OMAP34XX_CTRL_BASE;
+ u32 sys_boot;
+
+ /* Grab the first 5 bits of the status register for SYS_BOOT. */
+ sys_boot = readl(&ctrl_base->status) & ((1 << 5) - 1);
+
+ if (sys_boot >= (sizeof(boot_devices) / sizeof(u32)))
+ return BOOT_DEVICE_NONE;
+
+ return boot_devices[sys_boot];
+}
#include <asm/arch/clocks_omap3.h>
#include <linux/linkage.h>
-#ifdef CONFIG_SPL_BUILD
-ENTRY(save_boot_params)
- ldr r4, =omap3_boot_device
- ldr r5, [r0, #0x4]
- and r5, r5, #0xff
- str r5, [r4]
- b save_boot_params_ret
-ENDPROC(save_boot_params)
-#endif
-
/*
* Funtion for making PPA HAL API calls in secure devices
* Input:
* get_board_rev() - setup to pass kernel board revision information
* returns:(bit[0-3] sub version, higher bit[7-4] is higher version)
*************************************************************************/
+#ifdef CONFIG_REVISION_TAG
u32 __weak get_board_rev(void)
{
return 0x20;
}
+#endif
/********************************************************
* get_base(); get upper addr of current execution
# SPDX-License-Identifier: GPL-2.0+
#
+obj-y += boot.o
obj-y += sdram_elpida.o
obj-y += hwinit.o
obj-y += emif.o
--- /dev/null
+/*
+ * OMAP4 boot
+ *
+ * Copyright (C) 2015 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/omap_common.h>
+#include <spl.h>
+
+static u32 boot_devices[] = {
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_XIPWAIT,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_ONENAND,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_MMC2_2,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_MMC2_2,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_MMC2_2,
+ BOOT_DEVICE_MMC2_2,
+ BOOT_DEVICE_NONE,
+ BOOT_DEVICE_XIPWAIT,
+};
+
+u32 omap_sys_boot_device(void)
+{
+ u32 sys_boot;
+
+ /* Grab the first 5 bits of the status register for SYS_BOOT. */
+ sys_boot = readl((u32 *) (*ctrl)->control_status) & ((1 << 5) - 1);
+
+ if (sys_boot >= (sizeof(boot_devices) / sizeof(u32)))
+ return BOOT_DEVICE_NONE;
+
+ return boot_devices[sys_boot];
+}
};
struct omap_sys_ctrl_regs const omap4_ctrl = {
+ .control_status = 0x4A0022C4,
.control_id_code = 0x4A002204,
.control_std_fuse_opp_bgap = 0x4a002260,
.control_status = 0x4a0022c4,
# SPDX-License-Identifier: GPL-2.0+
#
+obj-y += boot.o
obj-y += hwinit.o
obj-y += emif.o
obj-y += sdram.o
--- /dev/null
+/*
+ * OMAP5 boot
+ *
+ * Copyright (C) 2015 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/omap_common.h>
+#include <spl.h>
+
+static u32 boot_devices[] = {
+#if defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_SATA,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_SPI,
+ BOOT_DEVICE_SPI,
+#else
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_NAND,
+ BOOT_DEVICE_MMC1,
+ BOOT_DEVICE_SATA,
+ BOOT_DEVICE_XIP,
+ BOOT_DEVICE_MMC2,
+ BOOT_DEVICE_XIPWAIT,
+#endif
+};
+
+u32 omap_sys_boot_device(void)
+{
+ u32 sys_boot;
+
+ /* Grab the first 4 bits of the status register for SYS_BOOT. */
+ sys_boot = readl((u32 *) (*ctrl)->control_status) & ((1 << 4) - 1);
+
+ if (sys_boot >= (sizeof(boot_devices) / sizeof(u32)))
+ return BOOT_DEVICE_NONE;
+
+ return boot_devices[sys_boot];
+}
*/
#include <common.h>
+#include <mmc.h>
#include <i2c.h>
#include <serial.h>
#ifdef CONFIG_SPL_BUILD
#include <asm/arch/gpio.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/timer.h>
+#include <asm/arch/mmc.h>
#include <linux/compiler.h>
}
#ifdef CONFIG_SPL_BUILD
+DECLARE_GLOBAL_DATA_PTR;
+
/* The sunxi internal brom will try to loader external bootloader
* from mmc0, nand flash, mmc2.
- * Unfortunately we can't check how SPL was loaded so assume
- * it's always the first SD/MMC controller
*/
u32 spl_boot_device(void)
{
+ struct mmc *mmc0, *mmc1;
/*
- * When booting from the SD card, the "eGON.BT0" signature is expected
- * to be found in memory at the address 0x0004 (see the "mksunxiboot"
- * tool, which generates this header).
+ * When booting from the SD card or NAND memory, the "eGON.BT0"
+ * signature is expected to be found in memory at the address 0x0004
+ * (see the "mksunxiboot" tool, which generates this header).
*
* When booting in the FEL mode over USB, this signature is patched in
* memory and replaced with something else by the 'fel' tool. This other
* valid bootable SD card image (because the BROM would refuse to
* execute the SPL in this case).
*
- * This branch is just making a decision at runtime whether to load
- * the main u-boot binary from the SD card (if the "eGON.BT0" signature
- * is found) or return to the FEL code in the BROM to wait and receive
- * the main u-boot binary over USB.
+ * This checks for the signature and if it is not found returns to
+ * the FEL code in the BROM to wait and receive the main u-boot
+ * binary over USB. If it is found, it determines where SPL was
+ * read from.
*/
- if (readl(4) == 0x4E4F4765 && readl(8) == 0x3054422E) /* eGON.BT0 */
- return BOOT_DEVICE_MMC1;
- else
+ if (readl(4) != 0x4E4F4765 || readl(8) != 0x3054422E) /* eGON.BT0 */
return BOOT_DEVICE_BOARD;
+
+ /* The BROM will try to boot from mmc0 first, so try that first. */
+ mmc_initialize(gd->bd);
+ mmc0 = find_mmc_device(0);
+ if (sunxi_mmc_has_egon_boot_signature(mmc0))
+ return BOOT_DEVICE_MMC1;
+
+ /* Fallback to booting NAND if enabled. */
+ if (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT))
+ return BOOT_DEVICE_NAND;
+
+ if (CONFIG_MMC_SUNXI_SLOT_EXTRA == 2) {
+ mmc1 = find_mmc_device(1);
+ if (sunxi_mmc_has_egon_boot_signature(mmc1)) {
+ /*
+ * spl_mmc.c: spl_mmc_load_image() is hard-coded to
+ * use find_mmc_device(0), no matter what we
+ * return. Swap mmc0 and mmc2 to make this work.
+ */
+ mmc0->block_dev.dev = 1;
+ mmc1->block_dev.dev = 0;
+ return BOOT_DEVICE_MMC2;
+ }
+ }
+
+ panic("Could not determine boot source\n");
+ return -1; /* Never reached */
}
/* No confirmation data available in SPL yet. Hardcode bootmode */
#include <asm/arch/clock.h>
#include <asm/arch/dram.h>
#include <asm/arch/prcm.h>
-#include <linux/kconfig.h>
static const struct dram_para dram_para = {
.clock = CONFIG_DRAM_CLK,
#include <asm/arch/clock.h>
#include <asm/arch/dram.h>
#include <asm/arch/prcm.h>
-#include <linux/kconfig.h>
/* PLL runs at 2x dram-clk, controller runs at PLL / 4 (dram-clk / 2) */
#define DRAM_CLK_MUL 2
*/
#include <config.h>
+
+#include <asm/arch-armv7/generictimer.h>
#include <asm/gic.h>
#include <asm/macro.h>
#include <asm/psci.h>
#define GICD_BASE 0x1c81000
#define GICC_BASE 0x1c82000
-.macro timer_wait reg, ticks
- @ Program CNTP_TVAL
- movw \reg, #(\ticks & 0xffff)
- movt \reg, #(\ticks >> 16)
- mcr p15, 0, \reg, c14, c2, 0
- isb
- @ Enable physical timer, mask interrupt
- mov \reg, #3
- mcr p15, 0, \reg, c14, c2, 1
- @ Poll physical timer until ISTATUS is on
-1: isb
- mrc p15, 0, \reg, c14, c2, 1
- ands \reg, \reg, #4
- bne 1b
- @ Disable timer
- mov \reg, #0
- mcr p15, 0, \reg, c14, c2, 1
- isb
-.endm
-
.globl psci_fiq_enter
psci_fiq_enter:
push {r0-r12}
*/
#include <config.h>
+
+#include <asm/arch-armv7/generictimer.h>
#include <asm/gic.h>
#include <asm/macro.h>
#include <asm/psci.h>
#define GICD_BASE 0x1c81000
#define GICC_BASE 0x1c82000
-.macro timer_wait reg, ticks
- @ Program CNTP_TVAL
- movw \reg, #(\ticks & 0xffff)
- movt \reg, #(\ticks >> 16)
- mcr p15, 0, \reg, c14, c2, 0
- isb
- @ Enable physical timer, mask interrupt
- mov \reg, #3
- mcr p15, 0, \reg, c14, c2, 1
- @ Poll physical timer until ISTATUS is on
-1: isb
- mrc p15, 0, \reg, c14, c2, 1
- ands \reg, \reg, #4
- bne 1b
- @ Disable timer
- mov \reg, #0
- mcr p15, 0, \reg, c14, c2, 1
- isb
-.endm
-
.globl psci_fiq_enter
psci_fiq_enter:
push {r0-r12}
int usb_rst_mask;
int gpio_vbus;
int gpio_vbus_det;
+ int gpio_id_det;
int id;
int init_count;
int power_on_count;
return -EINVAL;
}
+static int get_id_detect_gpio(int index)
+{
+ switch (index) {
+ case 0: return sunxi_name_to_gpio(CONFIG_USB0_ID_DET);
+ }
+ return -EINVAL;
+}
+
static void usb_phy_write(struct sunxi_usb_phy *phy, int addr,
int data, int len)
{
struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
int err, retries = 3;
- if (phy->gpio_vbus_det < 0) {
- eprintf("Error: invalid vbus detection pin\n");
+ if (phy->gpio_vbus_det < 0)
return phy->gpio_vbus_det;
- }
err = gpio_get_value(phy->gpio_vbus_det);
/*
return err;
}
+int sunxi_usb_phy_id_detect(int index)
+{
+ struct sunxi_usb_phy *phy = &sunxi_usb_phy[index];
+
+ if (phy->gpio_id_det < 0)
+ return phy->gpio_id_det;
+
+ return gpio_get_value(phy->gpio_id_det);
+}
+
int sunxi_usb_phy_probe(void)
{
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
if (ret)
return ret;
}
+
+ phy->gpio_id_det = get_id_detect_gpio(i);
+ if (phy->gpio_id_det >= 0) {
+ ret = gpio_request(phy->gpio_id_det, "usb_id_det");
+ if (ret)
+ return ret;
+ ret = gpio_direction_input(phy->gpio_id_det);
+ if (ret)
+ return ret;
+ sunxi_gpio_set_pull(phy->gpio_id_det,
+ SUNXI_GPIO_PULL_UP);
+ }
}
setbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
if (phy->gpio_vbus_det >= 0)
gpio_free(phy->gpio_vbus_det);
+
+ if (phy->gpio_id_det >= 0)
+ gpio_free(phy->gpio_id_det);
}
return 0;
#error "CONFIG_STM32_HSE_HZ not defined!"
#else
#if (CONFIG_STM32_HSE_HZ == 8000000)
-struct pll_psc pll_psc_168 = {
+#if (CONFIG_SYS_CLK_FREQ == 180000000)
+/* 180 MHz */
+struct pll_psc sys_pll_psc = {
+ .pll_m = 8,
+ .pll_n = 360,
+ .pll_p = 2,
+ .pll_q = 8,
+ .ahb_psc = AHB_PSC_1,
+ .apb1_psc = APB_PSC_4,
+ .apb2_psc = APB_PSC_2
+};
+#else
+/* default 168 MHz */
+struct pll_psc sys_pll_psc = {
.pll_m = 8,
.pll_n = 336,
.pll_p = 2,
.apb1_psc = APB_PSC_4,
.apb2_psc = APB_PSC_2
};
+#endif
#else
#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists"
#endif
while (!(readl(&STM32_RCC->cr) & RCC_CR_HSERDY))
;
- /* Enable high performance mode, System frequency up to 168 MHz */
+ /* Enable high performance mode, System frequency up to 180 MHz */
setbits_le32(&STM32_RCC->apb1enr, RCC_APB1ENR_PWREN);
writel(PWR_CR_VOS_SCALE_MODE_1, &STM32_PWR->cr);
setbits_le32(&STM32_RCC->cfgr, ((
- pll_psc_168.ahb_psc << RCC_CFGR_HPRE_SHIFT)
- | (pll_psc_168.apb1_psc << RCC_CFGR_PPRE1_SHIFT)
- | (pll_psc_168.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
-
- writel(pll_psc_168.pll_m
- | (pll_psc_168.pll_n << RCC_PLLCFGR_PLLN_SHIFT)
- | (((pll_psc_168.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT)
- | (pll_psc_168.pll_q << RCC_PLLCFGR_PLLQ_SHIFT),
+ sys_pll_psc.ahb_psc << RCC_CFGR_HPRE_SHIFT)
+ | (sys_pll_psc.apb1_psc << RCC_CFGR_PPRE1_SHIFT)
+ | (sys_pll_psc.apb2_psc << RCC_CFGR_PPRE2_SHIFT)));
+
+ writel(sys_pll_psc.pll_m
+ | (sys_pll_psc.pll_n << RCC_PLLCFGR_PLLN_SHIFT)
+ | (((sys_pll_psc.pll_p >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT)
+ | (sys_pll_psc.pll_q << RCC_PLLCFGR_PLLQ_SHIFT),
&STM32_RCC->pllcfgr);
setbits_le32(&STM32_RCC->pllcfgr, RCC_PLLCFGR_PLLSRC);
obj-y += transition.o
obj-$(CONFIG_FSL_LSCH3) += fsl-lsch3/
-obj-$(CONFIG_TARGET_XILINX_ZYNQMP) += zynqmp/
+obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/
/* to activate the MMU we need to set up virtual memory */
static void mmu_setup(void)
{
- int i, j, el;
bd_t *bd = gd->bd;
- u64 *page_table = (u64 *)gd->arch.tlb_addr;
+ u64 *page_table = (u64 *)gd->arch.tlb_addr, i, j;
+ int el;
/* Setup an identity-mapping for all spaces */
for (i = 0; i < (PGTABLE_SIZE >> 3); i++) {
return (get_sctlr() & CR_C) != 0;
}
+u64 *__weak arch_get_page_table(void) {
+ puts("No page table offset defined\n");
+
+ return NULL;
+}
+
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+ enum dcache_option option)
+{
+ u64 *page_table = arch_get_page_table();
+ u64 upto, end;
+
+ if (page_table == NULL)
+ return;
+
+ end = ALIGN(start + size, (1 << MMU_SECTION_SHIFT)) >>
+ MMU_SECTION_SHIFT;
+ start = start >> MMU_SECTION_SHIFT;
+ for (upto = start; upto < end; upto++) {
+ page_table[upto] &= ~PMD_ATTRINDX_MASK;
+ page_table[upto] |= PMD_ATTRINDX(option);
+ }
+ asm volatile("dsb sy");
+ __asm_invalidate_tlb_all();
+ asm volatile("dsb sy");
+ asm volatile("isb");
+ start = start << MMU_SECTION_SHIFT;
+ end = end << MMU_SECTION_SHIFT;
+ flush_dcache_range(start, end);
+ asm volatile("dsb sy");
+}
#else /* CONFIG_SYS_DCACHE_OFF */
void invalidate_dcache_all(void)
return 0;
}
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+ enum dcache_option option)
+{
+}
+
#endif /* CONFIG_SYS_DCACHE_OFF */
#ifndef CONFIG_SYS_ICACHE_OFF
This architecture supports Freescale ARMv8 SoCs with Chassis generation 3,
for example LS2085A.
+DDR Layout
+============
+Entire DDR region splits into two regions.
+ - Region 1 is at address 0x8000_0000 to 0xffff_ffff.
+ - Region 2 is at 0x80_8000_0000 to the top of total memory,
+ for example 16GB, 0x83_ffff_ffff.
+
+All DDR memory is marked as cache-enabled.
+
+When MC and Debug server is enabled, they carve 512MB away from the high
+end of DDR. For example, if the total DDR is 16GB, it shrinks to 15.5GB
+with MC and Debug server enabled. Linux only sees 15.5GB.
+
+The reserved 512MB layout looks like
+
+ +---------------+ <-- top/end of memory
+ | 256MB | debug server
+ +---------------+
+ | 256MB | MC
+ +---------------+
+ | ... |
+
+MC requires the memory to be aligned with 512MB, so even debug server is
+not enabled, 512MB is reserved, not 256MB.
+
Flash Layout
============
#include <asm/system.h>
#include <asm/armv8/mmu.h>
#include <asm/io.h>
+#include <asm/arch-fsl-lsch3/soc.h>
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
#include <fsl_debug_server.h>
#include <fsl-mc/fsl_mc.h>
DECLARE_GLOBAL_DATA_PTR;
+static struct cpu_type cpu_type_list[] = {
+#ifdef CONFIG_LS2085A
+ CPU_TYPE_ENTRY(LS2085, LS2085, 8),
+ CPU_TYPE_ENTRY(LS2080, LS2080, 8),
+ CPU_TYPE_ENTRY(LS2045, LS2045, 4),
+#endif
+};
+
+void cpu_name(char *name)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int i, svr, ver;
+
+ svr = in_le32(&gur->svr);
+ ver = SVR_SOC_VER(svr);
+
+ for (i = 0; i < ARRAY_SIZE(cpu_type_list); i++)
+ if ((cpu_type_list[i].soc_ver & SVR_WO_E) == ver) {
+ strcpy(name, cpu_type_list[i].name);
+
+ if (IS_E_PROCESSOR(svr))
+ strcat(name, "E");
+ break;
+ }
+
+ if (i == ARRAY_SIZE(cpu_type_list))
+ strcpy(name, "unknown");
+}
+
#ifndef CONFIG_SYS_DCACHE_OFF
/*
* To start MMU before DDR is available, we create MMU table in SRAM.
TCR_ORGN_NC | \
TCR_IRGN_NC | \
TCR_T0SZ(LSCH3_VA_BITS))
+#define LSCH3_TCR_FINAL (TCR_TG0_4K | \
+ TCR_EL2_PS_40BIT | \
+ TCR_SHARED_OUTER | \
+ TCR_ORGN_WBWA | \
+ TCR_IRGN_WBWA | \
+ TCR_T0SZ(LSCH3_VA_BITS))
/*
* Final MMU
/* point TTBR to the new table */
el = current_el();
- asm volatile("dsb sy");
- if (el == 1) {
- asm volatile("msr ttbr0_el1, %0"
- : : "r" ((u64)level0_table) : "memory");
- } else if (el == 2) {
- asm volatile("msr ttbr0_el2, %0"
- : : "r" ((u64)level0_table) : "memory");
- } else if (el == 3) {
- asm volatile("msr ttbr0_el3, %0"
- : : "r" ((u64)level0_table) : "memory");
- } else {
- hang();
- }
- asm volatile("isb");
-
+ set_ttbr_tcr_mair(el, (u64)level0_table, LSCH3_TCR_FINAL,
+ MEMORY_ATTRIBUTES);
/*
* MMU is already enabled, just need to invalidate TLB to load the
* new table. The new table is compatible with the current table, if
unsigned int i, core;
u32 type;
+ puts("SoC: ");
+
+ cpu_name(buf);
+ printf(" %s (0x%x)\n", buf, in_le32(&gur->svr));
+
+ memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
+
get_sys_info(&sysinfo);
puts("Clock Configuration:");
for_each_cpu(i, core, cpu_numcores(), cpu_mask()) {
}
printf("\n Bus: %-4s MHz ",
strmhz(buf, sysinfo.freq_systembus));
- printf("DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus));
- printf(" DP-DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus2));
+ printf("DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus));
+ printf(" DP-DDR: %-4s MT/s", strmhz(buf, sysinfo.freq_ddrbus2));
puts("\n");
/* Display the RCW, so that no one gets confused as to what RCW
#include <common.h>
#include <libfdt.h>
#include <fdt_support.h>
+#include <asm/arch-fsl-lsch3/fdt.h>
#ifdef CONFIG_FSL_ESDHC
#include <fsl_esdhc.h>
#endif
}
#endif
+/*
+ * the burden is on the the caller to not request a count
+ * exceeding the bounds of the stream_ids[] array
+ */
+void alloc_stream_ids(int start_id, int count, u32 *stream_ids, int max_cnt)
+{
+ int i;
+
+ if (count > max_cnt) {
+ printf("\n%s: ERROR: max per-device stream ID count exceed\n",
+ __func__);
+ return;
+ }
+
+ for (i = 0; i < count; i++)
+ stream_ids[i] = start_id++;
+}
+
+/*
+ * This function updates the mmu-masters property on the SMMU
+ * node as per the SMMU binding-- phandle and list of stream IDs
+ * for each MMU master.
+ */
+void append_mmu_masters(void *blob, const char *smmu_path,
+ const char *master_name, u32 *stream_ids, int count)
+{
+ u32 phandle;
+ int smmu_nodeoffset;
+ int master_nodeoffset;
+ int i;
+
+ /* get phandle of mmu master device */
+ master_nodeoffset = fdt_path_offset(blob, master_name);
+ if (master_nodeoffset < 0) {
+ printf("\n%s: ERROR: master not found\n", __func__);
+ return;
+ }
+ phandle = fdt_get_phandle(blob, master_nodeoffset);
+ if (!phandle) { /* if master has no phandle, create one */
+ phandle = fdt_create_phandle(blob, master_nodeoffset);
+ if (!phandle) {
+ printf("\n%s: ERROR: unable to create phandle\n",
+ __func__);
+ return;
+ }
+ }
+
+ /* append it to mmu-masters */
+ smmu_nodeoffset = fdt_path_offset(blob, smmu_path);
+ if (fdt_appendprop_u32(blob, smmu_nodeoffset, "mmu-masters",
+ phandle) < 0) {
+ printf("\n%s: ERROR: unable to update SMMU node\n", __func__);
+ return;
+ }
+
+ /* for each stream ID, append to mmu-masters */
+ for (i = 0; i < count; i++) {
+ fdt_appendprop_u32(blob, smmu_nodeoffset, "mmu-masters",
+ stream_ids[i]);
+ }
+
+ /* fix up #stream-id-cells with stream ID count */
+ if (fdt_setprop_u32(blob, master_nodeoffset, "#stream-id-cells",
+ count) < 0)
+ printf("\n%s: ERROR: unable to update #stream-id-cells\n",
+ __func__);
+}
+
+
+/*
+ * The info below summarizes how streamID partitioning works
+ * for ls2085a and how it is conveyed to the OS via the device tree.
+ *
+ * -non-PCI legacy, platform devices (USB, SD/MMC, SATA, DMA)
+ * -all legacy devices get a unique ICID assigned and programmed in
+ * their AMQR registers by u-boot
+ * -u-boot updates the hardware device tree with streamID properties
+ * for each platform/legacy device (smmu-masters property)
+ *
+ * -PCIe
+ * -for each PCI controller that is active (as per RCW settings),
+ * u-boot will allocate a range of ICID and convey that to Linux via
+ * the device tree (smmu-masters property)
+ *
+ * -DPAA2
+ * -u-boot will allocate a range of ICIDs to be used by the Management
+ * Complex for containers and will set these values in the MC DPC image.
+ * -the MC is responsible for allocating and setting up ICIDs
+ * for all DPAA2 devices.
+ *
+ */
+static void fdt_fixup_smmu(void *blob)
+{
+ int nodeoffset;
+
+ nodeoffset = fdt_path_offset(blob, "/iommu@5000000");
+ if (nodeoffset < 0) {
+ printf("\n%s: WARNING: no SMMU node found\n", __func__);
+ return;
+ }
+
+ /* fixup for all PCI controllers */
+#ifdef CONFIG_PCI
+ fdt_fixup_smmu_pcie(blob);
+#endif
+}
+
void ft_cpu_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_MP
"clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
#endif
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
+#endif
+
#if defined(CONFIG_FSL_ESDHC)
fdt_fixup_esdhc(blob, bd);
#endif
+
+ fdt_fixup_smmu(blob);
}
switch (clk) {
case MXC_I2C_CLK:
return get_bus_freq(0) / 2;
+ case MXC_DSPI_CLK:
+ return get_bus_freq(0) / 2;
default:
printf("Unsupported clock\n");
}
#ifdef CONFIG_ARM_ERRATA_828024
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
/* Disable non-allocate hint of w-b-n-a memory type */
- mov x0, #0x1 << 49
+ orr x0, x0, #1 << 49
/* Disable write streaming no L1-allocate threshold */
- mov x0, #0x3 << 25
+ orr x0, x0, #3 << 25
/* Disable write streaming no-allocate threshold */
- mov x0, #0x3 << 27
+ orr x0, x0, #3 << 27
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
#endif
#ifdef CONFIG_ARM_ERRATA_826974
mrs x0, S3_1_c15_c2_0 /* cpuactlr_el1 */
/* Disable speculative load execution ahead of a DMB */
- mov x0, #0x1 << 59
+ orr x0, x0, #1 << 59
msr S3_1_c15_c2_0, x0 /* cpuactlr_el1 */
#endif
--- /dev/null
+if ARCH_ZYNQMP
+
+choice
+ prompt "Xilinx ZynqMP board select"
+
+config TARGET_ZYNQMP_EP
+ bool "ZynqMP EP Board"
+
+endchoice
+
+config SYS_BOARD
+ default "zynqmp"
+
+config SYS_VENDOR
+ default "xilinx"
+
+config SYS_SOC
+ default "zynqmp"
+
+config SYS_CONFIG_NAME
+ default "xilinx_zynqmp_ep" if TARGET_ZYNQMP_EP
+
+endif
obj-y += clk.o
obj-y += cpu.o
obj-$(CONFIG_MP) += mp.o
+obj-y += slcr.o
printf("R5 lockstep mode\n");
set_r5_tcm_mode(LOCK);
set_r5_halt_mode(HALT, LOCK);
-
- if (boot_addr == 0)
- set_r5_start(0);
- else
- set_r5_start(1);
-
+ set_r5_start(boot_addr);
enable_clock_r5();
release_r5_reset(LOCK);
set_r5_halt_mode(RELEASE, LOCK);
--- /dev/null
+/*
+ * (C) Copyright 2014 - 2015 Xilinx, Inc.
+ * Michal Simek <michal.simek@xilinx.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <malloc.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/clk.h>
+
+/*
+ * zynq_slcr_mio_get_status - Get the status of MIO peripheral.
+ *
+ * @peri_name: Name of the peripheral for checking MIO status
+ * @get_pins: Pointer to array of get pin for this peripheral
+ * @num_pins: Number of pins for this peripheral
+ * @mask: Mask value
+ * @check_val: Required check value to get the status of periph
+ */
+struct zynq_slcr_mio_get_status {
+ const char *peri_name;
+ const int *get_pins;
+ int num_pins;
+ u32 mask;
+ u32 check_val;
+};
+
+static const struct zynq_slcr_mio_get_status mio_periphs[] = {
+};
+
+/*
+ * zynq_slcr_get_mio_pin_status - Get the MIO pin status of peripheral.
+ *
+ * @periph: Name of the peripheral
+ *
+ * Returns count to indicate the number of pins configured for the
+ * given @periph.
+ */
+int zynq_slcr_get_mio_pin_status(const char *periph)
+{
+ const struct zynq_slcr_mio_get_status *mio_ptr;
+ int val, i, j;
+ int mio = 0;
+
+ for (i = 0; i < ARRAY_SIZE(mio_periphs); i++) {
+ if (strcmp(periph, mio_periphs[i].peri_name) == 0) {
+ mio_ptr = &mio_periphs[i];
+ for (j = 0; j < mio_ptr->num_pins; j++) {
+ val = readl(&slcr_base->mio_pin
+ [mio_ptr->get_pins[j]]);
+ if ((val & mio_ptr->mask) == mio_ptr->check_val)
+ mio++;
+ }
+ break;
+ }
+ }
+
+ return mio;
+}
}
. = ALIGN(4);
- .u_boot_list : {
- KEEP(*(SORT(.u_boot_list*_i2c_*)));
- }
-
- . = .;
#ifdef CONFIG_SPL_DM
.u_boot_list : {
KEEP(*(SORT(.u_boot_list_*_driver_*)));
KEEP(*(SORT(.u_boot_list_*_uclass_*)));
}
#endif
+ . = .;
+ .u_boot_list : {
+ KEEP(*(SORT(.u_boot_list*_i2c_*)));
+ }
+
. = ALIGN(4);
__image_copy_end = .;
. = ALIGN(4);
__bss_end = .;
}
-
+ __bss_size = __bss_end - __bss_start;
.dynsym _image_binary_end : { *(.dynsym) }
.dynbss : { *(.dynbss) }
.dynstr : { *(.dynstr*) }
tegra114-dalmore.dtb \
tegra124-jetson-tk1.dtb \
tegra124-nyan-big.dtb \
- tegra124-venice2.dtb
+ tegra124-venice2.dtb \
+ tegra210-p2571.dtb
dtb-$(CONFIG_ARCH_UNIPHIER) += \
uniphier-ph1-sld3-ref.dtb \
uniphier-ph1-pro4-ref.dtb \
zynq-microzed.dtb \
zynq-picozed.dtb \
zynq-zc770-xm010.dtb \
+ zynq-zc770-xm011.dtb \
zynq-zc770-xm012.dtb \
zynq-zc770-xm013.dtb
dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb
dtb-$(CONFIG_LS102XA) += ls1021a-qds.dtb \
ls1021a-twr.dtb
+dtb-$(CONFIG_FSL_LSCH3) += fsl-ls2085a-qds.dtb \
+ fsl-ls2085a-rdb.dtb
dtb-$(CONFIG_MACH_SUN4I) += \
sun4i-a10-a1000.dtb \
--- /dev/null
+/*
+ * Freescale ls2085a QDS board device tree source
+ *
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "fsl-ls2085a.dtsi"
+
+/ {
+ model = "Freescale Layerscape 2085a QDS Board";
+ compatible = "fsl,ls2085a-qds", "fsl,ls2085a";
+
+ aliases {
+ spi1 = &dspi;
+ };
+};
+
+&dspi {
+ bus-num = <0>;
+ status = "okay";
+
+ dflash0: n25q128a {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <3000000>;
+ spi-cpol;
+ spi-cpha;
+ reg = <0>;
+ };
+ dflash1: sst25wf040b {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <3000000>;
+ spi-cpol;
+ spi-cpha;
+ reg = <1>;
+ };
+ dflash2: en25s64 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <3000000>;
+ spi-cpol;
+ spi-cpha;
+ reg = <2>;
+ };
+};
--- /dev/null
+/*
+ * Freescale ls2085a RDB board device tree source
+ *
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+
+#include "fsl-ls2085a.dtsi"
+
+/ {
+ model = "Freescale Layerscape 2085a RDB Board";
+ compatible = "fsl,ls2085a-rdb", "fsl,ls2085a";
+
+ aliases {
+ spi1 = &dspi;
+ };
+};
+
+&dspi {
+ bus-num = <0>;
+ status = "okay";
+
+ dflash0: n25q512a {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <3000000>;
+ spi-cpol;
+ spi-cpha;
+ reg = <0>;
+ };
+};
--- /dev/null
+/*
+ * Freescale ls2085a SOC common device tree source
+ *
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/ {
+ compatible = "fsl,ls2085a";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ /*
+ * We expect the enable-method for cpu's to be "psci", but this
+ * is dependent on the SoC FW, which will fill this in.
+ *
+ * Currently supported enable-method is psci v0.2
+ */
+
+ /* We have 4 clusters having 2 Cortex-A57 cores each */
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x0>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x1>;
+ };
+
+ cpu@100 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x100>;
+ };
+
+ cpu@101 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x101>;
+ };
+
+ cpu@200 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x200>;
+ };
+
+ cpu@201 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x201>;
+ };
+
+ cpu@300 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x300>;
+ };
+
+ cpu@301 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a57";
+ reg = <0x0 0x301>;
+ };
+ };
+
+ memory@80000000 {
+ device_type = "memory";
+ reg = <0x00000000 0x80000000 0 0x80000000>;
+ /* DRAM space - 1, size : 2 GB DRAM */
+ };
+
+ gic: interrupt-controller@6000000 {
+ compatible = "arm,gic-v3";
+ reg = <0x0 0x06000000 0 0x10000>, /* GIC Dist */
+ <0x0 0x06100000 0 0x100000>; /* GICR (RD_base + SGI_base) */
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ interrupts = <1 9 0x4>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <1 13 0x8>, /* Physical Secure PPI, active-low */
+ <1 14 0x8>, /* Physical Non-Secure PPI, active-low */
+ <1 11 0x8>, /* Virtual PPI, active-low */
+ <1 10 0x8>; /* Hypervisor PPI, active-low */
+ };
+
+ serial0: serial@21c0500 {
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21c0500 0x0 0x100>;
+ clock-frequency = <0>; /* Updated by bootloader */
+ interrupts = <0 32 0x1>; /* edge triggered */
+ };
+
+ serial1: serial@21c0600 {
+ device_type = "serial";
+ compatible = "fsl,ns16550", "ns16550a";
+ reg = <0x0 0x21c0600 0x0 0x100>;
+ clock-frequency = <0>; /* Updated by bootloader */
+ interrupts = <0 32 0x1>; /* edge triggered */
+ };
+
+ fsl_mc: fsl-mc@80c000000 {
+ compatible = "fsl,qoriq-mc";
+ reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
+ <0x00000000 0x08340000 0 0x40000>; /* MC control reg */
+ };
+
+ dspi: dspi@2100000 {
+ compatible = "fsl,vf610-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0 0x2100000 0x0 0x10000>;
+ interrupts = <0 26 0x4>; /* Level high type */
+ num-cs = <6>;
+ };
+};
model = "Utoo P66";
compatible = "utoo,p66", "allwinner,sun5i-a13";
- aliases {
- serial0 = &uart1;
- };
-
- chosen {
- stdout-path = "serial0:115200n8";
- };
-
i2c_lcd: i2c@0 {
/* The lcd panel i2c interface is hooked up via gpios */
compatible = "i2c-gpio";
status = "okay";
};
-&uart1 {
- pinctrl-names = "default";
- pinctrl-0 = <&uart1_pins_b>;
- status = "okay";
-};
-
&usbphy {
usb0_vbus-supply = <®_usb0_vbus>;
usb1_vbus-supply = <®_ldo3>;
#size-cells = <0>;
};
+ ehci0: usb@01c1a000 {
+ compatible = "allwinner,sun8i-a23-ehci", "generic-ehci";
+ reg = <0x01c1a000 0x100>;
+ interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 26>;
+ resets = <&ahb1_rst 26>;
+ status = "disabled";
+ };
+
+ ohci0: usb@01c1a400 {
+ compatible = "allwinner,sun8i-a23-ohci", "generic-ohci";
+ reg = <0x01c1a400 0x100>;
+ interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ahb1_gates 29>, <&usb_clk 16>;
+ resets = <&ahb1_rst 29>;
+ status = "disabled";
+ };
+
pio: pinctrl@01c20800 {
/* compatible gets set in SoC specific dtsi file */
reg = <0x01c20800 0x400>;
};
};
+&ehci0 {
+ status = "okay";
+};
+
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c0_pins_a>;
status = "okay";
};
+&ohci0 {
+ status = "okay";
+};
+
&pio {
mmc0_cd_pin_q8h: mmc0_cd_pin@0 {
allwinner,pins = "PB4";
--- /dev/null
+/dts-v1/;
+
+#include "tegra210.dtsi"
+
+/ {
+ model = "NVIDIA P2571";
+ compatible = "nvidia,p2571", "nvidia,tegra210";
+
+ chosen {
+ stdout-path = &uarta;
+ };
+
+ aliases {
+ i2c0 = "/i2c@0,7000d000";
+ i2c1 = "/i2c@0,7000c000";
+ i2c2 = "/i2c@0,7000c400";
+ i2c3 = "/i2c@0,7000c500";
+ i2c4 = "/i2c@0,7000c700";
+ i2c5 = "/i2c@0,7000d100";
+ sdhci0 = "/sdhci@0,700b0600";
+ sdhci1 = "/sdhci@0,700b0000";
+ spi0 = "/spi@0,7000d400";
+ spi1 = "/spi@0,7000da00";
+ spi2 = "/spi@0,70410000";
+ usb0 = "/usb@0,7d000000";
+ };
+
+ memory {
+ reg = <0x0 0x80000000 0x0 0xc0000000>;
+ };
+
+ i2c@0,7000c000 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@0,7000c400 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@0,7000c500 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@0,7000c700 {
+ status = "okay";
+ clock-frequency = <100000>;
+ };
+
+ i2c@0,7000d000 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+
+ i2c@0,7000d100 {
+ status = "okay";
+ clock-frequency = <400000>;
+ };
+
+ spi@0,7000d400 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ };
+
+ spi@0,7000da00 {
+ status = "okay";
+ spi-max-frequency = <25000000>;
+ };
+
+ spi@0,70410000 {
+ status = "okay";
+ spi-max-frequency = <24000000>;
+ };
+
+ sdhci@0,700b0000 {
+ status = "okay";
+ cd-gpios = <&gpio TEGRA_GPIO(Z, 1) GPIO_ACTIVE_LOW>;
+ power-gpios = <&gpio TEGRA_GPIO(Z, 4) GPIO_ACTIVE_HIGH>;
+ bus-width = <4>;
+ };
+
+ sdhci@0,700b0600 {
+ status = "okay";
+ bus-width = <8>;
+ };
+
+ usb@0,7d000000 {
+ status = "okay";
+ dr_mode = "otg";
+ };
+
+ clocks {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ clk32k_in: clock@0 {
+ compatible = "fixed-clock";
+ reg = <0>;
+ #clock-cells = <0>;
+ clock-frequency = <32768>;
+ };
+ };
+};
--- /dev/null
+#include <dt-bindings/clock/tegra210-car.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
+
+#include "skeleton.dtsi"
+
+/ {
+ compatible = "nvidia,tegra210";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ gic: interrupt-controller@0,50041000 {
+ compatible = "arm,gic-400";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x0 0x50041000 0x0 0x1000>,
+ <0x0 0x50042000 0x0 0x2000>,
+ <0x0 0x50044000 0x0 0x2000>,
+ <0x0 0x50046000 0x0 0x2000>;
+ interrupts = <GIC_PPI 9
+ (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
+ interrupt-parent = <&gic>;
+ };
+
+ tegra_car: clock@0,60006000 {
+ compatible = "nvidia,tegra210-car";
+ reg = <0x0 0x60006000 0x0 0x1000>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+ };
+
+ gpio: gpio@0,6000d000 {
+ compatible = "nvidia,tegra210-gpio", "nvidia,tegra30-gpio";
+ reg = <0x0 0x6000d000 0x0 0x1000>;
+ interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+ };
+
+ i2c@0,7000c000 {
+ compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000c000 0x0 0x100>;
+ interrupts = <0 38 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 12>;
+ status = "disabled";
+ };
+
+ i2c@0,7000c400 {
+ compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000c400 0x0 0x100>;
+ interrupts = <0 84 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 54>;
+ status = "disabled";
+ };
+
+ i2c@0,7000c500 {
+ compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000c500 0x0 0x100>;
+ interrupts = <0 92 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 67>;
+ status = "disabled";
+ };
+
+ i2c@0,7000c700 {
+ compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000c700 0x0 0x100>;
+ interrupts = <0 120 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 103>;
+ status = "disabled";
+ };
+
+ i2c@0,7000d000 {
+ compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000d000 0x0 0x100>;
+ interrupts = <0 53 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 47>;
+ status = "disabled";
+ };
+
+ i2c@0,7000d100 {
+ compatible = "nvidia,tegra210-i2c", "nvidia,tegra114-i2c";
+ reg = <0x0 0x7000d100 0x0 0x100>;
+ interrupts = <0 53 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 47>;
+ status = "disabled";
+ };
+
+ uarta: serial@0,70006000 {
+ compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006000 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_UARTA>;
+ resets = <&tegra_car 6>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ uartb: serial@0,70006040 {
+ compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006040 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_UARTB>;
+ resets = <&tegra_car 7>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ uartc: serial@0,70006200 {
+ compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006200 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_UARTC>;
+ resets = <&tegra_car 55>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ uartd: serial@0,70006300 {
+ compatible = "nvidia,tegra210-uart", "nvidia,tegra20-uart";
+ reg = <0x0 0x70006300 0x0 0x40>;
+ reg-shift = <2>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&tegra_car TEGRA210_CLK_UARTD>;
+ resets = <&tegra_car 65>;
+ reset-names = "serial";
+ status = "disabled";
+ };
+
+ spi@0,7000d400 {
+ compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000d400 0x0 0x200>;
+ interrupts = <0 59 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA210_CLK_SBC1>;
+ resets = <&tegra_car 41>;
+ reset-names = "spi";
+ status = "disabled";
+ };
+
+ spi@0,7000d600 {
+ compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000d600 0x0 0x200>;
+ interrupts = <0 82 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA210_CLK_SBC2>;
+ resets = <&tegra_car 44>;
+ reset-names = "spi";
+ status = "disabled";
+ };
+
+ spi@0,7000d800 {
+ compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000d800 0x0 0x200>;
+ interrupts = <0 83 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA210_CLK_SBC3>;
+ resets = <&tegra_car 46>;
+ reset-names = "spi";
+ status = "disabled";
+ };
+
+ spi@0,7000da00 {
+ compatible = "nvidia,tegra210-spi", "nvidia,tegra114-spi";
+ reg = <0x0 0x7000da00 0x0 0x200>;
+ interrupts = <0 93 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car TEGRA210_CLK_SBC4>;
+ resets = <&tegra_car 68>;
+ reset-names = "spi";
+ status = "disabled";
+ };
+
+ spi@0,70410000 {
+ compatible = "nvidia,tegra210-qspi";
+ reg = <0x0 0x70410000 0x0 0x1000>;
+ interrupts = <0 10 0x04>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ clocks = <&tegra_car 211>;
+ status = "disabled";
+ };
+
+ padctl: padctl@0,7009f000 {
+ compatible = "nvidia,tegra210-xusb-padctl";
+ reg = <0x0 0x7009f000 0x0 0x1000>;
+ resets = <&tegra_car 142>;
+ reset-names = "padctl";
+ #phy-cells = <1>;
+ };
+
+ sdhci@0,700b0000 {
+ compatible = "nvidia,tegra210-sdhci";
+ reg = <0x0 0x700b0000 0x0 0x200>;
+ interrupts = <0 14 0x04>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC1>;
+ resets = <&tegra_car 14>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0200 {
+ compatible = "nvidia,tegra210-sdhci";
+ reg = <0x0 0x700b0200 0x0 0x200>;
+ interrupts = <0 15 0x04>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC2>;
+ resets = <&tegra_car 9>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0400 {
+ compatible = "nvidia,tegra210-sdhci";
+ reg = <0x0 0x700b0400 0x0 0x200>;
+ interrupts = <0 19 0x04>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC3>;
+ resets = <&tegra_car 69>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ sdhci@0,700b0600 {
+ compatible = "nvidia,tegra210-sdhci";
+ reg = <0x0 0x700b0600 0x0 0x200>;
+ interrupts = <0 31 0x04>;
+ clocks = <&tegra_car TEGRA210_CLK_SDMMC4>;
+ resets = <&tegra_car 15>;
+ reset-names = "sdhci";
+ status = "disabled";
+ };
+
+ usb@0,7d000000 {
+ compatible = "nvidia,tegra210-ehci";
+ reg = <0x0 0x7d000000 0x0 0x4000>;
+ interrupts = <0 20 0x04>;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA210_CLK_USBD>;
+ resets = <&tegra_car 22>;
+ reset-names = "usb";
+ status = "disabled";
+ };
+
+ usb@0,7d004000 {
+ compatible = "nvidia,tegra210-ehci";
+ reg = <0x0 0x7d004000 0x0 0x4000>;
+ interrupts = < 53 >;
+ phy_type = "utmi";
+ clocks = <&tegra_car TEGRA210_CLK_USB2>;
+ resets = <&tegra_car 58>;
+ reset-names = "usb";
+ status = "disabled";
+ };
+};
status = "disabled";
};
+ i2c4: i2c@58600000 {
+ compatible = "panasonic,uniphier-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x58600000 0x40>;
+ clock-frequency = <400000>;
+ status = "okay";
+ };
+
system-bus-controller-misc@59800000 {
compatible = "socionext,uniphier-system-bus-controller-misc",
"syscon";
&i2c0 {
eeprom {
- compatible = "i2c-eeprom";
+ compatible = "microchip,24lc128", "i2c-eeprom";
reg = <0x50>;
u-boot,i2c-offset-len = <2>;
};
* Xilinx Zynq 7000 DTSI
* Describes the hardware common to all Zynq 7000-based boards.
*
- * Copyright (C) 2013 Xilinx, Inc.
+ * Copyright (C) 2011 - 2015 Xilinx
*
* SPDX-License-Identifier: GPL-2.0+
*/
reg = <0>;
clocks = <&clkc 3>;
clock-latency = <1000>;
+ cpu0-supply = <®ulator_vccpint>;
operating-points = <
/* kHz uV */
666667 1000000
333334 1000000
- 222223 1000000
>;
};
reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;
};
- amba {
+ regulator_vccpint: fixedregulator@0 {
+ compatible = "regulator-fixed";
+ regulator-name = "VCCPINT";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ amba: amba {
compatible = "simple-bus";
#address-cells = <1>;
#size-cells = <1>;
interrupt-parent = <&intc>;
ranges;
- i2c0: zynq-i2c@e0004000 {
+ adc: adc@f8007100 {
+ compatible = "xlnx,zynq-xadc-1.00.a";
+ reg = <0xf8007100 0x20>;
+ interrupts = <0 7 4>;
+ interrupt-parent = <&intc>;
+ clocks = <&clkc 12>;
+ };
+
+ can0: can@e0008000 {
+ compatible = "xlnx,zynq-can-1.0";
+ status = "disabled";
+ clocks = <&clkc 19>, <&clkc 36>;
+ clock-names = "can_clk", "pclk";
+ reg = <0xe0008000 0x1000>;
+ interrupts = <0 28 4>;
+ interrupt-parent = <&intc>;
+ tx-fifo-depth = <0x40>;
+ rx-fifo-depth = <0x40>;
+ };
+
+ can1: can@e0009000 {
+ compatible = "xlnx,zynq-can-1.0";
+ status = "disabled";
+ clocks = <&clkc 20>, <&clkc 37>;
+ clock-names = "can_clk", "pclk";
+ reg = <0xe0009000 0x1000>;
+ interrupts = <0 51 4>;
+ interrupt-parent = <&intc>;
+ tx-fifo-depth = <0x40>;
+ rx-fifo-depth = <0x40>;
+ };
+
+ gpio0: gpio@e000a000 {
+ compatible = "xlnx,zynq-gpio-1.0";
+ #gpio-cells = <2>;
+ clocks = <&clkc 42>;
+ gpio-controller;
+ interrupt-parent = <&intc>;
+ interrupts = <0 20 4>;
+ reg = <0xe000a000 0x1000>;
+ };
+
+ i2c0: i2c@e0004000 {
compatible = "cdns,i2c-r1p10";
status = "disabled";
clocks = <&clkc 38>;
#size-cells = <0>;
};
- i2c1: zynq-i2c@e0005000 {
+ i2c1: i2c@e0005000 {
compatible = "cdns,i2c-r1p10";
status = "disabled";
clocks = <&clkc 39>;
intc: interrupt-controller@f8f01000 {
compatible = "arm,cortex-a9-gic";
#interrupt-cells = <3>;
- #address-cells = <1>;
interrupt-controller;
reg = <0xF8F01000 0x1000>,
<0xF8F00100 0x100>;
};
- L2: cache-controller {
+ L2: cache-controller@f8f02000 {
compatible = "arm,pl310-cache";
reg = <0xF8F02000 0x1000>;
+ interrupts = <0 2 4>;
arm,data-latency = <3 2 2>;
arm,tag-latency = <2 2 2>;
cache-unified;
cache-level = <2>;
};
- uart0: uart@e0000000 {
- compatible = "xlnx,xuartps";
+ mc: memory-controller@f8006000 {
+ compatible = "xlnx,zynq-ddrc-a05";
+ reg = <0xf8006000 0x1000>;
+ };
+
+ uart0: serial@e0000000 {
+ compatible = "xlnx,xuartps", "cdns,uart-r1p8";
status = "disabled";
clocks = <&clkc 23>, <&clkc 40>;
- clock-names = "ref_clk", "aper_clk";
+ clock-names = "uart_clk", "pclk";
reg = <0xE0000000 0x1000>;
interrupts = <0 27 4>;
};
- uart1: uart@e0001000 {
- compatible = "xlnx,xuartps";
+ uart1: serial@e0001000 {
+ compatible = "xlnx,xuartps", "cdns,uart-r1p8";
status = "disabled";
clocks = <&clkc 24>, <&clkc 41>;
- clock-names = "ref_clk", "aper_clk";
+ clock-names = "uart_clk", "pclk";
reg = <0xE0001000 0x1000>;
interrupts = <0 50 4>;
};
spi0: spi@e0006000 {
- compatible = "xlnx,zynq-spi";
+ compatible = "xlnx,zynq-spi-r1p6";
reg = <0xe0006000 0x1000>;
status = "disabled";
interrupt-parent = <&intc>;
};
spi1: spi@e0007000 {
- compatible = "xlnx,zynq-spi";
+ compatible = "xlnx,zynq-spi-r1p6";
reg = <0xe0007000 0x1000>;
status = "disabled";
interrupt-parent = <&intc>;
};
gem0: ethernet@e000b000 {
- compatible = "cdns,gem";
- reg = <0xe000b000 0x4000>;
+ compatible = "cdns,zynq-gem", "cdns,gem";
+ reg = <0xe000b000 0x1000>;
status = "disabled";
interrupts = <0 22 4>;
clocks = <&clkc 30>, <&clkc 30>, <&clkc 13>;
clock-names = "pclk", "hclk", "tx_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
};
gem1: ethernet@e000c000 {
- compatible = "cdns,gem";
- reg = <0xe000c000 0x4000>;
+ compatible = "cdns,zynq-gem", "cdns,gem";
+ reg = <0xe000c000 0x1000>;
status = "disabled";
interrupts = <0 45 4>;
clocks = <&clkc 31>, <&clkc 31>, <&clkc 14>;
clock-names = "pclk", "hclk", "tx_clk";
+ #address-cells = <1>;
+ #size-cells = <0>;
};
- sdhci0: ps7-sdhci@e0100000 {
+ sdhci0: sdhci@e0100000 {
compatible = "arasan,sdhci-8.9a";
status = "disabled";
clock-names = "clk_xin", "clk_ahb";
reg = <0xe0100000 0x1000>;
} ;
- sdhci1: ps7-sdhci@e0101000 {
+ sdhci1: sdhci@e0101000 {
compatible = "arasan,sdhci-8.9a";
status = "disabled";
clock-names = "clk_xin", "clk_ahb";
slcr: slcr@f8000000 {
#address-cells = <1>;
#size-cells = <1>;
- compatible = "xlnx,zynq-slcr", "syscon";
+ compatible = "xlnx,zynq-slcr", "syscon", "simple-bus";
reg = <0xF8000000 0x1000>;
ranges;
clkc: clkc@100 {
#clock-cells = <1>;
compatible = "xlnx,ps7-clkc";
- ps-clk-frequency = <33333333>;
fclk-enable = <0>;
clock-output-names = "armpll", "ddrpll", "iopll", "cpu_6or4x",
"cpu_3or2x", "cpu_2x", "cpu_1x", "ddr2x", "ddr3x",
"dbg_trc", "dbg_apb";
reg = <0x100 0x100>;
};
+
+ pinctrl0: pinctrl@700 {
+ compatible = "xlnx,pinctrl-zynq";
+ reg = <0x700 0x200>;
+ syscon = <&slcr>;
+ };
+ };
+
+ dmac_s: dmac@f8003000 {
+ compatible = "arm,pl330", "arm,primecell";
+ reg = <0xf8003000 0x1000>;
+ interrupt-parent = <&intc>;
+ interrupt-names = "abort", "dma0", "dma1", "dma2", "dma3",
+ "dma4", "dma5", "dma6", "dma7";
+ interrupts = <0 13 4>,
+ <0 14 4>, <0 15 4>,
+ <0 16 4>, <0 17 4>,
+ <0 40 4>, <0 41 4>,
+ <0 42 4>, <0 43 4>;
+ #dma-cells = <1>;
+ #dma-channels = <8>;
+ #dma-requests = <4>;
+ clocks = <&clkc 27>;
+ clock-names = "apb_pclk";
+ };
+
+ devcfg: devcfg@f8007000 {
+ compatible = "xlnx,zynq-devcfg-1.0";
+ reg = <0xf8007000 0x100>;
};
global_timer: timer@f8f00200 {
clocks = <&clkc 4>;
};
- ttc0: ttc0@f8001000 {
+ ttc0: timer@f8001000 {
interrupt-parent = <&intc>;
- interrupts = < 0 10 4 0 11 4 0 12 4 >;
+ interrupts = <0 10 4>, <0 11 4>, <0 12 4>;
compatible = "cdns,ttc";
clocks = <&clkc 6>;
reg = <0xF8001000 0x1000>;
};
- ttc1: ttc1@f8002000 {
+ ttc1: timer@f8002000 {
interrupt-parent = <&intc>;
- interrupts = < 0 37 4 0 38 4 0 39 4 >;
+ interrupts = <0 37 4>, <0 38 4>, <0 39 4>;
compatible = "cdns,ttc";
clocks = <&clkc 6>;
reg = <0xF8002000 0x1000>;
};
- scutimer: scutimer@f8f00600 {
+
+ scutimer: timer@f8f00600 {
interrupt-parent = <&intc>;
interrupts = < 1 13 0x301 >;
compatible = "arm,cortex-a9-twd-timer";
reg = < 0xf8f00600 0x20 >;
clocks = <&clkc 4>;
} ;
+
+ usb0: usb@e0002000 {
+ compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
+ status = "disabled";
+ clocks = <&clkc 28>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 21 4>;
+ reg = <0xe0002000 0x1000>;
+ phy_type = "ulpi";
+ };
+
+ usb1: usb@e0003000 {
+ compatible = "xlnx,zynq-usb-2.20a", "chipidea,usb2";
+ status = "disabled";
+ clocks = <&clkc 29>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 44 4>;
+ reg = <0xe0003000 0x1000>;
+ phy_type = "ulpi";
+ };
+
+ watchdog0: watchdog@f8005000 {
+ clocks = <&clkc 45>;
+ compatible = "cdns,wdt-r1p2";
+ interrupt-parent = <&intc>;
+ interrupts = <0 9 1>;
+ reg = <0xf8005000 0x1000>;
+ timeout-sec = <10>;
+ };
};
};
/*
* Xilinx ZC702 board DTS
*
- * Copyright (C) 2013 Xilinx, Inc.
+ * Copyright (C) 2011 - 2015 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "zynq-7000.dtsi"
/ {
- model = "Zynq ZC702 Board";
+ model = "Zynq ZC702 Development Board";
compatible = "xlnx,zynq-zc702", "xlnx,zynq-7000";
aliases {
+ ethernet0 = &gem0;
+ i2c0 = &i2c0;
serial0 = &uart1;
};
memory {
device_type = "memory";
- reg = <0 0x40000000>;
+ reg = <0x0 0x40000000>;
};
+
+ chosen {
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ autorepeat;
+ sw14 {
+ label = "sw14";
+ gpios = <&gpio0 12 0>;
+ linux,code = <108>; /* down */
+ gpio-key,wakeup;
+ autorepeat;
+ };
+ sw13 {
+ label = "sw13";
+ gpios = <&gpio0 14 0>;
+ linux,code = <103>; /* up */
+ gpio-key,wakeup;
+ autorepeat;
+ };
+ };
+
+ leds {
+ compatible = "gpio-leds";
+
+ ds23 {
+ label = "ds23";
+ gpios = <&gpio0 10 0>;
+ linux,default-trigger = "heartbeat";
+ };
+ };
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&amba {
+ ocm: sram@fffc0000 {
+ compatible = "mmio-sram";
+ reg = <0xfffc0000 0x10000>;
+ };
+};
+
+&can0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_can0_default>;
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <ðernet_phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gem0_default>;
+
+ ethernet_phy: ethernet-phy@7 {
+ reg = <7>;
+ };
+};
+
+&gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ i2cswitch@74 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x74>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ si570: clock-generator@5d {
+ #clock-cells = <0>;
+ compatible = "silabs,si570";
+ temperature-stability = <50>;
+ reg = <0x5d>;
+ factory-fout = <156250000>;
+ clock-frequency = <148500000>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ eeprom@54 {
+ compatible = "at,24c08";
+ reg = <0x54>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ gpio@21 {
+ compatible = "ti,tca6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ hwmon@52 {
+ compatible = "ti,ucd9248";
+ reg = <52>;
+ };
+ hwmon@53 {
+ compatible = "ti,ucd9248";
+ reg = <53>;
+ };
+ hwmon@54 {
+ compatible = "ti,ucd9248";
+ reg = <54>;
+ };
+ };
+ };
+};
+
+&pinctrl0 {
+ pinctrl_can0_default: can0-default {
+ mux {
+ function = "can0";
+ groups = "can0_9_grp";
+ };
+
+ conf {
+ groups = "can0_9_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO46";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO47";
+ bias-disable;
+ };
+ };
+
+ pinctrl_gem0_default: gem0-default {
+ mux {
+ function = "ethernet0";
+ groups = "ethernet0_0_grp";
+ };
+
+ conf {
+ groups = "ethernet0_0_grp";
+ slew-rate = <0>;
+ io-standard = <4>;
+ };
+
+ conf-rx {
+ pins = "MIO22", "MIO23", "MIO24", "MIO25", "MIO26", "MIO27";
+ bias-high-impedance;
+ low-power-disable;
+ };
+
+ conf-tx {
+ pins = "MIO16", "MIO17", "MIO18", "MIO19", "MIO20", "MIO21";
+ bias-disable;
+ low-power-enable;
+ };
+
+ mux-mdio {
+ function = "mdio0";
+ groups = "mdio0_0_grp";
+ };
+
+ conf-mdio {
+ groups = "mdio0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio0_default: gpio0-default {
+ mux {
+ function = "gpio0";
+ groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",
+ "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
+ "gpio0_13_grp", "gpio0_14_grp";
+ };
+
+ conf {
+ groups = "gpio0_7_grp", "gpio0_8_grp", "gpio0_9_grp",
+ "gpio0_10_grp", "gpio0_11_grp", "gpio0_12_grp",
+ "gpio0_13_grp", "gpio0_14_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-pull-up {
+ pins = "MIO9", "MIO10", "MIO11", "MIO12", "MIO13", "MIO14";
+ bias-pull-up;
+ };
+
+ conf-pull-none {
+ pins = "MIO7", "MIO8";
+ bias-disable;
+ };
+ };
+
+ pinctrl_i2c0_default: i2c0-default {
+ mux {
+ groups = "i2c0_10_grp";
+ function = "i2c0";
+ };
+
+ conf {
+ groups = "i2c0_10_grp";
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_sdhci0_default: sdhci0-default {
+ mux {
+ groups = "sdio0_2_grp";
+ function = "sdio0";
+ };
+
+ conf {
+ groups = "sdio0_2_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+
+ mux-cd {
+ groups = "gpio0_0_grp";
+ function = "sdio0_cd";
+ };
+
+ conf-cd {
+ groups = "gpio0_0_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ mux-wp {
+ groups = "gpio0_15_grp";
+ function = "sdio0_wp";
+ };
+
+ conf-wp {
+ groups = "gpio0_15_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_uart1_default: uart1-default {
+ mux {
+ groups = "uart1_10_grp";
+ function = "uart1";
+ };
+
+ conf {
+ groups = "uart1_10_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO49";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO48";
+ bias-disable;
+ };
+ };
+
+ pinctrl_usb0_default: usb0-default {
+ mux {
+ groups = "usb0_0_grp";
+ function = "usb0";
+ };
+
+ conf {
+ groups = "usb0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO29", "MIO31", "MIO36";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO28", "MIO30", "MIO32", "MIO33", "MIO34",
+ "MIO35", "MIO37", "MIO38", "MIO39";
+ bias-disable;
+ };
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhci0_default>;
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_default>;
};
/*
* Xilinx ZC706 board DTS
*
- * Copyright (C) 2013 Xilinx, Inc.
+ * Copyright (C) 2011 - 2015 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "zynq-7000.dtsi"
/ {
- model = "Zynq ZC706 Board";
+ model = "Zynq ZC706 Development Board";
compatible = "xlnx,zynq-zc706", "xlnx,zynq-7000";
aliases {
+ ethernet0 = &gem0;
+ i2c0 = &i2c0;
serial0 = &uart1;
};
memory {
device_type = "memory";
- reg = <0 0x40000000>;
+ reg = <0x0 0x40000000>;
};
+
+ chosen {
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
+ };
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <ðernet_phy>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gem0_default>;
+
+ ethernet_phy: ethernet-phy@7 {
+ reg = <7>;
+ };
+};
+
+&gpio0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_gpio0_default>;
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c0_default>;
+
+ i2cswitch@74 {
+ compatible = "nxp,pca9548";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x74>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ si570: clock-generator@5d {
+ #clock-cells = <0>;
+ compatible = "silabs,si570";
+ temperature-stability = <50>;
+ reg = <0x5d>;
+ factory-fout = <156250000>;
+ clock-frequency = <148500000>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <2>;
+ eeprom@54 {
+ compatible = "at,24c08";
+ reg = <0x54>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <3>;
+ gpio@21 {
+ compatible = "ti,tca6416";
+ reg = <0x21>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+ };
+
+ i2c@4 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <4>;
+ rtc@51 {
+ compatible = "nxp,pcf8563";
+ reg = <0x51>;
+ };
+ };
+
+ i2c@7 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <7>;
+ ucd90120@65 {
+ compatible = "ti,ucd90120";
+ reg = <0x65>;
+ };
+ };
+ };
+};
+
+&pinctrl0 {
+ pinctrl_gem0_default: gem0-default {
+ mux {
+ function = "ethernet0";
+ groups = "ethernet0_0_grp";
+ };
+
+ conf {
+ groups = "ethernet0_0_grp";
+ slew-rate = <0>;
+ io-standard = <4>;
+ };
+
+ conf-rx {
+ pins = "MIO22", "MIO23", "MIO24", "MIO25", "MIO26", "MIO27";
+ bias-high-impedance;
+ low-power-disable;
+ };
+
+ conf-tx {
+ pins = "MIO16", "MIO17", "MIO18", "MIO19", "MIO20", "MIO21";
+ low-power-enable;
+ bias-disable;
+ };
+
+ mux-mdio {
+ function = "mdio0";
+ groups = "mdio0_0_grp";
+ };
+
+ conf-mdio {
+ groups = "mdio0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+ };
+
+ pinctrl_gpio0_default: gpio0-default {
+ mux {
+ function = "gpio0";
+ groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
+ };
+
+ conf {
+ groups = "gpio0_7_grp", "gpio0_46_grp", "gpio0_47_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-pull-up {
+ pins = "MIO46", "MIO47";
+ bias-pull-up;
+ };
+
+ conf-pull-none {
+ pins = "MIO7";
+ bias-disable;
+ };
+ };
+
+ pinctrl_i2c0_default: i2c0-default {
+ mux {
+ groups = "i2c0_10_grp";
+ function = "i2c0";
+ };
+
+ conf {
+ groups = "i2c0_10_grp";
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_sdhci0_default: sdhci0-default {
+ mux {
+ groups = "sdio0_2_grp";
+ function = "sdio0";
+ };
+
+ conf {
+ groups = "sdio0_2_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ bias-disable;
+ };
+
+ mux-cd {
+ groups = "gpio0_14_grp";
+ function = "sdio0_cd";
+ };
+
+ conf-cd {
+ groups = "gpio0_14_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ mux-wp {
+ groups = "gpio0_15_grp";
+ function = "sdio0_wp";
+ };
+
+ conf-wp {
+ groups = "gpio0_15_grp";
+ bias-high-impedance;
+ bias-pull-up;
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+ };
+
+ pinctrl_uart1_default: uart1-default {
+ mux {
+ groups = "uart1_10_grp";
+ function = "uart1";
+ };
+
+ conf {
+ groups = "uart1_10_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO49";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO48";
+ bias-disable;
+ };
+ };
+
+ pinctrl_usb0_default: usb0-default {
+ mux {
+ groups = "usb0_0_grp";
+ function = "usb0";
+ };
+
+ conf {
+ groups = "usb0_0_grp";
+ slew-rate = <0>;
+ io-standard = <1>;
+ };
+
+ conf-rx {
+ pins = "MIO29", "MIO31", "MIO36";
+ bias-high-impedance;
+ };
+
+ conf-tx {
+ pins = "MIO28", "MIO30", "MIO32", "MIO33", "MIO34",
+ "MIO35", "MIO37", "MIO38", "MIO39";
+ bias-disable;
+ };
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sdhci0_default>;
+};
+
+&uart1 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_default>;
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usb0_default>;
};
/*
* Xilinx ZC770 XM010 board DTS
*
- * Copyright (C) 2013 Xilinx, Inc.
+ * Copyright (C) 2013 - 2015 Xilinx, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "zynq-7000.dtsi"
/ {
- model = "Zynq ZC770 XM010 Board";
compatible = "xlnx,zynq-zc770-xm010", "xlnx,zynq-7000";
+ model = "Xilinx Zynq";
aliases {
+ ethernet0 = &gem0;
+ i2c0 = &i2c0;
serial0 = &uart1;
- spi1 = &spi1;
+ spi0 = &spi1;
};
- memory {
+ chosen {
+ bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+ linux,stdout-path = &uart1;
+ stdout-path = &uart1;
+ };
+
+ memory@0 {
device_type = "memory";
- reg = <0 0x40000000>;
+ reg = <0x0 0x40000000>;
+ };
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
};
};
&spi1 {
status = "okay";
+ num-cs = <4>;
+ is-decoded-cs = <0>;
+ flash@0 {
+ compatible = "sst25wf080";
+ reg = <1>;
+ spi-max-frequency = <1000000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ partition@test {
+ label = "spi-flash";
+ reg = <0x0 0x100000>;
+ };
+ };
+};
+
+&can0 {
+ status = "okay";
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <ðernet_phy>;
+
+ ethernet_phy: ethernet-phy@7 {
+ reg = <7>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ m24c02_eeprom@52 {
+ compatible = "at,24c02";
+ reg = <0x52>;
+ };
+
+};
+
+&sdhci0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
};
--- /dev/null
+/*
+ * Xilinx ZC770 XM013 board DTS
+ *
+ * Copyright (C) 2013 Xilinx, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+/dts-v1/;
+#include "zynq-7000.dtsi"
+/ {
+ compatible = "xlnx,zynq-zc770-xm011", "xlnx,zynq-7000";
+ model = "Xilinx Zynq";
+
+ aliases {
+ i2c0 = &i2c1;
+ serial0 = &uart1;
+ spi0 = &spi0;
+ };
+
+ chosen {
+ bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+ linux,stdout-path = &uart1;
+ stdout-path = &uart1;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x40000000>;
+ };
+
+ usb_phy1: phy1 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&spi0 {
+ status = "okay";
+ num-cs = <4>;
+ is-decoded-cs = <0>;
+};
+
+&can0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ m24c02_eeprom@52 {
+ compatible = "at,24c02";
+ reg = <0x52>;
+ };
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&usb1 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy1>;
+};
/*
* Xilinx ZC770 XM012 board DTS
*
- * Copyright (C) 2013 Xilinx, Inc.
+ * Copyright (C) 2013 - 2015 Xilinx, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "zynq-7000.dtsi"
/ {
- model = "Zynq ZC770 XM012 Board";
compatible = "xlnx,zynq-zc770-xm012", "xlnx,zynq-7000";
+ model = "Xilinx Zynq";
aliases {
+ i2c0 = &i2c0;
+ i2c1 = &i2c1;
serial0 = &uart1;
+ spi0 = &spi1;
};
- memory {
+ chosen {
+ bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+ linux,stdout-path = &uart1;
+ stdout-path = &uart1;
+ };
+
+ memory@0 {
device_type = "memory";
- reg = <0 0x40000000>;
+ reg = <0x0 0x40000000>;
+ };
+};
+
+&spi1 {
+ status = "okay";
+ num-cs = <4>;
+ is-decoded-cs = <0>;
+};
+
+&can1 {
+ status = "okay";
+};
+
+&i2c0 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ m24c02_eeprom@52 {
+ compatible = "at,24c02";
+ reg = <0x52>;
+ };
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ m24c02_eeprom@52 {
+ compatible = "at,24c02";
+ reg = <0x52>;
};
};
+
+&uart1 {
+ status = "okay";
+};
#include "zynq-7000.dtsi"
/ {
- model = "Zynq ZC770 XM013 Board";
compatible = "xlnx,zynq-zc770-xm013", "xlnx,zynq-7000";
+ model = "Xilinx Zynq";
aliases {
+ ethernet0 = &gem1;
+ i2c0 = &i2c1;
serial0 = &uart0;
+ spi0 = &spi0;
};
- memory {
+ chosen {
+ bootargs = "console=ttyPS0,115200 root=/dev/ram rw earlyprintk";
+ linux,stdout-path = &uart0;
+ stdout-path = &uart0;
+ };
+
+ memory@0 {
device_type = "memory";
- reg = <0 0x40000000>;
+ reg = <0x0 0x40000000>;
+ };
+};
+
+&spi0 {
+ status = "okay";
+ num-cs = <4>;
+ is-decoded-cs = <0>;
+ eeprom: at25@0 {
+ at25,byte-len = <8192>;
+ at25,addr-mode = <2>;
+ at25,page-size = <32>;
+
+ compatible = "atmel,at25";
+ reg = <2>;
+ spi-max-frequency = <1000000>;
+ };
+};
+
+&can1 {
+ status = "okay";
+};
+
+&gem1 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <ðernet_phy>;
+
+ ethernet_phy: ethernet-phy@7 {
+ reg = <7>;
};
};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <400000>;
+
+ si570: clock-generator@55 {
+ #clock-cells = <0>;
+ compatible = "silabs,si570";
+ temperature-stability = <50>;
+ reg = <0x55>;
+ factory-fout = <156250000>;
+ clock-frequency = <148500000>;
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
/*
* Xilinx ZED board DTS
*
- * Copyright (C) 2013 Xilinx, Inc.
+ * Copyright (C) 2011 - 2015 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "zynq-7000.dtsi"
/ {
- model = "Zynq ZED Board";
+ model = "Zynq Zed Development Board";
compatible = "xlnx,zynq-zed", "xlnx,zynq-7000";
aliases {
+ ethernet0 = &gem0;
serial0 = &uart1;
};
memory {
device_type = "memory";
- reg = <0 0x20000000>;
+ reg = <0x0 0x20000000>;
};
+
+ chosen {
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
+ };
+
+ usb_phy0: phy0 {
+ compatible = "usb-nop-xceiv";
+ #phy-cells = <0>;
+ };
+};
+
+&clkc {
+ ps-clk-frequency = <33333333>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <ðernet_phy>;
+
+ ethernet_phy: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
+
+&usb0 {
+ status = "okay";
+ dr_mode = "host";
+ usb-phy = <&usb_phy0>;
};
/*
* Digilent ZYBO board DTS
*
- * Copyright (C) 2013 Xilinx, Inc.
+ * Copyright (C) 2011 - 2015 Xilinx
+ * Copyright (C) 2012 National Instruments Corp.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include "zynq-7000.dtsi"
/ {
- model = "Zynq ZYBO Board";
- compatible = "xlnx,zynq-zybo", "xlnx,zynq-7000";
+ model = "Zynq ZYBO Development Board";
+ compatible = "digilent,zynq-zybo", "xlnx,zynq-7000";
aliases {
+ ethernet0 = &gem0;
serial0 = &uart1;
};
memory {
device_type = "memory";
- reg = <0 0x20000000>;
+ reg = <0x0 0x20000000>;
};
+
+ chosen {
+ bootargs = "earlyprintk";
+ stdout-path = "serial0:115200n8";
+ };
+
+};
+
+&clkc {
+ ps-clk-frequency = <50000000>;
+};
+
+&gem0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <ðernet_phy>;
+
+ ethernet_phy: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&sdhci0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
};
#define AM4372_BOARD_VERSION_END SRAM_SCRATCH_SPACE_ADDR + 0x14
#define QSPI_BASE 0x47900000
#endif
+
+/* Boot parameters */
+#ifndef __ASSEMBLY__
+struct omap_boot_parameters {
+ unsigned int reserved;
+ unsigned int boot_device_descriptor;
+ unsigned char boot_device;
+ unsigned char reset_reason;
+};
+#endif
+
#endif
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
-#if defined(CONFIG_TI816X)
-#define BOOT_DEVICE_XIP 2
-#define BOOT_DEVICE_NAND 3
-#define BOOT_DEVICE_MMC1 6
-#define BOOT_DEVICE_MMC2 5
+#define BOOT_DEVICE_NONE 0x00
+#define BOOT_DEVICE_MMC2_2 0xFF
+
+#if defined(CONFIG_TI814X)
+#define BOOT_DEVICE_XIP 0x01
+#define BOOT_DEVICE_XIPWAIT 0x02
+#define BOOT_DEVICE_NAND 0x05
+#define BOOT_DEVICE_NAND_I2C 0x06
+#define BOOT_DEVICE_MMC2 0x08 /* ROM only supports 2nd instance. */
+#define BOOT_DEVICE_MMC1 0x09
+#define BOOT_DEVICE_SPI 0x15
+#define BOOT_DEVICE_UART 0x41
+#define BOOT_DEVICE_USBETH 0x44
+#define BOOT_DEVICE_CPGMAC 0x46
+
+#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC2
+#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC1
+#elif defined(CONFIG_TI816X)
+#define BOOT_DEVICE_XIP 0x01
+#define BOOT_DEVICE_XIPWAIT 0x02
+#define BOOT_DEVICE_NAND 0x03
+#define BOOT_DEVICE_ONENAD 0x04
+#define BOOT_DEVICE_MMC2 0x05 /* ROM only supports 2nd instance. */
+#define BOOT_DEVICE_MMC1 0x06
#define BOOT_DEVICE_UART 0x43
-#elif defined(CONFIG_AM43XX)
-#define BOOT_DEVICE_NOR 1
-#define BOOT_DEVICE_NAND 5
-#define BOOT_DEVICE_MMC1 7
-#define BOOT_DEVICE_MMC2 8
-#define BOOT_DEVICE_SPI 10
-#define BOOT_DEVICE_USB 13
-#define BOOT_DEVICE_UART 65
-#define BOOT_DEVICE_CPGMAC 71
-#else
-#define BOOT_DEVICE_XIP 2
-#define BOOT_DEVICE_NAND 5
-#define BOOT_DEVICE_NAND_I2C 6
-#if defined(CONFIG_AM33XX)
-#define BOOT_DEVICE_MMC1 8
-#define BOOT_DEVICE_MMC2 9 /* eMMC or daughter card */
-#elif defined(CONFIG_TI814X)
-#define BOOT_DEVICE_MMC1 9
-#define BOOT_DEVICE_MMC2 8 /* ROM only supports 2nd instance */
-#endif
-#define BOOT_DEVICE_SPI 11
-#define BOOT_DEVICE_UART 65
-#define BOOT_DEVICE_USBETH 68
-#define BOOT_DEVICE_CPGMAC 70
-#endif
-#define BOOT_DEVICE_MMC2_2 0xFF
+#define BOOT_DEVICE_USB 0x45
-#if defined(CONFIG_AM33XX)
-#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC1
-#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC2
+#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC2
+#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC1
+#elif defined(CONFIG_AM33XX)
+#define BOOT_DEVICE_XIP 0x01
+#define BOOT_DEVICE_XIPWAIT 0x02
+#define BOOT_DEVICE_NAND 0x05
+#define BOOT_DEVICE_NAND_I2C 0x06
+#define BOOT_DEVICE_MMC1 0x08
+#define BOOT_DEVICE_MMC2 0x09
+#define BOOT_DEVICE_SPI 0x15
+#define BOOT_DEVICE_UART 0x41
+#define BOOT_DEVICE_USBETH 0x44
+#define BOOT_DEVICE_CPGMAC 0x46
+
+#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC1
+#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC2
#elif defined(CONFIG_AM43XX)
-#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC1
+#define BOOT_DEVICE_NOR 0x01
+#define BOOT_DEVICE_NAND 0x05
+#define BOOT_DEVICE_MMC1 0x07
+#define BOOT_DEVICE_MMC2 0x08
+#define BOOT_DEVICE_SPI 0x0A
+#define BOOT_DEVICE_UART 0x41
+#define BOOT_DEVICE_USB 0x45
+#define BOOT_DEVICE_CPGMAC 0x47
+
+#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC1
#ifdef CONFIG_SPL_USB_SUPPORT
-#define MMC_BOOT_DEVICES_END BOOT_DEVICE_USB
+#define MMC_BOOT_DEVICES_END BOOT_DEVICE_USB
#else
-#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC2
+#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC2
#endif
-#elif defined(CONFIG_TI81XX)
-#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC2
-#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC1
#endif
+
#endif
#ifndef _SYS_PROTO_H_
#define _SYS_PROTO_H_
#include <linux/mtd/omap_gpmc.h>
-#include <asm/ti-common/sys_proto.h>
#include <asm/arch/cpu.h>
u32 get_cpu_rev(void);
--- /dev/null
+/*
+ * Copyright (C) 2013 - ARM Ltd
+ * Author: Marc Zyngier <marc.zyngier@arm.com>
+ *
+ * Based on code by Carl van Schaik <carl@ok-labs.com>.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _GENERICTIMER_H_
+#define _GENERICTIMER_H_
+
+#ifdef __ASSEMBLY__
+
+/*
+ * This macro provide a physical timer that can be used for delay in the code.
+ * The macro is moved from sunxi/psci_sun7i.S
+ *
+ * reg: is used in this macro.
+ * ticks: The freq is based on generic timer.
+ */
+.macro timer_wait reg, ticks
+ movw \reg, #(\ticks & 0xffff)
+ movt \reg, #(\ticks >> 16)
+ mcr p15, 0, \reg, c14, c2, 0
+ isb
+ mov \reg, #3
+ mcr p15, 0, \reg, c14, c2, 1
+1 : isb
+ mrc p15, 0, \reg, c14, c2, 1
+ ands \reg, \reg, #4
+ bne 1b
+ mov \reg, #0
+ mcr p15, 0, \reg, c14, c2, 1
+ isb
+.endm
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* _GENERICTIMER_H_ */
#define SECWD2_BASE_ADDR 0x35002f40
#define TIMER_BASE_ADDR 0x3e00d000
+#define HSOTG_DCTL_OFFSET 0x00000804
+#define HSOTG_DCTL_SFTDISCON_MASK 0x00000002
+
+#define HSOTG_CTRL_PHY_P1CTL_OFFSET 0x00000008
+#define HSOTG_CTRL_PHY_P1CTL_SOFT_RESET_MASK 0x00000002
+#define HSOTG_CTRL_PHY_P1CTL_NON_DRIVING_MASK 0x00000001
+
#endif
MXC_UART_CLK,
MXC_ESDHC_CLK,
MXC_I2C_CLK,
+ MXC_DSPI_CLK,
};
unsigned int mxc_get_clock(enum mxc_clock clk);
#define DCFG_PORSR1 0x000
#define DCFG_PORSR1_RCW_SRC 0xff800000
#define DCFG_PORSR1_RCW_SRC_NOR 0x12f00000
+#define DCFG_RCWSR13 0x130
+#define DCFG_RCWSR13_DSPI (0 << 8)
#define DCFG_DCSR_BASE 0X700100000ULL
#define DCFG_DCSR_PORCR1 0x000
--- /dev/null
+/*
+ * Copyright 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+void alloc_stream_ids(int start_id, int count, u32 *stream_ids, int max_cnt);
+void append_mmu_masters(void *blob, const char *smmu_path,
+ const char *master_name, u32 *stream_ids, int count);
+void fdt_fixup_smmu_pcie(void *blob);
--- /dev/null
+/*
+ * Copyright 2014 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ */
+#ifndef __FSL_STREAM_ID_H
+#define __FSL_STREAM_ID_H
+
+/* Stream IDs on ls2085a devices are not hardwired and are
+ * programmed by sw. There are a limited number of stream IDs
+ * available, and the partitioning of them is scenario dependent.
+ * This header defines the partitioning between legacy, PCI,
+ * and DPAA2 devices.
+ *
+ * This partitiong can be customized in this file depending
+ * on the specific hardware config-- e.g. perhaps not all
+ * PEX controllers are in use.
+ *
+ * On LS2085 stream IDs are programmed in AMQ registers (32-bits) for
+ * each of the different bus masters. The relationship between
+ * the AMQ registers and stream IDs is defined in the table below:
+ * AMQ bit streamID bit
+ * ---------------------------
+ * PL[18] 9
+ * BMT[17] 8
+ * VA[16] 7
+ * [15] -
+ * ICID[14:7] -
+ * ICID[6:0] 6-0
+ * ----------------------------
+ */
+
+#define AMQ_PL_MASK (0x1 << 18) /* priviledge bit */
+#define AMQ_BMT_MASK (0x1 << 17) /* bypass bit */
+
+#define FSL_INVALID_STREAM_ID 0
+
+#define FSL_BYPASS_AMQ (AMQ_PL_MASK | AMQ_BMT_MASK)
+
+/* legacy devices */
+#define FSL_USB1_STREAM_ID 1
+#define FSL_USB2_STREAM_ID 2
+#define FSL_SDMMC_STREAM_ID 3
+#define FSL_SATA1_STREAM_ID 4
+#define FSL_SATA2_STREAM_ID 5
+#define FSL_DMA_STREAM_ID 6
+
+/* PCI - programmed in PEXn_LUT by OS */
+/* 4 IDs per controller */
+#define FSL_PEX1_STREAM_ID_START 7
+#define FSL_PEX1_STREAM_ID_END 10
+#define FSL_PEX2_STREAM_ID_START 11
+#define FSL_PEX2_STREAM_ID_END 14
+#define FSL_PEX3_STREAM_ID_START 15
+#define FSL_PEX3_STREAM_ID_END 18
+#define FSL_PEX4_STREAM_ID_START 19
+#define FSL_PEX4_STREAM_ID_END 22
+
+/* DPAA2 - set in MC DPC and alloced by MC */
+#define FSL_DPAA2_STREAM_ID_START 23
+#define FSL_DPAA2_STREAM_ID_END 63
+
+#endif
* SPDX-License-Identifier: GPL-2.0+
*/
+struct cpu_type {
+ char name[15];
+ u32 soc_ver;
+ u32 num_cores;
+};
+
+#define CPU_TYPE_ENTRY(n, v, nc) \
+ { .name = #n, .soc_ver = SVR_##v, .num_cores = (nc)}
+
+#define SVR_WO_E 0xFFFFFE
+#define SVR_LS2045 0x870120
+#define SVR_LS2080 0x870110
+#define SVR_LS2085 0x870100
+
+#define SVR_MAJ(svr) (((svr) >> 4) & 0xf)
+#define SVR_MIN(svr) (((svr) >> 0) & 0xf)
+#define SVR_SOC_VER(svr) (((svr) >> 8) & SVR_WO_E)
+#define IS_E_PROCESSOR(svr) (!((svr >> 8) & 0x1))
+
void fsl_lsch3_early_init_f(void);
+void cpu_name(char *name);
#define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x011c0500)
#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011d0500)
#define CONFIG_SYS_DCU_ADDR (CONFIG_SYS_IMMR + 0x01ce0000)
+#define CONFIG_SYS_LS102XA_XHCI_USB1_ADDR (CONFIG_SYS_IMMR + 0x02100000)
#define CONFIG_SYS_LS102XA_USB1_ADDR \
(CONFIG_SYS_IMMR + CONFIG_SYS_LS102XA_USB1_OFFSET)
#define SCFG_ETSECCMCR_GE1_CLK125 0x08000000
#define SCFG_PIXCLKCR_PXCKEN 0x80000000
#define SCFG_QSPI_CLKSEL 0xc0100000
+#define SCFG_ENDIANCR_LE 0x80000000
/* Supplemental Configuration Unit */
struct ccsr_scfg {
u32 qos2;
u32 qos3;
u32 cci_cfg;
- u32 resv8[1];
+ u32 endiancr;
u32 etsecdmamcr;
u32 usb3prm3cr;
u32 resv9[1];
} pcounter[4]; /* Performance Counter */
u8 res_e004[0x10000 - 0xe004];
};
+
#endif /* __ASM_ARCH_LS102XA_IMMAP_H_ */
#define NON_SECURE_SRAM_START 0x40208000 /* Works for GP & EMU */
#define NON_SECURE_SRAM_END 0x40210000
+#define SRAM_SCRATCH_SPACE_ADDR 0x4020E000
#define LOW_LEVEL_SRAM_STACK 0x4020FFFC
/* ABB tranxdone mask */
#define OMAP_ABB_MPU_TXDONE_MASK (0x1 << 26)
+/* Boot parameters */
+#ifndef __ASSEMBLY__
+struct omap_boot_parameters {
+ unsigned int boot_message;
+ unsigned char boot_device;
+ unsigned char reserved;
+ unsigned char reset_reason;
+ unsigned char ch_flags;
+ unsigned int boot_device_descriptor;
+};
+#endif
+
#endif
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
-#define BOOT_DEVICE_NONE 0
-#define BOOT_DEVICE_XIP 1
-#define BOOT_DEVICE_NAND 2
-#define BOOT_DEVICE_ONENAND 3
-#define BOOT_DEVICE_MMC2 5 /*emmc*/
-#define BOOT_DEVICE_MMC1 6
-#define BOOT_DEVICE_XIPWAIT 7
-#define BOOT_DEVICE_MMC2_2 0xFF
+#define BOOT_DEVICE_NONE 0x00
+#define BOOT_DEVICE_XIP 0x01
+#define BOOT_DEVICE_NAND 0x02
+#define BOOT_DEVICE_ONENAND 0x03
+#define BOOT_DEVICE_MMC2 0x05
+#define BOOT_DEVICE_MMC1 0x06
+#define BOOT_DEVICE_XIPWAIT 0x07
+#define BOOT_DEVICE_MMC2_2 0x08
+#define BOOT_DEVICE_UART 0x10
+#define BOOT_DEVICE_USB 0x11
#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC2
#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC1
u32 get_cpu_family(void);
u32 get_cpu_rev(void);
u32 get_sku_id(void);
-u32 get_sysboot_value(void);
u32 is_gpmc_muxed(void);
u32 get_gpmc0_type(void);
u32 get_gpmc0_width(void);
void do_omap3_emu_romcode_call(u32 service_id, u32 parameters);
void omap3_set_aux_cr_secure(u32 acr);
u32 warm_reset(void);
+
+void save_omap_boot_params(void);
#endif
/* ABB tranxdone mask */
#define OMAP_ABB_MPU_TXDONE_MASK (0x1 << 7)
+/* Boot parameters */
+#ifndef __ASSEMBLY__
+struct omap_boot_parameters {
+ unsigned int boot_message;
+ unsigned int boot_device_descriptor;
+ unsigned char boot_device;
+ unsigned char reset_reason;
+ unsigned char ch_flags;
+};
+#endif
+
#endif
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
-#define BOOT_DEVICE_NONE 0
-#define BOOT_DEVICE_XIP 1
-#define BOOT_DEVICE_XIPWAIT 2
-#define BOOT_DEVICE_NAND 3
-#define BOOT_DEVICE_ONENAND 4
-#define BOOT_DEVICE_MMC1 5
-#define BOOT_DEVICE_MMC2 6
-#define BOOT_DEVICE_MMC2_2 0xFF
+#define BOOT_DEVICE_NONE 0x00
+#define BOOT_DEVICE_XIP 0x01
+#define BOOT_DEVICE_XIPWAIT 0x02
+#define BOOT_DEVICE_NAND 0x03
+#define BOOT_DEVICE_ONENAND 0x04
+#define BOOT_DEVICE_MMC1 0x05
+#define BOOT_DEVICE_MMC2 0x06
+#define BOOT_DEVICE_MMC2_2 0x07
+#define BOOT_DEVICE_UART 0x43
+#define BOOT_DEVICE_USB 0x45
#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC1
-#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC2
+#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC2_2
#endif
};
#endif /* __ASSEMBLY__ */
+
+/* Boot parameters */
+#ifndef __ASSEMBLY__
+struct omap_boot_parameters {
+ unsigned int boot_message;
+ unsigned int boot_device_descriptor;
+ unsigned char boot_device;
+ unsigned char reset_reason;
+ unsigned char ch_flags;
+};
+#endif
+
#endif
#ifndef _ASM_ARCH_SPL_H_
#define _ASM_ARCH_SPL_H_
-#define BOOT_DEVICE_NONE 0
-#define BOOT_DEVICE_XIP 1
-#define BOOT_DEVICE_XIPWAIT 2
-#define BOOT_DEVICE_NAND 3
-#define BOOT_DEVICE_ONENAND 4
-#define BOOT_DEVICE_MMC1 5
-#define BOOT_DEVICE_MMC2 6
-#define BOOT_DEVICE_MMC2_2 7
-#define BOOT_DEVICE_SATA 9
-#define BOOT_DEVICE_SPI 10
+#define BOOT_DEVICE_NONE 0x00
+#define BOOT_DEVICE_XIP 0x01
+#define BOOT_DEVICE_XIPWAIT 0x02
+#define BOOT_DEVICE_NAND 0x03
+#define BOOT_DEVICE_ONENAND 0x04
+#define BOOT_DEVICE_MMC1 0x05
+#define BOOT_DEVICE_MMC2 0x06
+#define BOOT_DEVICE_MMC2_2 0x07
+#define BOOT_DEVICE_SATA 0x09
+#define BOOT_DEVICE_SPI 0x0A
+#define BOOT_DEVICE_QSPI_1 0x0A
+#define BOOT_DEVICE_QSPI_4 0x0B
#define BOOT_DEVICE_UART 0x43
+#define BOOT_DEVICE_USB 0x45
#define MMC_BOOT_DEVICES_START BOOT_DEVICE_MMC1
#define MMC_BOOT_DEVICES_END BOOT_DEVICE_MMC2_2
/*
* Peripheral memory map
*/
+#define STM32_SYSMEM_BASE 0x1FFF0000
#define STM32_PERIPH_BASE 0x40000000
#define STM32_APB1PERIPH_BASE (STM32_PERIPH_BASE + 0x00000000)
#define STM32_APB2PERIPH_BASE (STM32_PERIPH_BASE + 0x00010000)
/*
* Register maps
*/
+struct stm32_u_id_regs {
+ u32 u_id_low;
+ u32 u_id_mid;
+ u32 u_id_high;
+};
+
struct stm32_rcc_regs {
u32 cr; /* RCC clock control */
u32 pllcfgr; /* RCC PLL configuration */
/*
* Registers access macros
*/
+#define STM32_U_ID_BASE (STM32_SYSMEM_BASE + 0x7A10)
+#define STM32_U_ID ((struct stm32_u_id_regs *)STM32_U_ID_BASE)
+
#define STM32_RCC_BASE (STM32_AHB1PERIPH_BASE + 0x3800)
#define STM32_RCC ((struct stm32_rcc_regs *)STM32_RCC_BASE)
#define SUNXI_MMC_COMMON_RESET (1 << 18)
struct mmc *sunxi_mmc_init(int sdc_no);
+int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc);
#endif /* _SUNXI_MMC_H */
void sunxi_usb_phy_power_on(int index);
void sunxi_usb_phy_power_off(int index);
int sunxi_usb_phy_vbus_detect(int index);
+int sunxi_usb_phy_id_detect(int index);
void sunxi_usb_phy_enable_squelch_detect(int index, int enable);
+
+/* Not really phy related, but we have to declare this somewhere ... */
+#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
+void sunxi_musb_board_init(void);
+#else
+#define sunxi_musb_board_init()
+#endif
/*
- * (C) Copyright 2010-2011
+ * (C) Copyright 2010-2015
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */
#define PG_UP_TAG_0 0x0
-#define CORESIGHT_UNLOCK 0xC5ACCE55;
-
/* AP base physical address of internal SRAM */
#define NV_PA_BASE_SRAM 0x40000000
/* Do any chip-specific cache config */
void config_cache(void);
-#if defined(CONFIG_TEGRA124)
+#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210)
/* Do chip-specific vpr config */
void config_vpr(void);
#else
TEGRA_CLK_REGS_VW = 2, /* Number of clock enable regs V/W */
TEGRA_CLK_SOURCES_VW = 32, /* Number of ppl clock sources V/W */
TEGRA_CLK_SOURCES_X = 32, /* Number of ppl clock sources X */
+ TEGRA_CLK_SOURCES_Y = 18, /* Number of ppl clock sources Y */
};
/* Clock/Reset Controller (CLK_RST_CONTROLLER_) regs */
uint crc_rst_dev_x_set; /* _RST_DEV_X_SET_0, 0x290 */
uint crc_rst_dev_x_clr; /* _RST_DEV_X_CLR_0, 0x294 */
- uint crc_reserved21[23]; /* _reserved_21, 0x298-2f0 */
+ uint crc_clk_out_enb_y; /* _CLK_OUT_ENB_Y_0, 0x298 */
+ uint crc_clk_enb_y_set; /* _CLK_ENB_Y_SET_0, 0x29c */
+ uint crc_clk_enb_y_clr; /* _CLK_ENB_Y_CLR_0, 0x2a0 */
+
+ uint crc_rst_devices_y; /* _RST_DEVICES_Y_0, 0x2a4 */
+ uint crc_rst_dev_y_set; /* _RST_DEV_Y_SET_0, 0x2a8 */
+ uint crc_rst_dev_y_clr; /* _RST_DEV_Y_CLR_0, 0x2ac */
+
+ uint crc_reserved21[17]; /* _reserved_21, 0x2b0-2f0 */
uint crc_dfll_base; /* _DFLL_BASE_0, 0x2f4 */
struct clk_set_clr crc_rst_dev_ex_vw[TEGRA_CLK_REGS_VW];
/* _CLK_ENB_V/W_CLR_0 0x440 ~ 0x44c */
struct clk_set_clr crc_clk_enb_ex_vw[TEGRA_CLK_REGS_VW];
- /* Additional (T114) registers */
+ /* Additional (T114+) registers */
uint crc_rst_cpug_cmplx_set; /* _RST_CPUG_CMPLX_SET_0, 0x450 */
uint crc_rst_cpug_cmplx_clr; /* _RST_CPUG_CMPLX_CLR_0, 0x454 */
uint crc_rst_cpulp_cmplx_set; /* _RST_CPULP_CMPLX_SET_0, 0x458 */
u32 _rsv32_1[7]; /* 0x574-58c */
struct clk_pll_simple plldp; /* _PLLDP_BASE, 0x590 _PLLDP_MISC */
u32 crc_plldp_ss_cfg; /* _PLLDP_SS_CFG, 0x598 */
- u32 _rsrv32_2[25];
- /* Tegra124 */
- uint crc_clk_src_x[TEGRA_CLK_SOURCES_X]; /* XUSB, etc, 0x600-0x678 */
+
+ /* Tegra124+ - skip to 0x600 here for new CLK_SOURCE_ regs */
+ uint _rsrv32_2[25]; /* _0x59C - 0x5FC */
+ uint crc_clk_src_x[TEGRA_CLK_SOURCES_X]; /* XUSB, etc, 0x600-0x67C */
+
+ /* Tegra210 - skip to 0x694 here for new CLK_SOURCE_ regs */
+ uint crc_reserved61[5]; /* _reserved_61, 0x680 - 0x690 */
+ /*
+ * NOTE: PLLA1 regs are in the middle of this Y region. Break this in
+ * two later if PLLA1 is needed, but for now this is cleaner.
+ */
+ uint crc_clk_src_y[TEGRA_CLK_SOURCES_Y]; /* SPARE1, etc, 0x694-0x6D8 */
};
/* CLK_RST_CONTROLLER_CLK_CPU_CMPLX_0 */
#define PLL_DIVP_SHIFT 20
#define PLL_DIVP_MASK (7U << PLL_DIVP_SHIFT)
+/* Special case for T210 PLLU DIVP */
+#define PLLU_DIVP_SHIFT 16
#define PLL_DIVN_SHIFT 8
#define PLL_DIVN_MASK (0x3ffU << PLL_DIVN_SHIFT)
#define PLL_LFCON_SHIFT 4
#define PLL_LFCON_MASK (15U << PLL_LFCON_SHIFT)
+/* CPCON/LFCON replaced by KCP/KVCO in T210 PLLU */
+#define PLLU_KVCO_SHIFT 24
+#define PLLU_KVCO_MASK (3U << PLLU_KVCO_SHIFT)
+#define PLLU_KCP_SHIFT 25
+#define PLLU_KCP_MASK (1U << PLLU_KCP_SHIFT)
+
#define PLLU_VCO_FREQ_SHIFT 20
#define PLLU_VCO_FREQ_MASK (1U << PLLU_VCO_FREQ_SHIFT)
/*
- * (C) Copyright 2010-2012
+ * (C) Copyright 2010-2015
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
#define CHIPID_TEGRA30 0x30
#define CHIPID_TEGRA114 0x35
#define CHIPID_TEGRA124 0x40
+#define CHIPID_TEGRA210 0x21
#endif /* _TEGRA_GP_PADCTRL_H_ */
/*
- * (C) Copyright 2010,2011,2014
+ * (C) Copyright 2010-2015
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
#define CRAIL 0
#define CE0 14
#define C0NC 15
+#define SOR 17
#define PMC_XOFS_SHIFT 1
#define PMC_XOFS_MASK (0x3F << PMC_XOFS_SHIFT)
#define TIMER_MULT_MASK (3 << TIMER_MULT_SHIFT)
#define TIMER_MULT_CPU_SHIFT 2
#define TIMER_MULT_CPU_MASK (3 << TIMER_MULT_CPU_SHIFT)
-#elif defined(CONFIG_TEGRA124)
+#elif defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210)
#define TIMER_MULT_SHIFT 0
#define TIMER_MULT_MASK (7 << TIMER_MULT_SHIFT)
#define TIMER_MULT_CPU_SHIFT 3
#define MULT_2 1
#define MULT_4 2
#define MULT_8 3
-#if defined(CONFIG_TEGRA124)
+#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210)
#define MULT_16 4
#endif
/*
- * (C) Copyright 2010,2011
+ * (C) Copyright 2010-2015
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
SKU_ID_T114_ENG = 0x00, /* Dalmore value, unfused */
SKU_ID_T114_1 = 0x01,
SKU_ID_T124_ENG = 0x00, /* Venice2 value, unfused */
+ SKU_ID_T210_ENG = 0x00, /* unfused value TBD */
};
/*
TEGRA_SOC_T30,
TEGRA_SOC_T114,
TEGRA_SOC_T124,
+ TEGRA_SOC_T210,
TEGRA_SOC_CNT,
TEGRA_SOC_UNKNOWN = -1,
/* USBx_UTMIP_BIAS_CFG1_0 */
#define UTMIP_FORCE_PDTRK_POWERDOWN 1
+#define UTMIP_BIAS_DEBOUNCE_TIMESCALE_SHIFT 8
+#define UTMIP_BIAS_DEBOUNCE_TIMESCALE_MASK \
+ (0x3f << UTMIP_BIAS_DEBOUNCE_TIMESCALE_SHIFT)
#define UTMIP_BIAS_PDTRK_COUNT_SHIFT 3
#define UTMIP_BIAS_PDTRK_COUNT_MASK \
(0x1f << UTMIP_BIAS_PDTRK_COUNT_SHIFT)
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_AHB_H_
+#define _TEGRA210_AHB_H_
+
+struct ahb_ctlr {
+ u32 reserved0; /* 00h */
+ u32 arbitration_disable; /* _ARBITRATION_DISABLE_0, 04h */
+ u32 arbitration_priority_ctrl; /* _ARBITRATION_PRIORITY_CTRL_0,08h */
+ u32 arbitration_usr_protect; /* _ARBITRATION_USR_PROTECT_0, 0ch */
+ u32 gizmo_ahb_mem; /* _GIZMO_AHB_MEM_0, 10h */
+ u32 gizmo_apb_dma; /* _GIZMO_APB_DMA_0, 14h */
+ u32 reserved6[2]; /* 18h, 1ch */
+ u32 gizmo_usb; /* _GIZMO_USB_0, 20h */
+ u32 gizmo_ahb_xbar_bridge; /* _GIZMO_AHB_XBAR_BRIDGE_0, 24h */
+ u32 gizmo_cpu_ahb_bridge; /* _GIZMO_CPU_AHB_BRIDGE_0, 28h */
+ u32 gizmo_cop_ahb_bridge; /* _GIZMO_COP_AHB_BRIDGE_0, 2ch */
+ u32 gizmo_xbar_apb_ctlr; /* _GIZMO_XBAR_APB_CTLR_0, 30h */
+ u32 gizmo_vcp_ahb_bridge; /* _GIZMO_VCP_AHB_BRIDGE_0, 34h */
+ u32 reserved13[2]; /* 38h, 3ch */
+ u32 gizmo_nand; /* _GIZMO_NAND_0, 40h */
+ u32 reserved15; /* 44h */
+ u32 gizmo_sdmmc4; /* _GIZMO_SDMMC4_0, 48h */
+ u32 reserved17; /* 4ch */
+ u32 gizmo_se; /* _GIZMO_SE_0, 50h */
+ u32 gizmo_tzram; /* _GIZMO_TZRAM_0, 54h */
+ u32 reserved20[3]; /* 58h, 5ch, 60h */
+ u32 gizmo_bsev; /* _GIZMO_BSEV_0, 64h */
+ u32 reserved22[3]; /* 68h, 6ch, 70h */
+ u32 gizmo_bsea; /* _GIZMO_BSEA_0, 74h */
+ u32 gizmo_nor; /* _GIZMO_NOR_0, 78h */
+ u32 gizmo_usb2; /* _GIZMO_USB2_0, 7ch */
+ u32 gizmo_usb3; /* _GIZMO_USB3_0, 80h */
+ u32 gizmo_sdmmc1; /* _GIZMO_SDMMC1_0, 84h */
+ u32 gizmo_sdmmc2; /* _GIZMO_SDMMC2_0, 88h */
+ u32 gizmo_sdmmc3; /* _GIZMO_SDMMC3_0, 8ch */
+ u32 reserved30[13]; /* 90h ~ c0h */
+ u32 ahb_wrq_empty; /* _AHB_WRQ_EMPTY_0, c4h */
+ u32 reserved32[5]; /* c8h ~ d8h */
+ u32 ahb_mem_prefetch_cfg_x; /* _AHB_MEM_PREFETCH_CFG_X_0, dch */
+ u32 arbitration_xbar_ctrl; /* _ARBITRATION_XBAR_CTRL_0, e0h */
+ u32 ahb_mem_prefetch_cfg3; /* _AHB_MEM_PREFETCH_CFG3_0, e4h */
+ u32 ahb_mem_prefetch_cfg4; /* _AHB_MEM_PREFETCH_CFG3_0, e8h */
+ u32 avp_ppcs_rd_coh_status; /* _AVP_PPCS_RD_COH_STATUS_0, ech */
+ u32 ahb_mem_prefetch_cfg1; /* _AHB_MEM_PREFETCH_CFG1_0, f0h */
+ u32 ahb_mem_prefetch_cfg2; /* _AHB_MEM_PREFETCH_CFG2_0, f4h */
+ u32 ahbslvmem_status; /* _AHBSLVMEM_STATUS_0, f8h */
+ /* _ARBITRATION_AHB_MEM_WRQUE_MST_ID_0, fch */
+ u32 arbitration_ahb_mem_wrque_mst_id;
+ u32 arbitration_cpu_abort_addr; /* _ARBITRATION_CPU_ABORT_ADDR_0,100h */
+ u32 arbitration_cpu_abort_info; /* _ARBITRATION_CPU_ABORT_INFO_0,104h */
+ u32 arbitration_cop_abort_addr; /* _ARBITRATION_COP_ABORT_ADDR_0,108h */
+ u32 arbitration_cop_abort_info; /* _ARBITRATION_COP_ABORT_INFO_0,10ch */
+ u32 reserved46[4]; /* 110h ~ 11ch */
+ u32 avpc_mccif_fifoctrl; /* _AVPC_MCCIF_FIFOCTRL_0, 120h */
+ u32 timeout_wcoal_avpc; /* _TIMEOUT_WCOAL_AVPC_0, 124h */
+ u32 mpcorelp_mccif_fifoctrl; /* _MPCORELP_MCCIF_FIFOCTRL_0, 128h */
+ u32 mpcore_mccif_fifoctrl; /* _MPCORE_MCCIF_FIFOCTRL_0, 12ch */
+ u32 axicif_fastsync_ctrl; /* AXICIF_FASTSYNC_CTRL_0, 130h */
+ u32 axicif_fastsync_statistics; /* _AXICIF_FASTSYNC_STATISTICS_0,134h */
+ /* _AXICIF_FASTSYNC0_CPUCLK_TO_MCCLK_0, 138h */
+ u32 axicif_fastsync0_cpuclk_to_mcclk;
+ /* _AXICIF_FASTSYNC1_CPUCLK_TO_MCCLK_0, 13ch */
+ u32 axicif_fastsync1_cpuclk_to_mcclk;
+ /* _AXICIF_FASTSYNC2_CPUCLK_TO_MCCLK_0, 140h */
+ u32 axicif_fastsync2_cpuclk_to_mcclk;
+ /* _AXICIF_FASTSYNC0_MCCLK_TO_CPUCLK_0, 144h */
+ u32 axicif_fastsync0_mcclk_to_cpuclk;
+ /* _AXICIF_FASTSYNC1_MCCLK_TO_CPUCLK_0, 148h */
+ u32 axicif_fastsync1_mcclk_to_cpuclk;
+ /* _AXICIF_FASTSYNC2_MCCLK_TO_CPUCLK_0, 14ch */
+ u32 axicif_fastsync2_mcclk_to_cpuclk;
+};
+
+#define PPSB_STOPCLK_ENABLE (1 << 2)
+
+#define GIZ_ENABLE_SPLIT (1 << 0)
+#define GIZ_ENB_FAST_REARB (1 << 2)
+#define GIZ_DONT_SPLIT_AHB_WR (1 << 7)
+
+#define GIZ_USB_IMMEDIATE (1 << 18)
+
+/* AHB_ARBITRATION_XBAR_CTRL_0 0xe0 */
+#define ARBITRATION_XBAR_CTRL_PPSB_ENABLE (1 << 2)
+
+#endif /* _TEGRA210_AHB_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Tegra210 clock PLL tables */
+
+#ifndef _TEGRA210_CLOCK_TABLES_H_
+#define _TEGRA210_CLOCK_TABLES_H_
+
+/* The PLLs supported by the hardware */
+enum clock_id {
+ CLOCK_ID_FIRST,
+ CLOCK_ID_CGENERAL = CLOCK_ID_FIRST,
+ CLOCK_ID_MEMORY,
+ CLOCK_ID_PERIPH,
+ CLOCK_ID_AUDIO,
+ CLOCK_ID_USB,
+ CLOCK_ID_DISPLAY,
+
+ /* now the simple ones */
+ CLOCK_ID_FIRST_SIMPLE,
+ CLOCK_ID_XCPU = CLOCK_ID_FIRST_SIMPLE,
+ CLOCK_ID_EPCI,
+ CLOCK_ID_SFROM32KHZ,
+
+ /* These are the base clocks (inputs to the Tegra SoC) */
+ CLOCK_ID_32KHZ,
+ CLOCK_ID_OSC,
+
+ CLOCK_ID_COUNT, /* number of PLLs */
+
+ /*
+ * These are clock IDs that are used in table clock_source[][]
+ * but will not be assigned as a clock source for any peripheral.
+ */
+ CLOCK_ID_DISPLAY2,
+ CLOCK_ID_CGENERAL_0,
+ CLOCK_ID_CGENERAL_1,
+ CLOCK_ID_CGENERAL2,
+ CLOCK_ID_CGENERAL3,
+ CLOCK_ID_CGENERAL4_0,
+ CLOCK_ID_CGENERAL4_1,
+ CLOCK_ID_CGENERAL4_2,
+ CLOCK_ID_MEMORY2,
+ CLOCK_ID_SRC2,
+
+ CLOCK_ID_NONE = -1,
+};
+
+/* The clocks supported by the hardware */
+enum periph_id {
+ PERIPH_ID_FIRST,
+
+ /* Low word: 31:0 (DEVICES_L) */
+ PERIPH_ID_CPU = PERIPH_ID_FIRST,
+ PERIPH_ID_COP,
+ PERIPH_ID_TRIGSYS,
+ PERIPH_ID_ISPB,
+ PERIPH_ID_RESERVED4,
+ PERIPH_ID_TMR,
+ PERIPH_ID_UART1,
+ PERIPH_ID_UART2,
+
+ /* 8 */
+ PERIPH_ID_GPIO,
+ PERIPH_ID_SDMMC2,
+ PERIPH_ID_SPDIF,
+ PERIPH_ID_I2S2,
+ PERIPH_ID_I2C1,
+ PERIPH_ID_RESERVED13,
+ PERIPH_ID_SDMMC1,
+ PERIPH_ID_SDMMC4,
+
+ /* 16 */
+ PERIPH_ID_TCW,
+ PERIPH_ID_PWM,
+ PERIPH_ID_I2S3,
+ PERIPH_ID_RESERVED19,
+ PERIPH_ID_VI,
+ PERIPH_ID_RESERVED21,
+ PERIPH_ID_USBD,
+ PERIPH_ID_ISP,
+
+ /* 24 */
+ PERIPH_ID_RESERVED24,
+ PERIPH_ID_RESERVED25,
+ PERIPH_ID_DISP2,
+ PERIPH_ID_DISP1,
+ PERIPH_ID_HOST1X,
+ PERIPH_ID_VCP,
+ PERIPH_ID_I2S1,
+ PERIPH_ID_CACHE2,
+
+ /* Middle word: 63:32 (DEVICES_H) */
+ PERIPH_ID_MEM,
+ PERIPH_ID_AHBDMA,
+ PERIPH_ID_APBDMA,
+ PERIPH_ID_RESERVED35,
+ PERIPH_ID_RESERVED36,
+ PERIPH_ID_STAT_MON,
+ PERIPH_ID_RESERVED38,
+ PERIPH_ID_FUSE,
+
+ /* 40 */
+ PERIPH_ID_KFUSE,
+ PERIPH_ID_SBC1,
+ PERIPH_ID_SNOR,
+ PERIPH_ID_RESERVED43,
+ PERIPH_ID_SBC2,
+ PERIPH_ID_XIO,
+ PERIPH_ID_SBC3,
+ PERIPH_ID_I2C5,
+
+ /* 48 */
+ PERIPH_ID_DSI,
+ PERIPH_ID_RESERVED49,
+ PERIPH_ID_HSI,
+ PERIPH_ID_HDMI,
+ PERIPH_ID_CSI,
+ PERIPH_ID_RESERVED53,
+ PERIPH_ID_I2C2,
+ PERIPH_ID_UART3,
+
+ /* 56 */
+ PERIPH_ID_MIPI_CAL,
+ PERIPH_ID_EMC,
+ PERIPH_ID_USB2,
+ PERIPH_ID_USB3,
+ PERIPH_ID_RESERVED60,
+ PERIPH_ID_VDE,
+ PERIPH_ID_BSEA,
+ PERIPH_ID_BSEV,
+
+ /* Upper word 95:64 (DEVICES_U) */
+ PERIPH_ID_RESERVED64,
+ PERIPH_ID_UART4,
+ PERIPH_ID_UART5,
+ PERIPH_ID_I2C3,
+ PERIPH_ID_SBC4,
+ PERIPH_ID_SDMMC3,
+ PERIPH_ID_PCIE,
+ PERIPH_ID_OWR,
+
+ /* 72 */
+ PERIPH_ID_AFI,
+ PERIPH_ID_CORESIGHT,
+ PERIPH_ID_PCIEXCLK,
+ PERIPH_ID_AVPUCQ,
+ PERIPH_ID_LA,
+ PERIPH_ID_TRACECLKIN,
+ PERIPH_ID_SOC_THERM,
+ PERIPH_ID_DTV,
+
+ /* 80 */
+ PERIPH_ID_RESERVED80,
+ PERIPH_ID_I2CSLOW,
+ PERIPH_ID_DSIB,
+ PERIPH_ID_TSEC,
+ PERIPH_ID_RESERVED84,
+ PERIPH_ID_RESERVED85,
+ PERIPH_ID_RESERVED86,
+ PERIPH_ID_EMUCIF,
+
+ /* 88 */
+ PERIPH_ID_RESERVED88,
+ PERIPH_ID_XUSB_HOST,
+ PERIPH_ID_RESERVED90,
+ PERIPH_ID_MSENC,
+ PERIPH_ID_RESERVED92,
+ PERIPH_ID_RESERVED93,
+ PERIPH_ID_RESERVED94,
+ PERIPH_ID_XUSB_DEV,
+
+ PERIPH_ID_VW_FIRST,
+ /* V word: 31:0 */
+ PERIPH_ID_CPUG = PERIPH_ID_VW_FIRST,
+ PERIPH_ID_CPULP,
+ PERIPH_ID_V_RESERVED2,
+ PERIPH_ID_MSELECT,
+ PERIPH_ID_V_RESERVED4,
+ PERIPH_ID_I2S4,
+ PERIPH_ID_I2S5,
+ PERIPH_ID_I2C4,
+
+ /* 104 */
+ PERIPH_ID_SBC5,
+ PERIPH_ID_SBC6,
+ PERIPH_ID_AHUB,
+ PERIPH_ID_APB2APE,
+ PERIPH_ID_V_RESERVED12,
+ PERIPH_ID_V_RESERVED13,
+ PERIPH_ID_V_RESERVED14,
+ PERIPH_ID_HDA2CODEC2X,
+
+ /* 112 */
+ PERIPH_ID_ATOMICS,
+ PERIPH_ID_V_RESERVED17,
+ PERIPH_ID_V_RESERVED18,
+ PERIPH_ID_V_RESERVED19,
+ PERIPH_ID_V_RESERVED20,
+ PERIPH_ID_V_RESERVED21,
+ PERIPH_ID_V_RESERVED22,
+ PERIPH_ID_ACTMON,
+
+ /* 120 */
+ PERIPH_ID_EXTPERIPH1,
+ PERIPH_ID_EXTPERIPH2,
+ PERIPH_ID_EXTPERIPH3,
+ PERIPH_ID_OOB,
+ PERIPH_ID_SATA,
+ PERIPH_ID_HDA,
+ PERIPH_ID_V_RESERVED30,
+ PERIPH_ID_V_RESERVED31,
+
+ /* W word: 31:0 */
+ PERIPH_ID_HDA2HDMICODEC,
+ PERIPH_ID_SATACOLD,
+ PERIPH_ID_W_RESERVED2,
+ PERIPH_ID_W_RESERVED3,
+ PERIPH_ID_W_RESERVED4,
+ PERIPH_ID_W_RESERVED5,
+ PERIPH_ID_W_RESERVED6,
+ PERIPH_ID_W_RESERVED7,
+
+ /* 136 */
+ PERIPH_ID_CEC,
+ PERIPH_ID_W_RESERVED9,
+ PERIPH_ID_W_RESERVED10,
+ PERIPH_ID_W_RESERVED11,
+ PERIPH_ID_W_RESERVED12,
+ PERIPH_ID_W_RESERVED13,
+ PERIPH_ID_XUSB_PADCTL,
+ PERIPH_ID_W_RESERVED15,
+
+ /* 144 */
+ PERIPH_ID_W_RESERVED16,
+ PERIPH_ID_W_RESERVED17,
+ PERIPH_ID_W_RESERVED18,
+ PERIPH_ID_W_RESERVED19,
+ PERIPH_ID_W_RESERVED20,
+ PERIPH_ID_ENTROPY,
+ PERIPH_ID_DDS,
+ PERIPH_ID_W_RESERVED23,
+
+ /* 152 */
+ PERIPH_ID_W_RESERVED24,
+ PERIPH_ID_W_RESERVED25,
+ PERIPH_ID_W_RESERVED26,
+ PERIPH_ID_DVFS,
+ PERIPH_ID_XUSB_SS,
+ PERIPH_ID_W_RESERVED29,
+ PERIPH_ID_W_RESERVED30,
+ PERIPH_ID_W_RESERVED31,
+
+ PERIPH_ID_X_FIRST,
+ /* X word: 31:0 */
+ PERIPH_ID_SPARE = PERIPH_ID_X_FIRST,
+ PERIPH_ID_X_RESERVED1,
+ PERIPH_ID_X_RESERVED2,
+ PERIPH_ID_X_RESERVED3,
+ PERIPH_ID_CAM_MCLK,
+ PERIPH_ID_CAM_MCLK2,
+ PERIPH_ID_I2C6,
+ PERIPH_ID_X_RESERVED7,
+
+ /* 168 */
+ PERIPH_ID_X_RESERVED8,
+ PERIPH_ID_X_RESERVED9,
+ PERIPH_ID_X_RESERVED10,
+ PERIPH_ID_VIM2_CLK,
+ PERIPH_ID_X_RESERVED12,
+ PERIPH_ID_X_RESERVED13,
+ PERIPH_ID_EMC_DLL,
+ PERIPH_ID_X_RESERVED15,
+
+ /* 176 */
+ PERIPH_ID_HDMI_AUDIO,
+ PERIPH_ID_CLK72MHZ,
+ PERIPH_ID_VIC,
+ PERIPH_ID_X_RESERVED19,
+ PERIPH_ID_X_RESERVED20,
+ PERIPH_ID_DPAUX,
+ PERIPH_ID_SOR0,
+ PERIPH_ID_X_RESERVED23,
+
+ /* 184 */
+ PERIPH_ID_GPU,
+ PERIPH_ID_X_RESERVED25,
+ PERIPH_ID_X_RESERVED26,
+ PERIPH_ID_X_RESERVED27,
+ PERIPH_ID_X_RESERVED28,
+ PERIPH_ID_X_RESERVED29,
+ PERIPH_ID_X_RESERVED30,
+ PERIPH_ID_X_RESERVED31,
+
+ PERIPH_ID_Y_FIRST,
+ /* Y word: 31:0 (192:223) */
+ PERIPH_ID_SPARE1 = PERIPH_ID_Y_FIRST,
+ PERIPH_ID_Y_RESERVED1,
+ PERIPH_ID_Y_RESERVED2,
+ PERIPH_ID_Y_RESERVED3,
+ PERIPH_ID_Y_RESERVED4,
+ PERIPH_ID_Y_RESERVED5,
+ PERIPH_ID_APE,
+ PERIPH_ID_Y_RESERVED7,
+
+ /* 200 */
+ PERIPH_ID_MC_CDPA,
+ PERIPH_ID_Y_RESERVED9,
+ PERIPH_ID_Y_RESERVED10,
+ PERIPH_ID_Y_RESERVED11,
+ PERIPH_ID_Y_RESERVED12,
+ PERIPH_ID_PEX_USB_UPHY,
+ PERIPH_ID_Y_RESERVED14,
+ PERIPH_ID_Y_RESERVED15,
+
+ /* 208 */
+ PERIPH_ID_VI_I2C,
+ PERIPH_ID_Y_RESERVED17,
+ PERIPH_ID_Y_RESERVED18,
+ PERIPH_ID_QSPI,
+ PERIPH_ID_Y_RESERVED20,
+ PERIPH_ID_Y_RESERVED21,
+ PERIPH_ID_Y_RESERVED22,
+ PERIPH_ID_Y_RESERVED23,
+
+ /* 216 */
+ PERIPH_ID_Y_RESERVED24,
+ PERIPH_ID_Y_RESERVED25,
+ PERIPH_ID_Y_RESERVED26,
+ PERIPH_ID_Y_RESERVED27,
+ PERIPH_ID_Y_RESERVED28,
+ PERIPH_ID_Y_RESERVED29,
+ PERIPH_ID_Y_RESERVED30,
+ PERIPH_ID_Y_RESERVED31,
+
+ PERIPH_ID_COUNT,
+ PERIPH_ID_NONE = -1,
+};
+
+enum pll_out_id {
+ PLL_OUT1,
+ PLL_OUT2,
+ PLL_OUT3,
+ PLL_OUT4
+};
+
+/*
+ * Clock peripheral IDs which sadly don't match up with PERIPH_ID. we want
+ * callers to use the PERIPH_ID for all access to peripheral clocks to avoid
+ * confusion bewteen PERIPH_ID_... and PERIPHC_...
+ *
+ * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be
+ * confusing.
+ */
+enum periphc_internal_id {
+ /* 0x00 */
+ PERIPHC_I2S2,
+ PERIPHC_I2S3,
+ PERIPHC_SPDIF_OUT,
+ PERIPHC_SPDIF_IN,
+ PERIPHC_PWM,
+ PERIPHC_05h,
+ PERIPHC_SBC2,
+ PERIPHC_SBC3,
+
+ /* 0x08 */
+ PERIPHC_08h,
+ PERIPHC_I2C1,
+ PERIPHC_I2C5,
+ PERIPHC_0bh,
+ PERIPHC_0ch,
+ PERIPHC_SBC1,
+ PERIPHC_DISP1,
+ PERIPHC_DISP2,
+
+ /* 0x10 */
+ PERIPHC_10h,
+ PERIPHC_11h,
+ PERIPHC_VI,
+ PERIPHC_13h,
+ PERIPHC_SDMMC1,
+ PERIPHC_SDMMC2,
+ PERIPHC_G3D,
+ PERIPHC_G2D,
+
+ /* 0x18 */
+ PERIPHC_18h,
+ PERIPHC_SDMMC4,
+ PERIPHC_VFIR,
+ PERIPHC_1Bh,
+ PERIPHC_1Ch,
+ PERIPHC_HSI,
+ PERIPHC_UART1,
+ PERIPHC_UART2,
+
+ /* 0x20 */
+ PERIPHC_HOST1X,
+ PERIPHC_21h,
+ PERIPHC_22h,
+ PERIPHC_HDMI,
+ PERIPHC_24h,
+ PERIPHC_25h,
+ PERIPHC_I2C2,
+ PERIPHC_EMC,
+
+ /* 0x28 */
+ PERIPHC_UART3,
+ PERIPHC_29h,
+ PERIPHC_VI_SENSOR,
+ PERIPHC_2bh,
+ PERIPHC_2ch,
+ PERIPHC_SBC4,
+ PERIPHC_I2C3,
+ PERIPHC_SDMMC3,
+
+ /* 0x30 */
+ PERIPHC_UART4,
+ PERIPHC_UART5,
+ PERIPHC_VDE,
+ PERIPHC_OWR,
+ PERIPHC_NOR,
+ PERIPHC_CSITE,
+ PERIPHC_I2S1,
+ PERIPHC_DTV,
+
+ /* 0x38 */
+ PERIPHC_38h,
+ PERIPHC_39h,
+ PERIPHC_3ah,
+ PERIPHC_3bh,
+ PERIPHC_MSENC,
+ PERIPHC_TSEC,
+ PERIPHC_3eh,
+ PERIPHC_OSC,
+
+ PERIPHC_VW_FIRST,
+ /* 0x40 */
+ PERIPHC_40h = PERIPHC_VW_FIRST,
+ PERIPHC_MSELECT,
+ PERIPHC_TSENSOR,
+ PERIPHC_I2S4,
+ PERIPHC_I2S5,
+ PERIPHC_I2C4,
+ PERIPHC_SBC5,
+ PERIPHC_SBC6,
+
+ /* 0x48 */
+ PERIPHC_AUDIO,
+ PERIPHC_49h,
+ PERIPHC_4ah,
+ PERIPHC_4bh,
+ PERIPHC_4ch,
+ PERIPHC_HDA2CODEC2X,
+ PERIPHC_ACTMON,
+ PERIPHC_EXTPERIPH1,
+
+ /* 0x50 */
+ PERIPHC_EXTPERIPH2,
+ PERIPHC_EXTPERIPH3,
+ PERIPHC_52h,
+ PERIPHC_I2CSLOW,
+ PERIPHC_SYS,
+ PERIPHC_55h,
+ PERIPHC_56h,
+ PERIPHC_57h,
+
+ /* 0x58 */
+ PERIPHC_58h,
+ PERIPHC_59h,
+ PERIPHC_5ah,
+ PERIPHC_5bh,
+ PERIPHC_SATAOOB,
+ PERIPHC_SATA,
+ PERIPHC_HDA, /* 0x428 */
+ PERIPHC_5fh,
+
+ PERIPHC_X_FIRST,
+ /* 0x60 */
+ PERIPHC_XUSB_CORE_HOST = PERIPHC_X_FIRST, /* 0x600 */
+ PERIPHC_XUSB_FALCON,
+ PERIPHC_XUSB_FS,
+ PERIPHC_XUSB_CORE_DEV,
+ PERIPHC_XUSB_SS,
+ PERIPHC_CILAB,
+ PERIPHC_CILCD,
+ PERIPHC_CILE,
+
+ /* 0x68 */
+ PERIPHC_DSIA_LP,
+ PERIPHC_DSIB_LP,
+ PERIPHC_ENTROPY,
+ PERIPHC_DVFS_REF,
+ PERIPHC_DVFS_SOC,
+ PERIPHC_TRACECLKIN,
+ PERIPHC_6Eh,
+ PERIPHC_6Fh,
+
+ /* 0x70 */
+ PERIPHC_EMC_LATENCY,
+ PERIPHC_SOC_THERM,
+ PERIPHC_72h,
+ PERIPHC_73h,
+ PERIPHC_74h,
+ PERIPHC_75h,
+ PERIPHC_VI_SENSOR2,
+ PERIPHC_I2C6,
+
+ /* 0x78 */
+ PERIPHC_78h,
+ PERIPHC_EMC_DLL,
+ PERIPHC_7ah,
+ PERIPHC_CLK72MHZ,
+ PERIPHC_7ch,
+ PERIPHC_7dh,
+ PERIPHC_VIC,
+ PERIPHC_7fh,
+
+ PERIPHC_Y_FIRST,
+ /* 0x80 */
+ PERIPHC_SDMMC_LEGACY_TM = PERIPHC_Y_FIRST, /* 0x694 */
+ PERIPHC_NVDEC, /* 0x698 */
+ PERIPHC_NVJPG, /* 0x69c */
+ PERIPHC_NVENC, /* 0x6a0 */
+ PERIPHC_84h,
+ PERIPHC_85h,
+ PERIPHC_86h,
+ PERIPHC_87h,
+
+ /* 0x88 */
+ PERIPHC_88h,
+ PERIPHC_89h,
+ PERIPHC_DMIC3, /* 0x6bc: */
+ PERIPHC_APE, /* 0x6c0: */
+ PERIPHC_QSPI, /* 0x6c4: */
+ PERIPHC_VI_I2C, /* 0x6c8: */
+ PERIPHC_USB2_HSIC_TRK, /* 0x6cc: */
+ PERIPHC_PEX_SATA_USB_RX_BYP, /* 0x6d0: */
+
+ /* 0x90 */
+ PERIPHC_MAUD, /* 0x6d4: */
+ PERIPHC_TSECB, /* 0x6d8: */
+
+ PERIPHC_COUNT,
+ PERIPHC_NONE = -1,
+};
+
+/* Converts a clock number to a clock register: 0=L, 1=H, 2=U, 0=V, 1=W */
+#define PERIPH_REG(id) \
+ (id < PERIPH_ID_VW_FIRST) ? \
+ ((id) >> 5) : ((id - PERIPH_ID_VW_FIRST) >> 5)
+
+/* Mask value for a clock (within PERIPH_REG(id)) */
+#define PERIPH_MASK(id) (1 << ((id) & 0x1f))
+
+/* return 1 if a PLL ID is in range */
+#define clock_id_is_pll(id) ((id) >= CLOCK_ID_FIRST && (id) < CLOCK_ID_COUNT)
+
+/* return 1 if a peripheral ID is in range */
+#define clock_periph_id_isvalid(id) ((id) >= PERIPH_ID_FIRST && \
+ (id) < PERIPH_ID_COUNT)
+
+#endif /* _TEGRA210_CLOCK_TABLES_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2010-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Tegra210 clock control definitions */
+
+#ifndef _TEGRA210_CLOCK_H_
+#define _TEGRA210_CLOCK_H_
+
+#include <asm/arch-tegra/clock.h>
+
+/* CLK_RST_CONTROLLER_OSC_CTRL_0 */
+#define OSC_FREQ_SHIFT 28
+#define OSC_FREQ_MASK (0xF << OSC_FREQ_SHIFT)
+
+/* PLL bits that differ from generic clk_rst.h */
+#define PLLC_RESET 30
+#define PLLC_IDDQ 27
+#define PLLD_ENABLE_CLK 21
+#define PLLD_EN_LCKDET 28
+
+int tegra_plle_enable(void);
+
+#endif /* _TEGRA210_CLOCK_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2010-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_FLOW_H_
+#define _TEGRA210_FLOW_H_
+
+struct flow_ctlr {
+ u32 halt_cpu_events; /* offset 0x00 */
+ u32 halt_cop_events; /* offset 0x04 */
+ u32 cpu_csr; /* offset 0x08 */
+ u32 cop_csr; /* offset 0x0c */
+ u32 xrq_events; /* offset 0x10 */
+ u32 halt_cpu1_events; /* offset 0x14 */
+ u32 cpu1_csr; /* offset 0x18 */
+ u32 halt_cpu2_events; /* offset 0x1c */
+ u32 cpu2_csr; /* offset 0x20 */
+ u32 halt_cpu3_events; /* offset 0x24 */
+ u32 cpu3_csr; /* offset 0x28 */
+ u32 cluster_control; /* offset 0x2c */
+ u32 halt_cop1_events; /* offset 0x30 */
+ u32 halt_cop1_csr; /* offset 0x34 */
+ u32 cpu_pwr_csr; /* offset 0x38 */
+ u32 mpid; /* offset 0x3c */
+ u32 ram_repair; /* offset 0x40 */
+};
+
+/* HALT_COP_EVENTS_0, 0x04 */
+#define EVENT_MSEC (1 << 24)
+#define EVENT_USEC (1 << 25)
+#define EVENT_JTAG (1 << 28)
+#define EVENT_MODE_STOP (2 << 29)
+
+/* FLOW_CTLR_CLUSTER_CONTROL_0 0x2c */
+#define ACTIVE_LP (1 << 0)
+
+/* CPUn_CSR_0 */
+#define CSR_ENABLE (1 << 0)
+#define CSR_IMMEDIATE_WAKE (1 << 3)
+#define CSR_WAIT_WFI_SHIFT 8
+
+#endif /* _TEGRA210_FLOW_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Tegra210 high-level function multiplexing */
+
+#ifndef _TEGRA210_FUNCMUX_H_
+#define _TEGRA210_FUNCMUX_H_
+
+#include <asm/arch-tegra/funcmux.h>
+
+/* Configs supported by the func mux */
+enum {
+ FUNCMUX_DEFAULT = 0, /* default config */
+
+ /* UART configs */
+ FUNCMUX_UART1_UART1 = 0,
+ FUNCMUX_UART4_UART4 = 0,
+};
+#endif /* _TEGRA210_FUNCMUX_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2010-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_GP_PADCTRL_H_
+#define _TEGRA210_GP_PADCTRL_H_
+
+#include <asm/arch-tegra/gp_padctrl.h>
+
+/* APB_MISC_GP and padctrl registers */
+struct apb_misc_gp_ctlr {
+ u32 modereg; /* 0x00: APB_MISC_GP_MODEREG */
+ u32 hidrev; /* 0x04: APB_MISC_GP_HIDREV */
+ u32 reserved0[22]; /* 0x08 - 0x5C: */
+ u32 emu_revid; /* 0x60: APB_MISC_GP_EMU_REVID */
+ u32 xactor_scratch; /* 0x64: APB_MISC_GP_XACTOR_SCRATCH */
+ u32 aocfg1; /* 0x68: APB_MISC_GP_AOCFG1PADCTRL */
+ u32 aocfg2; /* 0x6C: APB_MISC_GP_AOCFG2PADCTRL */
+ u32 atcfg1; /* 0x70: APB_MISC_GP_ATCFG1PADCTRL */
+ u32 atcfg2; /* 0x74: APB_MISC_GP_ATCFG2PADCTRL */
+ u32 atcfg3; /* 0x78: APB_MISC_GP_ATCFG3PADCTRL */
+ u32 atcfg4; /* 0x7C: APB_MISC_GP_ATCFG4PADCTRL */
+ u32 atcfg5; /* 0x80: APB_MISC_GP_ATCFG5PADCTRL */
+ u32 cdev1cfg; /* 0x84: APB_MISC_GP_CDEV1CFGPADCTRL */
+ u32 cdev2cfg; /* 0x88: APB_MISC_GP_CDEV2CFGPADCTRL */
+ u32 reserved1; /* 0x8C: */
+ u32 dap1cfg; /* 0x90: APB_MISC_GP_DAP1CFGPADCTRL */
+ u32 dap2cfg; /* 0x94: APB_MISC_GP_DAP2CFGPADCTRL */
+ u32 dap3cfg; /* 0x98: APB_MISC_GP_DAP3CFGPADCTRL */
+ u32 dap4cfg; /* 0x9C: APB_MISC_GP_DAP4CFGPADCTRL */
+ u32 dbgcfg; /* 0xA0: APB_MISC_GP_DBGCFGPADCTRL */
+ u32 reserved2[3]; /* 0xA4 - 0xAC: */
+ u32 sdio3cfg; /* 0xB0: APB_MISC_GP_SDIO3CFGPADCTRL */
+ u32 spicfg; /* 0xB4: APB_MISC_GP_SPICFGPADCTRL */
+ u32 uaacfg; /* 0xB8: APB_MISC_GP_UAACFGPADCTRL */
+ u32 uabcfg; /* 0xBC: APB_MISC_GP_UABCFGPADCTRL */
+ u32 uart2cfg; /* 0xC0: APB_MISC_GP_UART2CFGPADCTRL */
+ u32 uart3cfg; /* 0xC4: APB_MISC_GP_UART3CFGPADCTRL */
+ u32 reserved3[9]; /* 0xC8-0xE8: */
+ u32 sdio1cfg; /* 0xEC: APB_MISC_GP_SDIO1CFGPADCTRL */
+ u32 reserved4[3]; /* 0xF0-0xF8: */
+ u32 ddccfg; /* 0xFC: APB_MISC_GP_DDCCFGPADCTRL */
+ u32 gmacfg; /* 0x100: APB_MISC_GP_GMACFGPADCTRL */
+ u32 reserved5[3]; /* 0x104-0x10C: */
+ u32 gmecfg; /* 0x110: APB_MISC_GP_GMECFGPADCTRL */
+ u32 gmfcfg; /* 0x114: APB_MISC_GP_GMFCFGPADCTRL */
+ u32 gmgcfg; /* 0x118: APB_MISC_GP_GMGCFGPADCTRL */
+ u32 gmhcfg; /* 0x11C: APB_MISC_GP_GMHCFGPADCTRL */
+ u32 owrcfg; /* 0x120: APB_MISC_GP_OWRCFGPADCTRL */
+ u32 uadcfg; /* 0x124: APB_MISC_GP_UADCFGPADCTRL */
+ u32 reserved6; /* 0x128: */
+ u32 dev3cfg; /* 0x12C: APB_MISC_GP_DEV3CFGPADCTRL */
+ u32 reserved7[2]; /* 0x130 - 0x134: */
+ u32 ceccfg; /* 0x138: APB_MISC_GP_CECCFGPADCTRL */
+ u32 reserved8[22]; /* 0x13C - 0x190: */
+ u32 atcfg6; /* 0x194: APB_MISC_GP_ATCFG6PADCTRL */
+ u32 dap5cfg; /* 0x198: APB_MISC_GP_DAP5CFGPADCTRL */
+ u32 vbuscfg; /* 0x19C: APB_MISC_GP_USBVBUSENCFGPADCTRL */
+ u32 aocfg3; /* 0x1A0: APB_MISC_GP_AOCFG3PADCTRL */
+ u32 hvccfg0; /* 0x1A4: APB_MISC_GP_HVCCFG0PADCTRL */
+ u32 sdio4cfg; /* 0x1A8: APB_MISC_GP_SDIO4CFGPADCTRL */
+ u32 aocfg0; /* 0x1AC: APB_MISC_GP_AOCFG0PADCTRL */
+};
+
+/* SDMMC1/3 settings from section 27.5 of T114 TRM */
+#define SDIOCFG_DRVUP_SLWF 0
+#define SDIOCFG_DRVDN_SLWR 0
+#define SDIOCFG_DRVUP 0x24
+#define SDIOCFG_DRVDN 0x14
+
+#endif /* _TEGRA210_GP_PADCTRL_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_GPIO_H_
+#define _TEGRA210_GPIO_H_
+
+/*
+ * The Tegra210 GPIO controller has 256 GPIOS in 8 banks of 4 ports,
+ * each with 8 GPIOs.
+ */
+#define TEGRA_GPIO_PORTS 4 /* number of ports per bank */
+#define TEGRA_GPIO_BANKS 8 /* number of banks */
+
+#include <asm/arch-tegra/gpio.h>
+
+/* GPIO Controller registers for a single bank */
+struct gpio_ctlr_bank {
+ uint gpio_config[TEGRA_GPIO_PORTS];
+ uint gpio_dir_out[TEGRA_GPIO_PORTS];
+ uint gpio_out[TEGRA_GPIO_PORTS];
+ uint gpio_in[TEGRA_GPIO_PORTS];
+ uint gpio_int_status[TEGRA_GPIO_PORTS];
+ uint gpio_int_enable[TEGRA_GPIO_PORTS];
+ uint gpio_int_level[TEGRA_GPIO_PORTS];
+ uint gpio_int_clear[TEGRA_GPIO_PORTS];
+ uint gpio_masked_config[TEGRA_GPIO_PORTS];
+ uint gpio_masked_dir_out[TEGRA_GPIO_PORTS];
+ uint gpio_masked_out[TEGRA_GPIO_PORTS];
+ uint gpio_masked_in[TEGRA_GPIO_PORTS];
+ uint gpio_masked_int_status[TEGRA_GPIO_PORTS];
+ uint gpio_masked_int_enable[TEGRA_GPIO_PORTS];
+ uint gpio_masked_int_level[TEGRA_GPIO_PORTS];
+ uint gpio_masked_int_clear[TEGRA_GPIO_PORTS];
+};
+
+struct gpio_ctlr {
+ struct gpio_ctlr_bank gpio_bank[TEGRA_GPIO_BANKS];
+};
+
+enum gpio_pin {
+ GPIO_PA0 = 0, /* pin 0 */
+ GPIO_PA1,
+ GPIO_PA2,
+ GPIO_PA3,
+ GPIO_PA4,
+ GPIO_PA5,
+ GPIO_PA6,
+ GPIO_PA7,
+ GPIO_PB0, /* pin 8 */
+ GPIO_PB1,
+ GPIO_PB2,
+ GPIO_PB3,
+ GPIO_PB4,
+ GPIO_PB5,
+ GPIO_PB6,
+ GPIO_PB7,
+ GPIO_PC0, /* pin 16 */
+ GPIO_PC1,
+ GPIO_PC2,
+ GPIO_PC3,
+ GPIO_PC4,
+ GPIO_PC5,
+ GPIO_PC6,
+ GPIO_PC7,
+ GPIO_PD0, /* pin 24 */
+ GPIO_PD1,
+ GPIO_PD2,
+ GPIO_PD3,
+ GPIO_PD4,
+ GPIO_PD5,
+ GPIO_PD6,
+ GPIO_PD7,
+ GPIO_PE0, /* pin 32 */
+ GPIO_PE1,
+ GPIO_PE2,
+ GPIO_PE3,
+ GPIO_PE4,
+ GPIO_PE5,
+ GPIO_PE6,
+ GPIO_PE7,
+ GPIO_PF0, /* pin 40 */
+ GPIO_PF1,
+ GPIO_PF2,
+ GPIO_PF3,
+ GPIO_PF4,
+ GPIO_PF5,
+ GPIO_PF6,
+ GPIO_PF7,
+ GPIO_PG0, /* pin 48 */
+ GPIO_PG1,
+ GPIO_PG2,
+ GPIO_PG3,
+ GPIO_PG4,
+ GPIO_PG5,
+ GPIO_PG6,
+ GPIO_PG7,
+ GPIO_PH0, /* pin 56 */
+ GPIO_PH1,
+ GPIO_PH2,
+ GPIO_PH3,
+ GPIO_PH4,
+ GPIO_PH5,
+ GPIO_PH6,
+ GPIO_PH7,
+ GPIO_PI0, /* pin 64 */
+ GPIO_PI1,
+ GPIO_PI2,
+ GPIO_PI3,
+ GPIO_PI4,
+ GPIO_PI5,
+ GPIO_PI6,
+ GPIO_PI7,
+ GPIO_PJ0, /* pin 72 */
+ GPIO_PJ1,
+ GPIO_PJ2,
+ GPIO_PJ3,
+ GPIO_PJ4,
+ GPIO_PJ5,
+ GPIO_PJ6,
+ GPIO_PJ7,
+ GPIO_PK0, /* pin 80 */
+ GPIO_PK1,
+ GPIO_PK2,
+ GPIO_PK3,
+ GPIO_PK4,
+ GPIO_PK5,
+ GPIO_PK6,
+ GPIO_PK7,
+ GPIO_PL0, /* pin 88 */
+ GPIO_PL1,
+ GPIO_PL2,
+ GPIO_PL3,
+ GPIO_PL4,
+ GPIO_PL5,
+ GPIO_PL6,
+ GPIO_PL7,
+ GPIO_PM0, /* pin 96 */
+ GPIO_PM1,
+ GPIO_PM2,
+ GPIO_PM3,
+ GPIO_PM4,
+ GPIO_PM5,
+ GPIO_PM6,
+ GPIO_PM7,
+ GPIO_PN0, /* pin 104 */
+ GPIO_PN1,
+ GPIO_PN2,
+ GPIO_PN3,
+ GPIO_PN4,
+ GPIO_PN5,
+ GPIO_PN6,
+ GPIO_PN7,
+ GPIO_PO0, /* pin 112 */
+ GPIO_PO1,
+ GPIO_PO2,
+ GPIO_PO3,
+ GPIO_PO4,
+ GPIO_PO5,
+ GPIO_PO6,
+ GPIO_PO7,
+ GPIO_PP0, /* pin 120 */
+ GPIO_PP1,
+ GPIO_PP2,
+ GPIO_PP3,
+ GPIO_PP4,
+ GPIO_PP5,
+ GPIO_PP6,
+ GPIO_PP7,
+ GPIO_PQ0, /* pin 128 */
+ GPIO_PQ1,
+ GPIO_PQ2,
+ GPIO_PQ3,
+ GPIO_PQ4,
+ GPIO_PQ5,
+ GPIO_PQ6,
+ GPIO_PQ7,
+ GPIO_PR0, /* pin 136 */
+ GPIO_PR1,
+ GPIO_PR2,
+ GPIO_PR3,
+ GPIO_PR4,
+ GPIO_PR5,
+ GPIO_PR6,
+ GPIO_PR7,
+ GPIO_PS0, /* pin 144 */
+ GPIO_PS1,
+ GPIO_PS2,
+ GPIO_PS3,
+ GPIO_PS4,
+ GPIO_PS5,
+ GPIO_PS6,
+ GPIO_PS7,
+ GPIO_PT0, /* pin 152 */
+ GPIO_PT1,
+ GPIO_PT2,
+ GPIO_PT3,
+ GPIO_PT4,
+ GPIO_PT5,
+ GPIO_PT6,
+ GPIO_PT7,
+ GPIO_PU0, /* pin 160 */
+ GPIO_PU1,
+ GPIO_PU2,
+ GPIO_PU3,
+ GPIO_PU4,
+ GPIO_PU5,
+ GPIO_PU6,
+ GPIO_PU7,
+ GPIO_PV0, /* pin 168 */
+ GPIO_PV1,
+ GPIO_PV2,
+ GPIO_PV3,
+ GPIO_PV4,
+ GPIO_PV5,
+ GPIO_PV6,
+ GPIO_PV7,
+ GPIO_PW0, /* pin 176 */
+ GPIO_PW1,
+ GPIO_PW2,
+ GPIO_PW3,
+ GPIO_PW4,
+ GPIO_PW5,
+ GPIO_PW6,
+ GPIO_PW7,
+ GPIO_PX0, /* pin 184 */
+ GPIO_PX1,
+ GPIO_PX2,
+ GPIO_PX3,
+ GPIO_PX4,
+ GPIO_PX5,
+ GPIO_PX6,
+ GPIO_PX7,
+ GPIO_PY0, /* pin 192 */
+ GPIO_PY1,
+ GPIO_PY2,
+ GPIO_PY3,
+ GPIO_PY4,
+ GPIO_PY5,
+ GPIO_PY6,
+ GPIO_PY7,
+ GPIO_PZ0, /* pin 200 */
+ GPIO_PZ1,
+ GPIO_PZ2,
+ GPIO_PZ3,
+ GPIO_PZ4,
+ GPIO_PZ5,
+ GPIO_PZ6,
+ GPIO_PZ7,
+ GPIO_PAA0, /* pin 208 */
+ GPIO_PAA1,
+ GPIO_PAA2,
+ GPIO_PAA3,
+ GPIO_PAA4,
+ GPIO_PAA5,
+ GPIO_PAA6,
+ GPIO_PAA7,
+ GPIO_PBB0, /* pin 216 */
+ GPIO_PBB1,
+ GPIO_PBB2,
+ GPIO_PBB3,
+ GPIO_PBB4,
+ GPIO_PBB5,
+ GPIO_PBB6,
+ GPIO_PBB7,
+ GPIO_PCC0, /* pin 224 */
+ GPIO_PCC1,
+ GPIO_PCC2,
+ GPIO_PCC3,
+ GPIO_PCC4,
+ GPIO_PCC5,
+ GPIO_PCC6,
+ GPIO_PCC7,
+ GPIO_PDD0, /* pin 232 */
+ GPIO_PDD1,
+ GPIO_PDD2,
+ GPIO_PDD3,
+ GPIO_PDD4,
+ GPIO_PDD5,
+ GPIO_PDD6,
+ GPIO_PDD7,
+ GPIO_PEE0, /* pin 240 */
+ GPIO_PEE1,
+ GPIO_PEE2,
+ GPIO_PEE3,
+ GPIO_PEE4,
+ GPIO_PEE5,
+ GPIO_PEE6,
+ GPIO_PEE7,
+ GPIO_PFF0, /* pin 248 */
+ GPIO_PFF1,
+ GPIO_PFF2,
+ GPIO_PFF3,
+ GPIO_PFF4,
+ GPIO_PFF5,
+ GPIO_PFF6,
+ GPIO_PFF7, /* pin 255 */
+};
+
+#endif /* _TEGRA210_GPIO_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2014-2015 NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_MC_H_
+#define _TEGRA210_MC_H_
+
+/**
+ * Defines the memory controller registers we need/care about
+ */
+struct mc_ctlr {
+ u32 reserved0[4]; /* offset 0x00 - 0x0C */
+ u32 mc_smmu_config; /* offset 0x10 */
+ u32 mc_smmu_tlb_config; /* offset 0x14 */
+ u32 mc_smmu_ptc_config; /* offset 0x18 */
+ u32 mc_smmu_ptb_asid; /* offset 0x1C */
+ u32 mc_smmu_ptb_data; /* offset 0x20 */
+ u32 reserved1[3]; /* offset 0x24 - 0x2C */
+ u32 mc_smmu_tlb_flush; /* offset 0x30 */
+ u32 mc_smmu_ptc_flush; /* offset 0x34 */
+ u32 reserved2[6]; /* offset 0x38 - 0x4C */
+ u32 mc_emem_cfg; /* offset 0x50 */
+ u32 mc_emem_adr_cfg; /* offset 0x54 */
+ u32 mc_emem_adr_cfg_dev0; /* offset 0x58 */
+ u32 mc_emem_adr_cfg_dev1; /* offset 0x5C */
+ u32 reserved3[4]; /* offset 0x60 - 0x6C */
+ u32 mc_security_cfg0; /* offset 0x70 */
+ u32 mc_security_cfg1; /* offset 0x74 */
+ u32 reserved4[6]; /* offset 0x7C - 0x8C */
+ u32 mc_emem_arb_reserved[28]; /* offset 0x90 - 0xFC */
+ u32 reserved5[74]; /* offset 0x100 - 0x224 */
+ u32 mc_smmu_translation_enable_0; /* offset 0x228 */
+ u32 mc_smmu_translation_enable_1; /* offset 0x22C */
+ u32 mc_smmu_translation_enable_2; /* offset 0x230 */
+ u32 mc_smmu_translation_enable_3; /* offset 0x234 */
+ u32 mc_smmu_afi_asid; /* offset 0x238 */
+ u32 mc_smmu_avpc_asid; /* offset 0x23C */
+ u32 mc_smmu_dc_asid; /* offset 0x240 */
+ u32 mc_smmu_dcb_asid; /* offset 0x244 */
+ u32 reserved6[2]; /* offset 0x248 - 0x24C */
+ u32 mc_smmu_hc_asid; /* offset 0x250 */
+ u32 mc_smmu_hda_asid; /* offset 0x254 */
+ u32 mc_smmu_isp2_asid; /* offset 0x258 */
+ u32 reserved7[2]; /* offset 0x25C - 0x260 */
+ u32 mc_smmu_msenc_asid; /* offset 0x264 */
+ u32 mc_smmu_nv_asid; /* offset 0x268 */
+ u32 mc_smmu_nv2_asid; /* offset 0x26C */
+ u32 mc_smmu_ppcs_asid; /* offset 0x270 */
+ u32 mc_smmu_sata_asid; /* offset 0x274 */
+ u32 reserved8[1]; /* offset 0x278 */
+ u32 mc_smmu_vde_asid; /* offset 0x27C */
+ u32 mc_smmu_vi_asid; /* offset 0x280 */
+ u32 mc_smmu_vic_asid; /* offset 0x284 */
+ u32 mc_smmu_xusb_host_asid; /* offset 0x288 */
+ u32 mc_smmu_xusb_dev_asid; /* offset 0x28C */
+ u32 reserved9[1]; /* offset 0x290 */
+ u32 mc_smmu_tsec_asid; /* offset 0x294 */
+ u32 mc_smmu_ppcs1_asid; /* offset 0x298 */
+ u32 reserved10[235]; /* offset 0x29C - 0x644 */
+ u32 mc_video_protect_bom; /* offset 0x648 */
+ u32 mc_video_protect_size_mb; /* offset 0x64c */
+ u32 mc_video_protect_reg_ctrl; /* offset 0x650 */
+};
+
+#define TEGRA_MC_SMMU_CONFIG_ENABLE (1 << 0)
+
+#define TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_ENABLED (0 << 0)
+#define TEGRA_MC_VIDEO_PROTECT_REG_WRITE_ACCESS_DISABLED (1 << 0)
+
+#endif /* _TEGRA210_MC_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2010-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_PMU_H_
+#define _TEGRA210_PMU_H_
+
+/* Set core and CPU voltages to nominal levels */
+int pmu_set_nominal(void);
+
+#endif /* _TEGRA210_PMU_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2014-2015 NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_POWERGATE_H_
+#define _TEGRA210_POWERGATE_H_
+
+#include <asm/arch-tegra/powergate.h>
+
+#endif /* _TEGRA210_POWERGATE_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_SYSCTR_H_
+#define _TEGRA210_SYSCTR_H_
+
+struct sysctr_ctlr {
+ u32 cntcr; /* 0x00: SYSCTR0_CNTCR Counter Control */
+ u32 cntsr; /* 0x04: SYSCTR0_CNTSR Counter Status */
+ u32 cntcv0; /* 0x08: SYSCTR0_CNTCV0 Counter Count 31:00 */
+ u32 cntcv1; /* 0x0C: SYSCTR0_CNTCV1 Counter Count 63:32 */
+ u32 reserved1[4]; /* 0x10 - 0x1C */
+ u32 cntfid0; /* 0x20: SYSCTR0_CNTFID0 Freq Table Entry */
+ u32 cntfid1; /* 0x24: SYSCTR0_CNTFID1 Freq Table End */
+ u32 reserved2[1002]; /* 0x28 - 0xFCC */
+ u32 counterid[12]; /* 0xFD0 - 0xFxx CounterID regs, RO */
+};
+
+#define TSC_CNTCR_ENABLE (1 << 0) /* Enable */
+#define TSC_CNTCR_HDBG (1 << 1) /* Halt on debug */
+
+#endif /* _TEGRA210_SYSCTR_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_TEGRA_H_
+#define _TEGRA210_TEGRA_H_
+
+#define GICD_BASE 0x50041000 /* Generic Int Cntrlr Distrib */
+#define GICC_BASE 0x50042000 /* Generic Int Cntrlr CPU I/F */
+#define NV_PA_AHB_BASE 0x6000C000 /* System regs (AHB, etc.) */
+#define NV_PA_TSC_BASE 0x700F0000 /* System Counter TSC regs */
+#define NV_PA_MC_BASE 0x70019000 /* Mem Ctlr regs (MCB, etc.) */
+#define NV_PA_SDRAM_BASE 0x80000000
+
+#include <asm/arch-tegra/tegra.h>
+
+#define BCT_ODMDATA_OFFSET 1288 /* offset to ODMDATA word */
+
+#undef NVBOOTINFOTABLE_BCTSIZE
+#undef NVBOOTINFOTABLE_BCTPTR
+#define NVBOOTINFOTABLE_BCTSIZE 0x48 /* BCT size in BIT in IRAM */
+#define NVBOOTINFOTABLE_BCTPTR 0x4C /* BCT pointer in BIT in IRAM */
+
+#define MAX_NUM_CPU 4
+#define MCB_EMEM_ARB_OVERRIDE (NV_PA_MC_BASE + 0xE8)
+
+#define TEGRA_USB1_BASE 0x7D000000
+
+#endif /* _TEGRA210_TEGRA_H_ */
#define ZYNQ_SERIAL_BASEADDR0 0xFF000000
#define ZYNQ_SERIAL_BASEADDR1 0xFF001000
+#define ZYNQ_GEM_BASEADDR0 0xFF0B0000
+#define ZYNQ_GEM_BASEADDR1 0xFF0C0000
+#define ZYNQ_GEM_BASEADDR2 0xFF0D0000
+#define ZYNQ_GEM_BASEADDR3 0xFF0E0000
+
#define ZYNQ_SPI_BASEADDR0 0xFF040000
#define ZYNQ_SPI_BASEADDR1 0xFF050000
#define ZYNQ_SDHCI_BASEADDR0 0xFF160000
#define ZYNQ_SDHCI_BASEADDR1 0xFF170000
+#define ZYNQMP_SATA_BASEADDR 0xFD0C0000
+
#define ZYNQMP_CRL_APB_BASEADDR 0xFF5E0000
#define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000
#define EMMC_MODE 0x00000006
#define JTAG_MODE 0x00000000
+#define ZYNQMP_IOU_SLCR_BASEADDR 0xFF180000
+
+struct iou_slcr_regs {
+ u32 mio_pin[78];
+ u32 reserved[442];
+};
+
+#define slcr_base ((struct iou_slcr_regs *)ZYNQMP_IOU_SLCR_BASEADDR)
+
#define ZYNQMP_RPU_BASEADDR 0xFF9A0000
struct rpu_regs {
#ifndef _ASM_ARCH_SYS_PROTO_H
#define _ASM_ARCH_SYS_PROTO_H
+/* Setup clk for network */
+static inline void zynq_slcr_gem_clk_setup(u32 gem_id, unsigned long clk_rate)
+{
+}
+
int zynq_sdhci_init(unsigned long regbase);
+int zynq_slcr_get_mio_pin_status(const char *periph);
unsigned int zynqmp_get_silicon_version(void);
#define TCR_ORGN_WBNWA (3 << 10)
#define TCR_ORGN_MASK (3 << 10)
#define TCR_SHARED_NON (0 << 12)
-#define TCR_SHARED_OUTER (1 << 12)
-#define TCR_SHARED_INNER (2 << 12)
+#define TCR_SHARED_OUTER (2 << 12)
+#define TCR_SHARED_INNER (3 << 12)
#define TCR_TG0_4K (0 << 14)
#define TCR_TG0_64K (1 << 14)
#define TCR_TG0_16K (2 << 14)
#ifndef __ASM_GBL_DATA_H
#define __ASM_GBL_DATA_H
-#ifdef CONFIG_OMAP
-#include <asm/omap_boot.h>
-#endif
-
/* Architecture-specific global data */
struct arch_global_data {
#if defined(CONFIG_FSL_ESDHC)
unsigned long tlb_size;
#endif
-#ifdef CONFIG_OMAP
- struct omap_boot_parameters omap_boot_params;
+#ifdef CONFIG_OMAP_COMMON
+ u32 omap_boot_device;
+ u32 omap_boot_mode;
+ u8 omap_ch_flags;
#endif
#ifdef CONFIG_FSL_LSCH3
unsigned long mem2_clk;
+++ /dev/null
-/*
- * (C) Copyright 2013
- * Texas Instruments, <www.ti.com>
- *
- * Sricharan R <r.sricharan@ti.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/* ROM code defines */
-/* Boot device */
-#define BOOT_DEVICE_MASK 0xFF
-#define BOOT_DEVICE_OFFSET 0x8
-#define DEV_DESC_PTR_OFFSET 0x4
-#define DEV_DATA_PTR_OFFSET 0x18
-#define BOOT_MODE_OFFSET 0x8
-#define RESET_REASON_OFFSET 0x9
-#define CH_FLAGS_OFFSET 0xA
-
-#define CH_FLAGS_CHSETTINGS (0x1 << 0)
-#define CH_FLAGS_CHRAM (0x1 << 1)
-#define CH_FLAGS_CHFLASH (0x1 << 2)
-#define CH_FLAGS_CHMMCSD (0x1 << 3)
-
-#ifndef __ASSEMBLY__
-struct omap_boot_parameters {
- char *boot_message;
- unsigned int mem_boot_descriptor;
- unsigned char omap_bootdevice;
- unsigned char reset_reason;
- unsigned char ch_flags;
- unsigned long omap_bootmode;
-};
-#endif
#define OMAP_SRAM_SCRATCH_BOOT_PARAMS (SRAM_SCRATCH_SPACE_ADDR + 0x24)
#define OMAP5_SRAM_SCRATCH_SPACE_END (SRAM_SCRATCH_SPACE_ADDR + 0x28)
+/* Boot parameters */
+#define DEVICE_DATA_OFFSET 0x18
+#define BOOT_MODE_OFFSET 0x8
+
+#define CH_FLAGS_CHSETTINGS (1 << 0)
+#define CH_FLAGS_CHRAM (1 << 1)
+#define CH_FLAGS_CHFLASH (1 << 2)
+#define CH_FLAGS_CHMMCSD (1 << 3)
+
+#ifndef __ASSEMBLY__
+u32 omap_sys_boot_device(void);
+#endif
+
#endif /* _OMAP_COMMON_H_ */
#define CR_EE (1 << 25) /* Exception (Big) Endian */
#define PGTABLE_SIZE (0x10000)
+/* 2MB granularity */
+#define MMU_SECTION_SHIFT 21
#ifndef __ASSEMBLY__
+enum dcache_option {
+ DCACHE_OFF = 0x3,
+};
+
#define isb() \
({asm volatile( \
"isb" : : : "memory"); \
#define TTBR0_IRGN_WB (1 << 0 | 1 << 6)
#endif
-/**
- * Change the cache settings for a region.
- *
- * \param start start address of memory region to change
- * \param size size of memory region to change
- * \param option dcache option to select
- */
-void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
- enum dcache_option option);
-
/**
* Register an update to the page tables, and flush the TLB
*
#endif /* CONFIG_ARM64 */
+#ifndef __ASSEMBLY__
+/**
+ * Change the cache settings for a region.
+ *
+ * \param start start address of memory region to change
+ * \param size size of memory region to change
+ * \param option dcache option to select
+ */
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+ enum dcache_option option);
+
+#endif /* __ASSEMBLY__ */
+
#endif
* variable by both SPL and u-boot.Check out for CHSETTINGS, which is a
* mandatory section if CH is present.
*/
- if ((gd->arch.omap_boot_params.ch_flags) & (CH_FLAGS_CHSETTINGS))
+ if (gd->arch.omap_ch_flags & CH_FLAGS_CHSETTINGS)
return 0;
else
return running_from_sdram();
cmp x0, x18
b.gt zero_gd
#if defined(CONFIG_SYS_MALLOC_F_LEN)
- sub x0, x18, #CONFIG_SYS_MALLOC_F_LEN
+ ldr x0, =CONFIG_SYS_MALLOC_F_LEN
+ sub x0, x18, x0
str x0, [x18, #GD_MALLOC_BASE]
#endif
bic sp, x0, #0xf /* 16-byte alignment for ABI compliance */
static void core_spin(void)
{
- while (1)
- ; /* forever */;
+ while (1) {
+ asm volatile (
+ "dsb\n"
+ "isb\n"
+ "wfi\n"
+ );
+ }
}
int mon_power_on(int core_id, void *ep)
obj-$(CONFIG_SPL_BUILD) += spl.o
obj-$(CONFIG_SPL_BUILD) += lowlevel_spl.o
-obj-y += serdes/
+obj-$(CONFIG_SYS_MVEBU_DDR_A38X) += serdes/a38x/
+obj-$(CONFIG_SYS_MVEBU_DDR_AXP) += serdes/axp/
+
endif
}
}
+void mmu_disable(void)
+{
+ asm volatile(
+ "mrc p15, 0, r0, c1, c0, 0\n"
+ "bic r0, #1\n"
+ "mcr p15, 0, r0, c1, c0, 0\n");
+}
+
#ifdef CONFIG_ARCH_CPU_INIT
static void set_cbar(u32 addr)
{
int arch_cpu_init(void)
{
+#ifndef CONFIG_SPL_BUILD
+ /*
+ * Only with disabled MMU its possible to switch the base
+ * register address on Armada 38x. Without this the SDRAM
+ * located at >= 0x4000.0000 is also not accessible, as its
+ * still locked to cache.
+ */
+ mmu_disable();
+#endif
+
/* Linux expects the internal registers to be at 0xf1000000 */
writel(SOC_REGS_PHY_BASE, INTREG_BASE_ADDR_REG);
set_cbar(SOC_REGS_PHY_BASE + 0xC000);
/*
* DDR3 init / training code ported from Marvell bin_hdr. Now
* available in mainline U-Boot in:
- * drivers/ddr/mvebu/
+ * drivers/ddr/marvell
*/
int ddr3_init(void);
#endif /* __ASSEMBLY__ */
/* SOC specific definations */
#define INTREG_BASE 0xd0000000
#define INTREG_BASE_ADDR_REG (INTREG_BASE + 0x20080)
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SYS_MVEBU_DDR_A38X)
+/*
+ * On A38x switching the regs base address without running from
+ * SDRAM doesn't seem to work. So let the SPL still use the
+ * default base address and switch to the new address in the
+ * main u-boot later.
+ */
+#define SOC_REGS_PHY_BASE 0xd0000000
+#else
#define SOC_REGS_PHY_BASE 0xf1000000
+#endif
#define MVEBU_REGISTER(x) (SOC_REGS_PHY_BASE + x)
#define MVEBU_SDRAM_SCRATCH (MVEBU_REGISTER(0x01504))
#define MVEBU_USB20_BASE (MVEBU_REGISTER(0x58000))
#define MVEBU_EGIGA0_BASE (MVEBU_REGISTER(0x70000))
#define MVEBU_EGIGA1_BASE (MVEBU_REGISTER(0x74000))
+#define MVEBU_AXP_SATA_BASE (MVEBU_REGISTER(0xa0000))
#define MVEBU_SATA0_BASE (MVEBU_REGISTER(0xa8000))
#define MVEBU_SDIO_BASE (MVEBU_REGISTER(0xd8000))
--- /dev/null
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_SPL_BUILD) = ctrl_pex.o
+obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec.o
+obj-$(CONFIG_SPL_BUILD) += high_speed_env_spec-38x.o
+obj-$(CONFIG_SPL_BUILD) += high_speed_topology_spec-38x.o
+obj-$(CONFIG_SPL_BUILD) += seq_exec.o
+obj-$(CONFIG_SPL_BUILD) += sys_env_lib.o
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ctrl_pex.h"
+#include "sys_env_lib.h"
+
+int hws_pex_config(struct serdes_map *serdes_map)
+{
+ u32 pex_idx, tmp, next_busno, first_busno, temp_pex_reg,
+ temp_reg, addr, dev_id, ctrl_mode;
+ enum serdes_type serdes_type;
+ u32 idx, max_lane_num;
+
+ DEBUG_INIT_FULL_S("\n### hws_pex_config ###\n");
+
+ max_lane_num = hws_serdes_get_max_lane();
+ for (idx = 0; idx < max_lane_num; idx++) {
+ serdes_type = serdes_map[idx].serdes_type;
+ /* configuration for PEX only */
+ if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
+ (serdes_type != PEX2) && (serdes_type != PEX3))
+ continue;
+
+ if ((serdes_type != PEX0) &&
+ ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
+ (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
+ /* for PEX by4 - relevant for the first port only */
+ continue;
+ }
+
+ pex_idx = serdes_type - PEX0;
+ tmp = reg_read(PEX_CAPABILITIES_REG(pex_idx));
+ tmp &= ~(0xf << 20);
+ tmp |= (0x4 << 20);
+ reg_write(PEX_CAPABILITIES_REG(pex_idx), tmp);
+ }
+
+ tmp = reg_read(SOC_CTRL_REG);
+ tmp &= ~0x03;
+
+ for (idx = 0; idx < max_lane_num; idx++) {
+ serdes_type = serdes_map[idx].serdes_type;
+ if ((serdes_type != PEX0) &&
+ ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
+ (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
+ /* for PEX by4 - relevant for the first port only */
+ continue;
+ }
+
+ switch (serdes_type) {
+ case PEX0:
+ tmp |= 0x1 << PCIE0_ENABLE_OFFS;
+ break;
+ case PEX1:
+ tmp |= 0x1 << PCIE1_ENABLE_OFFS;
+ break;
+ case PEX2:
+ tmp |= 0x1 << PCIE2_ENABLE_OFFS;
+ break;
+ case PEX3:
+ tmp |= 0x1 << PCIE3_ENABLE_OFFS;
+ break;
+ default:
+ break;
+ }
+ }
+
+ reg_write(SOC_CTRL_REG, tmp);
+
+ /* Support gen1/gen2 */
+ DEBUG_INIT_FULL_S("Support gen1/gen2\n");
+ next_busno = 0;
+ mdelay(150);
+
+ for (idx = 0; idx < max_lane_num; idx++) {
+ serdes_type = serdes_map[idx].serdes_type;
+ DEBUG_INIT_FULL_S(" serdes_type=0x");
+ DEBUG_INIT_FULL_D(serdes_type, 8);
+ DEBUG_INIT_FULL_S("\n");
+ DEBUG_INIT_FULL_S(" idx=0x");
+ DEBUG_INIT_FULL_D(idx, 8);
+ DEBUG_INIT_FULL_S("\n");
+
+ /* Configuration for PEX only */
+ if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
+ (serdes_type != PEX2) && (serdes_type != PEX3))
+ continue;
+
+ if ((serdes_type != PEX0) &&
+ ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
+ (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
+ /* for PEX by4 - relevant for the first port only */
+ continue;
+ }
+
+ pex_idx = serdes_type - PEX0;
+ tmp = reg_read(PEX_DBG_STATUS_REG(pex_idx));
+
+ first_busno = next_busno;
+ if ((tmp & 0x7f) != 0x7e) {
+ DEBUG_INIT_S("PCIe, Idx ");
+ DEBUG_INIT_D(pex_idx, 1);
+ DEBUG_INIT_S(": detected no link\n");
+ continue;
+ }
+
+ next_busno++;
+ temp_pex_reg = reg_read((PEX_CFG_DIRECT_ACCESS
+ (pex_idx, PEX_LINK_CAPABILITY_REG)));
+ temp_pex_reg &= 0xf;
+ if (temp_pex_reg != 0x2)
+ continue;
+
+ temp_reg = (reg_read(PEX_CFG_DIRECT_ACCESS(
+ pex_idx,
+ PEX_LINK_CTRL_STAT_REG)) &
+ 0xf0000) >> 16;
+
+ /* Check if the link established is GEN1 */
+ DEBUG_INIT_FULL_S
+ ("Checking if the link established is gen1\n");
+ if (temp_reg != 0x1)
+ continue;
+
+ pex_local_bus_num_set(pex_idx, first_busno);
+ pex_local_dev_num_set(pex_idx, 1);
+ DEBUG_INIT_FULL_S("PCIe, Idx ");
+ DEBUG_INIT_FULL_D(pex_idx, 1);
+
+ DEBUG_INIT_S(":** Link is Gen1, check the EP capability\n");
+ /* link is Gen1, check the EP capability */
+ addr = pex_config_read(pex_idx, first_busno, 0, 0, 0x34) & 0xff;
+ DEBUG_INIT_FULL_C("pex_config_read: return addr=0x%x", addr, 4);
+ if (addr == 0xff) {
+ DEBUG_INIT_FULL_C
+ ("pex_config_read: return 0xff -->PCIe (%d): Detected No Link.",
+ pex_idx, 1);
+ continue;
+ }
+
+ while ((pex_config_read(pex_idx, first_busno, 0, 0, addr)
+ & 0xff) != 0x10) {
+ addr = (pex_config_read(pex_idx, first_busno, 0,
+ 0, addr) & 0xff00) >> 8;
+ }
+
+ /* Check for Gen2 and above */
+ if ((pex_config_read(pex_idx, first_busno, 0, 0,
+ addr + 0xc) & 0xf) < 0x2) {
+ DEBUG_INIT_S("PCIe, Idx ");
+ DEBUG_INIT_D(pex_idx, 1);
+ DEBUG_INIT_S(": remains Gen1\n");
+ continue;
+ }
+
+ tmp = reg_read(PEX_LINK_CTRL_STATUS2_REG(pex_idx));
+ DEBUG_RD_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
+ tmp &= ~(BIT(0) | BIT(1));
+ tmp |= BIT(1);
+ tmp |= BIT(6); /* Select Deemphasize (-3.5d_b) */
+ reg_write(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
+ DEBUG_WR_REG(PEX_LINK_CTRL_STATUS2_REG(pex_idx), tmp);
+
+ tmp = reg_read(PEX_CTRL_REG(pex_idx));
+ DEBUG_RD_REG(PEX_CTRL_REG(pex_idx), tmp);
+ tmp |= BIT(10);
+ reg_write(PEX_CTRL_REG(pex_idx), tmp);
+ DEBUG_WR_REG(PEX_CTRL_REG(pex_idx), tmp);
+
+ /*
+ * We need to wait 10ms before reading the PEX_DBG_STATUS_REG
+ * in order not to read the status of the former state
+ */
+ mdelay(10);
+
+ DEBUG_INIT_S("PCIe, Idx ");
+ DEBUG_INIT_D(pex_idx, 1);
+ DEBUG_INIT_S
+ (": Link upgraded to Gen2 based on client cpabilities\n");
+ }
+
+ /* Update pex DEVICE ID */
+ ctrl_mode = sys_env_model_get();
+
+ for (idx = 0; idx < max_lane_num; idx++) {
+ serdes_type = serdes_map[idx].serdes_type;
+ /* configuration for PEX only */
+ if ((serdes_type != PEX0) && (serdes_type != PEX1) &&
+ (serdes_type != PEX2) && (serdes_type != PEX3))
+ continue;
+
+ if ((serdes_type != PEX0) &&
+ ((serdes_map[idx].serdes_mode == PEX_ROOT_COMPLEX_X4) ||
+ (serdes_map[idx].serdes_mode == PEX_END_POINT_X4))) {
+ /* for PEX by4 - relevant for the first port only */
+ continue;
+ }
+
+ pex_idx = serdes_type - PEX0;
+ dev_id = reg_read(PEX_CFG_DIRECT_ACCESS
+ (pex_idx, PEX_DEVICE_AND_VENDOR_ID));
+ dev_id &= 0xffff;
+ dev_id |= ((ctrl_mode << 16) & 0xffff0000);
+ reg_write(PEX_CFG_DIRECT_ACCESS
+ (pex_idx, PEX_DEVICE_AND_VENDOR_ID), dev_id);
+ }
+ DEBUG_INIT_FULL_C("Update PEX Device ID ", ctrl_mode, 4);
+
+ return MV_OK;
+}
+
+int pex_local_bus_num_set(u32 pex_if, u32 bus_num)
+{
+ u32 pex_status;
+
+ DEBUG_INIT_FULL_S("\n### pex_local_bus_num_set ###\n");
+
+ if (bus_num >= MAX_PEX_BUSSES) {
+ DEBUG_INIT_C("pex_local_bus_num_set: Illegal bus number %d\n",
+ bus_num, 4);
+ return MV_BAD_PARAM;
+ }
+
+ pex_status = reg_read(PEX_STATUS_REG(pex_if));
+ pex_status &= ~PXSR_PEX_BUS_NUM_MASK;
+ pex_status |=
+ (bus_num << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
+ reg_write(PEX_STATUS_REG(pex_if), pex_status);
+
+ return MV_OK;
+}
+
+int pex_local_dev_num_set(u32 pex_if, u32 dev_num)
+{
+ u32 pex_status;
+
+ DEBUG_INIT_FULL_S("\n### pex_local_dev_num_set ###\n");
+
+ pex_status = reg_read(PEX_STATUS_REG(pex_if));
+ pex_status &= ~PXSR_PEX_DEV_NUM_MASK;
+ pex_status |=
+ (dev_num << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
+ reg_write(PEX_STATUS_REG(pex_if), pex_status);
+
+ return MV_OK;
+}
+
+/*
+ * pex_config_read - Read from configuration space
+ *
+ * DESCRIPTION:
+ * This function performs a 32 bit read from PEX configuration space.
+ * It supports both type 0 and type 1 of Configuration Transactions
+ * (local and over bridge). In order to read from local bus segment, use
+ * bus number retrieved from pex_local_bus_num_get(). Other bus numbers
+ * will result configuration transaction of type 1 (over bridge).
+ *
+ * INPUT:
+ * pex_if - PEX interface number.
+ * bus - PEX segment bus number.
+ * dev - PEX device number.
+ * func - Function number.
+ * reg_offs - Register offset.
+ *
+ * OUTPUT:
+ * None.
+ *
+ * RETURN:
+ * 32bit register data, 0xffffffff on error
+ */
+u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off)
+{
+ u32 pex_data = 0;
+ u32 local_dev, local_bus;
+ u32 pex_status;
+
+ pex_status = reg_read(PEX_STATUS_REG(pex_if));
+ local_dev =
+ ((pex_status & PXSR_PEX_DEV_NUM_MASK) >> PXSR_PEX_DEV_NUM_OFFS);
+ local_bus =
+ ((pex_status & PXSR_PEX_BUS_NUM_MASK) >> PXSR_PEX_BUS_NUM_OFFS);
+
+ /*
+ * In PCI Express we have only one device number
+ * and this number is the first number we encounter
+ * else that the local_dev
+ * spec pex define return on config read/write on any device
+ */
+ if (bus == local_bus) {
+ if (local_dev == 0) {
+ /*
+ * if local dev is 0 then the first number we encounter
+ * after 0 is 1
+ */
+ if ((dev != 1) && (dev != local_dev))
+ return MV_ERROR;
+ } else {
+ /*
+ * if local dev is not 0 then the first number we
+ * encounter is 0
+ */
+ if ((dev != 0) && (dev != local_dev))
+ return MV_ERROR;
+ }
+ }
+
+ /* Creating PEX address to be passed */
+ pex_data = (bus << PXCAR_BUS_NUM_OFFS);
+ pex_data |= (dev << PXCAR_DEVICE_NUM_OFFS);
+ pex_data |= (func << PXCAR_FUNC_NUM_OFFS);
+ /* Legacy register space */
+ pex_data |= (reg_off & PXCAR_REG_NUM_MASK);
+ /* Extended register space */
+ pex_data |= (((reg_off & PXCAR_REAL_EXT_REG_NUM_MASK) >>
+ PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
+ pex_data |= PXCAR_CONFIG_EN;
+
+ /* Write the address to the PEX configuration address register */
+ reg_write(PEX_CFG_ADDR_REG(pex_if), pex_data);
+
+ /*
+ * In order to let the PEX controller absorbed the address
+ * of the read transaction we perform a validity check that
+ * the address was written
+ */
+ if (pex_data != reg_read(PEX_CFG_ADDR_REG(pex_if)))
+ return MV_ERROR;
+
+ /* Cleaning Master Abort */
+ reg_bit_set(PEX_CFG_DIRECT_ACCESS(pex_if, PEX_STATUS_AND_COMMAND),
+ PXSAC_MABORT);
+ /* Read the Data returned in the PEX Data register */
+ pex_data = reg_read(PEX_CFG_DATA_REG(pex_if));
+
+ DEBUG_INIT_FULL_C(" --> ", pex_data, 4);
+
+ return pex_data;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _CTRL_PEX_H
+#define _CTRL_PEX_H
+
+#include "high_speed_env_spec.h"
+
+/* Sample at Reset */
+#define MPP_SAMPLE_AT_RESET(id) (0xe4200 + (id * 4))
+
+/* PCI Express Control and Status Registers */
+#define MAX_PEX_BUSSES 256
+
+#define MISC_REGS_OFFSET 0x18200
+#define MV_MISC_REGS_BASE MISC_REGS_OFFSET
+#define SOC_CTRL_REG (MV_MISC_REGS_BASE + 0x4)
+
+#define PEX_IF_REGS_OFFSET(if) ((if) > 0 ? \
+ (0x40000 + ((if) - 1) * 0x4000) : \
+ 0x80000)
+#define PEX_IF_REGS_BASE(if) (PEX_IF_REGS_OFFSET(if))
+#define PEX_CAPABILITIES_REG(if) ((PEX_IF_REGS_BASE(if)) + 0x60)
+#define PEX_LINK_CTRL_STATUS2_REG(if) ((PEX_IF_REGS_BASE(if)) + 0x90)
+#define PEX_CTRL_REG(if) ((PEX_IF_REGS_BASE(if)) + 0x1a00)
+#define PEX_STATUS_REG(if) ((PEX_IF_REGS_BASE(if)) + 0x1a04)
+#define PEX_DBG_STATUS_REG(if) ((PEX_IF_REGS_BASE(if)) + 0x1a64)
+#define PEX_LINK_CAPABILITY_REG 0x6c
+#define PEX_LINK_CTRL_STAT_REG 0x70
+#define PXSR_PEX_DEV_NUM_OFFS 16 /* Device Number Indication */
+#define PXSR_PEX_DEV_NUM_MASK (0x1f << PXSR_PEX_DEV_NUM_OFFS)
+#define PXSR_PEX_BUS_NUM_OFFS 8 /* Bus Number Indication */
+#define PXSR_PEX_BUS_NUM_MASK (0xff << PXSR_PEX_BUS_NUM_OFFS)
+
+/* PEX_CAPABILITIES_REG fields */
+#define PCIE0_ENABLE_OFFS 0
+#define PCIE0_ENABLE_MASK (0x1 << PCIE0_ENABLE_OFFS)
+#define PCIE1_ENABLE_OFFS 1
+#define PCIE1_ENABLE_MASK (0x1 << PCIE1_ENABLE_OFFS)
+#define PCIE2_ENABLE_OFFS 2
+#define PCIE2_ENABLE_MASK (0x1 << PCIE2_ENABLE_OFFS)
+#define PCIE3_ENABLE_OFFS 3
+#define PCIE4_ENABLE_MASK (0x1 << PCIE3_ENABLE_OFFS)
+
+/* Controller revision info */
+#define PEX_DEVICE_AND_VENDOR_ID 0x000
+
+/* PCI Express Configuration Address Register */
+#define PXCAR_REG_NUM_OFFS 2
+#define PXCAR_REG_NUM_MAX 0x3f
+#define PXCAR_REG_NUM_MASK (PXCAR_REG_NUM_MAX << \
+ PXCAR_REG_NUM_OFFS)
+#define PXCAR_FUNC_NUM_OFFS 8
+#define PXCAR_FUNC_NUM_MAX 0x7
+#define PXCAR_FUNC_NUM_MASK (PXCAR_FUNC_NUM_MAX << \
+ PXCAR_FUNC_NUM_OFFS)
+#define PXCAR_DEVICE_NUM_OFFS 11
+#define PXCAR_DEVICE_NUM_MAX 0x1f
+#define PXCAR_DEVICE_NUM_MASK (PXCAR_DEVICE_NUM_MAX << \
+ PXCAR_DEVICE_NUM_OFFS)
+#define PXCAR_BUS_NUM_OFFS 16
+#define PXCAR_BUS_NUM_MAX 0xff
+#define PXCAR_BUS_NUM_MASK (PXCAR_BUS_NUM_MAX << \
+ PXCAR_BUS_NUM_OFFS)
+#define PXCAR_EXT_REG_NUM_OFFS 24
+#define PXCAR_EXT_REG_NUM_MAX 0xf
+
+#define PEX_CFG_ADDR_REG(if) ((PEX_IF_REGS_BASE(if)) + 0x18f8)
+#define PEX_CFG_DATA_REG(if) ((PEX_IF_REGS_BASE(if)) + 0x18fc)
+
+#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
+#define PXCAR_REAL_EXT_REG_NUM_MASK (0xf << PXCAR_REAL_EXT_REG_NUM_OFFS)
+
+#define PXCAR_CONFIG_EN BIT(31)
+#define PEX_STATUS_AND_COMMAND 0x004
+#define PXSAC_MABORT BIT(29) /* Recieved Master Abort */
+
+int hws_pex_config(struct serdes_map *serdes_map);
+int pex_local_bus_num_set(u32 pex_if, u32 bus_num);
+int pex_local_dev_num_set(u32 pex_if, u32 dev_num);
+u32 pex_config_read(u32 pex_if, u32 bus, u32 dev, u32 func, u32 reg_off);
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "high_speed_env_spec.h"
+#include "sys_env_lib.h"
+
+#define SERDES_VERION "2.0"
+
+u8 selectors_serdes_rev1_map[LAST_SERDES_TYPE][MAX_SERDES_LANES] = {
+ /* 0 1 2 3 4 5 */
+ {0x1, 0x1, NA, NA, NA, NA}, /* PEX0 */
+ {NA, 0x2, 0x1, NA, 0x1, NA}, /* PEX1 */
+ {NA, NA, 0x2, NA, NA, 0x1}, /* PEX2 */
+ {NA, NA, NA, 0x1, NA, NA}, /* PEX3 */
+ {0x2, 0x3, NA, NA, NA, NA}, /* SATA0 */
+ {NA, NA, 0x3, NA, 0x2, NA}, /* SATA1 */
+ {NA, NA, NA, NA, 0x6, 0x2}, /* SATA2 */
+ {NA, NA, NA, 0x3, NA, NA}, /* SATA3 */
+ {0x3, 0x4, NA, NA, NA, NA}, /* SGMII0 */
+ {NA, 0x5, 0x4, NA, 0x3, NA}, /* SGMII1 */
+ {NA, NA, NA, 0x4, NA, 0x3}, /* SGMII2 */
+ {NA, 0x7, NA, NA, NA, NA}, /* QSGMII */
+ {NA, 0x6, NA, NA, 0x4, NA}, /* USB3_HOST0 */
+ {NA, NA, NA, 0x5, NA, 0x4}, /* USB3_HOST1 */
+ {NA, NA, NA, 0x6, 0x5, 0x5}, /* USB3_DEVICE */
+ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0} /* DEFAULT_SERDES */
+};
+
+int hws_serdes_seq_init(void)
+{
+ DEBUG_INIT_FULL_S("\n### serdes_seq_init ###\n");
+
+ if (hws_serdes_seq_db_init() != MV_OK) {
+ printf("hws_serdes_seq_init: Error: Serdes initialization fail\n");
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+int serdes_power_up_ctrl_ext(u32 serdes_num, int serdes_power_up,
+ enum serdes_type serdes_type,
+ enum serdes_speed baud_rate,
+ enum serdes_mode serdes_mode,
+ enum ref_clock ref_clock)
+{
+ return MV_NOT_SUPPORTED;
+}
+
+u32 hws_serdes_silicon_ref_clock_get(void)
+{
+ DEBUG_INIT_FULL_S("\n### hws_serdes_silicon_ref_clock_get ###\n");
+
+ return REF_CLOCK_25MHZ;
+}
+
+u32 hws_serdes_get_max_lane(void)
+{
+ switch (sys_env_device_id_get()) {
+ case MV_6811: /* A381/A3282: 6811/6821: single/dual cpu */
+ return 4;
+ case MV_6810:
+ return 5;
+ case MV_6820:
+ case MV_6828:
+ return 6;
+ default: /* not the right module */
+ printf("%s: Device ID Error, using 4 SerDes lanes\n",
+ __func__);
+ return 4;
+ }
+ return 6;
+}
+
+int hws_is_serdes_active(u8 lane_num)
+{
+ int ret = 1;
+
+ /* Maximum lane count for A388 (6828) is 6 */
+ if (lane_num > 6)
+ ret = 0;
+
+ /* 4th Lane (#4 on Device 6810 is not Active */
+ if (sys_env_device_id_get() == MV_6810 && lane_num == 4) {
+ printf("%s: Error: Lane#4 on Device 6810 is not Active.\n",
+ __func__);
+ return 0;
+ }
+
+ /*
+ * 6th Lane (#5) on Device 6810 is Active, even though 6810
+ * has only 5 lanes
+ */
+ if (sys_env_device_id_get() == MV_6810 && lane_num == 5)
+ return 1;
+
+ if (lane_num >= hws_serdes_get_max_lane())
+ ret = 0;
+
+ return ret;
+}
+
+int hws_get_ext_base_addr(u32 serdes_num, u32 base_addr, u32 unit_base_offset,
+ u32 *unit_base_reg, u32 *unit_offset)
+{
+ *unit_base_reg = base_addr;
+ *unit_offset = unit_base_offset;
+
+ return MV_OK;
+}
+
+/*
+ * hws_serdes_get_phy_selector_val
+ *
+ * DESCRIPTION: Get the mapping of Serdes Selector values according to the
+ * Serdes revision number
+ * INPUT: serdes_num - Serdes number
+ * serdes_type - Serdes type
+ * OUTPUT: None
+ * RETURN:
+ * Mapping of Serdes Selector values
+ */
+u32 hws_serdes_get_phy_selector_val(int serdes_num,
+ enum serdes_type serdes_type)
+{
+ if (serdes_type >= LAST_SERDES_TYPE)
+ return 0xff;
+
+ if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2) {
+ return selectors_serdes_rev1_map
+ [serdes_type][serdes_num];
+ } else
+ return selectors_serdes_rev2_map
+ [serdes_type][serdes_num];
+}
+
+u32 hws_get_physical_serdes_num(u32 serdes_num)
+{
+ if ((serdes_num == 4) && (sys_env_device_id_get() == MV_6810)) {
+ /*
+ * For 6810, there are 5 Serdes and Serdes Num 4 doesn't
+ * exist. Instead Serdes Num 5 is connected.
+ */
+ return 5;
+ } else {
+ return serdes_num;
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "high_speed_env_spec.h"
+#include "high_speed_topology_spec.h"
+#include "sys_env_lib.h"
+#include "ctrl_pex.h"
+
+#if defined(CONFIG_ARMADA_38X)
+#elif defined(CONFIG_ARMADA_39X)
+#else
+#error "No device is defined"
+#endif
+
+/*
+ * The board topology map, initialized in the beginning of
+ * ctrl_high_speed_serdes_phy_config
+ */
+struct serdes_map serdes_configuration_map[MAX_SERDES_LANES];
+
+/*
+ * serdes_seq_db - holds all serdes sequences, their size and the
+ * relevant index in the data array initialized in serdes_seq_init
+ */
+struct cfg_seq serdes_seq_db[SERDES_LAST_SEQ];
+
+#define SERDES_VERION "2.0"
+#define ENDED_OK "High speed PHY - Ended Successfully\n"
+
+#define LINK_WAIT_CNTR 100
+#define LINK_WAIT_SLEEP 100
+
+#define MAX_UNIT_NUMB 4
+#define TOPOLOGY_TEST_OK 0
+#define WRONG_NUMBER_OF_UNITS 1
+#define SERDES_ALREADY_IN_USE 2
+#define UNIT_NUMBER_VIOLATION 3
+
+/*
+ * serdes_lane_in_use_count contains the exact amount of serdes lanes
+ * needed per type
+ */
+u8 serdes_lane_in_use_count[MAX_UNITS_ID][MAX_UNIT_NUMB] = {
+ /* 0 1 2 3 */
+ { 1, 1, 1, 1 }, /* PEX */
+ { 1, 1, 1, 1 }, /* ETH_GIG */
+ { 1, 1, 0, 0 }, /* USB3H */
+ { 1, 1, 1, 0 }, /* USB3D */
+ { 1, 1, 1, 1 }, /* SATA */
+ { 1, 0, 0, 0 }, /* QSGMII */
+ { 4, 0, 0, 0 }, /* XAUI */
+ { 2, 0, 0, 0 } /* RXAUI */
+};
+
+/*
+ * serdes_unit_count count unit number.
+ * (i.e a single XAUI is counted as 1 unit)
+ */
+u8 serdes_unit_count[MAX_UNITS_ID] = { 0 };
+
+/* Selector mapping for A380-A0 and A390-Z1 */
+u8 selectors_serdes_rev2_map[LAST_SERDES_TYPE][MAX_SERDES_LANES] = {
+ /* 0 1 2 3 4 5 6 */
+ { 0x1, 0x1, NA, NA, NA, NA, NA }, /* PEX0 */
+ { NA, NA, 0x1, NA, 0x1, NA, 0x1 }, /* PEX1 */
+ { NA, NA, NA, NA, 0x7, 0x1, NA }, /* PEX2 */
+ { NA, NA, NA, 0x1, NA, NA, NA }, /* PEX3 */
+ { 0x2, 0x3, NA, NA, NA, NA, NA }, /* SATA0 */
+ { NA, NA, 0x3, NA, NA, NA, NA }, /* SATA1 */
+ { NA, NA, NA, NA, 0x6, 0x2, NA }, /* SATA2 */
+ { NA, NA, NA, 0x3, NA, NA, NA }, /* SATA3 */
+ { 0x3, 0x4, NA, NA, NA, NA, NA }, /* SGMII0 */
+ { NA, 0x5, 0x4, NA, 0x3, NA, NA }, /* SGMII1 */
+ { NA, NA, NA, 0x4, NA, 0x3, NA }, /* SGMII2 */
+ { NA, 0x7, NA, NA, NA, NA, NA }, /* QSGMII */
+ { NA, 0x6, NA, NA, 0x4, NA, NA }, /* USB3_HOST0 */
+ { NA, NA, NA, 0x5, NA, 0x4, NA }, /* USB3_HOST1 */
+ { NA, NA, NA, 0x6, 0x5, 0x5, NA }, /* USB3_DEVICE */
+#ifdef CONFIG_ARMADA_39X
+ { NA, NA, 0x5, NA, 0x8, NA, 0x2 }, /* SGMII3 */
+ { NA, NA, NA, 0x8, 0x9, 0x8, 0x4 }, /* XAUI */
+ { NA, NA, NA, NA, NA, 0x8, 0x4 }, /* RXAUI */
+#endif
+ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, NA } /* DEFAULT_SERDES */
+};
+
+/* Selector mapping for PEX by 4 confiuration */
+u8 common_phys_selectors_pex_by4_lanes[] = { 0x1, 0x2, 0x2, 0x2 };
+
+static const char *const serdes_type_to_string[] = {
+ "PCIe0",
+ "PCIe1",
+ "PCIe2",
+ "PCIe3",
+ "SATA0",
+ "SATA1",
+ "SATA2",
+ "SATA3",
+ "SGMII0",
+ "SGMII1",
+ "SGMII2",
+ "QSGMII",
+ "USB3 HOST0",
+ "USB3 HOST1",
+ "USB3 DEVICE",
+ "SGMII3",
+ "XAUI",
+ "RXAUI",
+ "DEFAULT SERDES",
+ "LAST_SERDES_TYPE"
+};
+
+struct serdes_unit_data {
+ u8 serdes_unit_id;
+ u8 serdes_unit_num;
+};
+
+static struct serdes_unit_data serdes_type_to_unit_info[] = {
+ {PEX_UNIT_ID, 0,},
+ {PEX_UNIT_ID, 1,},
+ {PEX_UNIT_ID, 2,},
+ {PEX_UNIT_ID, 3,},
+ {SATA_UNIT_ID, 0,},
+ {SATA_UNIT_ID, 1,},
+ {SATA_UNIT_ID, 2,},
+ {SATA_UNIT_ID, 3,},
+ {ETH_GIG_UNIT_ID, 0,},
+ {ETH_GIG_UNIT_ID, 1,},
+ {ETH_GIG_UNIT_ID, 2,},
+ {QSGMII_UNIT_ID, 0,},
+ {USB3H_UNIT_ID, 0,},
+ {USB3H_UNIT_ID, 1,},
+ {USB3D_UNIT_ID, 0,},
+ {ETH_GIG_UNIT_ID, 3,},
+ {XAUI_UNIT_ID, 0,},
+ {RXAUI_UNIT_ID, 0,},
+};
+
+/* Sequences DB */
+
+/*
+ * SATA and SGMII
+ */
+
+struct op_params sata_port0_power_up_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, wait_time,
+ * num_of_loops
+ */
+ /* Access to reg 0x48(OOB param 1) */
+ {SATA_VENDOR_PORT_0_REG_ADDR, 0x38000, 0xffffffff, {0x48,}, 0, 0},
+ /* OOB Com_wake and Com_reset spacing upper limit data */
+ {SATA_VENDOR_PORT_0_REG_DATA, 0x38000, 0xf03f, {0x6018,}, 0, 0},
+ /* Access to reg 0xa(PHY Control) */
+ {SATA_VENDOR_PORT_0_REG_ADDR, 0x38000, 0xffffffff, {0xa,}, 0, 0},
+ /* Rx clk and Tx clk select non-inverted mode */
+ {SATA_VENDOR_PORT_0_REG_DATA, 0x38000, 0x3000, {0x0,}, 0, 0},
+ /* Power Down Sata addr */
+ {SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x0,}, 0, 0},
+ /* Power Down Sata Port 0 */
+ {SATA_CTRL_REG_IND_DATA, 0x38000, 0xffff00ff, {0xc40040,}, 0, 0},
+};
+
+struct op_params sata_port1_power_up_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, wait_time,
+ * num_of_loops
+ */
+ /* Access to reg 0x48(OOB param 1) */
+ {SATA_VENDOR_PORT_1_REG_ADDR, 0x38000, 0xffffffff, {0x48,}, 0, 0},
+ /* OOB Com_wake and Com_reset spacing upper limit data */
+ {SATA_VENDOR_PORT_1_REG_DATA, 0x38000, 0xf03f, {0x6018,}, 0, 0},
+ /* Access to reg 0xa(PHY Control) */
+ {SATA_VENDOR_PORT_1_REG_ADDR, 0x38000, 0xffffffff, {0xa,}, 0, 0},
+ /* Rx clk and Tx clk select non-inverted mode */
+ {SATA_VENDOR_PORT_1_REG_DATA, 0x38000, 0x3000, {0x0,}, 0, 0},
+ /* Power Down Sata addr */
+ {SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x0,}, 0, 0},
+ /* Power Down Sata Port 1 */
+ {SATA_CTRL_REG_IND_DATA, 0x38000, 0xffffff00, {0xc44000,}, 0, 0},
+};
+
+/* SATA and SGMII - power up seq */
+struct op_params sata_and_sgmii_power_up_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, SGMII data,
+ * wait_time, num_of_loops
+ */
+ /* Power Up */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x90006, {0x80002, 0x80002},
+ 0, 0},
+ /* Unreset */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x7800, {0x6000, 0x6000}, 0, 0},
+ /* Phy Selector */
+ {POWER_AND_PLL_CTRL_REG, 0x800, 0x0e0, {0x0, 0x80}, 0, 0},
+ /* Ref clock source select */
+ {MISC_REG, 0x800, 0x440, {0x440, 0x400}, 0, 0}
+};
+
+/* SATA and SGMII - speed config seq */
+struct op_params sata_and_sgmii_speed_config_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data,
+ * SGMII (1.25G), SGMII (3.125G), wait_time, num_of_loops
+ */
+ /* Baud Rate */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x3fc00000,
+ {0x8800000, 0x19800000, 0x22000000}, 0, 0},
+ /* Select Baud Rate for SATA only */
+ {INTERFACE_REG, 0x800, 0xc00, {0x800, NO_DATA, NO_DATA}, 0, 0},
+ /* Phy Gen RX and TX */
+ {ISOLATE_REG, 0x800, 0xff, {NO_DATA, 0x66, 0x66}, 0, 0},
+ /* Bus Width */
+ {LOOPBACK_REG, 0x800, 0xe, {0x4, 0x2, 0x2}, 0, 0}
+};
+
+/* SATA and SGMII - TX config seq */
+struct op_params sata_and_sgmii_tx_config_params1[] = {
+ /*
+ * unitunit_base_reg, unit_offset, mask, SATA data, SGMII data,
+ * wait_time, num_of_loops
+ */
+ {GLUE_REG, 0x800, 0x1800, {NO_DATA, 0x800}, 0, 0},
+ /* Sft Reset pulse */
+ {RESET_DFE_REG, 0x800, 0x401, {0x401, 0x401}, 0, 0},
+ /* Sft Reset pulse */
+ {RESET_DFE_REG, 0x800, 0x401, {0x0, 0x0}, 0, 0},
+ /* Power up PLL, RX and TX */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0xf0000, {0x70000, 0x70000},
+ 0, 0}
+};
+
+struct op_params sata_port0_tx_config_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, wait_time,
+ * num_of_loops
+ */
+ /* Power Down Sata addr */
+ {SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x0}, 0, 0},
+ /* Power Down Sata Port 0 */
+ {SATA_CTRL_REG_IND_DATA, 0x38000, 0xffff00ff, {0xc40000}, 0, 0},
+ /* Regret bit addr */
+ {SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x4}, 0, 0},
+ /* Regret bit data */
+ {SATA_CTRL_REG_IND_DATA, 0x38000, 0xffffffff, {0x80}, 0, 0}
+};
+
+struct op_params sata_port1_tx_config_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, wait_time,
+ * num_of_loops
+ */
+ /* Power Down Sata addr */
+ {SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x0}, 0, 0},
+ /* Power Down Sata Port 1 */
+ {SATA_CTRL_REG_IND_DATA, 0x38000, 0xffffff00, {0xc40000}, 0, 0},
+ /* Regret bit addr */
+ {SATA_CTRL_REG_IND_ADDR, 0x38000, 0xffffffff, {0x4}, 0, 0},
+ /* Regret bit data */
+ {SATA_CTRL_REG_IND_DATA, 0x38000, 0xffffffff, {0x80}, 0, 0}
+};
+
+struct op_params sata_and_sgmii_tx_config_serdes_rev1_params2[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, SGMII data,
+ * wait_time, num_of_loops
+ */
+ /* Wait for PHY power up sequence to finish */
+ {COMMON_PHY_STATUS1_REG, 0x28, 0xc, {0xc, 0xc}, 10, 1000},
+ /* Wait for PHY power up sequence to finish */
+ {COMMON_PHY_STATUS1_REG, 0x28, 0x1, {0x1, 0x1}, 1, 1000}
+};
+
+struct op_params sata_and_sgmii_tx_config_serdes_rev2_params2[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, SGMII data,
+ * wait_time, num_of_loops
+ */
+ /* Wait for PHY power up sequence to finish */
+ {COMMON_PHY_STATUS1_REG, 0x28, 0xc, {0xc, 0xc}, 10, 1000},
+ /* Assert Rx Init for SGMII */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x40000000, {NA, 0x40000000},
+ 0, 0},
+ /* Assert Rx Init for SATA */
+ {ISOLATE_REG, 0x800, 0x400, {0x400, NA}, 0, 0},
+ /* Wait for PHY power up sequence to finish */
+ {COMMON_PHY_STATUS1_REG, 0x28, 0x1, {0x1, 0x1}, 1, 1000},
+ /* De-assert Rx Init for SGMII */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x40000000, {NA, 0x0}, 0, 0},
+ /* De-assert Rx Init for SATA */
+ {ISOLATE_REG, 0x800, 0x400, {0x0, NA}, 0, 0},
+ /* os_ph_offset_force (align 90) */
+ {RX_REG3, 0x800, 0xff, {0xde, NO_DATA}, 0, 0},
+ /* Set os_ph_valid */
+ {RX_REG3, 0x800, 0x100, {0x100, NO_DATA}, 0, 0},
+ /* Unset os_ph_valid */
+ {RX_REG3, 0x800, 0x100, {0x0, NO_DATA}, 0, 0},
+};
+
+struct op_params sata_electrical_config_serdes_rev1_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, wait_time,
+ * num_of_loops
+ */
+ /* enable SSC and DFE update enable */
+ {COMMON_PHY_CONFIGURATION4_REG, 0x28, 0x400008, {0x400000,}, 0, 0},
+ /* tximpcal_th and rximpcal_th */
+ {VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x4000,}, 0, 0},
+ /* SQ_THRESH and FFE Setting */
+ {SQUELCH_FFE_SETTING_REG, 0x800, 0xfff, {0x6cf,}, 0, 0},
+ /* G1_TX SLEW, EMPH1 and AMP */
+ {G1_SETTINGS_0_REG, 0x800, 0xffff, {0x8a32,}, 0, 0},
+ /* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9,}, 0, 0},
+ /* G2_TX SLEW, EMPH1 and AMP */
+ {G2_SETTINGS_0_REG, 0x800, 0xffff, {0x8b5c,}, 0, 0},
+ /* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2,}, 0, 0},
+ /* G3_TX SLEW, EMPH1 and AMP */
+ {G3_SETTINGS_0_REG, 0x800, 0xffff, {0xe6e,}, 0, 0},
+ /* G3_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G3_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2,}, 0, 0},
+ /* Cal rxclkalign90 ext enable and Cal os ph ext */
+ {CAL_REG6, 0x800, 0xff00, {0xdd00,}, 0, 0},
+ /* Dtl Clamping disable and Dtl clamping Sel(6000ppm) */
+ {RX_REG2, 0x800, 0xf0, {0x70,}, 0, 0},
+};
+
+struct op_params sata_electrical_config_serdes_rev2_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SATA data, wait_time,
+ * num_of_loops
+ */
+ /* SQ_THRESH and FFE Setting */
+ {SQUELCH_FFE_SETTING_REG, 0x800, 0xf00, {0x600}, 0, 0},
+ /* enable SSC and DFE update enable */
+ {COMMON_PHY_CONFIGURATION4_REG, 0x28, 0x400008, {0x400000}, 0, 0},
+ /* G1_TX SLEW, EMPH1 and AMP */
+ {G1_SETTINGS_0_REG, 0x800, 0xffff, {0x8a32}, 0, 0},
+ /* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
+ /* G2_TX SLEW, EMPH1 and AMP */
+ {G2_SETTINGS_0_REG, 0x800, 0xffff, {0x8b5c}, 0, 0},
+ /* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2}, 0, 0},
+ /* G3_TX SLEW, EMPH1 and AMP */
+ {G3_SETTINGS_0_REG, 0x800, 0xffff, {0xe6e}, 0, 0},
+ /*
+ * G3_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI & DFE_En Gen3,
+ * DC wander calibration dis
+ */
+ {G3_SETTINGS_1_REG, 0x800, 0x47ff, {0x7d2}, 0, 0},
+ /* Bit[12]=0x0 idle_sync_en */
+ {PCIE_REG0, 0x800, 0x1000, {0x0}, 0, 0},
+ /* Dtl Clamping disable and Dtl clamping Sel(6000ppm) */
+ {RX_REG2, 0x800, 0xf0, {0x70,}, 0, 0},
+ /* tximpcal_th and rximpcal_th */
+ {VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000}, 0, 0},
+ /* DFE_STEP_FINE_FX[3:0] =0xa */
+ {DFE_REG0, 0x800, 0xa00f, {0x800a}, 0, 0},
+ /* DFE_EN and Dis Update control from pin disable */
+ {DFE_REG3, 0x800, 0xc000, {0x0}, 0, 0},
+ /* FFE Force FFE_REs and cap settings for Gen1 */
+ {G1_SETTINGS_3_REG, 0x800, 0xff, {0xcf}, 0, 0},
+ /* FFE Force FFE_REs and cap settings for Gen2 */
+ {G2_SETTINGS_3_REG, 0x800, 0xff, {0xbf}, 0, 0},
+ /* FE Force FFE_REs=4 and cap settings for Gen3n */
+ {G3_SETTINGS_3_REG, 0x800, 0xff, {0xcf}, 0, 0},
+ /* Set DFE Gen 3 Resolution to 3 */
+ {G3_SETTINGS_4_REG, 0x800, 0x300, {0x300}, 0, 0},
+};
+
+struct op_params sgmii_electrical_config_serdes_rev1_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SGMII (1.25G), SGMII (3.125G),
+ * wait_time, num_of_loops
+ */
+ /* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9, 0x3c9}, 0, 0},
+ /* SQ_THRESH and FFE Setting */
+ {SQUELCH_FFE_SETTING_REG, 0x800, 0xfff, {0x8f, 0xbf}, 0, 0},
+ /* tximpcal_th and rximpcal_th */
+ {VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x4000, 0x4000}, 0, 0},
+};
+
+struct op_params sgmii_electrical_config_serdes_rev2_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, SGMII (1.25G), SGMII (3.125G),
+ * wait_time, num_of_loops
+ */
+ /* Set Slew_rate, Emph and Amp */
+ {G1_SETTINGS_0_REG, 0x800, 0xffff, {0x8fa, 0x8fa}, 0, 0},
+ /* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9, 0x3c9}, 0, 0},
+ /* DTL_FLOOP_EN */
+ {RX_REG2, 0x800, 0x4, {0x0, 0x0}, 0, 0},
+ /* G1 FFE Setting Force, RES and CAP */
+ {G1_SETTINGS_3_REG, 0x800, 0xff, {0x8f, 0xbf}, 0, 0},
+ /* tximpcal_th and rximpcal_th */
+ {VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000, 0x3000}, 0, 0},
+};
+
+/*
+ * PEX and USB3
+ */
+
+/* PEX and USB3 - power up seq for Serdes Rev 1.2 */
+struct op_params pex_and_usb3_power_up_serdes_rev1_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
+ * wait_time, num_of_loops
+ */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x3fc7f806,
+ {0x4471804, 0x4479804}, 0, 0},
+ {COMMON_PHY_CONFIGURATION2_REG, 0x28, 0x5c, {0x58, 0x58}, 0, 0},
+ {COMMON_PHY_CONFIGURATION4_REG, 0x28, 0x3, {0x1, 0x1}, 0, 0},
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x7800, {0x6000, 0xe000}, 0, 0},
+ {GLOBAL_CLK_CTRL, 0x800, 0xd, {0x5, 0x1}, 0, 0},
+ /* Ref clock source select */
+ {MISC_REG, 0x800, 0x4c0, {0x80, 0x4c0}, 0, 0}
+};
+
+/* PEX and USB3 - power up seq for Serdes Rev 2.1 */
+struct op_params pex_and_usb3_power_up_serdes_rev2_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
+ * wait_time, num_of_loops
+ */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x3fc7f806,
+ {0x4471804, 0x4479804}, 0, 0},
+ {COMMON_PHY_CONFIGURATION2_REG, 0x28, 0x5c, {0x58, 0x58}, 0, 0},
+ {COMMON_PHY_CONFIGURATION4_REG, 0x28, 0x3, {0x1, 0x1}, 0, 0},
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x7800, {0x6000, 0xe000}, 0, 0},
+ {GLOBAL_CLK_CTRL, 0x800, 0xd, {0x5, 0x1}, 0, 0},
+ {GLOBAL_MISC_CTRL, 0x800, 0xc0, {0x0, NO_DATA}, 0, 0},
+ /* Ref clock source select */
+ {MISC_REG, 0x800, 0x4c0, {0x80, 0x4c0}, 0, 0}
+};
+
+/* PEX and USB3 - speed config seq */
+struct op_params pex_and_usb3_speed_config_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
+ * wait_time, num_of_loops
+ */
+ /* Maximal PHY Generation Setting */
+ {INTERFACE_REG, 0x800, 0xc00, {0x400, 0x400, 0x400, 0x400, 0x400},
+ 0, 0},
+};
+
+struct op_params usb3_electrical_config_serdes_rev1_params[] = {
+ /* Spread Spectrum Clock Enable */
+ {LANE_CFG4_REG, 0x800, 0x80, {0x80}, 0, 0},
+ /* G2_TX_SSC_AMP[6:0]=4.5k_p_pM and TX emphasis mode=m_v */
+ {G2_SETTINGS_2_REG, 0x800, 0xfe40, {0x4440}, 0, 0},
+ /* tximpcal_th and rximpcal_th */
+ {VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x4000}, 0, 0},
+ /* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2}, 0, 0},
+ /* FFE Setting Force, RES and CAP */
+ {SQUELCH_FFE_SETTING_REG, 0x800, 0xff, {0xef}, 0, 0},
+ /* Dtl Clamping disable and Dtl-clamping-Sel(6000ppm) */
+ {RX_REG2, 0x800, 0xf0, {0x70}, 0, 0},
+ /* cal_rxclkalign90_ext_en and cal_os_ph_ext */
+ {CAL_REG6, 0x800, 0xff00, {0xd500}, 0, 0},
+ /* vco_cal_vth_sel */
+ {REF_REG0, 0x800, 0x38, {0x20}, 0, 0},
+};
+
+struct op_params usb3_electrical_config_serdes_rev2_params[] = {
+ /* Spread Spectrum Clock Enable */
+ {LANE_CFG4_REG, 0x800, 0x80, {0x80}, 0, 0},
+ /* G2_TX_SSC_AMP[6:0]=4.5k_p_pM and TX emphasis mode=m_v */
+ {G2_SETTINGS_2_REG, 0x800, 0xfe40, {0x4440}, 0, 0},
+ /* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2}, 0, 0},
+ /* Dtl Clamping disable and Dtl-clamping-Sel(6000ppm) */
+ {RX_REG2, 0x800, 0xf0, {0x70}, 0, 0},
+ /* vco_cal_vth_sel */
+ {REF_REG0, 0x800, 0x38, {0x20}, 0, 0},
+ /* Spread Spectrum Clock Enable */
+ {LANE_CFG5_REG, 0x800, 0x4, {0x4}, 0, 0},
+};
+
+/* PEX and USB3 - TX config seq */
+
+/*
+ * For PEXx1: the pex_and_usb3_tx_config_params1/2/3 configurations should run
+ * one by one on the lane.
+ * For PEXx4: the pex_and_usb3_tx_config_params1/2/3 configurations should run
+ * by setting each sequence for all 4 lanes.
+ */
+struct op_params pex_and_usb3_tx_config_params1[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
+ * wait_time, num_of_loops
+ */
+ {GLOBAL_CLK_CTRL, 0x800, 0x1, {0x0, 0x0}, 0, 0},
+ /* 10ms delay */
+ {0x0, 0x0, 0x0, {0x0, 0x0}, 10, 0},
+ /* os_ph_offset_force (align 90) */
+ {RX_REG3, 0x800, 0xff, {0xdc, NO_DATA}, 0, 0},
+ /* Set os_ph_valid */
+ {RX_REG3, 0x800, 0x100, {0x100, NO_DATA}, 0, 0},
+ /* Unset os_ph_valid */
+ {RX_REG3, 0x800, 0x100, {0x0, NO_DATA}, 0, 0},
+};
+
+struct op_params pex_and_usb3_tx_config_params2[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
+ * wait_time, num_of_loops
+ */
+ /* Sft Reset pulse */
+ {RESET_DFE_REG, 0x800, 0x401, {0x401, 0x401}, 0, 0},
+};
+
+struct op_params pex_and_usb3_tx_config_params3[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, USB3 data,
+ * wait_time, num_of_loops
+ */
+ /* Sft Reset pulse */
+ {RESET_DFE_REG, 0x800, 0x401, {0x0, 0x0}, 0, 0},
+ /* 10ms delay */
+ {0x0, 0x0, 0x0, {0x0, 0x0}, 10, 0}
+};
+
+/* PEX by 4 config seq */
+struct op_params pex_by4_config_params[] = {
+ /* unit_base_reg, unit_offset, mask, data, wait_time, num_of_loops */
+ {GLOBAL_CLK_SRC_HI, 0x800, 0x7, {0x5, 0x0, 0x0, 0x2}, 0, 0},
+ /* Lane Alignement enable */
+ {LANE_ALIGN_REG0, 0x800, 0x1000, {0x0, 0x0, 0x0, 0x0}, 0, 0},
+ /* Max PLL phy config */
+ {CALIBRATION_CTRL_REG, 0x800, 0x1000, {0x1000, 0x1000, 0x1000, 0x1000},
+ 0, 0},
+ /* Max PLL pipe config */
+ {LANE_CFG1_REG, 0x800, 0x600, {0x600, 0x600, 0x600, 0x600}, 0, 0},
+};
+
+/* USB3 device donfig seq */
+struct op_params usb3_device_config_params[] = {
+ /* unit_base_reg, unit_offset, mask, data, wait_time, num_of_loops */
+ {LANE_CFG4_REG, 0x800, 0x200, {0x200}, 0, 0}
+};
+
+/* PEX - electrical configuration seq Rev 1.2 */
+struct op_params pex_electrical_config_serdes_rev1_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, wait_time,
+ * num_of_loops
+ */
+ /* G1_TX_SLEW_CTRL_EN and G1_TX_SLEW_RATE */
+ {G1_SETTINGS_0_REG, 0x800, 0xf000, {0xb000}, 0, 0},
+ /* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
+ /* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
+ /* CFG_DFE_EN_SEL */
+ {LANE_CFG4_REG, 0x800, 0x8, {0x8}, 0, 0},
+ /* FFE Setting Force, RES and CAP */
+ {SQUELCH_FFE_SETTING_REG, 0x800, 0xff, {0xaf}, 0, 0},
+ /* tximpcal_th and rximpcal_th */
+ {VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000}, 0, 0},
+ /* cal_rxclkalign90_ext_en and cal_os_ph_ext */
+ {CAL_REG6, 0x800, 0xff00, {0xdc00}, 0, 0},
+};
+
+/* PEX - electrical configuration seq Rev 2.1 */
+struct op_params pex_electrical_config_serdes_rev2_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, wait_time,
+ * num_of_loops
+ */
+ /* G1_TX_SLEW_CTRL_EN and G1_TX_SLEW_RATE */
+ {G1_SETTINGS_0_REG, 0x800, 0xf000, {0xb000}, 0, 0},
+ /* G1_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G1_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
+ /* G1 FFE Setting Force, RES and CAP */
+ {G1_SETTINGS_3_REG, 0x800, 0xff, {0xcf}, 0, 0},
+ /* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
+ {G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3c9}, 0, 0},
+ /* G2 FFE Setting Force, RES and CAP */
+ {G2_SETTINGS_3_REG, 0x800, 0xff, {0xaf}, 0, 0},
+ /* G2 DFE resolution value */
+ {G2_SETTINGS_4_REG, 0x800, 0x300, {0x300}, 0, 0},
+ /* DFE resolution force */
+ {DFE_REG0, 0x800, 0x8000, {0x8000}, 0, 0},
+ /* Tx amplitude for Tx Margin 0 */
+ {PCIE_REG1, 0x800, 0xf80, {0xd00}, 0, 0},
+ /* Tx_Emph value for -3.5d_b and -6d_b */
+ {PCIE_REG3, 0x800, 0xff00, {0xaf00}, 0, 0},
+ /* CFG_DFE_EN_SEL */
+ {LANE_CFG4_REG, 0x800, 0x8, {0x8}, 0, 0},
+ /* tximpcal_th and rximpcal_th */
+ {VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000}, 0, 0},
+};
+
+/* PEX - configuration seq for REF_CLOCK_25MHz */
+struct op_params pex_config_ref_clock25_m_hz[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, wait_time,
+ * num_of_loops
+ */
+ /* Bits[4:0]=0x2 - REF_FREF_SEL */
+ {POWER_AND_PLL_CTRL_REG, 0x800, 0x1f, {0x2}, 0, 0},
+ /* Bit[10]=0x1 - REFCLK_SEL */
+ {MISC_REG, 0x800, 0x400, {0x400}, 0, 0},
+ /* Bits[7:0]=0x7 - CFG_PM_RXDLOZ_WAIT */
+ {GLOBAL_PM_CTRL, 0x800, 0xff, {0x7}, 0, 0},
+};
+
+/* PEX - configuration seq for REF_CLOCK_40MHz */
+struct op_params pex_config_ref_clock40_m_hz[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, wait_time,
+ * num_of_loops
+ */
+ /* Bits[4:0]=0x3 - REF_FREF_SEL */
+ {POWER_AND_PLL_CTRL_REG, 0x800, 0x1f, {0x3}, 0, 0},
+ /* Bits[10]=0x1 - REFCLK_SEL */
+ {MISC_REG, 0x800, 0x400, {0x400}, 0, 0},
+ /* Bits[7:0]=0xc - CFG_PM_RXDLOZ_WAIT */
+ {GLOBAL_PM_CTRL, 0x800, 0xff, {0xc}, 0, 0},
+};
+
+/* PEX - configuration seq for REF_CLOCK_100MHz */
+struct op_params pex_config_ref_clock100_m_hz[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, PEX data, wait_time,
+ * num_of_loops
+ */
+ /* Bits[4:0]=0x0 - REF_FREF_SEL */
+ {POWER_AND_PLL_CTRL_REG, 0x800, 0x1f, {0x0}, 0, 0},
+ /* Bit[10]=0x0 - REFCLK_SEL */
+ {MISC_REG, 0x800, 0x400, {0x0}, 0, 0},
+ /* Bits[7:0]=0x1e - CFG_PM_RXDLOZ_WAIT */
+ {GLOBAL_PM_CTRL, 0x800, 0xff, {0x1e}, 0, 0},
+};
+
+/*
+ * USB2
+ */
+
+struct op_params usb2_power_up_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, USB2 data, wait_time,
+ * num_of_loops
+ */
+ /* Init phy 0 */
+ {0x18440, 0x0 /*NA*/, 0xffffffff, {0x62}, 0, 0},
+ /* Init phy 1 */
+ {0x18444, 0x0 /*NA*/, 0xffffffff, {0x62}, 0, 0},
+ /* Init phy 2 */
+ {0x18448, 0x0 /*NA*/, 0xffffffff, {0x62}, 0, 0},
+ /* Phy offset 0x0 - PLL_CONTROL0 */
+ {0xc0000, 0x0 /*NA*/, 0xffffffff, {0x40605205}, 0, 0},
+ {0xc001c, 0x0 /*NA*/, 0xffffffff, {0x39f16ce}, 0, 0},
+ {0xc201c, 0x0 /*NA*/, 0xffffffff, {0x39f16ce}, 0, 0},
+ {0xc401c, 0x0 /*NA*/, 0xffffffff, {0x39f16ce}, 0, 0},
+ /* Phy offset 0x1 - PLL_CONTROL1 */
+ {0xc0004, 0x0 /*NA*/, 0x1, {0x1}, 0, 0},
+ /* Phy0 register 3 - TX Channel control 0 */
+ {0xc000c, 0x0 /*NA*/, 0x1000000, {0x1000000}, 0, 0},
+ /* Phy0 register 3 - TX Channel control 0 */
+ {0xc200c, 0x0 /*NA*/, 0x1000000, {0x1000000}, 0, 0},
+ /* Phy0 register 3 - TX Channel control 0 */
+ {0xc400c, 0x0 /*NA*/, 0x1000000, {0x1000000}, 0, 0},
+ /* check PLLCAL_DONE is set and IMPCAL_DONE is set */
+ {0xc0008, 0x0 /*NA*/, 0x80800000, {0x80800000}, 1, 1000},
+ /* check REG_SQCAL_DONE is set */
+ {0xc0018, 0x0 /*NA*/, 0x80000000, {0x80000000}, 1, 1000},
+ /* check PLL_READY is set */
+ {0xc0000, 0x0 /*NA*/, 0x80000000, {0x80000000}, 1, 1000}
+};
+
+/*
+ * QSGMII
+ */
+
+/* QSGMII - power up seq */
+struct op_params qsgmii_port_power_up_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
+ * num_of_loops
+ */
+ /* Connect the QSGMII to Gigabit Ethernet units */
+ {QSGMII_CONTROL_REG1, 0x0, 0x40000000, {0x40000000}, 0, 0},
+ /* Power Up */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0xf0006, {0x80002}, 0, 0},
+ /* Unreset */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x7800, {0x6000}, 0, 0},
+ /* Phy Selector */
+ {POWER_AND_PLL_CTRL_REG, 0x800, 0xff, {0xfc81}, 0, 0},
+ /* Ref clock source select */
+ {MISC_REG, 0x800, 0x4c0, {0x480}, 0, 0}
+};
+
+/* QSGMII - speed config seq */
+struct op_params qsgmii_port_speed_config_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
+ * num_of_loops
+ */
+ /* Baud Rate */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x3fc00000, {0xcc00000}, 0, 0},
+ /* Phy Gen RX and TX */
+ {ISOLATE_REG, 0x800, 0xff, {0x33}, 0, 0},
+ /* Bus Width */
+ {LOOPBACK_REG, 0x800, 0xe, {0x2}, 0, 0}
+};
+
+/* QSGMII - Select electrical param seq */
+struct op_params qsgmii_port_electrical_config_params[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
+ * num_of_loops
+ */
+ /* Slew rate and emphasis */
+ {G1_SETTINGS_0_REG, 0x800, 0x8000, {0x0}, 0, 0}
+};
+
+/* QSGMII - TX config seq */
+struct op_params qsgmii_port_tx_config_params1[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
+ * num_of_loops
+ */
+ {GLUE_REG, 0x800, 0x1800, {0x800}, 0, 0},
+ /* Sft Reset pulse */
+ {RESET_DFE_REG, 0x800, 0x401, {0x401}, 0, 0},
+ /* Sft Reset pulse */
+ {RESET_DFE_REG, 0x800, 0x401, {0x0}, 0, 0},
+ /* Lane align */
+ {LANE_ALIGN_REG0, 0x800, 0x1000, {0x1000}, 0, 0},
+ /* Power up PLL, RX and TX */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x70000, {0x70000}, 0, 0},
+ /* Tx driver output idle */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x80000, {0x80000}, 0, 0}
+};
+
+struct op_params qsgmii_port_tx_config_params2[] = {
+ /*
+ * unit_base_reg, unit_offset, mask, QSGMII data, wait_time,
+ * num_of_loops
+ */
+ /* Wait for PHY power up sequence to finish */
+ {COMMON_PHY_STATUS1_REG, 0x28, 0xc, {0xc}, 10, 1000},
+ /* Assert Rx Init and Tx driver output valid */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x40080000, {0x40000000}, 0, 0},
+ /* Wait for PHY power up sequence to finish */
+ {COMMON_PHY_STATUS1_REG, 0x28, 0x1, {0x1}, 1, 1000},
+ /* De-assert Rx Init */
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, 0x40000000, {0x0}, 0, 0}
+};
+
+/* SERDES_POWER_DOWN */
+struct op_params serdes_power_down_params[] = {
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, (0xf << 11), {(0x3 << 11)},
+ 0, 0},
+ {COMMON_PHY_CONFIGURATION1_REG, 0x28, (0x7 << 16), {0}, 0, 0}
+};
+
+/*
+ * hws_ctrl_serdes_rev_get
+ *
+ * DESCRIPTION: Get the Serdes revision number
+ *
+ * INPUT: config_field - Field description enum
+ *
+ * OUTPUT: None
+ *
+ * RETURN:
+ * 8bit Serdes revision number
+ */
+u8 hws_ctrl_serdes_rev_get(void)
+{
+#ifdef CONFIG_ARMADA_38X
+ /* for A38x-Z1 */
+ if (sys_env_device_rev_get() == MV_88F68XX_Z1_ID)
+ return MV_SERDES_REV_1_2;
+#endif
+
+ /* for A39x-Z1, A38x-A0 */
+ return MV_SERDES_REV_2_1;
+}
+
+u32 hws_serdes_topology_verify(enum serdes_type serdes_type, u32 serdes_id,
+ enum serdes_mode serdes_mode)
+{
+ u32 test_result = 0;
+ u8 serd_max_num, unit_numb;
+ enum unit_id unit_id;
+
+ if (serdes_type > RXAUI) {
+ printf("%s: Warning: Wrong serdes type %s serdes#%d\n",
+ __func__, serdes_type_to_string[serdes_type], serdes_id);
+ return MV_FAIL;
+ }
+
+ unit_id = serdes_type_to_unit_info[serdes_type].serdes_unit_id;
+ unit_numb = serdes_type_to_unit_info[serdes_type].serdes_unit_num;
+ serd_max_num = sys_env_unit_max_num_get(unit_id);
+
+ /* if didn't exceed amount of required Serdes lanes for current type */
+ if (serdes_lane_in_use_count[unit_id][unit_numb] != 0) {
+ /* update amount of required Serdes lanes for current type */
+ serdes_lane_in_use_count[unit_id][unit_numb]--;
+
+ /*
+ * If reached the exact amount of required Serdes lanes for
+ * current type
+ */
+ if (serdes_lane_in_use_count[unit_id][unit_numb] == 0) {
+ if (((serdes_type <= PEX3)) &&
+ ((serdes_mode == PEX_END_POINT_X4) ||
+ (serdes_mode == PEX_ROOT_COMPLEX_X4))) {
+ /* PCiex4 uses 2 SerDes */
+ serdes_unit_count[PEX_UNIT_ID] += 2;
+ } else {
+ serdes_unit_count[unit_id]++;
+ }
+
+ /* test SoC unit count limitation */
+ if (serdes_unit_count[unit_id] > serd_max_num) {
+ test_result = WRONG_NUMBER_OF_UNITS;
+ } else if (unit_numb >= serd_max_num) {
+ /* test SoC unit number limitation */
+ test_result = UNIT_NUMBER_VIOLATION;
+ }
+ }
+ } else {
+ test_result = SERDES_ALREADY_IN_USE;
+ if (test_result == SERDES_ALREADY_IN_USE) {
+ printf("%s: Error: serdes lane %d is configured to type %s: type already in use\n",
+ __func__, serdes_id,
+ serdes_type_to_string[serdes_type]);
+ return MV_FAIL;
+ } else if (test_result == WRONG_NUMBER_OF_UNITS) {
+ printf("%s: Warning: serdes lane %d is set to type %s.\n",
+ __func__, serdes_id,
+ serdes_type_to_string[serdes_type]);
+ printf("%s: Maximum supported lanes are already set to this type (limit = %d)\n",
+ __func__, serd_max_num);
+ return MV_FAIL;
+ } else if (test_result == UNIT_NUMBER_VIOLATION) {
+ printf("%s: Warning: serdes lane %d type is %s: current device support only %d units of this type.\n",
+ __func__, serdes_id,
+ serdes_type_to_string[serdes_type],
+ serd_max_num);
+ return MV_FAIL;
+ }
+ }
+
+ return MV_OK;
+}
+
+void hws_serdes_xaui_topology_verify(void)
+{
+ /*
+ * If XAUI is in use - serdes_lane_in_use_count has to be = 0;
+ * if it is not in use hast be = 4
+ */
+ if ((serdes_lane_in_use_count[XAUI_UNIT_ID][0] != 0) &&
+ (serdes_lane_in_use_count[XAUI_UNIT_ID][0] != 4)) {
+ printf("%s: Warning: wrong number of lanes is set to XAUI - %d\n",
+ __func__, serdes_lane_in_use_count[XAUI_UNIT_ID][0]);
+ printf("%s: XAUI has to be defined on 4 lanes\n", __func__);
+ }
+
+ /*
+ * If RXAUI is in use - serdes_lane_in_use_count has to be = 0;
+ * if it is not in use hast be = 2
+ */
+ if ((serdes_lane_in_use_count[RXAUI_UNIT_ID][0] != 0) &&
+ (serdes_lane_in_use_count[RXAUI_UNIT_ID][0] != 2)) {
+ printf("%s: Warning: wrong number of lanes is set to RXAUI - %d\n",
+ __func__, serdes_lane_in_use_count[RXAUI_UNIT_ID][0]);
+ printf("%s: RXAUI has to be defined on 2 lanes\n", __func__);
+ }
+}
+
+int hws_serdes_seq_db_init(void)
+{
+ u8 serdes_rev = hws_ctrl_serdes_rev_get();
+
+ DEBUG_INIT_FULL_S("\n### serdes_seq38x_init ###\n");
+
+ if (serdes_rev == MV_SERDES_REV_NA) {
+ printf("hws_serdes_seq_db_init: serdes revision number is not supported\n");
+ return MV_NOT_SUPPORTED;
+ }
+
+ /* SATA_PORT_0_ONLY_POWER_UP_SEQ sequence init */
+ serdes_seq_db[SATA_PORT_0_ONLY_POWER_UP_SEQ].op_params_ptr =
+ sata_port0_power_up_params;
+ serdes_seq_db[SATA_PORT_0_ONLY_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(sata_port0_power_up_params) / sizeof(struct op_params);
+ serdes_seq_db[SATA_PORT_0_ONLY_POWER_UP_SEQ].data_arr_idx = SATA;
+
+ /* SATA_PORT_1_ONLY_POWER_UP_SEQ sequence init */
+ serdes_seq_db[SATA_PORT_1_ONLY_POWER_UP_SEQ].op_params_ptr =
+ sata_port1_power_up_params;
+ serdes_seq_db[SATA_PORT_1_ONLY_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(sata_port1_power_up_params) / sizeof(struct op_params);
+ serdes_seq_db[SATA_PORT_1_ONLY_POWER_UP_SEQ].data_arr_idx = SATA;
+
+ /* SATA_POWER_UP_SEQ sequence init */
+ serdes_seq_db[SATA_POWER_UP_SEQ].op_params_ptr =
+ sata_and_sgmii_power_up_params;
+ serdes_seq_db[SATA_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(sata_and_sgmii_power_up_params) / sizeof(struct op_params);
+ serdes_seq_db[SATA_POWER_UP_SEQ].data_arr_idx = SATA;
+
+ /* SATA_1_5_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[SATA_1_5_SPEED_CONFIG_SEQ].op_params_ptr =
+ sata_and_sgmii_speed_config_params;
+ serdes_seq_db[SATA_1_5_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_and_sgmii_speed_config_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[SATA_1_5_SPEED_CONFIG_SEQ].data_arr_idx = SATA;
+
+ /* SATA_3_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[SATA_3_SPEED_CONFIG_SEQ].op_params_ptr =
+ sata_and_sgmii_speed_config_params;
+ serdes_seq_db[SATA_3_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_and_sgmii_speed_config_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[SATA_3_SPEED_CONFIG_SEQ].data_arr_idx = SATA;
+
+ /* SATA_6_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[SATA_6_SPEED_CONFIG_SEQ].op_params_ptr =
+ sata_and_sgmii_speed_config_params;
+ serdes_seq_db[SATA_6_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_and_sgmii_speed_config_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[SATA_6_SPEED_CONFIG_SEQ].data_arr_idx = SATA;
+
+ /* SATA_ELECTRICAL_CONFIG_SEQ seq sequence init */
+ if (serdes_rev == MV_SERDES_REV_1_2) {
+ serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ sata_electrical_config_serdes_rev1_params;
+ serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_electrical_config_serdes_rev1_params) /
+ sizeof(struct op_params);
+ } else {
+ serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ sata_electrical_config_serdes_rev2_params;
+ serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_electrical_config_serdes_rev2_params) /
+ sizeof(struct op_params);
+ }
+ serdes_seq_db[SATA_ELECTRICAL_CONFIG_SEQ].data_arr_idx = SATA;
+
+ /* SATA_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[SATA_TX_CONFIG_SEQ1].op_params_ptr =
+ sata_and_sgmii_tx_config_params1;
+ serdes_seq_db[SATA_TX_CONFIG_SEQ1].cfg_seq_size =
+ sizeof(sata_and_sgmii_tx_config_params1) / sizeof(struct op_params);
+ serdes_seq_db[SATA_TX_CONFIG_SEQ1].data_arr_idx = SATA;
+
+ /* SATA_PORT_0_ONLY_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[SATA_PORT_0_ONLY_TX_CONFIG_SEQ].op_params_ptr =
+ sata_port0_tx_config_params;
+ serdes_seq_db[SATA_PORT_0_ONLY_TX_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_port0_tx_config_params) / sizeof(struct op_params);
+ serdes_seq_db[SATA_PORT_0_ONLY_TX_CONFIG_SEQ].data_arr_idx = SATA;
+
+ /* SATA_PORT_1_ONLY_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[SATA_PORT_1_ONLY_TX_CONFIG_SEQ].op_params_ptr =
+ sata_port1_tx_config_params;
+ serdes_seq_db[SATA_PORT_1_ONLY_TX_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_port1_tx_config_params) / sizeof(struct op_params);
+ serdes_seq_db[SATA_PORT_1_ONLY_TX_CONFIG_SEQ].data_arr_idx = SATA;
+
+ /* SATA_TX_CONFIG_SEQ2 sequence init */
+ if (serdes_rev == MV_SERDES_REV_1_2) {
+ serdes_seq_db[SATA_TX_CONFIG_SEQ2].op_params_ptr =
+ sata_and_sgmii_tx_config_serdes_rev1_params2;
+ serdes_seq_db[SATA_TX_CONFIG_SEQ2].cfg_seq_size =
+ sizeof(sata_and_sgmii_tx_config_serdes_rev1_params2) /
+ sizeof(struct op_params);
+ } else {
+ serdes_seq_db[SATA_TX_CONFIG_SEQ2].op_params_ptr =
+ sata_and_sgmii_tx_config_serdes_rev2_params2;
+ serdes_seq_db[SATA_TX_CONFIG_SEQ2].cfg_seq_size =
+ sizeof(sata_and_sgmii_tx_config_serdes_rev2_params2) /
+ sizeof(struct op_params);
+ }
+ serdes_seq_db[SATA_TX_CONFIG_SEQ2].data_arr_idx = SATA;
+
+ /* SGMII_POWER_UP_SEQ sequence init */
+ serdes_seq_db[SGMII_POWER_UP_SEQ].op_params_ptr =
+ sata_and_sgmii_power_up_params;
+ serdes_seq_db[SGMII_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(sata_and_sgmii_power_up_params) / sizeof(struct op_params);
+ serdes_seq_db[SGMII_POWER_UP_SEQ].data_arr_idx = SGMII;
+
+ /* SGMII_1_25_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[SGMII_1_25_SPEED_CONFIG_SEQ].op_params_ptr =
+ sata_and_sgmii_speed_config_params;
+ serdes_seq_db[SGMII_1_25_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_and_sgmii_speed_config_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[SGMII_1_25_SPEED_CONFIG_SEQ].data_arr_idx = SGMII;
+
+ /* SGMII_3_125_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[SGMII_3_125_SPEED_CONFIG_SEQ].op_params_ptr =
+ sata_and_sgmii_speed_config_params;
+ serdes_seq_db[SGMII_3_125_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sata_and_sgmii_speed_config_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[SGMII_3_125_SPEED_CONFIG_SEQ].data_arr_idx = SGMII_3_125;
+
+ /* SGMII_ELECTRICAL_CONFIG_SEQ seq sequence init */
+ if (serdes_rev == MV_SERDES_REV_1_2) {
+ serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ sgmii_electrical_config_serdes_rev1_params;
+ serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sgmii_electrical_config_serdes_rev1_params) /
+ sizeof(struct op_params);
+ } else {
+ serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ sgmii_electrical_config_serdes_rev2_params;
+ serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(sgmii_electrical_config_serdes_rev2_params) /
+ sizeof(struct op_params);
+ }
+ serdes_seq_db[SGMII_ELECTRICAL_CONFIG_SEQ].data_arr_idx = SGMII;
+
+ /* SGMII_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[SGMII_TX_CONFIG_SEQ1].op_params_ptr =
+ sata_and_sgmii_tx_config_params1;
+ serdes_seq_db[SGMII_TX_CONFIG_SEQ1].cfg_seq_size =
+ sizeof(sata_and_sgmii_tx_config_params1) / sizeof(struct op_params);
+ serdes_seq_db[SGMII_TX_CONFIG_SEQ1].data_arr_idx = SGMII;
+
+ /* SGMII_TX_CONFIG_SEQ sequence init */
+ if (serdes_rev == MV_SERDES_REV_1_2) {
+ serdes_seq_db[SGMII_TX_CONFIG_SEQ2].op_params_ptr =
+ sata_and_sgmii_tx_config_serdes_rev1_params2;
+ serdes_seq_db[SGMII_TX_CONFIG_SEQ2].cfg_seq_size =
+ sizeof(sata_and_sgmii_tx_config_serdes_rev1_params2) /
+ sizeof(struct op_params);
+ } else {
+ serdes_seq_db[SGMII_TX_CONFIG_SEQ2].op_params_ptr =
+ sata_and_sgmii_tx_config_serdes_rev2_params2;
+ serdes_seq_db[SGMII_TX_CONFIG_SEQ2].cfg_seq_size =
+ sizeof(sata_and_sgmii_tx_config_serdes_rev2_params2) /
+ sizeof(struct op_params);
+ }
+ serdes_seq_db[SGMII_TX_CONFIG_SEQ2].data_arr_idx = SGMII;
+
+ /* PEX_POWER_UP_SEQ sequence init */
+ if (serdes_rev == MV_SERDES_REV_1_2) {
+ serdes_seq_db[PEX_POWER_UP_SEQ].op_params_ptr =
+ pex_and_usb3_power_up_serdes_rev1_params;
+ serdes_seq_db[PEX_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(pex_and_usb3_power_up_serdes_rev1_params) /
+ sizeof(struct op_params);
+ } else {
+ serdes_seq_db[PEX_POWER_UP_SEQ].op_params_ptr =
+ pex_and_usb3_power_up_serdes_rev2_params;
+ serdes_seq_db[PEX_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(pex_and_usb3_power_up_serdes_rev2_params) /
+ sizeof(struct op_params);
+ }
+ serdes_seq_db[PEX_POWER_UP_SEQ].data_arr_idx = PEX;
+
+ /* PEX_2_5_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[PEX_2_5_SPEED_CONFIG_SEQ].op_params_ptr =
+ pex_and_usb3_speed_config_params;
+ serdes_seq_db[PEX_2_5_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(pex_and_usb3_speed_config_params) / sizeof(struct op_params);
+ serdes_seq_db[PEX_2_5_SPEED_CONFIG_SEQ].data_arr_idx =
+ PEXSERDES_SPEED_2_5_GBPS;
+
+ /* PEX_5_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[PEX_5_SPEED_CONFIG_SEQ].op_params_ptr =
+ pex_and_usb3_speed_config_params;
+ serdes_seq_db[PEX_5_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(pex_and_usb3_speed_config_params) / sizeof(struct op_params);
+ serdes_seq_db[PEX_5_SPEED_CONFIG_SEQ].data_arr_idx =
+ PEXSERDES_SPEED_5_GBPS;
+
+ /* PEX_ELECTRICAL_CONFIG_SEQ seq sequence init */
+ if (serdes_rev == MV_SERDES_REV_1_2) {
+ serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ pex_electrical_config_serdes_rev1_params;
+ serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(pex_electrical_config_serdes_rev1_params) /
+ sizeof(struct op_params);
+ } else {
+ serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ pex_electrical_config_serdes_rev2_params;
+ serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(pex_electrical_config_serdes_rev2_params) /
+ sizeof(struct op_params);
+ }
+ serdes_seq_db[PEX_ELECTRICAL_CONFIG_SEQ].data_arr_idx = PEX;
+
+ /* PEX_TX_CONFIG_SEQ1 sequence init */
+ serdes_seq_db[PEX_TX_CONFIG_SEQ1].op_params_ptr =
+ pex_and_usb3_tx_config_params1;
+ serdes_seq_db[PEX_TX_CONFIG_SEQ1].cfg_seq_size =
+ sizeof(pex_and_usb3_tx_config_params1) / sizeof(struct op_params);
+ serdes_seq_db[PEX_TX_CONFIG_SEQ1].data_arr_idx = PEX;
+
+ /* PEX_TX_CONFIG_SEQ2 sequence init */
+ serdes_seq_db[PEX_TX_CONFIG_SEQ2].op_params_ptr =
+ pex_and_usb3_tx_config_params2;
+ serdes_seq_db[PEX_TX_CONFIG_SEQ2].cfg_seq_size =
+ sizeof(pex_and_usb3_tx_config_params2) / sizeof(struct op_params);
+ serdes_seq_db[PEX_TX_CONFIG_SEQ2].data_arr_idx = PEX;
+
+ /* PEX_TX_CONFIG_SEQ3 sequence init */
+ serdes_seq_db[PEX_TX_CONFIG_SEQ3].op_params_ptr =
+ pex_and_usb3_tx_config_params3;
+ serdes_seq_db[PEX_TX_CONFIG_SEQ3].cfg_seq_size =
+ sizeof(pex_and_usb3_tx_config_params3) / sizeof(struct op_params);
+ serdes_seq_db[PEX_TX_CONFIG_SEQ3].data_arr_idx = PEX;
+
+ /* PEX_BY_4_CONFIG_SEQ sequence init */
+ serdes_seq_db[PEX_BY_4_CONFIG_SEQ].op_params_ptr =
+ pex_by4_config_params;
+ serdes_seq_db[PEX_BY_4_CONFIG_SEQ].cfg_seq_size =
+ sizeof(pex_by4_config_params) / sizeof(struct op_params);
+ serdes_seq_db[PEX_BY_4_CONFIG_SEQ].data_arr_idx = PEX;
+
+ /* PEX_CONFIG_REF_CLOCK_25MHZ_SEQ sequence init */
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_25MHZ_SEQ].op_params_ptr =
+ pex_config_ref_clock25_m_hz;
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_25MHZ_SEQ].cfg_seq_size =
+ sizeof(pex_config_ref_clock25_m_hz) / sizeof(struct op_params);
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_25MHZ_SEQ].data_arr_idx = PEX;
+
+ /* PEX_ELECTRICAL_CONFIG_REF_CLOCK_40MHZ_SEQ sequence init */
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_40MHZ_SEQ].op_params_ptr =
+ pex_config_ref_clock40_m_hz;
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_40MHZ_SEQ].cfg_seq_size =
+ sizeof(pex_config_ref_clock40_m_hz) / sizeof(struct op_params);
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_40MHZ_SEQ].data_arr_idx = PEX;
+
+ /* PEX_CONFIG_REF_CLOCK_100MHZ_SEQ sequence init */
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_100MHZ_SEQ].op_params_ptr =
+ pex_config_ref_clock100_m_hz;
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_100MHZ_SEQ].cfg_seq_size =
+ sizeof(pex_config_ref_clock100_m_hz) / sizeof(struct op_params);
+ serdes_seq_db[PEX_CONFIG_REF_CLOCK_100MHZ_SEQ].data_arr_idx = PEX;
+
+ /* USB3_POWER_UP_SEQ sequence init */
+ if (serdes_rev == MV_SERDES_REV_1_2) {
+ serdes_seq_db[USB3_POWER_UP_SEQ].op_params_ptr =
+ pex_and_usb3_power_up_serdes_rev1_params;
+ serdes_seq_db[USB3_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(pex_and_usb3_power_up_serdes_rev1_params) /
+ sizeof(struct op_params);
+ } else {
+ serdes_seq_db[USB3_POWER_UP_SEQ].op_params_ptr =
+ pex_and_usb3_power_up_serdes_rev2_params;
+ serdes_seq_db[USB3_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(pex_and_usb3_power_up_serdes_rev2_params) /
+ sizeof(struct op_params);
+ }
+ serdes_seq_db[USB3_POWER_UP_SEQ].data_arr_idx = USB3;
+
+ /* USB3_HOST_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[USB3_HOST_SPEED_CONFIG_SEQ].op_params_ptr =
+ pex_and_usb3_speed_config_params;
+ serdes_seq_db[USB3_HOST_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(pex_and_usb3_speed_config_params) / sizeof(struct op_params);
+ serdes_seq_db[USB3_HOST_SPEED_CONFIG_SEQ].data_arr_idx =
+ USB3SERDES_SPEED_5_GBPS_HOST;
+
+ /* USB3_DEVICE_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[USB3_DEVICE_SPEED_CONFIG_SEQ].op_params_ptr =
+ pex_and_usb3_speed_config_params;
+ serdes_seq_db[USB3_DEVICE_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(pex_and_usb3_speed_config_params) / sizeof(struct op_params);
+ serdes_seq_db[USB3_DEVICE_SPEED_CONFIG_SEQ].data_arr_idx =
+ USB3SERDES_SPEED_5_GBPS_DEVICE;
+
+ /* USB3_ELECTRICAL_CONFIG_SEQ seq sequence init */
+ if (serdes_rev == MV_SERDES_REV_1_2) {
+ serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ usb3_electrical_config_serdes_rev1_params;
+ serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(usb3_electrical_config_serdes_rev1_params) /
+ sizeof(struct op_params);
+ } else {
+ serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ usb3_electrical_config_serdes_rev2_params;
+ serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(usb3_electrical_config_serdes_rev2_params) /
+ sizeof(struct op_params);
+ }
+ serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].data_arr_idx = USB3;
+
+ /* USB3_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[USB3_TX_CONFIG_SEQ1].op_params_ptr =
+ pex_and_usb3_tx_config_params1;
+ serdes_seq_db[USB3_TX_CONFIG_SEQ1].cfg_seq_size =
+ sizeof(pex_and_usb3_tx_config_params1) / sizeof(struct op_params);
+ serdes_seq_db[USB3_TX_CONFIG_SEQ1].data_arr_idx = USB3;
+
+ /* USB3_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[USB3_TX_CONFIG_SEQ2].op_params_ptr =
+ pex_and_usb3_tx_config_params2;
+ serdes_seq_db[USB3_TX_CONFIG_SEQ2].cfg_seq_size =
+ sizeof(pex_and_usb3_tx_config_params2) / sizeof(struct op_params);
+ serdes_seq_db[USB3_TX_CONFIG_SEQ2].data_arr_idx = USB3;
+
+ /* USB3_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[USB3_TX_CONFIG_SEQ3].op_params_ptr =
+ pex_and_usb3_tx_config_params3;
+ serdes_seq_db[USB3_TX_CONFIG_SEQ3].cfg_seq_size =
+ sizeof(pex_and_usb3_tx_config_params3) / sizeof(struct op_params);
+ serdes_seq_db[USB3_TX_CONFIG_SEQ3].data_arr_idx = USB3;
+
+ /* USB2_POWER_UP_SEQ sequence init */
+ serdes_seq_db[USB2_POWER_UP_SEQ].op_params_ptr = usb2_power_up_params;
+ serdes_seq_db[USB2_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(usb2_power_up_params) / sizeof(struct op_params);
+ serdes_seq_db[USB2_POWER_UP_SEQ].data_arr_idx = 0;
+
+ /* USB3_DEVICE_CONFIG_SEQ sequence init */
+ serdes_seq_db[USB3_DEVICE_CONFIG_SEQ].op_params_ptr =
+ usb3_device_config_params;
+ serdes_seq_db[USB3_DEVICE_CONFIG_SEQ].cfg_seq_size =
+ sizeof(usb3_device_config_params) / sizeof(struct op_params);
+ serdes_seq_db[USB3_DEVICE_CONFIG_SEQ].data_arr_idx = 0; /* Not relevant */
+
+ /* SERDES_POWER_DOWN_SEQ sequence init */
+ serdes_seq_db[SERDES_POWER_DOWN_SEQ].op_params_ptr =
+ serdes_power_down_params;
+ serdes_seq_db[SERDES_POWER_DOWN_SEQ].cfg_seq_size =
+ sizeof(serdes_power_down_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[SERDES_POWER_DOWN_SEQ].data_arr_idx = FIRST_CELL;
+
+ if (serdes_rev == MV_SERDES_REV_2_1) {
+ /* QSGMII_POWER_UP_SEQ sequence init */
+ serdes_seq_db[QSGMII_POWER_UP_SEQ].op_params_ptr =
+ qsgmii_port_power_up_params;
+ serdes_seq_db[QSGMII_POWER_UP_SEQ].cfg_seq_size =
+ sizeof(qsgmii_port_power_up_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[QSGMII_POWER_UP_SEQ].data_arr_idx =
+ QSGMII_SEQ_IDX;
+
+ /* QSGMII_5_SPEED_CONFIG_SEQ sequence init */
+ serdes_seq_db[QSGMII_5_SPEED_CONFIG_SEQ].op_params_ptr =
+ qsgmii_port_speed_config_params;
+ serdes_seq_db[QSGMII_5_SPEED_CONFIG_SEQ].cfg_seq_size =
+ sizeof(qsgmii_port_speed_config_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[QSGMII_5_SPEED_CONFIG_SEQ].data_arr_idx =
+ QSGMII_SEQ_IDX;
+
+ /* QSGMII_ELECTRICAL_CONFIG_SEQ seq sequence init */
+ serdes_seq_db[QSGMII_ELECTRICAL_CONFIG_SEQ].op_params_ptr =
+ qsgmii_port_electrical_config_params;
+ serdes_seq_db[QSGMII_ELECTRICAL_CONFIG_SEQ].cfg_seq_size =
+ sizeof(qsgmii_port_electrical_config_params) /
+ sizeof(struct op_params);
+ serdes_seq_db[QSGMII_ELECTRICAL_CONFIG_SEQ].data_arr_idx =
+ QSGMII_SEQ_IDX;
+
+ /* QSGMII_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[QSGMII_TX_CONFIG_SEQ1].op_params_ptr =
+ qsgmii_port_tx_config_params1;
+ serdes_seq_db[QSGMII_TX_CONFIG_SEQ1].cfg_seq_size =
+ sizeof(qsgmii_port_tx_config_params1) /
+ sizeof(struct op_params);
+ serdes_seq_db[QSGMII_TX_CONFIG_SEQ1].data_arr_idx =
+ QSGMII_SEQ_IDX;
+
+ /* QSGMII_TX_CONFIG_SEQ sequence init */
+ serdes_seq_db[QSGMII_TX_CONFIG_SEQ2].op_params_ptr =
+ qsgmii_port_tx_config_params2;
+ serdes_seq_db[QSGMII_TX_CONFIG_SEQ2].cfg_seq_size =
+ sizeof(qsgmii_port_tx_config_params2) /
+ sizeof(struct op_params);
+ serdes_seq_db[QSGMII_TX_CONFIG_SEQ2].data_arr_idx =
+ QSGMII_SEQ_IDX;
+ }
+
+ return MV_OK;
+}
+
+enum serdes_seq serdes_type_and_speed_to_speed_seq(enum serdes_type serdes_type,
+ enum serdes_speed baud_rate)
+{
+ enum serdes_seq seq_id = SERDES_LAST_SEQ;
+
+ DEBUG_INIT_FULL_S("\n### serdes_type_and_speed_to_speed_seq ###\n");
+ switch (serdes_type) {
+ case PEX0:
+ case PEX1:
+ case PEX2:
+ case PEX3:
+ if (baud_rate == SERDES_SPEED_2_5_GBPS)
+ seq_id = PEX_2_5_SPEED_CONFIG_SEQ;
+ else if (baud_rate == SERDES_SPEED_5_GBPS)
+ seq_id = PEX_5_SPEED_CONFIG_SEQ;
+ break;
+ case USB3_HOST0:
+ case USB3_HOST1:
+ if (baud_rate == SERDES_SPEED_5_GBPS)
+ seq_id = USB3_HOST_SPEED_CONFIG_SEQ;
+ break;
+ case USB3_DEVICE:
+ if (baud_rate == SERDES_SPEED_5_GBPS)
+ seq_id = USB3_DEVICE_SPEED_CONFIG_SEQ;
+ break;
+ case SATA0:
+ case SATA1:
+ case SATA2:
+ case SATA3:
+ if (baud_rate == SERDES_SPEED_1_5_GBPS)
+ seq_id = SATA_1_5_SPEED_CONFIG_SEQ;
+ else if (baud_rate == SERDES_SPEED_3_GBPS)
+ seq_id = SATA_3_SPEED_CONFIG_SEQ;
+ else if (baud_rate == SERDES_SPEED_6_GBPS)
+ seq_id = SATA_6_SPEED_CONFIG_SEQ;
+ break;
+ case SGMII0:
+ case SGMII1:
+ case SGMII2:
+#ifdef CONFIG_ARMADA_39X
+ case SGMII3:
+#endif
+ if (baud_rate == SERDES_SPEED_1_25_GBPS)
+ seq_id = SGMII_1_25_SPEED_CONFIG_SEQ;
+ else if (baud_rate == SERDES_SPEED_3_125_GBPS)
+ seq_id = SGMII_3_125_SPEED_CONFIG_SEQ;
+ break;
+ case QSGMII:
+ seq_id = QSGMII_5_SPEED_CONFIG_SEQ;
+ break;
+#ifdef CONFIG_ARMADA_39X
+ case XAUI:
+ seq_id = XAUI_3_125_SPEED_CONFIG_SEQ;
+ break;
+ case RXAUI:
+ seq_id = RXAUI_6_25_SPEED_CONFIG_SEQ;
+ break;
+#endif
+ default:
+ return SERDES_LAST_SEQ;
+ }
+
+ return seq_id;
+}
+
+/*
+ * This is the weak default function for the Marvell evaluation or
+ * development boarrds. Like the DB-88F6820-GP and others.
+ * Custom boards should define this function in their board
+ * code (board directory). And overwrite this default function
+ * with this custom specific code.
+ */
+__weak int hws_board_topology_load(struct serdes_map *serdes_map_array)
+{
+ u32 board_id = mv_board_id_get();
+ u32 board_id_index = mv_board_id_index_get(board_id);
+
+ DEBUG_INIT_FULL_S("\n### hws_board_topology_load ###\n");
+ /* getting board topology according to the board id */
+ DEBUG_INIT_FULL_S("Getting board topology according to the board id\n");
+
+ CHECK_STATUS(load_topology_func_arr[board_id_index] (serdes_map_array));
+
+ return MV_OK;
+}
+
+void print_topology_details(struct serdes_map *serdes_map_array)
+{
+ u32 lane_num;
+
+ DEBUG_INIT_S("board SerDes lanes topology details:\n");
+
+ DEBUG_INIT_S(" | Lane # | Speed | Type |\n");
+ DEBUG_INIT_S(" --------------------------------\n");
+ for (lane_num = 0; lane_num < hws_serdes_get_max_lane(); lane_num++) {
+ if (serdes_map_array[lane_num].serdes_type == DEFAULT_SERDES)
+ continue;
+ DEBUG_INIT_S(" | ");
+ DEBUG_INIT_D(hws_get_physical_serdes_num(lane_num), 1);
+ DEBUG_INIT_S(" | ");
+ DEBUG_INIT_D(serdes_map_array[lane_num].serdes_speed, 2);
+ DEBUG_INIT_S(" | ");
+ DEBUG_INIT_S((char *)
+ serdes_type_to_string[serdes_map_array[lane_num].
+ serdes_type]);
+ DEBUG_INIT_S("\t|\n");
+ }
+ DEBUG_INIT_S(" --------------------------------\n");
+}
+
+int hws_pre_serdes_init_config(void)
+{
+ u32 data;
+
+ /*
+ * Configure Core PLL
+ */
+ /*
+ * set PLL parameters
+ * bits[2:0] =0x3 (Core-PLL Kdiv)
+ * bits[20:12]=0x9f (Core-PLL Ndiv)
+ * bits[24:21]=0x7(Core-PLL VCO Band)
+ * bits[28:25]=0x1(Core-PLL Rlf)
+ * bits[31:29]=0x2(Core-PLL charge-pump adjust)
+ */
+ reg_write(CORE_PLL_PARAMETERS_REG, 0x42e9f003);
+
+ /* Enable PLL Configuration */
+ data = reg_read(CORE_PLL_CONFIG_REG);
+ data = SET_BIT(data, 9);
+ reg_write(CORE_PLL_CONFIG_REG, data);
+
+ return MV_OK;
+}
+
+int serdes_phy_config(void)
+{
+ DEBUG_INIT_FULL_S("\n### ctrl_high_speed_serdes_phy_config ###\n");
+
+ DEBUG_INIT_S("High speed PHY - Version: ");
+ DEBUG_INIT_S(SERDES_VERION);
+ DEBUG_INIT_S("\n");
+
+ /* Init serdes sequences DB */
+ if (hws_serdes_seq_init() != MV_OK) {
+ printf("hws_ctrl_high_speed_serdes_phy_config: Error: Serdes initialization fail\n");
+ return MV_FAIL;
+ }
+
+ /* I2C init */
+ i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+ /* Board topology load */
+ DEBUG_INIT_FULL_S
+ ("ctrl_high_speed_serdes_phy_config: Loading board topology..\n");
+ CHECK_STATUS(hws_board_topology_load(serdes_configuration_map));
+
+ /* print topology */
+ print_topology_details(serdes_configuration_map);
+ CHECK_STATUS(hws_pre_serdes_init_config());
+
+ /* Power-Up sequence */
+ DEBUG_INIT_FULL_S
+ ("ctrl_high_speed_serdes_phy_config: Starting serdes power up sequence\n");
+
+ CHECK_STATUS(hws_power_up_serdes_lanes(serdes_configuration_map));
+
+ DEBUG_INIT_FULL_S
+ ("\n### ctrl_high_speed_serdes_phy_config ended successfully ###\n");
+
+ DEBUG_INIT_S(ENDED_OK);
+
+ return MV_OK;
+}
+
+int serdes_polarity_config(u32 serdes_num, int is_rx)
+{
+ u32 data;
+ u32 reg_addr;
+ u8 bit_off = (is_rx) ? 11 : 10;
+
+ reg_addr = SERDES_REGS_LANE_BASE_OFFSET(serdes_num) + SYNC_PATTERN_REG;
+ data = reg_read(reg_addr);
+ data = SET_BIT(data, bit_off);
+ reg_write(reg_addr, data);
+
+ return MV_OK;
+}
+
+int hws_power_up_serdes_lanes(struct serdes_map *serdes_config_map)
+{
+ u32 serdes_id, serdes_lane_num;
+ enum ref_clock ref_clock;
+ enum serdes_type serdes_type;
+ enum serdes_speed serdes_speed;
+ enum serdes_mode serdes_mode;
+ int serdes_rx_polarity_swap;
+ int serdes_tx_polarity_swap;
+ int is_pex_enabled = 0;
+
+ /*
+ * is_pex_enabled:
+ * Flag which indicates that one of the Serdes is of PEX.
+ * In this case, PEX unit will be initialized after Serdes power-up
+ */
+
+ DEBUG_INIT_FULL_S("\n### hws_power_up_serdes_lanes ###\n");
+
+ /* COMMON PHYS SELECTORS register configuration */
+ DEBUG_INIT_FULL_S
+ ("hws_power_up_serdes_lanes: Updating COMMON PHYS SELECTORS reg\n");
+ CHECK_STATUS(hws_update_serdes_phy_selectors(serdes_configuration_map));
+
+ /* per Serdes Power Up */
+ for (serdes_id = 0; serdes_id < hws_serdes_get_max_lane();
+ serdes_id++) {
+ DEBUG_INIT_FULL_S
+ ("calling serdes_power_up_ctrl: serdes lane number ");
+ DEBUG_INIT_FULL_D_10(serdes_lane_num, 1);
+ DEBUG_INIT_FULL_S("\n");
+
+ serdes_lane_num = hws_get_physical_serdes_num(serdes_id);
+ serdes_type = serdes_config_map[serdes_id].serdes_type;
+ serdes_speed = serdes_config_map[serdes_id].serdes_speed;
+ serdes_mode = serdes_config_map[serdes_id].serdes_mode;
+ serdes_rx_polarity_swap = serdes_config_map[serdes_id].swap_rx;
+ serdes_tx_polarity_swap = serdes_config_map[serdes_id].swap_tx;
+
+ /* serdes lane is not in use */
+ if (serdes_type == DEFAULT_SERDES)
+ continue;
+ else if (serdes_type <= PEX3) /* PEX type */
+ is_pex_enabled = 1;
+
+ ref_clock = hws_serdes_get_ref_clock_val(serdes_type);
+ if (ref_clock == REF_CLOCK_UNSUPPORTED) {
+ DEBUG_INIT_S
+ ("hws_power_up_serdes_lanes: unsupported ref clock\n");
+ return MV_NOT_SUPPORTED;
+ }
+ CHECK_STATUS(serdes_power_up_ctrl(serdes_lane_num,
+ 1,
+ serdes_type,
+ serdes_speed,
+ serdes_mode, ref_clock));
+
+ /* RX Polarity config */
+ if (serdes_rx_polarity_swap)
+ CHECK_STATUS(serdes_polarity_config
+ (serdes_lane_num, 1));
+
+ /* TX Polarity config */
+ if (serdes_tx_polarity_swap)
+ CHECK_STATUS(serdes_polarity_config
+ (serdes_lane_num, 0));
+ }
+
+ if (is_pex_enabled) {
+ /* Set PEX_TX_CONFIG_SEQ sequence for PEXx4 mode.
+ After finish the Power_up sequence for all lanes,
+ the lanes should be released from reset state. */
+ CHECK_STATUS(hws_pex_tx_config_seq(serdes_config_map));
+
+ /* PEX configuration */
+ CHECK_STATUS(hws_pex_config(serdes_config_map));
+ }
+
+ /* USB2 configuration */
+ DEBUG_INIT_FULL_S("hws_power_up_serdes_lanes: init USB2 Phys\n");
+ CHECK_STATUS(mv_seq_exec(0 /* not relevant */ , USB2_POWER_UP_SEQ));
+
+ DEBUG_INIT_FULL_S
+ ("### hws_power_up_serdes_lanes ended successfully ###\n");
+
+ return MV_OK;
+}
+
+int ctrl_high_speed_serdes_phy_config(void)
+{
+ return hws_ctrl_high_speed_serdes_phy_config();
+}
+
+static int serdes_pex_usb3_pipe_delay_w_a(u32 serdes_num, u8 serdes_type)
+{
+ u32 reg_data;
+
+ /* WA for A380 Z1 relevant for lanes 3,4,5 only */
+ if (serdes_num >= 3) {
+ reg_data = reg_read(GENERAL_PURPOSE_RESERVED0_REG);
+ /* set delay on pipe -
+ * When lane 3 is connected to a MAC of Pex -> set bit 7 to 1.
+ * When lane 3 is connected to a MAC of USB3 -> set bit 7 to 0.
+ * When lane 4 is connected to a MAC of Pex -> set bit 8 to 1.
+ * When lane 4 is connected to a MAC of USB3 -> set bit 8 to 0.
+ * When lane 5 is connected to a MAC of Pex -> set bit 8 to 1.
+ * When lane 5 is connected to a MAC of USB3 -> set bit 8 to 0.
+ */
+ if (serdes_type == PEX)
+ reg_data |= 1 << (7 + (serdes_num - 3));
+ if (serdes_type == USB3) {
+ /* USB3 */
+ reg_data &= ~(1 << (7 + (serdes_num - 3)));
+ }
+ reg_write(GENERAL_PURPOSE_RESERVED0_REG, reg_data);
+ }
+
+ return MV_OK;
+}
+
+/*
+ * hws_serdes_pex_ref_clock_satr_get -
+ *
+ * DESCRIPTION: Get the reference clock value from DEVICE_SAMPLE_AT_RESET1_REG
+ * and check:
+ * bit[2] for PEX#0, bit[3] for PEX#1, bit[30] for PEX#2, bit[31]
+ * for PEX#3.
+ * If bit=0 --> REF_CLOCK_100MHz
+ * If bit=1 && DEVICE_SAMPLE_AT_RESET2_REG bit[0]=0
+ * --> REF_CLOCK_25MHz
+ * If bit=1 && DEVICE_SAMPLE_AT_RESET2_REG bit[0]=1
+ * --> REF_CLOCK_40MHz
+ *
+ * INPUT: serdes_type - Type of Serdes
+ *
+ * OUTPUT: pex_satr - Return the REF_CLOCK value:
+ * REF_CLOCK_25MHz, REF_CLOCK_40MHz or REF_CLOCK_100MHz
+ *
+ * RETURNS: MV_OK - for success
+ * MV_BAD_PARAM - for fail
+ */
+int hws_serdes_pex_ref_clock_satr_get(enum serdes_type serdes_type, u32 *pex_satr)
+{
+ u32 data, reg_satr1;
+
+ reg_satr1 = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
+
+ switch (serdes_type) {
+ case PEX0:
+ data = REF_CLK_SELECTOR_VAL_PEX0(reg_satr1);
+ break;
+ case PEX1:
+ data = REF_CLK_SELECTOR_VAL_PEX1(reg_satr1);
+ break;
+ case PEX2:
+ data = REF_CLK_SELECTOR_VAL_PEX2(reg_satr1);
+ break;
+ case PEX3:
+ data = REF_CLK_SELECTOR_VAL_PEX3(reg_satr1);
+ break;
+ default:
+ printf("%s: Error: SerDes type %d is not supported\n",
+ __func__, serdes_type);
+ return MV_BAD_PARAM;
+ }
+
+ *pex_satr = data;
+
+ return MV_OK;
+}
+
+u32 hws_serdes_get_ref_clock_val(enum serdes_type serdes_type)
+{
+ u32 pex_satr;
+ enum ref_clock ref_clock;
+
+ DEBUG_INIT_FULL_S("\n### hws_serdes_get_ref_clock_val ###\n");
+
+ if (serdes_type >= LAST_SERDES_TYPE)
+ return REF_CLOCK_UNSUPPORTED;
+
+ /* read ref clock from S@R */
+ ref_clock = hws_serdes_silicon_ref_clock_get();
+
+ if (serdes_type > PEX3) {
+ /* for all Serdes types but PCIe */
+ return ref_clock;
+ }
+
+ /* for PCIe, need also to check PCIe S@R */
+ CHECK_STATUS(hws_serdes_pex_ref_clock_satr_get
+ (serdes_type, &pex_satr));
+
+ if (pex_satr == 0) {
+ return REF_CLOCK_100MHZ;
+ } else if (pex_satr == 1) {
+ /* value of 1 means we can use ref clock from SoC (as other Serdes types) */
+ return ref_clock;
+ } else {
+ printf
+ ("%s: Error: REF_CLK_SELECTOR_VAL for SerDes type %d is wrong\n",
+ __func__, serdes_type);
+ return REF_CLOCK_UNSUPPORTED;
+ }
+}
+
+int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up,
+ enum serdes_type serdes_type,
+ enum serdes_speed baud_rate,
+ enum serdes_mode serdes_mode, enum ref_clock ref_clock)
+{
+ u32 sata_idx, pex_idx, sata_port;
+ enum serdes_seq speed_seq_id;
+ u32 reg_data;
+ int is_pex_by1;
+
+ DEBUG_INIT_FULL_S("\n### serdes_power_up_ctrl ###\n");
+
+ if (serdes_power_up == 1) { /* Serdes power up */
+ DEBUG_INIT_FULL_S
+ ("serdes_power_up_ctrl: executing power up.. ");
+ DEBUG_INIT_FULL_C("serdes num = ", serdes_num, 2);
+ DEBUG_INIT_FULL_C("serdes type = ", serdes_type, 2);
+
+ DEBUG_INIT_FULL_S("Going access 1");
+
+ /* Getting the Speed Select sequence id */
+ speed_seq_id =
+ serdes_type_and_speed_to_speed_seq(serdes_type,
+ baud_rate);
+ if (speed_seq_id == SERDES_LAST_SEQ) {
+ printf
+ ("serdes_power_up_ctrl: serdes type %d and speed %d are not supported together\n",
+ serdes_type, baud_rate);
+
+ return MV_BAD_PARAM;
+ }
+
+ /* Executing power up, ref clock set, speed config and TX config */
+ switch (serdes_type) {
+ case PEX0:
+ case PEX1:
+ case PEX2:
+ case PEX3:
+ if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2) {
+ CHECK_STATUS(serdes_pex_usb3_pipe_delay_w_a
+ (serdes_num, PEX));
+ }
+
+ is_pex_by1 = (serdes_mode == PEX_ROOT_COMPLEX_X1) ||
+ (serdes_mode == PEX_END_POINT_X1);
+ pex_idx = serdes_type - PEX0;
+
+ if ((is_pex_by1 == 1) || (serdes_type == PEX0)) {
+ /* For PEX by 4, init only the PEX 0 */
+ reg_data = reg_read(SOC_CONTROL_REG1);
+ if (is_pex_by1 == 1)
+ reg_data |= 0x4000;
+ else
+ reg_data &= ~0x4000;
+ reg_write(SOC_CONTROL_REG1, reg_data);
+
+ reg_data =
+ reg_read(((PEX_IF_REGS_BASE(pex_idx)) +
+ 0x6c));
+ reg_data &= ~0x3f0;
+ if (is_pex_by1 == 1)
+ reg_data |= 0x10;
+ else
+ reg_data |= 0x40;
+ reg_write(((PEX_IF_REGS_BASE(pex_idx)) + 0x6c),
+ reg_data);
+
+ reg_data =
+ reg_read(((PEX_IF_REGS_BASE(pex_idx)) +
+ 0x6c));
+ reg_data &= ~0xf;
+ reg_data |= 0x2;
+ reg_write(((PEX_IF_REGS_BASE(pex_idx)) + 0x6c),
+ reg_data);
+
+ reg_data =
+ reg_read(((PEX_IF_REGS_BASE(pex_idx)) +
+ 0x70));
+ reg_data &= ~0x40;
+ reg_data |= 0x40;
+ reg_write(((PEX_IF_REGS_BASE(pex_idx)) + 0x70),
+ reg_data);
+ }
+
+ CHECK_STATUS(mv_seq_exec(serdes_num, PEX_POWER_UP_SEQ));
+ if (is_pex_by1 == 0) {
+ /*
+ * for PEX by 4 - use the PEX index as the
+ * seq array index
+ */
+ serdes_seq_db[PEX_BY_4_CONFIG_SEQ].
+ data_arr_idx = pex_idx;
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, PEX_BY_4_CONFIG_SEQ));
+ }
+
+ CHECK_STATUS(hws_ref_clock_set
+ (serdes_num, serdes_type, ref_clock));
+ CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, PEX_ELECTRICAL_CONFIG_SEQ));
+
+ if (is_pex_by1 == 1) {
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, PEX_TX_CONFIG_SEQ2));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, PEX_TX_CONFIG_SEQ3));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, PEX_TX_CONFIG_SEQ1));
+ }
+ udelay(20);
+
+ break;
+ case USB3_HOST0:
+ case USB3_HOST1:
+ case USB3_DEVICE:
+ if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2) {
+ CHECK_STATUS(serdes_pex_usb3_pipe_delay_w_a
+ (serdes_num, USB3));
+ }
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, USB3_POWER_UP_SEQ));
+ CHECK_STATUS(hws_ref_clock_set
+ (serdes_num, serdes_type, ref_clock));
+ CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
+ if (serdes_type == USB3_DEVICE) {
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num,
+ USB3_DEVICE_CONFIG_SEQ));
+ }
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, USB3_ELECTRICAL_CONFIG_SEQ));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, USB3_TX_CONFIG_SEQ1));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, USB3_TX_CONFIG_SEQ2));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, USB3_TX_CONFIG_SEQ3));
+
+ udelay(10000);
+ break;
+ case SATA0:
+ case SATA1:
+ case SATA2:
+ case SATA3:
+ sata_idx = ((serdes_type == SATA0) ||
+ (serdes_type == SATA1)) ? 0 : 1;
+ sata_port = ((serdes_type == SATA0) ||
+ (serdes_type == SATA2)) ? 0 : 1;
+
+ CHECK_STATUS(mv_seq_exec
+ (sata_idx, (sata_port == 0) ?
+ SATA_PORT_0_ONLY_POWER_UP_SEQ :
+ SATA_PORT_1_ONLY_POWER_UP_SEQ));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, SATA_POWER_UP_SEQ));
+ CHECK_STATUS(hws_ref_clock_set
+ (serdes_num, serdes_type, ref_clock));
+ CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, SATA_ELECTRICAL_CONFIG_SEQ));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, SATA_TX_CONFIG_SEQ1));
+ CHECK_STATUS(mv_seq_exec
+ (sata_idx, (sata_port == 0) ?
+ SATA_PORT_0_ONLY_TX_CONFIG_SEQ :
+ SATA_PORT_1_ONLY_TX_CONFIG_SEQ));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, SATA_TX_CONFIG_SEQ2));
+
+ udelay(10000);
+ break;
+ case SGMII0:
+ case SGMII1:
+ case SGMII2:
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, SGMII_POWER_UP_SEQ));
+ CHECK_STATUS(hws_ref_clock_set
+ (serdes_num, serdes_type, ref_clock));
+ CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, SGMII_ELECTRICAL_CONFIG_SEQ));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, SGMII_TX_CONFIG_SEQ1));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, SGMII_TX_CONFIG_SEQ2));
+
+ /* GBE configuration */
+ reg_data = reg_read(GBE_CONFIGURATION_REG);
+ /* write the SGMII index */
+ reg_data |= 0x1 << (serdes_type - SGMII0);
+ reg_write(GBE_CONFIGURATION_REG, reg_data);
+
+ break;
+ case QSGMII:
+ if (hws_ctrl_serdes_rev_get() < MV_SERDES_REV_2_1)
+ return MV_NOT_SUPPORTED;
+
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, QSGMII_POWER_UP_SEQ));
+ CHECK_STATUS(hws_ref_clock_set
+ (serdes_num, serdes_type, ref_clock));
+ CHECK_STATUS(mv_seq_exec(serdes_num, speed_seq_id));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num,
+ QSGMII_ELECTRICAL_CONFIG_SEQ));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, QSGMII_TX_CONFIG_SEQ1));
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num, QSGMII_TX_CONFIG_SEQ2));
+ break;
+ case SGMII3:
+ case XAUI:
+ case RXAUI:
+ CHECK_STATUS(serdes_power_up_ctrl_ext
+ (serdes_num, serdes_power_up, serdes_type,
+ baud_rate, serdes_mode, ref_clock));
+ break;
+ default:
+ DEBUG_INIT_S
+ ("serdes_power_up_ctrl: bad serdes_type parameter\n");
+ return MV_BAD_PARAM;
+ }
+ } else { /* Serdes power down */
+ DEBUG_INIT_FULL_S("serdes_power_up: executing power down.. ");
+ DEBUG_INIT_FULL_C("serdes num = ", serdes_num, 1);
+
+ CHECK_STATUS(mv_seq_exec(serdes_num, SERDES_POWER_DOWN_SEQ));
+ }
+
+ DEBUG_INIT_FULL_C(
+ "serdes_power_up_ctrl ended successfully for serdes ",
+ serdes_num, 2);
+
+ return MV_OK;
+}
+
+int hws_update_serdes_phy_selectors(struct serdes_map *serdes_config_map)
+{
+ u32 lane_data, idx, serdes_lane_hw_num, reg_data = 0;
+ enum serdes_type serdes_type;
+ enum serdes_mode serdes_mode;
+ u8 select_bit_off;
+ int is_pex_x4 = 0;
+ int updated_topology_print = 0;
+
+ DEBUG_INIT_FULL_S("\n### hws_update_serdes_phy_selectors ###\n");
+ DEBUG_INIT_FULL_S
+ ("Updating the COMMON PHYS SELECTORS register with the serdes types\n");
+
+ if (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2)
+ select_bit_off = 3;
+ else
+ select_bit_off = 4;
+
+ /*
+ * Updating bits 0-17 in the COMMON PHYS SELECTORS register
+ * according to the serdes types
+ */
+ for (idx = 0; idx < hws_serdes_get_max_lane();
+ idx++) {
+ serdes_type = serdes_config_map[idx].serdes_type;
+ serdes_mode = serdes_config_map[idx].serdes_mode;
+ serdes_lane_hw_num = hws_get_physical_serdes_num(idx);
+
+ lane_data =
+ hws_serdes_get_phy_selector_val(serdes_lane_hw_num,
+ serdes_type);
+
+ if (serdes_type == DEFAULT_SERDES)
+ continue;
+
+ if (hws_serdes_topology_verify
+ (serdes_type, idx, serdes_mode) != MV_OK) {
+ serdes_config_map[idx].serdes_type =
+ DEFAULT_SERDES;
+ printf("%s: SerDes lane #%d is disabled\n", __func__,
+ serdes_lane_hw_num);
+ updated_topology_print = 1;
+ continue;
+ }
+
+ /*
+ * Checking if the board topology configuration includes
+ * PEXx4 - for the next step
+ */
+ if ((serdes_mode == PEX_END_POINT_X4) ||
+ (serdes_mode == PEX_ROOT_COMPLEX_X4)) {
+ /* update lane data to the 3 next SERDES lanes */
+ lane_data =
+ common_phys_selectors_pex_by4_lanes
+ [serdes_lane_hw_num];
+ if (serdes_type == PEX0)
+ is_pex_x4 = 1;
+ }
+
+ if (lane_data == NA) {
+ printf
+ ("%s: Warning: SerDes lane #%d and type %d are not supported together\n",
+ __func__, serdes_lane_hw_num, serdes_mode);
+ serdes_config_map[idx].serdes_type =
+ DEFAULT_SERDES;
+ printf("%s: SerDes lane #%d is disabled\n", __func__,
+ serdes_lane_hw_num);
+ continue;
+ }
+
+ /*
+ * Updating the data that will be written to
+ * COMMON_PHYS_SELECTORS_REG
+ */
+ reg_data |= (lane_data <<
+ (select_bit_off * serdes_lane_hw_num));
+ }
+
+ /*
+ * Check that number of used lanes for XAUI and RXAUI
+ * (if used) is right
+ */
+ hws_serdes_xaui_topology_verify();
+
+ /* Print topology */
+ if (updated_topology_print)
+ print_topology_details(serdes_config_map);
+
+ /*
+ * Updating the PEXx4 Enable bit in the COMMON PHYS SELECTORS
+ * register for PEXx4 mode
+ */
+ reg_data |= (is_pex_x4 == 1) ? (0x1 << PEX_X4_ENABLE_OFFS) : 0;
+
+ /* Updating the COMMON PHYS SELECTORS register */
+ reg_write(COMMON_PHYS_SELECTORS_REG, reg_data);
+
+ return MV_OK;
+}
+
+int hws_ref_clock_set(u32 serdes_num, enum serdes_type serdes_type,
+ enum ref_clock ref_clock)
+{
+ u32 data1 = 0, data2 = 0, data3 = 0, reg_data;
+
+ DEBUG_INIT_FULL_S("\n### hws_ref_clock_set ###\n");
+
+ if (hws_is_serdes_active(serdes_num) != 1) {
+ printf("%s: SerDes lane #%d is not Active\n", __func__,
+ serdes_num);
+ return MV_BAD_PARAM;
+ }
+
+ switch (serdes_type) {
+ case PEX0:
+ case PEX1:
+ case PEX2:
+ case PEX3:
+ switch (ref_clock) {
+ case REF_CLOCK_25MHZ:
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num,
+ PEX_CONFIG_REF_CLOCK_25MHZ_SEQ));
+ return MV_OK;
+ case REF_CLOCK_100MHZ:
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num,
+ PEX_CONFIG_REF_CLOCK_100MHZ_SEQ));
+ return MV_OK;
+#ifdef CONFIG_ARMADA_39X
+ case REF_CLOCK_40MHZ:
+ CHECK_STATUS(mv_seq_exec
+ (serdes_num,
+ PEX_CONFIG_REF_CLOCK_40MHZ_SEQ));
+ return MV_OK;
+#endif
+ default:
+ printf
+ ("%s: Error: ref_clock %d for SerDes lane #%d, type %d is not supported\n",
+ __func__, ref_clock, serdes_num, serdes_type);
+ return MV_BAD_PARAM;
+ }
+ case USB3_HOST0:
+ case USB3_HOST1:
+ case USB3_DEVICE:
+ if (ref_clock == REF_CLOCK_25MHZ) {
+ data1 = POWER_AND_PLL_CTRL_REG_25MHZ_VAL_2;
+ data2 = GLOBAL_PM_CTRL_REG_25MHZ_VAL;
+ data3 = LANE_CFG4_REG_25MHZ_VAL;
+ } else if (ref_clock == REF_CLOCK_40MHZ) {
+ data1 = POWER_AND_PLL_CTRL_REG_40MHZ_VAL;
+ data2 = GLOBAL_PM_CTRL_REG_40MHZ_VAL;
+ data3 = LANE_CFG4_REG_40MHZ_VAL;
+ } else {
+ printf
+ ("hws_ref_clock_set: ref clock is not valid for serdes type %d\n",
+ serdes_type);
+ return MV_BAD_PARAM;
+ }
+ break;
+ case SATA0:
+ case SATA1:
+ case SATA2:
+ case SATA3:
+ case SGMII0:
+ case SGMII1:
+ case SGMII2:
+ case QSGMII:
+ if (ref_clock == REF_CLOCK_25MHZ) {
+ data1 = POWER_AND_PLL_CTRL_REG_25MHZ_VAL_1;
+ } else if (ref_clock == REF_CLOCK_40MHZ) {
+ data1 = POWER_AND_PLL_CTRL_REG_40MHZ_VAL;
+ } else {
+ printf
+ ("hws_ref_clock_set: ref clock is not valid for serdes type %d\n",
+ serdes_type);
+ return MV_BAD_PARAM;
+ }
+ break;
+#ifdef CONFIG_ARMADA_39X
+ case SGMII3:
+ case XAUI:
+ case RXAUI:
+ if (ref_clock == REF_CLOCK_25MHZ) {
+ data1 = POWER_AND_PLL_CTRL_REG_25MHZ_VAL_1;
+ } else if (ref_clock == REF_CLOCK_40MHZ) {
+ data1 = POWER_AND_PLL_CTRL_REG_40MHZ_VAL;
+ } else {
+ printf
+ ("hws_ref_clock_set: ref clock is not valid for serdes type %d\n",
+ serdes_type);
+ return MV_BAD_PARAM;
+ }
+ break;
+#endif
+ default:
+ DEBUG_INIT_S("hws_ref_clock_set: not supported serdes type\n");
+ return MV_BAD_PARAM;
+ }
+
+ /*
+ * Write the ref_clock to relevant SELECT_REF_CLOCK_REG bits and
+ * offset
+ */
+ reg_data = reg_read(POWER_AND_PLL_CTRL_REG +
+ SERDES_REGS_LANE_BASE_OFFSET(serdes_num));
+ reg_data &= POWER_AND_PLL_CTRL_REG_MASK;
+ reg_data |= data1;
+ reg_write(POWER_AND_PLL_CTRL_REG +
+ SERDES_REGS_LANE_BASE_OFFSET(serdes_num), reg_data);
+
+ if ((serdes_type == USB3_HOST0) || (serdes_type == USB3_HOST1) ||
+ (serdes_type == USB3_DEVICE)) {
+ reg_data = reg_read(GLOBAL_PM_CTRL +
+ SERDES_REGS_LANE_BASE_OFFSET(serdes_num));
+ reg_data &= GLOBAL_PM_CTRL_REG_MASK;
+ reg_data |= data2;
+ reg_write(GLOBAL_PM_CTRL +
+ SERDES_REGS_LANE_BASE_OFFSET(serdes_num), reg_data);
+
+ reg_data = reg_read(LANE_CFG4_REG +
+ SERDES_REGS_LANE_BASE_OFFSET(serdes_num));
+ reg_data &= LANE_CFG4_REG_MASK;
+ reg_data |= data3;
+ reg_write(LANE_CFG4_REG +
+ SERDES_REGS_LANE_BASE_OFFSET(serdes_num), reg_data);
+ }
+
+ return MV_OK;
+}
+
+/*
+ * hws_pex_tx_config_seq -
+ *
+ * DESCRIPTION: Set PEX_TX_CONFIG_SEQ sequence init for PEXx4 mode
+ * INPUT: serdes_map - The board topology map
+ * OUTPUT: None
+ * RETURNS: MV_OK - for success
+ * MV_BAD_PARAM - for fail
+ */
+int hws_pex_tx_config_seq(struct serdes_map *serdes_map)
+{
+ enum serdes_mode serdes_mode;
+ u32 serdes_lane_id, serdes_lane_hw_num;
+
+ DEBUG_INIT_FULL_S("\n### hws_pex_tx_config_seq ###\n");
+
+ /*
+ * For PEXx4: the pex_and_usb3_tx_config_params1/2/3
+ * configurations should run by setting each sequence for
+ * all 4 lanes.
+ */
+
+ /* relese pipe soft reset for all lanes */
+ for (serdes_lane_id = 0; serdes_lane_id < hws_serdes_get_max_lane();
+ serdes_lane_id++) {
+ serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
+ serdes_lane_hw_num =
+ hws_get_physical_serdes_num(serdes_lane_id);
+
+ if ((serdes_mode == PEX_ROOT_COMPLEX_X4) ||
+ (serdes_mode == PEX_END_POINT_X4)) {
+ CHECK_STATUS(mv_seq_exec
+ (serdes_lane_hw_num, PEX_TX_CONFIG_SEQ1));
+ }
+ }
+
+ /* set phy soft reset for all lanes */
+ for (serdes_lane_id = 0; serdes_lane_id < hws_serdes_get_max_lane();
+ serdes_lane_id++) {
+ serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
+ serdes_lane_hw_num =
+ hws_get_physical_serdes_num(serdes_lane_id);
+ if ((serdes_mode == PEX_ROOT_COMPLEX_X4) ||
+ (serdes_mode == PEX_END_POINT_X4)) {
+ CHECK_STATUS(mv_seq_exec
+ (serdes_lane_hw_num, PEX_TX_CONFIG_SEQ2));
+ }
+ }
+
+ /* set phy soft reset for all lanes */
+ for (serdes_lane_id = 0; serdes_lane_id < hws_serdes_get_max_lane();
+ serdes_lane_id++) {
+ serdes_mode = serdes_map[serdes_lane_id].serdes_mode;
+ serdes_lane_hw_num =
+ hws_get_physical_serdes_num(serdes_lane_id);
+ if ((serdes_mode == PEX_ROOT_COMPLEX_X4) ||
+ (serdes_mode == PEX_END_POINT_X4)) {
+ CHECK_STATUS(mv_seq_exec
+ (serdes_lane_hw_num, PEX_TX_CONFIG_SEQ3));
+ }
+ }
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _HIGH_SPEED_ENV_SPEC_H
+#define _HIGH_SPEED_ENV_SPEC_H
+
+#include "seq_exec.h"
+
+/*
+ * For setting or clearing a certain bit (bit is a number between 0 and 31)
+ * in the data
+ */
+#define SET_BIT(data, bit) ((data) | (0x1 << (bit)))
+#define CLEAR_BIT(data, bit) ((data) & (~(0x1 << (bit))))
+
+#define MAX_SERDES_LANES 7 /* as in a39x */
+
+/* Serdes revision */
+/* Serdes revision 1.2 (for A38x-Z1) */
+#define MV_SERDES_REV_1_2 0x0
+/* Serdes revision 2.1 (for A39x-Z1, A38x-A0) */
+#define MV_SERDES_REV_2_1 0x1
+#define MV_SERDES_REV_NA 0xff
+
+#define SERDES_REGS_LANE_BASE_OFFSET(lane) (0x800 * (lane))
+
+#define PEX_X4_ENABLE_OFFS \
+ (hws_ctrl_serdes_rev_get() == MV_SERDES_REV_1_2 ? 18 : 31)
+
+/* Serdes lane types */
+enum serdes_type {
+ PEX0,
+ PEX1,
+ PEX2,
+ PEX3,
+ SATA0,
+ SATA1,
+ SATA2,
+ SATA3,
+ SGMII0,
+ SGMII1,
+ SGMII2,
+ QSGMII,
+ USB3_HOST0,
+ USB3_HOST1,
+ USB3_DEVICE,
+ SGMII3,
+ XAUI,
+ RXAUI,
+ DEFAULT_SERDES,
+ LAST_SERDES_TYPE
+};
+
+/* Serdes baud rates */
+enum serdes_speed {
+ SERDES_SPEED_1_25_GBPS,
+ SERDES_SPEED_1_5_GBPS,
+ SERDES_SPEED_2_5_GBPS,
+ SERDES_SPEED_3_GBPS,
+ SERDES_SPEED_3_125_GBPS,
+ SERDES_SPEED_5_GBPS,
+ SERDES_SPEED_6_GBPS,
+ SERDES_SPEED_6_25_GBPS,
+ LAST_SERDES_SPEED
+};
+
+/* Serdes modes */
+enum serdes_mode {
+ PEX_ROOT_COMPLEX_X1,
+ PEX_ROOT_COMPLEX_X4,
+ PEX_END_POINT_X1,
+ PEX_END_POINT_X4,
+
+ SERDES_DEFAULT_MODE, /* not pex */
+
+ SERDES_LAST_MODE
+};
+
+struct serdes_map {
+ enum serdes_type serdes_type;
+ enum serdes_speed serdes_speed;
+ enum serdes_mode serdes_mode;
+ int swap_rx;
+ int swap_tx;
+};
+
+/* Serdes ref clock options */
+enum ref_clock {
+ REF_CLOCK_25MHZ,
+ REF_CLOCK_100MHZ,
+ REF_CLOCK_40MHZ,
+ REF_CLOCK_UNSUPPORTED
+};
+
+/* Serdes sequences */
+enum serdes_seq {
+ SATA_PORT_0_ONLY_POWER_UP_SEQ,
+ SATA_PORT_1_ONLY_POWER_UP_SEQ,
+ SATA_POWER_UP_SEQ,
+ SATA_1_5_SPEED_CONFIG_SEQ,
+ SATA_3_SPEED_CONFIG_SEQ,
+ SATA_6_SPEED_CONFIG_SEQ,
+ SATA_ELECTRICAL_CONFIG_SEQ,
+ SATA_TX_CONFIG_SEQ1,
+ SATA_PORT_0_ONLY_TX_CONFIG_SEQ,
+ SATA_PORT_1_ONLY_TX_CONFIG_SEQ,
+ SATA_TX_CONFIG_SEQ2,
+
+ SGMII_POWER_UP_SEQ,
+ SGMII_1_25_SPEED_CONFIG_SEQ,
+ SGMII_3_125_SPEED_CONFIG_SEQ,
+ SGMII_ELECTRICAL_CONFIG_SEQ,
+ SGMII_TX_CONFIG_SEQ1,
+ SGMII_TX_CONFIG_SEQ2,
+
+ PEX_POWER_UP_SEQ,
+ PEX_2_5_SPEED_CONFIG_SEQ,
+ PEX_5_SPEED_CONFIG_SEQ,
+ PEX_ELECTRICAL_CONFIG_SEQ,
+ PEX_TX_CONFIG_SEQ1,
+ PEX_TX_CONFIG_SEQ2,
+ PEX_TX_CONFIG_SEQ3,
+ PEX_BY_4_CONFIG_SEQ,
+ PEX_CONFIG_REF_CLOCK_25MHZ_SEQ,
+ PEX_CONFIG_REF_CLOCK_100MHZ_SEQ,
+ PEX_CONFIG_REF_CLOCK_40MHZ_SEQ,
+
+ USB3_POWER_UP_SEQ,
+ USB3_HOST_SPEED_CONFIG_SEQ,
+ USB3_DEVICE_SPEED_CONFIG_SEQ,
+ USB3_ELECTRICAL_CONFIG_SEQ,
+ USB3_TX_CONFIG_SEQ1,
+ USB3_TX_CONFIG_SEQ2,
+ USB3_TX_CONFIG_SEQ3,
+ USB3_DEVICE_CONFIG_SEQ,
+
+ USB2_POWER_UP_SEQ,
+
+ SERDES_POWER_DOWN_SEQ,
+
+ SGMII3_POWER_UP_SEQ,
+ SGMII3_1_25_SPEED_CONFIG_SEQ,
+ SGMII3_TX_CONFIG_SEQ1,
+ SGMII3_TX_CONFIG_SEQ2,
+
+ QSGMII_POWER_UP_SEQ,
+ QSGMII_5_SPEED_CONFIG_SEQ,
+ QSGMII_ELECTRICAL_CONFIG_SEQ,
+ QSGMII_TX_CONFIG_SEQ1,
+ QSGMII_TX_CONFIG_SEQ2,
+
+ XAUI_POWER_UP_SEQ,
+ XAUI_3_125_SPEED_CONFIG_SEQ,
+ XAUI_ELECTRICAL_CONFIG_SEQ,
+ XAUI_TX_CONFIG_SEQ1,
+ XAUI_TX_CONFIG_SEQ2,
+
+ RXAUI_POWER_UP_SEQ,
+ RXAUI_6_25_SPEED_CONFIG_SEQ,
+ RXAUI_ELECTRICAL_CONFIG_SEQ,
+ RXAUI_TX_CONFIG_SEQ1,
+ RXAUI_TX_CONFIG_SEQ2,
+
+ SERDES_LAST_SEQ
+};
+
+/* The different sequence types for PEX and USB3 */
+enum {
+ PEX,
+ USB3,
+ LAST_PEX_USB_SEQ_TYPE
+};
+
+enum {
+ PEXSERDES_SPEED_2_5_GBPS,
+ PEXSERDES_SPEED_5_GBPS,
+ USB3SERDES_SPEED_5_GBPS_HOST,
+ USB3SERDES_SPEED_5_GBPS_DEVICE,
+ LAST_PEX_USB_SPEED_SEQ_TYPE
+};
+
+/* The different sequence types for SATA and SGMII */
+enum {
+ SATA,
+ SGMII,
+ SGMII_3_125,
+ LAST_SATA_SGMII_SEQ_TYPE
+};
+
+enum {
+ QSGMII_SEQ_IDX,
+ LAST_QSGMII_SEQ_TYPE
+};
+
+enum {
+ XAUI_SEQ_IDX,
+ RXAUI_SEQ_IDX,
+ LAST_XAUI_RXAUI_SEQ_TYPE
+};
+
+enum {
+ SATASERDES_SPEED_1_5_GBPS,
+ SATASERDES_SPEED_3_GBPS,
+ SATASERDES_SPEED_6_GBPS,
+ SGMIISERDES_SPEED_1_25_GBPS,
+ SGMIISERDES_SPEED_3_125_GBPS,
+ LAST_SATA_SGMII_SPEED_SEQ_TYPE
+};
+
+extern u8 selectors_serdes_rev1_map[LAST_SERDES_TYPE][MAX_SERDES_LANES];
+extern u8 selectors_serdes_rev2_map[LAST_SERDES_TYPE][MAX_SERDES_LANES];
+
+u8 hws_ctrl_serdes_rev_get(void);
+int mv_update_serdes_select_phy_mode_seq(void);
+int hws_board_topology_load(struct serdes_map *serdes_map_array);
+enum serdes_seq serdes_type_and_speed_to_speed_seq(enum serdes_type serdes_type,
+ enum serdes_speed baud_rate);
+int hws_serdes_seq_init(void);
+int hws_serdes_seq_db_init(void);
+int hws_power_up_serdes_lanes(struct serdes_map *serdes_config_map);
+int hws_ctrl_high_speed_serdes_phy_config(void);
+int serdes_power_up_ctrl(u32 serdes_num, int serdes_power_up,
+ enum serdes_type serdes_type,
+ enum serdes_speed baud_rate,
+ enum serdes_mode serdes_mode,
+ enum ref_clock ref_clock);
+int serdes_power_up_ctrl_ext(u32 serdes_num, int serdes_power_up,
+ enum serdes_type serdes_type,
+ enum serdes_speed baud_rate,
+ enum serdes_mode serdes_mode,
+ enum ref_clock ref_clock);
+u32 hws_serdes_silicon_ref_clock_get(void);
+int hws_serdes_pex_ref_clock_get(enum serdes_type serdes_type,
+ enum ref_clock *ref_clock);
+int hws_ref_clock_set(u32 serdes_num, enum serdes_type serdes_type,
+ enum ref_clock ref_clock);
+int hws_update_serdes_phy_selectors(struct serdes_map *serdes_config_map);
+u32 hws_serdes_get_phy_selector_val(int serdes_num,
+ enum serdes_type serdes_type);
+u32 hws_serdes_get_ref_clock_val(enum serdes_type serdes_type);
+u32 hws_serdes_get_max_lane(void);
+int hws_get_ext_base_addr(u32 serdes_num, u32 base_addr, u32 unit_base_offset,
+ u32 *unit_base_reg, u32 *unit_offset);
+int hws_pex_tx_config_seq(struct serdes_map *serdes_map);
+u32 hws_get_physical_serdes_num(u32 serdes_num);
+int hws_is_serdes_active(u8 lane_num);
+
+#endif /* _HIGH_SPEED_ENV_SPEC_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "high_speed_topology_spec.h"
+#include "sys_env_lib.h"
+
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+/*
+ * This is an example implementation for this custom board
+ * specific function
+ */
+static struct serdes_map custom_board_topology_config[] = {
+ /* Customer Board Topology - reference from Marvell DB-GP board */
+ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {SATA3, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {SATA2, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+int hws_board_topology_load(struct serdes_map *serdes_map_array)
+{
+ serdes_map_array = custom_board_topology_config;
+}
+#endif
+
+load_topology_func_ptr load_topology_func_arr[] = {
+ load_topology_rd, /* RD NAS */
+ load_topology_db, /* 6820 DB-BP (A38x) */
+ load_topology_rd, /* RD AP */
+ load_topology_db_ap, /* DB AP */
+ load_topology_db_gp, /* DB GP */
+ load_topology_db_381, /* 6821 DB-BP (A381) */
+ load_topology_db_amc, /* DB-AMC */
+};
+
+/*****************************************/
+/** Load topology - Marvell 380 DB - BP **/
+/*****************************************/
+/* Configuration options */
+struct serdes_map db_config_default[MAX_SERDES_LANES] = {
+ {SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {SATA3, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+struct serdes_map db_config_slm1363_c[MAX_SERDES_LANES] = {
+ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {PEX3, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {SATA2, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+};
+
+struct serdes_map db_config_slm1363_d[MAX_SERDES_LANES] = {
+ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X4, 0, 0},
+ {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X4, 0, 0},
+ {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X4, 0, 0},
+ {PEX3, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X4, 0, 0},
+ {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+struct serdes_map db_config_slm1363_e[MAX_SERDES_LANES] = {
+ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {SATA2, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+struct serdes_map db_config_slm1363_f[MAX_SERDES_LANES] = {
+ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {PEX3, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {SATA2, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+struct serdes_map db_config_slm1364_d[MAX_SERDES_LANES] = {
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {SGMII0, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {SGMII1, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {SGMII2, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+struct serdes_map db_config_slm1364_e[MAX_SERDES_LANES] = {
+ {SGMII0, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {SGMII1, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {SGMII2, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}
+};
+
+struct serdes_map db_config_slm1364_f[MAX_SERDES_LANES] = {
+ {SGMII0, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {SGMII1, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {SGMII2, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0, 0},
+ {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}
+};
+
+/*************************************************************************/
+/** The following structs are mapping for DB board 'SatR' configuration **/
+/*************************************************************************/
+struct serdes_map db_satr_config_lane1[SATR_DB_LANE1_MAX_OPTIONS] = {
+ /* 0 */ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 1 */ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ /* 2 */ {SATA0, SERDES_SPEED_3_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ /* 3 */ {SGMII0, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 4 */ {SGMII1, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 5 */ {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 6 */ {QSGMII, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+struct serdes_map db_satr_config_lane2[SATR_DB_LANE2_MAX_OPTIONS] = {
+ /* 0 */ {DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 1 */ {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ /* 2 */ {SATA1, SERDES_SPEED_3_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ /* 3 */ {SGMII1, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0}
+};
+
+/*******************************************************/
+/* Configuration options DB ****************************/
+/* mapping from TWSI address data to configuration map */
+/*******************************************************/
+struct serdes_map *topology_config_db[] = {
+ db_config_slm1363_c,
+ db_config_slm1363_d,
+ db_config_slm1363_e,
+ db_config_slm1363_f,
+ db_config_slm1364_d,
+ db_config_slm1364_e,
+ db_config_slm1364_f,
+ db_config_default
+};
+
+/*************************************/
+/** Load topology - Marvell DB - AP **/
+/*************************************/
+struct serdes_map db_ap_config_default[MAX_SERDES_LANES] = {
+ /* 0 */ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ /* 1 */ {SGMII1, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 2 */ {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ /* 3 */ {SGMII2, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 4 */ {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 5 */ {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}
+};
+
+/*************************************/
+/** Load topology - Marvell DB - GP **/
+/*************************************/
+struct serdes_map db_gp_config_default[MAX_SERDES_LANES] = {
+ /* 0 */ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ /* 1 */ {SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ /* 2 */ {SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ /* 3 */ {SATA3, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ /* 4 */ {SATA2, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0},
+ /* 5 */ {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0}
+};
+
+struct serdes_map db_amc_config_default[MAX_SERDES_LANES] = {
+ /* 0 */ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X4, 0, 0},
+ /* 1 */ {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X4, 0, 0},
+ /* 2 */ {PEX2, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X4, 0, 0},
+ /* 3 */ {PEX3, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X4, 0, 0},
+ /* 4 */ {SGMII1, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0},
+ /* 5 */ {SGMII2, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0,
+ 0},
+};
+
+/*****************************************/
+/** Load topology - Marvell 381 DB - BP **/
+/*****************************************/
+/* Configuration options */
+struct serdes_map db381_config_default[MAX_SERDES_LANES] = {
+ {SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 1, 1},
+ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {PEX1, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0},
+ {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}
+};
+
+struct serdes_map db_config_slm1427[MAX_SERDES_LANES] = {
+ {SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 1, 1},
+ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 1, 1},
+ {SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 1, 1},
+ {USB3_HOST1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 1, 1}
+};
+
+struct serdes_map db_config_slm1426[MAX_SERDES_LANES] = {
+ {SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 1, 1},
+ {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 1, 1},
+ {SATA1, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 1, 1},
+ {SGMII2, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 1, 1}
+};
+
+/*
+ * this array must be aligned with enum topology_config_db381 enum,
+ * every update to this array requires update to enum topology_config_db381
+ * enum
+ */
+struct serdes_map *topology_config_db_381[] = {
+ db_config_slm1427,
+ db_config_slm1426,
+ db381_config_default,
+};
+
+u8 topology_config_db_mode_get(void)
+{
+ u8 mode;
+
+ DEBUG_INIT_FULL_S("\n### topology_config_db_mode_get ###\n");
+
+ /* Default - return DB_CONFIG_DEFAULT */
+
+ if (!i2c_read(DB_GET_MODE_SLM1363_ADDR, 0, 1, &mode, 1)) {
+ switch (mode & 0xf) {
+ case 0xc:
+ DEBUG_INIT_S("\nInit DB board SLM 1363 C topology\n");
+ return DB_CONFIG_SLM1363_C;
+ case 0xd:
+ DEBUG_INIT_S("\nInit DB board SLM 1363 D topology\n");
+ return DB_CONFIG_SLM1363_D;
+ case 0xe:
+ DEBUG_INIT_S("\nInit DB board SLM 1363 E topology\n");
+ return DB_CONFIG_SLM1363_E;
+ case 0xf:
+ DEBUG_INIT_S("\nInit DB board SLM 1363 F topology\n");
+ return DB_CONFIG_SLM1363_F;
+ default: /* not the right module */
+ break;
+ }
+ }
+
+ /* SLM1364 Module */
+ if (i2c_read(DB_GET_MODE_SLM1364_ADDR, 0, 1, &mode, 1)) {
+ DEBUG_INIT_S("\nInit DB board default topology\n");
+ return DB_CONFIG_DEFAULT;
+ }
+
+ switch (mode & 0xf) {
+ case 0xd:
+ DEBUG_INIT_S("\nInit DB board SLM 1364 D topology\n");
+ return DB_CONFIG_SLM1364_D;
+ case 0xe:
+ DEBUG_INIT_S("\nInit DB board SLM 1364 E topology\n");
+ return DB_CONFIG_SLM1364_E;
+ case 0xf:
+ DEBUG_INIT_S("\nInit DB board SLM 1364 F topology\n");
+ return DB_CONFIG_SLM1364_F;
+ default: /* Default configuration */
+ DEBUG_INIT_S("\nInit DB board default topology\n");
+ return DB_CONFIG_DEFAULT;
+ }
+}
+
+u8 topology_config_db_381_mode_get(void)
+{
+ u8 mode;
+
+ DEBUG_INIT_FULL_S("\n### topology_config_db_381_mode_get ###\n");
+
+ if (!i2c_read(DB381_GET_MODE_SLM1426_1427_ADDR, 0, 2, &mode, 1)) {
+ switch (mode & 0xf) {
+ case 0x1:
+ DEBUG_INIT_S("\nInit DB-381 board SLM 1427 topology\n");
+ return DB_CONFIG_SLM1427;
+ case 0x2:
+ DEBUG_INIT_S("\nInit DB-381 board SLM 1426 topology\n");
+ return DB_CONFIG_SLM1426;
+ default: /* not the right module */
+ break;
+ }
+ }
+
+ /* in case not detected any supported module, use default topology */
+ DEBUG_INIT_S("\nInit DB-381 board default topology\n");
+ return DB_381_CONFIG_DEFAULT;
+}
+
+/*
+ * Read SatR field 'sgmiispeed' and update lane topology SGMII entries
+ * speed setup
+ */
+int update_topology_sgmii_speed(struct serdes_map *serdes_map_array)
+{
+ u32 serdes_type, lane_num;
+ u8 config_val;
+
+ /* Update SGMII speed settings by 'sgmiispeed' SatR value */
+ for (lane_num = 0; lane_num < hws_serdes_get_max_lane(); lane_num++) {
+ serdes_type = serdes_map_array[lane_num].serdes_type;
+ /*Read SatR configuration for SGMII speed */
+ if ((serdes_type == SGMII0) || (serdes_type == SGMII1) ||
+ (serdes_type == SGMII2)) {
+ /* Read SatR 'sgmiispeed' value */
+ if (i2c_read(EEPROM_I2C_ADDR, 0, 2, &config_val, 1)) {
+ printf("%s: TWSI Read of 'sgmiispeed' failed\n",
+ __func__);
+ return MV_FAIL;
+ }
+
+ if (0 == (config_val & 0x40)) {
+ serdes_map_array[lane_num].serdes_speed =
+ SERDES_SPEED_1_25_GBPS;
+ } else {
+ serdes_map_array[lane_num].serdes_speed =
+ SERDES_SPEED_3_125_GBPS;
+ }
+ }
+ }
+ return MV_OK;
+}
+
+struct serdes_map default_lane = {
+ DEFAULT_SERDES, LAST_SERDES_SPEED, SERDES_DEFAULT_MODE
+};
+int is_custom_topology = 0; /* indicate user of non-default topology */
+
+/*
+ * Read SatR fields (dbserdes1/2 , gpserdes1/2/5) and update lane
+ * topology accordingly
+ */
+int update_topology_satr(struct serdes_map *serdes_map_array)
+{
+ u8 config_val, lane_select, i;
+ u32 board_id = mv_board_id_get();
+
+ switch (board_id) {
+ case DB_68XX_ID: /* read 'dbserdes1' & 'dbserdes2' */
+ case DB_BP_6821_ID:
+ if (i2c_read(EEPROM_I2C_ADDR, 1, 2, &config_val, 1)) {
+ printf("%s: TWSI Read of 'dbserdes1/2' failed\n",
+ __func__);
+ return MV_FAIL;
+ }
+
+ /* Lane #1 */
+ lane_select = (config_val & SATR_DB_LANE1_CFG_MASK) >>
+ SATR_DB_LANE1_CFG_OFFSET;
+ if (lane_select >= SATR_DB_LANE1_MAX_OPTIONS) {
+ printf("\n\%s: Error: invalid value for SatR field 'dbserdes1' (%x)\n",
+ __func__, lane_select);
+ printf("\t_skipping Topology update (run 'SatR write default')\n");
+ return MV_FAIL;
+ }
+
+ /*
+ * If modified default serdes_type for lane#1, update
+ * topology and mark it as custom
+ */
+ if (serdes_map_array[1].serdes_type !=
+ db_satr_config_lane1[lane_select].serdes_type) {
+ serdes_map_array[1] = db_satr_config_lane1[lane_select];
+ is_custom_topology = 1;
+ /* DB 381/2 board has inverted SerDes polarity */
+ if (board_id == DB_BP_6821_ID)
+ serdes_map_array[1].swap_rx =
+ serdes_map_array[1].swap_tx = 1;
+ }
+
+ /* Lane #2 */
+ lane_select = (config_val & SATR_DB_LANE2_CFG_MASK) >>
+ SATR_DB_LANE2_CFG_OFFSET;
+ if (lane_select >= SATR_DB_LANE2_MAX_OPTIONS) {
+ printf("\n\%s: Error: invalid value for SatR field 'dbserdes2' (%x)\n",
+ __func__, lane_select);
+ printf("\t_skipping Topology update (run 'SatR write default')\n");
+ return MV_FAIL;
+ }
+
+ /*
+ * If modified default serdes_type for lane@2, update
+ * topology and mark it as custom
+ */
+ if (serdes_map_array[2].serdes_type !=
+ db_satr_config_lane2[lane_select].serdes_type) {
+ serdes_map_array[2] = db_satr_config_lane2[lane_select];
+ is_custom_topology = 1;
+ /* DB 381/2 board has inverted SerDes polarity */
+ if (board_id == DB_BP_6821_ID)
+ serdes_map_array[2].swap_rx =
+ serdes_map_array[2].swap_tx = 1;
+ }
+
+ if (is_custom_topology == 1) {
+ /*
+ * Check for conflicts with detected lane #1 and
+ * lane #2 (Disable conflicted lanes)
+ */
+ for (i = 0; i < hws_serdes_get_max_lane(); i++) {
+ if (i != 1 && serdes_map_array[1].serdes_type ==
+ serdes_map_array[i].serdes_type) {
+ printf("\t_lane #%d Type conflicts with Lane #1 (Lane #%d disabled)\n",
+ i, i);
+ serdes_map_array[i] =
+ db_satr_config_lane1[0];
+ }
+
+ if (i != 2 &&
+ serdes_map_array[2].serdes_type ==
+ serdes_map_array[i].serdes_type) {
+ printf("\t_lane #%d Type conflicts with Lane #2 (Lane #%d disabled)\n",
+ i, i);
+ serdes_map_array[i] =
+ db_satr_config_lane1[0];
+ }
+ }
+ }
+
+ break; /* case DB_68XX_ID */
+ case DB_GP_68XX_ID: /* read 'gpserdes1' & 'gpserdes2' */
+ if (i2c_read(EEPROM_I2C_ADDR, 2, 2, &config_val, 1)) {
+ printf("%s: TWSI Read of 'gpserdes1/2' failed\n",
+ __func__);
+ return MV_FAIL;
+ }
+
+ /*
+ * Lane #1:
+ * lane_select = 0 --> SATA0,
+ * lane_select = 1 --> PCIe0 (mini PCIe)
+ */
+ lane_select = (config_val & SATR_GP_LANE1_CFG_MASK) >>
+ SATR_GP_LANE1_CFG_OFFSET;
+ if (lane_select == 1) {
+ serdes_map_array[1].serdes_mode = PEX0;
+ serdes_map_array[1].serdes_speed = SERDES_SPEED_5_GBPS;
+ serdes_map_array[1].serdes_type = PEX_ROOT_COMPLEX_X1;
+ /*
+ * If lane 1 is set to PCIe0 --> disable PCIe0
+ * on lane 0
+ */
+ serdes_map_array[0] = default_lane;
+ /* indicate user of non-default topology */
+ is_custom_topology = 1;
+ }
+ printf("Lane 1 detection: %s\n",
+ lane_select ? "PCIe0 (mini PCIe)" : "SATA0");
+
+ /*
+ * Lane #2:
+ * lane_select = 0 --> SATA1,
+ * lane_select = 1 --> PCIe1 (mini PCIe)
+ */
+ lane_select = (config_val & SATR_GP_LANE2_CFG_MASK) >>
+ SATR_GP_LANE2_CFG_OFFSET;
+ if (lane_select == 1) {
+ serdes_map_array[2].serdes_type = PEX1;
+ serdes_map_array[2].serdes_speed = SERDES_SPEED_5_GBPS;
+ serdes_map_array[2].serdes_mode = PEX_ROOT_COMPLEX_X1;
+ /* indicate user of non-default topology */
+ is_custom_topology = 1;
+ }
+ printf("Lane 2 detection: %s\n",
+ lane_select ? "PCIe1 (mini PCIe)" : "SATA1");
+ break; /* case DB_GP_68XX_ID */
+ }
+
+ if (is_custom_topology)
+ printf("\nDetected custom SerDes topology (to restore default run 'SatR write default')\n\n");
+
+ return MV_OK;
+}
+
+/*
+ * hws_update_device_toplogy
+ * DESCRIPTION: Update the default board topology for specific device Id
+ * INPUT:
+ * topology_config_ptr - pointer to the Serdes mapping
+ * topology_mode - topology mode (index)
+ * OUTPUT: None
+ * RRETURNS:
+ * MV_OK - if updating the board topology success
+ * MV_BAD_PARAM - if the input parameter is wrong
+ */
+int hws_update_device_toplogy(struct serdes_map *topology_config_ptr,
+ enum topology_config_db topology_mode)
+{
+ u32 dev_id = sys_env_device_id_get();
+ u32 board_id = mv_board_id_get();
+
+ switch (topology_mode) {
+ case DB_CONFIG_DEFAULT:
+ switch (dev_id) {
+ case MV_6810:
+ /*
+ * DB-AP : default for Lane3=SGMII2 -->
+ * 6810 supports only 2 SGMII interfaces:
+ * lane 3 disabled
+ */
+ if (board_id == DB_AP_68XX_ID) {
+ printf("Device 6810 supports only 2 SGMII interfaces: SGMII-2 @ lane3 disabled\n");
+ topology_config_ptr[3] = default_lane;
+ }
+
+ /*
+ * 6810 has only 4 SerDes and the forth one is
+ * Serdes number 5 (i.e. Serdes 4 is not connected),
+ * therefore we need to copy SerDes 5 configuration
+ * to SerDes 4
+ */
+ printf("Device 6810 does not supports SerDes Lane #4: replaced topology entry with lane #5\n");
+ topology_config_ptr[4] = topology_config_ptr[5];
+
+ /*
+ * No break between cases since the 1st
+ * 6820 limitation apply on 6810
+ */
+ case MV_6820:
+ /*
+ * DB-GP & DB-BP: default for Lane3=SATA3 -->
+ * 6810/20 supports only 2 SATA interfaces:
+ * lane 3 disabled
+ */
+ if ((board_id == DB_68XX_ID) ||
+ (board_id == DB_GP_68XX_ID)) {
+ printf("Device 6810/20 supports only 2 SATA interfaces: SATA Port 3 @ lane3 disabled\n");
+ topology_config_ptr[3] = default_lane;
+ }
+ /*
+ * DB-GP on 6820 only: default for Lane4=SATA2
+ * --> 6820 supports only 2 SATA interfaces:
+ * lane 3 disabled
+ */
+ if (board_id == DB_GP_68XX_ID && dev_id == MV_6820) {
+ printf("Device 6820 supports only 2 SATA interfaces: SATA Port 2 @ lane4 disabled\n");
+ topology_config_ptr[4] = default_lane;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ default:
+ printf("sys_env_update_device_toplogy: selected topology is not supported by this routine\n");
+ break;
+ }
+
+ return MV_OK;
+}
+
+int load_topology_db_381(struct serdes_map *serdes_map_array)
+{
+ u32 lane_num;
+ u8 topology_mode;
+ struct serdes_map *topology_config_ptr;
+ u8 twsi_data;
+ u8 usb3_host0_or_device = 0, usb3_host1_or_device = 0;
+
+ printf("\nInitialize DB-88F6821-BP board topology\n");
+
+ /* Getting the relevant topology mode (index) */
+ topology_mode = topology_config_db_381_mode_get();
+ topology_config_ptr = topology_config_db_381[topology_mode];
+
+ /* Read USB3.0 mode: HOST/DEVICE */
+ if (load_topology_usb_mode_get(&twsi_data) == MV_OK) {
+ usb3_host0_or_device = (twsi_data & 0x1);
+ /* Only one USB3 device is enabled */
+ if (usb3_host0_or_device == 0)
+ usb3_host1_or_device = ((twsi_data >> 1) & 0x1);
+ }
+
+ /* Updating the topology map */
+ for (lane_num = 0; lane_num < hws_serdes_get_max_lane(); lane_num++) {
+ serdes_map_array[lane_num].serdes_mode =
+ topology_config_ptr[lane_num].serdes_mode;
+ serdes_map_array[lane_num].serdes_speed =
+ topology_config_ptr[lane_num].serdes_speed;
+ serdes_map_array[lane_num].serdes_type =
+ topology_config_ptr[lane_num].serdes_type;
+ serdes_map_array[lane_num].swap_rx =
+ topology_config_ptr[lane_num].swap_rx;
+ serdes_map_array[lane_num].swap_tx =
+ topology_config_ptr[lane_num].swap_tx;
+
+ /* Update USB3 device if needed */
+ if (usb3_host0_or_device == 1 &&
+ serdes_map_array[lane_num].serdes_type == USB3_HOST0)
+ serdes_map_array[lane_num].serdes_type = USB3_DEVICE;
+
+ if (usb3_host1_or_device == 1 &&
+ serdes_map_array[lane_num].serdes_type == USB3_HOST1)
+ serdes_map_array[lane_num].serdes_type = USB3_DEVICE;
+ }
+
+ /* If not detected any SerDes Site module, read 'SatR' lane setup */
+ if (topology_mode == DB_381_CONFIG_DEFAULT)
+ update_topology_satr(serdes_map_array);
+
+ /* update 'sgmiispeed' settings */
+ update_topology_sgmii_speed(serdes_map_array);
+
+ return MV_OK;
+}
+
+int load_topology_db(struct serdes_map *serdes_map_array)
+{
+ u32 lane_num;
+ u8 topology_mode;
+ struct serdes_map *topology_config_ptr;
+ u8 twsi_data;
+ u8 usb3_host0_or_device = 0, usb3_host1_or_device = 0;
+
+ printf("\nInitialize DB-88F6820-BP board topology\n");
+
+ /* Getting the relevant topology mode (index) */
+ topology_mode = topology_config_db_mode_get();
+
+ if (topology_mode == DB_NO_TOPOLOGY)
+ topology_mode = DB_CONFIG_DEFAULT;
+
+ topology_config_ptr = topology_config_db[topology_mode];
+
+ /* Update the default board topology device flavours */
+ CHECK_STATUS(hws_update_device_toplogy
+ (topology_config_ptr, topology_mode));
+
+ /* Read USB3.0 mode: HOST/DEVICE */
+ if (load_topology_usb_mode_get(&twsi_data) == MV_OK) {
+ usb3_host0_or_device = (twsi_data & 0x1);
+ /* Only one USB3 device is enabled */
+ if (usb3_host0_or_device == 0)
+ usb3_host1_or_device = ((twsi_data >> 1) & 0x1);
+ }
+
+ /* Updating the topology map */
+ for (lane_num = 0; lane_num < hws_serdes_get_max_lane(); lane_num++) {
+ serdes_map_array[lane_num].serdes_mode =
+ topology_config_ptr[lane_num].serdes_mode;
+ serdes_map_array[lane_num].serdes_speed =
+ topology_config_ptr[lane_num].serdes_speed;
+ serdes_map_array[lane_num].serdes_type =
+ topology_config_ptr[lane_num].serdes_type;
+ serdes_map_array[lane_num].swap_rx =
+ topology_config_ptr[lane_num].swap_rx;
+ serdes_map_array[lane_num].swap_tx =
+ topology_config_ptr[lane_num].swap_tx;
+
+ /*
+ * Update USB3 device if needed - relevant for
+ * lane 3,4,5 only
+ */
+ if (lane_num >= 3) {
+ if ((serdes_map_array[lane_num].serdes_type ==
+ USB3_HOST0) && (usb3_host0_or_device == 1))
+ serdes_map_array[lane_num].serdes_type =
+ USB3_DEVICE;
+
+ if ((serdes_map_array[lane_num].serdes_type ==
+ USB3_HOST1) && (usb3_host1_or_device == 1))
+ serdes_map_array[lane_num].serdes_type =
+ USB3_DEVICE;
+ }
+ }
+
+ /* If not detected any SerDes Site module, read 'SatR' lane setup */
+ if (topology_mode == DB_CONFIG_DEFAULT)
+ update_topology_satr(serdes_map_array);
+
+ /* update 'sgmiispeed' settings */
+ update_topology_sgmii_speed(serdes_map_array);
+
+ return MV_OK;
+}
+
+int load_topology_db_ap(struct serdes_map *serdes_map_array)
+{
+ u32 lane_num;
+ struct serdes_map *topology_config_ptr;
+
+ DEBUG_INIT_FULL_S("\n### load_topology_db_ap ###\n");
+
+ printf("\nInitialize DB-AP board topology\n");
+ topology_config_ptr = db_ap_config_default;
+
+ /* Update the default board topology device flavours */
+ CHECK_STATUS(hws_update_device_toplogy
+ (topology_config_ptr, DB_CONFIG_DEFAULT));
+
+ /* Updating the topology map */
+ for (lane_num = 0; lane_num < hws_serdes_get_max_lane(); lane_num++) {
+ serdes_map_array[lane_num].serdes_mode =
+ topology_config_ptr[lane_num].serdes_mode;
+ serdes_map_array[lane_num].serdes_speed =
+ topology_config_ptr[lane_num].serdes_speed;
+ serdes_map_array[lane_num].serdes_type =
+ topology_config_ptr[lane_num].serdes_type;
+ serdes_map_array[lane_num].swap_rx =
+ topology_config_ptr[lane_num].swap_rx;
+ serdes_map_array[lane_num].swap_tx =
+ topology_config_ptr[lane_num].swap_tx;
+ }
+
+ update_topology_sgmii_speed(serdes_map_array);
+
+ return MV_OK;
+}
+
+int load_topology_db_gp(struct serdes_map *serdes_map_array)
+{
+ u32 lane_num;
+ struct serdes_map *topology_config_ptr;
+ int is_sgmii = 0;
+
+ DEBUG_INIT_FULL_S("\n### load_topology_db_gp ###\n");
+
+ topology_config_ptr = db_gp_config_default;
+
+ printf("\nInitialize DB-GP board topology\n");
+
+ /* check S@R: if lane 5 is USB3 or SGMII */
+ if (load_topology_rd_sgmii_usb(&is_sgmii) != MV_OK)
+ printf("%s: TWSI Read failed - Loading Default Topology\n",
+ __func__);
+ else {
+ topology_config_ptr[5].serdes_type =
+ is_sgmii ? SGMII2 : USB3_HOST1;
+ topology_config_ptr[5].serdes_speed = is_sgmii ?
+ SERDES_SPEED_3_125_GBPS : SERDES_SPEED_5_GBPS;
+ topology_config_ptr[5].serdes_mode = SERDES_DEFAULT_MODE;
+ }
+
+ /* Update the default board topology device flavours */
+ CHECK_STATUS(hws_update_device_toplogy
+ (topology_config_ptr, DB_CONFIG_DEFAULT));
+
+ /* Updating the topology map */
+ for (lane_num = 0; lane_num < hws_serdes_get_max_lane(); lane_num++) {
+ serdes_map_array[lane_num].serdes_mode =
+ topology_config_ptr[lane_num].serdes_mode;
+ serdes_map_array[lane_num].serdes_speed =
+ topology_config_ptr[lane_num].serdes_speed;
+ serdes_map_array[lane_num].serdes_type =
+ topology_config_ptr[lane_num].serdes_type;
+ serdes_map_array[lane_num].swap_rx =
+ topology_config_ptr[lane_num].swap_rx;
+ serdes_map_array[lane_num].swap_tx =
+ topology_config_ptr[lane_num].swap_tx;
+ }
+
+ /*
+ * Update 'gpserdes1/2/3' lane configuration , and 'sgmiispeed'
+ * for SGMII lanes
+ */
+ update_topology_satr(serdes_map_array);
+ update_topology_sgmii_speed(serdes_map_array);
+
+ return MV_OK;
+}
+
+int load_topology_db_amc(struct serdes_map *serdes_map_array)
+{
+ u32 lane_num;
+ struct serdes_map *topology_config_ptr;
+
+ DEBUG_INIT_FULL_S("\n### load_topology_db_amc ###\n");
+
+ printf("\nInitialize DB-AMC board topology\n");
+ topology_config_ptr = db_amc_config_default;
+
+ /* Update the default board topology device flavours */
+ CHECK_STATUS(hws_update_device_toplogy
+ (topology_config_ptr, DB_CONFIG_DEFAULT));
+
+ /* Updating the topology map */
+ for (lane_num = 0; lane_num < hws_serdes_get_max_lane(); lane_num++) {
+ serdes_map_array[lane_num].serdes_mode =
+ topology_config_ptr[lane_num].serdes_mode;
+ serdes_map_array[lane_num].serdes_speed =
+ topology_config_ptr[lane_num].serdes_speed;
+ serdes_map_array[lane_num].serdes_type =
+ topology_config_ptr[lane_num].serdes_type;
+ serdes_map_array[lane_num].swap_rx =
+ topology_config_ptr[lane_num].swap_rx;
+ serdes_map_array[lane_num].swap_tx =
+ topology_config_ptr[lane_num].swap_tx;
+ }
+
+ update_topology_sgmii_speed(serdes_map_array);
+
+ return MV_OK;
+}
+
+int load_topology_rd(struct serdes_map *serdes_map_array)
+{
+ u8 mode;
+
+ DEBUG_INIT_FULL_S("\n### load_topology_rd ###\n");
+
+ DEBUG_INIT_S("\nInit RD board ");
+
+ /* Reading mode */
+ DEBUG_INIT_FULL_S("load_topology_rd: getting mode\n");
+ if (i2c_read(EEPROM_I2C_ADDR, 0, 2, &mode, 1)) {
+ DEBUG_INIT_S("load_topology_rd: TWSI Read failed\n");
+ return MV_FAIL;
+ }
+
+ /* Updating the topology map */
+ DEBUG_INIT_FULL_S("load_topology_rd: Loading board topology details\n");
+
+ /* RD mode: 0 = NAS, 1 = AP */
+ if (((mode >> 1) & 0x1) == 0) {
+ CHECK_STATUS(load_topology_rd_nas(serdes_map_array));
+ } else {
+ CHECK_STATUS(load_topology_rd_ap(serdes_map_array));
+ }
+
+ update_topology_sgmii_speed(serdes_map_array);
+
+ return MV_OK;
+}
+
+int load_topology_rd_nas(struct serdes_map *serdes_map_array)
+{
+ int is_sgmii = 0;
+ u32 i;
+
+ DEBUG_INIT_S("\nInit RD NAS topology ");
+
+ /* check if lane 4 is USB3 or SGMII */
+ if (load_topology_rd_sgmii_usb(&is_sgmii) != MV_OK) {
+ DEBUG_INIT_S("load_topology_rd NAS: TWSI Read failed\n");
+ return MV_FAIL;
+ }
+
+ /* Lane 0 */
+ serdes_map_array[0].serdes_type = PEX0;
+ serdes_map_array[0].serdes_speed = SERDES_SPEED_5_GBPS;
+ serdes_map_array[0].serdes_mode = PEX_ROOT_COMPLEX_X1;
+
+ /* Lane 1 */
+ serdes_map_array[1].serdes_type = SATA0;
+ serdes_map_array[1].serdes_speed = SERDES_SPEED_3_GBPS;
+ serdes_map_array[1].serdes_mode = SERDES_DEFAULT_MODE;
+
+ /* Lane 2 */
+ serdes_map_array[2].serdes_type = SATA1;
+ serdes_map_array[2].serdes_speed = SERDES_SPEED_3_GBPS;
+ serdes_map_array[2].serdes_mode = SERDES_DEFAULT_MODE;
+
+ /* Lane 3 */
+ serdes_map_array[3].serdes_type = SATA3;
+ serdes_map_array[3].serdes_speed = SERDES_SPEED_3_GBPS;
+ serdes_map_array[3].serdes_mode = SERDES_DEFAULT_MODE;
+
+ /* Lane 4 */
+ if (is_sgmii == 1) {
+ DEBUG_INIT_S("Serdes Lane 4 is SGMII\n");
+ serdes_map_array[4].serdes_type = SGMII1;
+ serdes_map_array[4].serdes_speed = SERDES_SPEED_3_125_GBPS;
+ serdes_map_array[4].serdes_mode = SERDES_DEFAULT_MODE;
+ } else {
+ DEBUG_INIT_S("Serdes Lane 4 is USB3\n");
+ serdes_map_array[4].serdes_type = USB3_HOST0;
+ serdes_map_array[4].serdes_speed = SERDES_SPEED_5_GBPS;
+ serdes_map_array[4].serdes_mode = SERDES_DEFAULT_MODE;
+ }
+
+ /* Lane 5 */
+ serdes_map_array[5].serdes_type = SATA2;
+ serdes_map_array[5].serdes_speed = SERDES_SPEED_3_GBPS;
+ serdes_map_array[5].serdes_mode = SERDES_DEFAULT_MODE;
+
+ /* init swap configuration */
+ for (i = 0; i <= 5; i++) {
+ serdes_map_array[i].swap_rx = 0;
+ serdes_map_array[i].swap_tx = 0;
+ }
+
+ return MV_OK;
+}
+
+int load_topology_rd_ap(struct serdes_map *serdes_map_array)
+{
+ int is_sgmii = 0;
+ u32 i;
+
+ DEBUG_INIT_S("\nInit RD AP topology ");
+
+ /* check if lane 4 is USB3 or SGMII */
+ if (load_topology_rd_sgmii_usb(&is_sgmii) != MV_OK) {
+ DEBUG_INIT_S("load_topology_rd AP: TWSI Read failed\n");
+ return MV_FAIL;
+ }
+
+ /* Lane 0 */
+ serdes_map_array[0].serdes_type = DEFAULT_SERDES;
+ serdes_map_array[0].serdes_speed = LAST_SERDES_SPEED;
+ serdes_map_array[0].serdes_mode = SERDES_DEFAULT_MODE;
+
+ /* Lane 1 */
+ serdes_map_array[1].serdes_type = PEX0;
+ serdes_map_array[1].serdes_speed = SERDES_SPEED_5_GBPS;
+ serdes_map_array[1].serdes_mode = PEX_ROOT_COMPLEX_X1;
+
+ /* Lane 2 */
+ serdes_map_array[2].serdes_type = PEX1;
+ serdes_map_array[2].serdes_speed = SERDES_SPEED_5_GBPS;
+ serdes_map_array[2].serdes_mode = PEX_ROOT_COMPLEX_X1;
+
+ /* Lane 3 */
+ serdes_map_array[3].serdes_type = SATA3;
+ serdes_map_array[3].serdes_speed = SERDES_SPEED_3_GBPS;
+ serdes_map_array[3].serdes_mode = SERDES_DEFAULT_MODE;
+
+ /* Lane 4 */
+ if (is_sgmii == 1) {
+ DEBUG_INIT_S("Serdes Lane 4 is SGMII\n");
+ serdes_map_array[4].serdes_type = SGMII1;
+ serdes_map_array[4].serdes_speed = SERDES_SPEED_3_125_GBPS;
+ serdes_map_array[4].serdes_mode = SERDES_DEFAULT_MODE;
+ } else {
+ DEBUG_INIT_S("Serdes Lane 4 is USB3\n");
+ serdes_map_array[4].serdes_type = USB3_HOST0;
+ serdes_map_array[4].serdes_speed = SERDES_SPEED_5_GBPS;
+ serdes_map_array[4].serdes_mode = SERDES_DEFAULT_MODE;
+ }
+
+ /* Lane 5 */
+ serdes_map_array[5].serdes_type = SATA2;
+ serdes_map_array[5].serdes_speed = SERDES_SPEED_3_GBPS;
+ serdes_map_array[5].serdes_mode = SERDES_DEFAULT_MODE;
+
+ /* init swap configuration */
+ for (i = 0; i <= 5; i++) {
+ serdes_map_array[i].swap_rx = 0;
+ serdes_map_array[i].swap_tx = 0;
+ }
+
+ return MV_OK;
+}
+
+int load_topology_rd_sgmii_usb(int *is_sgmii)
+{
+ u8 mode;
+
+ /*
+ * DB-GP board: Device 6810 supports only 2 GbE ports:
+ * SGMII2 not supported (USE USB3 Host instead)
+ */
+ if (sys_env_device_id_get() == MV_6810) {
+ printf("Device 6810 supports only 2 GbE ports: SGMII-2 @ lane5 disabled (setting USB3.0 H1 instead)\n");
+ *is_sgmii = 0;
+ return MV_OK;
+ }
+
+ if (!i2c_read(RD_GET_MODE_ADDR, 1, 2, &mode, 1)) {
+ *is_sgmii = ((mode >> 2) & 0x1);
+ } else {
+ /* else use the default - USB3 */
+ *is_sgmii = 0;
+ }
+
+ if (*is_sgmii)
+ is_custom_topology = 1;
+
+ printf("Lane 5 detection: %s\n",
+ *is_sgmii ? "SGMII2" : "USB3.0 Host Port 1");
+
+ return MV_OK;
+}
+
+/*
+ * 'usb3port0'/'usb3port1' fields are located in EEPROM,
+ * at 3rd byte(offset=2), bit 0:1 (respectively)
+ */
+int load_topology_usb_mode_get(u8 *twsi_data)
+{
+ if (!i2c_read(EEPROM_I2C_ADDR, 2, 2, twsi_data, 1))
+ return MV_OK;
+
+ return MV_ERROR;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _HIGHSPEED_TOPOLOGY_SPEC_H
+#define _HIGHSPEED_TOPOLOGY_SPEC_H
+
+#include "high_speed_env_spec.h"
+
+/* Topology map options for the DB_A38X_BP board */
+enum topology_config_db {
+ DB_CONFIG_SLM1363_C,
+ DB_CONFIG_SLM1363_D,
+ DB_CONFIG_SLM1363_E,
+ DB_CONFIG_SLM1363_F,
+ DB_CONFIG_SLM1364_D,
+ DB_CONFIG_SLM1364_E,
+ DB_CONFIG_SLM1364_F,
+ DB_CONFIG_DEFAULT,
+ DB_NO_TOPOLOGY
+};
+
+/*
+ * this enum must be aligned with topology_config_db_381 array,
+ * every update to this enum requires update to topology_config_db_381
+ * array
+ */
+enum topology_config_db381 {
+ DB_CONFIG_SLM1427, /* enum for db_config_slm1427 */
+ DB_CONFIG_SLM1426, /* enum for db_config_slm1426 */
+ DB_381_CONFIG_DEFAULT,
+ DB_381_NO_TOPOLOGY
+};
+
+/* A generic function pointer for loading the board topology map */
+typedef int (*load_topology_func_ptr)(struct serdes_map *serdes_map_array);
+
+extern load_topology_func_ptr load_topology_func_arr[];
+
+/*
+ * topology_config_db_mode_get -
+ *
+ * DESCRIPTION: Gets the relevant topology mode (index).
+ * for load_topology_db use only.
+ * INPUT: None.
+ * OUTPUT: None.
+ * RETURNS: the topology mode
+ */
+u8 topology_config_db_mode_get(void);
+
+/*
+ * load_topology_xxx -
+ *
+ * DESCRIPTION: Loads the board topology for the XXX board
+ * INPUT: serdes_map_array - The struct that will contain
+ * the board topology map
+ * OUTPUT: The board topology map.
+ * RETURNS: MV_OK for success
+ * MV_FAIL for failure (a wrong topology mode was read
+ * from the board)
+ */
+
+/* load_topology_db - Loads the board topology for DB Board */
+int load_topology_db(struct serdes_map *serdes_map_array);
+
+/* load_topology_rd - Loads the board topology for RD Board */
+int load_topology_rd(struct serdes_map *serdes_map_array);
+
+/* load_topology_rd_nas - Loads the board topology for RD NAS Board */
+int load_topology_rd_nas(struct serdes_map *serdes_map_array);
+
+/* load_topology_rd_ap - Loads the board topology for RD Ap Board */
+int load_topology_rd_ap(struct serdes_map *serdes_map_array);
+
+/* load_topology_db_ap - Loads the board topology for DB-AP Board */
+int load_topology_db_ap(struct serdes_map *serdes_map_array);
+
+/* load_topology_db_gp - Loads the board topology for DB GP Board */
+int load_topology_db_gp(struct serdes_map *serdes_map_array);
+
+/* load_topology_db_381 - Loads the board topology for 381 DB-BP Board */
+int load_topology_db_381(struct serdes_map *serdes_map_array);
+
+/* load_topology_db_amc - Loads the board topology for DB-AMC Board */
+int load_topology_db_amc(struct serdes_map *serdes_map_array);
+
+/*
+ * hws_update_device_toplogy
+ * DESCRIPTION: Update the default board topology for specific device Id
+ * INPUT:
+ * topology_config_ptr - pointer to the Serdes mapping
+ * topology_mode - topology mode (index)
+ * OUTPUT: None
+ * RRETURNS:
+ * MV_OK - if updating the board topology success
+ * MV_BAD_PARAM - if the input parameter is wrong
+ */
+int hws_update_device_toplogy(struct serdes_map *topology_config_ptr,
+ enum topology_config_db topology_mode);
+
+/*
+ * load_topology_rd_sgmii_usb -
+ *
+ * DESCRIPTION: For RD board check if lane 4 is USB3 or SGMII
+ * INPUT: None
+ * OUTPUT: is_sgmii - return 1 if lane 4 is SGMII
+ * return 0 if lane 4 is USB.
+ * RETURNS: MV_OK for success
+ */
+int load_topology_rd_sgmii_usb(int *is_sgmii);
+
+/*
+ * load_topology_usb_mode_get -
+ *
+ * DESCRIPTION: For DB board check if USB3.0 mode
+ * INPUT: None
+ * OUTPUT: twsi_data - return data read from S@R via I2C
+ * RETURNS: MV_OK for success
+ */
+int load_topology_usb_mode_get(u8 *twsi_data);
+
+#endif /* _HIGHSPEED_TOPOLOGY_SPEC_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "seq_exec.h"
+#include "high_speed_env_spec.h"
+
+#include "../../../drivers/ddr/marvell/a38x/ddr3_init.h"
+
+#if defined(MV_DEBUG_INIT_FULL) || defined(MV_DEBUG)
+#define DB(x) x
+#else
+#define DB(x)
+#endif
+
+/* Array for mapping the operation (write, poll or delay) functions */
+op_execute_func_ptr op_execute_func_arr[] = {
+ write_op_execute,
+ delay_op_execute,
+ poll_op_execute
+};
+
+int write_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx)
+{
+ u32 unit_base_reg, unit_offset, data, mask, reg_data, reg_addr;
+
+ /* Getting write op params from the input parameter */
+ data = params->data[data_arr_idx];
+ mask = params->mask;
+
+ /* an empty operation */
+ if (data == NO_DATA)
+ return MV_OK;
+
+ /* get updated base address since it can be different between Serdes */
+ CHECK_STATUS(hws_get_ext_base_addr(serdes_num, params->unit_base_reg,
+ params->unit_offset,
+ &unit_base_reg, &unit_offset));
+
+ /* Address calculation */
+ reg_addr = unit_base_reg + unit_offset * serdes_num;
+
+#ifdef SEQ_DEBUG
+ printf("Write: 0x%x: 0x%x (mask 0x%x) - ", reg_addr, data, mask);
+#endif
+ /* Reading old value */
+ reg_data = reg_read(reg_addr);
+ reg_data &= (~mask);
+
+ /* Writing new data */
+ data &= mask;
+ reg_data |= data;
+ reg_write(reg_addr, reg_data);
+
+#ifdef SEQ_DEBUG
+ printf(" - 0x%x\n", reg_data);
+#endif
+
+ return MV_OK;
+}
+
+int delay_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx)
+{
+ u32 delay;
+
+ /* Getting delay op params from the input parameter */
+ delay = params->wait_time;
+#ifdef SEQ_DEBUG
+ printf("Delay: %d\n", delay);
+#endif
+ mdelay(delay);
+
+ return MV_OK;
+}
+
+int poll_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx)
+{
+ u32 unit_base_reg, unit_offset, data, mask, num_of_loops, wait_time;
+ u32 poll_counter = 0;
+ u32 reg_addr, reg_data;
+
+ /* Getting poll op params from the input parameter */
+ data = params->data[data_arr_idx];
+ mask = params->mask;
+ num_of_loops = params->num_of_loops;
+ wait_time = params->wait_time;
+
+ /* an empty operation */
+ if (data == NO_DATA)
+ return MV_OK;
+
+ /* get updated base address since it can be different between Serdes */
+ CHECK_STATUS(hws_get_ext_base_addr(serdes_num, params->unit_base_reg,
+ params->unit_offset,
+ &unit_base_reg, &unit_offset));
+
+ /* Address calculation */
+ reg_addr = unit_base_reg + unit_offset * serdes_num;
+
+ /* Polling */
+#ifdef SEQ_DEBUG
+ printf("Poll: 0x%x: 0x%x (mask 0x%x)\n", reg_addr, data, mask);
+#endif
+
+ do {
+ reg_data = reg_read(reg_addr) & mask;
+ poll_counter++;
+ udelay(wait_time);
+ } while ((reg_data != data) && (poll_counter < num_of_loops));
+
+ if ((poll_counter >= num_of_loops) && (reg_data != data)) {
+ DEBUG_INIT_S("poll_op_execute: TIMEOUT\n");
+ return MV_TIMEOUT;
+ }
+
+ return MV_OK;
+}
+
+enum mv_op get_cfg_seq_op(struct op_params *params)
+{
+ if (params->wait_time == 0)
+ return WRITE_OP;
+ else if (params->num_of_loops == 0)
+ return DELAY_OP;
+
+ return POLL_OP;
+}
+
+int mv_seq_exec(u32 serdes_num, u32 seq_id)
+{
+ u32 seq_idx;
+ struct op_params *seq_arr;
+ u32 seq_size;
+ u32 data_arr_idx;
+ enum mv_op curr_op;
+
+ DB(printf("\n### mv_seq_exec ###\n"));
+ DB(printf("seq id: %d\n", seq_id));
+
+ if (hws_is_serdes_active(serdes_num) != 1) {
+ printf("mv_seq_exec_ext:Error: SerDes lane %d is not valid\n",
+ serdes_num);
+ return MV_BAD_PARAM;
+ }
+
+ seq_arr = serdes_seq_db[seq_id].op_params_ptr;
+ seq_size = serdes_seq_db[seq_id].cfg_seq_size;
+ data_arr_idx = serdes_seq_db[seq_id].data_arr_idx;
+
+ DB(printf("seq_size: %d\n", seq_size));
+ DB(printf("data_arr_idx: %d\n", data_arr_idx));
+
+ /* Executing the sequence operations */
+ for (seq_idx = 0; seq_idx < seq_size; seq_idx++) {
+ curr_op = get_cfg_seq_op(&seq_arr[seq_idx]);
+ op_execute_func_arr[curr_op](serdes_num, &seq_arr[seq_idx],
+ data_arr_idx);
+ }
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SEQ_EXEC_H
+#define _SEQ_EXEC_H
+
+#define NA 0xff
+#define DEFAULT_PARAM 0
+#define MV_BOARD_TCLK_ERROR 0xffffffff
+
+#define NO_DATA 0xffffffff
+#define MAX_DATA_ARRAY 5
+#define FIRST_CELL 0
+
+/* Operation types */
+enum mv_op {
+ WRITE_OP,
+ DELAY_OP,
+ POLL_OP,
+};
+
+/* Operation parameters */
+struct op_params {
+ u32 unit_base_reg;
+ u32 unit_offset;
+ u32 mask;
+ u32 data[MAX_DATA_ARRAY]; /* data array */
+ u8 wait_time; /* msec */
+ u16 num_of_loops; /* for polling only */
+};
+
+/*
+ * Sequence parameters. Each sequence contains:
+ * 1. Sequence id.
+ * 2. Sequence size (total amount of operations during the sequence)
+ * 3. a series of operations. operations can be write, poll or delay
+ * 4. index in the data array (the entry where the relevant data sits)
+ */
+struct cfg_seq {
+ struct op_params *op_params_ptr;
+ u8 cfg_seq_size;
+ u8 data_arr_idx;
+};
+
+extern struct cfg_seq serdes_seq_db[];
+
+/*
+ * A generic function type for executing an operation (write, poll or delay)
+ */
+typedef int (*op_execute_func_ptr)(u32 serdes_num, struct op_params *params,
+ u32 data_arr_idx);
+
+/* Specific functions for executing each operation */
+int write_op_execute(u32 serdes_num, struct op_params *params,
+ u32 data_arr_idx);
+int delay_op_execute(u32 serdes_num, struct op_params *params,
+ u32 data_arr_idx);
+int poll_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx);
+enum mv_op get_cfg_seq_op(struct op_params *params);
+int mv_seq_exec(u32 serdes_num, u32 seq_id);
+
+#endif /*_SEQ_EXEC_H*/
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "seq_exec.h"
+#include "sys_env_lib.h"
+
+#include "../../../drivers/ddr/marvell/a38x/ddr3_a38x.h"
+
+#ifdef CONFIG_ARMADA_38X
+enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
+/* 6820 6810 6811 6828 */
+/* PEX_UNIT_ID */ { 4, 3, 3, 4},
+/* ETH_GIG_UNIT_ID */ { 3, 2, 3, 3},
+/* USB3H_UNIT_ID */ { 2, 2, 2, 2},
+/* USB3D_UNIT_ID */ { 1, 1, 1, 1},
+/* SATA_UNIT_ID */ { 2, 2, 2, 4},
+/* QSGMII_UNIT_ID */ { 1, 0, 0, 1},
+/* XAUI_UNIT_ID */ { 0, 0, 0, 0},
+/* RXAUI_UNIT_ID */ { 0, 0, 0, 0}
+};
+#else /* if (CONFIG_ARMADA_39X) */
+enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
+/* 6920 6928 */
+/* PEX_UNIT_ID */ { 4, 4},
+/* ETH_GIG_UNIT_ID */ { 3, 4},
+/* USB3H_UNIT_ID */ { 1, 2},
+/* USB3D_UNIT_ID */ { 0, 1},
+/* SATA_UNIT_ID */ { 0, 4},
+/* QSGMII_UNIT_ID */ { 0, 1},
+/* XAUI_UNIT_ID */ { 1, 1},
+/* RXAUI_UNIT_ID */ { 1, 1}
+};
+#endif
+
+u32 g_dev_id = -1;
+
+u32 mv_board_id_get(void)
+{
+#if defined(CONFIG_DB_88F6820_GP)
+ return DB_GP_68XX_ID;
+#else
+ /*
+ * Return 0 here for custom board as this should not be used
+ * for custom boards.
+ */
+ return 0;
+#endif
+}
+
+u32 mv_board_tclk_get(void)
+{
+ u32 value;
+
+ value = (reg_read(DEVICE_SAMPLE_AT_RESET1_REG) >> 15) & 0x1;
+
+ switch (value) {
+ case (0x0):
+ return 250000000;
+ case (0x1):
+ return 200000000;
+ default:
+ return 0xffffffff;
+ }
+}
+
+u32 mv_board_id_index_get(u32 board_id)
+{
+ /*
+ * Marvell Boards use 0x10 as base for Board ID:
+ * mask MSB to receive index for board ID
+ */
+ return board_id & (MARVELL_BOARD_ID_MASK - 1);
+}
+
+/*
+ * sys_env_suspend_wakeup_check
+ * DESCRIPTION: Reads GPIO input for suspend-wakeup indication.
+ * INPUT: None.
+ * OUTPUT:
+ * RETURNS: u32 indicating suspend wakeup status:
+ * 0 - Not supported,
+ * 1 - supported: read magic word detect wakeup,
+ * 2 - detected wakeup from GPIO.
+ */
+enum suspend_wakeup_status sys_env_suspend_wakeup_check(void)
+{
+ u32 reg, board_id_index, gpio;
+ struct board_wakeup_gpio board_gpio[] = MV_BOARD_WAKEUP_GPIO_INFO;
+
+ board_id_index = mv_board_id_index_get(mv_board_id_get());
+ if (!(sizeof(board_gpio) / sizeof(struct board_wakeup_gpio) >
+ board_id_index)) {
+ printf("\n_failed loading Suspend-Wakeup information (invalid board ID)\n");
+ return SUSPEND_WAKEUP_DISABLED;
+ }
+
+ /*
+ * - Detect if Suspend-Wakeup is supported on current board
+ * - Fetch the GPIO number for wakeup status input indication
+ */
+ if (board_gpio[board_id_index].gpio_num == -1) {
+ /* Suspend to RAM is not supported */
+ return SUSPEND_WAKEUP_DISABLED;
+ } else if (board_gpio[board_id_index].gpio_num == -2) {
+ /*
+ * Suspend to RAM is supported but GPIO indication is
+ * not implemented - Skip
+ */
+ return SUSPEND_WAKEUP_ENABLED;
+ } else {
+ gpio = board_gpio[board_id_index].gpio_num;
+ }
+
+ /* Initialize MPP for GPIO (set MPP = 0x0) */
+ reg = reg_read(MPP_CONTROL_REG(MPP_REG_NUM(gpio)));
+ /* reset MPP21 to 0x0, keep rest of MPP settings*/
+ reg &= ~MPP_MASK(gpio);
+ reg_write(MPP_CONTROL_REG(MPP_REG_NUM(gpio)), reg);
+
+ /* Initialize GPIO as input */
+ reg = reg_read(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)));
+ reg |= GPP_MASK(gpio);
+ reg_write(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)), reg);
+
+ /*
+ * Check GPP for input status from PIC: 0 - regular init,
+ * 1 - suspend wakeup
+ */
+ reg = reg_read(GPP_DATA_IN_REG(GPP_REG_NUM(gpio)));
+
+ /* if GPIO is ON: wakeup from S2RAM indication detected */
+ return (reg & GPP_MASK(gpio)) ? SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED :
+ SUSPEND_WAKEUP_DISABLED;
+}
+
+/*
+ * mv_ctrl_dev_id_index_get
+ *
+ * DESCRIPTION: return SOC device index
+ * INPUT: None
+ * OUTPUT: None
+ * RETURN:
+ * return SOC device index
+ */
+u32 sys_env_id_index_get(u32 ctrl_model)
+{
+ switch (ctrl_model) {
+ case MV_6820_DEV_ID:
+ return MV_6820_INDEX;
+ case MV_6810_DEV_ID:
+ return MV_6810_INDEX;
+ case MV_6811_DEV_ID:
+ return MV_6811_INDEX;
+ case MV_6828_DEV_ID:
+ return MV_6828_INDEX;
+ case MV_6920_DEV_ID:
+ return MV_6920_INDEX;
+ case MV_6928_DEV_ID:
+ return MV_6928_INDEX;
+ default:
+ return MV_6820_INDEX;
+ }
+}
+
+u32 sys_env_unit_max_num_get(enum unit_id unit)
+{
+ u32 dev_id_index;
+
+ if (unit >= MAX_UNITS_ID) {
+ printf("%s: Error: Wrong unit type (%u)\n", __func__, unit);
+ return 0;
+ }
+
+ dev_id_index = sys_env_id_index_get(sys_env_model_get());
+ return sys_env_soc_unit_nums[unit][dev_id_index];
+}
+
+/*
+ * sys_env_model_get
+ * DESCRIPTION: Returns 16bit describing the device model (ID) as defined
+ * in Vendor ID configuration register
+ */
+u16 sys_env_model_get(void)
+{
+ u32 default_ctrl_id, ctrl_id = reg_read(DEV_ID_REG);
+ ctrl_id = (ctrl_id & (DEV_ID_REG_DEVICE_ID_MASK)) >>
+ DEV_ID_REG_DEVICE_ID_OFFS;
+
+ switch (ctrl_id) {
+ case MV_6820_DEV_ID:
+ case MV_6810_DEV_ID:
+ case MV_6811_DEV_ID:
+ case MV_6828_DEV_ID:
+ case MV_6920_DEV_ID:
+ case MV_6928_DEV_ID:
+ return ctrl_id;
+ default:
+ /* Device ID Default for A38x: 6820 , for A39x: 6920 */
+ #ifdef CONFIG_ARMADA_38X
+ default_ctrl_id = MV_6820_DEV_ID;
+ #else
+ default_ctrl_id = MV_6920_DEV_ID;
+ #endif
+ printf("%s: Error retrieving device ID (%x), using default ID = %x\n",
+ __func__, ctrl_id, default_ctrl_id);
+ return default_ctrl_id;
+ }
+}
+
+/*
+ * sys_env_device_id_get
+ * DESCRIPTION: Returns enum (0..7) index of the device model (ID)
+ */
+u32 sys_env_device_id_get(void)
+{
+ char *device_id_str[7] = {
+ "6810", "6820", "6811", "6828", "NONE", "6920", "6928"
+ };
+
+ if (g_dev_id != -1)
+ return g_dev_id;
+
+ g_dev_id = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
+ g_dev_id = g_dev_id >> SAR_DEV_ID_OFFS & SAR_DEV_ID_MASK;
+ printf("Detected Device ID %s\n", device_id_str[g_dev_id]);
+
+ return g_dev_id;
+}
+
+#ifdef MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI
+/*
+* sys_env_get_topology_update_info
+* DESCRIPTION: Read TWSI fields to update DDR topology structure
+* INPUT: None
+* OUTPUT: None, 0 means no topology update
+* RETURN:
+* Bit mask of changes topology features
+*/
+#ifdef CONFIG_ARMADA_39X
+u32 sys_env_get_topology_update_info(
+ struct topology_update_info *tui)
+{
+ /* Set 16/32 bit configuration*/
+ tui->update_width = 1;
+ tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
+
+#ifdef CONFIG_DDR3
+ if (1 == sys_env_config_get(MV_CONFIG_DDR_BUSWIDTH)) {
+ /* 16bit */
+ tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
+ } else {
+ /* 32bit */
+ tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
+ }
+#endif
+
+ /* Set ECC/no ECC bit configuration */
+ tui->update_ecc = 1;
+ if (0 == sys_env_config_get(MV_CONFIG_DDR_ECC_EN)) {
+ /* NO ECC */
+ tui->ecc = TOPOLOGY_UPDATE_ECC_OFF;
+ } else {
+ /* ECC */
+ tui->ecc = TOPOLOGY_UPDATE_ECC_ON;
+ }
+
+ tui->update_ecc_pup3_mode = 1;
+ tui->ecc_pup_mode_offset = TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
+
+ return MV_OK;
+}
+#else /*CONFIG_ARMADA_38X*/
+u32 sys_env_get_topology_update_info(
+ struct topology_update_info *tui)
+{
+ u8 config_val;
+ u8 ecc_mode[A38X_MV_MAX_MARVELL_BOARD_ID -
+ A38X_MARVELL_BOARD_ID_BASE][5] = TOPOLOGY_UPDATE;
+ u8 board_id = mv_board_id_get();
+ int ret;
+
+ board_id = mv_board_id_index_get(board_id);
+ ret = i2c_read(EEPROM_I2C_ADDR, 0, 2, &config_val, 1);
+ if (ret) {
+ DEBUG_INIT_S("sys_env_get_topology_update_info: TWSI Read failed\n");
+ return 0;
+ }
+
+ /* Set 16/32 bit configuration */
+ if ((0 == (config_val & DDR_SATR_CONFIG_MASK_WIDTH)) ||
+ (ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT] == 0)) {
+ /* 16bit by SatR of 32bit mode not supported for the board */
+ if ((ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT] != 0)) {
+ tui->update_width = 1;
+ tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
+ }
+ } else {
+ /* 32bit */
+ if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT] != 0)) {
+ tui->update_width = 1;
+ tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
+ }
+ }
+
+ /* Set ECC/no ECC bit configuration */
+ if (0 == (config_val & DDR_SATR_CONFIG_MASK_ECC)) {
+ /* NO ECC */
+ tui->update_ecc = 1;
+ tui->ecc = TOPOLOGY_UPDATE_ECC_OFF;
+ } else {
+ /* ECC */
+ if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0) ||
+ (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] != 0) ||
+ (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC_PUP3] != 0)) {
+ tui->update_ecc = 1;
+ tui->ecc = TOPOLOGY_UPDATE_ECC_ON;
+ }
+ }
+
+ /* Set ECC pup bit configuration */
+ if (0 == (config_val & DDR_SATR_CONFIG_MASK_ECC_PUP)) {
+ /* PUP3 */
+ /*
+ * Check if PUP3 configuration allowed, if not -
+ * force Pup4 with warning message
+ */
+ if ((ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC_PUP3] != 0)) {
+ if (tui->width == TOPOLOGY_UPDATE_WIDTH_16BIT) {
+ tui->update_ecc_pup3_mode = 1;
+ tui->ecc_pup_mode_offset =
+ TOPOLOGY_UPDATE_ECC_OFFSET_PUP3;
+ } else {
+ if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0)) {
+ printf("DDR Topology Update: ECC PUP3 not valid for 32bit mode, force ECC in PUP4\n");
+ tui->update_ecc_pup3_mode = 1;
+ tui->ecc_pup_mode_offset =
+ TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
+ }
+ }
+ } else {
+ if (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] !=
+ 0) {
+ printf("DDR Topology Update: ECC on PUP3 not supported, force ECC on PUP4\n");
+ tui->update_ecc_pup3_mode = 1;
+ tui->ecc_pup_mode_offset =
+ TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
+ }
+ }
+ } else {
+ /* PUP4 */
+ if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0) ||
+ (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] != 0)) {
+ tui->update_ecc_pup3_mode = 1;
+ tui->ecc_pup_mode_offset =
+ TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
+ }
+ }
+
+ /*
+ * Check for forbidden ECC mode,
+ * if by default width and pup selection set 32bit ECC mode and this
+ * mode not supported for the board - config 16bit with ECC on PUP3
+ */
+ if ((tui->ecc == TOPOLOGY_UPDATE_ECC_ON) &&
+ (tui->width == TOPOLOGY_UPDATE_WIDTH_32BIT)) {
+ if (ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] == 0) {
+ printf("DDR Topology Update: 32bit mode with ECC not allowed on this board, forced 16bit with ECC on PUP3\n");
+ tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
+ tui->update_ecc_pup3_mode = 1;
+ tui->ecc_pup_mode_offset =
+ TOPOLOGY_UPDATE_ECC_OFFSET_PUP3;
+ }
+ }
+
+ return MV_OK;
+}
+#endif /* CONFIG_ARMADA_38X */
+#endif /* MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _SYS_ENV_LIB_H
+#define _SYS_ENV_LIB_H
+
+#include "../../../drivers/ddr/marvell/a38x/ddr3_init.h"
+#include "../../../drivers/ddr/marvell/a38x/ddr3_hws_hw_training.h"
+
+/* Serdes definitions */
+#define COMMON_PHY_BASE_ADDR 0x18300
+
+#define DEVICE_CONFIGURATION_REG0 0x18284
+#define DEVICE_CONFIGURATION_REG1 0x18288
+#define COMMON_PHY_CONFIGURATION1_REG 0x18300
+#define COMMON_PHY_CONFIGURATION2_REG 0x18304
+#define COMMON_PHY_CONFIGURATION4_REG 0x1830c
+#define COMMON_PHY_STATUS1_REG 0x18318
+#define COMMON_PHYS_SELECTORS_REG 0x183fc
+#define SOC_CONTROL_REG1 0x18204
+#define GENERAL_PURPOSE_RESERVED0_REG 0x182e0
+#define GBE_CONFIGURATION_REG 0x18460
+#define DEVICE_SAMPLE_AT_RESET1_REG 0x18600
+#define DEVICE_SAMPLE_AT_RESET2_REG 0x18604
+#define DEV_ID_REG 0x18238
+
+#define CORE_PLL_PARAMETERS_REG 0xe42e0
+#define CORE_PLL_CONFIG_REG 0xe42e4
+
+#define QSGMII_CONTROL_REG1 0x18494
+
+#define DEV_ID_REG_DEVICE_ID_OFFS 16
+#define DEV_ID_REG_DEVICE_ID_MASK 0xffff0000
+
+#define SAR_DEV_ID_OFFS 27
+#define SAR_DEV_ID_MASK 0x7
+
+#define POWER_AND_PLL_CTRL_REG 0xa0004
+#define CALIBRATION_CTRL_REG 0xa0008
+#define DFE_REG0 0xa001c
+#define DFE_REG3 0xa0028
+#define RESET_DFE_REG 0xa0148
+#define LOOPBACK_REG 0xa008c
+#define SYNC_PATTERN_REG 0xa0090
+#define INTERFACE_REG 0xa0094
+#define ISOLATE_REG 0xa0098
+#define MISC_REG 0xa013c
+#define GLUE_REG 0xa0140
+#define GENERATION_DIVIDER_FORCE_REG 0xa0144
+#define PCIE_REG0 0xa0120
+#define LANE_ALIGN_REG0 0xa0124
+#define SQUELCH_FFE_SETTING_REG 0xa0018
+#define G1_SETTINGS_0_REG 0xa0034
+#define G1_SETTINGS_1_REG 0xa0038
+#define G1_SETTINGS_3_REG 0xa0440
+#define G1_SETTINGS_4_REG 0xa0444
+#define G2_SETTINGS_0_REG 0xa003c
+#define G2_SETTINGS_1_REG 0xa0040
+#define G2_SETTINGS_2_REG 0xa00f8
+#define G2_SETTINGS_3_REG 0xa0448
+#define G2_SETTINGS_4_REG 0xa044c
+#define G3_SETTINGS_0_REG 0xa0044
+#define G3_SETTINGS_1_REG 0xa0048
+#define G3_SETTINGS_3_REG 0xa0450
+#define G3_SETTINGS_4_REG 0xa0454
+#define VTHIMPCAL_CTRL_REG 0xa0104
+#define REF_REG0 0xa0134
+#define CAL_REG6 0xa0168
+#define RX_REG2 0xa0184
+#define RX_REG3 0xa0188
+#define PCIE_REG1 0xa0288
+#define PCIE_REG3 0xa0290
+#define LANE_CFG1_REG 0xa0604
+#define LANE_CFG4_REG 0xa0620
+#define LANE_CFG5_REG 0xa0624
+#define GLOBAL_CLK_CTRL 0xa0704
+#define GLOBAL_MISC_CTRL 0xa0718
+#define GLOBAL_CLK_SRC_HI 0xa0710
+
+#define GLOBAL_CLK_CTRL 0xa0704
+#define GLOBAL_MISC_CTRL 0xa0718
+#define GLOBAL_PM_CTRL 0xa0740
+
+/* SATA registers */
+#define SATA_CTRL_REG_IND_ADDR 0xa80a0
+#define SATA_CTRL_REG_IND_DATA 0xa80a4
+
+#define SATA_VENDOR_PORT_0_REG_ADDR 0xa8178
+#define SATA_VENDOR_PORT_1_REG_ADDR 0xa81f8
+#define SATA_VENDOR_PORT_0_REG_DATA 0xa817c
+#define SATA_VENDOR_PORT_1_REG_DATA 0xa81fc
+
+/* Reference clock values and mask */
+#define POWER_AND_PLL_CTRL_REG_100MHZ_VAL 0x0
+#define POWER_AND_PLL_CTRL_REG_25MHZ_VAL_1 0x1
+#define POWER_AND_PLL_CTRL_REG_25MHZ_VAL_2 0x2
+#define POWER_AND_PLL_CTRL_REG_40MHZ_VAL 0x3
+#define GLOBAL_PM_CTRL_REG_25MHZ_VAL 0x7
+#define GLOBAL_PM_CTRL_REG_40MHZ_VAL 0xc
+#define LANE_CFG4_REG_25MHZ_VAL 0x200
+#define LANE_CFG4_REG_40MHZ_VAL 0x300
+
+#define POWER_AND_PLL_CTRL_REG_MASK (~(0x1f))
+#define GLOBAL_PM_CTRL_REG_MASK (~(0xff))
+#define LANE_CFG4_REG_MASK (~(0x1f00))
+
+#define REF_CLK_SELECTOR_VAL_PEX0(reg_val) (reg_val >> 2) & 0x1
+#define REF_CLK_SELECTOR_VAL_PEX1(reg_val) (reg_val >> 3) & 0x1
+#define REF_CLK_SELECTOR_VAL_PEX2(reg_val) (reg_val >> 30) & 0x1
+#define REF_CLK_SELECTOR_VAL_PEX3(reg_val) (reg_val >> 31) & 0x1
+#define REF_CLK_SELECTOR_VAL(reg_val) (reg_val & 0x1)
+
+#define MAX_SELECTOR_VAL 10
+
+/* TWSI addresses */
+/* starting from A38x A0, i2c address of EEPROM is 0x57 */
+#ifdef CONFIG_ARMADA_39X
+#define EEPROM_I2C_ADDR 0x50
+#else
+#define EEPROM_I2C_ADDR (sys_env_device_rev_get() == \
+ MV_88F68XX_Z1_ID ? 0x50 : 0x57)
+#endif
+#define RD_GET_MODE_ADDR 0x4c
+#define DB_GET_MODE_SLM1363_ADDR 0x25
+#define DB_GET_MODE_SLM1364_ADDR 0x24
+#define DB381_GET_MODE_SLM1426_1427_ADDR 0x56
+
+/* DB-BP Board 'SatR' mapping */
+#define SATR_DB_LANE1_MAX_OPTIONS 7
+#define SATR_DB_LANE1_CFG_MASK 0x7
+#define SATR_DB_LANE1_CFG_OFFSET 0
+#define SATR_DB_LANE2_MAX_OPTIONS 4
+#define SATR_DB_LANE2_CFG_MASK 0x38
+#define SATR_DB_LANE2_CFG_OFFSET 3
+
+/* GP Board 'SatR' mapping */
+#define SATR_GP_LANE1_CFG_MASK 0x4
+#define SATR_GP_LANE1_CFG_OFFSET 2
+#define SATR_GP_LANE2_CFG_MASK 0x8
+#define SATR_GP_LANE2_CFG_OFFSET 3
+
+/* For setting MPP2 and MPP3 to be TWSI mode and MPP 0,1 to UART mode */
+#define MPP_CTRL_REG 0x18000
+#define MPP_SET_MASK (~(0xffff))
+#define MPP_SET_DATA (0x1111)
+#define MPP_UART1_SET_MASK (~(0xff000))
+#define MPP_UART1_SET_DATA (0x66000)
+
+#define AVS_DEBUG_CNTR_REG 0xe4124
+#define AVS_DEBUG_CNTR_DEFAULT_VALUE 0x08008073
+
+#define AVS_ENABLED_CONTROL 0xe4130
+#define AVS_LOW_VDD_LIMIT_OFFS 4
+#define AVS_LOW_VDD_LIMIT_MASK (0xff << AVS_LOW_VDD_LIMIT_OFFS)
+#define AVS_LOW_VDD_LIMIT_VAL (0x27 << AVS_LOW_VDD_LIMIT_OFFS)
+
+#define AVS_HIGH_VDD_LIMIT_OFFS 12
+#define AVS_HIGH_VDD_LIMIT_MASK (0xff << AVS_HIGH_VDD_LIMIT_OFFS)
+#define AVS_HIGH_VDD_LIMIT_VAL (0x27 << AVS_HIGH_VDD_LIMIT_OFFS)
+
+/* Board ID numbers */
+#define MARVELL_BOARD_ID_MASK 0x10
+/* Customer boards for A38x */
+#define A38X_CUSTOMER_BOARD_ID_BASE 0x0
+#define A38X_CUSTOMER_BOARD_ID0 (A38X_CUSTOMER_BOARD_ID_BASE + 0)
+#define A38X_CUSTOMER_BOARD_ID1 (A38X_CUSTOMER_BOARD_ID_BASE + 1)
+#define A38X_MV_MAX_CUSTOMER_BOARD_ID (A38X_CUSTOMER_BOARD_ID_BASE + 2)
+#define A38X_MV_CUSTOMER_BOARD_NUM (A38X_MV_MAX_CUSTOMER_BOARD_ID - \
+ A38X_CUSTOMER_BOARD_ID_BASE)
+
+/* Marvell boards for A38x */
+#define A38X_MARVELL_BOARD_ID_BASE 0x10
+#define RD_NAS_68XX_ID (A38X_MARVELL_BOARD_ID_BASE + 0)
+#define DB_68XX_ID (A38X_MARVELL_BOARD_ID_BASE + 1)
+#define RD_AP_68XX_ID (A38X_MARVELL_BOARD_ID_BASE + 2)
+#define DB_AP_68XX_ID (A38X_MARVELL_BOARD_ID_BASE + 3)
+#define DB_GP_68XX_ID (A38X_MARVELL_BOARD_ID_BASE + 4)
+#define DB_BP_6821_ID (A38X_MARVELL_BOARD_ID_BASE + 5)
+#define DB_AMC_6820_ID (A38X_MARVELL_BOARD_ID_BASE + 6)
+#define A38X_MV_MAX_MARVELL_BOARD_ID (A38X_MARVELL_BOARD_ID_BASE + 7)
+#define A38X_MV_MARVELL_BOARD_NUM (A38X_MV_MAX_MARVELL_BOARD_ID - \
+ A38X_MARVELL_BOARD_ID_BASE)
+
+/* Customer boards for A39x */
+#define A39X_CUSTOMER_BOARD_ID_BASE 0x20
+#define A39X_CUSTOMER_BOARD_ID0 (A39X_CUSTOMER_BOARD_ID_BASE + 0)
+#define A39X_CUSTOMER_BOARD_ID1 (A39X_CUSTOMER_BOARD_ID_BASE + 1)
+#define A39X_MV_MAX_CUSTOMER_BOARD_ID (A39X_CUSTOMER_BOARD_ID_BASE + 2)
+#define A39X_MV_CUSTOMER_BOARD_NUM (A39X_MV_MAX_CUSTOMER_BOARD_ID - \
+ A39X_CUSTOMER_BOARD_ID_BASE)
+
+/* Marvell boards for A39x */
+#define A39X_MARVELL_BOARD_ID_BASE 0x30
+#define A39X_DB_69XX_ID (A39X_MARVELL_BOARD_ID_BASE + 0)
+#define A39X_RD_69XX_ID (A39X_MARVELL_BOARD_ID_BASE + 1)
+#define A39X_MV_MAX_MARVELL_BOARD_ID (A39X_MARVELL_BOARD_ID_BASE + 2)
+#define A39X_MV_MARVELL_BOARD_NUM (A39X_MV_MAX_MARVELL_BOARD_ID - \
+ A39X_MARVELL_BOARD_ID_BASE)
+
+#ifdef CONFIG_ARMADA_38X
+#define CUTOMER_BOARD_ID_BASE A38X_CUSTOMER_BOARD_ID_BASE
+#define CUSTOMER_BOARD_ID0 A38X_CUSTOMER_BOARD_ID0
+#define CUSTOMER_BOARD_ID1 A38X_CUSTOMER_BOARD_ID1
+#define MV_MAX_CUSTOMER_BOARD_ID A38X_MV_MAX_CUSTOMER_BOARD_ID
+#define MV_CUSTOMER_BOARD_NUM A38X_MV_CUSTOMER_BOARD_NUM
+#define MARVELL_BOARD_ID_BASE A38X_MARVELL_BOARD_ID_BASE
+#define MV_MAX_MARVELL_BOARD_ID A38X_MV_MAX_MARVELL_BOARD_ID
+#define MV_MARVELL_BOARD_NUM A38X_MV_MARVELL_BOARD_NUM
+#define MV_DEFAULT_BOARD_ID DB_68XX_ID
+#define MV_DEFAULT_DEVICE_ID MV_6811
+#elif defined(CONFIG_ARMADA_39X)
+#define CUTOMER_BOARD_ID_BASE A39X_CUSTOMER_BOARD_ID_BASE
+#define CUSTOMER_BOARD_ID0 A39X_CUSTOMER_BOARD_ID0
+#define CUSTOMER_BOARD_ID1 A39X_CUSTOMER_BOARD_ID1
+#define MV_MAX_CUSTOMER_BOARD_ID A39X_MV_MAX_CUSTOMER_BOARD_ID
+#define MV_CUSTOMER_BOARD_NUM A39X_MV_CUSTOMER_BOARD_NUM
+#define MARVELL_BOARD_ID_BASE A39X_MARVELL_BOARD_ID_BASE
+#define MV_MAX_MARVELL_BOARD_ID A39X_MV_MAX_MARVELL_BOARD_ID
+#define MV_MARVELL_BOARD_NUM A39X_MV_MARVELL_BOARD_NUM
+#define MV_DEFAULT_BOARD_ID A39X_DB_69XX_ID
+#define MV_DEFAULT_DEVICE_ID MV_6920
+#endif
+
+#define MV_INVALID_BOARD_ID 0xffffffff
+
+/* device revesion */
+#define DEV_VERSION_ID_REG 0x1823c
+#define REVISON_ID_OFFS 8
+#define REVISON_ID_MASK 0xf00
+
+/* A38x revisions */
+#define MV_88F68XX_Z1_ID 0x0
+#define MV_88F68XX_A0_ID 0x4
+/* A39x revisions */
+#define MV_88F69XX_Z1_ID 0x2
+
+#define MPP_CONTROL_REG(id) (0x18000 + (id * 4))
+#define GPP_DATA_OUT_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x00)
+#define GPP_DATA_OUT_EN_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x04)
+#define GPP_DATA_IN_REG(grp) (MV_GPP_REGS_BASE(grp) + 0x10)
+#define MV_GPP_REGS_BASE(unit) (0x18100 + ((unit) * 0x40))
+
+#define MPP_REG_NUM(GPIO_NUM) (GPIO_NUM / 8)
+#define MPP_MASK(GPIO_NUM) (0xf << 4 * (GPIO_NUM - \
+ (MPP_REG_NUM(GPIO_NUM) * 8)));
+#define GPP_REG_NUM(GPIO_NUM) (GPIO_NUM / 32)
+#define GPP_MASK(GPIO_NUM) (1 << GPIO_NUM % 32)
+
+/* device ID */
+/* Armada 38x Family */
+#define MV_6810_DEV_ID 0x6810
+#define MV_6811_DEV_ID 0x6811
+#define MV_6820_DEV_ID 0x6820
+#define MV_6828_DEV_ID 0x6828
+/* Armada 39x Family */
+#define MV_6920_DEV_ID 0x6920
+#define MV_6928_DEV_ID 0x6928
+
+enum {
+ MV_6810,
+ MV_6820,
+ MV_6811,
+ MV_6828,
+ MV_NONE,
+ MV_6920,
+ MV_6928,
+ MV_MAX_DEV_ID,
+};
+
+#define MV_6820_INDEX 0
+#define MV_6810_INDEX 1
+#define MV_6811_INDEX 2
+#define MV_6828_INDEX 3
+
+#define MV_6920_INDEX 0
+#define MV_6928_INDEX 1
+
+#ifdef CONFIG_ARMADA_38X
+#define MAX_DEV_ID_NUM 4
+#else
+#define MAX_DEV_ID_NUM 2
+#endif
+
+#define MV_6820_INDEX 0
+#define MV_6810_INDEX 1
+#define MV_6811_INDEX 2
+#define MV_6828_INDEX 3
+#define MV_6920_INDEX 0
+#define MV_6928_INDEX 1
+
+enum unit_id {
+ PEX_UNIT_ID,
+ ETH_GIG_UNIT_ID,
+ USB3H_UNIT_ID,
+ USB3D_UNIT_ID,
+ SATA_UNIT_ID,
+ QSGMII_UNIT_ID,
+ XAUI_UNIT_ID,
+ RXAUI_UNIT_ID,
+ MAX_UNITS_ID
+};
+
+struct board_wakeup_gpio {
+ u32 board_id;
+ int gpio_num;
+};
+
+enum suspend_wakeup_status {
+ SUSPEND_WAKEUP_DISABLED,
+ SUSPEND_WAKEUP_ENABLED,
+ SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED,
+};
+
+/*
+ * GPIO status indication for Suspend Wakeup:
+ * If suspend to RAM is supported and GPIO inidcation is implemented,
+ * set the gpio number
+ * If suspend to RAM is supported but GPIO indication is not implemented
+ * set '-2'
+ * If suspend to RAM is not supported set '-1'
+ */
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+#ifdef CONFIG_ARMADA_38X
+#define MV_BOARD_WAKEUP_GPIO_INFO { \
+ {A38X_CUSTOMER_BOARD_ID0, -1 }, \
+ {A38X_CUSTOMER_BOARD_ID0, -1 }, \
+};
+#else
+#define MV_BOARD_WAKEUP_GPIO_INFO { \
+ {A39X_CUSTOMER_BOARD_ID0, -1 }, \
+ {A39X_CUSTOMER_BOARD_ID0, -1 }, \
+};
+#endif /* CONFIG_ARMADA_38X */
+
+#else
+
+#ifdef CONFIG_ARMADA_38X
+#define MV_BOARD_WAKEUP_GPIO_INFO { \
+ {RD_NAS_68XX_ID, -2 }, \
+ {DB_68XX_ID, -1 }, \
+ {RD_AP_68XX_ID, -2 }, \
+ {DB_AP_68XX_ID, -2 }, \
+ {DB_GP_68XX_ID, -2 }, \
+ {DB_BP_6821_ID, -2 }, \
+ {DB_AMC_6820_ID, -2 }, \
+};
+#else
+#define MV_BOARD_WAKEUP_GPIO_INFO { \
+ {A39X_RD_69XX_ID, -1 }, \
+ {A39X_DB_69XX_ID, -1 }, \
+};
+#endif /* CONFIG_ARMADA_38X */
+#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
+
+u32 mv_board_tclk_get(void);
+u32 mv_board_id_get(void);
+u32 mv_board_id_index_get(u32 board_id);
+u32 sys_env_unit_max_num_get(enum unit_id unit);
+enum suspend_wakeup_status sys_env_suspend_wakeup_check(void);
+u8 sys_env_device_rev_get(void);
+u32 sys_env_device_id_get(void);
+u16 sys_env_model_get(void);
+struct dlb_config *sys_env_dlb_config_ptr_get(void);
+u32 sys_env_get_topology_update_info(
+ struct topology_update_info *topology_update_info);
+u32 sys_env_get_cs_ena_from_reg(void);
+
+#endif /* _SYS_ENV_LIB_H */
#ifndef __HIGHSPEED_ENV_SPEC_H
#define __HIGHSPEED_ENV_SPEC_H
-#include "../../../drivers/ddr/mvebu/ddr3_hw_training.h"
+#include "../../../drivers/ddr/marvell/axp/ddr3_hw_training.h"
typedef enum {
SERDES_UNIT_UNCONNECTED = 0x0,
u32 spl_boot_device(void)
{
- /* Right now only booting via SPI NOR flash is supported */
+#if defined(CONFIG_SPL_SPI_FLASH_SUPPORT)
return BOOT_DEVICE_SPI;
+#endif
+#if defined(CONFIG_SPL_MMC_SUPPORT)
+ return BOOT_DEVICE_MMC1;
+#endif
}
+#ifdef CONFIG_SPL_MMC_SUPPORT
+u32 spl_boot_mode(void)
+{
+ return MMCSD_MODE_RAW;
+}
+#endif
+
void board_init_f(ulong dummy)
{
/* Set global data pointer */
/* Linux expects the internal registers to be at 0xf1000000 */
arch_cpu_init();
+ /*
+ * Pin muxing needs to be done before UART output, since
+ * on A38x the UART pins need some re-muxing for output
+ * to work.
+ */
+ board_early_init_f();
+
preloader_console_init();
+ timer_init();
+
/* First init the serdes PHY's */
serdes_phy_config();
#define timestamp gd->arch.tbl
#define lastdec gd->arch.lastinc
+static int init_done;
+
/* Timer reload and current value registers */
struct kwtmr_val {
u32 reload; /* Timer reload reg */
*/
int timer_init(void)
{
+ /* Only init the timer once */
+ if (init_done)
+ return 0;
+ init_done = 1;
+
/* load value into timer */
writel(TIMER_LOAD_VAL, CNTMR_RELOAD_REG(UBOOT_CNTR));
writel(TIMER_LOAD_VAL, CNTMR_VAL_REG(UBOOT_CNTR));
if TEGRA
+config TEGRA_ARMV7_COMMON
+ bool "Tegra 32-bit"
+ select SUPPORT_SPL
+ select SPL
+ select OF_CONTROL
+ select SPL_DISABLE_OF_CONTROL
+ select CPU_V7
+ select DM
+ select DM_SPI_FLASH
+ select DM_SERIAL
+ select DM_I2C
+ select DM_SPI
+ select DM_GPIO
+
choice
prompt "Tegra SoC select"
optional
config TEGRA20
bool "Tegra20 family"
+ select TEGRA_ARMV7_COMMON
config TEGRA30
bool "Tegra30 family"
+ select TEGRA_ARMV7_COMMON
config TEGRA114
bool "Tegra114 family"
+ select TEGRA_ARMV7_COMMON
config TEGRA124
bool "Tegra124 family"
+ select TEGRA_ARMV7_COMMON
+
+config TEGRA210
+ bool "Tegra210 family"
+ select OF_CONTROL
+ select ARM64
+ select DM
+ select DM_SPI_FLASH
+ select DM_SERIAL
+ select DM_I2C
+ select DM_SPI
+ select DM_GPIO
endchoice
source "arch/arm/mach-tegra/tegra30/Kconfig"
source "arch/arm/mach-tegra/tegra114/Kconfig"
source "arch/arm/mach-tegra/tegra124/Kconfig"
+source "arch/arm/mach-tegra/tegra210/Kconfig"
endif
#
-# (C) Copyright 2010,2011 Nvidia Corporation.
+# (C) Copyright 2010-2015 Nvidia Corporation.
#
# (C) Copyright 2000-2008
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
obj-y += powergate.o
obj-y += xusb-padctl.o
obj-$(CONFIG_DISPLAY_CPUINFO) += sys_info.o
+#TCW Fix this to use a common config switch (CONFIG_LOCK_VPR?)
obj-$(CONFIG_TEGRA124) += vpr.o
+obj-$(CONFIG_TEGRA210) += vpr.o
obj-$(CONFIG_TEGRA_CLOCK_SCALING) += emc.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_TEGRA30) += tegra30/
obj-$(CONFIG_TEGRA114) += tegra114/
obj-$(CONFIG_TEGRA124) += tegra124/
+obj-$(CONFIG_TEGRA210) += tegra210/
/*
-* (C) Copyright 2010-2014
+* (C) Copyright 2010-2015
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
return TEGRA_SOC_T124;
}
break;
+ case CHIPID_TEGRA210:
+ switch (sku_id) {
+ case SKU_ID_T210_ENG:
+ default:
+ return TEGRA_SOC_T210;
+ }
+ break;
}
/* unknown chip/sku id */
return TEGRA_SOC_UNKNOWN;
}
+#ifndef CONFIG_ARM64
static void enable_scu(void)
{
struct scu_ctlr *scu = (struct scu_ctlr *)NV_PA_ARM_PERIPHBASE;
* on BCTs for currently supported SoCs, which are locked down.
* If this changes in new chips, we can revisit this algorithm.
*/
-
- u32 bct_start, odmdata;
+ unsigned long bct_start;
+ u32 odmdata;
bct_start = readl(NV_PA_BASE_SRAM + NVBOOTINFOTABLE_BCTPTR);
odmdata = readl(bct_start + BCT_ODMDATA_OFFSET);
/* init vpr */
config_vpr();
}
+#endif
/*
- * (C) Copyright 2010-2014
+ * (C) Copyright 2010-2015
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <spl.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/funcmux.h>
#include <asm/arch-tegra/sys_proto.h>
#include <asm/arch-tegra/warmboot.h>
+void save_boot_params_ret(void);
+
DECLARE_GLOBAL_DATA_PTR;
enum {
UART_COUNT = 5,
};
+static bool from_spl __attribute__ ((section(".data")));
+
+#ifndef CONFIG_SPL_BUILD
+void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3)
+{
+ from_spl = r0 != UBOOT_NOT_LOADED_FROM_SPL;
+ save_boot_params_ret();
+}
+#endif
+
+bool spl_was_boot_source(void)
+{
+ return from_spl;
+}
+
#if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
#if !defined(CONFIG_TEGRA124)
#error tegra_cpu_is_non_secure has only been validated on Tegra124
-1,
FUNCMUX_UART4_GMI, /* UARTD */
-1,
-#else /* Tegra124 */
+#elif defined(CONFIG_TEGRA124)
FUNCMUX_UART1_KBC, /* UARTA */
-1,
-1,
FUNCMUX_UART4_GPIO, /* UARTD */
-1,
+#else /* Tegra210 */
+ FUNCMUX_UART1_UART1, /* UARTA */
+ -1,
+ -1,
+ FUNCMUX_UART4_UART4, /* UARTD */
+ -1,
#endif
};
setup_uarts(uart_ids);
}
-#ifndef CONFIG_SYS_DCACHE_OFF
+#if !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_ARM64)
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
int board_early_init_f(void)
{
+ /* Do any special system timer/TSC setup */
+#if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
+ if (!tegra_cpu_is_non_secure())
+#endif
+ arch_timer_init();
+
pinmux_init();
board_init_uart_f();
#endif /* T30 */
}
#endif /* MMC */
+
+#ifdef CONFIG_ARM64
+/*
+ * Most hardware on 64-bit Tegra is still restricted to DMA to the lower
+ * 32-bits of the physical address space. Cap the maximum usable RAM area
+ * at 4 GiB to avoid DMA buffers from being allocated beyond the 32-bit
+ * boundary that most devices can address.
+ */
+ulong board_get_usable_ram_top(ulong total_size)
+{
+ if (gd->ram_top > 0x100000000)
+ return 0x100000000;
+
+ return gd->ram_top;
+}
+#endif
#include <asm/arch-tegra/ap.h>
#include <asm/arch/gp_padctrl.h>
+#ifndef CONFIG_ARM64
void config_cache(void)
{
u32 reg = 0;
reg |= 2;
asm("mcr p15, 1, %0, c9, c0, 2" : : "r" (reg));
}
+#endif
/*
- * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
data = readl(&pll->pll_misc);
*cpcon = (data & PLL_CPCON_MASK) >> PLL_CPCON_SHIFT;
*lfcon = (data & PLL_LFCON_MASK) >> PLL_LFCON_SHIFT;
-
+#if defined(CONFIG_TEGRA210)
+ /* T210 PLLU uses KCP/KVCO instead of CPCON/LFCON */
+ *cpcon = (data & PLLU_KCP_MASK) >> PLLU_KCP_SHIFT;
+ *lfcon = (data & PLLU_KVCO_MASK) >> PLLU_KVCO_SHIFT;
+#endif
return 0;
}
* - same fields are always mapped at same offsets, except DCCON
* - DCCON is always 0, doesn't conflict
* - M,N, P of PLLP values are ignored for PLLP
+ * NOTE: Above is no longer true with T210 - TBD: FIX THIS
*/
misc_data = (cpcon << PLL_CPCON_SHIFT) | (lfcon << PLL_LFCON_SHIFT);
+#if defined(CONFIG_TEGRA210)
+ /* T210 PLLU uses KCP/KVCO instead of cpcon/lfcon */
+ if (clkid == CLOCK_ID_USB) {
+ /* preserve EN_LOCKDET, set by default */
+ misc_data = readl(&pll->pll_misc);
+ misc_data |= (cpcon << PLLU_KCP_SHIFT) |
+ (lfcon << PLLU_KVCO_SHIFT);
+ }
+#endif
data = (divm << PLL_DIVM_SHIFT) | (divn << PLL_DIVN_SHIFT) |
(0 << PLL_BYPASS_SHIFT) | (1 << PLL_ENABLE_SHIFT);
if (clkid == CLOCK_ID_USB)
+#if defined(CONFIG_TEGRA210)
+ data |= divp << PLLU_DIVP_SHIFT;
+#else
data |= divp << PLLU_VCO_FREQ_SHIFT;
+#endif
else
data |= divp << PLL_DIVP_SHIFT;
if (pll) {
/* Set cpcon to PLL_MISC */
misc_reg = readl(&pll->pll_misc);
+#if !defined(CONFIG_TEGRA210)
misc_reg &= ~PLL_CPCON_MASK;
misc_reg |= cpcon << PLL_CPCON_SHIFT;
+#else
+ /* T210 uses KCP instead, use the most common bit shift (PLLA/U/D2) */
+ misc_reg &= ~PLLU_KCP_MASK;
+ misc_reg |= cpcon << PLLU_KCP_SHIFT;
+#endif
+
writel(misc_reg, &pll->pll_misc);
/* Enable PLL */
debug("PLLC = %d\n", pll_rate[CLOCK_ID_CGENERAL]);
debug("PLLD = %d\n", pll_rate[CLOCK_ID_DISPLAY]);
debug("PLLX = %d\n", pll_rate[CLOCK_ID_XCPU]);
-
- /* Do any special system timer/TSC setup */
-#if defined(CONFIG_TEGRA_SUPPORT_NON_SECURE)
- if (!tegra_cpu_is_non_secure())
-#endif
- arch_timer_init();
}
static void set_avp_clock_source(u32 src)
/*
* This function is useful on Tegra30, and any later SoCs that have compatible
* PLLP configuration registers.
+ * NOTE: Not used on Tegra210 - see tegra210_setup_pllp in T210 clock.c
*/
void tegra30_set_up_pllp(void)
{
/*
- * Copyright (c) 2010-2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
{
struct apb_misc_gp_ctlr *gp;
uint rev;
+ debug("%s entry\n", __func__);
gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;
break;
case CHIPID_TEGRA30:
case CHIPID_TEGRA114:
+ case CHIPID_TEGRA124:
+ case CHIPID_TEGRA210:
default:
return 4;
break;
{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */
{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */
},
+
+ /*
+ * T210: 700 MHz
+ *
+ * Register Field Bits Width
+ * ------------------------------
+ * PLLX_BASE p 24:20 5
+ * PLLX_BASE n 15: 8 8
+ * PLLX_BASE m 7: 0 8
+ */
+ {
+ { .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz = 702 MHz*/
+ { .n = 73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz = 700.8 MHz*/
+ { .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz = 696 MHz*/
+ { .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz = 702 MHz*/
+ },
};
static inline void pllx_set_iddq(void)
{
-#if defined(CONFIG_TEGRA124)
+#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210)
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
u32 reg;
+ debug("%s entry\n", __func__);
/* Disable IDDQ */
reg = readl(&clkrst->crc_pllx_misc3);
{
int chip = tegra_get_chip();
u32 reg;
+ debug("%s entry\n", __func__);
/* If PLLX is already enabled, just return */
if (readl(&pll->pll_base) & PLL_ENABLE_MASK) {
- debug("pllx_set_rate: PLLX already enabled, returning\n");
+ debug("%s: PLLX already enabled, returning\n", __func__);
return 0;
}
- debug(" pllx_set_rate entry\n");
-
pllx_set_iddq();
/* Set BYPASS, m, n and p to PLLX_BASE */
reg = readl(&pll->pll_base);
reg &= ~PLL_BYPASS_MASK;
writel(reg, &pll->pll_base);
- debug("pllx_set_rate: base = 0x%08X\n", reg);
+ debug("%s: base = 0x%08X\n", __func__, reg);
/* Set lock_enable to PLLX_MISC */
reg = readl(&pll->pll_misc);
reg |= PLL_LOCK_ENABLE_MASK;
writel(reg, &pll->pll_misc);
- debug("pllx_set_rate: misc = 0x%08X\n", reg);
+ debug("%s: misc = 0x%08X\n", __func__, reg);
/* Enable PLLX last, once it's all configured */
reg = readl(&pll->pll_base);
reg |= PLL_ENABLE_MASK;
writel(reg, &pll->pll_base);
- debug("pllx_set_rate: base final = 0x%08X\n", reg);
+ debug("%s: base final = 0x%08X\n", __func__, reg);
return 0;
}
int soc_type, sku_info, chip_sku;
enum clock_osc_freq osc;
struct clk_pll_table *sel;
-
- debug("init_pllx entry\n");
+ debug("%s entry\n", __func__);
/* get SOC (chip) type */
soc_type = tegra_get_chip();
- debug(" init_pllx: SoC = 0x%02X\n", soc_type);
+ debug("%s: SoC = 0x%02X\n", __func__, soc_type);
/* get SKU info */
sku_info = tegra_get_sku_info();
- debug(" init_pllx: SKU info byte = 0x%02X\n", sku_info);
+ debug("%s: SKU info byte = 0x%02X\n", __func__, sku_info);
/* get chip SKU, combo of the above info */
chip_sku = tegra_get_chip_sku();
- debug(" init_pllx: Chip SKU = %d\n", chip_sku);
+ debug("%s: Chip SKU = %d\n", __func__, chip_sku);
/* get osc freq */
osc = clock_get_osc_freq();
- debug(" init_pllx: osc = %d\n", osc);
+ debug("%s: osc = %d\n", __func__, osc);
/* set pllx */
sel = &tegra_pll_x_table[chip_sku][osc];
{
struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
u32 clk;
+ debug("%s entry\n", __func__);
/*
* NOTE:
{
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
u32 reg;
+ debug("%s entry\n", __func__);
/* Remove the clamps on the CPU I/O signals */
reg = readl(&pmc->pmc_remove_clamping);
struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
u32 reg;
int timeout = IO_STABILIZATION_DELAY;
+ debug("%s entry\n", __func__);
if (!is_cpu_powered()) {
/* Toggle the CPU power state (OFF -> ON) */
int num_cpus = get_num_cpus();
int cpu;
- debug("reset_a9_cpu entry\n");
+ debug("%s entry\n", __func__);
/* Hold CPUs 1 onwards in reset, and CPU 0 if asked */
for (cpu = 1; cpu < num_cpus; cpu++)
reset_cmplx_set_enable(cpu, mask, 1);
{
u32 rst, src = 2;
- debug("clock_enable_coresight entry\n");
+ debug("%s entry\n", __func__);
clock_set_enable(PERIPH_ID_CORESIGHT, enable);
reset_set_enable(PERIPH_ID_CORESIGHT, !enable);
void halt_avp(void)
{
+ debug("%s entry\n", __func__);
+
for (;;) {
writel(HALT_COP_EVENT_JTAG | (FLOW_MODE_STOP << 29),
FLOW_CTLR_HALT_COP_EVENTS);
/*
- * (C) Copyright 2010-2014
+ * (C) Copyright 2010-2015
* NVIDIA Corporation <www.nvidia.com>
*
* SPDX-License-Identifier: GPL-2.0+
#define NVBL_PLLP_KHZ 216000
#define CSITE_KHZ 144000
#elif defined(CONFIG_TEGRA30) || defined(CONFIG_TEGRA114) || \
- defined(CONFIG_TEGRA124)
+ defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210)
#define NVBL_PLLP_KHZ 408000
#define CSITE_KHZ 204000
#else
#define PG_UP_TAG_0_PID_CPU 0x55555555 /* CPU aka "a9" aka "mpcore" */
#define PG_UP_TAG_0 0x0
-#define CORESIGHT_UNLOCK 0xC5ACCE55;
+#define CORESIGHT_UNLOCK 0xC5ACCE55
#define EXCEP_VECTOR_CPU_RESET_VECTOR (NV_PA_EVP_BASE + 0x100)
#define CSITE_CPU_DBG0_LAR (NV_PA_CSITE_BASE + 0x10FB0)
#define SIMPLE_PLLX (CLOCK_ID_XCPU - CLOCK_ID_FIRST_SIMPLE)
+/* SB_AA64_RESET_LOW and _HIGH defines for CPU reset vector */
+#define SB_AA64_RESET_LOW 0x6000C230
+#define SB_AA64_RESET_HIGH 0x6000C234
+
struct clk_pll_table {
u16 n;
u16 m;
#include <config.h>
#include <linux/linkage.h>
+#ifdef CONFIG_ARM64
+ .align 5
+ENTRY(reset_cpu)
+ /* get address for global reset register */
+ ldr x1, =PRM_RSTCTRL
+ ldr w3, [x1]
+ /* force reset */
+ orr w3, w3, #0x10
+ str w3, [x1]
+ mov w0, w0
+1:
+ b 1b
+ENDPROC(reset_cpu)
+#else
.align 5
ENTRY(reset_cpu)
ldr r1, rstctl @ get addr for global reset
rstctl:
.word PRM_RSTCTRL
ENDPROC(reset_cpu)
+#endif
(((hsm) >= PMUX_HSM_DISABLE) && ((hsm) <= PMUX_HSM_ENABLE))
#endif
-#define _R(offset) (u32 *)(NV_PA_APB_MISC_BASE + (offset))
+#define _R(offset) (u32 *)((unsigned long)NV_PA_APB_MISC_BASE + (offset))
#if defined(CONFIG_TEGRA20)
--- /dev/null
+if TEGRA210
+
+choice
+ prompt "Tegra210 board select"
+
+config TARGET_P2571
+ bool "NVIDIA Tegra210 P2571 base board"
+ help
+ P2571 is a P2530 married to a P1963 I/O board
+
+endchoice
+
+config SYS_SOC
+ default "tegra210"
+
+source "board/nvidia/p2571/Kconfig"
+
+endif
--- /dev/null
+#
+# (C) Copyright 2013-2015
+# NVIDIA Corporation <www.nvidia.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += clock.o
+obj-y += funcmux.o
+obj-y += pinmux.o
+obj-y += xusb-padctl.o
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Tegra210 Clock control functions */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sysctr.h>
+#include <asm/arch/tegra.h>
+#include <asm/arch-tegra/clk_rst.h>
+#include <asm/arch-tegra/timer.h>
+#include <div64.h>
+#include <fdtdec.h>
+
+/*
+ * Clock types that we can use as a source. The Tegra210 has muxes for the
+ * peripheral clocks, and in most cases there are four options for the clock
+ * source. This gives us a clock 'type' and exploits what commonality exists
+ * in the device.
+ *
+ * Letters are obvious, except for T which means CLK_M, and S which means the
+ * clock derived from 32KHz. Beware that CLK_M (also called OSC in the
+ * datasheet) and PLL_M are different things. The former is the basic
+ * clock supplied to the SOC from an external oscillator. The latter is the
+ * memory clock PLL.
+ *
+ * See definitions in clock_id in the header file.
+ */
+enum clock_type_id {
+ CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */
+ CLOCK_TYPE_MCPA, /* and so on */
+ CLOCK_TYPE_MCPT,
+ CLOCK_TYPE_PCM,
+ CLOCK_TYPE_PCMT,
+ CLOCK_TYPE_PDCT,
+ CLOCK_TYPE_ACPT,
+ CLOCK_TYPE_ASPTE,
+ CLOCK_TYPE_PMDACD2T,
+ CLOCK_TYPE_PCST,
+
+ CLOCK_TYPE_PC2CC3M,
+ CLOCK_TYPE_PC2CC3S_T,
+ CLOCK_TYPE_PC2CC3M_T,
+ CLOCK_TYPE_PC2CC3M_T16, /* PC2CC3M_T, but w/16-bit divisor (I2C) */
+ CLOCK_TYPE_MC2CC3P_A,
+ CLOCK_TYPE_M,
+ CLOCK_TYPE_MCPTM2C2C3,
+ CLOCK_TYPE_PC2CC3T_S,
+ CLOCK_TYPE_AC2CC3P_TS2,
+ CLOCK_TYPE_PC01C00_C42C41TC40,
+
+ CLOCK_TYPE_COUNT,
+ CLOCK_TYPE_NONE = -1, /* invalid clock type */
+};
+
+enum {
+ CLOCK_MAX_MUX = 8 /* number of source options for each clock */
+};
+
+/*
+ * Clock source mux for each clock type. This just converts our enum into
+ * a list of mux sources for use by the code.
+ *
+ * Note:
+ * The extra column in each clock source array is used to store the mask
+ * bits in its register for the source.
+ */
+#define CLK(x) CLOCK_ID_ ## x
+static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = {
+ { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_30},
+ { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_30},
+ { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_30},
+ { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_30},
+ { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_30},
+ { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_30},
+ { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_30},
+ { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC),
+ CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_29},
+ { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO),
+ CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE),
+ MASK_BITS_31_29},
+ { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_28},
+
+ /* Additional clock types on Tegra114+ */
+ /* CLOCK_TYPE_PC2CC3M */
+ { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
+ CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_29},
+ /* CLOCK_TYPE_PC2CC3S_T */
+ { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
+ CLK(SFROM32KHZ), CLK(NONE), CLK(OSC), CLK(NONE),
+ MASK_BITS_31_29},
+ /* CLOCK_TYPE_PC2CC3M_T */
+ { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
+ CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE),
+ MASK_BITS_31_29},
+ /* CLOCK_TYPE_PC2CC3M_T, w/16-bit divisor (I2C) */
+ { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
+ CLK(MEMORY), CLK(NONE), CLK(OSC), CLK(NONE),
+ MASK_BITS_31_29},
+ /* CLOCK_TYPE_MC2CC3P_A */
+ { CLK(MEMORY), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
+ CLK(PERIPH), CLK(NONE), CLK(AUDIO), CLK(NONE),
+ MASK_BITS_31_29},
+ /* CLOCK_TYPE_M */
+ { CLK(MEMORY), CLK(NONE), CLK(NONE), CLK(NONE),
+ CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE),
+ MASK_BITS_31_30},
+ /* CLOCK_TYPE_MCPTM2C2C3 */
+ { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC),
+ CLK(MEMORY2), CLK(CGENERAL2), CLK(CGENERAL3), CLK(NONE),
+ MASK_BITS_31_29},
+ /* CLOCK_TYPE_PC2CC3T_S */
+ { CLK(PERIPH), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
+ CLK(OSC), CLK(NONE), CLK(SFROM32KHZ), CLK(NONE),
+ MASK_BITS_31_29},
+ /* CLOCK_TYPE_AC2CC3P_TS2 */
+ { CLK(AUDIO), CLK(CGENERAL2), CLK(CGENERAL), CLK(CGENERAL3),
+ CLK(PERIPH), CLK(NONE), CLK(OSC), CLK(SRC2),
+ MASK_BITS_31_29},
+ /* CLOCK_TYPE_PC01C00_C42C41TC40 */
+ { CLK(PERIPH), CLK(CGENERAL_1), CLK(CGENERAL_0), CLK(NONE),
+ CLK(CGENERAL4_2), CLK(CGENERAL4_1), CLK(OSC), CLK(CGENERAL4_0),
+ MASK_BITS_31_29},
+};
+
+/*
+ * Clock type for each peripheral clock source. We put the name in each
+ * record just so it is easy to match things up
+ */
+#define TYPE(name, type) type
+static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
+ /* 0x00 */
+ TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT),
+ TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT),
+ TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT),
+ TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PC2CC3M),
+ TYPE(PERIPHC_PWM, CLOCK_TYPE_PC2CC3S_T),
+ TYPE(PERIPHC_05h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_SBC2, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_SBC3, CLOCK_TYPE_PC2CC3M_T),
+
+ /* 0x08 */
+ TYPE(PERIPHC_08h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_I2C1, CLOCK_TYPE_PC2CC3M_T16),
+ TYPE(PERIPHC_I2C5, CLOCK_TYPE_PC2CC3M_T16),
+ TYPE(PERIPHC_0bh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_0ch, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_SBC1, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T),
+ TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T),
+
+ /* 0x10 */
+ TYPE(PERIPHC_10h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_11h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_VI, CLOCK_TYPE_MC2CC3P_A),
+ TYPE(PERIPHC_13h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_16h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_17h, CLOCK_TYPE_NONE),
+
+ /* 0x18 */
+ TYPE(PERIPHC_18h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_VFIR, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_1Bh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_1Ch, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_HSI, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_UART1, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_UART2, CLOCK_TYPE_PC2CC3M_T),
+
+ /* 0x20 */
+ TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MC2CC3P_A),
+ TYPE(PERIPHC_21h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_22h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_23h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_24h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_25h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_I2C2, CLOCK_TYPE_PC2CC3M_T16),
+ TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPTM2C2C3),
+
+ /* 0x28 */
+ TYPE(PERIPHC_UART3, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_29h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_VI_SENSOR, CLOCK_TYPE_MC2CC3P_A),
+ TYPE(PERIPHC_2bh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_2ch, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_SBC4, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_I2C3, CLOCK_TYPE_PC2CC3M_T16),
+ TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PC2CC3M_T),
+
+ /* 0x30 */
+ TYPE(PERIPHC_UART4, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_UART5, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_VDE, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_OWR, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_NOR, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_CSITE, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT),
+ TYPE(PERIPHC_DTV, CLOCK_TYPE_NONE),
+
+ /* 0x38 */
+ TYPE(PERIPHC_38h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_39h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_3ah, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_3bh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_MSENC, CLOCK_TYPE_MC2CC3P_A),
+ TYPE(PERIPHC_TSEC, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_3eh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_OSC, CLOCK_TYPE_NONE),
+
+ /* 0x40 */
+ TYPE(PERIPHC_40h, CLOCK_TYPE_NONE), /* start with 0x3b0 */
+ TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PC2CC3T_S),
+ TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT),
+ TYPE(PERIPHC_I2S5, CLOCK_TYPE_AXPT),
+ TYPE(PERIPHC_I2C4, CLOCK_TYPE_PC2CC3M_T16),
+ TYPE(PERIPHC_SBC5, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_SBC6, CLOCK_TYPE_PC2CC3M_T),
+
+ /* 0x48 */
+ TYPE(PERIPHC_AUDIO, CLOCK_TYPE_AC2CC3P_TS2),
+ TYPE(PERIPHC_49h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_4ah, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_4bh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_4ch, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PC2CC3S_T),
+ TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE),
+
+ /* 0x50 */
+ TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE),
+ TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE),
+ TYPE(PERIPHC_52h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PC2CC3S_T),
+ TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_55h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_56h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_57h, CLOCK_TYPE_NONE),
+
+ /* 0x58 */
+ TYPE(PERIPHC_58h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_59h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_5ah, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_5bh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT),
+ TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT),
+ TYPE(PERIPHC_HDA, CLOCK_TYPE_PC2CC3M_T),
+ TYPE(PERIPHC_5fh, CLOCK_TYPE_NONE),
+
+ /* 0x60 */
+ TYPE(PERIPHC_XUSB_CORE_HOST, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_XUSB_FALCON, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_XUSB_FS, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_XUSB_CORE_DEV, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_XUSB_SS, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_CILAB, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_CILCD, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_CILE, CLOCK_TYPE_NONE),
+
+ /* 0x68 */
+ TYPE(PERIPHC_DSIA_LP, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_DSIB_LP, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_ENTROPY, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_DVFS_REF, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_DVFS_SOC, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_TRACECLKIN, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_6eh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_6fh, CLOCK_TYPE_NONE),
+
+ /* 0x70 */
+ TYPE(PERIPHC_EMC_LATENCY, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_SOC_THERM, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_72h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_73h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_74h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_75h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_VI_SENSOR2, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_I2C6, CLOCK_TYPE_PC2CC3M_T16),
+
+ /* 0x78 */
+ TYPE(PERIPHC_78h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_EMC_DLL, CLOCK_TYPE_MCPTM2C2C3),
+ TYPE(PERIPHC_7ah, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_CLK72MHZ, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_7ch, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_7dh, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_VIC, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_7Fh, CLOCK_TYPE_NONE),
+
+ /* 0x80 */
+ TYPE(PERIPHC_SDMMC_LEGACY_TM, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_NVDEC, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_NVJPG, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_NVENC, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_84h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_85h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_86h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_87h, CLOCK_TYPE_NONE),
+
+ /* 0x88 */
+ TYPE(PERIPHC_88h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_89h, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_DMIC3, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_APE, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_QSPI, CLOCK_TYPE_PC01C00_C42C41TC40),
+ TYPE(PERIPHC_VI_I2C, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_USB2_HSIC_TRK, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_PEX_SATA_USB_RX_BYP, CLOCK_TYPE_NONE),
+
+ /* 0x90 */
+ TYPE(PERIPHC_MAUD, CLOCK_TYPE_NONE),
+ TYPE(PERIPHC_TSECB, CLOCK_TYPE_NONE),
+};
+
+/*
+ * This array translates a periph_id to a periphc_internal_id
+ *
+ * Not present/matched up:
+ * uint vi_sensor; _VI_SENSOR_0, 0x1A8
+ * SPDIF - which is both 0x08 and 0x0c
+ *
+ */
+#define NONE(name) (-1)
+#define OFFSET(name, value) PERIPHC_ ## name
+#define INTERNAL_ID(id) (id & 0x000000ff)
+static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
+ /* Low word: 31:0 */
+ NONE(CPU),
+ NONE(COP),
+ NONE(TRIGSYS),
+ NONE(ISPB),
+ NONE(RESERVED4),
+ NONE(TMR),
+ PERIPHC_UART1,
+ PERIPHC_UART2, /* and vfir 0x68 */
+
+ /* 8 */
+ NONE(GPIO),
+ PERIPHC_SDMMC2,
+ PERIPHC_SPDIF_IN,
+ PERIPHC_I2S2,
+ PERIPHC_I2C1,
+ NONE(RESERVED13),
+ PERIPHC_SDMMC1,
+ PERIPHC_SDMMC4,
+
+ /* 16 */
+ NONE(TCW),
+ PERIPHC_PWM,
+ PERIPHC_I2S3,
+ NONE(RESERVED19),
+ PERIPHC_VI,
+ NONE(RESERVED21),
+ NONE(USBD),
+ NONE(ISP),
+
+ /* 24 */
+ NONE(RESERVED24),
+ NONE(RESERVED25),
+ PERIPHC_DISP2,
+ PERIPHC_DISP1,
+ PERIPHC_HOST1X,
+ NONE(VCP),
+ PERIPHC_I2S1,
+ NONE(CACHE2),
+
+ /* Middle word: 63:32 */
+ NONE(MEM),
+ NONE(AHBDMA),
+ NONE(APBDMA),
+ NONE(RESERVED35),
+ NONE(RESERVED36),
+ NONE(STAT_MON),
+ NONE(RESERVED38),
+ NONE(FUSE),
+
+ /* 40 */
+ NONE(KFUSE),
+ PERIPHC_SBC1, /* SBCx = SPIx */
+ PERIPHC_NOR,
+ NONE(RESERVED43),
+ PERIPHC_SBC2,
+ NONE(XIO),
+ PERIPHC_SBC3,
+ PERIPHC_I2C5,
+
+ /* 48 */
+ NONE(DSI),
+ NONE(RESERVED49),
+ PERIPHC_HSI,
+ NONE(RESERVED51),
+ NONE(CSI),
+ NONE(RESERVED53),
+ PERIPHC_I2C2,
+ PERIPHC_UART3,
+
+ /* 56 */
+ NONE(MIPI_CAL),
+ PERIPHC_EMC,
+ NONE(USB2),
+ NONE(USB3),
+ NONE(RESERVED60),
+ PERIPHC_VDE,
+ NONE(BSEA),
+ NONE(BSEV),
+
+ /* Upper word 95:64 */
+ NONE(RESERVED64),
+ PERIPHC_UART4,
+ PERIPHC_UART5,
+ PERIPHC_I2C3,
+ PERIPHC_SBC4,
+ PERIPHC_SDMMC3,
+ NONE(PCIE),
+ PERIPHC_OWR,
+
+ /* 72 */
+ NONE(AFI),
+ PERIPHC_CSITE,
+ NONE(PCIEXCLK),
+ NONE(AVPUCQ),
+ NONE(LA),
+ NONE(TRACECLKIN),
+ NONE(SOC_THERM),
+ NONE(DTV),
+
+ /* 80 */
+ NONE(RESERVED80),
+ PERIPHC_I2CSLOW,
+ NONE(DSIB),
+ PERIPHC_TSEC,
+ NONE(RESERVED84),
+ NONE(RESERVED85),
+ NONE(RESERVED86),
+ NONE(EMUCIF),
+
+ /* 88 */
+ NONE(RESERVED88),
+ NONE(XUSB_HOST),
+ NONE(RESERVED90),
+ PERIPHC_MSENC,
+ NONE(RESERVED92),
+ NONE(RESERVED93),
+ NONE(RESERVED94),
+ NONE(XUSB_DEV),
+
+ /* V word: 31:0 */
+ NONE(CPUG),
+ NONE(CPULP),
+ NONE(V_RESERVED2),
+ PERIPHC_MSELECT,
+ NONE(V_RESERVED4),
+ PERIPHC_I2S4,
+ PERIPHC_I2S5,
+ PERIPHC_I2C4,
+
+ /* 104 */
+ PERIPHC_SBC5,
+ PERIPHC_SBC6,
+ PERIPHC_AUDIO,
+ NONE(APBIF),
+ NONE(V_RESERVED12),
+ NONE(V_RESERVED13),
+ NONE(V_RESERVED14),
+ PERIPHC_HDA2CODEC2X,
+
+ /* 112 */
+ NONE(ATOMICS),
+ NONE(V_RESERVED17),
+ NONE(V_RESERVED18),
+ NONE(V_RESERVED19),
+ NONE(V_RESERVED20),
+ NONE(V_RESERVED21),
+ NONE(V_RESERVED22),
+ PERIPHC_ACTMON,
+
+ /* 120 */
+ NONE(EXTPERIPH1),
+ NONE(EXTPERIPH2),
+ NONE(EXTPERIPH3),
+ NONE(OOB),
+ PERIPHC_SATA,
+ PERIPHC_HDA,
+ NONE(TZRAM),
+ NONE(SE),
+
+ /* W word: 31:0 */
+ NONE(HDA2HDMICODEC),
+ NONE(SATACOLD),
+ NONE(W_RESERVED2),
+ NONE(W_RESERVED3),
+ NONE(W_RESERVED4),
+ NONE(W_RESERVED5),
+ NONE(W_RESERVED6),
+ NONE(W_RESERVED7),
+
+ /* 136 */
+ NONE(CEC),
+ NONE(W_RESERVED9),
+ NONE(W_RESERVED10),
+ NONE(W_RESERVED11),
+ NONE(W_RESERVED12),
+ NONE(W_RESERVED13),
+ NONE(XUSB_PADCTL),
+ NONE(W_RESERVED15),
+
+ /* 144 */
+ NONE(W_RESERVED16),
+ NONE(W_RESERVED17),
+ NONE(W_RESERVED18),
+ NONE(W_RESERVED19),
+ NONE(W_RESERVED20),
+ NONE(ENTROPY),
+ NONE(DDS),
+ NONE(W_RESERVED23),
+
+ /* 152 */
+ NONE(W_RESERVED24),
+ NONE(W_RESERVED25),
+ NONE(W_RESERVED26),
+ NONE(DVFS),
+ NONE(XUSB_SS),
+ NONE(W_RESERVED29),
+ NONE(W_RESERVED30),
+ NONE(W_RESERVED31),
+
+ /* X word: 31:0 */
+ NONE(SPARE),
+ NONE(X_RESERVED1),
+ NONE(X_RESERVED2),
+ NONE(X_RESERVED3),
+ NONE(CAM_MCLK),
+ NONE(CAM_MCLK2),
+ PERIPHC_I2C6,
+ NONE(X_RESERVED7),
+
+ /* 168 */
+ NONE(X_RESERVED8),
+ NONE(X_RESERVED9),
+ NONE(X_RESERVED10),
+ NONE(VIM2_CLK),
+ NONE(X_RESERVED12),
+ NONE(X_RESERVED13),
+ NONE(EMC_DLL),
+ NONE(X_RESERVED15),
+
+ /* 176 */
+ NONE(X_RESERVED16),
+ NONE(CLK72MHZ),
+ NONE(VIC),
+ NONE(X_RESERVED19),
+ NONE(X_RESERVED20),
+ NONE(DPAUX),
+ NONE(SOR0),
+ NONE(X_RESERVED23),
+
+ /* 184 */
+ NONE(GPU),
+ NONE(X_RESERVED25),
+ NONE(X_RESERVED26),
+ NONE(X_RESERVED27),
+ NONE(X_RESERVED28),
+ NONE(X_RESERVED29),
+ NONE(X_RESERVED30),
+ NONE(X_RESERVED31),
+
+ /* Y: 192 (192 - 223) */
+ NONE(Y_RESERVED0),
+ PERIPHC_SDMMC_LEGACY_TM,
+ PERIPHC_NVDEC,
+ PERIPHC_NVJPG,
+ NONE(Y_RESERVED4),
+ PERIPHC_DMIC3, /* 197 */
+ PERIPHC_APE, /* 198 */
+ NONE(Y_RESERVED7),
+
+ /* 200 */
+ NONE(Y_RESERVED8),
+ NONE(Y_RESERVED9),
+ NONE(Y_RESERVED10),
+ NONE(Y_RESERVED11),
+ NONE(Y_RESERVED12),
+ NONE(Y_RESERVED13),
+ NONE(Y_RESERVED14),
+ NONE(Y_RESERVED15),
+
+ /* 208 */
+ PERIPHC_VI_I2C, /* 208 */
+ NONE(Y_RESERVED17),
+ NONE(Y_RESERVED18),
+ PERIPHC_QSPI, /* 211 */
+ NONE(Y_RESERVED20),
+ NONE(Y_RESERVED21),
+ NONE(Y_RESERVED22),
+ NONE(Y_RESERVED23),
+
+ /* 216 */
+ NONE(Y_RESERVED24),
+ NONE(Y_RESERVED25),
+ NONE(Y_RESERVED26),
+ PERIPHC_NVENC, /* 219 */
+ NONE(Y_RESERVED28),
+ NONE(Y_RESERVED29),
+ NONE(Y_RESERVED30),
+ NONE(Y_RESERVED31),
+};
+
+/*
+ * Get the oscillator frequency, from the corresponding hardware configuration
+ * field. Note that Tegra30+ support 3 new higher freqs, but we map back
+ * to the old T20 freqs. Support for the higher oscillators is TBD.
+ */
+enum clock_osc_freq clock_get_osc_freq(void)
+{
+ struct clk_rst_ctlr *clkrst =
+ (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 reg;
+
+ reg = readl(&clkrst->crc_osc_ctrl);
+ reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
+ /*
+ * 0 = 13MHz, 1 = 16.8MHz, 4 = 19.2MHz, 5 = 38.4MHz,
+ * 8 = 12MHz, 9 = 48MHz, 12 = 26MHz
+ */
+ if (reg == 5) {
+ debug("OSC_FREQ is 38.4MHz (%d) ...\n", reg);
+ /* Map it to 19.2MHz for now. 38.4MHz OSC support TBD */
+ return 1;
+ }
+
+ /*
+ * Map to most common (T20) freqs (except 38.4, handled above):
+ * 13/16.8 = 0, 19.2 = 1, 12/48 = 2, 26 = 3
+ */
+ return reg >> 2;
+}
+
+/* Returns a pointer to the clock source register for a peripheral */
+u32 *get_periph_source_reg(enum periph_id periph_id)
+{
+ struct clk_rst_ctlr *clkrst =
+ (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ enum periphc_internal_id internal_id;
+
+ /* Coresight is a special case */
+ if (periph_id == PERIPH_ID_CSI)
+ return &clkrst->crc_clk_src[PERIPH_ID_CSI+1];
+
+ assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT);
+ internal_id = INTERNAL_ID(periph_id_to_internal_id[periph_id]);
+ assert(internal_id != -1);
+
+ if (internal_id < PERIPHC_VW_FIRST)
+ /* L, H, U */
+ return &clkrst->crc_clk_src[internal_id];
+
+ if (internal_id < PERIPHC_X_FIRST) {
+ /* VW */
+ internal_id -= PERIPHC_VW_FIRST;
+ return &clkrst->crc_clk_src_vw[internal_id];
+ }
+
+ if (internal_id < PERIPHC_Y_FIRST) {
+ /* X */
+ internal_id -= PERIPHC_X_FIRST;
+ return &clkrst->crc_clk_src_x[internal_id];
+ }
+
+ /* Y */
+ internal_id -= PERIPHC_Y_FIRST;
+ return &clkrst->crc_clk_src_y[internal_id];
+}
+
+/**
+ * Given a peripheral ID and the required source clock, this returns which
+ * value should be programmed into the source mux for that peripheral.
+ *
+ * There is special code here to handle the one source type with 5 sources.
+ *
+ * @param periph_id peripheral to start
+ * @param source PLL id of required parent clock
+ * @param mux_bits Set to number of bits in mux register: 2 or 4
+ * @param divider_bits Set to number of divider bits (8 or 16)
+ * @return mux value (0-4, or -1 if not found)
+ */
+int get_periph_clock_source(enum periph_id periph_id,
+ enum clock_id parent, int *mux_bits, int *divider_bits)
+{
+ enum clock_type_id type;
+ enum periphc_internal_id internal_id;
+ int mux;
+
+ assert(clock_periph_id_isvalid(periph_id));
+
+ internal_id = INTERNAL_ID(periph_id_to_internal_id[periph_id]);
+ assert(periphc_internal_id_isvalid(internal_id));
+
+ type = clock_periph_type[internal_id];
+ assert(clock_type_id_isvalid(type));
+
+ *mux_bits = clock_source[type][CLOCK_MAX_MUX];
+
+ if (type == CLOCK_TYPE_PC2CC3M_T16)
+ *divider_bits = 16;
+ else
+ *divider_bits = 8;
+
+ for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
+ if (clock_source[type][mux] == parent)
+ return mux;
+
+ /* if we get here, either us or the caller has made a mistake */
+ printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
+ parent);
+ return -1;
+}
+
+void clock_set_enable(enum periph_id periph_id, int enable)
+{
+ struct clk_rst_ctlr *clkrst =
+ (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 *clk;
+ u32 reg;
+
+ /* Enable/disable the clock to this peripheral */
+ assert(clock_periph_id_isvalid(periph_id));
+ if ((int)periph_id < (int)PERIPH_ID_VW_FIRST)
+ clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
+ else if ((int)periph_id < (int)PERIPH_ID_X_FIRST)
+ clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)];
+ else if ((int)periph_id < (int)PERIPH_ID_Y_FIRST)
+ clk = &clkrst->crc_clk_out_enb_x;
+ else
+ clk = &clkrst->crc_clk_out_enb_y;
+
+ reg = readl(clk);
+ if (enable)
+ reg |= PERIPH_MASK(periph_id);
+ else
+ reg &= ~PERIPH_MASK(periph_id);
+ writel(reg, clk);
+}
+
+void reset_set_enable(enum periph_id periph_id, int enable)
+{
+ struct clk_rst_ctlr *clkrst =
+ (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 *reset;
+ u32 reg;
+
+ /* Enable/disable reset to the peripheral */
+ assert(clock_periph_id_isvalid(periph_id));
+ if (periph_id < PERIPH_ID_VW_FIRST)
+ reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
+ else if ((int)periph_id < (int)PERIPH_ID_X_FIRST)
+ reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)];
+ else if ((int)periph_id < (int)PERIPH_ID_Y_FIRST)
+ reset = &clkrst->crc_rst_devices_x;
+ else
+ reset = &clkrst->crc_rst_devices_y;
+
+ reg = readl(reset);
+ if (enable)
+ reg |= PERIPH_MASK(periph_id);
+ else
+ reg &= ~PERIPH_MASK(periph_id);
+ writel(reg, reset);
+}
+
+#ifdef CONFIG_OF_CONTROL
+/*
+ * Convert a device tree clock ID to our peripheral ID. They are mostly
+ * the same but we are very cautious so we check that a valid clock ID is
+ * provided.
+ *
+ * @param clk_id Clock ID according to tegra210 device tree binding
+ * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid
+ */
+enum periph_id clk_id_to_periph_id(int clk_id)
+{
+ if (clk_id > PERIPH_ID_COUNT)
+ return PERIPH_ID_NONE;
+
+ switch (clk_id) {
+ case PERIPH_ID_RESERVED4:
+ case PERIPH_ID_RESERVED25:
+ case PERIPH_ID_RESERVED35:
+ case PERIPH_ID_RESERVED36:
+ case PERIPH_ID_RESERVED38:
+ case PERIPH_ID_RESERVED43:
+ case PERIPH_ID_RESERVED49:
+ case PERIPH_ID_RESERVED53:
+ case PERIPH_ID_RESERVED64:
+ case PERIPH_ID_RESERVED84:
+ case PERIPH_ID_RESERVED85:
+ case PERIPH_ID_RESERVED86:
+ case PERIPH_ID_RESERVED88:
+ case PERIPH_ID_RESERVED90:
+ case PERIPH_ID_RESERVED92:
+ case PERIPH_ID_RESERVED93:
+ case PERIPH_ID_RESERVED94:
+ case PERIPH_ID_V_RESERVED2:
+ case PERIPH_ID_V_RESERVED4:
+ case PERIPH_ID_V_RESERVED17:
+ case PERIPH_ID_V_RESERVED18:
+ case PERIPH_ID_V_RESERVED19:
+ case PERIPH_ID_V_RESERVED20:
+ case PERIPH_ID_V_RESERVED21:
+ case PERIPH_ID_V_RESERVED22:
+ case PERIPH_ID_W_RESERVED2:
+ case PERIPH_ID_W_RESERVED3:
+ case PERIPH_ID_W_RESERVED4:
+ case PERIPH_ID_W_RESERVED5:
+ case PERIPH_ID_W_RESERVED6:
+ case PERIPH_ID_W_RESERVED7:
+ case PERIPH_ID_W_RESERVED9:
+ case PERIPH_ID_W_RESERVED10:
+ case PERIPH_ID_W_RESERVED11:
+ case PERIPH_ID_W_RESERVED12:
+ case PERIPH_ID_W_RESERVED13:
+ case PERIPH_ID_W_RESERVED15:
+ case PERIPH_ID_W_RESERVED16:
+ case PERIPH_ID_W_RESERVED17:
+ case PERIPH_ID_W_RESERVED18:
+ case PERIPH_ID_W_RESERVED19:
+ case PERIPH_ID_W_RESERVED20:
+ case PERIPH_ID_W_RESERVED23:
+ case PERIPH_ID_W_RESERVED29:
+ case PERIPH_ID_W_RESERVED30:
+ case PERIPH_ID_W_RESERVED31:
+ return PERIPH_ID_NONE;
+ default:
+ return clk_id;
+ }
+}
+#endif /* CONFIG_OF_CONTROL */
+
+/*
+ * T210 redefines PLLP_OUT2 as PLLP_VCO/DIVP, so do different OUT1-4 setup here.
+ * PLLP_BASE/MISC/etc. is already set up for 408MHz in the BootROM.
+ */
+void tegra210_setup_pllp(void)
+{
+ struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 reg;
+
+ /* Set PLLP_OUT1, 3 & 4 freqs to 9.6, 102 & 204MHz */
+
+ /* OUT1 */
+ /* Assert RSTN before enable */
+ reg = PLLP_OUT1_RSTN_EN;
+ writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[0]);
+ /* Set divisor and reenable */
+ reg = (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO)
+ | PLLP_OUT1_OVR | PLLP_OUT1_CLKEN | PLLP_OUT1_RSTN_DIS;
+ writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[0]);
+
+ /* OUT3, 4 */
+ /* Assert RSTN before enable */
+ reg = PLLP_OUT4_RSTN_EN | PLLP_OUT3_RSTN_EN;
+ writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]);
+ /* Set divisor and reenable */
+ reg = (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO)
+ | PLLP_OUT4_OVR | PLLP_OUT4_CLKEN | PLLP_OUT4_RSTN_DIS
+ | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO)
+ | PLLP_OUT3_OVR | PLLP_OUT3_CLKEN | PLLP_OUT3_RSTN_DIS;
+ writel(reg, &clkrst->crc_pll[CLOCK_ID_PERIPH].pll_out[1]);
+
+ /*
+ * NOTE: If you want to change PLLP_OUT2 away from 204MHz,
+ * you can change PLLP_BASE DIVP here. Currently defaults
+ * to 1, which is 2^1, or 2, so PLLP_OUT2 is 204MHz.
+ * See Table 13 in section 5.1.4 in T210 TRM for more info.
+ */
+}
+
+void clock_early_init(void)
+{
+ struct clk_rst_ctlr *clkrst =
+ (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
+ u32 data;
+
+ tegra210_setup_pllp();
+
+ /*
+ * PLLC output frequency set to 600Mhz
+ * PLLD output frequency set to 925Mhz
+ */
+ switch (clock_get_osc_freq()) {
+ case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */
+ clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
+ clock_set_rate(CLOCK_ID_DISPLAY, 925, 12, 0, 12);
+ break;
+
+ case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */
+ clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
+ clock_set_rate(CLOCK_ID_DISPLAY, 925, 26, 0, 12);
+ break;
+
+ case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */
+ clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
+ clock_set_rate(CLOCK_ID_DISPLAY, 925, 13, 0, 12);
+ break;
+ case CLOCK_OSC_FREQ_19_2:
+ clock_set_rate(CLOCK_ID_CGENERAL, 125, 4, 0, 0);
+ clock_set_rate(CLOCK_ID_DISPLAY, 96, 2, 0, 12);
+ break;
+ default:
+ /*
+ * These are not supported. It is too early to print a
+ * message and the UART likely won't work anyway due to the
+ * oscillator being wrong.
+ */
+ break;
+ }
+
+ /* PLLC_MISC1: Turn IDDQ off. NOTE: T210 PLLC_MISC_1 maps to pll_misc */
+ clrbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_misc,
+ (1 << PLLC_IDDQ));
+ udelay(2);
+
+ /*
+ * PLLC_MISC: Take PLLC out of reset. NOTE: T210 PLLC_MISC maps
+ * to pll_out[1]
+ */
+ clrbits_le32(&clkrst->crc_pll[CLOCK_ID_CGENERAL].pll_out[1],
+ (1 << PLLC_RESET));
+ udelay(2);
+
+ /* PLLD_MISC: Set CLKENABLE and LOCK_DETECT bits */
+ data = (1 << PLLD_ENABLE_CLK) | (1 << PLLD_EN_LCKDET);
+ writel(data, &clkrst->crc_pll[CLOCK_ID_DISPLAY].pll_misc);
+ udelay(2);
+}
+
+void arch_timer_init(void)
+{
+ struct sysctr_ctlr *sysctr = (struct sysctr_ctlr *)NV_PA_TSC_BASE;
+ u32 freq, val;
+
+ freq = clock_get_rate(CLOCK_ID_OSC);
+ debug("%s: osc freq is %dHz [0x%08X]\n", __func__, freq, freq);
+
+ /* ARM CNTFRQ */
+#ifndef CONFIG_ARM64
+ asm("mcr p15, 0, %0, c14, c0, 0\n" : : "r" (freq));
+#endif
+
+ /* Only Tegra114+ has the System Counter regs */
+ debug("%s: setting CNTFID0 to 0x%08X\n", __func__, freq);
+ writel(freq, &sysctr->cntfid0);
+
+ val = readl(&sysctr->cntcr);
+ val |= TSC_CNTCR_ENABLE | TSC_CNTCR_HDBG;
+ writel(val, &sysctr->cntcr);
+ debug("%s: TSC CNTCR = 0x%08X\n", __func__, val);
+}
+
+#define PLLE_SS_CNTL 0x68
+#define PLLE_SS_CNTL_SSCINCINTR(x) (((x) & 0x3f) << 24)
+#define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16)
+#define PLLE_SS_CNTL_SSCINVERT (1 << 15)
+#define PLLE_SS_CNTL_SSCCENTER (1 << 14)
+#define PLLE_SS_CNTL_SSCBYP (1 << 12)
+#define PLLE_SS_CNTL_INTERP_RESET (1 << 11)
+#define PLLE_SS_CNTL_BYPASS_SS (1 << 10)
+#define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0)
+
+#define PLLE_BASE 0x0e8
+#define PLLE_BASE_ENABLE (1 << 30)
+#define PLLE_BASE_LOCK_OVERRIDE (1 << 29)
+#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24)
+#define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8)
+#define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0)
+
+#define PLLE_MISC 0x0ec
+#define PLLE_MISC_IDDQ_SWCTL (1 << 14)
+#define PLLE_MISC_IDDQ_OVERRIDE (1 << 13)
+#define PLLE_MISC_LOCK_ENABLE (1 << 9)
+#define PLLE_MISC_PTS (1 << 8)
+#define PLLE_MISC_VREG_BG_CTRL(x) (((x) & 0x3) << 4)
+#define PLLE_MISC_VREG_CTRL(x) (((x) & 0x3) << 2)
+
+#define PLLE_AUX 0x48c
+#define PLLE_AUX_SEQ_ENABLE (1 << 24)
+#define PLLE_AUX_ENABLE_SWCTL (1 << 4)
+
+int tegra_plle_enable(void)
+{
+ unsigned int m = 1, n = 200, cpcon = 13;
+ u32 value;
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
+ value &= ~PLLE_BASE_LOCK_OVERRIDE;
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_AUX);
+ value |= PLLE_AUX_ENABLE_SWCTL;
+ value &= ~PLLE_AUX_SEQ_ENABLE;
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_AUX);
+
+ udelay(1);
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
+ value |= PLLE_MISC_IDDQ_SWCTL;
+ value &= ~PLLE_MISC_IDDQ_OVERRIDE;
+ value |= PLLE_MISC_LOCK_ENABLE;
+ value |= PLLE_MISC_PTS;
+ value |= PLLE_MISC_VREG_BG_CTRL(3);
+ value |= PLLE_MISC_VREG_CTRL(2);
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC);
+
+ udelay(5);
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+ value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET |
+ PLLE_SS_CNTL_BYPASS_SS;
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
+ value &= ~PLLE_BASE_PLDIV_CML(0xf);
+ value &= ~PLLE_BASE_NDIV(0xff);
+ value &= ~PLLE_BASE_MDIV(0xff);
+ value |= PLLE_BASE_PLDIV_CML(cpcon);
+ value |= PLLE_BASE_NDIV(n);
+ value |= PLLE_BASE_MDIV(m);
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
+
+ udelay(1);
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
+ value |= PLLE_BASE_ENABLE;
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
+
+ /* wait for lock */
+ udelay(300);
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+ value &= ~PLLE_SS_CNTL_SSCINVERT;
+ value &= ~PLLE_SS_CNTL_SSCCENTER;
+
+ value &= ~PLLE_SS_CNTL_SSCINCINTR(0x3f);
+ value &= ~PLLE_SS_CNTL_SSCINC(0xff);
+ value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff);
+
+ value |= PLLE_SS_CNTL_SSCINCINTR(0x20);
+ value |= PLLE_SS_CNTL_SSCINC(0x01);
+ value |= PLLE_SS_CNTL_SSCMAX(0x25);
+
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+ value &= ~PLLE_SS_CNTL_SSCBYP;
+ value &= ~PLLE_SS_CNTL_BYPASS_SS;
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+
+ udelay(1);
+
+ value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+ value &= ~PLLE_SS_CNTL_INTERP_RESET;
+ writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
+
+ udelay(1);
+
+ return 0;
+}
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Tegra210 high-level function multiplexing */
+
+#include <common.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/funcmux.h>
+#include <asm/arch/pinmux.h>
+
+int funcmux_select(enum periph_id id, int config)
+{
+ int bad_config = config != FUNCMUX_DEFAULT;
+
+ switch (id) {
+ /*
+ * Add other periph IDs here as needed.
+ * Note that all pinmux/pads should have already
+ * been set up in the board pinmux table in
+ * pinmux-config-<board>.h for all periphs.
+ * Leave this in for the odd case where a mux
+ * needs to be changed on-the-fly.
+ */
+
+ default:
+ debug("%s: invalid periph_id %d", __func__, id);
+ return -1;
+ }
+
+ if (bad_config) {
+ debug("%s: invalid config %d for periph_id %d", __func__,
+ config, id);
+ return -1;
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#define pr_fmt(fmt) "tegra-xusb-padctl: " fmt
+
+#include <common.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <malloc.h>
+
+#include <asm/io.h>
+
+#include <asm/arch/clock.h>
+#include <asm/arch-tegra/xusb-padctl.h>
+
+#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
+
+struct tegra_xusb_phy_ops {
+ int (*prepare)(struct tegra_xusb_phy *phy);
+ int (*enable)(struct tegra_xusb_phy *phy);
+ int (*disable)(struct tegra_xusb_phy *phy);
+ int (*unprepare)(struct tegra_xusb_phy *phy);
+};
+
+struct tegra_xusb_phy {
+ const struct tegra_xusb_phy_ops *ops;
+
+ struct tegra_xusb_padctl *padctl;
+};
+
+struct tegra_xusb_padctl {
+ struct fdt_resource regs;
+
+ unsigned int enable;
+
+ struct tegra_xusb_phy phys[2];
+};
+
+static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
+ unsigned long offset)
+{
+ u32 value = readl(padctl->regs.start + offset);
+ debug("padctl: %08lx > %08x\n", offset, value);
+ return value;
+}
+
+static inline void padctl_writel(struct tegra_xusb_padctl *padctl,
+ u32 value, unsigned long offset)
+{
+ debug("padctl: %08lx < %08x\n", offset, value);
+ writel(value, padctl->regs.start + offset);
+}
+
+#define XUSB_PADCTL_ELPG_PROGRAM 0x024
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 31)
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 30)
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 29)
+
+static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
+{
+ u32 value;
+
+ if (padctl->enable++ > 0)
+ return 0;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ udelay(100);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ udelay(100);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ return 0;
+}
+
+static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
+{
+ u32 value;
+
+ if (padctl->enable == 0) {
+ error("unbalanced enable/disable");
+ return 0;
+ }
+
+ if (--padctl->enable > 0)
+ return 0;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ udelay(100);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ udelay(100);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ return 0;
+}
+
+static int phy_prepare(struct tegra_xusb_phy *phy)
+{
+ int err;
+
+ err = tegra_xusb_padctl_enable(phy->padctl);
+ if (err < 0)
+ return err;
+
+ reset_set_enable(PERIPH_ID_PEX_USB_UPHY, 0);
+
+ return 0;
+}
+
+static int phy_unprepare(struct tegra_xusb_phy *phy)
+{
+ reset_set_enable(PERIPH_ID_PEX_USB_UPHY, 1);
+
+ return tegra_xusb_padctl_disable(phy->padctl);
+}
+
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1 0x360
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV_MASK (0xff << 20)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV(x) (((x) & 0xff) << 20)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_MDIV_MASK (0x3 << 16)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS (1 << 15)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD (1 << 4)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_ENABLE (1 << 3)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP_MASK (0x3 << 1)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP(x) (((x) & 0x3) << 1)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL1_IDDQ (1 << 0)
+
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL2 0x364
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL_MASK (0xffffff << 4)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL(x) (((x) & 0xffffff) << 4)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD (1 << 2)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE (1 << 1)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN (1 << 0)
+
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL4 0x36c
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_EN (1 << 15)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL_MASK (0x3 << 12)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL(x) (((x) & 0x3) << 12)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLKBUF_EN (1 << 8)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLK_SEL_MASK (0xf << 4)
+
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL5 0x370
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL_MASK (0xff << 16)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL(x) (((x) & 0xff) << 16)
+
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL8 0x37c
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE (1 << 31)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD (1 << 15)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN (1 << 13)
+#define XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN (1 << 12)
+
+#define CLK_RST_XUSBIO_PLL_CFG0 0x51c
+#define CLK_RST_XUSBIO_PLL_CFG0_SEQ_ENABLE (1 << 24)
+#define CLK_RST_XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ (1 << 13)
+#define CLK_RST_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET (1 << 6)
+#define CLK_RST_XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL (1 << 2)
+#define CLK_RST_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL (1 << 0)
+
+static int pcie_phy_enable(struct tegra_xusb_phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy->padctl;
+ unsigned long start;
+ u32 value;
+
+ debug("> %s(phy=%p)\n", __func__, phy);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL_MASK;
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_CTRL(0x136);
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL_MASK;
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL5_DCO_CTRL(0x2a);
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL5);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL_MASK;
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLK_SEL_MASK;
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_SEL(2);
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_TXCLKREF_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_MDIV_MASK;
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV_MASK;
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_FREQ_NDIV(25);
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_SLEEP_MASK;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+
+ udelay(1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL4_REFCLKBUF_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL4);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+
+ debug(" waiting for calibration\n");
+
+ start = get_timer(0);
+
+ while (get_timer(start) < 250) {
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+ if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE)
+ break;
+ }
+
+ debug(" done\n");
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+
+ debug(" waiting for calibration to stop\n");
+
+ start = get_timer(0);
+
+ while (get_timer(start) < 250) {
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+ if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_DONE) == 0)
+ break;
+ }
+
+ debug(" done\n");
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL1_ENABLE;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+
+ debug(" waiting for PLL to lock...\n");
+ start = get_timer(0);
+
+ while (get_timer(start) < 250) {
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+ if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL1_LOCKDET_STATUS)
+ break;
+ }
+
+ debug(" done\n");
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN;
+ value |= XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+
+ debug(" waiting for register calibration...\n");
+ start = get_timer(0);
+
+ while (get_timer(start) < 250) {
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+ if (value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE)
+ break;
+ }
+
+ debug(" done\n");
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+
+ debug(" waiting for register calibration to stop...\n");
+ start = get_timer(0);
+
+ while (get_timer(start) < 250) {
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+ if ((value & XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_DONE) == 0)
+ break;
+ }
+
+ debug(" done\n");
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_CLK_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+
+ value = readl(NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
+ value &= ~CLK_RST_XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL;
+ value &= ~CLK_RST_XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL;
+ value |= CLK_RST_XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET;
+ value |= CLK_RST_XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ;
+ writel(value, NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL1_PWR_OVRD;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL2_CAL_OVRD;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL2);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+ value &= ~XUSB_PADCTL_UPHY_PLL_P0_CTL8_RCAL_OVRD;
+ padctl_writel(padctl, value, XUSB_PADCTL_UPHY_PLL_P0_CTL8);
+
+ udelay(1);
+
+ value = readl(NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
+ value |= CLK_RST_XUSBIO_PLL_CFG0_SEQ_ENABLE;
+ writel(value, NV_PA_CLK_RST_BASE + CLK_RST_XUSBIO_PLL_CFG0);
+
+ debug("< %s()\n", __func__);
+ return 0;
+}
+
+static int pcie_phy_disable(struct tegra_xusb_phy *phy)
+{
+ return 0;
+}
+
+static const struct tegra_xusb_phy_ops pcie_phy_ops = {
+ .prepare = phy_prepare,
+ .enable = pcie_phy_enable,
+ .disable = pcie_phy_disable,
+ .unprepare = phy_unprepare,
+};
+
+static struct tegra_xusb_padctl *padctl = &(struct tegra_xusb_padctl) {
+ .phys = {
+ [0] = {
+ .ops = &pcie_phy_ops,
+ },
+ },
+};
+
+static int tegra_xusb_padctl_parse_dt(struct tegra_xusb_padctl *padctl,
+ const void *fdt, int node)
+{
+ int err;
+
+ err = fdt_get_resource(fdt, node, "reg", 0, &padctl->regs);
+ if (err < 0) {
+ error("registers not found");
+ return err;
+ }
+
+ debug("regs: %pa-%pa\n", &padctl->regs.start,
+ &padctl->regs.end);
+
+ return 0;
+}
+
+static int process_nodes(const void *fdt, int nodes[], unsigned int count)
+{
+ unsigned int i;
+ int err;
+
+ debug("> %s(fdt=%p, nodes=%p, count=%u)\n", __func__, fdt, nodes,
+ count);
+
+ for (i = 0; i < count; i++) {
+ enum fdt_compat_id id;
+
+ if (!fdtdec_get_is_enabled(fdt, nodes[i]))
+ continue;
+
+ id = fdtdec_lookup(fdt, nodes[i]);
+ switch (id) {
+ case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL:
+ case COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL:
+ break;
+
+ default:
+ error("unsupported compatible: %s",
+ fdtdec_get_compatible(id));
+ continue;
+ }
+
+ err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]);
+ if (err < 0) {
+ error("failed to parse DT: %d",
+ err);
+ continue;
+ }
+
+ /* deassert XUSB padctl reset */
+ reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0);
+
+ /* only a single instance is supported */
+ break;
+ }
+
+ debug("< %s()\n", __func__);
+ return 0;
+}
+
+struct tegra_xusb_phy *tegra_xusb_phy_get(unsigned int type)
+{
+ struct tegra_xusb_phy *phy = NULL;
+
+ switch (type) {
+ case TEGRA_XUSB_PADCTL_PCIE:
+ phy = &padctl->phys[0];
+ phy->padctl = padctl;
+ break;
+ }
+
+ return phy;
+}
+
+int tegra_xusb_phy_prepare(struct tegra_xusb_phy *phy)
+{
+ if (phy && phy->ops && phy->ops->prepare)
+ return phy->ops->prepare(phy);
+
+ return phy ? -ENOSYS : -EINVAL;
+}
+
+int tegra_xusb_phy_enable(struct tegra_xusb_phy *phy)
+{
+ if (phy && phy->ops && phy->ops->enable)
+ return phy->ops->enable(phy);
+
+ return phy ? -ENOSYS : -EINVAL;
+}
+
+int tegra_xusb_phy_disable(struct tegra_xusb_phy *phy)
+{
+ if (phy && phy->ops && phy->ops->disable)
+ return phy->ops->disable(phy);
+
+ return phy ? -ENOSYS : -EINVAL;
+}
+
+int tegra_xusb_phy_unprepare(struct tegra_xusb_phy *phy)
+{
+ if (phy && phy->ops && phy->ops->unprepare)
+ return phy->ops->unprepare(phy);
+
+ return phy ? -ENOSYS : -EINVAL;
+}
+
+void tegra_xusb_padctl_init(const void *fdt)
+{
+ int count, nodes[1];
+
+ debug("> %s(fdt=%p)\n", __func__, fdt);
+
+ count = fdtdec_find_aliases_for_id(fdt, "padctl",
+ COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,
+ nodes, ARRAY_SIZE(nodes));
+ if (process_nodes(fdt, nodes, count))
+ return;
+
+ count = fdtdec_find_aliases_for_id(fdt, "padctl",
+ COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL,
+ nodes, ARRAY_SIZE(nodes));
+ if (process_nodes(fdt, nodes, count))
+ return;
+
+ debug("< %s()\n", __func__);
+}
prompt "UniPhier SoC select"
default MACH_PH1_PRO4
-config MACH_PH1_PRO4
- bool "PH1-Pro4"
+config MACH_PH1_SLD3
+ bool "PH1-sLD3"
select UNIPHIER_SMP
config MACH_PH1_LD4
bool "PH1-LD4"
+config MACH_PH1_PRO4
+ bool "PH1-Pro4"
+ select UNIPHIER_SMP
+
config MACH_PH1_SLD8
bool "PH1-sLD8"
config DDR_FREQ_1600
bool "DDR3 1600"
- depends on MACH_PH1_PRO4 || MACH_PH1_LD4
+ depends on MACH_PH1_SLD3 || MACH_PH1_LD4 || MACH_PH1_PRO4
config DDR_FREQ_1333
bool "DDR3 1333"
- depends on MACH_PH1_LD4 || MACH_PH1_SLD8
+ depends on MACH_PH1_SLD3 || MACH_PH1_LD4 || MACH_PH1_SLD8
endchoice
obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += support_card.o
obj-$(CONFIG_DCC_MICRO_SUPPORT_CARD) += support_card.o
-obj-$(CONFIG_MACH_PH1_LD4) += ph1-ld4/
-obj-$(CONFIG_MACH_PH1_PRO4) += ph1-pro4/
-obj-$(CONFIG_MACH_PH1_SLD8) += ph1-sld8/
+obj-$(CONFIG_MACH_PH1_SLD3) += ph1-sld3/
+obj-$(CONFIG_MACH_PH1_LD4) += ph1-ld4/
+obj-$(CONFIG_MACH_PH1_PRO4) += ph1-pro4/
+obj-$(CONFIG_MACH_PH1_SLD8) += ph1-sld8/
/*
* UniPhier SC (System Control) block registers
*
- * Copyright (C) 2011-2015 Panasonic Corporation
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef ARCH_SC_REGS_H
#define ARCH_SC_REGS_H
+#if defined(CONFIG_MACH_PH1_SLD3)
+#define SC_BASE_ADDR 0xf1840000
+#else
#define SC_BASE_ADDR 0x61840000
+#endif
#define SC_DPLLCTRL (SC_BASE_ADDR | 0x1200)
#define SC_DPLLCTRL_SSC_EN (0x1 << 31)
#if defined(CONFIG_MACH_PH1_PRO4)
# define SG_PINCTRL(n) (SG_PINCTRL_BASE + (n) * 8)
-#elif defined(CONFIG_MACH_PH1_LD4) || defined(CONFIG_MACH_PH1_SLD8)
+#elif defined(CONFIG_MACH_PH1_SLD3) || defined(CONFIG_MACH_PH1_LD4) || \
+ defined(CONFIG_MACH_PH1_SLD8)
# define SG_PINCTRL(n) (SG_PINCTRL_BASE + (n) * 4)
#endif
-#if defined(CONFIG_MACH_PH1_PRO4)
+#if defined(CONFIG_MACH_PH1_SLD3) || defined(CONFIG_MACH_PH1_PRO4)
#define SG_PINSELBITS 4
#elif defined(CONFIG_MACH_PH1_LD4) || defined(CONFIG_MACH_PH1_SLD8)
#define SG_PINSELBITS 8
--- /dev/null
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+ifdef CONFIG_SPL_BUILD
+obj-$(CONFIG_DEBUG_LL) += lowlevel_debug.o
+obj-y += bcu_init.o memconf.o sg_init.o pll_init.o early_clkrst_init.o \
+ early_pinctrl.o pll_spectrum.o umc_init.o
+obj-$(CONFIG_PFC_MICRO_SUPPORT_CARD) += sbc_init.o
+obj-$(CONFIG_DCC_MICRO_SUPPORT_CARD) += sbc_init_3cs.o
+obj-$(CONFIG_SPL_DM) += platdevice.o
+else
+obj-$(CONFIG_BOARD_EARLY_INIT_F) += pinctrl.o clkrst_init.o
+endif
+
+obj-y += boot-mode.o
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <mach/bcu-regs.h>
+
+#define ch(x) ((x) >= 32 ? 0 : (x) < 0 ? 0x11111111 : 0x11111111 << (x))
+
+void bcu_init(void)
+{
+ int shift;
+
+ writel(0x11111111, BCSCR2); /* 0x80000000-0x9fffffff: IPPC/IPPD-bus */
+ writel(0x11111111, BCSCR3); /* 0xa0000000-0xbfffffff: IPPC/IPPD-bus */
+ writel(0x11111111, BCSCR4); /* 0xc0000000-0xdfffffff: IPPC/IPPD-bus */
+ /*
+ * 0xe0000000-0xefffffff: Ex-bus
+ * 0xf0000000-0xfbffffff: ASM bus
+ * 0xfc000000-0xffffffff: OCM bus
+ */
+ writel(0x24440000, BCSCR5);
+
+ /* Specify DDR channel */
+ shift = (CONFIG_SDRAM1_BASE - CONFIG_SDRAM0_BASE) / 0x04000000 * 4;
+ writel(ch(shift), BCIPPCCHR2); /* 0x80000000-0x9fffffff */
+
+ shift -= 32;
+ writel(ch(shift), BCIPPCCHR3); /* 0xa0000000-0xbfffffff */
+
+ shift -= 32;
+ writel(ch(shift), BCIPPCCHR4); /* 0xc0000000-0xdfffffff */
+}
--- /dev/null
+/*
+ * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <linux/io.h>
+#include <mach/boot-device.h>
+#include <mach/sg-regs.h>
+#include <mach/sbc-regs.h>
+
+struct boot_device_info boot_device_table[] = {
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "External Master"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_MMC1, "eMMC (3.3V, Boot Oparation)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_MMC1, "eMMC (1.8V, Boot Oparation)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_MMC1, "eMMC (3.3V, Normal)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_MMC1, "eMMC (1.8V, Normal)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 128KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 256KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, EraseSize 512KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 128KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 256KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, EraseSize 512KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 4, ECC 24, EraseSize 1MB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 128KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 256KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, EraseSize 512KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 128KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 256KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, EraseSize 512KB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 24, EraseSize 1MB, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 8, ONFI, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 1, ECC 16, ONFI, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 4, ECC 24, ONFI, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 8, ONFI, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 16, ONFI, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NAND, "NAND (Mirror 8, ECC 24, ONFI, Addr 5)"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ {BOOT_DEVICE_NONE, "Reserved"},
+ { /* sentinel */ }
+};
+
+int get_boot_mode_sel(void)
+{
+ return readl(SG_PINMON0) & 0x3f;
+}
+
+u32 spl_boot_device(void)
+{
+ int boot_mode;
+
+ if (boot_is_swapped())
+ return BOOT_DEVICE_NOR;
+
+ boot_mode = get_boot_mode_sel();
+
+ return boot_device_table[boot_mode].type;
+}
--- /dev/null
+#include "../ph1-pro4/clkrst_init.c"
--- /dev/null
+#include "../ph1-pro4/early_clkrst_init.c"
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <mach/sg-regs.h>
+
+void early_pin_init(void)
+{
+ /* Comment format: PAD Name -> Function Name */
+
+#ifdef CONFIG_UNIPHIER_SERIAL
+ sg_set_pinsel(63, 0); /* RXD0 */
+ sg_set_pinsel(64, 1); /* TXD0 */
+
+ sg_set_pinsel(65, 0); /* RXD1 */
+ sg_set_pinsel(66, 1); /* TXD1 */
+
+ sg_set_pinsel(96, 2); /* RXD2 */
+ sg_set_pinsel(102, 2); /* TXD2 */
+#endif
+}
--- /dev/null
+/*
+ * On-chip UART initializaion for low-level debugging
+ *
+ * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <linux/linkage.h>
+#include <mach/bcu-regs.h>
+#include <mach/sc-regs.h>
+#include <mach/sg-regs.h>
+#include <mach/debug-uart.S>
+
+ENTRY(setup_lowlevel_debug)
+ ldr r0, =BCSCR5
+ ldr r1, =0x24440000
+ str r1, [r0]
+
+ ldr r0, =SC_CLKCTRL
+ ldr r1, [r0]
+ orr r1, r1, #SC_CLKCTRL_CEN_PERI
+ str r1, [r0]
+
+ init_debug_uart r0, r1, r2
+
+ set_pinsel 63, 0, r0, r1
+ set_pinsel 64, 1, r0, r1
+
+ mov pc, lr
+ENDPROC(setup_lowlevel_debug)
--- /dev/null
+/*
+ * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/types.h>
+#include <linux/sizes.h>
+#include <mach/sg-regs.h>
+
+static inline u32 sg_memconf_val_ch2(unsigned long size, int num)
+{
+ int size_mb = size / num;
+ u32 ret;
+
+ switch (size_mb) {
+ case SZ_64M:
+ ret = SG_MEMCONF_CH2_SZ_64M;
+ break;
+ case SZ_128M:
+ ret = SG_MEMCONF_CH2_SZ_128M;
+ break;
+ case SZ_256M:
+ ret = SG_MEMCONF_CH2_SZ_256M;
+ break;
+ case SZ_512M:
+ ret = SG_MEMCONF_CH2_SZ_512M;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ switch (num) {
+ case 1:
+ ret |= SG_MEMCONF_CH2_NUM_1;
+ break;
+ case 2:
+ ret |= SG_MEMCONF_CH2_NUM_2;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return ret;
+}
+
+u32 memconf_additional_val(void)
+{
+ return sg_memconf_val_ch2(CONFIG_SDRAM2_SIZE, CONFIG_DDR_NUM_CH2);
+}
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <mach/sg-regs.h>
+
+void pin_init(void)
+{
+#ifdef CONFIG_USB_EHCI_UNIPHIER
+ sg_set_pinsel(13, 0); /* USB0OC */
+ sg_set_pinsel(14, 1); /* USB0VBUS */
+
+ sg_set_pinsel(15, 0); /* USB1OC */
+ sg_set_pinsel(16, 1); /* USB1VBUS */
+
+ sg_set_pinsel(17, 0); /* USB2OC */
+ sg_set_pinsel(18, 1); /* USB2VBUS */
+
+ sg_set_pinsel(19, 0); /* USB3OC */
+ sg_set_pinsel(20, 1); /* USB3VBUS */
+#endif
+}
--- /dev/null
+#include "../ph1-ld4/platdevice.c"
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+void pll_init(void)
+{
+ /* add pll init code here */
+}
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <mach/sc-regs.h>
+
+void enable_dpll_ssc(void)
+{
+ u32 tmp;
+
+ tmp = readl(SC_DPLLCTRL);
+ tmp |= SC_DPLLCTRL_SSC_EN;
+ writel(tmp, SC_DPLLCTRL);
+}
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <mach/sbc-regs.h>
+#include <mach/sg-regs.h>
+
+void sbc_init(void)
+{
+ /* only address/data multiplex mode is supported */
+
+ /*
+ * Only CS1 is connected to support card.
+ * BKSZ[1:0] should be set to "01".
+ */
+ writel(SBCTRL0_ADMULTIPLX_MEM_VALUE, SBCTRL10);
+ writel(SBCTRL1_ADMULTIPLX_MEM_VALUE, SBCTRL11);
+ writel(SBCTRL2_ADMULTIPLX_MEM_VALUE, SBCTRL12);
+
+ if (boot_is_swapped()) {
+ /*
+ * Boot Swap On: boot from external NOR/SRAM
+ * 0x02000000-0x03ffffff is a mirror of 0x00000000-0x01ffffff.
+ *
+ * 0x00000000-0x01efffff, 0x02000000-0x03efffff: memory bank
+ * 0x01f00000-0x01ffffff, 0x03f00000-0x03ffffff: peripherals
+ */
+ writel(0x0000bc01, SBBASE0);
+ } else {
+ /*
+ * Boot Swap Off: boot from mask ROM
+ * 0x00000000-0x01ffffff: mask ROM
+ * 0x02000000-0x03efffff: memory bank (31MB)
+ * 0x03f00000-0x03ffffff: peripherals (1MB)
+ */
+ writel(0x0000be01, SBBASE0); /* dummy */
+ writel(0x0200be01, SBBASE1);
+ }
+
+ sg_set_pinsel(99, 1); /* GPIO26 -> EA24 */
+}
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <linux/io.h>
+#include <mach/sbc-regs.h>
+#include <mach/sg-regs.h>
+
+void sbc_init(void)
+{
+ /* only address/data multiplex mode is supported */
+
+ /* XECS0 : boot/sub memory (boot swap = off/on) */
+ writel(SBCTRL0_ADMULTIPLX_MEM_VALUE, SBCTRL00);
+ writel(SBCTRL1_ADMULTIPLX_MEM_VALUE, SBCTRL01);
+ writel(SBCTRL2_ADMULTIPLX_MEM_VALUE, SBCTRL02);
+
+ /* XECS1 : sub/boot memory (boot swap = off/on) */
+ writel(SBCTRL0_ADMULTIPLX_MEM_VALUE, SBCTRL10);
+ writel(SBCTRL1_ADMULTIPLX_MEM_VALUE, SBCTRL11);
+ writel(SBCTRL2_ADMULTIPLX_MEM_VALUE, SBCTRL12);
+
+ /* XECS2 : peripherals */
+ writel(SBCTRL0_ADMULTIPLX_PERI_VALUE, SBCTRL20);
+ writel(SBCTRL1_ADMULTIPLX_PERI_VALUE, SBCTRL21);
+ writel(SBCTRL2_ADMULTIPLX_PERI_VALUE, SBCTRL22);
+
+ /* base address regsiters */
+ writel(0x0000bc01, SBBASE0);
+ writel(0x0400bc01, SBBASE1);
+ writel(0x0800bf01, SBBASE2);
+
+ sg_set_pinsel(99, 1); /* GPIO26 -> EA24 */
+}
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+void sg_init(void)
+{
+}
--- /dev/null
+/*
+ * Copyright (C) 2011-2015 Masahiro Yamada <yamada.masahiro@socionext.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+
+int umc_init(void)
+{
+ /* add UMC init code here */
+ printf("Implement memory init code\n");
+
+ return 0;
+}
struct clk;
/**
- * struct clk_ops:
+ * struct zynq_clk_ops:
* @set_rate: Function pointer to set_rate() implementation
* @get_rate: Function pointer to get_rate() implementation
*/
-struct clk_ops {
+struct zynq_clk_ops {
int (*set_rate)(struct clk *clk, unsigned long rate);
unsigned long (*get_rate)(struct clk *clk);
};
enum zynq_clk parent;
unsigned int flags;
u32 *reg;
- struct clk_ops ops;
+ struct zynq_clk_ops ops;
};
#define ZYNQ_CLK_FLAGS_HAS_2_DIVS 1
config MPC83xx
bool "MPC83xx"
+ select CREATE_ARCH_SYMLINK
config MPC85xx
bool "MPC85xx"
+ select CREATE_ARCH_SYMLINK
config MPC86xx
bool "MPC86xx"
config 4xx
bool "PPC4xx"
+ select CREATE_ARCH_SYMLINK
endchoice
CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
CONFIG_SYS_PBI_FLASH_WINDOW & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
0, r6
+
+#elif defined(CONFIG_RAMBOOT_PBL) && defined(CONFIG_SECURE_BOOT)
+ /* create a temp mapping in AS = 1 for mapping CONFIG_SYS_MONITOR_BASE
+ * to L3 Address configured by PBL for ISBC code
+ */
+ create_tlb1_entry 15, \
+ 1, BOOKE_PAGESZ_1M, \
+ CONFIG_SYS_MONITOR_BASE & 0xfff00000, MAS2_I|MAS2_G, \
+ CONFIG_SYS_INIT_L3_ADDR & 0xfff00000, MAS3_SX|MAS3_SW|MAS3_SR, \
+ 0, r6
+
#else
/*
* create a temp mapping in AS=1 to the 1M CONFIG_SYS_MONITOR_BASE space, the main
#ifdef CONFIG_SYS_DPAA_FMAN
struct liodn_id_table fman1_liodn_tbl[] = {
- SET_FMAN_RX_1G_LIODN(1, 0, 88),
+ SET_FMAN_RX_10G_TYPE2_LIODN(1, 0, 88),
SET_FMAN_RX_1G_LIODN(1, 1, 89),
SET_FMAN_RX_1G_LIODN(1, 2, 90),
SET_FMAN_RX_1G_LIODN(1, 3, 91),
- SET_FMAN_RX_10G_LIODN(1, 0, 94),
};
int fman1_liodn_tbl_sz = ARRAY_SIZE(fman1_liodn_tbl);
#endif
{4, {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2}},
{5, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1} },
{6, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1}},
- {7, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, NONE, NONE, NONE} },
- {8, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, NONE, NONE, NONE}},
+ {7, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1} },
+ {8, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1} },
{9, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN}},
{10, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
#elif defined(CONFIG_PPC_T4160) || defined(CONFIG_PPC_T4080)
static const struct serdes_config serdes1_cfg_tbl[] = {
/* SerDes 1 */
- {1, {XAUI_FM1_MAC9, XAUI_FM1_MAC9,
- XAUI_FM1_MAC9, XAUI_FM1_MAC9,
+ {1, {NONE, NONE, NONE, NONE,
XAUI_FM1_MAC10, XAUI_FM1_MAC10,
XAUI_FM1_MAC10, XAUI_FM1_MAC10} },
- {2, {HIGIG_FM1_MAC9, HIGIG_FM1_MAC9,
- HIGIG_FM1_MAC9, HIGIG_FM1_MAC9,
+ {2, {NONE, NONE, NONE, NONE,
HIGIG_FM1_MAC10, HIGIG_FM1_MAC10,
HIGIG_FM1_MAC10, HIGIG_FM1_MAC10} },
- {4, {HIGIG_FM1_MAC9, HIGIG_FM1_MAC9,
- HIGIG_FM1_MAC9, HIGIG_FM1_MAC9,
+ {4, {NONE, NONE, NONE, NONE,
HIGIG_FM1_MAC10, HIGIG_FM1_MAC10,
HIGIG_FM1_MAC10, HIGIG_FM1_MAC10} },
- {27, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
- SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC9,
+ {27, {NONE, NONE, NONE, NONE,
SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4} },
- {28, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
- SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC9,
+ {28, {NONE, NONE, NONE, NONE,
SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4} },
- {35, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
- SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC9,
+ {35, {NONE, NONE, NONE, NONE,
SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4} },
- {36, {SGMII_FM1_DTSEC5, SGMII_FM1_DTSEC6,
- SGMII_FM1_DTSEC10, SGMII_FM1_DTSEC9,
+ {36, {NONE, NONE, NONE, NONE,
SGMII_FM1_DTSEC1, SGMII_FM1_DTSEC2,
SGMII_FM1_DTSEC3, SGMII_FM1_DTSEC4} },
- {37, {NONE, NONE, QSGMII_FM1_B, NONE,
+ {37, {NONE, NONE, NONE, NONE,
NONE, NONE, QSGMII_FM1_A, NONE} },
- {38, {NONE, NONE, QSGMII_FM1_B, NONE,
+ {38, {NONE, NONE, NONE, NONE,
NONE, NONE, QSGMII_FM1_A, NONE} },
{}
};
SGMII_FM2_DTSEC1, SGMII_FM2_DTSEC2,
SGMII_FM2_DTSEC3, SGMII_FM2_DTSEC4} },
{37, {NONE, NONE, QSGMII_FM2_B, NONE,
- NONE, QSGMII_FM1_A, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{38, {NONE, NONE, QSGMII_FM2_B, NONE,
- NONE, QSGMII_FM1_A, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{39, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,
SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9,
- NONE, QSGMII_FM1_A, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{40, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,
SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9,
- NONE, QSGMII_FM1_A, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{45, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,
SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9,
- NONE, QSGMII_FM1_A, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{46, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,
SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9,
- NONE, QSGMII_FM1_A, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{47, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,
SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9,
- NONE, QSGMII_FM1_A, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{48, {SGMII_FM2_DTSEC5, SGMII_FM2_DTSEC6,
SGMII_FM2_DTSEC10, SGMII_FM2_DTSEC9,
- NONE, QSGMII_FM1_A, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{49, {XAUI_FM2_MAC9, XAUI_FM2_MAC9,
XAUI_FM2_MAC9, XAUI_FM2_MAC9,
- NONE, NONE, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{50, {XAUI_FM2_MAC9, XAUI_FM2_MAC9,
XAUI_FM2_MAC9, XAUI_FM2_MAC9,
- NONE, NONE, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{51, {HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,
HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,
- NONE, NONE, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{52, {HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,
HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,
- NONE, NONE, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{53, {HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,
HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,
- NONE, NONE, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{54, {HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,
HIGIG_FM2_MAC9, HIGIG_FM2_MAC9,
- NONE, NONE, NONE, NONE} },
+ NONE, NONE, QSGMII_FM2_A, NONE} },
{55, {NONE, XFI_FM1_MAC10,
XFI_FM2_MAC10, NONE,
SGMII_FM2_DTSEC1, SGMII_FM2_DTSEC2,
{4, {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2} },
{5, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1} },
{6, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1} },
- {7, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, NONE, NONE, NONE} },
- {8, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, NONE, NONE, NONE} },
+ {7, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1} },
+ {8, {PCIE1, PCIE1, PCIE1, PCIE1, SRIO1, SRIO1, SRIO1, SRIO1} },
{9, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN} },
{10, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN} },
- {11, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
+ {11, {NONE, NONE, NONE, NONE,
PCIE2, PCIE2, PCIE2, PCIE2} },
- {12, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
+ {12, {NONE, NONE, NONE, NONE,
PCIE2, PCIE2, PCIE2, PCIE2} },
{13, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
PCIE2, PCIE2, PCIE2, PCIE2} },
{14, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
PCIE2, PCIE2, PCIE2, PCIE2} },
- {15, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
+ {15, {NONE, NONE, NONE, NONE,
SRIO1, SRIO1, SRIO1, SRIO1} },
- {16, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
+ {16, {NONE, NONE, NONE, NONE,
SRIO1, SRIO1, SRIO1, SRIO1} },
- {17, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
+ {17, {NONE, NONE, NONE, NONE,
SRIO1, SRIO1, SRIO1, SRIO1} },
{18, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
SRIO1, SRIO1, SRIO1, SRIO1} },
{19, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
SRIO1, SRIO1, SRIO1, SRIO1} },
{20, {INTERLAKEN, INTERLAKEN, INTERLAKEN, INTERLAKEN,
- NONE, NONE, NONE, NONE} },
+ SRIO1, SRIO1, SRIO1, SRIO1} },
{}
};
static const struct serdes_config serdes4_cfg_tbl[] = {
/* SerDes 4 */
- {3, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4} },
- {4, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4} },
- {5, {SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2} },
- {6, {SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2} },
- {7, {SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2} },
- {8, {SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2, SRIO2} },
- {9, {PCIE3, PCIE3, PCIE3, PCIE3, SATA1, SATA1, SATA2, SATA2} },
- {10, {PCIE3, PCIE3, PCIE3, PCIE3, SATA1, SATA1, SATA2, SATA2} },
- {11, {AURORA, AURORA, AURORA, AURORA, SATA1, SATA1, SATA2, SATA2} },
- {12, {AURORA, AURORA, AURORA, AURORA, SATA1, SATA1, SATA2, SATA2} },
- {13, {AURORA, AURORA, AURORA, AURORA, SRIO2, SRIO2, SRIO2, SRIO2} },
- {14, {AURORA, AURORA, AURORA, AURORA, SRIO2, SRIO2, SRIO2, SRIO2} },
- {15, {AURORA, AURORA, AURORA, AURORA, SRIO2, SRIO2, SRIO2, SRIO2} },
- {16, {AURORA, AURORA, AURORA, AURORA, SRIO2, SRIO2, SRIO2, SRIO2} },
- {18, {AURORA, AURORA, AURORA, AURORA, AURORA, AURORA, AURORA, AURORA} },
+ {3, {NONE, NONE, NONE, NONE, PCIE4, PCIE4, PCIE4, PCIE4} },
+ {4, {NONE, NONE, NONE, NONE, PCIE4, PCIE4, PCIE4, PCIE4} },
+ {5, {NONE, NONE, NONE, NONE, SRIO2, SRIO2, SRIO2, SRIO2} },
+ {6, {NONE, NONE, NONE, NONE, SRIO2, SRIO2, SRIO2, SRIO2} },
+ {7, {NONE, NONE, NONE, NONE, SRIO2, SRIO2, SRIO2, SRIO2} },
+ {8, {NONE, NONE, NONE, NONE, SRIO2, SRIO2, SRIO2, SRIO2} },
+ {9, {NONE, NONE, NONE, NONE, PCIE4, PCIE4, SATA1, SATA2} },
+ {10, {NONE, NONE, NONE, NONE, PCIE4, PCIE4, SATA1, SATA2} },
+ {11, {NONE, NONE, NONE, NONE, AURORA, AURORA, SATA1, SATA2} },
+ {12, {NONE, NONE, NONE, NONE, AURORA, AURORA, SATA1, SATA2} },
+ {13, {NONE, NONE, NONE, NONE, AURORA, AURORA, SRIO2, SRIO2} },
+ {14, {NONE, NONE, NONE, NONE, AURORA, AURORA, SRIO2, SRIO2} },
+ {15, {NONE, NONE, NONE, NONE, AURORA, AURORA, SRIO2, SRIO2} },
+ {16, {NONE, NONE, NONE, NONE, AURORA, AURORA, SRIO2, SRIO2} },
+ {18, {NONE, NONE, NONE, NONE, AURORA, AURORA, AURORA, AURORA} },
{}
}
;
#elif defined(CONFIG_P1025)
#define CONFIG_MAX_CPUS 2
#define CONFIG_SYS_FSL_NUM_LAWS 12
-#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#define CONFIG_SYS_PPC_E500_DEBUG_TLB 2
#define CONFIG_TSECV2
#define CONFIG_FSL_PCIE_DISABLE_ASPM
#define QE_MURAM_SIZE 0x6000UL
#define MAX_QE_RISC 1
#define QE_NUM_OF_SNUM 28
+#define CONFIG_SYS_FSL_SFP_VER_3_0
#elif defined(CONFIG_PPC_T1024) || defined(CONFIG_PPC_T1023) ||\
defined(CONFIG_PPC_T1014) || defined(CONFIG_PPC_T1013)
FM_PPID_RX_PORT_OFFSET(fmNum, enetNum + 16), \
CONFIG_SYS_FSL_FM##fmNum##_RX##enetNum##_10G_OFFSET) \
+/* enetNum is 0, 1, 2... so we + 8 for type-2 10g to get to HW Port ID */
+#define SET_FMAN_RX_10G_TYPE2_LIODN(fmNum, enetNum, liodn) \
+ SET_LIODN_ENTRY_1("fsl,fman-port-10g-rx", liodn, \
+ FM_PPID_RX_PORT_OFFSET(fmNum, enetNum + 8), \
+ CONFIG_SYS_FSL_FM##fmNum##_RX##enetNum##_1G_OFFSET) \
+
/*
* handle both old and new versioned SEC properties:
* "fsl,secX.Y" became "fsl,sec-vX.Y" during development
defined(CONFIG_T2080QDS) || \
defined(CONFIG_T2080RDB) || \
defined(CONFIG_T1040QDS) || \
+ defined(CONFIG_T104xD4QDS) || \
defined(CONFIG_T104xRDB) || \
+ defined(CONFIG_T104xD4RDB) || \
defined(CONFIG_PPC_T1023) || \
defined(CONFIG_PPC_T1024)
#define CONFIG_SYS_CPC_REINIT_F
#define CONFIG_SYS_INIT_L3_ADDR 0xbff00000
#endif
+#if defined(CONFIG_RAMBOOT_PBL)
+#undef CONFIG_SYS_INIT_L3_ADDR
+#define CONFIG_SYS_INIT_L3_ADDR 0xbff00000
+#endif
+
#if defined(CONFIG_C29XPCIE)
#define CONFIG_KEY_REVOCATION
#endif
#endif
#ifndef CONFIG_FIT_SIGNATURE
+/* If Boot Script is not on NOR and is required to be copied on RAM */
+#ifdef CONFIG_BOOTSCRIPT_COPY_RAM
+#define CONFIG_BS_HDR_ADDR_RAM 0x00010000
+#define CONFIG_BS_HDR_ADDR_FLASH 0x00800000
+#define CONFIG_BS_HDR_SIZE 0x00002000
+#define CONFIG_BS_ADDR_RAM 0x00012000
+#define CONFIG_BS_ADDR_FLASH 0x00802000
+#define CONFIG_BS_SIZE 0x00001000
+
+#define CONFIG_BOOTSCRIPT_HDR_ADDR CONFIG_BS_HDR_ADDR_RAM
+#else
+
/* The bootscript header address is different for B4860 because the NOR
* mapping is different on B4 due to reduced NOR size.
*/
#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xee020000
#endif
+#endif
+
#include <config_fsl_secboot.h>
#endif
unsigned long map_len;
#endif
-void reset_cpu(ulong ignored)
+void sandbox_exit(void)
{
/* Do this here while it still has an effect */
os_fd_restore();
os_exit(0);
}
-int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
- reset_cpu(0);
-
- return 0;
-}
-
/* delay x useconds */
void __udelay(unsigned long usec)
{
state->ram_buf = os_malloc(state->ram_size);
assert(state->ram_buf);
+ /* No reset yet, so mark it as such. Always allow power reset */
+ state->last_reset = RESET_COUNT;
+ state->reset_allowed[RESET_POWER] = true;
+
/*
* Example of how to use GPIOs:
*
model = "sandbox";
compatible = "sandbox";
#address-cells = <1>;
- #size-cells = <0>;
+ #size-cells = <1>;
aliases {
console = &uart0;
};
a-test {
- reg = <0>;
+ reg = <0 1>;
compatible = "denx,u-boot-fdt-test";
ping-expect = <0>;
ping-add = <0>;
};
junk {
- reg = <1>;
+ reg = <1 1>;
compatible = "not,compatible";
};
no-compatible {
- reg = <2>;
+ reg = <2 1>;
};
b-test {
- reg = <3>;
+ reg = <3 1>;
compatible = "denx,u-boot-fdt-test";
ping-expect = <3>;
ping-add = <3>;
#address-cells = <1>;
#size-cells = <0>;
compatible = "denx,u-boot-test-bus";
- reg = <3>;
+ reg = <3 1>;
ping-expect = <4>;
ping-add = <4>;
c-test@5 {
};
d-test {
- reg = <3>;
+ reg = <3 1>;
ping-expect = <6>;
ping-add = <6>;
compatible = "google,another-fdt-test";
};
e-test {
- reg = <3>;
+ reg = <3 1>;
ping-expect = <6>;
ping-add = <6>;
compatible = "google,another-fdt-test";
compatible = "denx,u-boot-fdt-test";
};
+ clk@0 {
+ compatible = "sandbox,clk";
+ };
+
eth@10002000 {
compatible = "sandbox,eth";
reg = <0x10002000 0x1000>;
i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
- reg = <0>;
+ reg = <0 1>;
compatible = "sandbox,i2c";
clock-frequency = <100000>;
eeprom@2c {
};
};
+ leds {
+ compatible = "gpio-leds";
+
+ iracibble {
+ gpios = <&gpio_a 1 0>;
+ label = "sandbox:red";
+ };
+
+ martinet {
+ gpios = <&gpio_a 2 0>;
+ label = "sandbox:green";
+ };
+ };
+
+ mmc {
+ compatible = "sandbox,mmc";
+ };
+
pci: pci-controller {
compatible = "sandbox,pci";
device_type = "pci";
};
};
+ ram {
+ compatible = "sandbox,ram";
+ };
+
+ reset@0 {
+ compatible = "sandbox,warm-reset";
+ };
+
+ reset@1 {
+ compatible = "sandbox,reset";
+ };
+
spi@0 {
#address-cells = <1>;
#size-cells = <0>;
- reg = <0>;
+ reg = <0 1>;
compatible = "sandbox,spi";
cs-gpios = <0>, <&gpio_a 0>;
spi.bin@0 {
};
};
+ syscon@0 {
+ compatible = "sandbox,syscon0";
+ reg = <0x10 4>;
+ };
+
+ syscon@1 {
+ compatible = "sandbox,syscon1";
+ reg = <0x20 5
+ 0x28 6
+ 0x30 7
+ 0x38 8>;
+ };
+
uart0: serial {
compatible = "sandbox,serial";
u-boot,dm-pre-reloc;
#define __SANDBOX_STATE_H
#include <config.h>
+#include <reset.h>
#include <stdbool.h>
#include <linux/stringify.h>
bool write_state; /* Write sandbox state on exit */
bool ignore_missing_state_on_read; /* No error if state missing */
bool show_lcd; /* Show LCD on start-up */
+ enum reset_t last_reset; /* Last reset type */
+ bool reset_allowed[RESET_COUNT]; /* Allowed reset types */
enum state_terminal_raw term_raw; /* Terminal raw/cooked */
/* Pointer to information for each SPI bus/cs */
#define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
#define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
+#define SANDBOX_CLK_RATE 32768
+
+enum {
+ PERIPH_ID_FIRST = 0,
+ PERIPH_ID_SPI = PERIPH_ID_FIRST,
+ PERIPH_ID_I2C,
+ PERIPH_ID_PCI,
+
+ PERIPH_ID_COUNT,
+};
+
+/* System controller driver data */
+enum {
+ SYSCON0 = 32,
+ SYSCON1,
+
+ SYSCON_COUNT
+};
+
/**
* sandbox_i2c_set_test_mode() - set test mode for running unit tests
*
*/
int sandbox_read_fdt_from_file(void);
+/* Exit sandbox (quit U-Boot) */
+void sandbox_exit(void);
+
#endif /* _U_BOOT_SANDBOX_H_ */
assigned to PCI devices - i.e. the memory and prefetch regions, as
passed to pci_set_region().
+config PCIE_ECAM_SIZE
+ hex
+ default 0x10000000
+ help
+ This is the size of memory-mapped address of PCI configuration space,
+ which is only available through the Enhanced Configuration Access
+ Mechanism (ECAM) with PCI Express. Each bus consumes 1 MiB memory,
+ so a default 0x10000000 size covers all of the 256 buses which is the
+ maximum number of PCI buses as defined by the PCI specification.
+
endmenu
mtrr_cap = native_read_msr(MTRR_CAP_MSR);
if (mtrr_cap & MTRR_CAP_FIX) {
/* Mark the VGA RAM area as uncacheable */
- native_write_msr(MTRR_FIX_16K_A0000_MSR, 0, 0);
-
- /* Mark the PCI ROM area as uncacheable */
- native_write_msr(MTRR_FIX_4K_C0000_MSR, 0, 0);
- native_write_msr(MTRR_FIX_4K_C8000_MSR, 0, 0);
- native_write_msr(MTRR_FIX_4K_D0000_MSR, 0, 0);
- native_write_msr(MTRR_FIX_4K_D8000_MSR, 0, 0);
+ native_write_msr(MTRR_FIX_16K_A0000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE),
+ MTRR_FIX_TYPE(MTRR_TYPE_UNCACHEABLE));
+
+ /*
+ * Mark the PCI ROM area as cacheable to improve ROM
+ * execution performance.
+ */
+ native_write_msr(MTRR_FIX_4K_C0000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+ native_write_msr(MTRR_FIX_4K_C8000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+ native_write_msr(MTRR_FIX_4K_D0000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
+ native_write_msr(MTRR_FIX_4K_D8000_MSR,
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK),
+ MTRR_FIX_TYPE(MTRR_TYPE_WRBACK));
/* Enable the fixed range MTRRs */
msr_setbits_64(MTRR_DEF_TYPE_MSR, MTRR_DEF_TYPE_FIX_EN);
#ifdef CONFIG_SMP
debug("Init additional CPUs\n");
x86_mp_init();
+#else
+ struct udevice *dev;
+
+ /*
+ * This causes the cpu-x86 driver to be probed.
+ * We don't check return value here as we want to allow boards
+ * which have not been converted to use cpu uclass driver to boot.
+ */
+ uclass_first_device(UCLASS_CPU, &dev);
#endif
return 0;
"pushl $"#x"\n" \
"jmp irq_common_entry\n"
+static char *exceptions[] = {
+ "Divide Error",
+ "Debug",
+ "NMI Interrupt",
+ "Breakpoint",
+ "Overflow",
+ "BOUND Range Exceeded",
+ "Invalid Opcode (Undefined Opcode)",
+ "Device Not Avaiable (No Math Coprocessor)",
+ "Double Fault",
+ "Coprocessor Segment Overrun",
+ "Invalid TSS",
+ "Segment Not Present",
+ "Stack Segment Fault",
+ "Gerneral Protection",
+ "Page Fault",
+ "Reserved",
+ "x87 FPU Floating-Point Error",
+ "Alignment Check",
+ "Machine Check",
+ "SIMD Floating-Point Exception",
+ "Virtualization Exception",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved",
+ "Reserved"
+};
+
static void dump_regs(struct irq_regs *regs)
{
+ unsigned long cs, eip, eflags;
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
unsigned long d0, d1, d2, d3, d6, d7;
unsigned long sp;
+ /*
+ * Some exceptions cause an error code to be saved on the current stack
+ * after the EIP value. We should extract CS/EIP/EFLAGS from different
+ * position on the stack based on the exception number.
+ */
+ switch (regs->irq_id) {
+ case EXC_DF:
+ case EXC_TS:
+ case EXC_NP:
+ case EXC_SS:
+ case EXC_GP:
+ case EXC_PF:
+ case EXC_AC:
+ cs = regs->context.ctx2.xcs;
+ eip = regs->context.ctx2.eip;
+ eflags = regs->context.ctx2.eflags;
+ /* We should fix up the ESP due to error code */
+ regs->esp += 4;
+ break;
+ default:
+ cs = regs->context.ctx1.xcs;
+ eip = regs->context.ctx1.eip;
+ eflags = regs->context.ctx1.eflags;
+ break;
+ }
+
printf("EIP: %04x:[<%08lx>] EFLAGS: %08lx\n",
- (u16)regs->xcs, regs->eip, regs->eflags);
+ (u16)cs, eip, eflags);
printf("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
regs->eax, regs->ebx, regs->ecx, regs->edx);
}
}
+static void do_exception(struct irq_regs *regs)
+{
+ printf("%s\n", exceptions[regs->irq_id]);
+ dump_regs(regs);
+ hang();
+}
+
struct idt_entry {
u16 base_low;
u16 selector;
* Order Number: 253665-029US, November 2008
* Table 6-1. Exceptions and Interrupts
*/
- switch (regs->irq_id) {
- case 0x00:
- printf("Divide Error (Division by zero)\n");
- dump_regs(regs);
- hang();
- break;
- case 0x01:
- printf("Debug Interrupt (Single step)\n");
- dump_regs(regs);
- break;
- case 0x02:
- printf("NMI Interrupt\n");
- dump_regs(regs);
- break;
- case 0x03:
- printf("Breakpoint\n");
- dump_regs(regs);
- break;
- case 0x04:
- printf("Overflow\n");
- dump_regs(regs);
- hang();
- break;
- case 0x05:
- printf("BOUND Range Exceeded\n");
- dump_regs(regs);
- hang();
- break;
- case 0x06:
- printf("Invalid Opcode (UnDefined Opcode)\n");
- dump_regs(regs);
- hang();
- break;
- case 0x07:
- printf("Device Not Available (No Math Coprocessor)\n");
- dump_regs(regs);
- hang();
- break;
- case 0x08:
- printf("Double fault\n");
- dump_regs(regs);
- hang();
- break;
- case 0x09:
- printf("Co-processor segment overrun\n");
- dump_regs(regs);
- hang();
- break;
- case 0x0a:
- printf("Invalid TSS\n");
- dump_regs(regs);
- break;
- case 0x0b:
- printf("Segment Not Present\n");
- dump_regs(regs);
- hang();
- break;
- case 0x0c:
- printf("Stack Segment Fault\n");
- dump_regs(regs);
- hang();
- break;
- case 0x0d:
- printf("General Protection\n");
- dump_regs(regs);
- break;
- case 0x0e:
- printf("Page fault\n");
- dump_regs(regs);
- hang();
- break;
- case 0x0f:
- printf("Floating-Point Error (Math Fault)\n");
- dump_regs(regs);
- break;
- case 0x10:
- printf("Alignment check\n");
- dump_regs(regs);
- break;
- case 0x11:
- printf("Machine Check\n");
- dump_regs(regs);
- break;
- case 0x12:
- printf("SIMD Floating-Point Exception\n");
- dump_regs(regs);
- break;
- case 0x13:
- case 0x14:
- case 0x15:
- case 0x16:
- case 0x17:
- case 0x18:
- case 0x19:
- case 0x1a:
- case 0x1b:
- case 0x1c:
- case 0x1d:
- case 0x1e:
- case 0x1f:
- printf("Reserved Exception\n");
- dump_regs(regs);
- break;
-
- default:
+ if (regs->irq_id < 32) {
+ /* Architecture defined exception */
+ do_exception(regs);
+ } else {
/* Hardware or User IRQ */
do_irq(regs->irq_id);
}
#include <asm/pci.h>
#include <asm/arch/pch.h>
#include <asm/arch/sandybridge.h>
-#include <linux/kconfig.h>
struct gt_powermeter {
u16 reg;
/* TODO: Handle power failure */
if (rtc_failed)
printf("RTC power failed\n");
- rtc_init();
}
/* CougarPoint PCH Power Management init */
static int read_seed_from_cmos(struct pei_data *pei_data)
{
u16 c1, c2, checksum, seed_checksum;
+ struct udevice *dev;
+ int rcode = 0;
+
+ rcode = uclass_get_device(UCLASS_RTC, 0, &dev);
+ if (rcode) {
+ debug("Cannot find RTC: err=%d\n", rcode);
+ return -ENODEV;
+ }
/*
* Read scrambler seeds from CMOS RAM. We don't want to store them in
* the flash too much. So we store these in CMOS and the large MRC
* data in SPI flash.
*/
- pei_data->scrambler_seed = rtc_read32(CMOS_OFFSET_MRC_SEED);
+ rtc_read32(dev, CMOS_OFFSET_MRC_SEED, &pei_data->scrambler_seed);
debug("Read scrambler seed 0x%08x from CMOS 0x%02x\n",
pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);
- pei_data->scrambler_seed_s3 = rtc_read32(CMOS_OFFSET_MRC_SEED_S3);
+ rtc_read32(dev, CMOS_OFFSET_MRC_SEED_S3, &pei_data->scrambler_seed_s3);
debug("Read S3 scrambler seed 0x%08x from CMOS 0x%02x\n",
pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);
sizeof(u32));
checksum = add_ip_checksums(sizeof(u32), c1, c2);
- seed_checksum = rtc_read8(CMOS_OFFSET_MRC_SEED_CHK);
- seed_checksum |= rtc_read8(CMOS_OFFSET_MRC_SEED_CHK + 1) << 8;
+ seed_checksum = rtc_read8(dev, CMOS_OFFSET_MRC_SEED_CHK);
+ seed_checksum |= rtc_read8(dev, CMOS_OFFSET_MRC_SEED_CHK + 1) << 8;
if (checksum != seed_checksum) {
debug("%s: invalid seed checksum\n", __func__);
static int write_seeds_to_cmos(struct pei_data *pei_data)
{
u16 c1, c2, checksum;
+ struct udevice *dev;
+ int rcode = 0;
+
+ rcode = uclass_get_device(UCLASS_RTC, 0, &dev);
+ if (rcode) {
+ debug("Cannot find RTC: err=%d\n", rcode);
+ return -ENODEV;
+ }
/* Save the MRC seed values to CMOS */
- rtc_write32(CMOS_OFFSET_MRC_SEED, pei_data->scrambler_seed);
+ rtc_write32(dev, CMOS_OFFSET_MRC_SEED, pei_data->scrambler_seed);
debug("Save scrambler seed 0x%08x to CMOS 0x%02x\n",
pei_data->scrambler_seed, CMOS_OFFSET_MRC_SEED);
- rtc_write32(CMOS_OFFSET_MRC_SEED_S3, pei_data->scrambler_seed_s3);
+ rtc_write32(dev, CMOS_OFFSET_MRC_SEED_S3, pei_data->scrambler_seed_s3);
debug("Save s3 scrambler seed 0x%08x to CMOS 0x%02x\n",
pei_data->scrambler_seed_s3, CMOS_OFFSET_MRC_SEED_S3);
sizeof(u32));
checksum = add_ip_checksums(sizeof(u32), c1, c2);
- rtc_write8(CMOS_OFFSET_MRC_SEED_CHK, checksum & 0xff);
- rtc_write8(CMOS_OFFSET_MRC_SEED_CHK + 1, (checksum >> 8) & 0xff);
+ rtc_write8(dev, CMOS_OFFSET_MRC_SEED_CHK, checksum & 0xff);
+ rtc_write8(dev, CMOS_OFFSET_MRC_SEED_CHK + 1, (checksum >> 8) & 0xff);
return 0;
}
return 0;
}
-void pci_assign_irqs(int bus, int device, int func, u8 irq[4])
+void pci_assign_irqs(int bus, int device, u8 irq[4])
{
pci_dev_t bdf;
+ int func;
+ u16 vendor;
u8 pin, line;
- bdf = PCI_BDF(bus, device, func);
+ for (func = 0; func < 8; func++) {
+ bdf = PCI_BDF(bus, device, func);
+ vendor = x86_pci_read_config16(bdf, PCI_VENDOR_ID);
+ if (vendor == 0xffff || vendor == 0x0000)
+ continue;
- pin = x86_pci_read_config8(bdf, PCI_INTERRUPT_PIN);
+ pin = x86_pci_read_config8(bdf, PCI_INTERRUPT_PIN);
- /* PCI spec says all values except 1..4 are reserved */
- if ((pin < 1) || (pin > 4))
- return;
+ /* PCI spec says all values except 1..4 are reserved */
+ if ((pin < 1) || (pin > 4))
+ continue;
- line = irq[pin - 1];
+ line = irq[pin - 1];
+ if (!line)
+ continue;
- debug("Assigning IRQ %d to PCI device %d.%x.%d (INT%c)\n",
- line, bus, device, func, 'A' + pin - 1);
+ debug("Assigning IRQ %d to PCI device %d.%x.%d (INT%c)\n",
+ line, bus, device, func, 'A' + pin - 1);
- x86_pci_write_config8(bdf, PCI_INTERRUPT_LINE, line);
+ x86_pci_write_config8(bdf, PCI_INTERRUPT_LINE, line);
+ }
}
DECLARE_GLOBAL_DATA_PTR;
+static bool i440fx;
+
void board_pci_setup_hose(struct pci_controller *hose)
{
hose->first_busno = 0;
int board_pci_post_scan(struct pci_controller *hose)
{
int ret = 0;
- u16 device;
+ u16 device, xbcs;
int pam, i;
pci_dev_t vga;
ulong start;
* PCI device ID.
*/
device = x86_pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID);
- pam = (device == PCI_DEVICE_ID_INTEL_82441) ? I440FX_PAM : Q35_PAM;
+ i440fx = (device == PCI_DEVICE_ID_INTEL_82441);
+ pam = i440fx ? I440FX_PAM : Q35_PAM;
/*
* Initialize Programmable Attribute Map (PAM) Registers
for (i = 0; i < PAM_NUM; i++)
x86_pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW);
- if (device == PCI_DEVICE_ID_INTEL_82441) {
+ if (i440fx) {
/*
* Enable legacy IDE I/O ports decode
*
*/
x86_pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN);
x86_pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN);
+
+ /* Enable I/O APIC */
+ xbcs = x86_pci_read_config16(PIIX_ISA, XBCS);
+ xbcs |= APIC_EN;
+ x86_pci_write_config16(PIIX_ISA, XBCS, xbcs);
+ } else {
+ /* Configure PCIe ECAM base address */
+ x86_pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR,
+ CONFIG_PCIE_ECAM_BASE | BAR_EN);
}
/*
* board, it shows as device 2, while for Q35 and ICH9 chipset board,
* it shows as device 1.
*/
- vga = (device == PCI_DEVICE_ID_INTEL_82441) ? I440FX_VGA : Q35_VGA;
+ vga = i440fx ? I440FX_VGA : Q35_VGA;
start = get_timer(0);
ret = pci_run_vga_bios(vga, NULL, PCI_ROM_USE_NATIVE);
debug("BIOS ran in %lums\n", get_timer(start));
return ret;
}
+
+#ifdef CONFIG_GENERATE_MP_TABLE
+int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq)
+{
+ u8 irq;
+
+ if (i440fx) {
+ /*
+ * Not like most x86 platforms, the PIRQ[A-D] on PIIX3 are not
+ * connected to I/O APIC INTPIN#16-19. Instead they are routed
+ * to an irq number controled by the PIRQ routing register.
+ */
+ irq = x86_pci_read_config8(PCI_BDF(bus, dev, func),
+ PCI_INTERRUPT_LINE);
+ } else {
+ /*
+ * ICH9's PIRQ[A-H] are not consecutive numbers from 0 to 7.
+ * PIRQ[A-D] still maps to [0-3] but PIRQ[E-H] maps to [8-11].
+ */
+ irq = pirq < 8 ? pirq + 16 : pirq + 12;
+ }
+
+ return irq;
+}
+#endif
obj-y += fsp_configs.o
obj-y += tnc.o topcliff.o
-obj-$(CONFIG_PCI) += tnc_pci.o
int arch_cpu_init(void)
{
- struct pci_controller *hose;
int ret;
post_code(POST_CPU_INIT);
if (ret)
return ret;
- ret = pci_early_init_hose(&hose);
- if (ret)
- return ret;
-
unprotect_spi_flash();
return 0;
+++ /dev/null
-/*
- * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <pci.h>
-#include <asm/pci.h>
-#include <asm/fsp/fsp_support.h>
-
-DECLARE_GLOBAL_DATA_PTR;
-
-void board_pci_setup_hose(struct pci_controller *hose)
-{
- hose->first_busno = 0;
- hose->last_busno = 0;
-
- /* PCI memory space */
- pci_set_region(hose->regions + 0,
- CONFIG_PCI_MEM_BUS,
- CONFIG_PCI_MEM_PHYS,
- CONFIG_PCI_MEM_SIZE,
- PCI_REGION_MEM);
-
- /* PCI IO space */
- pci_set_region(hose->regions + 1,
- CONFIG_PCI_IO_BUS,
- CONFIG_PCI_IO_PHYS,
- CONFIG_PCI_IO_SIZE,
- PCI_REGION_IO);
-
- pci_set_region(hose->regions + 2,
- CONFIG_PCI_PREF_BUS,
- CONFIG_PCI_PREF_PHYS,
- CONFIG_PCI_PREF_SIZE,
- PCI_REGION_PREFETCH);
-
- pci_set_region(hose->regions + 3,
- 0,
- 0,
- gd->ram_size,
- PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
-
- hose->region_count = 4;
-}
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
+/include/ "rtc.dtsi"
/ {
model = "Google Link";
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
+/include/ "rtc.dtsi"
/ {
model = "Google Panther";
pci {
#address-cells = <3>;
#size-cells = <2>;
- compatible = "intel,pci";
+ compatible = "pci-x86";
device_type = "pci";
+ u-boot,dm-pre-reloc;
+ ranges = <0x02000000 0x0 0x40000000 0x40000000 0 0x80000000
+ 0x42000000 0x0 0xc0000000 0xc0000000 0 0x20000000
+ 0x01000000 0x0 0x2000 0x2000 0 0xe000>;
pcie@17,0 {
#address-cells = <3>;
#include <dt-bindings/interrupt-router/intel-irq.h>
/include/ "skeleton.dtsi"
+/include/ "rtc.dtsi"
/ {
model = "Intel Galileo";
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
+/include/ "rtc.dtsi"
/ {
model = "Intel Minnowboard Max";
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
+/include/ "rtc.dtsi"
/ {
model = "QEMU x86 (I440FX)";
stdout-path = "/serial";
};
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "cpu-x86";
+ reg = <0>;
+ intel,apic-id = <0>;
+ };
+ };
+
pci {
compatible = "pci-x86";
#address-cells = <3>;
/include/ "skeleton.dtsi"
/include/ "serial.dtsi"
+/include/ "rtc.dtsi"
/ {
model = "QEMU x86 (Q35)";
stdout-path = "/serial";
};
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "cpu-x86";
+ reg = <0>;
+ intel,apic-id = <0>;
+ };
+ };
+
pci {
compatible = "pci-x86";
#address-cells = <3>;
/ {
rtc {
compatible = "motorola,mc146818";
+ u-boot,dm-pre-reloc;
reg = <0x70 2>;
};
};
#define PAM_NUM 7
#define PAM_RW 0x33
+/* X-Bus Chip Select Register */
+#define XBCS 0x4e
+#define APIC_EN (1 << 8)
+
/* IDE Timing Register */
#define IDE0_TIM 0x40
#define IDE1_TIM 0x42
-#define IDE_DECODE_EN 0x8000
+#define IDE_DECODE_EN (1 << 15)
+
+/* PCIe ECAM Base Address Register */
+#define PCIEX_BAR 0x60
+#define BAR_EN (1 << 0)
/* I/O Ports */
#define CMOS_ADDR_PORT 0x70
#include <asm/types.h>
+/* Architecture defined exceptions */
+enum x86_exception {
+ EXC_DE = 0,
+ EXC_DB,
+ EXC_NMI,
+ EXC_BP,
+ EXC_OF,
+ EXC_BR,
+ EXC_UD,
+ EXC_NM,
+ EXC_DF,
+ EXC_CSO,
+ EXC_TS,
+ EXC_NP,
+ EXC_SS,
+ EXC_GP,
+ EXC_PF,
+ EXC_MF = 16,
+ EXC_AC,
+ EXC_MC,
+ EXC_XM,
+ EXC_VE
+};
+
/* arch/x86/cpu/interrupts.c */
void set_vector(u8 intnum, void *routine);
-/* arch/x86/lib/interrupts.c */
-void disable_irq(int irq);
-void enable_irq(int irq);
-
/* Architecture specific functions */
void mask_irq(int irq);
void unmask_irq(int irq);
*/
u32 mptable_finalize(struct mp_config_table *mc);
+/**
+ * mp_determine_pci_dstirq() - Determine PCI device's int pin on the I/O APIC
+ *
+ * This determines a PCI device's interrupt pin number on the I/O APIC.
+ *
+ * This can be implemented by platform codes to handle specifal cases, which
+ * do not conform to the normal chipset/board design where PIRQ[A-H] are mapped
+ * directly to I/O APIC INTPIN#16-23.
+ *
+ * @bus: bus number of the pci device
+ * @dev: device number of the pci device
+ * @func: function number of the pci device
+ * @pirq: PIRQ number the PCI device's interrupt pin is routed to
+ * @return: interrupt pin number on the I/O APIC
+ */
+int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq);
+
/**
* write_mp_table() - Write MP table
*
#define MTRR_FIX_4K_F0000_MSR 0x26e
#define MTRR_FIX_4K_F8000_MSR 0x26f
+#define MTRR_FIX_TYPE(t) ((t << 24) | (t << 16) | (t << 8) | t)
+
#if !defined(__ASSEMBLER__)
/**
*
* @bus: PCI bus number
* @device: PCI device number
- * @func: PCI function number
* @irq: An array of IRQ numbers that are assigned to INTA through
* INTD of this PCI device.
*/
-void pci_assign_irqs(int bus, int device, int func, u8 irq[4]);
+void pci_assign_irqs(int bus, int device, u8 irq[4]);
#endif /* __ASSEMBLY__ */
/* Pushed by vector handler (irq_<num>) */
long irq_id;
/* Pushed by cpu in response to interrupt */
- long eip;
- long xcs;
- long eflags;
+ union {
+ struct {
+ long eip;
+ long xcs;
+ long eflags;
+ } ctx1;
+ struct {
+ long err;
+ long eip;
+ long xcs;
+ long eflags;
+ } ctx2;
+ } context;
} __attribute__ ((packed));
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
num_entries++;
}
+ /* Mark PCIe ECAM address range as reserved */
+ entries[num_entries].addr = CONFIG_PCIE_ECAM_BASE;
+ entries[num_entries].size = CONFIG_PCIE_ECAM_SIZE;
+ entries[num_entries].type = E820_RESERVED;
+ num_entries++;
+
return num_entries;
}
DECLARE_GLOBAL_DATA_PTR;
+static bool isa_irq_occupied[16];
+
struct mp_config_table *mp_write_floating_table(struct mp_floating_table *mf)
{
u32 mc;
MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
bus_isa, 0, apicid, 2);
- for (i = 3; i < 16; i++)
+ for (i = 3; i < 16; i++) {
+ /*
+ * Do not write ISA interrupt entry if it is already occupied
+ * by the platform devices.
+ */
+ if (isa_irq_occupied[i])
+ continue;
+
mp_write_intsrc(mc, MP_INT,
MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH,
bus_isa, i, apicid, i);
+ }
}
/*
return (i == entry_num) ? false : true;
}
+/* TODO: move this to driver model */
+__weak int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq)
+{
+ /* PIRQ[A-H] are connected to I/O APIC INTPIN#16-23 */
+ return pirq + 16;
+}
+
static int mptable_add_intsrc(struct mp_config_table *mc,
int bus_isa, int apicid)
{
const u32 *cell;
int i;
- /* Legacy Interrupts */
- debug("Writing ISA IRQs\n");
- mptable_add_isa_interrupts(mc, bus_isa, apicid, 0);
-
/* Get I/O interrupt information from device tree */
node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_IRQ_ROUTER);
if (node < 0) {
for (i = 0; i < count; i++) {
struct pirq_routing pr;
+ int bus, dev, func;
+ int dstirq;
pr.bdf = fdt_addr_to_cpu(cell[0]);
pr.pin = fdt_addr_to_cpu(cell[1]);
pr.pirq = fdt_addr_to_cpu(cell[2]);
+ bus = PCI_BUS(pr.bdf);
+ dev = PCI_DEV(pr.bdf);
+ func = PCI_FUNC(pr.bdf);
if (check_dup_entry(intsrc_base, intsrc_entries,
- PCI_BUS(pr.bdf), PCI_DEV(pr.bdf), pr.pin)) {
+ bus, dev, pr.pin)) {
debug("found entry for bus %d device %d INT%c, skipping\n",
- PCI_BUS(pr.bdf), PCI_DEV(pr.bdf),
- 'A' + pr.pin - 1);
+ bus, dev, 'A' + pr.pin - 1);
cell += sizeof(struct pirq_routing) / sizeof(u32);
continue;
}
- /* PIRQ[A-H] are always connected to I/O APIC INTPIN#16-23 */
- mp_write_pci_intsrc(mc, MP_INT, PCI_BUS(pr.bdf),
- PCI_DEV(pr.bdf), pr.pin, apicid,
- pr.pirq + 16);
+ dstirq = mp_determine_pci_dstirq(bus, dev, func, pr.pirq);
+ /*
+ * For PIRQ which is connected to I/O APIC interrupt pin#0-15,
+ * mark it as occupied so that we can skip it later.
+ */
+ if (dstirq < 16)
+ isa_irq_occupied[dstirq] = true;
+ mp_write_pci_intsrc(mc, MP_INT, bus, dev, pr.pin,
+ apicid, dstirq);
intsrc_entries++;
cell += sizeof(struct pirq_routing) / sizeof(u32);
}
+ /* Legacy Interrupts */
+ debug("Writing ISA IRQs\n");
+ mptable_add_isa_interrupts(mc, bus_isa, apicid, 0);
+
return 0;
}
}
/* Bus, device, slots IRQs for {A,B,C,D} */
- pci_assign_irqs(irq->bus, irq->devfn >> 3, irq->devfn & 7,
- irq_slot);
+ pci_assign_irqs(irq->bus, irq->devfn >> 3, irq_slot);
irq++;
}
entries[2].addr = ISA_END_ADDRESS;
entries[2].size = gd->ram_size - ISA_END_ADDRESS;
entries[2].type = E820_RAM;
+ entries[3].addr = CONFIG_PCIE_ECAM_BASE;
+ entries[3].size = CONFIG_PCIE_ECAM_SIZE;
+ entries[3].type = E820_RESERVED;
- return 3;
+ return 4;
}
static void build_command_line(char *command_line, int auto_boot)
--- /dev/null
+Update from original Marvell U-Boot to mainline U-Boot:
+-------------------------------------------------------
+
+The resulting image including the SPL binary with the
+full DDR setup is "u-boot-spl.kwb".
+
+To update the SPI NOR flash, please use the following
+command:
+
+=> sf probe;tftpboot 2000000 db-88f6820-gp/u-boot-spl.kwb;\
+sf update 2000000 0 60000
+
+Note that the original Marvell U-Boot seems to have
+problems with the "sf update" command. This does not
+work reliable. So here this command should be used:
+
+=> sf probe;tftpboot 2000000 db-88f6820-gp/u-boot-spl.kwb;\
+sf erase 0 60000;sf write 2000000 0 60000
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
+#include "../drivers/ddr/marvell/a38x/ddr3_a38x_topology.h"
+
DECLARE_GLOBAL_DATA_PTR;
#define BIT(nr) (1UL << (nr))
{ 0x21, 3, 0xC0 } /* Output Data, register#1 */
};
+/*
+ * Define the DDR layout / topology here in the board file. This will
+ * be used by the DDR3 init code in the SPL U-Boot version to configure
+ * the DDR3 controller.
+ */
+static struct hws_topology_map board_topology_map = {
+ 0x1, /* active interfaces */
+ /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */
+ { { { {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0},
+ {0x1, 0, 0, 0} },
+ SPEED_BIN_DDR_1866L, /* speed_bin */
+ BUS_WIDTH_8, /* memory_width */
+ MEM_4G, /* mem_size */
+ DDR_FREQ_800, /* frequency */
+ 0, 0, /* cas_l cas_wl */
+ HWS_TEMP_LOW} }, /* temperature */
+ 5, /* Num Of Bus Per Interface*/
+ BUS_MASK_32BIT /* Busses mask */
+};
+
+struct hws_topology_map *ddr3_get_topology_map(void)
+{
+ /* Return the board topology as defined in the board code */
+ return &board_topology_map;
+}
+
int board_early_init_f(void)
{
/* Configure MPP */
BOOT_FROM spi
# Binary Header (bin_hdr) with DDR3 training code
-BINARY board/Marvell/db-88f6820-gp/binary.0 0000005b 00000068
+BINARY spl/u-boot-spl.bin 0000005b 00000068
#include <asm/kona-common/clk.h>
#include <asm/arch/sysmap.h>
+#include <usb.h>
+#include <usb/s3c_udc.h>
+#include <g_dnl.h>
+
#define SECWATCHDOG_SDOGCR_OFFSET 0x00000000
#define SECWATCHDOG_SDOGCR_EN_SHIFT 27
#define SECWATCHDOG_SDOGCR_SRSTEN_SHIFT 26
#define SECWATCHDOG_SDOGCR_CLKS_SHIFT 20
#define SECWATCHDOG_SDOGCR_LD_SHIFT 0
+#ifndef CONFIG_USB_SERIALNO
+#define CONFIG_USB_SERIALNO "1234567890"
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
/*
return ret;
}
#endif
+
+#ifdef CONFIG_USB_GADGET
+static struct s3c_plat_otg_data bcm_otg_data = {
+ .regs_otg = HSOTG_BASE_ADDR
+};
+
+int board_usb_init(int index, enum usb_init_type init)
+{
+ debug("%s: performing s3c_udc_probe\n", __func__);
+ return s3c_udc_probe(&bcm_otg_data);
+}
+
+int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
+{
+ debug("%s\n", __func__);
+ if (!getenv("serial#"))
+ g_dnl_set_serialnumber(CONFIG_USB_SERIALNO);
+ return 0;
+}
+
+int g_dnl_get_board_bcd_device_number(int gcnum)
+{
+ debug("%s\n", __func__);
+ return 1;
+}
+
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+ debug("%s\n", __func__);
+ return 0;
+}
+#endif
#ifdef CONFIG_SYS_MMC_ENV_PART
uint mmc_get_env_part(struct mmc *mmc)
{
- u32 bootmode = gd->arch.omap_boot_params.omap_bootmode;
+ u32 bootmode = gd->arch.omap_boot_mode;
uint bootpart = CONFIG_SYS_MMC_ENV_PART;
/*
/* TLB 1 */
/* *I*** - Covers boot page */
#if defined(CONFIG_SYS_RAMBOOT) && defined(CONFIG_SYS_INIT_L3_ADDR)
+
+#if !defined(CONFIG_SECURE_BOOT)
/*
* *I*G - L3SRAM. When L3 is used as 1M SRAM, the address of the
* SRAM is at 0xfff00000, it covered the 0xfffff000.
SET_TLB_ENTRY(1, CONFIG_SYS_INIT_L3_ADDR, CONFIG_SYS_INIT_L3_ADDR,
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
0, 0, BOOKE_PAGESZ_1M, 1),
+#else
+ /*
+ * *I*G - L3SRAM. When L3 is used as 1M SRAM, in case of Secure Boot
+ * the physical address of the SRAM is at CONFIG_SYS_INIT_L3_ADDR,
+ * and virtual address is CONFIG_SYS_MONITOR_BASE
+ */
+
+ SET_TLB_ENTRY(1, CONFIG_SYS_MONITOR_BASE & 0xfff00000,
+ CONFIG_SYS_INIT_L3_ADDR & 0xfff00000,
+ MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
+ 0, 0, BOOKE_PAGESZ_1M, 1),
+#endif
+
#elif defined(CONFIG_SRIO_PCIE_BOOT_SLAVE)
/*
* SRIO_PCIE_BOOT-SLAVE. When slave boot, the address of the
/* EEPROM tag ID, either CCID or NXID */
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
printf("ID: %c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
- e.version);
+ be32_to_cpu(e.version));
#else
printf("ID: %c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
#endif
if (cmd == 'i') {
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
memcpy(e.id, "NXID", sizeof(e.id));
- e.version = NXID_VERSION;
+ e.version = cpu_to_be32(NXID_VERSION);
#else
memcpy(e.id, "CCID", sizeof(e.id));
#endif
#ifdef CONFIG_SYS_I2C_EEPROM_NXID
printf("%c%c%c%c v%u\n", e.id[0], e.id[1], e.id[2], e.id[3],
- e.version);
+ be32_to_cpu(e.version));
#else
printf("%c%c%c%c\n", e.id[0], e.id[1], e.id[2], e.id[3]);
#endif
* that at boot time, U-Boot will still say "NXID v0".
*/
if (e.version == 0) {
- e.version = NXID_VERSION;
+ e.version = cpu_to_be32(NXID_VERSION);
update_crc();
}
#endif
F: configs/P5040DS_SDCARD_defconfig
F: configs/P5040DS_SPIFLASH_defconfig
F: configs/P5040DS_SECURE_BOOT_defconfig
+
+CORENET_DS_SECURE_BOOT BOARD
+M: Aneesh Bansal <aneesh.bansal@freescale.com>
+S: Maintained
+F: configs/P3041DS_NAND_SECURE_BOOT_defconfig
+F: configs/P5020DS_NAND_SECURE_BOOT_defconfig
+F: configs/P5040DS_NAND_SECURE_BOOT_defconfig
out_be32(&scfg->pixclkcr, SCFG_PIXCLKCR_PXCKEN);
#endif
+ /* Configure Little endian for SAI, ASRC and SPDIF */
+ out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE);
+
/*
* Enable snoop requests and DVM message requests for
* Slave insterface S4 (A7 core cluster)
out_be32(&scfg->qspi_cfg, SCFG_QSPI_CLKSEL);
#endif
+ /* Configure Little endian for SAI, ASRC and SPDIF */
+ out_be32(&scfg->endiancr, SCFG_ENDIANCR_LE);
+
/*
* Enable snoop requests and DVM message requests for
* Slave insterface S4 (A7 core cluster)
Other addresses are either reserved, or not used directly by u-boot.
This list should be updated when more addresses are used.
+
+Booting Linux flavors which do not support 48-bit VA (< Linux 3.18)
+-------------------------------------------------------------------
+One needs to use appropriate bootargs to boot Linux flavors which do
+not support 48-bit VA (for e.g. < Linux 3.18) by appending mem=2048M, as shown
+below:
+
+=> setenv bootargs 'console=ttyS1,115200 root=/dev/ram
+ earlycon=uart8250,mmio,0x21c0600,115200 default_hugepagesz=2m hugepagesz=2m
+ hugepages=16 mem=2048M'
+
dram_to_hide += mc_get_dram_block_size();
#endif
- return dram_to_hide;
+ return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN);
}
int board_eth_init(bd_t *bis)
#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
- phys_addr_t base;
- phys_size_t size;
+ u64 base[CONFIG_NR_DRAM_BANKS];
+ u64 size[CONFIG_NR_DRAM_BANKS];
ft_cpu_setup(blob, bd);
- /* limit the memory size to bank 1 until Linux can handle 40-bit PA */
- base = getenv_bootm_low();
- size = getenv_bootm_size();
- fdt_fixup_memory(blob, (u64)base, (u64)size);
+ /* fixup DT for the two GPP DDR banks */
+ base[0] = gd->bd->bi_dram[0].start;
+ size[0] = gd->bd->bi_dram[0].size;
+ base[1] = gd->bd->bi_dram[1].start;
+ size[1] = gd->bd->bi_dram[1].size;
+
+ fdt_fixup_memory_banks(blob, base, size, 2);
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
c) NAND boot
d) SD boot
e) QSPI boot
+
+Environment Variables
+---------------------
+- mcboottimeout: MC boot timeout in milliseconds. If this variable is not defined
+ the value CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS will be assumed.
+
+- mcmemsize: MC DRAM block size. If this variable is not defined
+ the value CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE will be assumed.
+
+Booting Linux flavors which do not support 48-bit VA (< Linux 3.18)
+-------------------------------------------------------------------
+One needs to use appropriate bootargs to boot Linux flavors which do
+not support 48-bit VA (for e.g. < Linux 3.18) by appending mem=2048M, as shown
+below:
+
+=> setenv bootargs 'console=ttyS1,115200 root=/dev/ram
+ earlycon=uart8250,mmio,0x21c0600,115200 default_hugepagesz=2m hugepagesz=2m
+ hugepages=16 mem=2048M'
+
#define EMI1_SLOT5 4
#define EMI1_SLOT6 5
#define EMI2 6
-#define SFP_TX 1
+#define SFP_TX 0
static const char * const mdio_names[] = {
"LS2085A_QDS_MDIO0",
switch (serdes2_prtcl) {
case 0x07:
case 0x08:
+ case 0x49:
printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n",
serdes2_prtcl);
lane_to_slot_fsm2[0] = EMI1_SLOT4;
switch (serdes2_prtcl) {
case 0x07:
case 0x08:
+ case 0x49:
lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
(dpmac_id - 9));
slot = lane_to_slot_fsm2[lane];
#include <environment.h>
#include <i2c.h>
#include <asm/arch-fsl-lsch3/soc.h>
+#include <hwconfig.h>
#include "../common/qixis.h"
#include "ls2085aqds_qixis.h"
+#define PIN_MUX_SEL_SDHC 0x00
+#define PIN_MUX_SEL_DSPI 0x0a
+
+#define SET_SDHC_MUX_SEL(reg, value) ((reg & 0xf0) | value)
+
DECLARE_GLOBAL_DATA_PTR;
+enum {
+ MUX_TYPE_SDHC,
+ MUX_TYPE_DSPI,
+};
+
unsigned long long get_qixis_addr(void)
{
unsigned long long addr;
"100 separate SSCG"};
int clock;
+ cpu_name(buf);
+ printf("Board: %s-QDS, ", buf);
+
sw = QIXIS_READ(arch);
- printf("Board: %s, ", CONFIG_IDENT_STRING);
printf("Board Arch: V%d, ", sw >> 4);
printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1);
+ memset((u8 *)buf, 0x00, ARRAY_SIZE(buf));
+
sw = QIXIS_READ(brdcfg[0]);
sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
return 0;
}
+int config_board_mux(int ctrl_type)
+{
+ u8 reg5;
+
+ reg5 = QIXIS_READ(brdcfg[5]);
+
+ switch (ctrl_type) {
+ case MUX_TYPE_SDHC:
+ reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_SDHC);
+ break;
+ case MUX_TYPE_DSPI:
+ reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_DSPI);
+ break;
+ default:
+ printf("Wrong mux interface type\n");
+ return -1;
+ }
+
+ QIXIS_WRITE(brdcfg[5], reg5);
+
+ return 0;
+}
+
int board_init(void)
{
+ char *env_hwconfig;
+ u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
+ u32 val;
+
init_final_memctl_regs();
+ val = in_le32(dcfg_ccsr + DCFG_RCWSR13 / 4);
+
+ env_hwconfig = getenv("hwconfig");
+
+ if (hwconfig_f("dspi", env_hwconfig) &&
+ DCFG_RCWSR13_DSPI == (val & (u32)(0xf << 8)))
+ config_board_mux(MUX_TYPE_DSPI);
+ else
+ config_board_mux(MUX_TYPE_SDHC);
+
#ifdef CONFIG_ENV_IS_NOWHERE
gd->env_addr = (ulong)&default_environment[0];
#endif
dram_to_hide += mc_get_dram_block_size();
#endif
- return dram_to_hide;
+ return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN);
}
#ifdef CONFIG_FSL_MC_ENET
#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
- phys_addr_t base;
- phys_size_t size;
+ u64 base[CONFIG_NR_DRAM_BANKS];
+ u64 size[CONFIG_NR_DRAM_BANKS];
ft_cpu_setup(blob, bd);
- /* limit the memory size to bank 1 until Linux can handle 40-bit PA */
- base = getenv_bootm_low();
- size = getenv_bootm_size();
- fdt_fixup_memory(blob, (u64)base, (u64)size);
+ /* fixup DT for the two GPP DDR banks */
+ base[0] = gd->bd->bi_dram[0].start;
+ size[0] = gd->bd->bi_dram[0].size;
+ base[1] = gd->bd->bi_dram[1].start;
+ size[1] = gd->bd->bi_dram[1].size;
+
+ fdt_fixup_memory_banks(blob, base, size, 2);
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
# SPDX-License-Identifier: GPL-2.0+
#
-obj-y += ls2085ardb.o
+obj-y += ls2085ardb.o eth_ls2085rdb.o
obj-y += ddr.o
---------------
a) NOR boot
b) NAND boot
+
+Booting Linux flavors which do not support 48-bit VA (< Linux 3.18)
+-------------------------------------------------------------------
+One needs to use appropriate bootargs to boot Linux flavors which do
+not support 48-bit VA (for e.g. < Linux 3.18) by appending mem=2048M, as shown
+below:
+
+=> setenv bootargs 'console=ttyS1,115200 root=/dev/ram
+ earlycon=uart8250,mmio,0x21c0600,115200 default_hugepagesz=2m hugepagesz=2m
+ hugepages=16 mem=2048M'
+
--- /dev/null
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <netdev.h>
+#include <malloc.h>
+#include <fsl_mdio.h>
+#include <miiphy.h>
+#include <phy.h>
+#include <fm_eth.h>
+#include <asm/io.h>
+#include <exports.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+#include <fsl-mc/ldpaa_wriop.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int load_firmware_cortina(struct phy_device *phy_dev)
+{
+ if (phy_dev->drv->config)
+ return phy_dev->drv->config(phy_dev);
+
+ return 0;
+}
+
+void load_phy_firmware(void)
+{
+ int i;
+ u8 phy_addr;
+ struct phy_device *phy_dev;
+ struct mii_dev *dev;
+ phy_interface_t interface;
+
+ /*Initialize and upload firmware for all the PHYs*/
+ for (i = WRIOP1_DPMAC1; i <= WRIOP1_DPMAC8; i++) {
+ interface = wriop_get_enet_if(i);
+ if (interface == PHY_INTERFACE_MODE_XGMII) {
+ dev = wriop_get_mdio(i);
+ phy_addr = wriop_get_phy_address(i);
+ phy_dev = phy_find_by_mask(dev, 1 << phy_addr,
+ interface);
+ if (!phy_dev) {
+ printf("No phydev for phyaddr %d\n", phy_addr);
+ continue;
+ }
+
+ /*Flash firmware for All CS4340 PHYS */
+ if (phy_dev->phy_id == PHY_UID_CS4340)
+ load_firmware_cortina(phy_dev);
+ }
+ }
+}
+
+int board_eth_init(bd_t *bis)
+{
+#if defined(CONFIG_FSL_MC_ENET)
+ int i, interface;
+ struct memac_mdio_info mdio_info;
+ struct mii_dev *dev;
+ struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 srds_s1;
+ struct memac_mdio_controller *reg;
+
+ srds_s1 = in_le32(&gur->rcwsr[28]) &
+ FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
+ srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
+
+ reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1;
+ mdio_info.regs = reg;
+ mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME;
+
+ /* Register the EMI 1 */
+ fm_memac_mdio_init(bis, &mdio_info);
+
+ reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2;
+ mdio_info.regs = reg;
+ mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME;
+
+ /* Register the EMI 2 */
+ fm_memac_mdio_init(bis, &mdio_info);
+
+ switch (srds_s1) {
+ case 0x2A:
+ wriop_set_phy_address(WRIOP1_DPMAC1, CORTINA_PHY_ADDR1);
+ wriop_set_phy_address(WRIOP1_DPMAC2, CORTINA_PHY_ADDR2);
+ wriop_set_phy_address(WRIOP1_DPMAC3, CORTINA_PHY_ADDR3);
+ wriop_set_phy_address(WRIOP1_DPMAC4, CORTINA_PHY_ADDR4);
+ wriop_set_phy_address(WRIOP1_DPMAC5, AQ_PHY_ADDR1);
+ wriop_set_phy_address(WRIOP1_DPMAC6, AQ_PHY_ADDR2);
+ wriop_set_phy_address(WRIOP1_DPMAC7, AQ_PHY_ADDR3);
+ wriop_set_phy_address(WRIOP1_DPMAC8, AQ_PHY_ADDR4);
+
+ break;
+ default:
+ printf("SerDes1 protocol 0x%x is not supported on LS2085aRDB\n",
+ srds_s1);
+ break;
+ }
+
+ for (i = WRIOP1_DPMAC1; i <= WRIOP1_DPMAC4; i++) {
+ interface = wriop_get_enet_if(i);
+ switch (interface) {
+ case PHY_INTERFACE_MODE_XGMII:
+ dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME);
+ wriop_set_mdio(i, dev);
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (i = WRIOP1_DPMAC5; i <= WRIOP1_DPMAC8; i++) {
+ switch (wriop_get_enet_if(i)) {
+ case PHY_INTERFACE_MODE_XGMII:
+ dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
+ wriop_set_mdio(i, dev);
+ break;
+ default:
+ break;
+ }
+ }
+
+ /* Load CORTINA CS4340 PHY firmware */
+ load_phy_firmware();
+
+ cpu_eth_init(bis);
+#endif /* CONFIG_FMAN_ENET */
+
+#ifdef CONFIG_PHY_AQUANTIA
+ /*
+ * Export functions to be used by AQ firmware
+ * upload application
+ */
+ gd->jt->strcpy = strcpy;
+ gd->jt->mdelay = mdelay;
+ gd->jt->mdio_get_current_dev = mdio_get_current_dev;
+ gd->jt->phy_find_by_mask = phy_find_by_mask;
+ gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname;
+ gd->jt->miiphy_set_current_dev = miiphy_set_current_dev;
+#endif
+ return pci_eth_init(bis);
+}
#include <fsl_ifc.h>
#include <fsl_ddr.h>
#include <asm/io.h>
+#include <hwconfig.h>
#include <fdt_support.h>
#include <libfdt.h>
#include <fsl_debug_server.h>
#include "../common/qixis.h"
#include "ls2085ardb_qixis.h"
+#define PIN_MUX_SEL_SDHC 0x00
+#define PIN_MUX_SEL_DSPI 0x0a
+
+#define SET_SDHC_MUX_SEL(reg, value) ((reg & 0xf0) | value)
DECLARE_GLOBAL_DATA_PTR;
+enum {
+ MUX_TYPE_SDHC,
+ MUX_TYPE_DSPI,
+};
+
unsigned long long get_qixis_addr(void)
{
unsigned long long addr;
int checkboard(void)
{
u8 sw;
+ char buf[15];
+
+ cpu_name(buf);
+ printf("Board: %s-RDB, ", buf);
sw = QIXIS_READ(arch);
- printf("Board: %s, ", CONFIG_IDENT_STRING);
printf("Board Arch: V%d, ", sw >> 4);
- printf("Board version: %c, boot from ", (sw & 0xf) + 'A' - 1);
+ printf("Board version: %c, boot from ", (sw & 0xf) + 'A');
sw = QIXIS_READ(brdcfg[0]);
sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
return 0;
}
+int config_board_mux(int ctrl_type)
+{
+ u8 reg5;
+
+ reg5 = QIXIS_READ(brdcfg[5]);
+
+ switch (ctrl_type) {
+ case MUX_TYPE_SDHC:
+ reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_SDHC);
+ break;
+ case MUX_TYPE_DSPI:
+ reg5 = SET_SDHC_MUX_SEL(reg5, PIN_MUX_SEL_DSPI);
+ break;
+ default:
+ printf("Wrong mux interface type\n");
+ return -1;
+ }
+
+ QIXIS_WRITE(brdcfg[5], reg5);
+
+ return 0;
+}
+
int board_init(void)
{
+ char *env_hwconfig;
+ u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
+ u32 val;
+
init_final_memctl_regs();
+ val = in_le32(dcfg_ccsr + DCFG_RCWSR13 / 4);
+
+ env_hwconfig = getenv("hwconfig");
+
+ if (hwconfig_f("dspi", env_hwconfig) &&
+ DCFG_RCWSR13_DSPI == (val & (u32)(0xf << 8)))
+ config_board_mux(MUX_TYPE_DSPI);
+ else
+ config_board_mux(MUX_TYPE_SDHC);
+
#ifdef CONFIG_ENV_IS_NOWHERE
gd->env_addr = (ulong)&default_environment[0];
#endif
return 0;
}
+int misc_init_r(void)
+{
+ if (hwconfig("sdhc"))
+ config_board_mux(MUX_TYPE_SDHC);
+
+ return 0;
+}
+
void detail_board_ddr_info(void)
{
puts("\nDDR ");
dram_to_hide += mc_get_dram_block_size();
#endif
- return dram_to_hide;
-}
-
-int board_eth_init(bd_t *bis)
-{
- int error = 0;
-
-#ifdef CONFIG_FSL_MC_ENET
- error = cpu_eth_init(bis);
-#endif
-
- error = pci_eth_init(bis);
-
- return error;
+ return roundup(dram_to_hide, CONFIG_SYS_MEM_TOP_HIDE_MIN);
}
#ifdef CONFIG_FSL_MC_ENET
#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
- phys_addr_t base;
- phys_size_t size;
+ u64 base[CONFIG_NR_DRAM_BANKS];
+ u64 size[CONFIG_NR_DRAM_BANKS];
ft_cpu_setup(blob, bd);
- /* limit the memory size to bank 1 until Linux can handle 40-bit PA */
- base = getenv_bootm_low();
- size = getenv_bootm_size();
- fdt_fixup_memory(blob, (u64)base, (u64)size);
+ /* fixup DT for the two GPP DDR banks */
+ base[0] = gd->bd->bi_dram[0].start;
+ size[0] = gd->bd->bi_dram[0].size;
+ base[1] = gd->bd->bi_dram[1].start;
+ size[1] = gd->bd->bi_dram[1].size;
+
+ fdt_fixup_memory_banks(blob, base, size, 2);
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1]));
}
}
+
+/*
+ * Board rev C and earlier has duplicated I2C addresses for 2nd controller.
+ * Both slots has 0x54, resulting 2nd slot unusable.
+ */
+void update_spd_address(unsigned int ctrl_num,
+ unsigned int slot,
+ unsigned int *addr)
+{
+ u8 sw;
+
+ sw = QIXIS_READ(arch);
+ if ((sw & 0xf) < 0x3) {
+ if (ctrl_num == 1 && slot == 0)
+ *addr = SPD_EEPROM_ADDRESS4;
+ else if (ctrl_num == 1 && slot == 1)
+ *addr = SPD_EEPROM_ADDRESS3;
+ }
+}
{
phys_addr_t base;
phys_size_t size;
+#if defined(CONFIG_P1020RDB_PD) || defined(CONFIG_P1020RDB_PC)
const char *soc_usb_compat = "fsl-usb2-dr";
- int err, usb1_off, usb2_off;
+ int usb_err, usb1_off, usb2_off;
+#endif
+#if defined(CONFIG_SDCARD) || defined(CONFIG_SPIFLASH)
+ int err;
+#endif
ft_cpu_setup(blob, bd);
}
#endif
+#if defined(CONFIG_P1020RDB_PD) || defined(CONFIG_P1020RDB_PC)
/* Delete USB2 node as it is muxed with eLBC */
usb1_off = fdt_node_offset_by_compatible(blob, -1,
soc_usb_compat);
soc_usb_compat);
return usb2_off;
}
- err = fdt_del_node(blob, usb2_off);
- if (err < 0) {
+ usb_err = fdt_del_node(blob, usb2_off);
+ if (usb_err < 0) {
printf("WARNING: could not remove %s\n", soc_usb_compat);
- return err;
+ return usb_err;
}
+#endif
return 0;
}
#Configure CPC1 as 256KB SRAM
09010100 00000000
09010104 fffc0007
-09010f00 08000000
+09010f00 081e000d
09010000 80000000
#Configure LAW for CPC1
09000cd0 00000000
I2C controller: 4 3
DDR: 64-bit 32-bit
IFC: 32-bit 28-bit
+Package: 23x23 19x19
T1024RDB board Overview
on T1024RDB:
set SW1[1:8] = '00010011', SW2[1] = '1', SW3[4] = '0' for NOR boot
on T1023RDB:
- set SW1[1:8] = '00010110', SW2[1] = '0', SW3[4] = '0' for NOR boot
+ set SW1[1:8] = '00010111', SW2[1] = '1', SW3[4] = '0' for NOR boot
Switching between default bank0 and alternate bank4 on NOR flash
To change boot source to vbank4:
via software: run command 'cpld reset altbank' in u-boot.
via DIP-switch: set SW3[5:7] = '100'
on T1023RDB:
- via software: run command 'gpio vbank4' in u-boot.
+ via software: run command 'switch bank4' in u-boot.
via DIP-switch: set SW3[5:7] = '100'
To change boot source to vbank0:
via software: run command 'cpld reset' in u-boot.
via DIP-Switch: set SW3[5:7] = '000'
on T1023RDB:
- via software: run command 'gpio vbank0' in u-boot.
+ via software: run command 'switch bank0' in u-boot.
via DIP-switch: set SW3[5:7] = '000'
2. NAND Boot:
=> tftp 1000000 u-boot-with-spl-pbl.bin
=> nand erase 0 $filesize
=> nand write 1000000 0 $filesize
- set SW1[1:8] = '10001000', SW2[1] = '1', SW3[4] = '1' for NAND boot
+ set SW1[1:8] = '10000010', SW2[1] = '1', SW3[4] = '1' for NAND boot
3. SPI Boot:
a. build PBL image for SPI boot
$ make
b. program u-boot-with-spl-pbl.bin to SD/MMC card
=> tftp 1000000 u-boot-with-spl-pbl.bin
- => mmc write 1000000 8 0x800
+ => mmc write 1000000 8 0x7f0
=> tftp 1000000 fsl_fman_ucode_t1024_xx.bin
=> mmc write 1000000 0x820 80
set SW1[1:8] = '00100000', SW2[1] = '0' for SD boot
+ SW3[3] = '1' for SD card(or 'switch sd' by software)
+ SW3[3] = '0' for eMMC (or 'switch emmc' by software)
+
2-stage NAND/SPI/SD boot loader
-------------------------------
0x160000 0x17FFFF FMAN Ucode 128KB
-SD Card memory Map on T1024RDB
+SD Card memory Map on T102xRDB
----------------------------------------------------
Block #blocks Definition Size
0x008 2048 u-boot img 1MB
0xa00000 0x3FFFFFF rootfs 54MB
-For more details, please refer to T1024RDB Reference Manual
+For more details, please refer to T1024RDB/T1023RDB User Guide
and Freescale QorIQ SDK Infocenter document.
return CONFIG_DDR_CLK_FREQ;
}
+#if defined(CONFIG_SPL_MMC_BOOT)
+#define GPIO1_SD_SEL 0x00020000
+int board_mmc_getcd(struct mmc *mmc)
+{
+ ccsr_gpio_t __iomem *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
+ u32 val = in_be32(&pgpio->gpdat);
+
+ /* GPIO1_14, 0: eMMC, 1: SD */
+ val &= GPIO1_SD_SEL;
+
+ return val ? -1 : 1;
+}
+
+int board_mmc_getwp(struct mmc *mmc)
+{
+ ccsr_gpio_t __iomem *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
+ u32 val = in_be32(&pgpio->gpdat);
+
+ val &= GPIO1_SD_SEL;
+
+ return val ? -1 : 0;
+}
+#endif
+
void board_init_f(ulong bootflag)
{
u32 plat_ratio, sys_clk, ccb_clk;
#Core/DDR: 1400Mhz/1600MT/s with single source clock
0810000e 00000000 00000000 00000000
3b800003 00000012 e8104000 21000000
-00000000 00000000 00000000 00020800
+00000000 00000000 00000000 00022800
00000130 04020200 00000000 00000006
#Configure CPC1 as 256KB SRAM
09010100 00000000
09010104 fffc0007
-09010f00 08000000
+09010f00 081e000d
09010000 80000000
#Configure LAW for CPC1
09000cd0 00000000
#include "t102xrdb.h"
#ifdef CONFIG_T1024RDB
#include "cpld.h"
+#elif defined(CONFIG_T1023RDB)
+#include <i2c.h>
+#include <mmc.h>
#endif
#include "../common/sleep.h"
#ifdef CONFIG_T1023RDB
enum {
- GPIO1_SD_SEL = 0x00020000, /* GPIO1_14, 0: EMMC, 1:SD/MMC */
+ GPIO1_SD_SEL = 0x00020000, /* GPIO1_14, 0: eMMC, 1:SD/MMC */
GPIO1_EMMC_SEL,
- GPIO1_VBANK0,
- GPIO1_VBANK4 = 0x00008000, /* GPIO1_16/20/22, 100:vBank4 */
- GPIO1_VBANK_MASK = 0x00008a00,
- GPIO1_DIR_OUTPUT = 0x00028a00,
- GPIO1_GET_VAL,
+ GPIO3_GET_VERSION, /* GPIO3_4/5, 00:RevB, 01: RevC */
+ GPIO3_BRD_VER_MASK = 0x0c000000,
+ GPIO3_OFFSET = 0x2000,
+ I2C_GET_BANK,
+ I2C_SET_BANK0,
+ I2C_SET_BANK4,
};
#endif
srds_s1 >>= FSL_CORENET2_RCWSR4_SRDS1_PRTCL_SHIFT;
printf("Board: %sRDB, ", cpu->name);
-#ifdef CONFIG_T1024RDB
+#if defined(CONFIG_T1024RDB)
printf("Board rev: 0x%02x CPLD ver: 0x%02x, ",
CPLD_READ(hw_ver), CPLD_READ(sw_ver));
+#elif defined(CONFIG_T1023RDB)
+ printf("Rev%c, ", t1023rdb_ctrl(GPIO3_GET_VERSION) + 'B');
#endif
printf("boot from ");
#ifdef CONFIG_NAND
puts("NAND\n");
#else
- printf("NOR vBank%d\n", (t1023rdb_gpio_ctrl(GPIO1_GET_VAL) &
- GPIO1_VBANK4) >> 15 ? 4 : 0);
+ printf("NOR vBank%d\n", t1023rdb_ctrl(I2C_GET_BANK));
#endif
#endif
fdt_fixup_board_enet(blob);
#endif
+#ifdef CONFIG_T1023RDB
+ if (t1023rdb_ctrl(GPIO3_GET_VERSION) > 0)
+ fdt_enable_nor(blob);
+#endif
+
return 0;
}
-
#ifdef CONFIG_T1023RDB
-static u32 t1023rdb_gpio_ctrl(u32 ctrl_type)
+/* Enable NOR flash for RevC */
+static void fdt_enable_nor(void *blob)
{
- ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
- u32 gpioval;
+ int nodeoff = fdt_node_offset_by_compatible(blob, 0, "cfi-flash");
+
+ if (nodeoff >= 0)
+ fdt_status_okay(blob, nodeoff);
+ else
+ printf("WARNING unable to set status for NOR\n");
+}
- setbits_be32(&pgpio->gpdir, GPIO1_DIR_OUTPUT);
- gpioval = in_be32(&pgpio->gpdat);
+int board_mmc_getcd(struct mmc *mmc)
+{
+ ccsr_gpio_t __iomem *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
+ u32 val = in_be32(&pgpio->gpdat);
+
+ /* GPIO1_14, 0: eMMC, 1: SD/MMC */
+ val &= GPIO1_SD_SEL;
+
+ return val ? -1 : 1;
+}
+
+int board_mmc_getwp(struct mmc *mmc)
+{
+ ccsr_gpio_t __iomem *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
+ u32 val = in_be32(&pgpio->gpdat);
+
+ val &= GPIO1_SD_SEL;
+
+ return val ? -1 : 0;
+}
+
+static u32 t1023rdb_ctrl(u32 ctrl_type)
+{
+ ccsr_gpio_t __iomem *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
+ ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ u32 val, orig_bus = i2c_get_bus_num();
+ u8 tmp;
switch (ctrl_type) {
case GPIO1_SD_SEL:
- gpioval |= GPIO1_SD_SEL;
+ val = in_be32(&pgpio->gpdat);
+ val |= GPIO1_SD_SEL;
+ out_be32(&pgpio->gpdat, val);
+ setbits_be32(&pgpio->gpdir, GPIO1_SD_SEL);
break;
case GPIO1_EMMC_SEL:
- gpioval &= ~GPIO1_SD_SEL;
+ val = in_be32(&pgpio->gpdat);
+ val &= ~GPIO1_SD_SEL;
+ out_be32(&pgpio->gpdat, val);
+ setbits_be32(&pgpio->gpdir, GPIO1_SD_SEL);
break;
- case GPIO1_VBANK0:
- gpioval &= ~GPIO1_VBANK_MASK;
+ case GPIO3_GET_VERSION:
+ pgpio = (ccsr_gpio_t *)(CONFIG_SYS_MPC85xx_GPIO_ADDR
+ + GPIO3_OFFSET);
+ val = in_be32(&pgpio->gpdat);
+ val = ((val & GPIO3_BRD_VER_MASK) >> 26) & 0x3;
+ if (val == 0x3) /* GPIO3_4/5 not used on RevB */
+ val = 0;
+ return val;
+ case I2C_GET_BANK:
+ i2c_set_bus_num(I2C_PCA6408_BUS_NUM);
+ i2c_read(I2C_PCA6408_ADDR, 0, 1, &tmp, 1);
+ tmp &= 0x7;
+ tmp = ((tmp & 1) << 2) | (tmp & 2) | ((tmp & 4) >> 2);
+ i2c_set_bus_num(orig_bus);
+ return tmp;
+ case I2C_SET_BANK0:
+ i2c_set_bus_num(I2C_PCA6408_BUS_NUM);
+ tmp = 0x0;
+ i2c_write(I2C_PCA6408_ADDR, 1, 1, &tmp, 1);
+ tmp = 0xf8;
+ i2c_write(I2C_PCA6408_ADDR, 3, 1, &tmp, 1);
+ /* asserting HRESET_REQ */
+ out_be32(&gur->rstcr, 0x2);
break;
- case GPIO1_VBANK4:
- gpioval &= ~GPIO1_VBANK_MASK;
- gpioval |= GPIO1_VBANK4;
+ case I2C_SET_BANK4:
+ i2c_set_bus_num(I2C_PCA6408_BUS_NUM);
+ tmp = 0x1;
+ i2c_write(I2C_PCA6408_ADDR, 1, 1, &tmp, 1);
+ tmp = 0xf8;
+ i2c_write(I2C_PCA6408_ADDR, 3, 1, &tmp, 1);
+ out_be32(&gur->rstcr, 0x2);
break;
- case GPIO1_GET_VAL:
- return gpioval;
default:
break;
}
- out_be32(&pgpio->gpdat, gpioval);
-
return 0;
}
-static int gpio_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
+static int switch_cmd(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
if (argc < 2)
return CMD_RET_USAGE;
- if (!strcmp(argv[1], "vbank0"))
- t1023rdb_gpio_ctrl(GPIO1_VBANK0);
- else if (!strcmp(argv[1], "vbank4"))
- t1023rdb_gpio_ctrl(GPIO1_VBANK4);
+ if (!strcmp(argv[1], "bank0"))
+ t1023rdb_ctrl(I2C_SET_BANK0);
+ else if (!strcmp(argv[1], "bank4") || !strcmp(argv[1], "altbank"))
+ t1023rdb_ctrl(I2C_SET_BANK4);
else if (!strcmp(argv[1], "sd"))
- t1023rdb_gpio_ctrl(GPIO1_SD_SEL);
- else if (!strcmp(argv[1], "EMMC"))
- t1023rdb_gpio_ctrl(GPIO1_EMMC_SEL);
+ t1023rdb_ctrl(GPIO1_SD_SEL);
+ else if (!strcmp(argv[1], "emmc"))
+ t1023rdb_ctrl(GPIO1_EMMC_SEL);
else
return CMD_RET_USAGE;
return 0;
}
U_BOOT_CMD(
- gpio, 2, 0, gpio_cmd,
- "for vbank0/vbank4/SD/eMMC switch control in runtime",
- "command (e.g. gpio vbank4)"
+ switch, 2, 0, switch_cmd,
+ "for bank0/bank4/sd/emmc switch control in runtime",
+ "command (e.g. switch bank4)"
);
#endif
void fdt_fixup_board_enet(void *blob);
void pci_of_setup(void *blob, bd_t *bd);
#ifdef CONFIG_T1023RDB
-static u32 t1023rdb_gpio_ctrl(u32 ctrl_type);
+static u32 t1023rdb_ctrl(u32 ctrl_type);
+static void fdt_enable_nor(void *blob);
#endif
#endif
#Configure CPC1 as 256KB SRAM
09010100 00000000
09010104 fffc0007
-09010f00 08000000
+09010f00 081e000d
09010000 80000000
#Configure LAW for CPC1
09000cf0 00000000
F: configs/T1040RDB_defconfig
F: configs/T1040RDB_NAND_defconfig
F: configs/T1040RDB_SPIFLASH_defconfig
+F: configs/T1040D4RDB_defconfig
+F: configs/T1040D4RDB_NAND_defconfig
+F: configs/T1040D4RDB_SPIFLASH_defconfig
F: configs/T1042RDB_defconfig
+F: configs/T1042D4RDB_defconfig
+F: configs/T1042D4RDB_NAND_defconfig
+F: configs/T1042D4RDB_SPIFLASH_defconfig
F: configs/T1042RDB_PI_defconfig
F: configs/T1042RDB_PI_NAND_defconfig
F: configs/T1042RDB_PI_SPIFLASH_defconfig
#M: -
S: Maintained
F: configs/T1040RDB_SDCARD_defconfig
+F: configs/T1040D4RDB_SDCARD_defconfig
+F: configs/T1042D4RDB_SDCARD_defconfig
F: configs/T1042RDB_PI_SDCARD_defconfig
T1040RDB_SECURE_BOOT BOARD
M: Aneesh Bansal <aneesh.bansal@freescale.com>
S: Maintained
F: configs/T1040RDB_SECURE_BOOT_defconfig
+F: configs/T1040D4RDB_SECURE_BOOT_defconfig
F: configs/T1042RDB_SECURE_BOOT_defconfig
+F: configs/T1042D4RDB_SECURE_BOOT_defconfig
(a personality of T1040 SoC). The board is similar to T1040RDB but is
designed specially with low power features targeted for Printing Image Market.
+The T1040D4RDB is a Freescale reference board that hosts the T1040 SoC.
+The board is re-designed T1040RDB board with following changes :
+ - Support of DDR4 memory and some enhancements
+
+The T1042D4RDB is a Freescale reference board that hosts the T1042 SoC.
+The board is re-designed T1040RDB board with following changes :
+ - Support of DDR4 memory
+ - Support for 0x86 serdes protocol which can support following interfaces
+ - 2 RGMII's on DTSEC4, DTSEC5
+ - 3 SGMII on DTSEC1, DTSEC2 & DTSEC3
+
Basic difference's among T1040RDB, T1042RDB_PI, T1042RDB
-------------------------------------------------------------------------
Board Si Protocol Targeted Market
T1040RDB T1040 0x66 Networking
T1040RDB T1042 0x86 Networking
T1042RDB_PI T1042 0x06 Printing & Imaging
+T1040D4RDB T1040 0x66 Networking
+T1042D4RDB T1042 0x86 Networking
T1040 SoC Overview
T1040 SoC Personalities
-------------------------
-
T1022 Personality:
T1022 is a reduced personality of T1040 with less core/clusters.
Please note QE Firmware is only valid for T1040RDB
-Switch Settings: (ON is 0, OFF is 1)
-===============
+Switch Settings for T104xRDB boards: (ON is 0, OFF is 1)
+==========================================================
+NOR boot SW setting:
+SW1: 00010011
+SW2: 10111011
+SW3: 11100001
+
NAND boot SW setting:
SW1: 10001000
SW2: 00111011
SW1: 00100000
SW2: 00111011
SW3: 11100001
+
+Switch Settings for T104xD4RDB boards: (ON is 0, OFF is 1)
+=============================================================
+NOR boot SW setting:
+SW1: 00010011
+SW2: 10111001
+SW3: 11100001
+
+NAND boot SW setting:
+SW1: 10001000
+SW2: 00111001
+SW3: 11110001
+
+SPI boot SW setting:
+SW1: 00100010
+SW2: 10111001
+SW3: 11100001
+
+SD boot SW setting:
+SW1: 00100000
+SW2: 00111001
+SW3: 11100001
+
+PBL-based image generation
+==========================
+Changes only the required register bit in in PBI commands.
+
+Provides reference code which might needs some
+modification as per requirement.
+example:
+By default PBI_SRC=14 (which is for IFC-NAND/NOR) in rcw.cfg file
+which needs to be changed for SPI and SD.
+
+For SD-boot
+==============
+1. Set RCW[192:195], PBI_SRC bits as 6 in RCW file (t1040d4_rcw.cfg type files)
+
+example:
+ RCW file: board/freescale/t104xrdb/t1040d4_rcw.cfg
+
+Change
+66000002 40000002 ec027000 01000000
+to
+66000002 40000002 6c027000 01000000
+
+2. SD does not support flush so remove flush from pbl, make changes in
+ tools/pblimage.c file, Update value of pbl_end_cmd[0] = 0x09138000
+ with 0x091380c0
+
+For SPI-boot
+==============
+1. Set RCW[192:195], PBI_SRC bits as 5 in RCW file (t1040d4_rcw.cfg type files)
+
+example:
+ RCW file: board/freescale/t104xrdb/t1040d4_rcw.cfg
+
+Change
+66000002 40000002 ec027000 01000000
+to
+66000002 40000002 5c027000 01000000
+
+2. SPI does not support flush so remove flush from pbl, make changes in
+ tools/pblimage.c file, Update value of pbl_end_cmd[0] = 0x09138000
+ with 0x091380c0
printf("int_status = 0x%02x\n", CPLD_READ(int_status));
printf("flash_ctl_status = 0x%02x\n", CPLD_READ(flash_ctl_status));
printf("fan_ctl_status = 0x%02x\n", CPLD_READ(fan_ctl_status));
+#if defined(CONFIG_T104XD4RDB)
+ printf("int_mask = 0x%02x\n", CPLD_READ(int_mask));
+#else
printf("led_ctl_status = 0x%02x\n", CPLD_READ(led_ctl_status));
+#endif
printf("sfp_ctl_status = 0x%02x\n", CPLD_READ(sfp_ctl_status));
printf("misc_ctl_status = 0x%02x\n", CPLD_READ(misc_ctl_status));
printf("boot_override = 0x%02x\n", CPLD_READ(boot_override));
u8 int_status; /* 0x12 - Interrupt status Register */
u8 flash_ctl_status; /* 0x13 - Flash control and status register */
u8 fan_ctl_status; /* 0x14 - Fan control and status register */
+#if defined(CONFIG_T104XD4RDB)
+ u8 int_mask; /* 0x15 - Interrupt mask Register */
+#else
u8 led_ctl_status; /* 0x15 - LED control and status register */
+#endif
u8 sfp_ctl_status; /* 0x16 - SFP control and status register */
u8 misc_ctl_status; /* 0x17 - Miscellanies ctrl & status register*/
u8 boot_override; /* 0x18 - Boot override register */
#define CPLD_READ(reg) cpld_read(offsetof(struct cpld_data, reg))
#define CPLD_WRITE(reg, value)\
cpld_write(offsetof(struct cpld_data, reg), value)
+#define MISC_CTL_SG_SEL 0x80
+#define MISC_CTL_AURORA_SEL 0x02
* Factors to consider for half-strength driver enable:
* - number of DIMMs installed
*/
+#ifdef CONFIG_SYS_FSL_DDR4
+ popts->half_strength_driver_enable = 1;
+#else
popts->half_strength_driver_enable = 0;
+#endif
/*
* Write leveling override
*/
popts->zq_en = 1;
/* DHC_EN =1, ODT = 75 Ohm */
+#ifdef CONFIG_SYS_FSL_DDR4
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_120OHM);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_120OHM) |
+ DDR_CDR2_VREF_OVRD(70); /* Vref = 70% */
+#else
popts->ddr_cdr1 = DDR_CDR1_DHC_EN | DDR_CDR1_ODT(DDR_CDR_ODT_75ohm);
popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_75ohm);
+#endif
}
#if defined(CONFIG_DEEP_SLEEP)
* num| hi| rank| clk| wrlvl | wrlvl
* ranks| mhz| GB |adjst| start | ctl2
*/
+#ifdef CONFIG_SYS_FSL_DDR4
+ {2, 1600, 4, 4, 6, 0x07090A0c, 0x0e0f100a},
+#elif defined(CONFIG_SYS_FSL_DDR3)
{2, 833, 4, 4, 6, 0x06060607, 0x08080807},
{2, 833, 0, 4, 6, 0x06060607, 0x08080807},
{2, 1350, 4, 4, 7, 0x0708080A, 0x0A0B0C09},
{1, 1350, 0, 4, 7, 0x0708080A, 0x0A0B0C09},
{1, 1666, 4, 4, 7, 0x0808090B, 0x0C0D0E0A},
{1, 1666, 0, 4, 7, 0x0808090B, 0x0C0D0E0A},
+#else
+#error DDR type not defined
+#endif
{}
};
+#endif
+
static const struct board_specific_parameters *udimms[] = {
udimm0,
};
-#endif
int idx = i - FM1_DTSEC1;
switch (fm_info_get_enet_if(i)) {
-#ifdef CONFIG_T1040RDB
+#if defined(CONFIG_T1040RDB) || defined(CONFIG_T1040D4RDB)
case PHY_INTERFACE_MODE_SGMII:
- /* T1040RDB only supports SGMII on DTSEC3 */
+ /* T1040RDB & T1040D4RDB only supports SGMII on
+ * DTSEC3
+ */
fm_info_set_phy_address(FM1_DTSEC3,
CONFIG_SYS_SGMII1_PHY_ADDR);
break;
fm_info_set_phy_address(FM1_DTSEC3,
CONFIG_SYS_SGMII1_PHY_ADDR);
break;
+#endif
+#ifdef CONFIG_T1042D4RDB
+ case PHY_INTERFACE_MODE_SGMII:
+ /* T1042D4RDB supports SGMII on DTSEC1, DTSEC2
+ * & DTSEC3
+ */
+ if (FM1_DTSEC1 == i)
+ phy_addr = CONFIG_SYS_SGMII1_PHY_ADDR;
+ if (FM1_DTSEC2 == i)
+ phy_addr = CONFIG_SYS_SGMII2_PHY_ADDR;
+ if (FM1_DTSEC3 == i)
+ phy_addr = CONFIG_SYS_SGMII3_PHY_ADDR;
+ fm_info_set_phy_address(i, phy_addr);
+ break;
#endif
case PHY_INTERFACE_MODE_RGMII:
if (FM1_DTSEC4 == i)
--- /dev/null
+#PBL preamble and RCW header
+aa55aa55 010e0100
+# serdes protocol 0x66
+0c18000e 0e000000 00000000 00000000
+66000002 40000002 ec027000 01000000
+00000000 00000000 00000000 00030810
+00000000 0342580f 00000000 00000000
--- /dev/null
+#PBL preamble and RCW header
+aa55aa55 010e0100
+# serdes protocol 0x86
+0c18000e 0e000000 00000000 00000000
+86000002 40000002 ec027000 01000000
+00000000 00000000 00000000 00030810
+00000000 0342500f 00000000 00000000
#Configure CPC1 as 256KB SRAM
09010100 00000000
09010104 fffc0007
-09010f00 08000000
+09010f00 081e000d
09010000 80000000
#Configure LAW for CPC1
09000cd0 00000000
struct cpu_type *cpu = gd->arch.cpu;
u8 sw;
+#ifdef CONFIG_T104XD4RDB
+ printf("Board: %sD4RDB\n", cpu->name);
+#else
printf("Board: %sRDB\n", cpu->name);
+#endif
printf("Board rev: 0x%02x CPLD ver: 0x%02x, ",
CPLD_READ(hw_ver), CPLD_READ(sw_ver));
sw = CPLD_READ(flash_ctl_status);
sw = ((sw & CPLD_LBMAP_MASK) >> CPLD_LBMAP_SHIFT);
- if (sw <= 7)
- printf("vBank: %d\n", sw);
- else
- printf("Unsupported Bank=%x\n", sw);
+ printf("vBank: %d\n", sw);
return 0;
}
int misc_init_r(void)
{
+ ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+ u32 srds_s1;
+
+ srds_s1 = in_be32(&gur->rcwsr[4]) >> 24;
+
+ printf("SERDES Reference : 0x%X\n", srds_s1);
+
+ /* select SGMII*/
+ if (srds_s1 == 0x86)
+ CPLD_WRITE(misc_ctl_status, CPLD_READ(misc_ctl_status) |
+ MISC_CTL_SG_SEL);
+
+ /* select SGMII and Aurora*/
+ if (srds_s1 == 0x8E)
+ CPLD_WRITE(misc_ctl_status, CPLD_READ(misc_ctl_status) |
+ MISC_CTL_SG_SEL | MISC_CTL_AURORA_SEL);
+
+#if defined(CONFIG_T1040D4RDB)
+ /* Mask all CPLD interrupt sources, except QSGMII interrupts */
+ if (CPLD_READ(sw_ver) < 0x03) {
+ debug("CPLD SW version 0x%02x doesn't support int_mask\n",
+ CPLD_READ(sw_ver));
+ } else {
+ CPLD_WRITE(int_mask, CPLD_INT_MASK_ALL &
+ ~(CPLD_INT_MASK_QSGMII1 | CPLD_INT_MASK_QSGMII2));
+ }
+#endif
+
return 0;
}
switch (curbank) {
case CPLD_SELECT_BANK0:
- altbank = CPLD_SELECT_BANK4;
- CPLD_WRITE(vbank, altbank);
- override = CPLD_READ(software_on);
- CPLD_WRITE(software_on, override | CPLD_BANK_SEL_EN);
- CPLD_WRITE(sys_reset, CPLD_SYSTEM_RESET);
- break;
case CPLD_SELECT_BANK4:
- altbank = CPLD_SELECT_BANK0;
+ altbank = CPLD_SELECT_BANK4;
CPLD_WRITE(vbank, altbank);
override = CPLD_READ(software_on);
CPLD_WRITE(software_on, override | CPLD_BANK_SEL_EN);
#include <asm/arch/soc.h>
#include <linux/mbus.h>
-#include "../drivers/ddr/mvebu/ddr3_hw_training.h"
-#include "../arch/arm/mach-mvebu/serdes/high_speed_env_spec.h"
+#include "../drivers/ddr/marvell/axp/ddr3_hw_training.h"
+#include "../arch/arm/mach-mvebu/serdes/axp/high_speed_env_spec.h"
DECLARE_GLOBAL_DATA_PTR;
/*
- * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
+ * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
PINCFG(SDMMC4_DAT6_PAA6, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
PINCFG(SDMMC4_DAT7_PAA7, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
PINCFG(PBB0, VGP6, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
- PINCFG(CAM_I2C_SCL_PBB1, RSVD3, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
- PINCFG(CAM_I2C_SDA_PBB2, RSVD3, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CAM_I2C_SCL_PBB1, I2C3, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
+ PINCFG(CAM_I2C_SDA_PBB2, I2C3, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
PINCFG(PBB3, VGP3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
PINCFG(PBB4, VGP4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
PINCFG(PBB5, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
PINCFG(HDMI_CEC_PEE3, CEC, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
PINCFG(SDMMC3_CLK_LB_OUT_PEE4, SDMMC3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
PINCFG(SDMMC3_CLK_LB_IN_PEE5, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
- PINCFG(DP_HPD_PFF0, DP, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
+ PINCFG(DP_HPD_PFF0, DP, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
PINCFG(USB_VBUS_EN2_PFF1, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
PINCFG(PFF2, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
PINCFG(CORE_PWR_REQ, PWRON, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
--- /dev/null
+if TARGET_P2571
+
+config SYS_BOARD
+ default "p2571"
+
+config SYS_VENDOR
+ default "nvidia"
+
+config SYS_CONFIG_NAME
+ default "p2571"
+
+endif
--- /dev/null
+P2571 BOARD
+M: Tom Warren <twarren@nvidia.com>
+S: Maintained
+F: board/nvidia/p2571/
+F: include/configs/p2571.h
+F: configs/p2571_defconfig
--- /dev/null
+#
+# (C) Copyright 2013-2015
+# NVIDIA Corporation <www.nvidia.com>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += max77620_init.o
+obj-y += p2571.o
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch-tegra/tegra_i2c.h>
+#include "max77620_init.h"
+
+/* MAX77620-PMIC-specific early init code - get CPU rails up, etc */
+
+void tegra_i2c_ll_write_addr(uint addr, uint config)
+{
+ struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
+
+ writel(addr, ®->cmd_addr0);
+ writel(config, ®->cnfg);
+}
+
+void tegra_i2c_ll_write_data(uint data, uint config)
+{
+ struct i2c_ctlr *reg = (struct i2c_ctlr *)TEGRA_DVC_BASE;
+
+ writel(data, ®->cmd_data1);
+ writel(config, ®->cnfg);
+}
+
+void pmic_enable_cpu_vdd(void)
+{
+ uint reg;
+ debug("%s entry\n", __func__);
+
+ /* Setup/Enable GPIO5 - VDD_CPU_REG_EN */
+ debug("%s: Setting GPIO5 to enable CPU regulator\n", __func__);
+ /* B3=1=logic high,B2=dontcare,B1=0=output,B0=1=push-pull */
+ reg = 0x0900 | MAX77620_GPIO5_REG;
+ tegra_i2c_ll_write_addr(MAX77620_I2C_ADDR, 2);
+ tegra_i2c_ll_write_data(reg, I2C_SEND_2_BYTES);
+ udelay(10 * 1000);
+
+ /* Setup/Enable GPIO1 - VDD_HDMI_5V0_BST_EN */
+ debug("%s: Setting GPIO1 to enable HDMI\n", __func__);
+ reg = 0x0900 | MAX77620_GPIO1_REG;
+ tegra_i2c_ll_write_addr(MAX77620_I2C_ADDR, 2);
+ tegra_i2c_ll_write_data(reg, I2C_SEND_2_BYTES);
+ udelay(10 * 1000);
+
+ /* GPIO 0,1,5,6,7 = GPIO, 2,3,4 = alt mode */
+ reg = 0x1C00 | MAX77620_AME_GPIO;
+ tegra_i2c_ll_write_addr(MAX77620_I2C_ADDR, 2);
+ tegra_i2c_ll_write_data(reg, I2C_SEND_2_BYTES);
+ udelay(10 * 1000);
+
+ /* Disable SD1 Remote Sense, Set SD1 for LPDDR4 to 1.125v */
+ debug("%s: Set SD1 for LPDDR4, disable SD1RS, voltage to 1.125v\n",
+ __func__);
+ /* bit1=0, SD1 remote sense disabled */
+ reg = 0x0400 | MAX77620_CNFG2SD_REG;
+ tegra_i2c_ll_write_addr(MAX77620_I2C_ADDR, 2);
+ tegra_i2c_ll_write_data(reg, I2C_SEND_2_BYTES);
+ udelay(10 * 1000);
+
+ /* SD1 output = 1.125V */
+ reg = 0x2A00 | MAX77620_SD1_REG;
+ tegra_i2c_ll_write_addr(MAX77620_I2C_ADDR, 2);
+ tegra_i2c_ll_write_data(reg, I2C_SEND_2_BYTES);
+ udelay(10 * 1000);
+
+ debug("%s: Set LDO2 for VDDIO_SDMMC_AP power to 3.3V\n", __func__);
+ /* 0xF2 for 3.3v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
+ reg = 0xF200 | MAX77620_CNFG1_L2_REG;
+ tegra_i2c_ll_write_addr(MAX77620_I2C_ADDR, 2);
+ tegra_i2c_ll_write_data(reg, I2C_SEND_2_BYTES);
+ udelay(10 * 1000);
+
+ debug("%s: Set LDO1 for USB3 phy power to 1.05V??\n", __func__);
+ /* 0xCA for 105v, enabled: bit7:6 = 11 = enable, bit5:0 = voltage */
+ reg = 0xCA00 | MAX77620_CNFG1_L1_REG;
+ tegra_i2c_ll_write_addr(MAX77620_I2C_ADDR, 2);
+ tegra_i2c_ll_write_data(reg, I2C_SEND_2_BYTES);
+ udelay(10 * 1000);
+}
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _MAX77620_INIT_H_
+#define _MAX77620_INIT_H_
+
+/* MAX77620-PMIC-specific early init regs */
+
+#define MAX77620_I2C_ADDR 0x78 /* or 0x3C 7-bit */
+
+#define MAX77620_SD0_REG 0x16
+#define MAX77620_SD1_REG 0x17
+#define MAX77620_SD2_REG 0x18
+#define MAX77620_SD3_REG 0x19
+#define MAX77620_CNFG2SD_REG 0x22
+
+#define MAX77620_CNFG1_L0_REG 0x23
+#define MAX77620_CNFG2_L0_REG 0x24
+#define MAX77620_CNFG1_L1_REG 0x25
+#define MAX77620_CNFG2_L1_REG 0x26
+#define MAX77620_CNFG1_L2_REG 0x27
+#define MAX77620_CNFG2_L2_REG 0x28
+#define MAX77620_CNFG1_L3_REG 0x29
+#define MAX77620_CNFG2_L3_REG 0x2A
+#define MAX77620_CNFG1_L4_REG 0x2B
+#define MAX77620_CNFG2_L4_REG 0x2C
+#define MAX77620_CNFG1_L5_REG 0x2D
+#define MAX77620_CNFG2_L5_REG 0x2E
+#define MAX77620_CNFG1_L6_REG 0x2F
+#define MAX77620_CNFG2_L6_REG 0x30
+#define MAX77620_CNFG1_L7_REG 0x31
+#define MAX77620_CNFG2_L7_REG 0x32
+#define MAX77620_CNFG1_L8_REG 0x33
+#define MAX77620_CNFG2_L8_REG 0x34
+#define MAX77620_CNFG3_LDO_REG 0x35
+
+#define MAX77620_GPIO0_REG 0x36
+#define MAX77620_GPIO1_REG 0x37
+#define MAX77620_GPIO2_REG 0x38
+#define MAX77620_GPIO3_REG 0x39
+#define MAX77620_GPIO4_REG 0x3A
+#define MAX77620_GPIO5_REG 0x3B
+#define MAX77620_GPIO6_REG 0x3C
+#define MAX77620_GPIO7_REG 0x3D
+#define MAX77620_GPIO_PUE_GPIO 0x3E
+#define MAX77620_GPIO_PDE_GPIO 0x3F
+
+#define MAX77620_AME_GPIO 0x40
+#define MAX77620_REG_ONOFF_CFG1 0x41
+#define MAX77620_REG_ONOFF_CFG2 0x42
+
+#define MAX77620_CID0_REG 0x58
+#define MAX77620_CID1_REG 0x59
+#define MAX77620_CID2_REG 0x5A
+#define MAX77620_CID3_REG 0x5B
+#define MAX77620_CID4_REG 0x5C
+#define MAX77620_CID5_REG 0x5D
+
+#define I2C_SEND_2_BYTES 0x0A02
+
+void pmic_enable_cpu_vdd(void);
+
+#endif /* _MAX77620_INIT_H_ */
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/pinmux.h>
+#include "pinmux-config-p2571.h"
+
+/*
+ * Routine: pinmux_init
+ * Description: Do individual peripheral pinmux configs
+ */
+void pinmux_init(void)
+{
+ pinmux_clear_tristate_input_clamping();
+
+ gpio_config_table(p2571_gpio_inits,
+ ARRAY_SIZE(p2571_gpio_inits));
+
+ pinmux_config_pingrp_table(p2571_pingrps,
+ ARRAY_SIZE(p2571_pingrps));
+
+ pinmux_config_drvgrp_table(p2571_drvgrps,
+ ARRAY_SIZE(p2571_drvgrps));
+}
--- /dev/null
+/*
+ * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _PINMUX_CONFIG_P2571_H_
+#define _PINMUX_CONFIG_P2571_H_
+
+#define GPIO_INIT(_gpio, _init) \
+ { \
+ .gpio = GPIO_P##_gpio, \
+ .init = TEGRA_GPIO_INIT_##_init, \
+ }
+
+static const struct tegra_gpio_config p2571_gpio_inits[] = {
+ /* gpio, init_val */
+ GPIO_INIT(A0, IN),
+ GPIO_INIT(A5, IN),
+ GPIO_INIT(D4, IN),
+ GPIO_INIT(E4, OUT0),
+ GPIO_INIT(G0, IN),
+ GPIO_INIT(H0, OUT0),
+ GPIO_INIT(H2, IN),
+ GPIO_INIT(H3, OUT0),
+ GPIO_INIT(H4, OUT0),
+ GPIO_INIT(H5, IN),
+ GPIO_INIT(I0, OUT0),
+ GPIO_INIT(I1, IN),
+ GPIO_INIT(V1, OUT0),
+ GPIO_INIT(V6, OUT1),
+ GPIO_INIT(X4, IN),
+ GPIO_INIT(X6, IN),
+ GPIO_INIT(X7, IN),
+ GPIO_INIT(Y1, IN),
+ GPIO_INIT(Z0, IN),
+ GPIO_INIT(Z4, OUT0),
+ GPIO_INIT(BB2, OUT0),
+ GPIO_INIT(CC1, IN),
+ GPIO_INIT(CC3, IN),
+};
+
+#define PINCFG(_pingrp, _mux, _pull, _tri, _io, _od, _e_io_hv) \
+ { \
+ .pingrp = PMUX_PINGRP_##_pingrp, \
+ .func = PMUX_FUNC_##_mux, \
+ .pull = PMUX_PULL_##_pull, \
+ .tristate = PMUX_TRI_##_tri, \
+ .io = PMUX_PIN_##_io, \
+ .od = PMUX_PIN_OD_##_od, \
+ .e_io_hv = PMUX_PIN_E_IO_HV_##_e_io_hv, \
+ .lock = PMUX_PIN_LOCK_DEFAULT, \
+ }
+
+static const struct pmux_pingrp_config p2571_pingrps[] = {
+ /* pingrp, mux, pull, tri, e_input, od, e_io_hv */
+ PINCFG(PEX_L0_RST_N_PA0, DEFAULT, UP, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(PEX_L0_CLKREQ_N_PA1, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, NORMAL),
+ PINCFG(PEX_WAKE_N_PA2, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, NORMAL),
+ PINCFG(PEX_L1_RST_N_PA3, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, NORMAL),
+ PINCFG(PEX_L1_CLKREQ_N_PA4, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, NORMAL),
+ PINCFG(SATA_LED_ACTIVE_PA5, DEFAULT, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(PA6, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DAP1_FS_PB0, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DAP1_DIN_PB1, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DAP1_DOUT_PB2, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DAP1_SCLK_PB3, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI2_MOSI_PB4, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI2_MISO_PB5, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI2_SCK_PB6, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI2_CS0_PB7, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI1_MOSI_PC0, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI1_MISO_PC1, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI1_SCK_PC2, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI1_CS0_PC3, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI1_CS1_PC4, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI4_SCK_PC5, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI4_CS0_PC6, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI4_MOSI_PC7, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPI4_MISO_PD0, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART3_TX_PD1, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART3_RX_PD2, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART3_RTS_PD3, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART3_CTS_PD4, DEFAULT, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DMIC1_CLK_PE0, I2S3, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DMIC1_DAT_PE1, I2S3, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DMIC2_CLK_PE2, I2S3, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DMIC2_DAT_PE3, I2S3, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DMIC3_CLK_PE4, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DMIC3_DAT_PE5, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PE6, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PE7, PWM3, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(GEN3_I2C_SCL_PF0, I2C3, NORMAL, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(GEN3_I2C_SDA_PF1, I2C3, NORMAL, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(UART2_TX_PG0, DEFAULT, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(UART2_RX_PG1, UARTB, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART2_RTS_PG2, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART2_CTS_PG3, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(WIFI_EN_PH0, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(WIFI_RST_PH1, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(WIFI_WAKE_AP_PH2, DEFAULT, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(AP_WAKE_BT_PH3, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(BT_RST_PH4, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(BT_WAKE_AP_PH5, DEFAULT, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(PH6, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(AP_WAKE_NFC_PH7, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(NFC_EN_PI0, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(NFC_INT_PI1, DEFAULT, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(GPS_EN_PI2, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(GPS_RST_PI3, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART4_TX_PI4, UARTD, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART4_RX_PI5, UARTD, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(UART4_RTS_PI6, UARTD, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART4_CTS_PI7, UARTD, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(GEN1_I2C_SDA_PJ0, I2C1, NORMAL, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(GEN1_I2C_SCL_PJ1, I2C1, NORMAL, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(GEN2_I2C_SCL_PJ2, I2C2, NORMAL, NORMAL, INPUT, DISABLE, HIGH),
+ PINCFG(GEN2_I2C_SDA_PJ3, I2C2, NORMAL, NORMAL, INPUT, DISABLE, HIGH),
+ PINCFG(DAP4_FS_PJ4, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DAP4_DIN_PJ5, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DAP4_DOUT_PJ6, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DAP4_SCLK_PJ7, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PK0, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PK1, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PK2, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PK3, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PK4, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PK5, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PK6, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PK7, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PL0, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PL1, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC1_CLK_PM0, SDMMC1, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC1_CMD_PM1, SDMMC1, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC1_DAT3_PM2, SDMMC1, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC1_DAT2_PM3, SDMMC1, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC1_DAT1_PM4, SDMMC1, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC1_DAT0_PM5, SDMMC1, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC3_CLK_PP0, SDMMC3, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC3_CMD_PP1, SDMMC3, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC3_DAT3_PP2, SDMMC3, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC3_DAT2_PP3, SDMMC3, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC3_DAT1_PP4, SDMMC3, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(SDMMC3_DAT0_PP5, SDMMC3, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(CAM1_MCLK_PS0, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CAM2_MCLK_PS1, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CAM_I2C_SCL_PS2, I2CVI, NORMAL, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(CAM_I2C_SDA_PS3, I2CVI, NORMAL, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(CAM_RST_PS4, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CAM_AF_EN_PS5, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CAM_FLASH_EN_PS6, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CAM1_PWDN_PS7, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CAM2_PWDN_PT0, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CAM1_STROBE_PT1, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART1_TX_PU0, UARTA, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART1_RX_PU1, UARTA, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(UART1_RTS_PU2, UARTA, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(UART1_CTS_PU3, UARTA, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(LCD_BL_PWM_PV0, PWM0, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(LCD_BL_EN_PV1, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(LCD_RST_PV2, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(LCD_GPIO1_PV3, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(LCD_GPIO2_PV4, PWM1, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(AP_READY_PV5, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(TOUCH_RST_PV6, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(TOUCH_CLK_PV7, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(MODEM_WAKE_AP_PX0, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(TOUCH_INT_PX1, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(MOTION_INT_PX2, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(ALS_PROX_INT_PX3, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(TEMP_ALERT_PX4, DEFAULT, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(BUTTON_POWER_ON_PX5, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(BUTTON_VOL_UP_PX6, DEFAULT, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(BUTTON_VOL_DOWN_PX7, DEFAULT, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(BUTTON_SLIDE_SW_PY0, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(BUTTON_HOME_PY1, DEFAULT, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(LCD_TE_PY2, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PWR_I2C_SCL_PY3, I2CPMU, NORMAL, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(PWR_I2C_SDA_PY4, I2CPMU, NORMAL, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(CLK_32K_OUT_PY5, SOC, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(PZ0, DEFAULT, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(PZ1, SDMMC1, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(PZ2, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PZ3, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PZ4, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PZ5, SOC, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DAP2_FS_PAA0, I2S2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DAP2_SCLK_PAA1, I2S2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DAP2_DIN_PAA2, I2S2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(DAP2_DOUT_PAA3, I2S2, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(AUD_MCLK_PBB0, AUD, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DVFS_PWM_PBB1, CLDVFS, NORMAL, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(DVFS_CLK_PBB2, DEFAULT, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(GPIO_X1_AUD_PBB3, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(GPIO_X3_AUD_PBB4, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(HDMI_CEC_PCC0, CEC, NORMAL, NORMAL, INPUT, DISABLE, HIGH),
+ PINCFG(HDMI_INT_DP_HPD_PCC1, DEFAULT, DOWN, NORMAL, INPUT, DISABLE, NORMAL),
+ PINCFG(SPDIF_OUT_PCC2, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SPDIF_IN_PCC3, DEFAULT, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(USB_VBUS_EN0_PCC4, USB, NORMAL, NORMAL, INPUT, DISABLE, HIGH),
+ PINCFG(USB_VBUS_EN1_PCC5, USB, NORMAL, NORMAL, INPUT, DISABLE, HIGH),
+ PINCFG(DP_HPD0_PCC6, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PCC7, RSVD0, DOWN, TRISTATE, OUTPUT, DISABLE, NORMAL),
+ PINCFG(SPI2_CS1_PDD0, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(QSPI_SCK_PEE0, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(QSPI_CS_N_PEE1, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(QSPI_IO0_PEE2, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(QSPI_IO1_PEE3, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(QSPI_IO2_PEE4, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(QSPI_IO3_PEE5, RSVD1, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CORE_PWR_REQ, CORE, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CPU_PWR_REQ, CPU, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(PWR_INT_N, PMI, UP, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(CLK_32K_IN, CLK, NORMAL, NORMAL, INPUT, DISABLE, DEFAULT),
+ PINCFG(JTAG_RTCK, JTAG, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(CLK_REQ, SYS, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+ PINCFG(SHUTDOWN, SHUTDOWN, NORMAL, NORMAL, OUTPUT, DISABLE, DEFAULT),
+};
+
+#define DRVCFG(_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) \
+ { \
+ .drvgrp = PMUX_DRVGRP_##_drvgrp, \
+ .slwf = _slwf, \
+ .slwr = _slwr, \
+ .drvup = _drvup, \
+ .drvdn = _drvdn, \
+ .lpmd = PMUX_LPMD_##_lpmd, \
+ .schmt = PMUX_SCHMT_##_schmt, \
+ .hsm = PMUX_HSM_##_hsm, \
+ }
+
+static const struct pmux_drvgrp_config p2571_drvgrps[] = {
+};
+
+#endif /* PINMUX_CONFIG_P2571_H */
#
obj-$(CONFIG_SOFT_I2C_MULTI_BUS) += multi_i2c.o
-obj-$(CONFIG_USBDOWNLOAD_GADGET) += gadget.o
+obj-$(CONFIG_USB_GADGET_DOWNLOAD) += gadget.o
obj-$(CONFIG_MISC_COMMON) += misc.o
ifndef CONFIG_SPL_BUILD
unsigned char eeprom_buf[0x3c00], hdr[4], buf[MAX_STRING_LENGTH];
unsigned char *cp, *cp1;
-#if defined(CONFIG_DFU_FUNCTION)
+#if defined(CONFIG_USB_FUNCTION_DFU)
factory_dat.usb_vendor_id = CONFIG_G_DNL_VENDOR_NUM;
factory_dat.usb_product_id = CONFIG_G_DNL_PRODUCT_NUM;
#endif
cp1 += 3;
}
-#if defined(CONFIG_DFU_FUNCTION)
+#if defined(CONFIG_USB_FUNCTION_DFU)
/* read vid and pid for dfu mode */
if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1",
(uchar *)"vid", buf,
return 0;
}
+
+#ifdef CONFIG_MISC_INIT_R
+int misc_init_r(void)
+{
+ char serialno[25];
+ uint32_t u_id_low, u_id_mid, u_id_high;
+
+ if (!getenv("serial#")) {
+ u_id_low = readl(&STM32_U_ID->u_id_low);
+ u_id_mid = readl(&STM32_U_ID->u_id_mid);
+ u_id_high = readl(&STM32_U_ID->u_id_high);
+ sprintf(serialno, "%08x%08x%08x",
+ u_id_high, u_id_mid, u_id_low);
+ setenv("serial#", serialno);
+ }
+
+ return 0;
+}
+#endif
Set the Vbus detect pin for usb0 (otg). This takes a string in the
format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
+config USB0_ID_DET
+ string "ID detect pin for usb0 (otg)"
+ default ""
+ ---help---
+ Set the ID detect pin for usb0 (otg). This takes a string in the
+ format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
+
config USB1_VBUS_PIN
string "Vbus enable pin for usb1 (ehci0)"
default "PH6" if MACH_SUN4I || MACH_SUN7I
#include <asm/arch/usb_phy.h>
#include <asm/gpio.h>
#include <asm/io.h>
-#include <linux/usb/musb.h>
#include <net.h>
#if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
return -1;
#endif
-#if CONFIG_MMC_SUNXI_SLOT == 0 && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
+#if !defined(CONFIG_SPL_BUILD) && CONFIG_MMC_SUNXI_SLOT_EXTRA == 2
/*
- * Both mmc0 and mmc2 are bootable, figure out where we're booting
- * from. Try mmc0 first, just like the brom does.
+ * On systems with an emmc (mmc2), figure out if we are booting from
+ * the emmc and if we are make it "mmc dev 0" so that boot.scr, etc.
+ * are searched there first. Note we only do this for u-boot proper,
+ * not for the SPL, see spl_boot_device().
*/
- if (mmc_getcd(mmc0) && mmc_init(mmc0) == 0 &&
- mmc0->block_dev.block_read(0, 16, 1, buf) == 1) {
- buf[12] = 0;
- if (strcmp(&buf[4], "eGON.BT0") == 0)
- return 0;
+ if (!sunxi_mmc_has_egon_boot_signature(mmc0) &&
+ sunxi_mmc_has_egon_boot_signature(mmc1)) {
+ /* Booting from emmc / mmc2, swap */
+ mmc0->block_dev.dev = 1;
+ mmc1->block_dev.dev = 0;
}
-
- /* no bootable card in mmc0, so we must be booting from mmc2, swap */
- mmc0->block_dev.dev = 1;
- mmc1->block_dev.dev = 0;
#endif
return 0;
}
#endif
-#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
-extern const struct musb_platform_ops sunxi_musb_ops;
-
-static struct musb_hdrc_config musb_config = {
- .multipoint = 1,
- .dyn_fifo = 1,
- .num_eps = 6,
- .ram_bits = 11,
-};
-
-static struct musb_hdrc_platform_data musb_plat = {
-#if defined(CONFIG_MUSB_HOST)
- .mode = MUSB_HOST,
-#else
- .mode = MUSB_PERIPHERAL,
-#endif
- .config = &musb_config,
- .power = 250,
- .platform_ops = &sunxi_musb_ops,
-};
-#endif
-
#ifdef CONFIG_USB_GADGET
int g_dnl_board_usb_cable_connected(void)
{
if (ret)
return ret;
#endif
-#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
- musb_register(&musb_plat, NULL, (void *)SUNXI_USB0_BASE);
-#endif
+ sunxi_musb_board_init();
+
return 0;
}
#endif
#include <common.h>
#include <asm/arch/dram.h>
-#include <linux/kconfig.h>
static struct dram_para dram_para = {
.clock = CONFIG_DRAM_CLK,
#include <common.h>
#include <asm/arch/dram.h>
-#include <linux/kconfig.h>
static struct dram_para dram_para = {
.clock = CONFIG_DRAM_CLK,
include/configs/k2hk_evm.h
include/configs/k2e_evm.h
include/configs/k2l_evm.h
-include/configs/k2l_evm.h
As u-boot is migrating to Kconfig there is also board defconfig files
configs/k2e_evm_defconfig
To build u-boot.bin
>make k2hk_evm_defconfig
- >make u-boot-spi.gph
+ >make u-boot.bin
To build u-boot-spi.gph
>make k2hk_evm_defconfig
int board_init(void)
{
- gd->bd->bi_boot_params = CONFIG_LINUX_BOOT_PARAM_ADDR;
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
return 0;
}
ifneq ($(wildcard $(srctree)/$(src)/ps7_init_gpl.c),)
init-objs := ps7_init_gpl.o
$(if $(CONFIG_SPL_BUILD),\
-$(warning Put custom ps7_init_gpl.c/h to board/xilinx/zynq/custome_hw_platform/))
+$(warning Put custom ps7_init_gpl.c/h to board/xilinx/zynq/custom_hw_platform/))
endif
endif
+++ /dev/null
-if TARGET_XILINX_ZYNQMP
-
-config SYS_BOARD
- default "zynqmp"
-
-config SYS_VENDOR
- default "xilinx"
-
-config SYS_SOC
- default "zynqmp"
-
-config SYS_CONFIG_NAME
- default "xilinx_zynqmp"
-
-endif
-XILINX_ZYNQMP BOARD
+XILINX_ZYNQMP_EP BOARD
M: Michal Simek <michal.simek@xilinx.com>
S: Maintained
F: board/xilinx/zynqmp/
F: include/configs/xilinx_zynqmp.h
-F: configs/xilinx_zynqmp_defconfig
+F: include/configs/xilinx_zynqmp_ep.h
+F: configs/xilinx_zynqmp_ep_defconfig
#include <common.h>
#include <netdev.h>
+#include <ahci.h>
+#include <scsi.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
#include <asm/io.h>
int board_init(void)
{
+ printf("EL Level:\tEL%d\n", current_el());
+
return 0;
}
{
}
+#ifdef CONFIG_SCSI_AHCI_PLAT
+void scsi_init(void)
+{
+ ahci_init((void __iomem *)ZYNQMP_SATA_BASEADDR);
+ scsi_scan(1);
+}
+#endif
+
+int board_eth_init(bd_t *bis)
+{
+ u32 ret = 0;
+
+#if defined(CONFIG_ZYNQ_GEM)
+# if defined(CONFIG_ZYNQ_GEM0)
+ ret |= zynq_gem_initialize(bis, ZYNQ_GEM_BASEADDR0,
+ CONFIG_ZYNQ_GEM_PHY_ADDR0, 0);
+# endif
+# if defined(CONFIG_ZYNQ_GEM1)
+ ret |= zynq_gem_initialize(bis, ZYNQ_GEM_BASEADDR1,
+ CONFIG_ZYNQ_GEM_PHY_ADDR1, 0);
+# endif
+# if defined(CONFIG_ZYNQ_GEM2)
+ ret |= zynq_gem_initialize(bis, ZYNQ_GEM_BASEADDR2,
+ CONFIG_ZYNQ_GEM_PHY_ADDR2, 0);
+# endif
+# if defined(CONFIG_ZYNQ_GEM3)
+ ret |= zynq_gem_initialize(bis, ZYNQ_GEM_BASEADDR3,
+ CONFIG_ZYNQ_GEM_PHY_ADDR3, 0);
+# endif
+#endif
+ return ret;
+}
+
#ifdef CONFIG_CMD_MMC
int board_mmc_init(bd_t *bd)
{
/*
* If the root node of the DTB has a "model" property, show it.
- * If CONFIG_OF_CONTROL is disabled or the "model" property is missing,
- * fall back to checkboard().
+ * Then call checkboard().
*/
int show_board_info(void)
{
model = fdt_getprop(gd->fdt_blob, 0, "model", NULL);
- if (model) {
+ if (model)
printf("Model: %s\n", model);
- return 0;
- }
#endif
return checkboard();
#include <common.h>
#include <command.h>
#include <g_dnl.h>
+#include <usb.h>
static int do_fastboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
+ int controller_index;
+ char *usb_controller;
int ret;
+ if (argc < 2)
+ return CMD_RET_USAGE;
+
+ usb_controller = argv[1];
+ controller_index = simple_strtoul(usb_controller, NULL, 0);
+
+ ret = board_usb_init(controller_index, USB_INIT_DEVICE);
+ if (ret) {
+ error("USB init failed: %d", ret);
+ return CMD_RET_FAILURE;
+ }
+
g_dnl_clear_detach();
ret = g_dnl_register("usb_dnl_fastboot");
if (ret)
if (!g_dnl_board_usb_cable_connected()) {
puts("\rUSB cable not detected.\n" \
"Command exit.\n");
- g_dnl_unregister();
- g_dnl_clear_detach();
- return CMD_RET_FAILURE;
+ ret = CMD_RET_FAILURE;
+ goto exit;
}
while (1) {
break;
if (ctrlc())
break;
- usb_gadget_handle_interrupts(0);
+ usb_gadget_handle_interrupts(controller_index);
}
+ ret = CMD_RET_SUCCESS;
+
+exit:
g_dnl_unregister();
g_dnl_clear_detach();
- return CMD_RET_SUCCESS;
+ board_usb_cleanup(controller_index, USB_INIT_DEVICE);
+
+ return ret;
}
U_BOOT_CMD(
- fastboot, 1, 0, do_fastboot,
+ fastboot, 2, 1, do_fastboot,
"use USB Fastboot protocol",
- "\n"
+ "<USB_controller>\n"
" - run as a fastboot usb device"
);
buf = map_sysmem(addr, 0);
working_fdt = buf;
- setenv_ulong("fdtaddr", addr);
+ setenv_hex("fdtaddr", addr);
}
/*
#include <common.h>
#include <command.h>
+static int cpu_status_all(void)
+{
+ unsigned long cpuid;
+
+ for (cpuid = 0; ; cpuid++) {
+ if (!is_core_valid(cpuid)) {
+ if (cpuid == 0) {
+ printf("Core num: %lu is not valid\n", cpuid);
+ return 1;
+ }
+ break;
+ }
+ cpu_status(cpuid);
+ }
+
+ return 0;
+}
+
static int
cpu_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
unsigned long cpuid;
+ if (argc == 2 && strncmp(argv[1], "status", 6) == 0)
+ return cpu_status_all();
+
if (argc < 3)
return CMD_RET_USAGE;
#ifdef CONFIG_SYS_LONGHELP
static char cpu_help_text[] =
"<num> reset - Reset cpu <num>\n"
+ "cpu status - Status of all cpus\n"
"cpu <num> status - Status of cpu <num>\n"
"cpu <num> disable - Disable cpu <num>\n"
"cpu <num> release <addr> [args] - Release cpu <num> at <addr> with [args]"
/* Try bootm for legacy and FIT format image */
if (genimg_get_format(buf) != IMAGE_FORMAT_INVALID)
do_bootm(cmdtp, 0, bootm_argc, bootm_argv);
-#ifdef CONFIG_CMD_BOOTZ
- /* Try booting a zImage */
+#ifdef CONFIG_CMD_BOOTI
+ /* Try booting an AArch64 Linux kernel image */
+ else
+ do_booti(cmdtp, 0, bootm_argc, bootm_argv);
+#elif defined(CONFIG_CMD_BOOTZ)
+ /* Try booting a Image */
else
do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
#endif
#include <tsi148.h>
-#define PCI_VENDOR PCI_VENDOR_ID_TUNDRA
-#define PCI_DEVICE PCI_DEVICE_ID_TUNDRA_TSI148
+#define LPCI_VENDOR PCI_VENDOR_ID_TUNDRA
+#define LPCI_DEVICE PCI_DEVICE_ID_TUNDRA_TSI148
typedef struct _TSI148_DEV TSI148_DEV;
pci_dev_t busdevfn;
unsigned int val;
- busdevfn = pci_find_device(PCI_VENDOR, PCI_DEVICE, 0);
+ busdevfn = pci_find_device(LPCI_VENDOR, LPCI_DEVICE, 0);
if (busdevfn == -1) {
puts("Tsi148: No Tundra Tsi148 found!\n");
return -1;
/* check mapping */
debug("Tsi148: Read via mapping, PCI_ID = %08X\n",
readl(&dev->uregs->pci_id));
- if (((PCI_DEVICE << 16) | PCI_VENDOR) != readl(&dev->uregs->pci_id)) {
+ if (((LPCI_DEVICE << 16) | LPCI_VENDOR) != readl(&dev->uregs->pci_id)) {
printf("Tsi148: Cannot read PCI-ID via Mapping: %08x\n",
readl(&dev->uregs->pci_id));
result = -1;
#ifdef CONFIG_USB_STORAGE
static int usb_stor_curr_dev = -1; /* current device */
#endif
-#ifdef CONFIG_USB_HOST_ETHER
-static int usb_ether_curr_dev = -1; /* current ethernet device */
+#if defined(CONFIG_USB_HOST_ETHER) && !defined(CONFIG_DM_ETH)
+static int __maybe_unused usb_ether_curr_dev = -1; /* current ethernet device */
#endif
/* some display routines (info command) */
#endif
/* check if we are the last one */
#ifdef CONFIG_DM_USB
- last_child = device_is_last_sibling(dev->dev);
+ /* Not the root of the usb tree? */
+ if (device_get_uclass_id(dev->dev->parent) != UCLASS_USB) {
+ last_child = device_is_last_sibling(dev->dev);
#else
- last_child = (dev->parent != NULL);
-#endif
- if (last_child) {
-#ifndef CONFIG_DM_USB
+ if (dev->parent != NULL) { /* not root? */
+ last_child = 1;
for (i = 0; i < dev->parent->maxchild; i++) {
/* search for children */
if (dev->parent->children[i] == dev) {
/* try to recognize storage devices immediately */
usb_stor_curr_dev = usb_stor_scan(1);
#endif
-#endif
#ifdef CONFIG_USB_HOST_ETHER
+# ifdef CONFIG_DM_ETH
+# error "You must use CONFIG_DM_USB if you want to use CONFIG_USB_HOST_ETHER with CONFIG_DM_ETH"
+# endif
/* try to recognize ethernet devices immediately */
usb_ether_curr_dev = usb_host_eth_scan(1);
#endif
+#endif
#ifdef CONFIG_USB_KEYBOARD
drv_usb_kbd_init();
#endif
bus;
uclass_next_device(&bus)) {
struct usb_device *udev;
- struct udevice *hub;
+ struct udevice *dev;
- device_find_first_child(bus, &hub);
- if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
- device_active(hub)) {
- udev = dev_get_parentdata(hub);
+ device_find_first_child(bus, &dev);
+ if (dev && device_active(dev)) {
+ udev = dev_get_parentdata(dev);
usb_show_tree(udev);
}
}
*/
#include <common.h>
+#include <debug_uart.h>
#include <stdarg.h>
#include <iomux.h>
#include <malloc.h>
void putc(const char c)
{
#ifdef CONFIG_SANDBOX
+ /* sandbox can send characters to stdout before it has a console */
if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
os_putc(c);
return;
}
#endif
+#ifdef CONFIG_DEBUG_UART
+ /* if we don't have a console yet, use the debug UART */
+ if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+ printch(c);
+ return;
+ }
+#endif
#ifdef CONFIG_SILENT_CONSOLE
if (gd->flags & GD_FLG_SILENT)
return;
return;
}
#endif
+#ifdef CONFIG_DEBUG_UART
+ if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+ while (*s) {
+ int ch = *s++;
+ printch(ch);
+ if (ch == '\n')
+ printch('\r');
+ }
+ return;
+ }
+#endif
#ifdef CONFIG_SILENT_CONSOLE
if (gd->flags & GD_FLG_SILENT)
return;
uint i;
char printbuffer[CONFIG_SYS_PBSIZE];
-#if !defined(CONFIG_SANDBOX) && !defined(CONFIG_PRE_CONSOLE_BUFFER)
- if (!gd->have_console)
- return 0;
-#endif
-
va_start(args, fmt);
/* For this to work, printbuffer must be larger than
#define EXPORT_FUNC(f, a, x, ...) gd->jt->x = f;
+#ifndef CONFIG_PHY_AQUANTIA
+# define mdio_get_current_dev dummy
+# define phy_find_by_mask dummy
+# define mdio_phydev_for_ethname dummy
+# define miiphy_set_current_dev dummy
+#endif
+
void jumptable_init(void)
{
gd->jt = malloc(sizeof(struct jt_funcs));
return err;
}
+ if (!banks)
+ return 0;
+
len = fdt_pack_reg(blob, tmp, start, size, banks);
err = fdt_setprop(blob, nodeoffset, "reg", tmp, len);
}
#endif
+const table_entry_t *get_table_entry(const table_entry_t *table, int id)
+{
+ for (; table->id >= 0; ++table) {
+ if (table->id == id)
+ return table;
+ }
+ return NULL;
+}
+
/**
* get_table_entry_name - translate entry id to long name
* @table: pointer to a translation table for entries of a specific type
*/
char *get_table_entry_name(const table_entry_t *table, char *msg, int id)
{
- for (; table->id >= 0; ++table) {
- if (table->id == id)
+ table = get_table_entry(table, id);
+ if (!table)
+ return msg;
#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
- return table->lname;
+ return table->lname;
#else
- return table->lname + gd->reloc_off;
+ return table->lname + gd->reloc_off;
#endif
- }
- return (msg);
}
const char *genimg_get_os_name(uint8_t os)
return (get_table_entry_name(uimage_type, "Unknown Image", type));
}
+const char *genimg_get_type_short_name(uint8_t type)
+{
+ const table_entry_t *table;
+
+ table = get_table_entry(uimage_type, type);
+ if (!table)
+ return "unknown";
+#if defined(USE_HOSTCC) || !defined(CONFIG_NEEDS_MANUAL_RELOC)
+ return table->sname;
+#else
+ return table->sname + gd->reloc_off;
+#endif
+}
+
const char *genimg_get_comp_name(uint8_t comp)
{
return (get_table_entry_name(uimage_comp, "Unknown Compression",
const char *table_name, const char *name)
{
const table_entry_t *t;
-#ifdef USE_HOSTCC
- int first = 1;
-
- for (t = table; t->id >= 0; ++t) {
- if (t->sname && strcasecmp(t->sname, name) == 0)
- return(t->id);
- }
- fprintf(stderr, "\nInvalid %s Type - valid names are", table_name);
- for (t = table; t->id >= 0; ++t) {
- if (t->sname == NULL)
- continue;
- fprintf(stderr, "%c %s", (first) ? ':' : ',', t->sname);
- first = 0;
- }
- fprintf(stderr, "\n");
-#else
for (t = table; t->id >= 0; ++t) {
#ifdef CONFIG_NEEDS_MANUAL_RELOC
- if (t->sname && strcmp(t->sname + gd->reloc_off, name) == 0)
+ if (t->sname && strcasecmp(t->sname + gd->reloc_off, name) == 0)
#else
- if (t->sname && strcmp(t->sname, name) == 0)
+ if (t->sname && strcasecmp(t->sname, name) == 0)
#endif
return (t->id);
}
debug("Invalid %s Type: %s\n", table_name, name);
-#endif /* USE_HOSTCC */
- return (-1);
+
+ return -1;
}
int genimg_get_os_id(const char *name)
}
#endif
-void board_init_r(gd_t *dummy1, ulong dummy2)
+int spl_init(void)
{
- u32 boot_device;
int ret;
- debug(">>spl:board_init_r()\n");
-
-#if defined(CONFIG_SYS_SPL_MALLOC_START)
- mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
- CONFIG_SYS_SPL_MALLOC_SIZE);
- gd->flags |= GD_FLG_FULL_MALLOC_INIT;
-#elif defined(CONFIG_SYS_MALLOC_F_LEN)
+ debug("spl_init()\n");
+#if defined(CONFIG_SYS_MALLOC_F_LEN)
gd->malloc_limit = CONFIG_SYS_MALLOC_F_LEN;
gd->malloc_ptr = 0;
#endif
ret = fdtdec_setup();
if (ret) {
debug("fdtdec_setup() returned error %d\n", ret);
- hang();
+ return ret;
}
}
if (IS_ENABLED(CONFIG_SPL_DM)) {
ret = dm_init_and_scan(true);
if (ret) {
debug("dm_init_and_scan() returned error %d\n", ret);
- hang();
+ return ret;
}
}
+ gd->flags |= GD_FLG_SPL_INIT;
+
+ return 0;
+}
+void board_init_r(gd_t *dummy1, ulong dummy2)
+{
+ u32 boot_device;
+
+ debug(">>spl:board_init_r()\n");
+
+#if defined(CONFIG_SYS_SPL_MALLOC_START)
+ mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START,
+ CONFIG_SYS_SPL_MALLOC_SIZE);
+ gd->flags |= GD_FLG_FULL_MALLOC_INIT;
+#endif
+ if (!(gd->flags & GD_FLG_SPL_INIT)) {
+ if (spl_init())
+ hang();
+ }
#ifndef CONFIG_PPC
/*
* timer_init() does not exist on PPC systems. The timer is initialized
gd->malloc_ptr / 1024);
#endif
+ debug("loaded - jumping to U-Boot...");
jump_to_image_no_args(&spl_image);
}
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
#include <spl.h>
#include <linux/compiler.h>
#include <asm/u-boot.h>
/* read image header to find the image size & load address */
count = mmc->block_dev.block_read(0, sector, 1, header);
+ debug("read sector %lx, count=%lu\n", sector, count);
if (count == 0)
goto end;
- if (image_get_magic(header) != IH_MAGIC)
+ if (image_get_magic(header) != IH_MAGIC) {
+ puts("bad magic\n");
return -1;
+ }
spl_parse_image_header(header);
/* Read the header too to avoid extra memcpy */
count = mmc->block_dev.block_read(0, sector, image_size_sectors,
- (void *) spl_image.load_addr);
+ (void *)spl_image.load_addr);
+ debug("read %x sectors to %x\n", image_size_sectors,
+ spl_image.load_addr);
end:
if (count == 0) {
return -1;
}
+#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
+ return mmc_load_image_raw_sector(mmc, info.start +
+ CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
+#else
return mmc_load_image_raw_sector(mmc, info.start);
+#endif
}
#endif
{
struct mmc *mmc;
u32 boot_mode;
- int err;
+ int err = 0;
__maybe_unused int part;
+#ifdef CONFIG_DM_MMC
+ struct udevice *dev;
+
+ mmc_initialize(NULL);
+ err = uclass_get_device(UCLASS_MMC, 0, &dev);
+ mmc = NULL;
+ if (!err)
+ mmc = mmc_get_mmc_dev(dev);
+#else
mmc_initialize(gd->bd);
/* We register only one device. So, the dev id is always 0 */
#endif
hang();
}
+#endif
+
+ if (!err)
+ err = mmc_init(mmc);
- err = mmc_init(mmc);
if (err) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
printf("spl: mmc init failed with error: %d\n", err);
}
#endif /* !CONFIG_DM_USB */
-#ifndef CONFIG_DM_USB
-int usb_legacy_port_reset(struct usb_device *hub, int portnr)
+static int usb_hub_port_reset(struct usb_device *dev, struct usb_device *hub)
{
if (hub) {
unsigned short portstatus;
int err;
/* reset the port for the second time */
- err = legacy_hub_port_reset(hub, portnr - 1, &portstatus);
+ err = legacy_hub_port_reset(hub, dev->portnr - 1, &portstatus);
if (err < 0) {
- printf("\n Couldn't reset port %i\n", portnr);
+ printf("\n Couldn't reset port %i\n", dev->portnr);
return err;
}
} else {
- usb_reset_root_port();
+ usb_reset_root_port(dev);
}
return 0;
}
-#endif
static int get_descriptor_len(struct usb_device *dev, int len, int expect_len)
{
}
static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
- struct usb_device *parent, int portnr)
+ struct usb_device *parent)
{
int err;
err = usb_setup_descriptor(dev, do_read);
if (err)
return err;
- err = usb_legacy_port_reset(parent, portnr);
+ err = usb_hub_port_reset(dev, parent);
if (err)
return err;
}
int usb_setup_device(struct usb_device *dev, bool do_read,
- struct usb_device *parent, int portnr)
+ struct usb_device *parent)
{
int addr;
int ret;
addr = dev->devnum;
dev->devnum = 0;
- ret = usb_prepare_device(dev, addr, do_read, parent, portnr);
+ ret = usb_prepare_device(dev, addr, do_read, parent);
if (ret)
return ret;
ret = usb_select_config(dev);
#ifdef CONFIG_USB_XHCI
do_read = false;
#endif
- err = usb_setup_device(dev, do_read, dev->parent, dev->portnr);
+ err = usb_setup_device(dev, do_read, dev->parent);
if (err)
return err;
{ } /* Terminating entry */
};
-USB_DEVICE(usb_generic_hub, hub_id_table);
+U_BOOT_USB_DEVICE(usb_generic_hub, hub_id_table);
#endif
debug("%s: Probing for keyboard\n", __func__);
#ifdef CONFIG_DM_USB
/*
- * TODO: We should add USB_DEVICE() declarations to each USB ethernet
- * driver and then most of this file can be removed.
+ * TODO: We should add U_BOOT_USB_DEVICE() declarations to each USB
+ * keyboard driver and then most of this file can be removed.
*/
struct udevice *bus;
struct uclass *uc;
{ } /* Terminating entry */
};
-USB_DEVICE(usb_mass_storage, mass_storage_id_table);
+U_BOOT_USB_DEVICE(usb_mass_storage, mass_storage_id_table);
#endif
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-olinuxino-lime"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPC(3)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-olinuxino-micro"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,SUNXI_EMAC,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,SUNXI_EMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino-micro"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun5i-a13-olinuxino"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=2,AXP209_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-lime2"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPC(3)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-lime"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPC(3)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-olinuxino-micro"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-auxtek-t004"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapi"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-bananapro"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31s-cs908"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3300
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_SUNXI=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_VIDEO_LCD_SPI_CS="PA0"
CONFIG_VIDEO_LCD_SPI_SCLK="PA1"
CONFIG_VIDEO_LCD_SPI_MOSI="PA2"
CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-colombus"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_ALDO1_VOLT=3300
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubieboard2"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-cubieboard"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPB(8)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-cubietruck"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3000
CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-hummingbird"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPA(21)"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPA(21)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_ALDO1_VOLT=3300
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_DRAM_ZQ=15291
CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH8"
CONFIG_AXP_GPIO=y
CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:51000,le:159,ri:160,up:22,lo:12,hs:1,vs:1,sync:3,vmode:0"
CONFIG_VIDEO_LCD_DCLK_PHASE=0
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3000
CONFIG_DRAM_ZQ=63306
CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH8"
CONFIG_AXP_GPIO=y
CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:167,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
CONFIG_VIDEO_LCD_DCLK_PHASE=0
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3000
CONFIG_DRAM_ZQ=63351
CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH8"
CONFIG_AXP_GPIO=y
CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
CONFIG_VIDEO_LCD_DCLK_PHASE=0
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3000
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3-nano"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(2)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-pcduino"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-mk808c"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_VIDEO_LCD_SSD2828_TX_CLK=27
CONFIG_VIDEO_LCD_SSD2828_RESET="PA26"
CONFIG_VIDEO_LCD_SPI_SCLK="PH10"
CONFIG_VIDEO_LCD_SPI_MOSI="PH11"
CONFIG_VIDEO_LCD_SPI_MISO="PH12"
-CONFIG_USB=y
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-marsboard"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_EMAC,AHCI"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-mele-a1000g-quad"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DCDC1_VOLT=3300
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_DLDO4_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3300
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_SUNXI=y
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-a1000"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-i7"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DCDC1_VOLT=3300
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_DLDO4_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3300
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-m3"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-m5"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,AHCI,USB_EHCI,STATUSLED=234"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,AHCI,STATUSLED=234"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-m9"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DCDC1_VOLT=3300
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_DLDO4_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3300
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-mini-xplus"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="PB9"
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-orangepi-mini"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
--- /dev/null
+CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,NAND,SECURE_BOOT,SYS_TEXT_BASE=0xFFF40000"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_P3041DS=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,NAND,SECURE_BOOT,SYS_TEXT_BASE=0xFFF40000"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_P5020DS=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SYS_EXTRA_OPTIONS="RAMBOOT_PBL,NAND,SECURE_BOOT,SYS_TEXT_BASE=0xFFF40000"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_P5040DS=y
+CONFIG_SPI_FLASH=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_ALDO1_VOLT=3000
-CONFIG_USB=y
-CONFIG_DM_USB=y
--- /dev/null
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1040,T1040D4RDB,RAMBOOT_PBL,SPL_FSL_PBL,NAND,T104XD4RDB,SYS_FSL_DDR4"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1040,T1040D4RDB,RAMBOOT_PBL,SPL_FSL_PBL,SDCARD,T104XD4RDB,SYS_FSL_DDR4"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1040,T1040D4RDB,T104XD4RDB,SYS_FSL_DDR4,SECURE_BOOT"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1040,T1040D4RDB,RAMBOOT_PBL,SPL_FSL_PBL,SPIFLASH,T104XD4RDB,SYS_FSL_DDR4"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1040,T1040D4RDB,T104XD4RDB,SYS_FSL_DDR4"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1042,T1042D4RDB,RAMBOOT_PBL,SPL_FSL_PBL,NAND,T104XD4RDB,SYS_FSL_DDR4"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1042,T1042D4RDB,RAMBOOT_PBL,SPL_FSL_PBL,SDCARD,T104XD4RDB,SYS_FSL_DDR4"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1042,T1042D4RDB,T104XD4RDB,SYS_FSL_DDR4,SECURE_BOOT"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SPL=y
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1042,T1042D4RDB,RAMBOOT_PBL,SPL_FSL_PBL,SPIFLASH,T104XD4RDB,SYS_FSL_DDR4"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
--- /dev/null
+CONFIG_SYS_EXTRA_OPTIONS="PPC_T1042,T1042D4RDB,T104XD4RDB,SYS_FSL_DDR4"
+CONFIG_PPC=y
+CONFIG_MPC85xx=y
+CONFIG_TARGET_T104XRDB=y
+CONFIG_SPI_FLASH=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
+# CONFIG_REQUIRE_SERIAL_CONSOLE is not set
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-wexler-tab7200"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-wits-pro-a20-dkt"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,RGMII,AHCI"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_AM3517_EVM=y
CONFIG_SPL=y
+CONFIG_FIT=y
# CONFIG_CMD_IMI is not set
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-ba10-tvbox"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="PB9"
CONFIG_VIDEO_VESA=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_DM_RTC=y
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_VSNPRINTF=y
CONFIG_VIDEO_VESA=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_DM_RTC=y
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_VSNPRINTF=y
CONFIG_CMD_BOOTSTAGE=y
CONFIG_OF_CONTROL=y
CONFIG_CPU=y
+CONFIG_DM_PCI=y
CONFIG_SPI_FLASH=y
CONFIG_VIDEO_VESA=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
+CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_TARGET_DB_88F6820_GP=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_DRAM_ODT_EN=y
CONFIG_USB0_VBUS_PIN="AXP0-VBUS-ENABLE"
CONFIG_USB0_VBUS_DET="AXP0-VBUS-DETECT"
+CONFIG_USB0_ID_DET="PH8"
CONFIG_AXP_GPIO=y
CONFIG_VIDEO_LCD_MODE="x:1024,y:600,depth:18,pclk_khz:52000,le:138,ri:162,up:22,lo:10,hs:20,vs:3,sync:3,vmode:0"
CONFIG_VIDEO_LCD_DCLK_PHASE=0
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_DLDO1_VOLT=3300
CONFIG_AXP221_ALDO1_VOLT=3000
+CONFIG_USB_EHCI_HCD=y
CONFIG_SPI_FLASH=y
CONFIG_NETDEVICES=y
CONFIG_ETH_DESIGNWARE=y
+CONFIG_DM_RTC=y
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_VSNPRINTF=y
CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-i12-tvbox"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-jesurun-q5"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,USB_EHCI,MACPWR=SUNXI_GPH(19)"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(19)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_ARM=y
CONFIG_TARGET_LS2085AQDS=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-ls2085a-qds"
+# CONFIG_SYS_MALLOC_F is not set
CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
# CONFIG_CMD_SETEXPR is not set
+CONFIG_OF_CONTROL=y
+CONFIG_DM=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_DM_SPI=y
+CONFIG_FSL_DSPI=y
CONFIG_ARM=y
CONFIG_TARGET_LS2085ARDB=y
+CONFIG_DEFAULT_DEVICE_TREE="fsl-ls2085a-rdb"
+# CONFIG_SYS_MALLOC_F is not set
CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
# CONFIG_CMD_SETEXPR is not set
+CONFIG_OF_CONTROL=y
+CONFIG_DM=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_DM_SPI=y
+CONFIG_FSL_DSPI=y
CONFIG_VIDEO_VESA=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_DM_RTC=y
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_VSNPRINTF=y
CONFIG_DEFAULT_DEVICE_TREE="sun6i-a31-mixtile-loftq"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="USB_EHCI,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPA(21)"
+CONFIG_SYS_EXTRA_OPTIONS="SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPA(21)"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
CONFIG_ETH_DESIGNWARE=y
-CONFIG_DM_SERIAL=y
CONFIG_AXP221_ALDO1_VOLT=3300
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-mk802"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-mk802ii"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
--- /dev/null
+CONFIG_ARM=y
+CONFIG_TEGRA=y
+CONFIG_TEGRA210=y
+CONFIG_TARGET_P2571=y
+CONFIG_DEFAULT_DEVICE_TREE="tegra210-p2571"
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_SETEXPR is not set
+# CONFIG_CMD_NFS is not set
+CONFIG_SPL_DM=y
+CONFIG_SPI_FLASH=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_PFC_MICRO_SUPPORT_CARD=y
CONFIG_SYS_TEXT_BASE=0x84000000
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-ld4-ref"
-CONFIG_FIT=y
-CONFIG_FIT_VERBOSE=y
CONFIG_HUSH_PARSER=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
CONFIG_PFC_MICRO_SUPPORT_CARD=y
CONFIG_SYS_TEXT_BASE=0x84000000
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-pro4-ref"
-CONFIG_FIT=y
-CONFIG_FIT_VERBOSE=y
CONFIG_HUSH_PARSER=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
--- /dev/null
+CONFIG_ARM=y
+CONFIG_ARCH_UNIPHIER=y
+CONFIG_MACH_PH1_SLD3=y
+CONFIG_PFC_MICRO_SUPPORT_CARD=y
+CONFIG_SYS_TEXT_BASE=0x84000000
+CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-sld3-ref"
+CONFIG_HUSH_PARSER=y
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_ENV_EXISTS is not set
+CONFIG_CMD_NAND=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_USB=y
+# CONFIG_CMD_FPGA is not set
+# CONFIG_CMD_SETEXPR is not set
+CONFIG_CMD_TFTPPUT=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_TIME=y
+# CONFIG_CMD_MISC is not set
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
+CONFIG_NAND_DENALI=y
+CONFIG_SYS_NAND_DENALI_64BIT=y
+CONFIG_NAND_DENALI_SPARE_AREA_SKIP_BYTES=8
+CONFIG_SPL_NAND_DENALI=y
+CONFIG_UNIPHIER_SERIAL=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_STORAGE=y
CONFIG_PFC_MICRO_SUPPORT_CARD=y
CONFIG_SYS_TEXT_BASE=0x84000000
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-sld8-ref"
-CONFIG_FIT=y
-CONFIG_FIT_VERBOSE=y
CONFIG_HUSH_PARSER=y
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_ENV_EXISTS is not set
CONFIG_X86=y
CONFIG_DEFAULT_DEVICE_TREE="qemu-x86_i440fx"
CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_CMD_CPU=y
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_SETEXPR is not set
CONFIG_BOOTSTAGE_REPORT=y
CONFIG_CMD_BOOTSTAGE=y
CONFIG_OF_CONTROL=y
+CONFIG_CPU=y
CONFIG_SPI_FLASH=y
CONFIG_VIDEO_VESA=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_111=y
+CONFIG_DM_RTC=y
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_VSNPRINTF=y
CONFIG_DEFAULT_DEVICE_TREE="sun5i-a10s-r7-tv-dongle"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP152_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_SPI_FLASH=y
CONFIG_SPI_FLASH_SANDBOX=y
CONFIG_CMD_CROS_EC=y
+CONFIG_CMD_DHRYSTONE=y
CONFIG_CROS_EC=y
CONFIG_CROS_EC_SANDBOX=y
CONFIG_DM_ETH=y
CONFIG_UT_TIME=y
CONFIG_UT_DM=y
CONFIG_UT_ENV=y
+CONFIG_CLK=y
+CONFIG_RESET=y
+CONFIG_RAM=y
+CONFIG_DM_MMC=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_SYSCON=y
CONFIG_DEFAULT_DEVICE_TREE="sun4i-a10-gemei-g9"
# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,USB_EHCI"
+CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER"
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
-CONFIG_DM_ETH=y
-CONFIG_DM_SERIAL=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
CONFIG_ARM=y
-CONFIG_TARGET_XILINX_ZYNQMP=y
-CONFIG_DEFAULT_DEVICE_TREE="zynqmp"
+CONFIG_ARCH_ZYNQMP=y
+CONFIG_DEFAULT_DEVICE_TREE="zynqmp-ep"
# CONFIG_CMD_CONSOLE is not set
# CONFIG_CMD_IMLS is not set
# CONFIG_CMD_XIMG is not set
# CONFIG_CMD_NFS is not set
CONFIG_CMD_TIME=y
CONFIG_CMD_TIMER=y
+CONFIG_SYS_TEXT_BASE=0x8000000
--- /dev/null
+CONFIG_ARM=y
+CONFIG_ARCH_ZYNQ=y
+CONFIG_TARGET_ZYNQ_ZC770=y
+CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm011"
+# CONFIG_SYS_MALLOC_F is not set
+CONFIG_SPL=y
+CONFIG_FIT=y
+CONFIG_FIT_VERBOSE=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM011"
+# CONFIG_CMD_IMLS is not set
+# CONFIG_CMD_FLASH is not set
+# CONFIG_CMD_SETEXPR is not set
The fastboot gadget relies on the USB download gadget, so the following
options must be configured:
-CONFIG_USBDOWNLOAD_GADGET
+CONFIG_USB_GADGET_DOWNLOAD
CONFIG_G_DNL_VENDOR_NUM
CONFIG_G_DNL_PRODUCT_NUM
CONFIG_G_DNL_MANUFACTURER
the fastboot client. The list of vendor IDs supported can be found in the
fastboot client source code (fastboot.c) mentioned above.
-The fastboot function is enabled by defining CONFIG_CMD_FASTBOOT and
-CONFIG_ANDROID_BOOT_IMAGE.
+The fastboot function is enabled by defining CONFIG_USB_FUNCTION_FASTBOOT,
+CONFIG_CMD_FASTBOOT and CONFIG_ANDROID_BOOT_IMAGE.
The fastboot protocol requires a large memory buffer for downloads. This
buffer should be as large as possible for a platform. The location of the
-buffer and size are set with CONFIG_USB_FASTBOOT_BUF_ADDR and
-CONFIG_USB_FASTBOOT_BUF_SIZE.
+buffer and size are set with CONFIG_FASTBOOT_BUF_ADDR and
+CONFIG_FASTBOOT_BUF_SIZE.
Fastboot partition aliases can also be defined for devices where GPT
limitations prevent user-friendly partition names such as "boot", "system"
Switch Settings
----------------
-SW1 OFF [0] OFF [1] OFF [1] OFF [0] OFF [1] OFF [0] OFF [1] OFF [1]
+SW1 OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0] OFF [0]
SW2 ON ON ON ON ON ON OFF OFF
SW3 OFF OFF OFF ON OFF OFF ON OFF
SW5 OFF OFF OFF OFF OFF OFF ON ON
Compile the source
------------------
-PH1-Pro4:
- $ make ph1_pro4_defconfig
+PH1-sLD3:
+ $ make ph1_sld3_defconfig
$ make CROSS_COMPILE=arm-linux-gnueabi-
PH1-LD4:
$ make ph1_ld4_defconfig
$ make CROSS_COMPILE=arm-linux-gnueabi-
+PH1-Pro4:
+ $ make ph1_pro4_defconfig
+ $ make CROSS_COMPILE=arm-linux-gnueabi-
+
PH1-sLD8:
$ make ph1_sld8_defconfig
$ make CROSS_COMPILE=arm-linux-gnueabi-
- Support card (SRAM, NOR flash, some peripherals)
+Micro Support Card
+------------------
+
+The recommended bit switch settings are as follows:
+
+ SW2 OFF(1)/ON(0) Description
+ ------------------------------------------
+ bit 1 <---- BKSZ[0]
+ bit 2 ----> BKSZ[1]
+ bit 3 <---- SoC Bus Width 16/32
+ bit 4 <---- SERIAL_SEL[0]
+ bit 5 ----> SERIAL_SEL[1]
+ bit 6 ----> BOOTSWAP_EN
+ bit 7 <---- CS1/CS5
+ bit 8 <---- SOC_SERIAL_DISABLE
+
+ SW8 OFF(1)/ON(0) Description
+ ------------------------------------------
+ bit 1 ----> CS1_SPLIT
+ bit 2 <---- CASE9_ON
+ bit 3 <---- CASE10_ON
+ bit 4 Don't Care Reserve
+ bit 5 Don't Care Reserve
+ bit 6 Don't Care Reserve
+ bit 7 ----> BURST_EN
+ bit 8 ----> FLASHBUS32_16
+
+The BKSZ[1:0] specifies the address range of memory slot and peripherals
+as follows:
+
+ BKSZ Description RAM slot Peripherals
+ --------------------------------------------------------------------
+ 0b00 15MB RAM / 1MB Peri 00000000-0effffff 0f000000-0fffffff
+ 0b01 31MB RAM / 1MB Peri 00000000-1effffff 1f000000-1fffffff
+ 0b10 64MB RAM / 1MB Peri 00000000-3effffff 3f000000-3fffffff
+ 0b11 127MB RAM / 1MB Peri 00000000-7effffff 7f000000-7fffffff
+
+Set BSKZ[1:0] to 0b01 for U-Boot.
+This mode is the most handy because EA[24] is always supported by the save pin
+mode of the system bus. On the other hand, EA[25] is not supported for some
+newer SoCs. Even if it is, EA[25] is not connected on most of the boards.
+
--
-Masahiro Yamada <yamada.m@jp.panasonic.com>
-Feb. 2015
+Masahiro Yamada <yamada.masahiro@socionext.com>
+Jul. 2015
--- /dev/null
+Common leds properties.
+
+Optional properties for child nodes:
+- label : The label for this LED. If omitted, the label is
+ taken from the node name (excluding the unit address).
+
+- linux,default-trigger : This parameter, if present, is a
+ string defining the trigger assigned to the LED. Current triggers are:
+ "backlight" - LED will act as a back-light, controlled by the framebuffer
+ system
+ "default-on" - LED will turn on (but for leds-gpio see "default-state"
+ property in Documentation/devicetree/bindings/gpio/led.txt)
+ "heartbeat" - LED "double" flashes at a load average based rate
+ "ide-disk" - LED indicates disk activity
+ "timer" - LED flashes at a fixed, configurable rate
+
+Examples:
+
+system-status {
+ label = "Status";
+ linux,default-trigger = "heartbeat";
+ ...
+};
--- /dev/null
+LEDs connected to GPIO lines
+
+Required properties:
+- compatible : should be "gpio-leds".
+
+Each LED is represented as a sub-node of the gpio-leds device. Each
+node's name represents the name of the corresponding LED.
+
+LED sub-node properties:
+- gpios : Should specify the LED's GPIO, see "gpios property" in
+ Documentation/devicetree/bindings/gpio/gpio.txt. Active low LEDs should be
+ indicated using flags in the GPIO specifier.
+- label : (optional)
+ see Documentation/devicetree/bindings/leds/common.txt
+- linux,default-trigger : (optional)
+ see Documentation/devicetree/bindings/leds/common.txt
+- default-state: (optional) The initial state of the LED. Valid
+ values are "on", "off", and "keep". If the LED is already on or off
+ and the default-state property is set the to same value, then no
+ glitch should be produced where the LED momentarily turns off (or
+ on). The "keep" setting will keep the LED at whatever its current
+ state is, without producing a glitch. The default is off if this
+ property is not present.
+
+Examples:
+
+leds {
+ compatible = "gpio-leds";
+ hdd {
+ label = "IDE Activity";
+ gpios = <&mcu_pio 0 1>; /* Active low */
+ linux,default-trigger = "ide-disk";
+ };
+
+ fault {
+ gpios = <&mcu_pio 1 0>;
+ /* Keep LED on if BIOS detected hardware fault */
+ default-state = "keep";
+ };
+};
+
+run-control {
+ compatible = "gpio-leds";
+ red {
+ gpios = <&mpc8572 6 0>;
+ default-state = "off";
+ };
+ green {
+ gpios = <&mpc8572 7 0>;
+ default-state = "on";
+ };
+};
-Zynq SPI controller Device Tree Bindings
-----------------------------------------
+Cadence SPI controller Device Tree Bindings
+-------------------------------------------
Required properties:
-- compatible : Should be "xlnx,spi-zynq".
+- compatible : Should be "cdns,spi-r1p6" or "xlnx,zynq-spi-r1p6".
- reg : Physical base address and size of SPI registers map.
-- status : Status will be disabled in dtsi and enabled in required dts.
-- interrupt-parent : Must be core interrupt controller.
- interrupts : Property with a value describing the interrupt
number.
-- clocks : Clock phandles (see clock bindings for details).
+- interrupt-parent : Must be core interrupt controller
- clock-names : List of input clock names - "ref_clk", "pclk"
(See clock bindings for details).
+- clocks : Clock phandles (see clock bindings for details).
- spi-max-frequency : Maximum SPI clocking speed of device in Hz
+Optional properties:
+- num-cs : Number of chip selects used.
+ If a decoder is used, this will be the number of
+ chip selects after the decoder.
+- is-decoded-cs : Flag to indicate whether decoder is used or not.
+
Example:
- spi@e0006000 {
- compatible = "xlnx,zynq-spi";
- reg = <0xe0006000 0x1000>;
- status = "disabled";
- interrupt-parent = <&intc>;
- interrupts = <0 26 4>;
- clocks = <&clkc 25>, <&clkc 34>;
+ spi@e0007000 {
+ compatible = "xlnx,zynq-spi-r1p6";
clock-names = "ref_clk", "pclk";
- spi-max-frequency = <166666700>;
- #address-cells = <1>;
- #size-cells = <0>;
+ clocks = <&clkc 26>, <&clkc 35>;
+ interrupt-parent = <&intc>;
+ interrupts = <0 49 4>;
+ num-cs = <4>;
+ is-decoded-cs = <0>;
+ reg = <0xe0007000 0x1000>;
} ;
Platform Data
-------------
+*** Note: platform data is the old way of doing things. It is
+*** basically a C structure which is passed to drivers to tell them about
+*** platform-specific settings like the address of its registers, bus
+*** speed, etc. Device tree is now the preferred way of handling this.
+*** Unless you have a good reason not to use device tree (the main one
+*** being you need serial support in SPL and don't have enough SRAM for
+*** the cut-down device tree and libfdt libraries) you should stay away
+*** from platform data.
+
Platform data is like Linux platform data, if you are familiar with that.
It provides the board-specific information to start up a device.
-----------
While platdata is useful, a more flexible way of providing device data is
-by using device tree. With device tree we replace the above code with the
-following device tree fragment:
+by using device tree. In U-Boot you should use this where possible. Avoid
+sending patches which make use of the U_BOOT_DEVICE() macro unless strictly
+necessary.
+
+With device tree we replace the above code with the following device tree
+fragment:
red-square {
compatible = "demo-shape";
menu "Device Drivers"
+source "drivers/clk/Kconfig"
+
source "drivers/core/Kconfig"
source "drivers/cpu/Kconfig"
source "drivers/input/Kconfig"
+source "drivers/led/Kconfig"
+
source "drivers/serial/Kconfig"
source "drivers/tpm/Kconfig"
source "drivers/power/Kconfig"
+source "drivers/ram/Kconfig"
+
source "drivers/hwmon/Kconfig"
source "drivers/watchdog/Kconfig"
+obj-$(CONFIG_CLK) += clk/
obj-$(CONFIG_DM) += core/
obj-$(CONFIG_DM_DEMO) += demo/
obj-$(CONFIG_BIOSEMU) += bios_emulator/
obj-y += crypto/
obj-$(CONFIG_FPGA) += fpga/
obj-y += hwmon/
+obj-$(CONFIG_LED) += led/
obj-y += misc/
obj-y += pcmcia/
obj-y += dfu/
+obj-$(CONFIG_RAM) += ram/
obj-y += rtc/
obj-y += sound/
obj-y += tpm/
#include <asm/arch/orion5x.h>
#elif defined(CONFIG_KIRKWOOD)
#include <asm/arch/soc.h>
+#elif defined(CONFIG_ARMADA_XP)
+#include <linux/mbus.h>
#endif
/* SATA port registers */
#define MVSATA_STATUS_OK 0
#define MVSATA_STATUS_TIMEOUT -1
+/*
+ * Registers for SATA MBUS memory windows
+ */
+
+#define MVSATA_WIN_CONTROL(w) (MVEBU_AXP_SATA_BASE + 0x30 + ((w) << 4))
+#define MVSATA_WIN_BASE(w) (MVEBU_AXP_SATA_BASE + 0x34 + ((w) << 4))
+
+/*
+ * Initialize SATA memory windows for Armada XP
+ */
+
+#ifdef CONFIG_ARMADA_XP
+static void mvsata_ide_conf_mbus_windows(void)
+{
+ const struct mbus_dram_target_info *dram;
+ int i;
+
+ dram = mvebu_mbus_dram_info();
+
+ /* Disable windows, Set Size/Base to 0 */
+ for (i = 0; i < 4; i++) {
+ writel(0, MVSATA_WIN_CONTROL(i));
+ writel(0, MVSATA_WIN_BASE(i));
+ }
+
+ for (i = 0; i < dram->num_cs; i++) {
+ const struct mbus_dram_window *cs = dram->cs + i;
+ writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+ MVSATA_WIN_CONTROL(i));
+ writel(cs->base & 0xffff0000, MVSATA_WIN_BASE(i));
+ }
+}
+#endif
+
/*
* Initialize one MVSATAHC port: set SControl's IPM to "always active"
* and DET to "reset", then wait for SStatus's DET to become "device and
int ret = MVSATA_STATUS_TIMEOUT;
int status;
+#ifdef CONFIG_ARMADA_XP
+ mvsata_ide_conf_mbus_windows();
+#endif
+
/* Enable ATA port 0 (could be SATA port 0 or 1) if declared */
#if defined(CONFIG_SYS_ATA_IDE0_OFFSET)
status = mvsata_ide_initialize_port(
--- /dev/null
+config CLK
+ bool "Enable clock driver support"
+ depends on DM
+ help
+ This allows drivers to be provided for clock generators, including
+ oscillators and PLLs. Devices can use a common clock API to request
+ a particular clock rate and check on available clocks. Clocks can
+ feed into other clocks in a tree structure, with multiplexers to
+ choose the source for each clock.
+
+config SPL_CLK_SUPPORT
+ bool "Enable clock support in SPL"
+ depends on CLK
+ help
+ The clock subsystem adds a small amount of overhead to the image.
+ If this is acceptable and you have a need to use clock drivers in
+ SPL, enable this option. It might provide a cleaner interface to
+ setting up clocks within SPL, and allows the same drivers to be
+ used as U-Boot proper.
--- /dev/null
+#
+# Copyright (c) 2015 Google, Inc
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_CLK) += clk-uclass.o
+obj-$(CONFIG_SANDBOX) += clk_sandbox.o
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+ulong clk_get_rate(struct udevice *dev)
+{
+ struct clk_ops *ops = clk_get_ops(dev);
+
+ if (!ops->get_rate)
+ return -ENOSYS;
+
+ return ops->get_rate(dev);
+}
+
+ulong clk_set_rate(struct udevice *dev, ulong rate)
+{
+ struct clk_ops *ops = clk_get_ops(dev);
+
+ if (!ops->set_rate)
+ return -ENOSYS;
+
+ return ops->set_rate(dev, rate);
+}
+
+ulong clk_get_periph_rate(struct udevice *dev, int periph)
+{
+ struct clk_ops *ops = clk_get_ops(dev);
+
+ if (!ops->get_periph_rate)
+ return -ENOSYS;
+
+ return ops->get_periph_rate(dev, periph);
+}
+
+ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate)
+{
+ struct clk_ops *ops = clk_get_ops(dev);
+
+ if (!ops->set_periph_rate)
+ return -ENOSYS;
+
+ return ops->set_periph_rate(dev, periph, rate);
+}
+
+UCLASS_DRIVER(clk) = {
+ .id = UCLASS_CLK,
+ .name = "clk",
+};
--- /dev/null
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/test.h>
+
+struct sandbox_clk_priv {
+ ulong rate;
+ ulong periph_rate[PERIPH_ID_COUNT];
+};
+
+static ulong sandbox_clk_get_rate(struct udevice *dev)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(dev);
+
+ return priv->rate;
+}
+
+static ulong sandbox_clk_set_rate(struct udevice *dev, ulong rate)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(dev);
+
+ if (!rate)
+ return -EINVAL;
+ priv->rate = rate;
+ return 0;
+}
+
+ulong sandbox_get_periph_rate(struct udevice *dev, int periph)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(dev);
+
+ if (periph < PERIPH_ID_FIRST || periph >= PERIPH_ID_COUNT)
+ return -EINVAL;
+ return priv->periph_rate[periph];
+}
+
+ulong sandbox_set_periph_rate(struct udevice *dev, int periph, ulong rate)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(dev);
+ ulong old_rate;
+
+ if (periph < PERIPH_ID_FIRST || periph >= PERIPH_ID_COUNT)
+ return -EINVAL;
+ old_rate = priv->periph_rate[periph];
+ priv->periph_rate[periph] = rate;
+
+ return old_rate;
+}
+
+static int sandbox_clk_probe(struct udevice *dev)
+{
+ struct sandbox_clk_priv *priv = dev_get_priv(dev);
+
+ priv->rate = SANDBOX_CLK_RATE;
+
+ return 0;
+}
+
+static struct clk_ops sandbox_clk_ops = {
+ .get_rate = sandbox_clk_get_rate,
+ .set_rate = sandbox_clk_set_rate,
+ .get_periph_rate = sandbox_get_periph_rate,
+ .set_periph_rate = sandbox_set_periph_rate,
+};
+
+static const struct udevice_id sandbox_clk_ids[] = {
+ { .compatible = "sandbox,clk" },
+ { }
+};
+
+U_BOOT_DRIVER(clk_sandbox) = {
+ .name = "clk_sandbox",
+ .id = UCLASS_CLK,
+ .of_match = sandbox_clk_ids,
+ .ops = &sandbox_clk_ops,
+ .priv_auto_alloc_size = sizeof(struct sandbox_clk_priv),
+ .probe = sandbox_clk_probe,
+};
device. This is not normally required in SPL, so by default this
option is disabled for SPL.
+ Note that this may have undesirable results in the USB subsystem as
+ it causes unplugged devices to linger around in the dm-tree, and it
+ causes USB host controllers to not be stopped when booting the OS.
+
config DM_STDIO
bool "Support stdio registration"
depends on DM
# SPDX-License-Identifier: GPL-2.0+
#
-obj-$(CONFIG_DM) += device.o lists.o root.o uclass.o util.o
+obj-y += device.o lists.o root.o uclass.o util.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_OF_CONTROL) += simple-bus.o
endif
obj-$(CONFIG_DM_DEVICE_REMOVE) += device-remove.o
+obj-$(CONFIG_DM) += dump.o
+obj-$(CONFIG_OF_CONTROL) += regmap.o
+obj-$(CONFIG_OF_CONTROL) += syscon-uclass.o
#include <dm/uclass-internal.h>
#include <dm/util.h>
-/**
- * device_chld_unbind() - Unbind all device's children from the device
- *
- * On error, the function continues to unbind all children, and reports the
- * first error.
- *
- * @dev: The device that is to be stripped of its children
- * @return 0 on success, -ve on error
- */
-static int device_chld_unbind(struct udevice *dev)
+int device_unbind_children(struct udevice *dev)
{
struct udevice *pos, *n;
int ret, saved_ret = 0;
return saved_ret;
}
-/**
- * device_chld_remove() - Stop all device's children
- * @dev: The device whose children are to be removed
- * @return 0 on success, -ve on error
- */
-static int device_chld_remove(struct udevice *dev)
+int device_remove_children(struct udevice *dev)
{
struct udevice *pos, *n;
int ret;
return ret;
}
- ret = device_chld_unbind(dev);
+ ret = device_unbind_children(dev);
if (ret)
return ret;
if (ret)
return ret;
- ret = device_chld_remove(dev);
+ ret = device_remove_children(dev);
if (ret)
goto err;
goto fail;
}
- dev->flags |= DM_FLAG_ACTIVATED;
if (drv->probe) {
ret = drv->probe(dev);
if (ret) {
void *dev_get_parent_platdata(struct udevice *dev)
{
if (!dev) {
- dm_warn("%s: null device", __func__);
+ dm_warn("%s: null device\n", __func__);
return NULL;
}
void *dev_get_uclass_platdata(struct udevice *dev)
{
if (!dev) {
- dm_warn("%s: null device", __func__);
+ dm_warn("%s: null device\n", __func__);
return NULL;
}
return -ENODEV;
}
-int device_get_child_by_of_offset(struct udevice *parent, int seq,
+int device_get_child_by_of_offset(struct udevice *parent, int node,
struct udevice **devp)
{
struct udevice *dev;
int ret;
*devp = NULL;
- ret = device_find_child_by_of_offset(parent, seq, &dev);
+ ret = device_find_child_by_of_offset(parent, node, &dev);
return device_get_device_tail(dev, ret, devp);
}
+static struct udevice *_device_find_global_by_of_offset(struct udevice *parent,
+ int of_offset)
+{
+ struct udevice *dev, *found;
+
+ if (parent->of_offset == of_offset)
+ return parent;
+
+ list_for_each_entry(dev, &parent->child_head, sibling_node) {
+ found = _device_find_global_by_of_offset(dev, of_offset);
+ if (found)
+ return found;
+ }
+
+ return NULL;
+}
+
+int device_get_global_by_of_offset(int of_offset, struct udevice **devp)
+{
+ struct udevice *dev;
+
+ dev = _device_find_global_by_of_offset(gd->dm_root, of_offset);
+ return device_get_device_tail(dev, dev ? 0 : -ENOENT, devp);
+}
+
int device_find_first_child(struct udevice *parent, struct udevice **devp)
{
if (list_empty(&parent->child_head)) {
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <dm/root.h>
+
+static void show_devices(struct udevice *dev, int depth, int last_flag)
+{
+ int i, is_last;
+ struct udevice *child;
+ char class_name[12];
+
+ /* print the first 11 characters to not break the tree-format. */
+ strlcpy(class_name, dev->uclass->uc_drv->name, sizeof(class_name));
+ printf(" %-11s [ %c ] ", class_name,
+ dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ');
+
+ for (i = depth; i >= 0; i--) {
+ is_last = (last_flag >> i) & 1;
+ if (i) {
+ if (is_last)
+ printf(" ");
+ else
+ printf("| ");
+ } else {
+ if (is_last)
+ printf("`-- ");
+ else
+ printf("|-- ");
+ }
+ }
+
+ printf("%s\n", dev->name);
+
+ list_for_each_entry(child, &dev->child_head, sibling_node) {
+ is_last = list_is_last(&child->sibling_node, &dev->child_head);
+ show_devices(child, depth + 1, (last_flag << 1) | is_last);
+ }
+}
+
+void dm_dump_all(void)
+{
+ struct udevice *root;
+
+ root = dm_root();
+ if (root) {
+ printf(" Class Probed Name\n");
+ printf("----------------------------------------\n");
+ show_devices(root, -1, 0);
+ }
+}
+
+/**
+ * dm_display_line() - Display information about a single device
+ *
+ * Displays a single line of information with an option prefix
+ *
+ * @dev: Device to display
+ */
+static void dm_display_line(struct udevice *dev)
+{
+ printf("- %c %s @ %08lx",
+ dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
+ dev->name, (ulong)map_to_sysmem(dev));
+ if (dev->seq != -1 || dev->req_seq != -1)
+ printf(", seq %d, (req %d)", dev->seq, dev->req_seq);
+ puts("\n");
+}
+
+void dm_dump_uclass(void)
+{
+ struct uclass *uc;
+ int ret;
+ int id;
+
+ for (id = 0; id < UCLASS_COUNT; id++) {
+ struct udevice *dev;
+
+ ret = uclass_get(id, &uc);
+ if (ret)
+ continue;
+
+ printf("uclass %d: %s\n", id, uc->uc_drv->name);
+ if (list_empty(&uc->dev_head))
+ continue;
+ list_for_each_entry(dev, &uc->dev_head, uclass_node) {
+ dm_display_line(dev);
+ }
+ puts("\n");
+ }
+}
drv = lists_driver_lookup_name(drv_name);
if (!drv) {
- printf("Cannot find driver '%s'\n", drv_name);
+ debug("Cannot find driver '%s'\n", drv_name);
return -ENOENT;
}
ret = device_bind(parent, drv, dev_name, NULL, node, devp);
if (ret) {
- printf("Cannot create device named '%s' (err=%d)\n",
- dev_name, ret);
+ debug("Cannot create device named '%s' (err=%d)\n",
+ dev_name, ret);
return ret;
}
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <libfdt.h>
+#include <malloc.h>
+#include <mapmem.h>
+#include <regmap.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int regmap_init_mem(struct udevice *dev, struct regmap **mapp)
+{
+ const void *blob = gd->fdt_blob;
+ struct regmap_range *range;
+ const fdt32_t *cell;
+ struct regmap *map;
+ int count;
+ int addr_len, size_len, both_len;
+ int parent;
+ int len;
+
+ parent = dev->parent->of_offset;
+ addr_len = fdt_address_cells(blob, parent);
+ size_len = fdt_size_cells(blob, parent);
+ both_len = addr_len + size_len;
+
+ cell = fdt_getprop(blob, dev->of_offset, "reg", &len);
+ len /= sizeof(*cell);
+ count = len / both_len;
+ if (!cell || !count)
+ return -EINVAL;
+
+ map = malloc(sizeof(struct regmap));
+ if (!map)
+ return -ENOMEM;
+
+ if (count <= 1) {
+ map->range = &map->base_range;
+ } else {
+ map->range = malloc(count * sizeof(struct regmap_range));
+ if (!map->range) {
+ free(map);
+ return -ENOMEM;
+ }
+ }
+
+ map->base = fdtdec_get_number(cell, addr_len);
+ map->range_count = count;
+
+ for (range = map->range; count > 0;
+ count--, cell += both_len, range++) {
+ range->start = fdtdec_get_number(cell, addr_len);
+ range->size = fdtdec_get_number(cell + addr_len, size_len);
+ }
+
+ *mapp = map;
+
+ return 0;
+}
+
+void *regmap_get_range(struct regmap *map, unsigned int range_num)
+{
+ struct regmap_range *range;
+
+ if (range_num >= map->range_count)
+ return NULL;
+ range = &map->range[range_num];
+
+ return map_sysmem(range->start, range->size);
+}
+
+int regmap_uninit(struct regmap *map)
+{
+ if (map->range_count > 1)
+ free(map->range);
+ free(map);
+
+ return 0;
+}
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <syscon.h>
+#include <dm.h>
+#include <errno.h>
+#include <regmap.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <linux/err.h>
+
+struct regmap *syscon_get_regmap(struct udevice *dev)
+{
+ struct syscon_uc_info *priv;
+
+ if (device_get_uclass_id(dev) != UCLASS_SYSCON)
+ return ERR_PTR(-ENOEXEC);
+ priv = dev_get_uclass_priv(dev);
+ return priv->regmap;
+}
+
+static int syscon_pre_probe(struct udevice *dev)
+{
+ struct syscon_uc_info *priv = dev_get_uclass_priv(dev);
+
+ return regmap_init_mem(dev, &priv->regmap);
+}
+
+struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_SYSCON, &uc);
+ if (ret)
+ return ERR_PTR(ret);
+ uclass_foreach_dev(dev, uc) {
+ if (dev->driver_data == driver_data) {
+ struct syscon_uc_info *priv;
+ int ret;
+
+ ret = device_probe(dev);
+ if (ret)
+ return ERR_PTR(ret);
+ priv = dev_get_uclass_priv(dev);
+
+ return priv->regmap;
+ }
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+
+void *syscon_get_first_range(ulong driver_data)
+{
+ struct regmap *map;
+
+ map = syscon_get_regmap_by_driver_data(driver_data);
+ if (IS_ERR(map))
+ return map;
+ return regmap_get_range(map, 0);
+}
+
+UCLASS_DRIVER(syscon) = {
+ .id = UCLASS_SYSCON,
+ .name = "syscon",
+ .per_device_auto_alloc_size = sizeof(struct syscon_uc_info),
+ .pre_probe = syscon_pre_probe,
+};
*ucp = NULL;
uc_drv = lists_uclass_lookup(id);
if (!uc_drv) {
- dm_warn("Cannot find uclass for id %d: please add the UCLASS_DRIVER() declaration for this UCLASS_... id\n",
- id);
+ debug("Cannot find uclass for id %d: please add the UCLASS_DRIVER() declaration for this UCLASS_... id\n",
+ id);
return -ENOENT;
}
uc = calloc(1, sizeof(*uc));
__attribute__((weak, alias("__get_spd")))
void get_spd(generic_spd_eeprom_t *spd, u8 i2c_address);
+/* This function allows boards to update SPD address */
+__weak void update_spd_address(unsigned int ctrl_num,
+ unsigned int slot,
+ unsigned int *addr)
+{
+}
+
void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
unsigned int ctrl_num, unsigned int dimm_slots_per_ctrl)
{
for (i = 0; i < dimm_slots_per_ctrl; i++) {
i2c_address = spd_i2c_addr[ctrl_num][i];
+ update_spd_address(ctrl_num, i, &i2c_address);
get_spd(&(ctrl_dimms_spd[i]), i2c_address);
}
}
--- /dev/null
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_SPL_BUILD) += ddr3_a38x.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_a38x_training.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_debug.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_hws_hw_training.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_init.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training_bist.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training_centralization.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training_db.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training_hw_algo.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training_ip_engine.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training_leveling.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training_pbs.o
+obj-$(CONFIG_SPL_BUILD) += ddr3_training_static.o
+obj-$(CONFIG_SPL_BUILD) += xor.o
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#define A38X_NUMBER_OF_INTERFACES 5
+
+#define SAR_DEV_ID_OFFS 27
+#define SAR_DEV_ID_MASK 0x7
+
+/* Termal Sensor Registers */
+#define TSEN_STATE_REG 0xe4070
+#define TSEN_STATE_OFFSET 31
+#define TSEN_STATE_MASK (0x1 << TSEN_STATE_OFFSET)
+#define TSEN_CONF_REG 0xe4074
+#define TSEN_CONF_RST_OFFSET 8
+#define TSEN_CONF_RST_MASK (0x1 << TSEN_CONF_RST_OFFSET)
+#define TSEN_STATUS_REG 0xe4078
+#define TSEN_STATUS_READOUT_VALID_OFFSET 10
+#define TSEN_STATUS_READOUT_VALID_MASK (0x1 << \
+ TSEN_STATUS_READOUT_VALID_OFFSET)
+#define TSEN_STATUS_TEMP_OUT_OFFSET 0
+#define TSEN_STATUS_TEMP_OUT_MASK (0x3ff << TSEN_STATUS_TEMP_OUT_OFFSET)
+
+static struct dfx_access interface_map[] = {
+ /* Pipe Client */
+ { 0, 17 },
+ { 1, 7 },
+ { 1, 11 },
+ { 0, 3 },
+ { 1, 25 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 }
+};
+
+/* This array hold the board round trip delay (DQ and CK) per <interface,bus> */
+struct trip_delay_element a38x_board_round_trip_delay_array[] = {
+ /* 1st board */
+ /* Interface bus DQS-delay CK-delay */
+ { 3952, 5060 },
+ { 3192, 4493 },
+ { 4785, 6677 },
+ { 3413, 7267 },
+ { 4282, 6086 }, /* ECC PUP */
+ { 3952, 5134 },
+ { 3192, 4567 },
+ { 4785, 6751 },
+ { 3413, 7341 },
+ { 4282, 6160 }, /* ECC PUP */
+
+ /* 2nd board */
+ /* Interface bus DQS-delay CK-delay */
+ { 3952, 5060 },
+ { 3192, 4493 },
+ { 4785, 6677 },
+ { 3413, 7267 },
+ { 4282, 6086 }, /* ECC PUP */
+ { 3952, 5134 },
+ { 3192, 4567 },
+ { 4785, 6751 },
+ { 3413, 7341 },
+ { 4282, 6160 } /* ECC PUP */
+};
+
+#ifdef STATIC_ALGO_SUPPORT
+/* package trace */
+static struct trip_delay_element a38x_package_round_trip_delay_array[] = {
+ /* IF BUS DQ_DELAY CK_DELAY */
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 }
+};
+
+static int a38x_silicon_delay_offset[] = {
+ /* board 0 */
+ 0,
+ /* board 1 */
+ 0,
+ /* board 2 */
+ 0
+};
+#endif
+
+static u8 a38x_bw_per_freq[DDR_FREQ_LIMIT] = {
+ 0x3, /* DDR_FREQ_100 */
+ 0x4, /* DDR_FREQ_400 */
+ 0x4, /* DDR_FREQ_533 */
+ 0x5, /* DDR_FREQ_667 */
+ 0x5, /* DDR_FREQ_800 */
+ 0x5, /* DDR_FREQ_933 */
+ 0x5, /* DDR_FREQ_1066 */
+ 0x3, /* DDR_FREQ_311 */
+ 0x3, /* DDR_FREQ_333 */
+ 0x4, /* DDR_FREQ_467 */
+ 0x5, /* DDR_FREQ_850 */
+ 0x5, /* DDR_FREQ_600 */
+ 0x3, /* DDR_FREQ_300 */
+ 0x5, /* DDR_FREQ_900 */
+ 0x3, /* DDR_FREQ_360 */
+ 0x5 /* DDR_FREQ_1000 */
+};
+
+static u8 a38x_rate_per_freq[DDR_FREQ_LIMIT] = {
+ /*TBD*/ 0x1, /* DDR_FREQ_100 */
+ 0x2, /* DDR_FREQ_400 */
+ 0x2, /* DDR_FREQ_533 */
+ 0x2, /* DDR_FREQ_667 */
+ 0x2, /* DDR_FREQ_800 */
+ 0x3, /* DDR_FREQ_933 */
+ 0x3, /* DDR_FREQ_1066 */
+ 0x1, /* DDR_FREQ_311 */
+ 0x1, /* DDR_FREQ_333 */
+ 0x2, /* DDR_FREQ_467 */
+ 0x2, /* DDR_FREQ_850 */
+ 0x2, /* DDR_FREQ_600 */
+ 0x1, /* DDR_FREQ_300 */
+ 0x2, /* DDR_FREQ_900 */
+ 0x1, /* DDR_FREQ_360 */
+ 0x2 /* DDR_FREQ_1000 */
+};
+
+static u16 a38x_vco_freq_per_sar[] = {
+ 666, /* 0 */
+ 1332,
+ 800,
+ 1600,
+ 1066,
+ 2132,
+ 1200,
+ 2400,
+ 1332,
+ 1332,
+ 1500,
+ 1500,
+ 1600, /* 12 */
+ 1600,
+ 1700,
+ 1700,
+ 1866,
+ 1866,
+ 1800, /* 18 */
+ 2000,
+ 2000,
+ 4000,
+ 2132,
+ 2132,
+ 2300,
+ 2300,
+ 2400,
+ 2400,
+ 2500,
+ 2500,
+ 800
+};
+
+u32 pipe_multicast_mask;
+
+u32 dq_bit_map_2_phy_pin[] = {
+ 1, 0, 2, 6, 9, 8, 3, 7, /* 0 */
+ 8, 9, 1, 7, 2, 6, 3, 0, /* 1 */
+ 3, 9, 7, 8, 1, 0, 2, 6, /* 2 */
+ 1, 0, 6, 2, 8, 3, 7, 9, /* 3 */
+ 0, 1, 2, 9, 7, 8, 3, 6, /* 4 */
+};
+
+static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
+ enum hws_ddr_freq freq);
+
+/*
+ * Read temperature TJ value
+ */
+u32 ddr3_ctrl_get_junc_temp(u8 dev_num)
+{
+ int reg = 0;
+
+ /* Initiates TSEN hardware reset once */
+ if ((reg_read(TSEN_CONF_REG) & TSEN_CONF_RST_MASK) == 0)
+ reg_bit_set(TSEN_CONF_REG, TSEN_CONF_RST_MASK);
+ mdelay(10);
+
+ /* Check if the readout field is valid */
+ if ((reg_read(TSEN_STATUS_REG) & TSEN_STATUS_READOUT_VALID_MASK) == 0) {
+ printf("%s: TSEN not ready\n", __func__);
+ return 0;
+ }
+
+ reg = reg_read(TSEN_STATUS_REG);
+ reg = (reg & TSEN_STATUS_TEMP_OUT_MASK) >> TSEN_STATUS_TEMP_OUT_OFFSET;
+
+ return ((((10000 * reg) / 21445) * 1000) - 272674) / 1000;
+}
+
+/*
+ * Name: ddr3_tip_a38x_get_freq_config.
+ * Desc:
+ * Args:
+ * Notes:
+ * Returns: MV_OK if success, other error code if fail.
+ */
+int ddr3_tip_a38x_get_freq_config(u8 dev_num, enum hws_ddr_freq freq,
+ struct hws_tip_freq_config_info
+ *freq_config_info)
+{
+ if (a38x_bw_per_freq[freq] == 0xff)
+ return MV_NOT_SUPPORTED;
+
+ if (freq_config_info == NULL)
+ return MV_BAD_PARAM;
+
+ freq_config_info->bw_per_freq = a38x_bw_per_freq[freq];
+ freq_config_info->rate_per_freq = a38x_rate_per_freq[freq];
+ freq_config_info->is_supported = 1;
+
+ return MV_OK;
+}
+
+/*
+ * Name: ddr3_tip_a38x_pipe_enable.
+ * Desc:
+ * Args:
+ * Notes:
+ * Returns: MV_OK if success, other error code if fail.
+ */
+int ddr3_tip_a38x_pipe_enable(u8 dev_num, enum hws_access_type interface_access,
+ u32 if_id, int enable)
+{
+ u32 data_value, pipe_enable_mask = 0;
+
+ if (enable == 0) {
+ pipe_enable_mask = 0;
+ } else {
+ if (interface_access == ACCESS_TYPE_MULTICAST)
+ pipe_enable_mask = pipe_multicast_mask;
+ else
+ pipe_enable_mask = (1 << interface_map[if_id].pipe);
+ }
+
+ CHECK_STATUS(ddr3_tip_reg_read
+ (dev_num, PIPE_ENABLE_ADDR, &data_value, MASK_ALL_BITS));
+ data_value = (data_value & (~0xff)) | pipe_enable_mask;
+ CHECK_STATUS(ddr3_tip_reg_write(dev_num, PIPE_ENABLE_ADDR, data_value));
+
+ return MV_OK;
+}
+
+/*
+ * Name: ddr3_tip_a38x_if_write.
+ * Desc:
+ * Args:
+ * Notes:
+ * Returns: MV_OK if success, other error code if fail.
+ */
+int ddr3_tip_a38x_if_write(u8 dev_num, enum hws_access_type interface_access,
+ u32 if_id, u32 reg_addr, u32 data_value,
+ u32 mask)
+{
+ u32 ui_data_read;
+
+ if (mask != MASK_ALL_BITS) {
+ CHECK_STATUS(ddr3_tip_a38x_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, reg_addr,
+ &ui_data_read, MASK_ALL_BITS));
+ data_value = (ui_data_read & (~mask)) | (data_value & mask);
+ }
+
+ reg_write(reg_addr, data_value);
+
+ return MV_OK;
+}
+
+/*
+ * Name: ddr3_tip_a38x_if_read.
+ * Desc:
+ * Args:
+ * Notes:
+ * Returns: MV_OK if success, other error code if fail.
+ */
+int ddr3_tip_a38x_if_read(u8 dev_num, enum hws_access_type interface_access,
+ u32 if_id, u32 reg_addr, u32 *data, u32 mask)
+{
+ *data = reg_read(reg_addr) & mask;
+
+ return MV_OK;
+}
+
+/*
+ * Name: ddr3_tip_a38x_select_ddr_controller.
+ * Desc: Enable/Disable access to Marvell's server.
+ * Args: dev_num - device number
+ * enable - whether to enable or disable the server
+ * Notes:
+ * Returns: MV_OK if success, other error code if fail.
+ */
+int ddr3_tip_a38x_select_ddr_controller(u8 dev_num, int enable)
+{
+ u32 reg;
+
+ reg = reg_read(CS_ENABLE_REG);
+
+ if (enable)
+ reg |= (1 << 6);
+ else
+ reg &= ~(1 << 6);
+
+ reg_write(CS_ENABLE_REG, reg);
+
+ return MV_OK;
+}
+
+/*
+ * Name: ddr3_tip_init_a38x_silicon.
+ * Desc: init Training SW DB.
+ * Args:
+ * Notes:
+ * Returns: MV_OK if success, other error code if fail.
+ */
+static int ddr3_tip_init_a38x_silicon(u32 dev_num, u32 board_id)
+{
+ struct hws_tip_config_func_db config_func;
+ enum hws_ddr_freq ddr_freq;
+ int status;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* new read leveling version */
+ config_func.tip_dunit_read_func = ddr3_tip_a38x_if_read;
+ config_func.tip_dunit_write_func = ddr3_tip_a38x_if_write;
+ config_func.tip_dunit_mux_select_func =
+ ddr3_tip_a38x_select_ddr_controller;
+ config_func.tip_get_freq_config_info_func =
+ ddr3_tip_a38x_get_freq_config;
+ config_func.tip_set_freq_divider_func = ddr3_tip_a38x_set_divider;
+ config_func.tip_get_device_info_func = ddr3_tip_a38x_get_device_info;
+ config_func.tip_get_temperature = ddr3_ctrl_get_junc_temp;
+
+ ddr3_tip_init_config_func(dev_num, &config_func);
+
+ ddr3_tip_register_dq_table(dev_num, dq_bit_map_2_phy_pin);
+
+#ifdef STATIC_ALGO_SUPPORT
+ {
+ struct hws_tip_static_config_info static_config;
+ u32 board_offset =
+ board_id * A38X_NUMBER_OF_INTERFACES *
+ tm->num_of_bus_per_interface;
+
+ static_config.silicon_delay =
+ a38x_silicon_delay_offset[board_id];
+ static_config.package_trace_arr =
+ a38x_package_round_trip_delay_array;
+ static_config.board_trace_arr =
+ &a38x_board_round_trip_delay_array[board_offset];
+ ddr3_tip_init_static_config_db(dev_num, &static_config);
+ }
+#endif
+ status = ddr3_tip_a38x_get_init_freq(dev_num, &ddr_freq);
+ if (MV_OK != status) {
+ DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
+ ("DDR3 silicon get target frequency - FAILED 0x%x\n",
+ status));
+ return status;
+ }
+
+ rl_version = 1;
+ mask_tune_func = (SET_LOW_FREQ_MASK_BIT |
+ LOAD_PATTERN_MASK_BIT |
+ SET_MEDIUM_FREQ_MASK_BIT | WRITE_LEVELING_MASK_BIT |
+ /* LOAD_PATTERN_2_MASK_BIT | */
+ WRITE_LEVELING_SUPP_MASK_BIT |
+ READ_LEVELING_MASK_BIT |
+ PBS_RX_MASK_BIT |
+ PBS_TX_MASK_BIT |
+ SET_TARGET_FREQ_MASK_BIT |
+ WRITE_LEVELING_TF_MASK_BIT |
+ WRITE_LEVELING_SUPP_TF_MASK_BIT |
+ READ_LEVELING_TF_MASK_BIT |
+ CENTRALIZATION_RX_MASK_BIT |
+ CENTRALIZATION_TX_MASK_BIT);
+ rl_mid_freq_wa = 1;
+
+ if ((ddr_freq == DDR_FREQ_333) || (ddr_freq == DDR_FREQ_400)) {
+ mask_tune_func = (WRITE_LEVELING_MASK_BIT |
+ LOAD_PATTERN_2_MASK_BIT |
+ WRITE_LEVELING_SUPP_MASK_BIT |
+ READ_LEVELING_MASK_BIT |
+ PBS_RX_MASK_BIT |
+ PBS_TX_MASK_BIT |
+ CENTRALIZATION_RX_MASK_BIT |
+ CENTRALIZATION_TX_MASK_BIT);
+ rl_mid_freq_wa = 0; /* WA not needed if 333/400 is TF */
+ }
+
+ /* Supplementary not supported for ECC modes */
+ if (1 == ddr3_if_ecc_enabled()) {
+ mask_tune_func &= ~WRITE_LEVELING_SUPP_TF_MASK_BIT;
+ mask_tune_func &= ~WRITE_LEVELING_SUPP_MASK_BIT;
+ mask_tune_func &= ~PBS_TX_MASK_BIT;
+ mask_tune_func &= ~PBS_RX_MASK_BIT;
+ }
+
+ if (ck_delay == -1)
+ ck_delay = 160;
+ if (ck_delay_16 == -1)
+ ck_delay_16 = 160;
+ ca_delay = 0;
+ delay_enable = 1;
+
+ calibration_update_control = 1;
+
+ init_freq = tm->interface_params[first_active_if].memory_freq;
+
+ ddr3_tip_a38x_get_medium_freq(dev_num, &medium_freq);
+
+ return MV_OK;
+}
+
+int ddr3_a38x_update_topology_map(u32 dev_num, struct hws_topology_map *tm)
+{
+ u32 if_id = 0;
+ enum hws_ddr_freq freq;
+
+ ddr3_tip_a38x_get_init_freq(dev_num, &freq);
+ tm->interface_params[if_id].memory_freq = freq;
+
+ /*
+ * re-calc topology parameters according to topology updates
+ * (if needed)
+ */
+ CHECK_STATUS(hws_ddr3_tip_load_topology_map(dev_num, tm));
+
+ return MV_OK;
+}
+
+int ddr3_tip_init_a38x(u32 dev_num, u32 board_id)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (NULL == tm)
+ return MV_FAIL;
+
+ ddr3_a38x_update_topology_map(dev_num, tm);
+ ddr3_tip_init_a38x_silicon(dev_num, board_id);
+
+ return MV_OK;
+}
+
+int ddr3_tip_a38x_get_init_freq(int dev_num, enum hws_ddr_freq *freq)
+{
+ u32 reg;
+
+ /* Read sample at reset setting */
+ reg = (reg_read(REG_DEVICE_SAR1_ADDR) >>
+ RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
+ RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
+ switch (reg) {
+ case 0x0:
+ case 0x1:
+ *freq = DDR_FREQ_333;
+ break;
+ case 0x2:
+ case 0x3:
+ *freq = DDR_FREQ_400;
+ break;
+ case 0x4:
+ case 0xd:
+ *freq = DDR_FREQ_533;
+ break;
+ case 0x6:
+ *freq = DDR_FREQ_600;
+ break;
+ case 0x8:
+ case 0x11:
+ case 0x14:
+ *freq = DDR_FREQ_667;
+ break;
+ case 0xc:
+ case 0x15:
+ case 0x1b:
+ *freq = DDR_FREQ_800;
+ break;
+ case 0x10:
+ *freq = DDR_FREQ_933;
+ break;
+ case 0x12:
+ *freq = DDR_FREQ_900;
+ break;
+ case 0x13:
+ *freq = DDR_FREQ_900;
+ break;
+ default:
+ *freq = 0;
+ return MV_NOT_SUPPORTED;
+ }
+
+ return MV_OK;
+}
+
+int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq)
+{
+ u32 reg;
+
+ /* Read sample at reset setting */
+ reg = (reg_read(REG_DEVICE_SAR1_ADDR) >>
+ RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
+ RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
+ switch (reg) {
+ case 0x0:
+ case 0x1:
+ /* Medium is same as TF to run PBS in this freq */
+ *freq = DDR_FREQ_333;
+ break;
+ case 0x2:
+ case 0x3:
+ /* Medium is same as TF to run PBS in this freq */
+ *freq = DDR_FREQ_400;
+ break;
+ case 0x4:
+ case 0xd:
+ *freq = DDR_FREQ_533;
+ break;
+ case 0x8:
+ case 0x11:
+ case 0x14:
+ *freq = DDR_FREQ_333;
+ break;
+ case 0xc:
+ case 0x15:
+ case 0x1b:
+ *freq = DDR_FREQ_400;
+ break;
+ case 0x6:
+ *freq = DDR_FREQ_300;
+ break;
+ case 0x12:
+ *freq = DDR_FREQ_360;
+ break;
+ case 0x13:
+ *freq = DDR_FREQ_400;
+ break;
+ default:
+ *freq = 0;
+ return MV_NOT_SUPPORTED;
+ }
+
+ return MV_OK;
+}
+
+u32 ddr3_tip_get_init_freq(void)
+{
+ enum hws_ddr_freq freq;
+
+ ddr3_tip_a38x_get_init_freq(0, &freq);
+
+ return freq;
+}
+
+static int ddr3_tip_a38x_set_divider(u8 dev_num, u32 if_id,
+ enum hws_ddr_freq frequency)
+{
+ u32 divider = 0;
+ u32 sar_val;
+
+ if (if_id != 0) {
+ DEBUG_TRAINING_ACCESS(DEBUG_LEVEL_ERROR,
+ ("A38x does not support interface 0x%x\n",
+ if_id));
+ return MV_BAD_PARAM;
+ }
+
+ /* get VCO freq index */
+ sar_val = (reg_read(REG_DEVICE_SAR1_ADDR) >>
+ RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET) &
+ RST2_CPU_DDR_CLOCK_SELECT_IN_MASK;
+ divider = a38x_vco_freq_per_sar[sar_val] / freq_val[frequency];
+
+ /* Set Sync mode */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x20220, 0x0,
+ 0x1000));
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe42f4, 0x0,
+ 0x200));
+
+ /* cpupll_clkdiv_reset_mask */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0x1f,
+ 0xff));
+
+ /* cpupll_clkdiv_reload_smooth */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260,
+ (0x2 << 8), (0xff << 8)));
+
+ /* cpupll_clkdiv_relax_en */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260,
+ (0x2 << 24), (0xff << 24)));
+
+ /* write the divider */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4268,
+ (divider << 8), (0x3f << 8)));
+
+ /* set cpupll_clkdiv_reload_ratio */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264,
+ (1 << 8), (1 << 8)));
+
+ /* undet cpupll_clkdiv_reload_ratio */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0,
+ (1 << 8)));
+
+ /* clear cpupll_clkdiv_reload_force */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260, 0,
+ (0xff << 8)));
+
+ /* clear cpupll_clkdiv_relax_en */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4260, 0,
+ (0xff << 24)));
+
+ /* clear cpupll_clkdiv_reset_mask */
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0xe4264, 0,
+ 0xff));
+
+ /* Dunit training clock + 1:1 mode */
+ if ((frequency == DDR_FREQ_LOW_FREQ) || (freq_val[frequency] <= 400)) {
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x18488,
+ (1 << 16), (1 << 16)));
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1524,
+ (0 << 15), (1 << 15)));
+ } else {
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x18488,
+ 0, (1 << 16)));
+ CHECK_STATUS(ddr3_tip_a38x_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1524,
+ (1 << 15), (1 << 15)));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * external read from memory
+ */
+int ddr3_tip_ext_read(u32 dev_num, u32 if_id, u32 reg_addr,
+ u32 num_of_bursts, u32 *data)
+{
+ u32 burst_num;
+
+ for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++)
+ data[burst_num] = readl(reg_addr + 4 * burst_num);
+
+ return MV_OK;
+}
+
+/*
+ * external write to memory
+ */
+int ddr3_tip_ext_write(u32 dev_num, u32 if_id, u32 reg_addr,
+ u32 num_of_bursts, u32 *data) {
+ u32 burst_num;
+
+ for (burst_num = 0; burst_num < num_of_bursts * 8; burst_num++)
+ writel(data[burst_num], reg_addr + 4 * burst_num);
+
+ return MV_OK;
+}
+
+int ddr3_silicon_pre_init(void)
+{
+ int result;
+
+ result = ddr3_silicon_init();
+
+ return result;
+}
+
+int ddr3_post_run_alg(void)
+{
+ return MV_OK;
+}
+
+int ddr3_silicon_post_init(void)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* Set half bus width */
+ if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask)) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+ REG_SDRAM_CONFIG_ADDR, 0x0, 0x8000));
+ }
+
+ return MV_OK;
+}
+
+int ddr3_tip_a38x_get_device_info(u8 dev_num, struct ddr3_device_info *info_ptr)
+{
+ info_ptr->device_id = 0x6800;
+ info_ptr->ck_delay = ck_delay;
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_A38X_H
+#define _DDR3_A38X_H
+
+#define MAX_INTERFACE_NUM 1
+#define MAX_BUS_NUM 5
+
+#include "ddr3_hws_hw_training_def.h"
+
+/* Allow topolgy update from board TWSI device*/
+#if !defined(CONFIG_CUSTOMER_BOARD_SUPPORT)
+#define MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI
+#endif
+
+#define ECC_SUPPORT
+
+/* right now, we're not supporting this in mainline */
+#undef SUPPORT_STATIC_DUNIT_CONFIG
+
+/* Controler bus divider 1 for 32 bit, 2 for 64 bit */
+#define DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER 1
+
+/* Tune internal training params values */
+#define TUNE_TRAINING_PARAMS_CK_DELAY 160
+#define TUNE_TRAINING_PARAMS_CK_DELAY_16 160
+#define TUNE_TRAINING_PARAMS_PFINGER 41
+#define TUNE_TRAINING_PARAMS_NFINGER 43
+#define TUNE_TRAINING_PARAMS_PHYREG3VAL 0xa
+
+#define MARVELL_BOARD MARVELL_BOARD_ID_BASE
+
+
+#define REG_DEVICE_SAR1_ADDR 0xe4204
+#define RST2_CPU_DDR_CLOCK_SELECT_IN_OFFSET 17
+#define RST2_CPU_DDR_CLOCK_SELECT_IN_MASK 0x1f
+
+/* DRAM Windows */
+#define REG_XBAR_WIN_5_CTRL_ADDR 0x20050
+#define REG_XBAR_WIN_5_BASE_ADDR 0x20054
+
+/* DRAM Windows */
+#define REG_XBAR_WIN_4_CTRL_ADDR 0x20040
+#define REG_XBAR_WIN_4_BASE_ADDR 0x20044
+#define REG_XBAR_WIN_4_REMAP_ADDR 0x20048
+#define REG_XBAR_WIN_7_REMAP_ADDR 0x20078
+#define REG_XBAR_WIN_16_CTRL_ADDR 0x200d0
+#define REG_XBAR_WIN_16_BASE_ADDR 0x200d4
+#define REG_XBAR_WIN_16_REMAP_ADDR 0x200dc
+#define REG_XBAR_WIN_19_CTRL_ADDR 0x200e8
+
+#define REG_FASTPATH_WIN_BASE_ADDR(win) (0x20180 + (0x8 * win))
+#define REG_FASTPATH_WIN_CTRL_ADDR(win) (0x20184 + (0x8 * win))
+
+/* SatR defined too change topology busWidth and ECC configuration */
+#define DDR_SATR_CONFIG_MASK_WIDTH 0x8
+#define DDR_SATR_CONFIG_MASK_ECC 0x10
+#define DDR_SATR_CONFIG_MASK_ECC_PUP 0x20
+
+#define REG_SAMPLE_RESET_HIGH_ADDR 0x18600
+
+#define MV_BOARD_REFCLK MV_BOARD_REFCLK_25MHZ
+
+/* Matrix enables DRAM modes (bus width/ECC) per boardId */
+#define TOPOLOGY_UPDATE_32BIT 0
+#define TOPOLOGY_UPDATE_32BIT_ECC 1
+#define TOPOLOGY_UPDATE_16BIT 2
+#define TOPOLOGY_UPDATE_16BIT_ECC 3
+#define TOPOLOGY_UPDATE_16BIT_ECC_PUP3 4
+#define TOPOLOGY_UPDATE { \
+ /* 32Bit, 32bit ECC, 16bit, 16bit ECC PUP4, 16bit ECC PUP3 */ \
+ {1, 1, 1, 1, 1}, /* RD_NAS_68XX_ID */ \
+ {1, 1, 1, 1, 1}, /* DB_68XX_ID */ \
+ {1, 0, 1, 0, 1}, /* RD_AP_68XX_ID */ \
+ {1, 0, 1, 0, 1}, /* DB_AP_68XX_ID */ \
+ {1, 0, 1, 0, 1}, /* DB_GP_68XX_ID */ \
+ {0, 0, 1, 1, 0}, /* DB_BP_6821_ID */ \
+ {1, 1, 1, 1, 1} /* DB_AMC_6820_ID */ \
+ };
+
+enum {
+ CPU_1066MHZ_DDR_400MHZ,
+ CPU_RESERVED_DDR_RESERVED0,
+ CPU_667MHZ_DDR_667MHZ,
+ CPU_800MHZ_DDR_800MHZ,
+ CPU_RESERVED_DDR_RESERVED1,
+ CPU_RESERVED_DDR_RESERVED2,
+ CPU_RESERVED_DDR_RESERVED3,
+ LAST_FREQ
+};
+
+#define ACTIVE_INTERFACE_MASK 0x1
+
+#endif /* _DDR3_A38X_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_A38X_MC_STATIC_H
+#define _DDR3_A38X_MC_STATIC_H
+
+#include "ddr3_a38x.h"
+
+#ifdef SUPPORT_STATIC_DUNIT_CONFIG
+
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+static struct reg_data ddr3_customer_800[] = {
+ /* parameters for customer board (based on 800MHZ) */
+ {0x1400, 0x7b00cc30, 0xffffffff},
+ {0x1404, 0x36301820, 0xffffffff},
+ {0x1408, 0x5415baab, 0xffffffff},
+ {0x140c, 0x38411def, 0xffffffff},
+ {0x1410, 0x18300000, 0xffffffff},
+ {0x1414, 0x00000700, 0xffffffff},
+ {0x1424, 0x0060f3ff, 0xffffffff},
+ {0x1428, 0x0011a940, 0xffffffff},
+ {0x142c, 0x28c5134, 0xffffffff},
+ {0x1474, 0x00000000, 0xffffffff},
+ {0x147c, 0x0000d771, 0xffffffff},
+ {0x1494, 0x00030000, 0xffffffff},
+ {0x149c, 0x00000300, 0xffffffff},
+ {0x14a8, 0x00000000, 0xffffffff},
+ {0x14cc, 0xbd09000d, 0xffffffff},
+ {0x1504, 0xfffffff1, 0xffffffff},
+ {0x150c, 0xffffffe5, 0xffffffff},
+ {0x1514, 0x00000000, 0xffffffff},
+ {0x151c, 0x00000000, 0xffffffff},
+ {0x1538, 0x00000b0b, 0xffffffff},
+ {0x153c, 0x00000c0c, 0xffffffff},
+ {0x15d0, 0x00000670, 0xffffffff},
+ {0x15d4, 0x00000046, 0xffffffff},
+ {0x15d8, 0x00000010, 0xffffffff},
+ {0x15dc, 0x00000000, 0xffffffff},
+ {0x15e0, 0x00000023, 0xffffffff},
+ {0x15e4, 0x00203c18, 0xffffffff},
+ {0x15ec, 0xf8000019, 0xffffffff},
+ {0x16a0, 0xcc000006, 0xffffffff}, /* Clock Delay */
+ {0xe4124, 0x08008073, 0xffffffff}, /* AVS BG default */
+ {0, 0, 0}
+};
+
+#else /* CONFIG_CUSTOMER_BOARD_SUPPORT */
+
+struct reg_data ddr3_a38x_933[MV_MAX_DDR3_STATIC_SIZE] = {
+ /* parameters for 933MHZ */
+ {0x1400, 0x7b00ce3a, 0xffffffff},
+ {0x1404, 0x36301820, 0xffffffff},
+ {0x1408, 0x7417eccf, 0xffffffff},
+ {0x140c, 0x3e421f98, 0xffffffff},
+ {0x1410, 0x1a300000, 0xffffffff},
+ {0x1414, 0x00000700, 0xffffffff},
+ {0x1424, 0x0060f3ff, 0xffffffff},
+ {0x1428, 0x0013ca50, 0xffffffff},
+ {0x142c, 0x028c5165, 0xffffffff},
+ {0x1474, 0x00000000, 0xffffffff},
+ {0x147c, 0x0000e871, 0xffffffff},
+ {0x1494, 0x00010000, 0xffffffff},
+ {0x149c, 0x00000001, 0xffffffff},
+ {0x14a8, 0x00000000, 0xffffffff},
+ {0x14cc, 0xbd09000d, 0xffffffff},
+ {0x1504, 0xffffffe1, 0xffffffff},
+ {0x150c, 0xffffffe5, 0xffffffff},
+ {0x1514, 0x00000000, 0xffffffff},
+ {0x151c, 0x00000000, 0xffffffff},
+ {0x1538, 0x00000d0d, 0xffffffff},
+ {0x153c, 0x00000d0d, 0xffffffff},
+ {0x15d0, 0x00000608, 0xffffffff},
+ {0x15d4, 0x00000044, 0xffffffff},
+ {0x15d8, 0x00000020, 0xffffffff},
+ {0x15dc, 0x00000000, 0xffffffff},
+ {0x15e0, 0x00000021, 0xffffffff},
+ {0x15e4, 0x00203c18, 0xffffffff},
+ {0x15ec, 0xf8000019, 0xffffffff},
+ {0x16a0, 0xcc000006, 0xffffffff}, /* Clock Delay */
+ {0xe4124, 0x08008073, 0xffffffff}, /* AVS BG default */
+ {0, 0, 0}
+};
+
+static struct reg_data ddr3_a38x_800[] = {
+ /* parameters for 800MHZ */
+ {0x1400, 0x7b00cc30, 0xffffffff},
+ {0x1404, 0x36301820, 0xffffffff},
+ {0x1408, 0x5415baab, 0xffffffff},
+ {0x140c, 0x38411def, 0xffffffff},
+ {0x1410, 0x18300000, 0xffffffff},
+ {0x1414, 0x00000700, 0xffffffff},
+ {0x1424, 0x0060f3ff, 0xffffffff},
+ {0x1428, 0x0011a940, 0xffffffff},
+ {0x142c, 0x28c5134, 0xffffffff},
+ {0x1474, 0x00000000, 0xffffffff},
+ {0x147c, 0x0000d771, 0xffffffff},
+ {0x1494, 0x00030000, 0xffffffff},
+ {0x149c, 0x00000300, 0xffffffff},
+ {0x14a8, 0x00000000, 0xffffffff},
+ {0x14cc, 0xbd09000d, 0xffffffff},
+ {0x1504, 0xfffffff1, 0xffffffff},
+ {0x150c, 0xffffffe5, 0xffffffff},
+ {0x1514, 0x00000000, 0xffffffff},
+ {0x151c, 0x00000000, 0xffffffff},
+ {0x1538, 0x00000b0b, 0xffffffff},
+ {0x153c, 0x00000c0c, 0xffffffff},
+ {0x15d0, 0x00000670, 0xffffffff},
+ {0x15d4, 0x00000046, 0xffffffff},
+ {0x15d8, 0x00000010, 0xffffffff},
+ {0x15dc, 0x00000000, 0xffffffff},
+ {0x15e0, 0x00000023, 0xffffffff},
+ {0x15e4, 0x00203c18, 0xffffffff},
+ {0x15ec, 0xf8000019, 0xffffffff},
+ {0x16a0, 0xcc000006, 0xffffffff}, /* Clock Delay */
+ {0xe4124, 0x08008073, 0xffffffff}, /* AVS BG default */
+ {0, 0, 0}
+};
+
+static struct reg_data ddr3_a38x_667[] = {
+ /* parameters for 667MHZ */
+ /* DDR SDRAM Configuration Register */
+ {0x1400, 0x7b00ca28, 0xffffffff},
+ /* Dunit Control Low Register - kw28 bit12 low (disable CLK1) */
+ {0x1404, 0x36301820, 0xffffffff},
+ /* DDR SDRAM Timing (Low) Register */
+ {0x1408, 0x43149997, 0xffffffff},
+ /* DDR SDRAM Timing (High) Register */
+ {0x140c, 0x38411bc7, 0xffffffff},
+ /* DDR SDRAM Address Control Register */
+ {0x1410, 0x14330000, 0xffffffff},
+ /* DDR SDRAM Open Pages Control Register */
+ {0x1414, 0x00000700, 0xffffffff},
+ /* Dunit Control High Register (2 :1 - bits 15:12 = 0xd) */
+ {0x1424, 0x0060f3ff, 0xffffffff},
+ /* Dunit Control High Register */
+ {0x1428, 0x000f8830, 0xffffffff},
+ /* Dunit Control High Register (2:1 - bit 29 = '1') */
+ {0x142c, 0x28c50f8, 0xffffffff},
+ {0x147c, 0x0000c671, 0xffffffff},
+ /* DDR SDRAM ODT Control (Low) Register */
+ {0x1494, 0x00030000, 0xffffffff},
+ /* DDR SDRAM ODT Control (High) Register, will be configured at WL */
+ {0x1498, 0x00000000, 0xffffffff},
+ /* DDR Dunit ODT Control Register */
+ {0x149c, 0x00000300, 0xffffffff},
+ {0x14a8, 0x00000000, 0xffffffff}, /* */
+ {0x14cc, 0xbd09000d, 0xffffffff}, /* */
+ {0x1474, 0x00000000, 0xffffffff},
+ /* Read Data Sample Delays Register */
+ {0x1538, 0x00000009, 0xffffffff},
+ /* Read Data Ready Delay Register */
+ {0x153c, 0x0000000c, 0xffffffff},
+ {0x1504, 0xfffffff1, 0xffffffff}, /* */
+ {0x150c, 0xffffffe5, 0xffffffff}, /* */
+ {0x1514, 0x00000000, 0xffffffff}, /* */
+ {0x151c, 0x0, 0xffffffff}, /* */
+ {0x15d0, 0x00000650, 0xffffffff}, /* MR0 */
+ {0x15d4, 0x00000046, 0xffffffff}, /* MR1 */
+ {0x15d8, 0x00000010, 0xffffffff}, /* MR2 */
+ {0x15dc, 0x00000000, 0xffffffff}, /* MR3 */
+ {0x15e0, 0x23, 0xffffffff}, /* */
+ {0x15e4, 0x00203c18, 0xffffffff}, /* ZQC Configuration Register */
+ {0x15ec, 0xf8000019, 0xffffffff}, /* DDR PHY */
+ {0x16a0, 0xcc000006, 0xffffffff}, /* Clock Delay */
+ {0xe4124, 0x08008073, 0xffffffff}, /* AVS BG default */
+ {0, 0, 0}
+};
+
+static struct reg_data ddr3_a38x_533[] = {
+ /* parameters for 533MHZ */
+ /* DDR SDRAM Configuration Register */
+ {0x1400, 0x7b00d040, 0xffffffff},
+ /* Dunit Control Low Register - kw28 bit12 low (disable CLK1) */
+ {0x1404, 0x36301820, 0xffffffff},
+ /* DDR SDRAM Timing (Low) Register */
+ {0x1408, 0x33137772, 0xffffffff},
+ /* DDR SDRAM Timing (High) Register */
+ {0x140c, 0x3841199f, 0xffffffff},
+ /* DDR SDRAM Address Control Register */
+ {0x1410, 0x10330000, 0xffffffff},
+ /* DDR SDRAM Open Pages Control Register */
+ {0x1414, 0x00000700, 0xffffffff},
+ /* Dunit Control High Register (2 :1 - bits 15:12 = 0xd) */
+ {0x1424, 0x0060f3ff, 0xffffffff},
+ /* Dunit Control High Register */
+ {0x1428, 0x000d6720, 0xffffffff},
+ /* Dunit Control High Register (2:1 - bit 29 = '1') */
+ {0x142c, 0x028c50c3, 0xffffffff},
+ {0x147c, 0x0000b571, 0xffffffff},
+ /* DDR SDRAM ODT Control (Low) Register */
+ {0x1494, 0x00030000, 0xffffffff},
+ /* DDR SDRAM ODT Control (High) Register, will be configured at WL */
+ {0x1498, 0x00000000, 0xffffffff},
+ /* DDR Dunit ODT Control Register */
+ {0x149c, 0x00000003, 0xffffffff},
+ {0x14a8, 0x00000000, 0xffffffff}, /* */
+ {0x14cc, 0xbd09000d, 0xffffffff}, /* */
+ {0x1474, 0x00000000, 0xffffffff},
+ /* Read Data Sample Delays Register */
+ {0x1538, 0x00000707, 0xffffffff},
+ /* Read Data Ready Delay Register */
+ {0x153c, 0x00000707, 0xffffffff},
+ {0x1504, 0xffffffe1, 0xffffffff}, /* */
+ {0x150c, 0xffffffe5, 0xffffffff}, /* */
+ {0x1514, 0x00000000, 0xffffffff}, /* */
+ {0x151c, 0x00000000, 0xffffffff}, /* */
+ {0x15d0, 0x00000630, 0xffffffff}, /* MR0 */
+ {0x15d4, 0x00000046, 0xffffffff}, /* MR1 */
+ {0x15d8, 0x00000008, 0xffffffff}, /* MR2 */
+ {0x15dc, 0x00000000, 0xffffffff}, /* MR3 */
+ {0x15e0, 0x00000023, 0xffffffff}, /* */
+ {0x15e4, 0x00203c18, 0xffffffff}, /* ZQC Configuration Register */
+ {0x15ec, 0xf8000019, 0xffffffff}, /* DDR PHY */
+ {0x16a0, 0xcc000006, 0xffffffff}, /* Clock Delay */
+ {0xe4124, 0x08008073, 0xffffffff}, /* AVS BG default */
+ {0, 0, 0}
+};
+
+#endif /* CONFIG_CUSTOMER_BOARD_SUPPORT */
+
+#endif /* SUPPORT_STATIC_DUNIT_CONFIG */
+
+#endif /* _DDR3_A38X_MC_STATIC_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_A38X_TOPOLOGY_H
+#define _DDR3_A38X_TOPOLOGY_H
+
+#include "ddr_topology_def.h"
+
+/* Bus mask variants */
+#define BUS_MASK_32BIT 0xf
+#define BUS_MASK_32BIT_ECC 0x1f
+#define BUS_MASK_16BIT 0x3
+#define BUS_MASK_16BIT_ECC 0x13
+#define BUS_MASK_16BIT_ECC_PUP3 0xb
+
+#define DYNAMIC_CS_SIZE_CONFIG
+#define DISABLE_L2_FILTERING_DURING_DDR_TRAINING
+
+#endif /* _DDR3_A38X_TOPOLOGY_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+/*
+ * Name: ddr3_tip_init_silicon
+ * Desc: initiate silicon parameters
+ * Args:
+ * Notes:
+ * Returns: required value
+ */
+int ddr3_silicon_init(void)
+{
+ int status;
+ static int init_done;
+
+ if (init_done == 1)
+ return MV_OK;
+
+ status = ddr3_tip_init_a38x(0, 0);
+ if (MV_OK != status) {
+ printf("DDR3 A38x silicon init - FAILED 0x%x\n", status);
+ return status;
+ }
+
+ init_done = 1;
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+u8 is_reg_dump = 0;
+u8 debug_pbs = DEBUG_LEVEL_ERROR;
+
+/*
+ * API to change flags outside of the lib
+ */
+#ifndef SILENT_LIB
+/* Debug flags for other Training modules */
+u8 debug_training_static = DEBUG_LEVEL_ERROR;
+u8 debug_training = DEBUG_LEVEL_ERROR;
+u8 debug_leveling = DEBUG_LEVEL_ERROR;
+u8 debug_centralization = DEBUG_LEVEL_ERROR;
+u8 debug_training_ip = DEBUG_LEVEL_ERROR;
+u8 debug_training_bist = DEBUG_LEVEL_ERROR;
+u8 debug_training_hw_alg = DEBUG_LEVEL_ERROR;
+u8 debug_training_access = DEBUG_LEVEL_ERROR;
+u8 debug_training_a38x = DEBUG_LEVEL_ERROR;
+
+void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
+{
+ switch (block) {
+ case DEBUG_BLOCK_STATIC:
+ debug_training_static = level;
+ break;
+ case DEBUG_BLOCK_TRAINING_MAIN:
+ debug_training = level;
+ break;
+ case DEBUG_BLOCK_LEVELING:
+ debug_leveling = level;
+ break;
+ case DEBUG_BLOCK_CENTRALIZATION:
+ debug_centralization = level;
+ break;
+ case DEBUG_BLOCK_PBS:
+ debug_pbs = level;
+ break;
+ case DEBUG_BLOCK_ALG:
+ debug_training_hw_alg = level;
+ break;
+ case DEBUG_BLOCK_DEVICE:
+ debug_training_a38x = level;
+ break;
+ case DEBUG_BLOCK_ACCESS:
+ debug_training_access = level;
+ break;
+ case DEBUG_STAGES_REG_DUMP:
+ if (level == DEBUG_LEVEL_TRACE)
+ is_reg_dump = 1;
+ else
+ is_reg_dump = 0;
+ break;
+ case DEBUG_BLOCK_ALL:
+ default:
+ debug_training_static = level;
+ debug_training = level;
+ debug_leveling = level;
+ debug_centralization = level;
+ debug_pbs = level;
+ debug_training_hw_alg = level;
+ debug_training_access = level;
+ debug_training_a38x = level;
+ }
+}
+#else
+void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level)
+{
+ return;
+}
+#endif
+
+struct hws_tip_config_func_db config_func_info[HWS_MAX_DEVICE_NUM];
+u8 is_default_centralization = 0;
+u8 is_tune_result = 0;
+u8 is_validate_window_per_if = 0;
+u8 is_validate_window_per_pup = 0;
+u8 sweep_cnt = 1;
+u32 is_bist_reset_bit = 1;
+static struct hws_xsb_info xsb_info[HWS_MAX_DEVICE_NUM];
+
+/*
+ * Dump Dunit & Phy registers
+ */
+int ddr3_tip_reg_dump(u32 dev_num)
+{
+ u32 if_id, reg_addr, data_value, bus_id;
+ u32 read_data[MAX_INTERFACE_NUM];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ printf("-- dunit registers --\n");
+ for (reg_addr = 0x1400; reg_addr < 0x19f0; reg_addr += 4) {
+ printf("0x%x ", reg_addr);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, reg_addr, read_data,
+ MASK_ALL_BITS));
+ printf("0x%x ", read_data[if_id]);
+ }
+ printf("\n");
+ }
+
+ printf("-- Phy registers --\n");
+ for (reg_addr = 0; reg_addr <= 0xff; reg_addr++) {
+ printf("0x%x ", reg_addr);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_id = 0;
+ bus_id < tm->num_of_bus_per_interface;
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_id,
+ DDR_PHY_DATA, reg_addr,
+ &data_value));
+ printf("0x%x ", data_value);
+ }
+ for (bus_id = 0;
+ bus_id < tm->num_of_bus_per_interface;
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_id,
+ DDR_PHY_CONTROL, reg_addr,
+ &data_value));
+ printf("0x%x ", data_value);
+ }
+ }
+ printf("\n");
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Register access func registration
+ */
+int ddr3_tip_init_config_func(u32 dev_num,
+ struct hws_tip_config_func_db *config_func)
+{
+ if (config_func == NULL)
+ return MV_BAD_PARAM;
+
+ memcpy(&config_func_info[dev_num], config_func,
+ sizeof(struct hws_tip_config_func_db));
+
+ return MV_OK;
+}
+
+/*
+ * Read training result table
+ */
+int hws_ddr3_tip_read_training_result(
+ u32 dev_num, enum hws_result result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM])
+{
+ dev_num = dev_num;
+
+ if (result == NULL)
+ return MV_BAD_PARAM;
+ memcpy(result, training_result, sizeof(result));
+
+ return MV_OK;
+}
+
+/*
+ * Get training result info pointer
+ */
+enum hws_result *ddr3_tip_get_result_ptr(u32 stage)
+{
+ return training_result[stage];
+}
+
+/*
+ * Device info read
+ */
+int ddr3_tip_get_device_info(u32 dev_num, struct ddr3_device_info *info_ptr)
+{
+ if (config_func_info[dev_num].tip_get_device_info_func != NULL) {
+ return config_func_info[dev_num].
+ tip_get_device_info_func((u8) dev_num, info_ptr);
+ }
+
+ return MV_FAIL;
+}
+
+#ifndef EXCLUDE_SWITCH_DEBUG
+/*
+ * Convert freq to character string
+ */
+static char *convert_freq(enum hws_ddr_freq freq)
+{
+ switch (freq) {
+ case DDR_FREQ_LOW_FREQ:
+ return "DDR_FREQ_LOW_FREQ";
+ case DDR_FREQ_400:
+ return "400";
+
+ case DDR_FREQ_533:
+ return "533";
+ case DDR_FREQ_667:
+ return "667";
+
+ case DDR_FREQ_800:
+ return "800";
+
+ case DDR_FREQ_933:
+ return "933";
+
+ case DDR_FREQ_1066:
+ return "1066";
+ case DDR_FREQ_311:
+ return "311";
+
+ case DDR_FREQ_333:
+ return "333";
+
+ case DDR_FREQ_467:
+ return "467";
+
+ case DDR_FREQ_850:
+ return "850";
+
+ case DDR_FREQ_900:
+ return "900";
+
+ case DDR_FREQ_360:
+ return "DDR_FREQ_360";
+
+ case DDR_FREQ_1000:
+ return "DDR_FREQ_1000";
+ default:
+ return "Unknown Frequency";
+ }
+}
+
+/*
+ * Convert device ID to character string
+ */
+static char *convert_dev_id(u32 dev_id)
+{
+ switch (dev_id) {
+ case 0x6800:
+ return "A38xx";
+ case 0x6900:
+ return "A39XX";
+ case 0xf400:
+ return "AC3";
+ case 0xfc00:
+ return "BC2";
+
+ default:
+ return "Unknown Device";
+ }
+}
+
+/*
+ * Convert device ID to character string
+ */
+static char *convert_mem_size(u32 dev_id)
+{
+ switch (dev_id) {
+ case 0:
+ return "512 MB";
+ case 1:
+ return "1 GB";
+ case 2:
+ return "2 GB";
+ case 3:
+ return "4 GB";
+ case 4:
+ return "8 GB";
+
+ default:
+ return "wrong mem size";
+ }
+}
+
+int print_device_info(u8 dev_num)
+{
+ struct ddr3_device_info info_ptr;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ CHECK_STATUS(ddr3_tip_get_device_info(dev_num, &info_ptr));
+ printf("=== DDR setup START===\n");
+ printf("\tDevice ID: %s\n", convert_dev_id(info_ptr.device_id));
+ printf("\tDDR3 CK delay: %d\n", info_ptr.ck_delay);
+ print_topology(tm);
+ printf("=== DDR setup END===\n");
+
+ return MV_OK;
+}
+
+void hws_ddr3_tip_sweep_test(int enable)
+{
+ if (enable) {
+ is_validate_window_per_if = 1;
+ is_validate_window_per_pup = 1;
+ debug_training = DEBUG_LEVEL_TRACE;
+ } else {
+ is_validate_window_per_if = 0;
+ is_validate_window_per_pup = 0;
+ }
+}
+#endif
+
+char *ddr3_tip_convert_tune_result(enum hws_result tune_result)
+{
+ switch (tune_result) {
+ case TEST_FAILED:
+ return "FAILED";
+ case TEST_SUCCESS:
+ return "PASS";
+ case NO_TEST_DONE:
+ return "NOT COMPLETED";
+ default:
+ return "Un-KNOWN";
+ }
+}
+
+/*
+ * Print log info
+ */
+int ddr3_tip_print_log(u32 dev_num, u32 mem_addr)
+{
+ u32 if_id = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ mem_addr = mem_addr;
+
+#ifndef EXCLUDE_SWITCH_DEBUG
+ if ((is_validate_window_per_if != 0) ||
+ (is_validate_window_per_pup != 0)) {
+ u32 is_pup_log = 0;
+ enum hws_ddr_freq freq;
+
+ freq = tm->interface_params[first_active_if].memory_freq;
+
+ is_pup_log = (is_validate_window_per_pup != 0) ? 1 : 0;
+ printf("===VALIDATE WINDOW LOG START===\n");
+ printf("DDR Frequency: %s ======\n", convert_freq(freq));
+ /* print sweep windows */
+ ddr3_tip_run_sweep_test(dev_num, sweep_cnt, 1, is_pup_log);
+ ddr3_tip_run_sweep_test(dev_num, sweep_cnt, 0, is_pup_log);
+ ddr3_tip_print_all_pbs_result(dev_num);
+ ddr3_tip_print_wl_supp_result(dev_num);
+ printf("===VALIDATE WINDOW LOG END ===\n");
+ CHECK_STATUS(ddr3_tip_restore_dunit_regs(dev_num));
+ ddr3_tip_reg_dump(dev_num);
+ }
+#endif
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("IF %d Status:\n", if_id));
+
+ if (mask_tune_func & INIT_CONTROLLER_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tInit Controller: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[INIT_CONTROLLER]
+ [if_id])));
+ }
+ if (mask_tune_func & SET_LOW_FREQ_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tLow freq Config: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[SET_LOW_FREQ]
+ [if_id])));
+ }
+ if (mask_tune_func & LOAD_PATTERN_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tLoad Pattern: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[LOAD_PATTERN]
+ [if_id])));
+ }
+ if (mask_tune_func & SET_MEDIUM_FREQ_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tMedium freq Config: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[SET_MEDIUM_FREQ]
+ [if_id])));
+ }
+ if (mask_tune_func & WRITE_LEVELING_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tWL: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[WRITE_LEVELING]
+ [if_id])));
+ }
+ if (mask_tune_func & LOAD_PATTERN_2_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tLoad Pattern: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[LOAD_PATTERN_2]
+ [if_id])));
+ }
+ if (mask_tune_func & READ_LEVELING_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tRL: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[READ_LEVELING]
+ [if_id])));
+ }
+ if (mask_tune_func & WRITE_LEVELING_SUPP_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tWL Supp: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[WRITE_LEVELING_SUPP]
+ [if_id])));
+ }
+ if (mask_tune_func & PBS_RX_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tPBS RX: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[PBS_RX]
+ [if_id])));
+ }
+ if (mask_tune_func & PBS_TX_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tPBS TX: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[PBS_TX]
+ [if_id])));
+ }
+ if (mask_tune_func & SET_TARGET_FREQ_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tTarget freq Config: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[SET_TARGET_FREQ]
+ [if_id])));
+ }
+ if (mask_tune_func & WRITE_LEVELING_TF_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tWL TF: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[WRITE_LEVELING_TF]
+ [if_id])));
+ }
+ if (mask_tune_func & READ_LEVELING_TF_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tRL TF: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[READ_LEVELING_TF]
+ [if_id])));
+ }
+ if (mask_tune_func & WRITE_LEVELING_SUPP_TF_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tWL TF Supp: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result
+ [WRITE_LEVELING_SUPP_TF]
+ [if_id])));
+ }
+ if (mask_tune_func & CENTRALIZATION_RX_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tCentr RX: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[CENTRALIZATION_RX]
+ [if_id])));
+ }
+ if (mask_tune_func & VREF_CALIBRATION_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tVREF_CALIBRATION: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[VREF_CALIBRATION]
+ [if_id])));
+ }
+ if (mask_tune_func & CENTRALIZATION_TX_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("\tCentr TX: %s\n",
+ ddr3_tip_convert_tune_result
+ (training_result[CENTRALIZATION_TX]
+ [if_id])));
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Print stability log info
+ */
+int ddr3_tip_print_stability_log(u32 dev_num)
+{
+ u8 if_id = 0, csindex = 0, bus_id = 0, idx = 0;
+ u32 reg_data;
+ u32 read_data[MAX_INTERFACE_NUM];
+ u32 max_cs = hws_ddr3_tip_max_cs_get();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* Title print */
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ printf("Title: I/F# , Tj, Calibration_n0, Calibration_p0, Calibration_n1, Calibration_p1, Calibration_n2, Calibration_p2,");
+ for (csindex = 0; csindex < max_cs; csindex++) {
+ printf("CS%d , ", csindex);
+ printf("\n");
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ printf("VWTx, VWRx, WL_tot, WL_ADLL, WL_PH, RL_Tot, RL_ADLL, RL_PH, RL_Smp, Cen_tx, Cen_rx, Vref, DQVref,");
+ printf("\t\t");
+ for (idx = 0; idx < 11; idx++)
+ printf("PBSTx-Pad%d,", idx);
+ printf("\t\t");
+ for (idx = 0; idx < 11; idx++)
+ printf("PBSRx-Pad%d,", idx);
+ }
+ }
+ printf("\n");
+
+ /* Data print */
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+
+ printf("Data: %d,%d,", if_id,
+ (config_func_info[dev_num].tip_get_temperature != NULL)
+ ? (config_func_info[dev_num].
+ tip_get_temperature(dev_num)) : (0));
+
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x14c8,
+ read_data, MASK_ALL_BITS));
+ printf("%d,%d,", ((read_data[if_id] & 0x3f0) >> 4),
+ ((read_data[if_id] & 0xfc00) >> 10));
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x17c8,
+ read_data, MASK_ALL_BITS));
+ printf("%d,%d,", ((read_data[if_id] & 0x3f0) >> 4),
+ ((read_data[if_id] & 0xfc00) >> 10));
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1dc8,
+ read_data, MASK_ALL_BITS));
+ printf("%d,%d,", ((read_data[if_id] & 0x3f0000) >> 16),
+ ((read_data[if_id] & 0xfc00000) >> 22));
+
+ for (csindex = 0; csindex < max_cs; csindex++) {
+ printf("CS%d , ", csindex);
+ for (bus_id = 0; bus_id < MAX_BUS_NUM; bus_id++) {
+ printf("\n");
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ RESULT_DB_PHY_REG_ADDR +
+ csindex, ®_data);
+ printf("%d,%d,", (reg_data & 0x1f),
+ ((reg_data & 0x3e0) >> 5));
+ /* WL */
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ WL_PHY_REG +
+ csindex * 4, ®_data);
+ printf("%d,%d,%d,",
+ (reg_data & 0x1f) +
+ ((reg_data & 0x1c0) >> 6) * 32,
+ (reg_data & 0x1f),
+ (reg_data & 0x1c0) >> 6);
+ /* RL */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id,
+ READ_DATA_SAMPLE_DELAY,
+ read_data, MASK_ALL_BITS));
+ read_data[if_id] =
+ (read_data[if_id] &
+ (0xf << (4 * csindex))) >>
+ (4 * csindex);
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_id,
+ DDR_PHY_DATA,
+ RL_PHY_REG + csindex * 4,
+ ®_data);
+ printf("%d,%d,%d,%d,",
+ (reg_data & 0x1f) +
+ ((reg_data & 0x1c0) >> 6) * 32 +
+ read_data[if_id] * 64,
+ (reg_data & 0x1f),
+ ((reg_data & 0x1c0) >> 6),
+ read_data[if_id]);
+ /* Centralization */
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_id,
+ DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG
+ + csindex * 4, ®_data);
+ printf("%d,", (reg_data & 0x3f));
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_id,
+ DDR_PHY_DATA,
+ READ_CENTRALIZATION_PHY_REG
+ + csindex * 4, ®_data);
+ printf("%d,", (reg_data & 0x1f));
+ /* Vref */
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_id,
+ DDR_PHY_DATA,
+ PAD_CONFIG_PHY_REG,
+ ®_data);
+ printf("%d,", (reg_data & 0x7));
+ /* DQVref */
+ /* Need to add the Read Function from device */
+ printf("%d,", 0);
+ printf("\t\t");
+ for (idx = 0; idx < 11; idx++) {
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ 0xd0 +
+ 12 * csindex +
+ idx, ®_data);
+ printf("%d,", (reg_data & 0x3f));
+ }
+ printf("\t\t");
+ for (idx = 0; idx < 11; idx++) {
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ 0x10 +
+ 16 * csindex +
+ idx, ®_data);
+ printf("%d,", (reg_data & 0x3f));
+ }
+ printf("\t\t");
+ for (idx = 0; idx < 11; idx++) {
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ 0x50 +
+ 16 * csindex +
+ idx, ®_data);
+ printf("%d,", (reg_data & 0x3f));
+ }
+ }
+ }
+ }
+ printf("\n");
+
+ return MV_OK;
+}
+
+/*
+ * Register XSB information
+ */
+int ddr3_tip_register_xsb_info(u32 dev_num, struct hws_xsb_info *xsb_info_table)
+{
+ memcpy(&xsb_info[dev_num], xsb_info_table, sizeof(struct hws_xsb_info));
+ return MV_OK;
+}
+
+/*
+ * Read ADLL Value
+ */
+int read_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+ int reg_addr, u32 mask)
+{
+ u32 data_value;
+ u32 if_id = 0, bus_id = 0;
+ u32 dev_num = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /*
+ * multi CS support - reg_addr is calucalated in calling function
+ * with CS offset
+ */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_id,
+ DDR_PHY_DATA, reg_addr,
+ &data_value));
+ pup_values[if_id *
+ tm->num_of_bus_per_interface + bus_id] =
+ data_value & mask;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Write ADLL Value
+ */
+int write_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+ int reg_addr)
+{
+ u32 if_id = 0, bus_id = 0;
+ u32 dev_num = 0, data;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /*
+ * multi CS support - reg_addr is calucalated in calling function
+ * with CS offset
+ */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ data = pup_values[if_id *
+ tm->num_of_bus_per_interface +
+ bus_id];
+ CHECK_STATUS(ddr3_tip_bus_write(dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ reg_addr, data));
+ }
+ }
+
+ return 0;
+}
+
+#ifndef EXCLUDE_SWITCH_DEBUG
+u32 rl_version = 1; /* 0 - old RL machine */
+struct hws_tip_config_func_db config_func_info[HWS_MAX_DEVICE_NUM];
+u32 start_xsb_offset = 0;
+u8 is_rl_old = 0;
+u8 is_freq_old = 0;
+u8 is_dfs_disabled = 0;
+u32 default_centrlization_value = 0x12;
+u32 vref = 0x4;
+u32 activate_select_before_run_alg = 1, activate_deselect_after_run_alg = 1,
+ rl_test = 0, reset_read_fifo = 0;
+int debug_acc = 0;
+u32 ctrl_sweepres[ADLL_LENGTH][MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u32 ctrl_adll[MAX_CS_NUM * MAX_INTERFACE_NUM * MAX_BUS_NUM];
+u8 cs_mask_reg[] = {
+ 0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+u32 xsb_test_table[][8] = {
+ {0x00000000, 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555,
+ 0x66666666, 0x77777777},
+ {0x88888888, 0x99999999, 0xaaaaaaaa, 0xbbbbbbbb, 0xcccccccc, 0xdddddddd,
+ 0xeeeeeeee, 0xffffffff},
+ {0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff},
+ {0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff},
+ {0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff},
+ {0x00000000, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff},
+ {0x00000000, 0x00000000, 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff},
+ {0x00000000, 0x00000000, 0x00000000, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000},
+ {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff}
+};
+
+static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr);
+
+int ddr3_tip_print_adll(void)
+{
+ u32 bus_cnt = 0, if_id, data_p1, data_p2, ui_data3, dev_num = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_cnt,
+ DDR_PHY_DATA, 0x1, &data_p1));
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST,
+ bus_cnt, DDR_PHY_DATA, 0x2, &data_p2));
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST,
+ bus_cnt, DDR_PHY_DATA, 0x3, &ui_data3));
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ (" IF %d bus_cnt %d phy_reg_1_data 0x%x phy_reg_2_data 0x%x phy_reg_3_data 0x%x\n",
+ if_id, bus_cnt, data_p1, data_p2,
+ ui_data3));
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Set attribute value
+ */
+int ddr3_tip_set_atr(u32 dev_num, u32 flag_id, u32 value)
+{
+ int ret;
+ u32 *ptr_flag = NULL;
+
+ ret = ddr3_tip_access_atr(dev_num, flag_id, value, &ptr_flag);
+ if (ptr_flag != NULL) {
+ printf("ddr3_tip_set_atr Flag ID 0x%x value is set to 0x%x (was 0x%x)\n",
+ flag_id, value, *ptr_flag);
+ *ptr_flag = value;
+ } else {
+ printf("ddr3_tip_set_atr Flag ID 0x%x value is set to 0x%x\n",
+ flag_id, value);
+ }
+
+ return ret;
+}
+
+/*
+ * Access attribute
+ */
+static int ddr3_tip_access_atr(u32 dev_num, u32 flag_id, u32 value, u32 **ptr)
+{
+ u32 tmp_val = 0, if_id = 0, pup_id = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ dev_num = dev_num;
+ *ptr = NULL;
+
+ switch (flag_id) {
+ case 0:
+ *ptr = (u32 *)&(tm->if_act_mask);
+ break;
+
+ case 0x1:
+ *ptr = (u32 *)&mask_tune_func;
+ break;
+
+ case 0x2:
+ *ptr = (u32 *)&low_freq;
+ break;
+
+ case 0x3:
+ *ptr = (u32 *)&medium_freq;
+ break;
+
+ case 0x4:
+ *ptr = (u32 *)&generic_init_controller;
+ break;
+
+ case 0x5:
+ *ptr = (u32 *)&rl_version;
+ break;
+
+ case 0x8:
+ *ptr = (u32 *)&start_xsb_offset;
+ break;
+
+ case 0x20:
+ *ptr = (u32 *)&is_rl_old;
+ break;
+
+ case 0x21:
+ *ptr = (u32 *)&is_freq_old;
+ break;
+
+ case 0x23:
+ *ptr = (u32 *)&is_dfs_disabled;
+ break;
+
+ case 0x24:
+ *ptr = (u32 *)&is_pll_before_init;
+ break;
+
+ case 0x25:
+ *ptr = (u32 *)&is_adll_calib_before_init;
+ break;
+#ifdef STATIC_ALGO_SUPPORT
+ case 0x26:
+ *ptr = (u32 *)&(silicon_delay[0]);
+ break;
+
+ case 0x27:
+ *ptr = (u32 *)&wl_debug_delay;
+ break;
+#endif
+ case 0x28:
+ *ptr = (u32 *)&is_tune_result;
+ break;
+
+ case 0x29:
+ *ptr = (u32 *)&is_validate_window_per_if;
+ break;
+
+ case 0x2a:
+ *ptr = (u32 *)&is_validate_window_per_pup;
+ break;
+
+ case 0x30:
+ *ptr = (u32 *)&sweep_cnt;
+ break;
+
+ case 0x31:
+ *ptr = (u32 *)&is_bist_reset_bit;
+ break;
+
+ case 0x32:
+ *ptr = (u32 *)&is_dfs_in_init;
+ break;
+
+ case 0x33:
+ *ptr = (u32 *)&p_finger;
+ break;
+
+ case 0x34:
+ *ptr = (u32 *)&n_finger;
+ break;
+
+ case 0x35:
+ *ptr = (u32 *)&init_freq;
+ break;
+
+ case 0x36:
+ *ptr = (u32 *)&(freq_val[DDR_FREQ_LOW_FREQ]);
+ break;
+
+ case 0x37:
+ *ptr = (u32 *)&start_pattern;
+ break;
+
+ case 0x38:
+ *ptr = (u32 *)&end_pattern;
+ break;
+
+ case 0x39:
+ *ptr = (u32 *)&phy_reg0_val;
+ break;
+
+ case 0x4a:
+ *ptr = (u32 *)&phy_reg1_val;
+ break;
+
+ case 0x4b:
+ *ptr = (u32 *)&phy_reg2_val;
+ break;
+
+ case 0x4c:
+ *ptr = (u32 *)&phy_reg3_val;
+ break;
+
+ case 0x4e:
+ *ptr = (u32 *)&sweep_pattern;
+ break;
+
+ case 0x50:
+ *ptr = (u32 *)&is_rzq6;
+ break;
+
+ case 0x51:
+ *ptr = (u32 *)&znri_data_phy_val;
+ break;
+
+ case 0x52:
+ *ptr = (u32 *)&zpri_data_phy_val;
+ break;
+
+ case 0x53:
+ *ptr = (u32 *)&finger_test;
+ break;
+
+ case 0x54:
+ *ptr = (u32 *)&n_finger_start;
+ break;
+
+ case 0x55:
+ *ptr = (u32 *)&n_finger_end;
+ break;
+
+ case 0x56:
+ *ptr = (u32 *)&p_finger_start;
+ break;
+
+ case 0x57:
+ *ptr = (u32 *)&p_finger_end;
+ break;
+
+ case 0x58:
+ *ptr = (u32 *)&p_finger_step;
+ break;
+
+ case 0x59:
+ *ptr = (u32 *)&n_finger_step;
+ break;
+
+ case 0x5a:
+ *ptr = (u32 *)&znri_ctrl_phy_val;
+ break;
+
+ case 0x5b:
+ *ptr = (u32 *)&zpri_ctrl_phy_val;
+ break;
+
+ case 0x5c:
+ *ptr = (u32 *)&is_reg_dump;
+ break;
+
+ case 0x5d:
+ *ptr = (u32 *)&vref;
+ break;
+
+ case 0x5e:
+ *ptr = (u32 *)&mode2_t;
+ break;
+
+ case 0x5f:
+ *ptr = (u32 *)&xsb_validate_type;
+ break;
+
+ case 0x60:
+ *ptr = (u32 *)&xsb_validation_base_address;
+ break;
+
+ case 0x67:
+ *ptr = (u32 *)&activate_select_before_run_alg;
+ break;
+
+ case 0x68:
+ *ptr = (u32 *)&activate_deselect_after_run_alg;
+ break;
+
+ case 0x69:
+ *ptr = (u32 *)&odt_additional;
+ break;
+
+ case 0x70:
+ *ptr = (u32 *)&debug_mode;
+ break;
+
+ case 0x71:
+ *ptr = (u32 *)&pbs_pattern;
+ break;
+
+ case 0x72:
+ *ptr = (u32 *)&delay_enable;
+ break;
+
+ case 0x73:
+ *ptr = (u32 *)&ck_delay;
+ break;
+
+ case 0x74:
+ *ptr = (u32 *)&ck_delay_16;
+ break;
+
+ case 0x75:
+ *ptr = (u32 *)&ca_delay;
+ break;
+
+ case 0x100:
+ *ptr = (u32 *)&debug_dunit;
+ break;
+
+ case 0x101:
+ debug_acc = (int)value;
+ break;
+
+ case 0x102:
+ debug_training = (u8)value;
+ break;
+
+ case 0x103:
+ debug_training_bist = (u8)value;
+ break;
+
+ case 0x104:
+ debug_centralization = (u8)value;
+ break;
+
+ case 0x105:
+ debug_training_ip = (u8)value;
+ break;
+
+ case 0x106:
+ debug_leveling = (u8)value;
+ break;
+
+ case 0x107:
+ debug_pbs = (u8)value;
+ break;
+
+ case 0x108:
+ debug_training_static = (u8)value;
+ break;
+
+ case 0x109:
+ debug_training_access = (u8)value;
+ break;
+
+ case 0x112:
+ *ptr = &start_pattern;
+ break;
+
+ case 0x113:
+ *ptr = &end_pattern;
+ break;
+
+ default:
+ if ((flag_id >= 0x200) && (flag_id < 0x210)) {
+ if_id = flag_id - 0x200;
+ *ptr = (u32 *)&(tm->interface_params
+ [if_id].memory_freq);
+ } else if ((flag_id >= 0x210) && (flag_id < 0x220)) {
+ if_id = flag_id - 0x210;
+ *ptr = (u32 *)&(tm->interface_params
+ [if_id].speed_bin_index);
+ } else if ((flag_id >= 0x220) && (flag_id < 0x230)) {
+ if_id = flag_id - 0x220;
+ *ptr = (u32 *)&(tm->interface_params
+ [if_id].bus_width);
+ } else if ((flag_id >= 0x230) && (flag_id < 0x240)) {
+ if_id = flag_id - 0x230;
+ *ptr = (u32 *)&(tm->interface_params
+ [if_id].memory_size);
+ } else if ((flag_id >= 0x240) && (flag_id < 0x250)) {
+ if_id = flag_id - 0x240;
+ *ptr = (u32 *)&(tm->interface_params
+ [if_id].cas_l);
+ } else if ((flag_id >= 0x250) && (flag_id < 0x260)) {
+ if_id = flag_id - 0x250;
+ *ptr = (u32 *)&(tm->interface_params
+ [if_id].cas_wl);
+ } else if ((flag_id >= 0x270) && (flag_id < 0x2cf)) {
+ if_id = (flag_id - 0x270) / MAX_BUS_NUM;
+ pup_id = (flag_id - 0x270) % MAX_BUS_NUM;
+ *ptr = (u32 *)&(tm->interface_params[if_id].
+ as_bus_params[pup_id].is_ck_swap);
+ } else if ((flag_id >= 0x2d0) && (flag_id < 0x32f)) {
+ if_id = (flag_id - 0x2d0) / MAX_BUS_NUM;
+ pup_id = (flag_id - 0x2d0) % MAX_BUS_NUM;
+ *ptr = (u32 *)&(tm->interface_params[if_id].
+ as_bus_params[pup_id].is_dqs_swap);
+ } else if ((flag_id >= 0x330) && (flag_id < 0x38f)) {
+ if_id = (flag_id - 0x330) / MAX_BUS_NUM;
+ pup_id = (flag_id - 0x330) % MAX_BUS_NUM;
+ *ptr = (u32 *)&(tm->interface_params[if_id].
+ as_bus_params[pup_id].cs_bitmask);
+ } else if ((flag_id >= 0x390) && (flag_id < 0x3ef)) {
+ if_id = (flag_id - 0x390) / MAX_BUS_NUM;
+ pup_id = (flag_id - 0x390) % MAX_BUS_NUM;
+ *ptr = (u32 *)&(tm->interface_params
+ [if_id].as_bus_params
+ [pup_id].mirror_enable_bitmask);
+ } else if ((flag_id >= 0x500) && (flag_id <= 0x50f)) {
+ tmp_val = flag_id - 0x320;
+ *ptr = (u32 *)&(clamp_tbl[tmp_val]);
+ } else {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("flag_id out of boundary %d\n",
+ flag_id));
+ return MV_BAD_PARAM;
+ }
+ }
+
+ return MV_OK;
+}
+
+#ifndef EXCLUDE_SWITCH_DEBUG
+/*
+ * Print ADLL
+ */
+int print_adll(u32 dev_num, u32 adll[MAX_INTERFACE_NUM * MAX_BUS_NUM])
+{
+ u32 i, j;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ dev_num = dev_num;
+
+ for (j = 0; j < tm->num_of_bus_per_interface; j++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, j);
+ for (i = 0; i < MAX_INTERFACE_NUM; i++) {
+ printf("%d ,",
+ adll[i * tm->num_of_bus_per_interface + j]);
+ }
+ }
+ printf("\n");
+
+ return MV_OK;
+}
+#endif
+
+/* byte_index - only byte 0, 1, 2, or 3, oxff - test all bytes */
+static u32 ddr3_tip_compare(u32 if_id, u32 *p_src, u32 *p_dst,
+ u32 byte_index)
+{
+ u32 burst_cnt = 0, addr_offset, i_id;
+ int b_is_fail = 0;
+
+ addr_offset =
+ (byte_index ==
+ 0xff) ? (u32) 0xffffffff : (u32) (0xff << (byte_index * 8));
+ for (burst_cnt = 0; burst_cnt < EXT_ACCESS_BURST_LENGTH; burst_cnt++) {
+ if ((p_src[burst_cnt] & addr_offset) !=
+ (p_dst[burst_cnt] & addr_offset))
+ b_is_fail = 1;
+ }
+
+ if (b_is_fail == 1) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("IF %d exp: ", if_id));
+ for (i_id = 0; i_id <= MAX_INTERFACE_NUM - 1; i_id++) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("0x%8x ", p_src[i_id]));
+ }
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("\n_i_f %d rcv: ", if_id));
+ for (i_id = 0; i_id <= MAX_INTERFACE_NUM - 1; i_id++) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("(0x%8x ", p_dst[i_id]));
+ }
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR, ("\n "));
+ }
+
+ return b_is_fail;
+}
+
+/* test_type = 0-tx , 1-rx */
+int ddr3_tip_sweep_test(u32 dev_num, u32 test_type,
+ u32 mem_addr, u32 is_modify_adll,
+ u32 start_if, u32 end_if, u32 startpup, u32 endpup)
+{
+ u32 bus_cnt = 0, adll_val = 0, if_id, ui_prev_adll, ui_mask_bit,
+ end_adll, start_adll;
+ u32 reg_addr = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ mem_addr = mem_addr;
+
+ if (test_type == 0) {
+ reg_addr = 1;
+ ui_mask_bit = 0x3f;
+ start_adll = 0;
+ end_adll = ui_mask_bit;
+ } else {
+ reg_addr = 3;
+ ui_mask_bit = 0x1f;
+ start_adll = 0;
+ end_adll = ui_mask_bit;
+ }
+
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("==============================\n"));
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("Test type %d (0-tx, 1-rx)\n", test_type));
+
+ for (if_id = start_if; if_id <= end_if; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_cnt = startpup; bus_cnt < endpup; bus_cnt++) {
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST,
+ bus_cnt, DDR_PHY_DATA, reg_addr,
+ &ui_prev_adll));
+
+ for (adll_val = start_adll; adll_val <= end_adll;
+ adll_val++) {
+ if (is_modify_adll == 1) {
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id, bus_cnt,
+ DDR_PHY_DATA, reg_addr,
+ adll_val, ui_mask_bit));
+ }
+ }
+ if (is_modify_adll == 1) {
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ bus_cnt, DDR_PHY_DATA, reg_addr,
+ ui_prev_adll));
+ }
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("\n"));
+ }
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("\n"));
+ }
+
+ return MV_OK;
+}
+
+#ifndef EXCLUDE_SWITCH_DEBUG
+/*
+ * Sweep validation
+ */
+int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
+ u32 mode)
+{
+ u32 pup = 0, start_pup = 0, end_pup = 0;
+ u32 adll = 0;
+ u32 res[MAX_INTERFACE_NUM] = { 0 };
+ int if_id = 0;
+ u32 adll_value = 0;
+ int reg = (direction == 0) ? WRITE_CENTRALIZATION_PHY_REG :
+ READ_CENTRALIZATION_PHY_REG;
+ enum hws_access_type pup_access;
+ u32 cs;
+ u32 max_cs = hws_ddr3_tip_max_cs_get();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ repeat_num = repeat_num;
+
+ if (mode == 1) {
+ /* per pup */
+ start_pup = 0;
+ end_pup = tm->num_of_bus_per_interface - 1;
+ pup_access = ACCESS_TYPE_UNICAST;
+ } else {
+ start_pup = 0;
+ end_pup = 0;
+ pup_access = ACCESS_TYPE_MULTICAST;
+ }
+
+ for (cs = 0; cs < max_cs; cs++) {
+ for (adll = 0; adll < ADLL_LENGTH; adll++) {
+ for (if_id = 0;
+ if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE
+ (tm->if_act_mask,
+ if_id);
+ for (pup = start_pup; pup <= end_pup; pup++) {
+ ctrl_sweepres[adll][if_id][pup] =
+ 0;
+ }
+ }
+ }
+
+ for (adll = 0; adll < (MAX_INTERFACE_NUM * MAX_BUS_NUM); adll++)
+ ctrl_adll[adll] = 0;
+ /* Save DQS value(after algorithm run) */
+ read_adll_value(ctrl_adll,
+ (reg + (cs * CS_REGISTER_ADDR_OFFSET)),
+ MASK_ALL_BITS);
+
+ /*
+ * Sweep ADLL from 0:31 on all I/F on all Pup and perform
+ * BIST on each stage.
+ */
+ for (pup = start_pup; pup <= end_pup; pup++) {
+ for (adll = 0; adll < ADLL_LENGTH; adll++) {
+ adll_value =
+ (direction == 0) ? (adll * 2) : adll;
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, 0,
+ pup_access, pup, DDR_PHY_DATA,
+ reg + CS_REG_VALUE(cs),
+ adll_value));
+ hws_ddr3_run_bist(dev_num, sweep_pattern, res,
+ cs);
+ /* ddr3_tip_reset_fifo_ptr(dev_num); */
+ for (if_id = 0;
+ if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE
+ (tm->if_act_mask,
+ if_id);
+ ctrl_sweepres[adll][if_id][pup]
+ = res[if_id];
+ if (mode == 1) {
+ CHECK_STATUS
+ (ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ pup,
+ DDR_PHY_DATA,
+ reg + CS_REG_VALUE(cs),
+ ctrl_adll[if_id *
+ cs *
+ tm->num_of_bus_per_interface
+ + pup]));
+ }
+ }
+ }
+ }
+ printf("Final, CS %d,%s, Sweep, Result, Adll,", cs,
+ ((direction == 0) ? "TX" : "RX"));
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (mode == 1) {
+ for (pup = start_pup; pup <= end_pup; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ printf("I/F%d-PHY%d , ", if_id, pup);
+ }
+ } else {
+ printf("I/F%d , ", if_id);
+ }
+ }
+ printf("\n");
+
+ for (adll = 0; adll < ADLL_LENGTH; adll++) {
+ adll_value = (direction == 0) ? (adll * 2) : adll;
+ printf("Final,%s, Sweep, Result, %d ,",
+ ((direction == 0) ? "TX" : "RX"), adll_value);
+
+ for (if_id = 0;
+ if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (pup = start_pup; pup <= end_pup; pup++) {
+ printf("%d , ",
+ ctrl_sweepres[adll][if_id]
+ [pup]);
+ }
+ }
+ printf("\n");
+ }
+
+ /*
+ * Write back to the phy the Rx DQS value, we store in
+ * the beginning.
+ */
+ write_adll_value(ctrl_adll,
+ (reg + cs * CS_REGISTER_ADDR_OFFSET));
+ /* print adll results */
+ read_adll_value(ctrl_adll, (reg + cs * CS_REGISTER_ADDR_OFFSET),
+ MASK_ALL_BITS);
+ printf("%s, DQS, ADLL,,,", (direction == 0) ? "Tx" : "Rx");
+ print_adll(dev_num, ctrl_adll);
+ }
+ ddr3_tip_reset_fifo_ptr(dev_num);
+
+ return 0;
+}
+
+void print_topology(struct hws_topology_map *topology_db)
+{
+ u32 ui, uj;
+
+ printf("\tinterface_mask: 0x%x\n", topology_db->if_act_mask);
+ printf("\tNum Bus: %d\n", topology_db->num_of_bus_per_interface);
+ printf("\tbus_act_mask: 0x%x\n", topology_db->bus_act_mask);
+
+ for (ui = 0; ui < MAX_INTERFACE_NUM; ui++) {
+ VALIDATE_ACTIVE(topology_db->if_act_mask, ui);
+ printf("\n\tInterface ID: %d\n", ui);
+ printf("\t\tDDR Frequency: %s\n",
+ convert_freq(topology_db->
+ interface_params[ui].memory_freq));
+ printf("\t\tSpeed_bin: %d\n",
+ topology_db->interface_params[ui].speed_bin_index);
+ printf("\t\tBus_width: %d\n",
+ (4 << topology_db->interface_params[ui].bus_width));
+ printf("\t\tMem_size: %s\n",
+ convert_mem_size(topology_db->
+ interface_params[ui].memory_size));
+ printf("\t\tCAS-WL: %d\n",
+ topology_db->interface_params[ui].cas_wl);
+ printf("\t\tCAS-L: %d\n",
+ topology_db->interface_params[ui].cas_l);
+ printf("\t\tTemperature: %d\n",
+ topology_db->interface_params[ui].interface_temp);
+ printf("\n");
+ for (uj = 0; uj < 4; uj++) {
+ printf("\t\tBus %d parameters- CS Mask: 0x%x\t", uj,
+ topology_db->interface_params[ui].
+ as_bus_params[uj].cs_bitmask);
+ printf("Mirror: 0x%x\t",
+ topology_db->interface_params[ui].
+ as_bus_params[uj].mirror_enable_bitmask);
+ printf("DQS Swap is %s \t",
+ (topology_db->
+ interface_params[ui].as_bus_params[uj].
+ is_dqs_swap == 1) ? "enabled" : "disabled");
+ printf("Ck Swap:%s\t",
+ (topology_db->
+ interface_params[ui].as_bus_params[uj].
+ is_ck_swap == 1) ? "enabled" : "disabled");
+ printf("\n");
+ }
+ }
+}
+#endif
+
+/*
+ * Execute XSB Test transaction (rd/wr/both)
+ */
+int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type,
+ u32 read_type, u32 burst_length)
+{
+ u32 seq = 0, if_id = 0, addr, cnt;
+ int ret = MV_OK, ret_tmp;
+ u32 data_read[MAX_INTERFACE_NUM];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ addr = mem_addr;
+ for (cnt = 0; cnt <= burst_length; cnt++) {
+ seq = (seq + 1) % 8;
+ if (write_type != 0) {
+ CHECK_STATUS(ddr3_tip_ext_write
+ (dev_num, if_id, addr, 1,
+ xsb_test_table[seq]));
+ }
+ if (read_type != 0) {
+ CHECK_STATUS(ddr3_tip_ext_read
+ (dev_num, if_id, addr, 1,
+ data_read));
+ }
+ if ((read_type != 0) && (write_type != 0)) {
+ ret_tmp =
+ ddr3_tip_compare(if_id,
+ xsb_test_table[seq],
+ data_read,
+ 0xff);
+ addr += (EXT_ACCESS_BURST_LENGTH * 4);
+ ret = (ret != MV_OK) ? ret : ret_tmp;
+ }
+ }
+ }
+
+ return ret;
+}
+
+#else /*EXCLUDE_SWITCH_DEBUG */
+
+u32 rl_version = 1; /* 0 - old RL machine */
+u32 vref = 0x4;
+u32 start_xsb_offset = 0;
+u8 cs_mask_reg[] = {
+ 0, 4, 8, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type,
+ u32 read_type, u32 burst_length)
+{
+ return MV_OK;
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#define REG_READ_DATA_SAMPLE_DELAYS_ADDR 0x1538
+#define REG_READ_DATA_SAMPLE_DELAYS_MASK 0x1f
+#define REG_READ_DATA_SAMPLE_DELAYS_OFFS 8
+
+#define REG_READ_DATA_READY_DELAYS_ADDR 0x153c
+#define REG_READ_DATA_READY_DELAYS_MASK 0x1f
+#define REG_READ_DATA_READY_DELAYS_OFFS 8
+
+int ddr3_if_ecc_enabled(void)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask) ||
+ DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
+ return 1;
+ else
+ return 0;
+}
+
+int ddr3_pre_algo_config(void)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* Set Bus3 ECC training mode */
+ if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask)) {
+ /* Set Bus3 ECC MUX */
+ CHECK_STATUS(ddr3_tip_if_write
+ (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+ REG_SDRAM_PINS_MUX, 0x100, 0x100));
+ }
+
+ /* Set regular ECC training mode (bus4 and bus 3) */
+ if ((DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask)) ||
+ (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))) {
+ /* Enable ECC Write MUX */
+ CHECK_STATUS(ddr3_tip_if_write
+ (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x100, 0x100));
+ /* General ECC enable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+ REG_SDRAM_CONFIG_ADDR, 0x40000, 0x40000));
+ /* Disable Read Data ECC MUX */
+ CHECK_STATUS(ddr3_tip_if_write
+ (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x0, 0x2));
+ }
+
+ return MV_OK;
+}
+
+int ddr3_post_algo_config(void)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+ int status;
+
+ status = ddr3_post_run_alg();
+ if (MV_OK != status) {
+ printf("DDR3 Post Run Alg - FAILED 0x%x\n", status);
+ return status;
+ }
+
+ /* Un_set ECC training mode */
+ if ((DDR3_IS_ECC_PUP4_MODE(tm->bus_act_mask)) ||
+ (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))) {
+ /* Disable ECC Write MUX */
+ CHECK_STATUS(ddr3_tip_if_write
+ (0, ACCESS_TYPE_UNICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x0, 0x100));
+ /* General ECC and Bus3 ECC MUX remains enabled */
+ }
+
+ return MV_OK;
+}
+
+int ddr3_hws_hw_training(void)
+{
+ enum hws_algo_type algo_mode = ALGO_TYPE_DYNAMIC;
+ int status;
+ struct init_cntr_param init_param;
+
+ status = ddr3_silicon_pre_init();
+ if (MV_OK != status) {
+ printf("DDR3 Pre silicon Config - FAILED 0x%x\n", status);
+ return status;
+ }
+
+ init_param.do_mrs_phy = 1;
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
+ init_param.is_ctrl64_bit = 0;
+#else
+ init_param.is_ctrl64_bit = 1;
+#endif
+#if defined(CONFIG_ALLEYCAT3) || defined(CONFIG_ARMADA_38X) || \
+ defined(CONFIG_ARMADA_39X)
+ init_param.init_phy = 1;
+#else
+ init_param.init_phy = 0;
+#endif
+ init_param.msys_init = 1;
+ status = hws_ddr3_tip_init_controller(0, &init_param);
+ if (MV_OK != status) {
+ printf("DDR3 init controller - FAILED 0x%x\n", status);
+ return status;
+ }
+
+ status = ddr3_silicon_post_init();
+ if (MV_OK != status) {
+ printf("DDR3 Post Init - FAILED 0x%x\n", status);
+ return status;
+ }
+
+ status = ddr3_pre_algo_config();
+ if (MV_OK != status) {
+ printf("DDR3 Pre Algo Config - FAILED 0x%x\n", status);
+ return status;
+ }
+
+ /* run algorithm in order to configure the PHY */
+ status = hws_ddr3_tip_run_alg(0, algo_mode);
+ if (MV_OK != status) {
+ printf("DDR3 run algorithm - FAILED 0x%x\n", status);
+ return status;
+ }
+
+ status = ddr3_post_algo_config();
+ if (MV_OK != status) {
+ printf("DDR3 Post Algo Config - FAILED 0x%x\n", status);
+ return status;
+ }
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_HWS_HW_TRAINING_H
+#define _DDR3_HWS_HW_TRAINING_H
+
+/* struct used for DLB configuration array */
+struct dlb_config {
+ u32 reg_addr;
+ u32 reg_data;
+};
+
+/* Topology update structure */
+struct topology_update_info {
+ int update_ecc;
+ u8 ecc;
+ int update_width;
+ u8 width;
+ int update_ecc_pup3_mode;
+ u8 ecc_pup_mode_offset;
+};
+
+/* Topology update defines */
+#define TOPOLOGY_UPDATE_WIDTH_16BIT 1
+#define TOPOLOGY_UPDATE_WIDTH_32BIT 0
+#define TOPOLOGY_UPDATE_WIDTH_32BIT_MASK 0xf
+#define TOPOLOGY_UPDATE_WIDTH_16BIT_MASK 0x3
+
+#define TOPOLOGY_UPDATE_ECC_ON 1
+#define TOPOLOGY_UPDATE_ECC_OFF 0
+#define TOPOLOGY_UPDATE_ECC_OFFSET_PUP4 4
+#define TOPOLOGY_UPDATE_ECC_OFFSET_PUP3 3
+
+/*
+ * 1. L2 filter should be set at binary header to 0xd000000,
+ * to avoid conflict with internal register IO.
+ * 2. U-Boot modifies internal registers base to 0xf100000,
+ * and than should update L2 filter accordingly to 0xf000000 (3.75 GB)
+ */
+/* temporary limit l2 filter to 3GiB (LSP issue) */
+#define L2_FILTER_FOR_MAX_MEMORY_SIZE 0xc0000000
+#define ADDRESS_FILTERING_END_REGISTER 0x8c04
+
+#define SUB_VERSION 0
+
+#endif /* _DDR3_HWS_HW_TRAINING_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_HWS_HW_TRAINING_DEF_H
+#define _DDR3_HWS_HW_TRAINING_DEF_H
+
+#define SAR_DDR3_FREQ_MASK 0xfe00000
+#define SAR_CPU_FAB_GET(cpu, fab) (((cpu & 0x7) << 21) | \
+ ((fab & 0xf) << 24))
+
+#define MAX_CS 4
+
+#define MIN_DIMM_ADDR 0x50
+#define FAR_END_DIMM_ADDR 0x50
+#define MAX_DIMM_ADDR 0x60
+
+#define SDRAM_CS_SIZE 0xfffffff
+#define SDRAM_CS_BASE 0x0
+#define SDRAM_DIMM_SIZE 0x80000000
+
+#define CPU_CONFIGURATION_REG(id) (0x21800 + (id * 0x100))
+#define CPU_MRVL_ID_OFFSET 0x10
+#define SAR1_CPU_CORE_MASK 0x00000018
+#define SAR1_CPU_CORE_OFFSET 3
+
+#define NEW_FABRIC_TWSI_ADDR 0x4e
+#ifdef DB_784MP_GP
+#define BUS_WIDTH_ECC_TWSI_ADDR 0x4e
+#else
+#define BUS_WIDTH_ECC_TWSI_ADDR 0x4f
+#endif
+#define MV_MAX_DDR3_STATIC_SIZE 50
+#define MV_DDR3_MODES_NUMBER 30
+
+#define RESUME_RL_PATTERNS_ADDR 0xfe0000
+#define RESUME_RL_PATTERNS_SIZE 0x100
+#define RESUME_TRAINING_VALUES_ADDR (RESUME_RL_PATTERNS_ADDR + \
+ RESUME_RL_PATTERNS_SIZE)
+#define RESUME_TRAINING_VALUES_MAX 0xcd0
+#define BOOT_INFO_ADDR (RESUME_RL_PATTERNS_ADDR + 0x1000)
+#define CHECKSUM_RESULT_ADDR (BOOT_INFO_ADDR + 0x1000)
+#define NUM_OF_REGISTER_ADDR (CHECKSUM_RESULT_ADDR + 4)
+#define SUSPEND_MAGIC_WORD 0xdeadb002
+#define REGISTER_LIST_END 0xffffffff
+
+/* MISC */
+#define INTER_REGS_BASE SOC_REGS_PHY_BASE
+
+/* DDR */
+#define REG_SDRAM_CONFIG_ADDR 0x1400
+#define REG_SDRAM_CONFIG_MASK 0x9fffffff
+#define REG_SDRAM_CONFIG_RFRS_MASK 0x3fff
+#define REG_SDRAM_CONFIG_WIDTH_OFFS 15
+#define REG_SDRAM_CONFIG_REGDIMM_OFFS 17
+#define REG_SDRAM_CONFIG_ECC_OFFS 18
+#define REG_SDRAM_CONFIG_IERR_OFFS 19
+#define REG_SDRAM_CONFIG_PUPRSTDIV_OFFS 28
+#define REG_SDRAM_CONFIG_RSTRD_OFFS 30
+
+#define REG_SDRAM_PINS_MUX 0x19d4
+
+#define REG_DUNIT_CTRL_LOW_ADDR 0x1404
+#define REG_DUNIT_CTRL_LOW_2T_OFFS 3
+#define REG_DUNIT_CTRL_LOW_2T_MASK 0x3
+#define REG_DUNIT_CTRL_LOW_DPDE_OFFS 14
+
+#define REG_SDRAM_TIMING_LOW_ADDR 0x1408
+#define REG_SDRAM_TIMING_HIGH_ADDR 0x140c
+#define REG_SDRAM_TIMING_H_R2R_OFFS 7
+#define REG_SDRAM_TIMING_H_R2R_MASK 0x3
+#define REG_SDRAM_TIMING_H_R2W_W2R_OFFS 9
+#define REG_SDRAM_TIMING_H_R2W_W2R_MASK 0x3
+#define REG_SDRAM_TIMING_H_W2W_OFFS 11
+#define REG_SDRAM_TIMING_H_W2W_MASK 0x1f
+#define REG_SDRAM_TIMING_H_R2R_H_OFFS 19
+#define REG_SDRAM_TIMING_H_R2R_H_MASK 0x7
+#define REG_SDRAM_TIMING_H_R2W_W2R_H_OFFS 22
+#define REG_SDRAM_TIMING_H_R2W_W2R_H_MASK 0x7
+
+#define REG_SDRAM_ADDRESS_CTRL_ADDR 0x1410
+#define REG_SDRAM_ADDRESS_SIZE_OFFS 2
+#define REG_SDRAM_ADDRESS_SIZE_HIGH_OFFS 18
+#define REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS 4
+
+#define REG_SDRAM_OPEN_PAGES_ADDR 0x1414
+#define REG_SDRAM_OPERATION_CS_OFFS 8
+
+#define REG_SDRAM_OPERATION_ADDR 0x1418
+#define REG_SDRAM_OPERATION_CWA_DELAY_SEL_OFFS 24
+#define REG_SDRAM_OPERATION_CWA_DATA_OFFS 20
+#define REG_SDRAM_OPERATION_CWA_DATA_MASK 0xf
+#define REG_SDRAM_OPERATION_CWA_RC_OFFS 16
+#define REG_SDRAM_OPERATION_CWA_RC_MASK 0xf
+#define REG_SDRAM_OPERATION_CMD_MR0 0xf03
+#define REG_SDRAM_OPERATION_CMD_MR1 0xf04
+#define REG_SDRAM_OPERATION_CMD_MR2 0xf08
+#define REG_SDRAM_OPERATION_CMD_MR3 0xf09
+#define REG_SDRAM_OPERATION_CMD_RFRS 0xf02
+#define REG_SDRAM_OPERATION_CMD_CWA 0xf0e
+#define REG_SDRAM_OPERATION_CMD_RFRS_DONE 0xf
+#define REG_SDRAM_OPERATION_CMD_MASK 0xf
+#define REG_SDRAM_OPERATION_CS_OFFS 8
+
+#define REG_OUDDR3_TIMING_ADDR 0x142c
+
+#define REG_SDRAM_MODE_ADDR 0x141c
+
+#define REG_SDRAM_EXT_MODE_ADDR 0x1420
+
+#define REG_DDR_CONT_HIGH_ADDR 0x1424
+
+#define REG_ODT_TIME_LOW_ADDR 0x1428
+#define REG_ODT_ON_CTL_RD_OFFS 12
+#define REG_ODT_OFF_CTL_RD_OFFS 16
+#define REG_SDRAM_ERROR_ADDR 0x1454
+#define REG_SDRAM_AUTO_PWR_SAVE_ADDR 0x1474
+#define REG_ODT_TIME_HIGH_ADDR 0x147c
+
+#define REG_SDRAM_INIT_CTRL_ADDR 0x1480
+#define REG_SDRAM_INIT_CTRL_OFFS 0
+#define REG_SDRAM_INIT_CKE_ASSERT_OFFS 2
+#define REG_SDRAM_INIT_RESET_DEASSERT_OFFS 3
+#define REG_SDRAM_INIT_RESET_MASK_OFFS 1
+
+#define REG_SDRAM_ODT_CTRL_LOW_ADDR 0x1494
+
+#define REG_SDRAM_ODT_CTRL_HIGH_ADDR 0x1498
+#define REG_SDRAM_ODT_CTRL_HIGH_OVRD_MASK 0x0
+#define REG_SDRAM_ODT_CTRL_HIGH_OVRD_ENA 0x3
+
+#define REG_DUNIT_ODT_CTRL_ADDR 0x149c
+#define REG_DUNIT_ODT_CTRL_OVRD_OFFS 8
+#define REG_DUNIT_ODT_CTRL_OVRD_VAL_OFFS 9
+
+#define REG_DRAM_FIFO_CTRL_ADDR 0x14a0
+
+#define REG_DRAM_AXI_CTRL_ADDR 0x14a8
+#define REG_DRAM_AXI_CTRL_AXIDATABUSWIDTH_OFFS 0
+
+#define REG_METAL_MASK_ADDR 0x14b0
+#define REG_METAL_MASK_MASK 0xdfffffff
+#define REG_METAL_MASK_RETRY_OFFS 0
+
+#define REG_DRAM_ADDR_CTRL_DRIVE_STRENGTH_ADDR 0x14c0
+
+#define REG_DRAM_DATA_DQS_DRIVE_STRENGTH_ADDR 0x14c4
+#define REG_DRAM_VER_CAL_MACHINE_CTRL_ADDR 0x14c8
+#define REG_DRAM_MAIN_PADS_CAL_ADDR 0x14cc
+
+#define REG_DRAM_HOR_CAL_MACHINE_CTRL_ADDR 0x17c8
+
+#define REG_CS_SIZE_SCRATCH_ADDR 0x1504
+#define REG_DYNAMIC_POWER_SAVE_ADDR 0x1520
+#define REG_DDR_IO_ADDR 0x1524
+#define REG_DDR_IO_CLK_RATIO_OFFS 15
+
+#define REG_DFS_ADDR 0x1528
+#define REG_DFS_DLLNEXTSTATE_OFFS 0
+#define REG_DFS_BLOCK_OFFS 1
+#define REG_DFS_SR_OFFS 2
+#define REG_DFS_ATSR_OFFS 3
+#define REG_DFS_RECONF_OFFS 4
+#define REG_DFS_CL_NEXT_STATE_OFFS 8
+#define REG_DFS_CL_NEXT_STATE_MASK 0xf
+#define REG_DFS_CWL_NEXT_STATE_OFFS 12
+#define REG_DFS_CWL_NEXT_STATE_MASK 0x7
+
+#define REG_READ_DATA_SAMPLE_DELAYS_ADDR 0x1538
+#define REG_READ_DATA_SAMPLE_DELAYS_MASK 0x1f
+#define REG_READ_DATA_SAMPLE_DELAYS_OFFS 8
+
+#define REG_READ_DATA_READY_DELAYS_ADDR 0x153c
+#define REG_READ_DATA_READY_DELAYS_MASK 0x1f
+#define REG_READ_DATA_READY_DELAYS_OFFS 8
+
+#define START_BURST_IN_ADDR 1
+
+#define REG_DRAM_TRAINING_SHADOW_ADDR 0x18488
+#define REG_DRAM_TRAINING_ADDR 0x15b0
+#define REG_DRAM_TRAINING_LOW_FREQ_OFFS 0
+#define REG_DRAM_TRAINING_PATTERNS_OFFS 4
+#define REG_DRAM_TRAINING_MED_FREQ_OFFS 2
+#define REG_DRAM_TRAINING_WL_OFFS 3
+#define REG_DRAM_TRAINING_RL_OFFS 6
+#define REG_DRAM_TRAINING_DQS_RX_OFFS 15
+#define REG_DRAM_TRAINING_DQS_TX_OFFS 16
+#define REG_DRAM_TRAINING_CS_OFFS 20
+#define REG_DRAM_TRAINING_RETEST_OFFS 24
+#define REG_DRAM_TRAINING_DFS_FREQ_OFFS 27
+#define REG_DRAM_TRAINING_DFS_REQ_OFFS 29
+#define REG_DRAM_TRAINING_ERROR_OFFS 30
+#define REG_DRAM_TRAINING_AUTO_OFFS 31
+#define REG_DRAM_TRAINING_RETEST_PAR 0x3
+#define REG_DRAM_TRAINING_RETEST_MASK 0xf8ffffff
+#define REG_DRAM_TRAINING_CS_MASK 0xff0fffff
+#define REG_DRAM_TRAINING_PATTERNS_MASK 0xff0f0000
+
+#define REG_DRAM_TRAINING_1_ADDR 0x15b4
+#define REG_DRAM_TRAINING_1_TRNBPOINT_OFFS 16
+
+#define REG_DRAM_TRAINING_2_ADDR 0x15b8
+#define REG_DRAM_TRAINING_2_OVERRUN_OFFS 17
+#define REG_DRAM_TRAINING_2_FIFO_RST_OFFS 4
+#define REG_DRAM_TRAINING_2_RL_MODE_OFFS 3
+#define REG_DRAM_TRAINING_2_WL_MODE_OFFS 2
+#define REG_DRAM_TRAINING_2_ECC_MUX_OFFS 1
+#define REG_DRAM_TRAINING_2_SW_OVRD_OFFS 0
+
+#define REG_DRAM_TRAINING_PATTERN_BASE_ADDR 0x15bc
+#define REG_DRAM_TRAINING_PATTERN_BASE_OFFS 3
+
+#define REG_TRAINING_DEBUG_2_ADDR 0x15c4
+#define REG_TRAINING_DEBUG_2_OFFS 16
+#define REG_TRAINING_DEBUG_2_MASK 0x3
+
+#define REG_TRAINING_DEBUG_3_ADDR 0x15c8
+#define REG_TRAINING_DEBUG_3_OFFS 3
+#define REG_TRAINING_DEBUG_3_MASK 0x7
+
+#define MR_CS_ADDR_OFFS 4
+
+#define REG_DDR3_MR0_ADDR 0x15d0
+#define REG_DDR3_MR0_CS_ADDR 0x1870
+#define REG_DDR3_MR0_CL_MASK 0x74
+#define REG_DDR3_MR0_CL_OFFS 2
+#define REG_DDR3_MR0_CL_HIGH_OFFS 3
+#define CL_MASK 0xf
+
+#define REG_DDR3_MR1_ADDR 0x15d4
+#define REG_DDR3_MR1_CS_ADDR 0x1874
+#define REG_DDR3_MR1_RTT_MASK 0xfffffdbb
+#define REG_DDR3_MR1_DLL_ENA_OFFS 0
+#define REG_DDR3_MR1_RTT_DISABLED 0x0
+#define REG_DDR3_MR1_RTT_RZQ2 0x40
+#define REG_DDR3_MR1_RTT_RZQ4 0x2
+#define REG_DDR3_MR1_RTT_RZQ6 0x42
+#define REG_DDR3_MR1_RTT_RZQ8 0x202
+#define REG_DDR3_MR1_RTT_RZQ12 0x4
+/* WL-disabled, OB-enabled */
+#define REG_DDR3_MR1_OUTBUF_WL_MASK 0xffffef7f
+/* Output Buffer Disabled */
+#define REG_DDR3_MR1_OUTBUF_DIS_OFFS 12
+#define REG_DDR3_MR1_WL_ENA_OFFS 7
+#define REG_DDR3_MR1_WL_ENA 0x80 /* WL Enabled */
+#define REG_DDR3_MR1_ODT_MASK 0xfffffdbb
+
+#define REG_DDR3_MR2_ADDR 0x15d8
+#define REG_DDR3_MR2_CS_ADDR 0x1878
+#define REG_DDR3_MR2_CWL_OFFS 3
+#define REG_DDR3_MR2_CWL_MASK 0x7
+#define REG_DDR3_MR2_ODT_MASK 0xfffff9ff
+#define REG_DDR3_MR3_ADDR 0x15dc
+#define REG_DDR3_MR3_CS_ADDR 0x187c
+
+#define REG_DDR3_RANK_CTRL_ADDR 0x15e0
+#define REG_DDR3_RANK_CTRL_CS_ENA_MASK 0xf
+#define REG_DDR3_RANK_CTRL_MIRROR_OFFS 4
+
+#define REG_ZQC_CONF_ADDR 0x15e4
+
+#define REG_DRAM_PHY_CONFIG_ADDR 0x15ec
+#define REG_DRAM_PHY_CONFIG_MASK 0x3fffffff
+
+#define REG_ODPG_CNTRL_ADDR 0x1600
+#define REG_ODPG_CNTRL_OFFS 21
+
+#define REG_PHY_LOCK_MASK_ADDR 0x1670
+#define REG_PHY_LOCK_MASK_MASK 0xfffff000
+
+#define REG_PHY_LOCK_STATUS_ADDR 0x1674
+#define REG_PHY_LOCK_STATUS_LOCK_OFFS 9
+#define REG_PHY_LOCK_STATUS_LOCK_MASK 0xfff
+#define REG_PHY_LOCK_APLL_ADLL_STATUS_MASK 0x7ff
+
+#define REG_PHY_REGISTRY_FILE_ACCESS_ADDR 0x16a0
+#define REG_PHY_REGISTRY_FILE_ACCESS_OP_WR 0xc0000000
+#define REG_PHY_REGISTRY_FILE_ACCESS_OP_RD 0x80000000
+#define REG_PHY_REGISTRY_FILE_ACCESS_OP_DONE 0x80000000
+#define REG_PHY_BC_OFFS 27
+#define REG_PHY_CNTRL_OFFS 26
+#define REG_PHY_CS_OFFS 16
+#define REG_PHY_DQS_REF_DLY_OFFS 10
+#define REG_PHY_PHASE_OFFS 8
+#define REG_PHY_PUP_OFFS 22
+
+#define REG_TRAINING_WL_ADDR 0x16ac
+#define REG_TRAINING_WL_CS_MASK 0xfffffffc
+#define REG_TRAINING_WL_UPD_OFFS 2
+#define REG_TRAINING_WL_CS_DONE_OFFS 3
+#define REG_TRAINING_WL_RATIO_MASK 0xffffff0f
+#define REG_TRAINING_WL_1TO1 0x50
+#define REG_TRAINING_WL_2TO1 0x10
+#define REG_TRAINING_WL_DELAYEXP_MASK 0x20000000
+#define REG_TRAINING_WL_RESULTS_MASK 0x000001ff
+#define REG_TRAINING_WL_RESULTS_OFFS 20
+
+#define REG_REGISTERED_DRAM_CTRL_ADDR 0x16d0
+#define REG_REGISTERED_DRAM_CTRL_SR_FLOAT_OFFS 15
+#define REG_REGISTERED_DRAM_CTRL_PARITY_MASK 0x3f
+
+/* DLB */
+#define REG_STATIC_DRAM_DLB_CONTROL 0x1700
+#define DLB_BUS_OPTIMIZATION_WEIGHTS_REG 0x1704
+#define DLB_AGING_REGISTER 0x1708
+#define DLB_EVICTION_CONTROL_REG 0x170c
+#define DLB_EVICTION_TIMERS_REGISTER_REG 0x1710
+#define DLB_USER_COMMAND_REG 0x1714
+#define DLB_BUS_WEIGHTS_DIFF_CS 0x1770
+#define DLB_BUS_WEIGHTS_DIFF_BG 0x1774
+#define DLB_BUS_WEIGHTS_SAME_BG 0x1778
+#define DLB_BUS_WEIGHTS_RD_WR 0x177c
+#define DLB_BUS_WEIGHTS_ATTR_SYS_PRIO 0x1780
+#define DLB_MAIN_QUEUE_MAP 0x1784
+#define DLB_LINE_SPLIT 0x1788
+
+#define DLB_ENABLE 0x1
+#define DLB_WRITE_COALESING (0x1 << 2)
+#define DLB_AXI_PREFETCH_EN (0x1 << 3)
+#define DLB_MBUS_PREFETCH_EN (0x1 << 4)
+#define PREFETCH_N_LN_SZ_TR (0x1 << 6)
+#define DLB_INTERJECTION_ENABLE (0x1 << 3)
+
+/* CPU */
+#define REG_BOOTROM_ROUTINE_ADDR 0x182d0
+#define REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS 12
+
+#define REG_DRAM_INIT_CTRL_STATUS_ADDR 0x18488
+#define REG_DRAM_INIT_CTRL_TRN_CLK_OFFS 16
+#define REG_CPU_DIV_CLK_CTRL_0_NEW_RATIO 0x000200ff
+#define REG_DRAM_INIT_CTRL_STATUS_2_ADDR 0x1488
+
+#define REG_CPU_DIV_CLK_CTRL_0_ADDR 0x18700
+
+#define REG_CPU_DIV_CLK_CTRL_1_ADDR 0x18704
+#define REG_CPU_DIV_CLK_CTRL_2_ADDR 0x18708
+
+#define REG_CPU_DIV_CLK_CTRL_3_ADDR 0x1870c
+#define REG_CPU_DIV_CLK_CTRL_3_FREQ_MASK 0xffffc0ff
+#define REG_CPU_DIV_CLK_CTRL_3_FREQ_OFFS 8
+
+#define REG_CPU_DIV_CLK_CTRL_4_ADDR 0x18710
+
+#define REG_CPU_DIV_CLK_STATUS_0_ADDR 0x18718
+#define REG_CPU_DIV_CLK_ALL_STABLE_OFFS 8
+
+#define REG_CPU_PLL_CTRL_0_ADDR 0x1871c
+#define REG_CPU_PLL_STATUS_0_ADDR 0x18724
+#define REG_CORE_DIV_CLK_CTRL_ADDR 0x18740
+#define REG_CORE_DIV_CLK_STATUS_ADDR 0x18744
+#define REG_DDRPHY_APLL_CTRL_ADDR 0x18780
+
+#define REG_DDRPHY_APLL_CTRL_2_ADDR 0x18784
+#define REG_SFABRIC_CLK_CTRL_ADDR 0x20858
+#define REG_SFABRIC_CLK_CTRL_SMPL_OFFS 8
+
+/* DRAM Windows */
+#define REG_XBAR_WIN_19_CTRL_ADDR 0x200e8
+#define REG_XBAR_WIN_4_CTRL_ADDR 0x20040
+#define REG_XBAR_WIN_4_BASE_ADDR 0x20044
+#define REG_XBAR_WIN_4_REMAP_ADDR 0x20048
+#define REG_FASTPATH_WIN_0_CTRL_ADDR 0x20184
+#define REG_XBAR_WIN_7_REMAP_ADDR 0x20078
+
+/* SRAM */
+#define REG_CDI_CONFIG_ADDR 0x20220
+#define REG_SRAM_WINDOW_0_ADDR 0x20240
+#define REG_SRAM_WINDOW_0_ENA_OFFS 0
+#define REG_SRAM_WINDOW_1_ADDR 0x20244
+#define REG_SRAM_L2_ENA_ADDR 0x8500
+#define REG_SRAM_CLEAN_BY_WAY_ADDR 0x87bc
+
+/* Timers */
+#define REG_TIMERS_CTRL_ADDR 0x20300
+#define REG_TIMERS_EVENTS_ADDR 0x20304
+#define REG_TIMER0_VALUE_ADDR 0x20314
+#define REG_TIMER1_VALUE_ADDR 0x2031c
+#define REG_TIMER0_ENABLE_MASK 0x1
+
+#define MV_BOARD_REFCLK_25MHZ 25000000
+#define CNTMR_RELOAD_REG(tmr) (REG_TIMERS_CTRL_ADDR + 0x10 + (tmr * 8))
+#define CNTMR_VAL_REG(tmr) (REG_TIMERS_CTRL_ADDR + 0x14 + (tmr * 8))
+#define CNTMR_CTRL_REG(tmr) (REG_TIMERS_CTRL_ADDR)
+#define CTCR_ARM_TIMER_EN_OFFS(timer) (timer * 2)
+#define CTCR_ARM_TIMER_EN_MASK(timer) (1 << CTCR_ARM_TIMER_EN_OFFS(timer))
+#define CTCR_ARM_TIMER_EN(timer) (1 << CTCR_ARM_TIMER_EN_OFFS(timer))
+
+#define CTCR_ARM_TIMER_AUTO_OFFS(timer) (1 + (timer * 2))
+#define CTCR_ARM_TIMER_AUTO_MASK(timer) (1 << CTCR_ARM_TIMER_EN_OFFS(timer))
+#define CTCR_ARM_TIMER_AUTO_EN(timer) (1 << CTCR_ARM_TIMER_AUTO_OFFS(timer))
+
+/* PMU */
+#define REG_PMU_I_F_CTRL_ADDR 0x1c090
+#define REG_PMU_DUNIT_BLK_OFFS 16
+#define REG_PMU_DUNIT_RFRS_OFFS 20
+#define REG_PMU_DUNIT_ACK_OFFS 24
+
+/* MBUS */
+#define MBUS_UNITS_PRIORITY_CONTROL_REG (MBUS_REGS_OFFSET + 0x420)
+#define FABRIC_UNITS_PRIORITY_CONTROL_REG (MBUS_REGS_OFFSET + 0x424)
+#define MBUS_UNITS_PREFETCH_CONTROL_REG (MBUS_REGS_OFFSET + 0x428)
+#define FABRIC_UNITS_PREFETCH_CONTROL_REG (MBUS_REGS_OFFSET + 0x42c)
+
+#define REG_PM_STAT_MASK_ADDR 0x2210c
+#define REG_PM_STAT_MASK_CPU0_IDLE_MASK_OFFS 16
+
+#define REG_PM_EVENT_STAT_MASK_ADDR 0x22120
+#define REG_PM_EVENT_STAT_MASK_DFS_DONE_OFFS 17
+
+#define REG_PM_CTRL_CONFIG_ADDR 0x22104
+#define REG_PM_CTRL_CONFIG_DFS_REQ_OFFS 18
+
+#define REG_FABRIC_LOCAL_IRQ_MASK_ADDR 0x218c4
+#define REG_FABRIC_LOCAL_IRQ_PMU_MASK_OFFS 18
+
+/* Controller revision info */
+#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
+#define PCCRIR_REVID_OFFS 0 /* Revision ID */
+#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
+
+/* Power Management Clock Gating Control Register */
+#define POWER_MNG_CTRL_REG 0x18220
+#define PEX_DEVICE_AND_VENDOR_ID 0x000
+#define PEX_CFG_DIRECT_ACCESS(if, reg) (PEX_IF_REGS_BASE(if) + (reg))
+#define PMC_PEXSTOPCLOCK_OFFS(p) ((p) < 8 ? (5 + (p)) : (18 + (p)))
+#define PMC_PEXSTOPCLOCK_MASK(p) (1 << PMC_PEXSTOPCLOCK_OFFS(p))
+#define PMC_PEXSTOPCLOCK_EN(p) (1 << PMC_PEXSTOPCLOCK_OFFS(p))
+#define PMC_PEXSTOPCLOCK_STOP(p) (0 << PMC_PEXSTOPCLOCK_OFFS(p))
+
+/* TWSI */
+#define TWSI_DATA_ADDR_MASK 0x7
+#define TWSI_DATA_ADDR_OFFS 1
+
+/* General */
+#define MAX_CS 4
+
+/* Frequencies */
+#define FAB_OPT 21
+#define CLK_CPU 12
+#define CLK_VCO (2 * CLK_CPU)
+#define CLK_DDR 12
+
+/* CPU Frequencies: */
+#define CLK_CPU_1000 0
+#define CLK_CPU_1066 1
+#define CLK_CPU_1200 2
+#define CLK_CPU_1333 3
+#define CLK_CPU_1500 4
+#define CLK_CPU_1666 5
+#define CLK_CPU_1800 6
+#define CLK_CPU_2000 7
+#define CLK_CPU_600 8
+#define CLK_CPU_667 9
+#define CLK_CPU_800 0xa
+
+/* Extra Cpu Frequencies: */
+#define CLK_CPU_1600 11
+#define CLK_CPU_2133 12
+#define CLK_CPU_2200 13
+#define CLK_CPU_2400 14
+
+#define SAR1_CPU_CORE_MASK 0x00000018
+#define SAR1_CPU_CORE_OFFSET 3
+
+#endif /* _DDR3_HWS_HW_TRAINING_DEF_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_HWS_SIL_TRAINING_H
+#define _DDR3_HWS_SIL_TRAINING_H
+
+#include "ddr3_training_ip.h"
+#include "ddr3_training_ip_prv_if.h"
+
+int ddr3_silicon_pre_config(void);
+int ddr3_silicon_init(void);
+int ddr3_silicon_get_ddr_target_freq(u32 *ddr_freq);
+
+#endif /* _DDR3_HWS_SIL_TRAINING_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#include "../../../../arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h"
+
+static struct dlb_config ddr3_dlb_config_table[] = {
+ {REG_STATIC_DRAM_DLB_CONTROL, 0x2000005c},
+ {DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0x00880000},
+ {DLB_AGING_REGISTER, 0x0f7f007f},
+ {DLB_EVICTION_CONTROL_REG, 0x0000129f},
+ {DLB_EVICTION_TIMERS_REGISTER_REG, 0x00ff0000},
+ {DLB_BUS_WEIGHTS_DIFF_CS, 0x04030802},
+ {DLB_BUS_WEIGHTS_DIFF_BG, 0x00000a02},
+ {DLB_BUS_WEIGHTS_SAME_BG, 0x09000a01},
+ {DLB_BUS_WEIGHTS_RD_WR, 0x00020005},
+ {DLB_BUS_WEIGHTS_ATTR_SYS_PRIO, 0x00060f10},
+ {DLB_MAIN_QUEUE_MAP, 0x00000543},
+ {DLB_LINE_SPLIT, 0x00000000},
+ {DLB_USER_COMMAND_REG, 0x00000000},
+ {0x0, 0x0}
+};
+
+static struct dlb_config ddr3_dlb_config_table_a0[] = {
+ {REG_STATIC_DRAM_DLB_CONTROL, 0x2000005c},
+ {DLB_BUS_OPTIMIZATION_WEIGHTS_REG, 0x00880000},
+ {DLB_AGING_REGISTER, 0x0f7f007f},
+ {DLB_EVICTION_CONTROL_REG, 0x0000129f},
+ {DLB_EVICTION_TIMERS_REGISTER_REG, 0x00ff0000},
+ {DLB_BUS_WEIGHTS_DIFF_CS, 0x04030802},
+ {DLB_BUS_WEIGHTS_DIFF_BG, 0x00000a02},
+ {DLB_BUS_WEIGHTS_SAME_BG, 0x09000a01},
+ {DLB_BUS_WEIGHTS_RD_WR, 0x00020005},
+ {DLB_BUS_WEIGHTS_ATTR_SYS_PRIO, 0x00060f10},
+ {DLB_MAIN_QUEUE_MAP, 0x00000543},
+ {DLB_LINE_SPLIT, 0x00000000},
+ {DLB_USER_COMMAND_REG, 0x00000000},
+ {0x0, 0x0}
+};
+
+#if defined(CONFIG_ARMADA_38X)
+struct dram_modes {
+ char *mode_name;
+ u8 cpu_freq;
+ u8 fab_freq;
+ u8 chip_id;
+ u8 chip_board_rev;
+ struct reg_data *regs;
+};
+
+struct dram_modes ddr_modes[] = {
+#ifdef SUPPORT_STATIC_DUNIT_CONFIG
+ /* Conf name, CPUFreq, Fab_freq, Chip ID, Chip/Board, MC regs*/
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+ {"a38x_customer_0_800", DDR_FREQ_800, 0, 0x0, A38X_CUSTOMER_BOARD_ID0,
+ ddr3_customer_800},
+ {"a38x_customer_1_800", DDR_FREQ_800, 0, 0x0, A38X_CUSTOMER_BOARD_ID1,
+ ddr3_customer_800},
+#else
+ {"a38x_533", DDR_FREQ_533, 0, 0x0, MARVELL_BOARD, ddr3_a38x_533},
+ {"a38x_667", DDR_FREQ_667, 0, 0x0, MARVELL_BOARD, ddr3_a38x_667},
+ {"a38x_800", DDR_FREQ_800, 0, 0x0, MARVELL_BOARD, ddr3_a38x_800},
+ {"a38x_933", DDR_FREQ_933, 0, 0x0, MARVELL_BOARD, ddr3_a38x_933},
+#endif
+#endif
+};
+#endif /* defined(CONFIG_ARMADA_38X) */
+
+/* Translates topology map definitions to real memory size in bits */
+u32 mem_size[] = {
+ ADDR_SIZE_512MB, ADDR_SIZE_1GB, ADDR_SIZE_2GB, ADDR_SIZE_4GB,
+ ADDR_SIZE_8GB
+};
+
+static char *ddr_type = "DDR3";
+
+/*
+ * Set 1 to use dynamic DUNIT configuration,
+ * set 0 (supported for A380 and AC3) to configure DUNIT in values set by
+ * ddr3_tip_init_specific_reg_config
+ */
+u8 generic_init_controller = 1;
+
+#ifdef SUPPORT_STATIC_DUNIT_CONFIG
+static u32 ddr3_get_static_ddr_mode(void);
+#endif
+static int ddr3_hws_tune_training_params(u8 dev_num);
+static int ddr3_update_topology_map(struct hws_topology_map *topology_map);
+
+/* device revision */
+#define DEV_VERSION_ID_REG 0x1823c
+#define REVISON_ID_OFFS 8
+#define REVISON_ID_MASK 0xf00
+
+/* A38x revisions */
+#define MV_88F68XX_Z1_ID 0x0
+#define MV_88F68XX_A0_ID 0x4
+/* A39x revisions */
+#define MV_88F69XX_Z1_ID 0x2
+
+/*
+ * sys_env_device_rev_get - Get Marvell controller device revision number
+ *
+ * DESCRIPTION:
+ * This function returns 8bit describing the device revision as defined
+ * Revision ID Register.
+ *
+ * INPUT:
+ * None.
+ *
+ * OUTPUT:
+ * None.
+ *
+ * RETURN:
+ * 8bit desscribing Marvell controller revision number
+ */
+u8 sys_env_device_rev_get(void)
+{
+ u32 value;
+
+ value = reg_read(DEV_VERSION_ID_REG);
+ return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS;
+}
+
+/*
+ * sys_env_dlb_config_ptr_get
+ *
+ * DESCRIPTION: defines pointer to to DLB COnfiguration table
+ *
+ * INPUT: none
+ *
+ * OUTPUT: pointer to DLB COnfiguration table
+ *
+ * RETURN:
+ * returns pointer to DLB COnfiguration table
+ */
+struct dlb_config *sys_env_dlb_config_ptr_get(void)
+{
+#ifdef CONFIG_ARMADA_39X
+ return &ddr3_dlb_config_table_a0[0];
+#else
+ if (sys_env_device_rev_get() == MV_88F68XX_A0_ID)
+ return &ddr3_dlb_config_table_a0[0];
+ else
+ return &ddr3_dlb_config_table[0];
+#endif
+}
+
+/*
+ * sys_env_get_cs_ena_from_reg
+ *
+ * DESCRIPTION: Get bit mask of enabled CS
+ *
+ * INPUT: None
+ *
+ * OUTPUT: None
+ *
+ * RETURN:
+ * Bit mask of enabled CS, 1 if only CS0 enabled,
+ * 3 if both CS0 and CS1 enabled
+ */
+u32 sys_env_get_cs_ena_from_reg(void)
+{
+ return reg_read(REG_DDR3_RANK_CTRL_ADDR) &
+ REG_DDR3_RANK_CTRL_CS_ENA_MASK;
+}
+
+static void ddr3_restore_and_set_final_windows(u32 *win)
+{
+ u32 win_ctrl_reg, num_of_win_regs;
+ u32 cs_ena = sys_env_get_cs_ena_from_reg();
+ u32 ui;
+
+ win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR;
+ num_of_win_regs = 16;
+
+ /* Return XBAR windows 4-7 or 16-19 init configuration */
+ for (ui = 0; ui < num_of_win_regs; ui++)
+ reg_write((win_ctrl_reg + 0x4 * ui), win[ui]);
+
+ printf("%s Training Sequence - Switching XBAR Window to FastPath Window\n",
+ ddr_type);
+
+#if defined DYNAMIC_CS_SIZE_CONFIG
+ if (ddr3_fast_path_dynamic_cs_size_config(cs_ena) != MV_OK)
+ printf("ddr3_fast_path_dynamic_cs_size_config FAILED\n");
+#else
+ u32 reg, cs;
+ reg = 0x1fffffe1;
+ for (cs = 0; cs < MAX_CS; cs++) {
+ if (cs_ena & (1 << cs)) {
+ reg |= (cs << 2);
+ break;
+ }
+ }
+ /* Open fast path Window to - 0.5G */
+ reg_write(REG_FASTPATH_WIN_0_CTRL_ADDR, reg);
+#endif
+}
+
+static int ddr3_save_and_set_training_windows(u32 *win)
+{
+ u32 cs_ena;
+ u32 reg, tmp_count, cs, ui;
+ u32 win_ctrl_reg, win_base_reg, win_remap_reg;
+ u32 num_of_win_regs, win_jump_index;
+ win_ctrl_reg = REG_XBAR_WIN_4_CTRL_ADDR;
+ win_base_reg = REG_XBAR_WIN_4_BASE_ADDR;
+ win_remap_reg = REG_XBAR_WIN_4_REMAP_ADDR;
+ win_jump_index = 0x10;
+ num_of_win_regs = 16;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+#ifdef DISABLE_L2_FILTERING_DURING_DDR_TRAINING
+ /*
+ * Disable L2 filtering during DDR training
+ * (when Cross Bar window is open)
+ */
+ reg_write(ADDRESS_FILTERING_END_REGISTER, 0);
+#endif
+
+ cs_ena = tm->interface_params[0].as_bus_params[0].cs_bitmask;
+
+ /* Close XBAR Window 19 - Not needed */
+ /* {0x000200e8} - Open Mbus Window - 2G */
+ reg_write(REG_XBAR_WIN_19_CTRL_ADDR, 0);
+
+ /* Save XBAR Windows 4-19 init configurations */
+ for (ui = 0; ui < num_of_win_regs; ui++)
+ win[ui] = reg_read(win_ctrl_reg + 0x4 * ui);
+
+ /* Open XBAR Windows 4-7 or 16-19 for other CS */
+ reg = 0;
+ tmp_count = 0;
+ for (cs = 0; cs < MAX_CS; cs++) {
+ if (cs_ena & (1 << cs)) {
+ switch (cs) {
+ case 0:
+ reg = 0x0e00;
+ break;
+ case 1:
+ reg = 0x0d00;
+ break;
+ case 2:
+ reg = 0x0b00;
+ break;
+ case 3:
+ reg = 0x0700;
+ break;
+ }
+ reg |= (1 << 0);
+ reg |= (SDRAM_CS_SIZE & 0xffff0000);
+
+ reg_write(win_ctrl_reg + win_jump_index * tmp_count,
+ reg);
+ reg = (((SDRAM_CS_SIZE + 1) * (tmp_count)) &
+ 0xffff0000);
+ reg_write(win_base_reg + win_jump_index * tmp_count,
+ reg);
+
+ if (win_remap_reg <= REG_XBAR_WIN_7_REMAP_ADDR)
+ reg_write(win_remap_reg +
+ win_jump_index * tmp_count, 0);
+
+ tmp_count++;
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Name: ddr3_init - Main DDR3 Init function
+ * Desc: This routine initialize the DDR3 MC and runs HW training.
+ * Args: None.
+ * Notes:
+ * Returns: None.
+ */
+int ddr3_init(void)
+{
+ u32 reg = 0;
+ u32 soc_num;
+ int status;
+ u32 win[16];
+
+ /* SoC/Board special Initializtions */
+ /* Get version from internal library */
+ ddr3_print_version();
+
+ /*Add sub_version string */
+ DEBUG_INIT_C("", SUB_VERSION, 1);
+
+ /* Switching CPU to MRVL ID */
+ soc_num = (reg_read(REG_SAMPLE_RESET_HIGH_ADDR) & SAR1_CPU_CORE_MASK) >>
+ SAR1_CPU_CORE_OFFSET;
+ switch (soc_num) {
+ case 0x3:
+ reg_bit_set(CPU_CONFIGURATION_REG(3), CPU_MRVL_ID_OFFSET);
+ reg_bit_set(CPU_CONFIGURATION_REG(2), CPU_MRVL_ID_OFFSET);
+ case 0x1:
+ reg_bit_set(CPU_CONFIGURATION_REG(1), CPU_MRVL_ID_OFFSET);
+ case 0x0:
+ reg_bit_set(CPU_CONFIGURATION_REG(0), CPU_MRVL_ID_OFFSET);
+ default:
+ break;
+ }
+
+ /*
+ * Set DRAM Reset Mask in case detected GPIO indication of wakeup from
+ * suspend i.e the DRAM values will not be overwritten / reset when
+ * waking from suspend
+ */
+ if (sys_env_suspend_wakeup_check() ==
+ SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED) {
+ reg_bit_set(REG_SDRAM_INIT_CTRL_ADDR,
+ 1 << REG_SDRAM_INIT_RESET_MASK_OFFS);
+ }
+
+ /*
+ * Stage 0 - Set board configuration
+ */
+
+ /* Check if DRAM is already initialized */
+ if (reg_read(REG_BOOTROM_ROUTINE_ADDR) &
+ (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) {
+ printf("%s Training Sequence - 2nd boot - Skip\n", ddr_type);
+ return MV_OK;
+ }
+
+ /*
+ * Stage 1 - Dunit Setup
+ */
+
+ /* Fix read ready phases for all SOC in reg 0x15c8 */
+ reg = reg_read(REG_TRAINING_DEBUG_3_ADDR);
+ reg &= ~(REG_TRAINING_DEBUG_3_MASK);
+ reg |= 0x4; /* Phase 0 */
+ reg &= ~(REG_TRAINING_DEBUG_3_MASK << REG_TRAINING_DEBUG_3_OFFS);
+ reg |= (0x4 << (1 * REG_TRAINING_DEBUG_3_OFFS)); /* Phase 1 */
+ reg &= ~(REG_TRAINING_DEBUG_3_MASK << (3 * REG_TRAINING_DEBUG_3_OFFS));
+ reg |= (0x6 << (3 * REG_TRAINING_DEBUG_3_OFFS)); /* Phase 3 */
+ reg &= ~(REG_TRAINING_DEBUG_3_MASK << (4 * REG_TRAINING_DEBUG_3_OFFS));
+ reg |= (0x6 << (4 * REG_TRAINING_DEBUG_3_OFFS));
+ reg &= ~(REG_TRAINING_DEBUG_3_MASK << (5 * REG_TRAINING_DEBUG_3_OFFS));
+ reg |= (0x6 << (5 * REG_TRAINING_DEBUG_3_OFFS));
+ reg_write(REG_TRAINING_DEBUG_3_ADDR, reg);
+
+ /*
+ * Axi_bresp_mode[8] = Compliant,
+ * Axi_addr_decode_cntrl[11] = Internal,
+ * Axi_data_bus_width[0] = 128bit
+ * */
+ /* 0x14a8 - AXI Control Register */
+ reg_write(REG_DRAM_AXI_CTRL_ADDR, 0);
+
+ /*
+ * Stage 2 - Training Values Setup
+ */
+ /* Set X-BAR windows for the training sequence */
+ ddr3_save_and_set_training_windows(win);
+
+#ifdef SUPPORT_STATIC_DUNIT_CONFIG
+ /*
+ * Load static controller configuration (in case dynamic/generic init
+ * is not enabled
+ */
+ if (generic_init_controller == 0) {
+ ddr3_tip_init_specific_reg_config(0,
+ ddr_modes
+ [ddr3_get_static_ddr_mode
+ ()].regs);
+ }
+#endif
+
+ /* Load topology for New Training IP */
+ status = ddr3_load_topology_map();
+ if (MV_OK != status) {
+ printf("%s Training Sequence topology load - FAILED\n",
+ ddr_type);
+ return status;
+ }
+
+ /* Tune training algo paramteres */
+ status = ddr3_hws_tune_training_params(0);
+ if (MV_OK != status)
+ return status;
+
+ /* Set log level for training lib */
+ ddr3_hws_set_log_level(DEBUG_BLOCK_ALL, DEBUG_LEVEL_ERROR);
+
+ /* Start New Training IP */
+ status = ddr3_hws_hw_training();
+ if (MV_OK != status) {
+ printf("%s Training Sequence - FAILED\n", ddr_type);
+ return status;
+ }
+
+ /*
+ * Stage 3 - Finish
+ */
+ /* Restore and set windows */
+ ddr3_restore_and_set_final_windows(win);
+
+ /* Update DRAM init indication in bootROM register */
+ reg = reg_read(REG_BOOTROM_ROUTINE_ADDR);
+ reg_write(REG_BOOTROM_ROUTINE_ADDR,
+ reg | (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS));
+
+ /* DLB config */
+ ddr3_new_tip_dlb_config();
+
+#if defined(ECC_SUPPORT)
+ if (ddr3_if_ecc_enabled())
+ ddr3_new_tip_ecc_scrub();
+#endif
+
+ printf("%s Training Sequence - Ended Successfully\n", ddr_type);
+
+ return MV_OK;
+}
+
+/*
+ * Name: ddr3_get_cpu_freq
+ * Desc: read S@R and return CPU frequency
+ * Args:
+ * Notes:
+ * Returns: required value
+ */
+u32 ddr3_get_cpu_freq(void)
+{
+ return ddr3_tip_get_init_freq();
+}
+
+/*
+ * Name: ddr3_get_fab_opt
+ * Desc: read S@R and return CPU frequency
+ * Args:
+ * Notes:
+ * Returns: required value
+ */
+u32 ddr3_get_fab_opt(void)
+{
+ return 0; /* No fabric */
+}
+
+/*
+ * Name: ddr3_get_static_m_cValue - Init Memory controller with
+ * static parameters
+ * Desc: Use this routine to init the controller without the HW training
+ * procedure.
+ * User must provide compatible header file with registers data.
+ * Args: None.
+ * Notes:
+ * Returns: None.
+ */
+u32 ddr3_get_static_mc_value(u32 reg_addr, u32 offset1, u32 mask1,
+ u32 offset2, u32 mask2)
+{
+ u32 reg, temp;
+
+ reg = reg_read(reg_addr);
+
+ temp = (reg >> offset1) & mask1;
+ if (mask2)
+ temp |= (reg >> offset2) & mask2;
+
+ return temp;
+}
+
+/*
+ * Name: ddr3_get_static_ddr_mode - Init Memory controller with
+ * static parameters
+ * Desc: Use this routine to init the controller without the HW training
+ * procedure.
+ * User must provide compatible header file with registers data.
+ * Args: None.
+ * Notes:
+ * Returns: None.
+ */
+u32 ddr3_get_static_ddr_mode(void)
+{
+ u32 chip_board_rev, i;
+ u32 size;
+
+ /* Valid only for A380 only, MSYS using dynamic controller config */
+#ifdef CONFIG_CUSTOMER_BOARD_SUPPORT
+ /*
+ * Customer boards select DDR mode according to
+ * board ID & Sample@Reset
+ */
+ chip_board_rev = mv_board_id_get();
+#else
+ /* Marvell boards select DDR mode according to Sample@Reset only */
+ chip_board_rev = MARVELL_BOARD;
+#endif
+
+ size = ARRAY_SIZE(ddr_modes);
+ for (i = 0; i < size; i++) {
+ if ((ddr3_get_cpu_freq() == ddr_modes[i].cpu_freq) &&
+ (ddr3_get_fab_opt() == ddr_modes[i].fab_freq) &&
+ (chip_board_rev == ddr_modes[i].chip_board_rev))
+ return i;
+ }
+
+ DEBUG_INIT_S("\n*** Error: ddr3_get_static_ddr_mode: No match for requested DDR mode. ***\n\n");
+
+ return 0;
+}
+
+/******************************************************************************
+ * Name: ddr3_get_cs_num_from_reg
+ * Desc:
+ * Args:
+ * Notes:
+ * Returns:
+ */
+u32 ddr3_get_cs_num_from_reg(void)
+{
+ u32 cs_ena = sys_env_get_cs_ena_from_reg();
+ u32 cs_count = 0;
+ u32 cs;
+
+ for (cs = 0; cs < MAX_CS; cs++) {
+ if (cs_ena & (1 << cs))
+ cs_count++;
+ }
+
+ return cs_count;
+}
+
+/*
+ * Name: ddr3_load_topology_map
+ * Desc:
+ * Args:
+ * Notes:
+ * Returns:
+ */
+int ddr3_load_topology_map(void)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+#if defined(MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI)
+ /* Update topology data */
+ if (MV_OK != ddr3_update_topology_map(tm)) {
+ DEBUG_INIT_FULL_S("Failed update of DDR3 Topology map\n");
+ }
+#endif
+
+ return MV_OK;
+}
+
+void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps)
+{
+ u32 tmp, hclk = 200;
+
+ switch (freq_mode) {
+ case 4:
+ tmp = 1; /* DDR_400; */
+ hclk = 200;
+ break;
+ case 0x8:
+ tmp = 1; /* DDR_666; */
+ hclk = 333;
+ break;
+ case 0xc:
+ tmp = 1; /* DDR_800; */
+ hclk = 400;
+ break;
+ default:
+ *ddr_freq = 0;
+ *hclk_ps = 0;
+ break;
+ }
+
+ *ddr_freq = tmp; /* DDR freq define */
+ *hclk_ps = 1000000 / hclk; /* values are 1/HCLK in ps */
+
+ return;
+}
+
+void ddr3_new_tip_dlb_config(void)
+{
+ u32 reg, i = 0;
+ struct dlb_config *config_table_ptr = sys_env_dlb_config_ptr_get();
+
+ /* Write the configuration */
+ while (config_table_ptr[i].reg_addr != 0) {
+ reg_write(config_table_ptr[i].reg_addr,
+ config_table_ptr[i].reg_data);
+ i++;
+ }
+
+ /* Enable DLB */
+ reg = reg_read(REG_STATIC_DRAM_DLB_CONTROL);
+ reg |= DLB_ENABLE | DLB_WRITE_COALESING | DLB_AXI_PREFETCH_EN |
+ DLB_MBUS_PREFETCH_EN | PREFETCH_N_LN_SZ_TR;
+ reg_write(REG_STATIC_DRAM_DLB_CONTROL, reg);
+}
+
+int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena)
+{
+ u32 reg, cs;
+ u32 mem_total_size = 0;
+ u32 cs_mem_size = 0;
+ u32 mem_total_size_c, cs_mem_size_c;
+
+#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
+ u32 physical_mem_size;
+ u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+#endif
+
+ /* Open fast path windows */
+ for (cs = 0; cs < MAX_CS; cs++) {
+ if (cs_ena & (1 << cs)) {
+ /* get CS size */
+ if (ddr3_calc_mem_cs_size(cs, &cs_mem_size) != MV_OK)
+ return MV_FAIL;
+
+#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
+ /*
+ * if number of address pins doesn't allow to use max
+ * mem size that is defined in topology
+ * mem size is defined by DEVICE_MAX_DRAM_ADDRESS_SIZE
+ */
+ physical_mem_size = mem_size
+ [tm->interface_params[0].memory_size];
+
+ if (ddr3_get_device_width(cs) == 16) {
+ /*
+ * 16bit mem device can be twice more - no need
+ * in less significant pin
+ */
+ max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE * 2;
+ }
+
+ if (physical_mem_size > max_mem_size) {
+ cs_mem_size = max_mem_size *
+ (ddr3_get_bus_width() /
+ ddr3_get_device_width(cs));
+ printf("Updated Physical Mem size is from 0x%x to %x\n",
+ physical_mem_size,
+ DEVICE_MAX_DRAM_ADDRESS_SIZE);
+ }
+#endif
+
+ /* set fast path window control for the cs */
+ reg = 0xffffe1;
+ reg |= (cs << 2);
+ reg |= (cs_mem_size - 1) & 0xffff0000;
+ /*Open fast path Window */
+ reg_write(REG_FASTPATH_WIN_CTRL_ADDR(cs), reg);
+
+ /* Set fast path window base address for the cs */
+ reg = ((cs_mem_size) * cs) & 0xffff0000;
+ /* Set base address */
+ reg_write(REG_FASTPATH_WIN_BASE_ADDR(cs), reg);
+
+ /*
+ * Since memory size may be bigger than 4G the summ may
+ * be more than 32 bit word,
+ * so to estimate the result divide mem_total_size and
+ * cs_mem_size by 0x10000 (it is equal to >> 16)
+ */
+ mem_total_size_c = mem_total_size >> 16;
+ cs_mem_size_c = cs_mem_size >> 16;
+ /* if the sum less than 2 G - calculate the value */
+ if (mem_total_size_c + cs_mem_size_c < 0x10000)
+ mem_total_size += cs_mem_size;
+ else /* put max possible size */
+ mem_total_size = L2_FILTER_FOR_MAX_MEMORY_SIZE;
+ }
+ }
+
+ /* Set L2 filtering to Max Memory size */
+ reg_write(ADDRESS_FILTERING_END_REGISTER, mem_total_size);
+
+ return MV_OK;
+}
+
+u32 ddr3_get_bus_width(void)
+{
+ u32 bus_width;
+
+ bus_width = (reg_read(REG_SDRAM_CONFIG_ADDR) & 0x8000) >>
+ REG_SDRAM_CONFIG_WIDTH_OFFS;
+
+ return (bus_width == 0) ? 16 : 32;
+}
+
+u32 ddr3_get_device_width(u32 cs)
+{
+ u32 device_width;
+
+ device_width = (reg_read(REG_SDRAM_ADDRESS_CTRL_ADDR) &
+ (0x3 << (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs))) >>
+ (REG_SDRAM_ADDRESS_CTRL_STRUCT_OFFS * cs);
+
+ return (device_width == 0) ? 8 : 16;
+}
+
+float ddr3_get_device_size(u32 cs)
+{
+ u32 device_size_low, device_size_high, device_size;
+ u32 data, cs_low_offset, cs_high_offset;
+
+ cs_low_offset = REG_SDRAM_ADDRESS_SIZE_OFFS + cs * 4;
+ cs_high_offset = REG_SDRAM_ADDRESS_SIZE_OFFS +
+ REG_SDRAM_ADDRESS_SIZE_HIGH_OFFS + cs;
+
+ data = reg_read(REG_SDRAM_ADDRESS_CTRL_ADDR);
+ device_size_low = (data >> cs_low_offset) & 0x3;
+ device_size_high = (data >> cs_high_offset) & 0x1;
+
+ device_size = device_size_low | (device_size_high << 2);
+
+ switch (device_size) {
+ case 0:
+ return 2;
+ case 2:
+ return 0.5;
+ case 3:
+ return 1;
+ case 4:
+ return 4;
+ case 5:
+ return 8;
+ case 1:
+ default:
+ DEBUG_INIT_C("Error: Wrong device size of Cs: ", cs, 1);
+ /*
+ * Small value will give wrong emem size in
+ * ddr3_calc_mem_cs_size
+ */
+ return 0.01;
+ }
+}
+
+int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size)
+{
+ float cs_mem_size;
+
+ /* Calculate in GiB */
+ cs_mem_size = ((ddr3_get_bus_width() / ddr3_get_device_width(cs)) *
+ ddr3_get_device_size(cs)) / 8;
+
+ /*
+ * Multiple controller bus width, 2x for 64 bit
+ * (SoC controller may be 32 or 64 bit,
+ * so bit 15 in 0x1400, that means if whole bus used or only half,
+ * have a differnt meaning
+ */
+ cs_mem_size *= DDR_CONTROLLER_BUS_WIDTH_MULTIPLIER;
+
+ if (cs_mem_size == 0.125) {
+ *cs_size = 128 << 20;
+ } else if (cs_mem_size == 0.25) {
+ *cs_size = 256 << 20;
+ } else if (cs_mem_size == 0.5) {
+ *cs_size = 512 << 20;
+ } else if (cs_mem_size == 1) {
+ *cs_size = 1 << 30;
+ } else if (cs_mem_size == 2) {
+ *cs_size = 2 << 30;
+ } else {
+ DEBUG_INIT_C("Error: Wrong Memory size of Cs: ", cs, 1);
+ return MV_BAD_VALUE;
+ }
+
+ return MV_OK;
+}
+
+#if defined(MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI)
+/*
+ * Name: ddr3_update_topology_map
+ * Desc:
+ * Args:
+ * Notes: Update topology map by Sat_r values
+ * Returns:
+ */
+static int ddr3_update_topology_map(struct hws_topology_map *tm)
+{
+ struct topology_update_info topology_update_info;
+
+ topology_update_info.update_width = 0;
+ topology_update_info.update_ecc = 0;
+ topology_update_info.update_ecc_pup3_mode = 0;
+ sys_env_get_topology_update_info(&topology_update_info);
+ if (topology_update_info.update_width) {
+ tm->bus_act_mask &=
+ ~(TOPOLOGY_UPDATE_WIDTH_32BIT_MASK);
+ if (topology_update_info.width == TOPOLOGY_UPDATE_WIDTH_16BIT)
+ tm->bus_act_mask =
+ TOPOLOGY_UPDATE_WIDTH_16BIT_MASK;
+ else
+ tm->bus_act_mask =
+ TOPOLOGY_UPDATE_WIDTH_32BIT_MASK;
+ }
+
+ if (topology_update_info.update_ecc) {
+ if (topology_update_info.ecc == TOPOLOGY_UPDATE_ECC_OFF) {
+ tm->bus_act_mask &=
+ ~(1 << topology_update_info.ecc_pup_mode_offset);
+ } else {
+ tm->bus_act_mask |=
+ topology_update_info.
+ ecc << topology_update_info.ecc_pup_mode_offset;
+ }
+ }
+
+ return MV_OK;
+}
+#endif
+
+/*
+ * Name: ddr3_hws_tune_training_params
+ * Desc:
+ * Args:
+ * Notes: Tune internal training params
+ * Returns:
+ */
+static int ddr3_hws_tune_training_params(u8 dev_num)
+{
+ struct tune_train_params params;
+ int status;
+
+ /* NOTE: do not remove any field initilization */
+ params.ck_delay = TUNE_TRAINING_PARAMS_CK_DELAY;
+ params.ck_delay_16 = TUNE_TRAINING_PARAMS_CK_DELAY_16;
+ params.p_finger = TUNE_TRAINING_PARAMS_PFINGER;
+ params.n_finger = TUNE_TRAINING_PARAMS_NFINGER;
+ params.phy_reg3_val = TUNE_TRAINING_PARAMS_PHYREG3VAL;
+
+ status = ddr3_tip_tune_training_params(dev_num, ¶ms);
+ if (MV_OK != status) {
+ printf("%s Training Sequence - FAILED\n", ddr_type);
+ return status;
+ }
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_INIT_H
+#define _DDR3_INIT_H
+
+#if defined(CONFIG_ARMADA_38X)
+#include "ddr3_a38x.h"
+#include "ddr3_a38x_mc_static.h"
+#include "ddr3_a38x_topology.h"
+#endif
+#include "ddr3_hws_hw_training.h"
+#include "ddr3_hws_sil_training.h"
+#include "ddr3_logging_def.h"
+#include "ddr3_training_hw_algo.h"
+#include "ddr3_training_ip.h"
+#include "ddr3_training_ip_centralization.h"
+#include "ddr3_training_ip_engine.h"
+#include "ddr3_training_ip_flow.h"
+#include "ddr3_training_ip_pbs.h"
+#include "ddr3_training_ip_prv_if.h"
+#include "ddr3_training_ip_static.h"
+#include "ddr3_training_leveling.h"
+#include "xor.h"
+
+/*
+ * MV_DEBUG_INIT need to be defines, otherwise the output of the
+ * DDR2 training code is not complete and misleading
+ */
+#define MV_DEBUG_INIT
+
+#define BIT(x) (1 << (x))
+
+#ifdef MV_DEBUG_INIT
+#define DEBUG_INIT_S(s) puts(s)
+#define DEBUG_INIT_D(d, l) printf("%x", d)
+#define DEBUG_INIT_D_10(d, l) printf("%d", d)
+#else
+#define DEBUG_INIT_S(s)
+#define DEBUG_INIT_D(d, l)
+#define DEBUG_INIT_D_10(d, l)
+#endif
+
+#ifdef MV_DEBUG_INIT_FULL
+#define DEBUG_INIT_FULL_S(s) puts(s)
+#define DEBUG_INIT_FULL_D(d, l) printf("%x", d)
+#define DEBUG_INIT_FULL_D_10(d, l) printf("%d", d)
+#define DEBUG_WR_REG(reg, val) \
+ { DEBUG_INIT_S("Write Reg: 0x"); DEBUG_INIT_D((reg), 8); \
+ DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); }
+#define DEBUG_RD_REG(reg, val) \
+ { DEBUG_INIT_S("Read Reg: 0x"); DEBUG_INIT_D((reg), 8); \
+ DEBUG_INIT_S("= "); DEBUG_INIT_D((val), 8); DEBUG_INIT_S("\n"); }
+#else
+#define DEBUG_INIT_FULL_S(s)
+#define DEBUG_INIT_FULL_D(d, l)
+#define DEBUG_INIT_FULL_D_10(d, l)
+#define DEBUG_WR_REG(reg, val)
+#define DEBUG_RD_REG(reg, val)
+#endif
+
+#define DEBUG_INIT_FULL_C(s, d, l) \
+ { DEBUG_INIT_FULL_S(s); \
+ DEBUG_INIT_FULL_D(d, l); \
+ DEBUG_INIT_FULL_S("\n"); }
+#define DEBUG_INIT_C(s, d, l) \
+ { DEBUG_INIT_S(s); DEBUG_INIT_D(d, l); DEBUG_INIT_S("\n"); }
+
+/*
+ * Debug (Enable/Disable modules) and Error report
+ */
+
+#ifdef BASIC_DEBUG
+#define MV_DEBUG_WL
+#define MV_DEBUG_RL
+#define MV_DEBUG_DQS_RESULTS
+#endif
+
+#ifdef FULL_DEBUG
+#define MV_DEBUG_WL
+#define MV_DEBUG_RL
+#define MV_DEBUG_DQS
+
+#define MV_DEBUG_PBS
+#define MV_DEBUG_DFS
+#define MV_DEBUG_MAIN_FULL
+#define MV_DEBUG_DFS_FULL
+#define MV_DEBUG_DQS_FULL
+#define MV_DEBUG_RL_FULL
+#define MV_DEBUG_WL_FULL
+#endif
+
+#if defined(CONFIG_ARMADA_38X)
+#include "ddr3_a38x.h"
+#include "ddr3_a38x_topology.h"
+#endif
+
+/* The following is a list of Marvell status */
+#define MV_ERROR (-1)
+#define MV_OK (0x00) /* Operation succeeded */
+#define MV_FAIL (0x01) /* Operation failed */
+#define MV_BAD_VALUE (0x02) /* Illegal value (general) */
+#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */
+#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */
+#define MV_BAD_PTR (0x05) /* Illegal pointer value */
+#define MV_BAD_SIZE (0x06) /* Illegal size */
+#define MV_BAD_STATE (0x07) /* Illegal state of state machine */
+#define MV_SET_ERROR (0x08) /* Set operation failed */
+#define MV_GET_ERROR (0x09) /* Get operation failed */
+#define MV_CREATE_ERROR (0x0a) /* Fail while creating an item */
+#define MV_NOT_FOUND (0x0b) /* Item not found */
+#define MV_NO_MORE (0x0c) /* No more items found */
+#define MV_NO_SUCH (0x0d) /* No such item */
+#define MV_TIMEOUT (0x0e) /* Time Out */
+#define MV_NO_CHANGE (0x0f) /* Parameter(s) is already in this value */
+#define MV_NOT_SUPPORTED (0x10) /* This request is not support */
+#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented*/
+#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */
+#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */
+#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */
+#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */
+#define MV_INIT_ERROR (0x16) /* Error occured while INIT process */
+#define MV_HW_ERROR (0x17) /* Hardware error */
+#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */
+#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */
+#define MV_NOT_READY (0x1a) /* The other side is not ready yet */
+#define MV_ALREADY_EXIST (0x1b) /* Tried to create existing item */
+#define MV_OUT_OF_CPU_MEM (0x1c) /* Cpu memory allocation failed. */
+#define MV_NOT_STARTED (0x1d) /* Not started yet */
+#define MV_BUSY (0x1e) /* Item is busy. */
+#define MV_TERMINATE (0x1f) /* Item terminates it's work. */
+#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */
+#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */
+#define MV_WRITE_PROTECT (0x22) /* Write protected */
+#define MV_INVALID (int)(-1)
+
+/* For checking function return values */
+#define CHECK_STATUS(orig_func) \
+ { \
+ int status; \
+ status = orig_func; \
+ if (MV_OK != status) \
+ return status; \
+ }
+
+enum log_level {
+ MV_LOG_LEVEL_0,
+ MV_LOG_LEVEL_1,
+ MV_LOG_LEVEL_2,
+ MV_LOG_LEVEL_3
+};
+
+/* Globals */
+extern u8 debug_training;
+extern u8 is_reg_dump;
+extern u8 generic_init_controller;
+extern u32 freq_val[];
+extern u32 is_pll_old;
+extern struct cl_val_per_freq cas_latency_table[];
+extern struct pattern_info pattern_table[];
+extern struct cl_val_per_freq cas_write_latency_table[];
+extern u8 debug_training;
+extern u8 debug_centralization, debug_training_ip, debug_training_bist,
+ debug_pbs, debug_training_static, debug_leveling;
+extern u32 pipe_multicast_mask;
+extern struct hws_tip_config_func_db config_func_info[];
+extern u8 cs_mask_reg[];
+extern u8 twr_mask_table[];
+extern u8 cl_mask_table[];
+extern u8 cwl_mask_table[];
+extern u16 rfc_table[];
+extern u32 speed_bin_table_t_rc[];
+extern u32 speed_bin_table_t_rcd_t_rp[];
+extern u32 ck_delay, ck_delay_16;
+
+extern u32 g_zpri_data;
+extern u32 g_znri_data;
+extern u32 g_zpri_ctrl;
+extern u32 g_znri_ctrl;
+extern u32 g_zpodt_data;
+extern u32 g_znodt_data;
+extern u32 g_zpodt_ctrl;
+extern u32 g_znodt_ctrl;
+extern u32 g_dic;
+extern u32 g_odt_config;
+extern u32 g_rtt_nom;
+
+extern u8 debug_training_access;
+extern u8 debug_training_a38x;
+extern u32 first_active_if;
+extern enum hws_ddr_freq init_freq;
+extern u32 delay_enable, ck_delay, ck_delay_16, ca_delay;
+extern u32 mask_tune_func;
+extern u32 rl_version;
+extern int rl_mid_freq_wa;
+extern u8 calibration_update_control; /* 2 external only, 1 is internal only */
+extern enum hws_ddr_freq medium_freq;
+
+extern u32 ck_delay, ck_delay_16;
+extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
+extern u32 first_active_if;
+extern u32 mask_tune_func;
+extern u32 freq_val[];
+extern enum hws_ddr_freq init_freq;
+extern enum hws_ddr_freq low_freq;
+extern enum hws_ddr_freq medium_freq;
+extern u8 generic_init_controller;
+extern enum auto_tune_stage training_stage;
+extern u32 is_pll_before_init;
+extern u32 is_adll_calib_before_init;
+extern u32 is_dfs_in_init;
+extern int wl_debug_delay;
+extern u32 silicon_delay[HWS_MAX_DEVICE_NUM];
+extern u32 p_finger;
+extern u32 n_finger;
+extern u32 freq_val[DDR_FREQ_LIMIT];
+extern u32 start_pattern, end_pattern;
+extern u32 phy_reg0_val;
+extern u32 phy_reg1_val;
+extern u32 phy_reg2_val;
+extern u32 phy_reg3_val;
+extern enum hws_pattern sweep_pattern;
+extern enum hws_pattern pbs_pattern;
+extern u8 is_rzq6;
+extern u32 znri_data_phy_val;
+extern u32 zpri_data_phy_val;
+extern u32 znri_ctrl_phy_val;
+extern u32 zpri_ctrl_phy_val;
+extern u8 debug_training_access;
+extern u32 finger_test, p_finger_start, p_finger_end, n_finger_start,
+ n_finger_end, p_finger_step, n_finger_step;
+extern u32 mode2_t;
+extern u32 xsb_validate_type;
+extern u32 xsb_validation_base_address;
+extern u32 odt_additional;
+extern u32 debug_mode;
+extern u32 delay_enable;
+extern u32 ca_delay;
+extern u32 debug_dunit;
+extern u32 clamp_tbl[];
+extern u32 freq_mask[HWS_MAX_DEVICE_NUM][DDR_FREQ_LIMIT];
+extern u32 start_pattern, end_pattern;
+
+extern u32 maxt_poll_tries;
+extern u32 is_bist_reset_bit;
+extern u8 debug_training_bist;
+
+extern u8 vref_window_size[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+extern u32 debug_mode;
+extern u32 effective_cs;
+extern int ddr3_tip_centr_skip_min_win_check;
+extern u32 *dq_map_table;
+extern enum auto_tune_stage training_stage;
+extern u8 debug_centralization;
+
+extern u32 delay_enable;
+extern u32 start_pattern, end_pattern;
+extern u32 freq_val[DDR_FREQ_LIMIT];
+extern u8 debug_training_hw_alg;
+extern enum auto_tune_stage training_stage;
+
+extern u8 debug_training_ip;
+extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
+extern enum auto_tune_stage training_stage;
+extern u32 effective_cs;
+
+extern u8 debug_leveling;
+extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
+extern enum auto_tune_stage training_stage;
+extern u32 rl_version;
+extern struct cl_val_per_freq cas_latency_table[];
+extern u32 start_xsb_offset;
+extern u32 debug_mode;
+extern u32 odt_config;
+extern u32 effective_cs;
+extern u32 phy_reg1_val;
+
+extern u8 debug_pbs;
+extern u32 effective_cs;
+extern u16 mask_results_dq_reg_map[];
+extern enum hws_ddr_freq medium_freq;
+extern u32 freq_val[];
+extern enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
+extern enum auto_tune_stage training_stage;
+extern u32 debug_mode;
+extern u32 *dq_map_table;
+
+extern u32 vref;
+extern struct cl_val_per_freq cas_latency_table[];
+extern u32 target_freq;
+extern struct hws_tip_config_func_db config_func_info[HWS_MAX_DEVICE_NUM];
+extern u32 clamp_tbl[];
+extern u32 init_freq;
+/* list of allowed frequency listed in order of enum hws_ddr_freq */
+extern u32 freq_val[];
+extern u8 debug_training_static;
+extern u32 first_active_if;
+
+/* Prototypes */
+int ddr3_tip_enable_init_sequence(u32 dev_num);
+
+int ddr3_tip_init_a38x(u32 dev_num, u32 board_id);
+
+int ddr3_hws_hw_training(void);
+int ddr3_silicon_pre_init(void);
+int ddr3_silicon_post_init(void);
+int ddr3_post_run_alg(void);
+int ddr3_if_ecc_enabled(void);
+void ddr3_new_tip_ecc_scrub(void);
+
+void ddr3_print_version(void);
+void ddr3_new_tip_dlb_config(void);
+struct hws_topology_map *ddr3_get_topology_map(void);
+
+int ddr3_if_ecc_enabled(void);
+int ddr3_tip_reg_write(u32 dev_num, u32 reg_addr, u32 data);
+int ddr3_tip_reg_read(u32 dev_num, u32 reg_addr, u32 *data, u32 reg_mask);
+int ddr3_silicon_get_ddr_target_freq(u32 *ddr_freq);
+int ddr3_tip_a38x_get_freq_config(u8 dev_num, enum hws_ddr_freq freq,
+ struct hws_tip_freq_config_info
+ *freq_config_info);
+int ddr3_a38x_update_topology_map(u32 dev_num,
+ struct hws_topology_map *topology_map);
+int ddr3_tip_a38x_get_init_freq(int dev_num, enum hws_ddr_freq *freq);
+int ddr3_tip_a38x_get_medium_freq(int dev_num, enum hws_ddr_freq *freq);
+int ddr3_tip_a38x_if_read(u8 dev_num, enum hws_access_type interface_access,
+ u32 if_id, u32 reg_addr, u32 *data, u32 mask);
+int ddr3_tip_a38x_if_write(u8 dev_num, enum hws_access_type interface_access,
+ u32 if_id, u32 reg_addr, u32 data, u32 mask);
+int ddr3_tip_a38x_get_device_info(u8 dev_num,
+ struct ddr3_device_info *info_ptr);
+
+int ddr3_tip_init_a38x(u32 dev_num, u32 board_id);
+
+int print_adll(u32 dev_num, u32 adll[MAX_INTERFACE_NUM * MAX_BUS_NUM]);
+int ddr3_tip_restore_dunit_regs(u32 dev_num);
+void print_topology(struct hws_topology_map *topology_db);
+
+u32 mv_board_id_get(void);
+
+int ddr3_load_topology_map(void);
+int ddr3_tip_init_specific_reg_config(u32 dev_num,
+ struct reg_data *reg_config_arr);
+u32 ddr3_tip_get_init_freq(void);
+void ddr3_hws_set_log_level(enum ddr_lib_debug_block block, u8 level);
+int ddr3_tip_tune_training_params(u32 dev_num,
+ struct tune_train_params *params);
+void get_target_freq(u32 freq_mode, u32 *ddr_freq, u32 *hclk_ps);
+int ddr3_fast_path_dynamic_cs_size_config(u32 cs_ena);
+void ddr3_fast_path_static_cs_size_config(u32 cs_ena);
+u32 ddr3_get_device_width(u32 cs);
+u32 mv_board_id_index_get(u32 board_id);
+u32 mv_board_id_get(void);
+u32 ddr3_get_bus_width(void);
+void ddr3_set_log_level(u32 n_log_level);
+int ddr3_calc_mem_cs_size(u32 cs, u32 *cs_size);
+
+int hws_ddr3_cs_base_adr_calc(u32 if_id, u32 cs, u32 *cs_base_addr);
+
+int ddr3_tip_print_pbs_result(u32 dev_num, u32 cs_num, enum pbs_dir pbs_mode);
+int ddr3_tip_clean_pbs_result(u32 dev_num, enum pbs_dir pbs_mode);
+
+int ddr3_tip_static_round_trip_arr_build(u32 dev_num,
+ struct trip_delay_element *table_ptr,
+ int is_wl, u32 *round_trip_delay_arr);
+
+u32 hws_ddr3_tip_max_cs_get(void);
+
+/*
+ * Accessor functions for the registers
+ */
+static inline void reg_write(u32 addr, u32 val)
+{
+ writel(val, INTER_REGS_BASE + addr);
+}
+
+static inline u32 reg_read(u32 addr)
+{
+ return readl(INTER_REGS_BASE + addr);
+}
+
+static inline void reg_bit_set(u32 addr, u32 mask)
+{
+ setbits_le32(INTER_REGS_BASE + addr, mask);
+}
+
+static inline void reg_bit_clr(u32 addr, u32 mask)
+{
+ clrbits_le32(INTER_REGS_BASE + addr, mask);
+}
+
+#endif /* _DDR3_INIT_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_LOGGING_CONFIG_H
+#define _DDR3_LOGGING_CONFIG_H
+
+#ifdef SILENT_LIB
+#define DEBUG_TRAINING_BIST_ENGINE(level, s)
+#define DEBUG_TRAINING_IP(level, s)
+#define DEBUG_CENTRALIZATION_ENGINE(level, s)
+#define DEBUG_TRAINING_HW_ALG(level, s)
+#define DEBUG_TRAINING_IP_ENGINE(level, s)
+#define DEBUG_LEVELING(level, s)
+#define DEBUG_PBS_ENGINE(level, s)
+#define DEBUG_TRAINING_STATIC_IP(level, s)
+#define DEBUG_TRAINING_ACCESS(level, s)
+#else
+#ifdef LIB_FUNCTIONAL_DEBUG_ONLY
+#define DEBUG_TRAINING_BIST_ENGINE(level, s)
+#define DEBUG_TRAINING_IP_ENGINE(level, s)
+#define DEBUG_TRAINING_IP(level, s) \
+ if (level >= debug_training) \
+ printf s
+#define DEBUG_CENTRALIZATION_ENGINE(level, s) \
+ if (level >= debug_centralization) \
+ printf s
+#define DEBUG_TRAINING_HW_ALG(level, s) \
+ if (level >= debug_training_hw_alg) \
+ printf s
+#define DEBUG_LEVELING(level, s) \
+ if (level >= debug_leveling) \
+ printf s
+#define DEBUG_PBS_ENGINE(level, s) \
+ if (level >= debug_pbs) \
+ printf s
+#define DEBUG_TRAINING_STATIC_IP(level, s) \
+ if (level >= debug_training_static) \
+ printf s
+#define DEBUG_TRAINING_ACCESS(level, s) \
+ if (level >= debug_training_access) \
+ printf s
+#else
+#define DEBUG_TRAINING_BIST_ENGINE(level, s) \
+ if (level >= debug_training_bist) \
+ printf s
+
+#define DEBUG_TRAINING_IP_ENGINE(level, s) \
+ if (level >= debug_training_ip) \
+ printf s
+#define DEBUG_TRAINING_IP(level, s) \
+ if (level >= debug_training) \
+ printf s
+#define DEBUG_CENTRALIZATION_ENGINE(level, s) \
+ if (level >= debug_centralization) \
+ printf s
+#define DEBUG_TRAINING_HW_ALG(level, s) \
+ if (level >= debug_training_hw_alg) \
+ printf s
+#define DEBUG_LEVELING(level, s) \
+ if (level >= debug_leveling) \
+ printf s
+#define DEBUG_PBS_ENGINE(level, s) \
+ if (level >= debug_pbs) \
+ printf s
+#define DEBUG_TRAINING_STATIC_IP(level, s) \
+ if (level >= debug_training_static) \
+ printf s
+#define DEBUG_TRAINING_ACCESS(level, s) \
+ if (level >= debug_training_access) \
+ printf s
+#endif
+#endif
+
+/* Logging defines */
+#define DEBUG_LEVEL_TRACE 1
+#define DEBUG_LEVEL_INFO 2
+#define DEBUG_LEVEL_ERROR 3
+
+enum ddr_lib_debug_block {
+ DEBUG_BLOCK_STATIC,
+ DEBUG_BLOCK_TRAINING_MAIN,
+ DEBUG_BLOCK_LEVELING,
+ DEBUG_BLOCK_CENTRALIZATION,
+ DEBUG_BLOCK_PBS,
+ DEBUG_BLOCK_IP,
+ DEBUG_BLOCK_BIST,
+ DEBUG_BLOCK_ALG,
+ DEBUG_BLOCK_DEVICE,
+ DEBUG_BLOCK_ACCESS,
+ DEBUG_STAGES_REG_DUMP,
+ /* All excluding IP and REG_DUMP, should be enabled separatelly */
+ DEBUG_BLOCK_ALL
+};
+
+int ddr3_tip_print_log(u32 dev_num, u32 mem_addr);
+int ddr3_tip_print_stability_log(u32 dev_num);
+
+#endif /* _DDR3_LOGGING_CONFIG_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __DDR3_PATTERNS_64_H
+#define __DDR3_PATTERNS_64_H
+
+/*
+ * Patterns Declerations
+ */
+
+u32 wl_sup_pattern[LEN_WL_SUP_PATTERN] __aligned(32) = {
+ 0x04030201, 0x08070605, 0x0c0b0a09, 0x100f0e0d,
+ 0x14131211, 0x18171615, 0x1c1b1a19, 0x201f1e1d,
+ 0x24232221, 0x28272625, 0x2c2b2a29, 0x302f2e2d,
+ 0x34333231, 0x38373635, 0x3c3b3a39, 0x403f3e3d,
+ 0x44434241, 0x48474645, 0x4c4b4a49, 0x504f4e4d,
+ 0x54535251, 0x58575655, 0x5c5b5a59, 0x605f5e5d,
+ 0x64636261, 0x68676665, 0x6c6b6a69, 0x706f6e6d,
+ 0x74737271, 0x78777675, 0x7c7b7a79, 0x807f7e7d
+};
+
+u32 pbs_pattern_32b[2][LEN_PBS_PATTERN] __aligned(32) = {
+ {
+ 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, 0x55555555,
+ 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, 0x55555555,
+ 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, 0x55555555,
+ 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa, 0x55555555
+ },
+ {
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa,
+ 0x55555555, 0xaaaaaaaa, 0x55555555, 0xaaaaaaaa
+ }
+};
+
+u32 pbs_pattern_64b[2][LEN_PBS_PATTERN] __aligned(32) = {
+ {
+ 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555,
+ 0xaaaaaaaa, 0xaaaaaaaa, 0x55555555, 0x55555555
+ },
+ {
+ 0x55555555, 0x55555555, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0x55555555, 0x55555555, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0x55555555, 0x55555555, 0xaaaaaaaa, 0xaaaaaaaa,
+ 0x55555555, 0x55555555, 0xaaaaaaaa, 0xaaaaaaaa
+ }
+};
+
+u32 rl_pattern[LEN_STD_PATTERN] __aligned(32) = {
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x01010101, 0x01010101, 0x01010101, 0x01010101
+};
+
+u32 killer_pattern_32b[DQ_NUM][LEN_KILLER_PATTERN] __aligned(32) = {
+ {
+ 0x01010101, 0x00000000, 0x01010101, 0xffffffff,
+ 0x01010101, 0x00000000, 0x01010101, 0xffffffff,
+ 0xfefefefe, 0xfefefefe, 0x01010101, 0xfefefefe,
+ 0xfefefefe, 0xfefefefe, 0x01010101, 0xfefefefe,
+ 0x01010101, 0xfefefefe, 0x01010101, 0x01010101,
+ 0x01010101, 0xfefefefe, 0x01010101, 0x01010101,
+ 0xfefefefe, 0x01010101, 0xfefefefe, 0x00000000,
+ 0xfefefefe, 0x01010101, 0xfefefefe, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x01010101,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x01010101,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0xfefefefe,
+ 0x00000000, 0x00000000, 0x00000000, 0xfefefefe,
+ 0xfefefefe, 0xffffffff, 0x00000000, 0x00000000,
+ 0xfefefefe, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xfefefefe, 0x00000000, 0xfefefefe, 0x00000000,
+ 0xfefefefe, 0x00000000, 0xfefefefe, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x01010101,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x01010101,
+ 0xffffffff, 0xffffffff, 0x01010101, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x01010101, 0x00000000,
+ 0x01010101, 0xffffffff, 0xfefefefe, 0xfefefefe,
+ 0x01010101, 0xffffffff, 0xfefefefe, 0xfefefefe
+ },
+ {
+ 0x02020202, 0x00000000, 0x02020202, 0xffffffff,
+ 0x02020202, 0x00000000, 0x02020202, 0xffffffff,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x02020202, 0xfdfdfdfd,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x02020202, 0xfdfdfdfd,
+ 0x02020202, 0xfdfdfdfd, 0x02020202, 0x02020202,
+ 0x02020202, 0xfdfdfdfd, 0x02020202, 0x02020202,
+ 0xfdfdfdfd, 0x02020202, 0xfdfdfdfd, 0x00000000,
+ 0xfdfdfdfd, 0x02020202, 0xfdfdfdfd, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x02020202,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x02020202,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0xfdfdfdfd,
+ 0x00000000, 0x00000000, 0x00000000, 0xfdfdfdfd,
+ 0xfdfdfdfd, 0xffffffff, 0x00000000, 0x00000000,
+ 0xfdfdfdfd, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xfdfdfdfd, 0x00000000, 0xfdfdfdfd, 0x00000000,
+ 0xfdfdfdfd, 0x00000000, 0xfdfdfdfd, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x02020202,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x02020202,
+ 0xffffffff, 0xffffffff, 0x02020202, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x02020202, 0x00000000,
+ 0x02020202, 0xffffffff, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0x02020202, 0xffffffff, 0xfdfdfdfd, 0xfdfdfdfd
+ },
+ {
+ 0x04040404, 0x00000000, 0x04040404, 0xffffffff,
+ 0x04040404, 0x00000000, 0x04040404, 0xffffffff,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x04040404, 0xfbfbfbfb,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x04040404, 0xfbfbfbfb,
+ 0x04040404, 0xfbfbfbfb, 0x04040404, 0x04040404,
+ 0x04040404, 0xfbfbfbfb, 0x04040404, 0x04040404,
+ 0xfbfbfbfb, 0x04040404, 0xfbfbfbfb, 0x00000000,
+ 0xfbfbfbfb, 0x04040404, 0xfbfbfbfb, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x04040404,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x04040404,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0xfbfbfbfb,
+ 0x00000000, 0x00000000, 0x00000000, 0xfbfbfbfb,
+ 0xfbfbfbfb, 0xffffffff, 0x00000000, 0x00000000,
+ 0xfbfbfbfb, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xfbfbfbfb, 0x00000000, 0xfbfbfbfb, 0x00000000,
+ 0xfbfbfbfb, 0x00000000, 0xfbfbfbfb, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x04040404,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x04040404,
+ 0xffffffff, 0xffffffff, 0x04040404, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x04040404, 0x00000000,
+ 0x04040404, 0xffffffff, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0x04040404, 0xffffffff, 0xfbfbfbfb, 0xfbfbfbfb
+ },
+ {
+ 0x08080808, 0x00000000, 0x08080808, 0xffffffff,
+ 0x08080808, 0x00000000, 0x08080808, 0xffffffff,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x08080808, 0xf7f7f7f7,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x08080808, 0xf7f7f7f7,
+ 0x08080808, 0xf7f7f7f7, 0x08080808, 0x08080808,
+ 0x08080808, 0xf7f7f7f7, 0x08080808, 0x08080808,
+ 0xf7f7f7f7, 0x08080808, 0xf7f7f7f7, 0x00000000,
+ 0xf7f7f7f7, 0x08080808, 0xf7f7f7f7, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x08080808,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x08080808,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0xf7f7f7f7,
+ 0x00000000, 0x00000000, 0x00000000, 0xf7f7f7f7,
+ 0xf7f7f7f7, 0xffffffff, 0x00000000, 0x00000000,
+ 0xf7f7f7f7, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xf7f7f7f7, 0x00000000, 0xf7f7f7f7, 0x00000000,
+ 0xf7f7f7f7, 0x00000000, 0xf7f7f7f7, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x08080808,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x08080808,
+ 0xffffffff, 0xffffffff, 0x08080808, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x08080808, 0x00000000,
+ 0x08080808, 0xffffffff, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0x08080808, 0xffffffff, 0xf7f7f7f7, 0xf7f7f7f7
+ },
+ {
+ 0x10101010, 0x00000000, 0x10101010, 0xffffffff,
+ 0x10101010, 0x00000000, 0x10101010, 0xffffffff,
+ 0xefefefef, 0xefefefef, 0x10101010, 0xefefefef,
+ 0xefefefef, 0xefefefef, 0x10101010, 0xefefefef,
+ 0x10101010, 0xefefefef, 0x10101010, 0x10101010,
+ 0x10101010, 0xefefefef, 0x10101010, 0x10101010,
+ 0xefefefef, 0x10101010, 0xefefefef, 0x00000000,
+ 0xefefefef, 0x10101010, 0xefefefef, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x10101010,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x10101010,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0xefefefef,
+ 0x00000000, 0x00000000, 0x00000000, 0xefefefef,
+ 0xefefefef, 0xffffffff, 0x00000000, 0x00000000,
+ 0xefefefef, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xefefefef, 0x00000000, 0xefefefef, 0x00000000,
+ 0xefefefef, 0x00000000, 0xefefefef, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x10101010,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x10101010,
+ 0xffffffff, 0xffffffff, 0x10101010, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x10101010, 0x00000000,
+ 0x10101010, 0xffffffff, 0xefefefef, 0xefefefef,
+ 0x10101010, 0xffffffff, 0xefefefef, 0xefefefef
+ },
+ {
+ 0x20202020, 0x00000000, 0x20202020, 0xffffffff,
+ 0x20202020, 0x00000000, 0x20202020, 0xffffffff,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x20202020, 0xdfdfdfdf,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x20202020, 0xdfdfdfdf,
+ 0x20202020, 0xdfdfdfdf, 0x20202020, 0x20202020,
+ 0x20202020, 0xdfdfdfdf, 0x20202020, 0x20202020,
+ 0xdfdfdfdf, 0x20202020, 0xdfdfdfdf, 0x00000000,
+ 0xdfdfdfdf, 0x20202020, 0xdfdfdfdf, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x20202020,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x20202020,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0xdfdfdfdf,
+ 0x00000000, 0x00000000, 0x00000000, 0xdfdfdfdf,
+ 0xdfdfdfdf, 0xffffffff, 0x00000000, 0x00000000,
+ 0xdfdfdfdf, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xdfdfdfdf, 0x00000000, 0xdfdfdfdf, 0x00000000,
+ 0xdfdfdfdf, 0x00000000, 0xdfdfdfdf, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x20202020,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x20202020,
+ 0xffffffff, 0xffffffff, 0x20202020, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x20202020, 0x00000000,
+ 0x20202020, 0xffffffff, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0x20202020, 0xffffffff, 0xdfdfdfdf, 0xdfdfdfdf
+ },
+ {
+ 0x40404040, 0x00000000, 0x40404040, 0xffffffff,
+ 0x40404040, 0x00000000, 0x40404040, 0xffffffff,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x40404040, 0xbfbfbfbf,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x40404040, 0xbfbfbfbf,
+ 0x40404040, 0xbfbfbfbf, 0x40404040, 0x40404040,
+ 0x40404040, 0xbfbfbfbf, 0x40404040, 0x40404040,
+ 0xbfbfbfbf, 0x40404040, 0xbfbfbfbf, 0x00000000,
+ 0xbfbfbfbf, 0x40404040, 0xbfbfbfbf, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x40404040,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x40404040,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0xbfbfbfbf,
+ 0x00000000, 0x00000000, 0x00000000, 0xbfbfbfbf,
+ 0xbfbfbfbf, 0xffffffff, 0x00000000, 0x00000000,
+ 0xbfbfbfbf, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xbfbfbfbf, 0x00000000, 0xbfbfbfbf, 0x00000000,
+ 0xbfbfbfbf, 0x00000000, 0xbfbfbfbf, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x40404040,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x40404040,
+ 0xffffffff, 0xffffffff, 0x40404040, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x40404040, 0x00000000,
+ 0x40404040, 0xffffffff, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0x40404040, 0xffffffff, 0xbfbfbfbf, 0xbfbfbfbf
+ },
+ {
+ 0x80808080, 0x00000000, 0x80808080, 0xffffffff,
+ 0x80808080, 0x00000000, 0x80808080, 0xffffffff,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x80808080, 0x7f7f7f7f,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x80808080, 0x7f7f7f7f,
+ 0x80808080, 0x7f7f7f7f, 0x80808080, 0x80808080,
+ 0x80808080, 0x7f7f7f7f, 0x80808080, 0x80808080,
+ 0x7f7f7f7f, 0x80808080, 0x7f7f7f7f, 0x00000000,
+ 0x7f7f7f7f, 0x80808080, 0x7f7f7f7f, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x00000000,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x80808080,
+ 0xffffffff, 0x00000000, 0xffffffff, 0x80808080,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x7f7f7f7f,
+ 0x00000000, 0x00000000, 0x00000000, 0x7f7f7f7f,
+ 0x7f7f7f7f, 0xffffffff, 0x00000000, 0x00000000,
+ 0x7f7f7f7f, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x00000000,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x00000000, 0xffffffff, 0x00000000, 0xffffffff,
+ 0x7f7f7f7f, 0x00000000, 0x7f7f7f7f, 0x00000000,
+ 0x7f7f7f7f, 0x00000000, 0x7f7f7f7f, 0x00000000,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x80808080,
+ 0x00000000, 0xffffffff, 0xffffffff, 0x80808080,
+ 0xffffffff, 0xffffffff, 0x80808080, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x80808080, 0x00000000,
+ 0x80808080, 0xffffffff, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x80808080, 0xffffffff, 0x7f7f7f7f, 0x7f7f7f7f
+ }
+};
+
+u32 killer_pattern_64b[DQ_NUM][LEN_KILLER_PATTERN] __aligned(32) = {
+ {
+ 0x01010101, 0x01010101, 0x00000000, 0x00000000,
+ 0x01010101, 0x01010101, 0xffffffff, 0xffffffff,
+ 0xfefefefe, 0xfefefefe, 0xfefefefe, 0xfefefefe,
+ 0x01010101, 0x01010101, 0xfefefefe, 0xfefefefe,
+ 0x01010101, 0x01010101, 0xfefefefe, 0xfefefefe,
+ 0x01010101, 0x01010101, 0x01010101, 0x01010101,
+ 0xfefefefe, 0xfefefefe, 0x01010101, 0x01010101,
+ 0xfefefefe, 0xfefefefe, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x01010101, 0x01010101,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xfefefefe, 0xfefefefe,
+ 0xfefefefe, 0xfefefefe, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xfefefefe, 0xfefefefe, 0x00000000, 0x00000000,
+ 0xfefefefe, 0xfefefefe, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x01010101, 0x01010101,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x01010101, 0x01010101, 0x00000000, 0x00000000,
+ 0x01010101, 0x01010101, 0xffffffff, 0xffffffff,
+ 0xfefefefe, 0xfefefefe, 0xfefefefe, 0xfefefefe
+ },
+ {
+ 0x02020202, 0x02020202, 0x00000000, 0x00000000,
+ 0x02020202, 0x02020202, 0xffffffff, 0xffffffff,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0x02020202, 0x02020202, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0x02020202, 0x02020202, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0x02020202, 0x02020202, 0x02020202, 0x02020202,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x02020202, 0x02020202,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x02020202, 0x02020202,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x00000000, 0x00000000,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x02020202, 0x02020202,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x02020202, 0x02020202, 0x00000000, 0x00000000,
+ 0x02020202, 0x02020202, 0xffffffff, 0xffffffff,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd
+ },
+ {
+ 0x04040404, 0x04040404, 0x00000000, 0x00000000,
+ 0x04040404, 0x04040404, 0xffffffff, 0xffffffff,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0x04040404, 0x04040404, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0x04040404, 0x04040404, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0x04040404, 0x04040404, 0x04040404, 0x04040404,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x04040404, 0x04040404,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x04040404, 0x04040404,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x00000000, 0x00000000,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x04040404, 0x04040404,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x04040404, 0x04040404, 0x00000000, 0x00000000,
+ 0x04040404, 0x04040404, 0xffffffff, 0xffffffff,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0xfbfbfbfb, 0xfbfbfbfb
+ },
+ {
+ 0x08080808, 0x08080808, 0x00000000, 0x00000000,
+ 0x08080808, 0x08080808, 0xffffffff, 0xffffffff,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0x08080808, 0x08080808, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0x08080808, 0x08080808, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0x08080808, 0x08080808, 0x08080808, 0x08080808,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x08080808, 0x08080808,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x08080808, 0x08080808,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x00000000, 0x00000000,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x08080808, 0x08080808,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x08080808, 0x08080808, 0x00000000, 0x00000000,
+ 0x08080808, 0x08080808, 0xffffffff, 0xffffffff,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0xf7f7f7f7, 0xf7f7f7f7
+ },
+ {
+ 0x10101010, 0x10101010, 0x00000000, 0x00000000,
+ 0x10101010, 0x10101010, 0xffffffff, 0xffffffff,
+ 0xefefefef, 0xefefefef, 0xefefefef, 0xefefefef,
+ 0x10101010, 0x10101010, 0xefefefef, 0xefefefef,
+ 0x10101010, 0x10101010, 0xefefefef, 0xefefefef,
+ 0x10101010, 0x10101010, 0x10101010, 0x10101010,
+ 0xefefefef, 0xefefefef, 0x10101010, 0x10101010,
+ 0xefefefef, 0xefefefef, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x10101010, 0x10101010,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xefefefef, 0xefefefef,
+ 0xefefefef, 0xefefefef, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xefefefef, 0xefefefef, 0x00000000, 0x00000000,
+ 0xefefefef, 0xefefefef, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x10101010, 0x10101010,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x10101010, 0x10101010, 0x00000000, 0x00000000,
+ 0x10101010, 0x10101010, 0xffffffff, 0xffffffff,
+ 0xefefefef, 0xefefefef, 0xefefefef, 0xefefefef
+ },
+ {
+ 0x20202020, 0x20202020, 0x00000000, 0x00000000,
+ 0x20202020, 0x20202020, 0xffffffff, 0xffffffff,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0x20202020, 0x20202020, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0x20202020, 0x20202020, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0x20202020, 0x20202020, 0x20202020, 0x20202020,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x20202020, 0x20202020,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x20202020, 0x20202020,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x00000000, 0x00000000,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x20202020, 0x20202020,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x20202020, 0x20202020, 0x00000000, 0x00000000,
+ 0x20202020, 0x20202020, 0xffffffff, 0xffffffff,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0xdfdfdfdf, 0xdfdfdfdf
+ },
+ {
+ 0x40404040, 0x40404040, 0x00000000, 0x00000000,
+ 0x40404040, 0x40404040, 0xffffffff, 0xffffffff,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0x40404040, 0x40404040, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0x40404040, 0x40404040, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0x40404040, 0x40404040, 0x40404040, 0x40404040,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x40404040, 0x40404040,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x40404040, 0x40404040,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x00000000, 0x00000000,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x40404040, 0x40404040,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x40404040, 0x40404040, 0x00000000, 0x00000000,
+ 0x40404040, 0x40404040, 0xffffffff, 0xffffffff,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0xbfbfbfbf, 0xbfbfbfbf
+ },
+ {
+ 0x80808080, 0x80808080, 0x00000000, 0x00000000,
+ 0x80808080, 0x80808080, 0xffffffff, 0xffffffff,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x80808080, 0x80808080, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x80808080, 0x80808080, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x80808080, 0x80808080, 0x80808080, 0x80808080,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x80808080, 0x80808080,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x80808080, 0x80808080,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x00000000, 0x00000000,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x80808080, 0x80808080,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x80808080, 0x80808080, 0x00000000, 0x00000000,
+ 0x80808080, 0x80808080, 0xffffffff, 0xffffffff,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f
+ }
+};
+
+u32 special_pattern[DQ_NUM][LEN_SPECIAL_PATTERN] __aligned(32) = {
+ {
+ 0x00000000, 0x00000000, 0x01010101, 0x01010101,
+ 0xffffffff, 0xffffffff, 0xfefefefe, 0xfefefefe,
+ 0xfefefefe, 0xfefefefe, 0x01010101, 0x01010101,
+ 0xfefefefe, 0xfefefefe, 0x01010101, 0x01010101,
+ 0xfefefefe, 0xfefefefe, 0x01010101, 0x01010101,
+ 0x01010101, 0x01010101, 0xfefefefe, 0xfefefefe,
+ 0x01010101, 0x01010101, 0xfefefefe, 0xfefefefe,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x01010101, 0x01010101, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xfefefefe, 0xfefefefe, 0xfefefefe, 0xfefefefe,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xfefefefe, 0xfefefefe,
+ 0x00000000, 0x00000000, 0xfefefefe, 0xfefefefe,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x01010101, 0x01010101, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x01010101, 0x01010101,
+ 0x00000000, 0x00000000, 0x01010101, 0x01010101,
+ 0xffffffff, 0xffffffff, 0xfefefefe, 0xfefefefe,
+ 0xfefefefe, 0xfefefefe, 0x00000000, 0x00000000
+ },
+ {
+ 0x00000000, 0x00000000, 0x02020202, 0x02020202,
+ 0xffffffff, 0xffffffff, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x02020202, 0x02020202,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x02020202, 0x02020202,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x02020202, 0x02020202,
+ 0x02020202, 0x02020202, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0x02020202, 0x02020202, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x02020202, 0x02020202, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0x00000000, 0x00000000, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x02020202, 0x02020202, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x02020202, 0x02020202,
+ 0x00000000, 0x00000000, 0x02020202, 0x02020202,
+ 0xffffffff, 0xffffffff, 0xfdfdfdfd, 0xfdfdfdfd,
+ 0xfdfdfdfd, 0xfdfdfdfd, 0x00000000, 0x00000000
+ },
+ {
+ 0x00000000, 0x00000000, 0x04040404, 0x04040404,
+ 0xffffffff, 0xffffffff, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x04040404, 0x04040404,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x04040404, 0x04040404,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x04040404, 0x04040404,
+ 0x04040404, 0x04040404, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0x04040404, 0x04040404, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x04040404, 0x04040404, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0x00000000, 0x00000000, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x04040404, 0x04040404, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x04040404, 0x04040404,
+ 0x00000000, 0x00000000, 0x04040404, 0x04040404,
+ 0xffffffff, 0xffffffff, 0xfbfbfbfb, 0xfbfbfbfb,
+ 0xfbfbfbfb, 0xfbfbfbfb, 0x00000000, 0x00000000
+ },
+ {
+ 0x00000000, 0x00000000, 0x08080808, 0x08080808,
+ 0xffffffff, 0xffffffff, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x08080808, 0x08080808,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x08080808, 0x08080808,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x08080808, 0x08080808,
+ 0x08080808, 0x08080808, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0x08080808, 0x08080808, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x08080808, 0x08080808, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0x00000000, 0x00000000, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x08080808, 0x08080808, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x08080808, 0x08080808,
+ 0x00000000, 0x00000000, 0x08080808, 0x08080808,
+ 0xffffffff, 0xffffffff, 0xf7f7f7f7, 0xf7f7f7f7,
+ 0xf7f7f7f7, 0xf7f7f7f7, 0x00000000, 0x00000000
+ },
+ {
+ 0x00000000, 0x00000000, 0x10101010, 0x10101010,
+ 0xffffffff, 0xffffffff, 0xefefefef, 0xefefefef,
+ 0xefefefef, 0xefefefef, 0x10101010, 0x10101010,
+ 0xefefefef, 0xefefefef, 0x10101010, 0x10101010,
+ 0xefefefef, 0xefefefef, 0x10101010, 0x10101010,
+ 0x10101010, 0x10101010, 0xefefefef, 0xefefefef,
+ 0x10101010, 0x10101010, 0xefefefef, 0xefefefef,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x10101010, 0x10101010, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xefefefef, 0xefefefef, 0xefefefef, 0xefefefef,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xefefefef, 0xefefefef,
+ 0x00000000, 0x00000000, 0xefefefef, 0xefefefef,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x10101010, 0x10101010, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x10101010, 0x10101010,
+ 0x00000000, 0x00000000, 0x10101010, 0x10101010,
+ 0xffffffff, 0xffffffff, 0xefefefef, 0xefefefef,
+ 0xefefefef, 0xefefefef, 0x00000000, 0x00000000
+ },
+ {
+ 0x00000000, 0x00000000, 0x20202020, 0x20202020,
+ 0xffffffff, 0xffffffff, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x20202020, 0x20202020,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x20202020, 0x20202020,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x20202020, 0x20202020,
+ 0x20202020, 0x20202020, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0x20202020, 0x20202020, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x20202020, 0x20202020, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0x00000000, 0x00000000, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x20202020, 0x20202020, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x20202020, 0x20202020,
+ 0x00000000, 0x00000000, 0x20202020, 0x20202020,
+ 0xffffffff, 0xffffffff, 0xdfdfdfdf, 0xdfdfdfdf,
+ 0xdfdfdfdf, 0xdfdfdfdf, 0x00000000, 0x00000000
+ },
+ {
+ 0x00000000, 0x00000000, 0x40404040, 0x40404040,
+ 0xffffffff, 0xffffffff, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x40404040, 0x40404040,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x40404040, 0x40404040,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x40404040, 0x40404040,
+ 0x40404040, 0x40404040, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0x40404040, 0x40404040, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x40404040, 0x40404040, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0x00000000, 0x00000000, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x40404040, 0x40404040, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x40404040, 0x40404040,
+ 0x00000000, 0x00000000, 0x40404040, 0x40404040,
+ 0xffffffff, 0xffffffff, 0xbfbfbfbf, 0xbfbfbfbf,
+ 0xbfbfbfbf, 0xbfbfbfbf, 0x00000000, 0x00000000
+ },
+ {
+ 0x00000000, 0x00000000, 0x80808080, 0x80808080,
+ 0xffffffff, 0xffffffff, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x80808080, 0x80808080,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x80808080, 0x80808080,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x80808080, 0x80808080,
+ 0x80808080, 0x80808080, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x80808080, 0x80808080, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0x80808080, 0x80808080, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x00000000, 0x00000000, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x80808080, 0x80808080, 0xffffffff, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0x80808080, 0x80808080,
+ 0x00000000, 0x00000000, 0x80808080, 0x80808080,
+ 0xffffffff, 0xffffffff, 0x7f7f7f7f, 0x7f7f7f7f,
+ 0x7f7f7f7f, 0x7f7f7f7f, 0x00000000, 0x00000000
+ }
+};
+
+/* Fabric ratios table */
+u32 fabric_ratio[FAB_OPT] = {
+ 0x04010204,
+ 0x04020202,
+ 0x08020306,
+ 0x08020303,
+ 0x04020303,
+ 0x04020204,
+ 0x04010202,
+ 0x08030606,
+ 0x08030505,
+ 0x04020306,
+ 0x0804050a,
+ 0x04030606,
+ 0x04020404,
+ 0x04030306,
+ 0x04020505,
+ 0x08020505,
+ 0x04010303,
+ 0x08050a0a,
+ 0x04030408,
+ 0x04010102,
+ 0x08030306
+};
+
+u32 pbs_dq_mapping[PUP_NUM_64BIT + 1][DQ_NUM] = {
+ {3, 2, 5, 7, 1, 0, 6, 4},
+ {2, 3, 6, 7, 1, 0, 4, 5},
+ {1, 3, 5, 6, 0, 2, 4, 7},
+ {0, 2, 4, 7, 1, 3, 5, 6},
+ {3, 0, 4, 6, 1, 2, 5, 7},
+ {0, 3, 5, 7, 1, 2, 4, 6},
+ {2, 3, 5, 7, 1, 0, 4, 6},
+ {0, 2, 5, 4, 1, 3, 6, 7},
+ {2, 3, 4, 7, 0, 1, 5, 6}
+};
+
+#endif /* __DDR3_PATTERNS_64_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TOPOLOGY_DEF_H
+#define _DDR3_TOPOLOGY_DEF_H
+
+/* TOPOLOGY */
+
+enum hws_speed_bin {
+ SPEED_BIN_DDR_800D,
+ SPEED_BIN_DDR_800E,
+ SPEED_BIN_DDR_1066E,
+ SPEED_BIN_DDR_1066F,
+ SPEED_BIN_DDR_1066G,
+ SPEED_BIN_DDR_1333F,
+ SPEED_BIN_DDR_1333G,
+ SPEED_BIN_DDR_1333H,
+ SPEED_BIN_DDR_1333J,
+ SPEED_BIN_DDR_1600G,
+ SPEED_BIN_DDR_1600H,
+ SPEED_BIN_DDR_1600J,
+ SPEED_BIN_DDR_1600K,
+ SPEED_BIN_DDR_1866J,
+ SPEED_BIN_DDR_1866K,
+ SPEED_BIN_DDR_1866L,
+ SPEED_BIN_DDR_1866M,
+ SPEED_BIN_DDR_2133K,
+ SPEED_BIN_DDR_2133L,
+ SPEED_BIN_DDR_2133M,
+ SPEED_BIN_DDR_2133N,
+
+ SPEED_BIN_DDR_1333H_EXT,
+ SPEED_BIN_DDR_1600K_EXT,
+ SPEED_BIN_DDR_1866M_EXT
+};
+
+enum hws_ddr_freq {
+ DDR_FREQ_LOW_FREQ,
+ DDR_FREQ_400,
+ DDR_FREQ_533,
+ DDR_FREQ_667,
+ DDR_FREQ_800,
+ DDR_FREQ_933,
+ DDR_FREQ_1066,
+ DDR_FREQ_311,
+ DDR_FREQ_333,
+ DDR_FREQ_467,
+ DDR_FREQ_850,
+ DDR_FREQ_600,
+ DDR_FREQ_300,
+ DDR_FREQ_900,
+ DDR_FREQ_360,
+ DDR_FREQ_1000,
+ DDR_FREQ_LIMIT
+};
+
+enum speed_bin_table_elements {
+ SPEED_BIN_TRCD,
+ SPEED_BIN_TRP,
+ SPEED_BIN_TRAS,
+ SPEED_BIN_TRC,
+ SPEED_BIN_TRRD1K,
+ SPEED_BIN_TRRD2K,
+ SPEED_BIN_TPD,
+ SPEED_BIN_TFAW1K,
+ SPEED_BIN_TFAW2K,
+ SPEED_BIN_TWTR,
+ SPEED_BIN_TRTP,
+ SPEED_BIN_TWR,
+ SPEED_BIN_TMOD
+};
+
+#endif /* _DDR3_TOPOLOGY_DEF_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#define GET_MAX_VALUE(x, y) \
+ ((x) > (y)) ? (x) : (y)
+#define CEIL_DIVIDE(x, y) \
+ ((x - (x / y) * y) == 0) ? ((x / y) - 1) : (x / y)
+
+#define TIME_2_CLOCK_CYCLES CEIL_DIVIDE
+
+#define GET_CS_FROM_MASK(mask) (cs_mask2_num[mask])
+#define CS_CBE_VALUE(cs_num) (cs_cbe_reg[cs_num])
+
+u32 window_mem_addr = 0;
+u32 phy_reg0_val = 0;
+u32 phy_reg1_val = 8;
+u32 phy_reg2_val = 0;
+u32 phy_reg3_val = 0xa;
+enum hws_ddr_freq init_freq = DDR_FREQ_667;
+enum hws_ddr_freq low_freq = DDR_FREQ_LOW_FREQ;
+enum hws_ddr_freq medium_freq;
+u32 debug_dunit = 0;
+u32 odt_additional = 1;
+u32 *dq_map_table = NULL;
+u32 odt_config = 1;
+
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ALLEYCAT3) || \
+ defined(CONFIG_ARMADA_39X)
+u32 is_pll_before_init = 0, is_adll_calib_before_init = 0, is_dfs_in_init = 0;
+u32 dfs_low_freq = 130;
+#else
+u32 is_pll_before_init = 0, is_adll_calib_before_init = 1, is_dfs_in_init = 0;
+u32 dfs_low_freq = 100;
+#endif
+u32 g_rtt_nom_c_s0, g_rtt_nom_c_s1;
+u8 calibration_update_control; /* 2 external only, 1 is internal only */
+
+enum hws_result training_result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM];
+enum auto_tune_stage training_stage = INIT_CONTROLLER;
+u32 finger_test = 0, p_finger_start = 11, p_finger_end = 64,
+ n_finger_start = 11, n_finger_end = 64,
+ p_finger_step = 3, n_finger_step = 3;
+u32 clamp_tbl[] = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+/* Initiate to 0xff, this variable is define by user in debug mode */
+u32 mode2_t = 0xff;
+u32 xsb_validate_type = 0;
+u32 xsb_validation_base_address = 0xf000;
+u32 first_active_if = 0;
+u32 dfs_low_phy1 = 0x1f;
+u32 multicast_id = 0;
+int use_broadcast = 0;
+struct hws_tip_freq_config_info *freq_info_table = NULL;
+u8 is_cbe_required = 0;
+u32 debug_mode = 0;
+u32 delay_enable = 0;
+int rl_mid_freq_wa = 0;
+
+u32 effective_cs = 0;
+
+u32 mask_tune_func = (SET_MEDIUM_FREQ_MASK_BIT |
+ WRITE_LEVELING_MASK_BIT |
+ LOAD_PATTERN_2_MASK_BIT |
+ READ_LEVELING_MASK_BIT |
+ SET_TARGET_FREQ_MASK_BIT | WRITE_LEVELING_TF_MASK_BIT |
+ READ_LEVELING_TF_MASK_BIT |
+ CENTRALIZATION_RX_MASK_BIT | CENTRALIZATION_TX_MASK_BIT);
+
+void ddr3_print_version(void)
+{
+ printf(DDR3_TIP_VERSION_STRING);
+}
+
+static int ddr3_tip_ddr3_training_main_flow(u32 dev_num);
+static int ddr3_tip_write_odt(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, u32 cl_value, u32 cwl_value);
+static int ddr3_tip_ddr3_auto_tune(u32 dev_num);
+static int is_bus_access_done(u32 dev_num, u32 if_id,
+ u32 dunit_reg_adrr, u32 bit);
+#ifdef ODT_TEST_SUPPORT
+static int odt_test(u32 dev_num, enum hws_algo_type algo_type);
+#endif
+
+int adll_calibration(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_ddr_freq frequency);
+static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_ddr_freq frequency);
+
+static struct page_element page_param[] = {
+ /*
+ * 8bits 16 bits
+ * page-size(K) page-size(K) mask
+ */
+ { 1, 2, 2},
+ /* 512M */
+ { 1, 2, 3},
+ /* 1G */
+ { 1, 2, 0},
+ /* 2G */
+ { 1, 2, 4},
+ /* 4G */
+ { 2, 2, 5}
+ /* 8G */
+};
+
+static u8 mem_size_config[MEM_SIZE_LAST] = {
+ 0x2, /* 512Mbit */
+ 0x3, /* 1Gbit */
+ 0x0, /* 2Gbit */
+ 0x4, /* 4Gbit */
+ 0x5 /* 8Gbit */
+};
+
+static u8 cs_mask2_num[] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
+
+static struct reg_data odpg_default_value[] = {
+ {0x1034, 0x38000, MASK_ALL_BITS},
+ {0x1038, 0x0, MASK_ALL_BITS},
+ {0x10b0, 0x0, MASK_ALL_BITS},
+ {0x10b8, 0x0, MASK_ALL_BITS},
+ {0x10c0, 0x0, MASK_ALL_BITS},
+ {0x10f0, 0x0, MASK_ALL_BITS},
+ {0x10f4, 0x0, MASK_ALL_BITS},
+ {0x10f8, 0xff, MASK_ALL_BITS},
+ {0x10fc, 0xffff, MASK_ALL_BITS},
+ {0x1130, 0x0, MASK_ALL_BITS},
+ {0x1830, 0x2000000, MASK_ALL_BITS},
+ {0x14d0, 0x0, MASK_ALL_BITS},
+ {0x14d4, 0x0, MASK_ALL_BITS},
+ {0x14d8, 0x0, MASK_ALL_BITS},
+ {0x14dc, 0x0, MASK_ALL_BITS},
+ {0x1454, 0x0, MASK_ALL_BITS},
+ {0x1594, 0x0, MASK_ALL_BITS},
+ {0x1598, 0x0, MASK_ALL_BITS},
+ {0x159c, 0x0, MASK_ALL_BITS},
+ {0x15a0, 0x0, MASK_ALL_BITS},
+ {0x15a4, 0x0, MASK_ALL_BITS},
+ {0x15a8, 0x0, MASK_ALL_BITS},
+ {0x15ac, 0x0, MASK_ALL_BITS},
+ {0x1604, 0x0, MASK_ALL_BITS},
+ {0x1608, 0x0, MASK_ALL_BITS},
+ {0x160c, 0x0, MASK_ALL_BITS},
+ {0x1610, 0x0, MASK_ALL_BITS},
+ {0x1614, 0x0, MASK_ALL_BITS},
+ {0x1618, 0x0, MASK_ALL_BITS},
+ {0x1624, 0x0, MASK_ALL_BITS},
+ {0x1690, 0x0, MASK_ALL_BITS},
+ {0x1694, 0x0, MASK_ALL_BITS},
+ {0x1698, 0x0, MASK_ALL_BITS},
+ {0x169c, 0x0, MASK_ALL_BITS},
+ {0x14b8, 0x6f67, MASK_ALL_BITS},
+ {0x1630, 0x0, MASK_ALL_BITS},
+ {0x1634, 0x0, MASK_ALL_BITS},
+ {0x1638, 0x0, MASK_ALL_BITS},
+ {0x163c, 0x0, MASK_ALL_BITS},
+ {0x16b0, 0x0, MASK_ALL_BITS},
+ {0x16b4, 0x0, MASK_ALL_BITS},
+ {0x16b8, 0x0, MASK_ALL_BITS},
+ {0x16bc, 0x0, MASK_ALL_BITS},
+ {0x16c0, 0x0, MASK_ALL_BITS},
+ {0x16c4, 0x0, MASK_ALL_BITS},
+ {0x16c8, 0x0, MASK_ALL_BITS},
+ {0x16cc, 0x1, MASK_ALL_BITS},
+ {0x16f0, 0x1, MASK_ALL_BITS},
+ {0x16f4, 0x0, MASK_ALL_BITS},
+ {0x16f8, 0x0, MASK_ALL_BITS},
+ {0x16fc, 0x0, MASK_ALL_BITS}
+};
+
+static int ddr3_tip_bus_access(u32 dev_num, enum hws_access_type interface_access,
+ u32 if_id, enum hws_access_type phy_access,
+ u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
+ u32 data_value, enum hws_operation oper_type);
+static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id);
+static int ddr3_tip_rank_control(u32 dev_num, u32 if_id);
+
+/*
+ * Update global training parameters by data from user
+ */
+int ddr3_tip_tune_training_params(u32 dev_num,
+ struct tune_train_params *params)
+{
+ if (params->ck_delay != -1)
+ ck_delay = params->ck_delay;
+ if (params->ck_delay_16 != -1)
+ ck_delay_16 = params->ck_delay_16;
+ if (params->phy_reg3_val != -1)
+ phy_reg3_val = params->phy_reg3_val;
+
+ return MV_OK;
+}
+
+/*
+ * Configure CS
+ */
+int ddr3_tip_configure_cs(u32 dev_num, u32 if_id, u32 cs_num, u32 enable)
+{
+ u32 data, addr_hi, data_high;
+ u32 mem_index;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (enable == 1) {
+ data = (tm->interface_params[if_id].bus_width ==
+ BUS_WIDTH_8) ? 0 : 1;
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ SDRAM_ACCESS_CONTROL_REG, (data << (cs_num * 4)),
+ 0x3 << (cs_num * 4)));
+ mem_index = tm->interface_params[if_id].memory_size;
+
+ addr_hi = mem_size_config[mem_index] & 0x3;
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ SDRAM_ACCESS_CONTROL_REG,
+ (addr_hi << (2 + cs_num * 4)),
+ 0x3 << (2 + cs_num * 4)));
+
+ data_high = (mem_size_config[mem_index] & 0x4) >> 2;
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ SDRAM_ACCESS_CONTROL_REG,
+ data_high << (20 + cs_num), 1 << (20 + cs_num)));
+
+ /* Enable Address Select Mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ SDRAM_ACCESS_CONTROL_REG, 1 << (16 + cs_num),
+ 1 << (16 + cs_num)));
+ }
+ switch (cs_num) {
+ case 0:
+ case 1:
+ case 2:
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ DDR_CONTROL_LOW_REG, (enable << (cs_num + 11)),
+ 1 << (cs_num + 11)));
+ break;
+ case 3:
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ DDR_CONTROL_LOW_REG, (enable << 15), 1 << 15));
+ break;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Calculate number of CS
+ */
+static int calc_cs_num(u32 dev_num, u32 if_id, u32 *cs_num)
+{
+ u32 cs;
+ u32 bus_cnt;
+ u32 cs_count;
+ u32 cs_bitmask;
+ u32 curr_cs_num = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ cs_count = 0;
+ cs_bitmask = tm->interface_params[if_id].
+ as_bus_params[bus_cnt].cs_bitmask;
+ for (cs = 0; cs < MAX_CS_NUM; cs++) {
+ if ((cs_bitmask >> cs) & 1)
+ cs_count++;
+ }
+
+ if (curr_cs_num == 0) {
+ curr_cs_num = cs_count;
+ } else if (cs_count != curr_cs_num) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("CS number is different per bus (IF %d BUS %d cs_num %d curr_cs_num %d)\n",
+ if_id, bus_cnt, cs_count,
+ curr_cs_num));
+ return MV_NOT_SUPPORTED;
+ }
+ }
+ *cs_num = curr_cs_num;
+
+ return MV_OK;
+}
+
+/*
+ * Init Controller Flow
+ */
+int hws_ddr3_tip_init_controller(u32 dev_num, struct init_cntr_param *init_cntr_prm)
+{
+ u32 if_id;
+ u32 cs_num;
+ u32 t_refi = 0, t_hclk = 0, t_ckclk = 0, t_faw = 0, t_pd = 0,
+ t_wr = 0, t2t = 0, txpdll = 0;
+ u32 data_value = 0, bus_width = 0, page_size = 0, cs_cnt = 0,
+ mem_mask = 0, bus_index = 0;
+ enum hws_speed_bin speed_bin_index = SPEED_BIN_DDR_2133N;
+ enum hws_mem_size memory_size = MEM_2G;
+ enum hws_ddr_freq freq = init_freq;
+ u32 cs_mask = 0;
+ u32 cl_value = 0, cwl_val = 0;
+ u32 refresh_interval_cnt = 0, bus_cnt = 0, adll_tap = 0;
+ enum hws_access_type access_type = ACCESS_TYPE_UNICAST;
+ u32 data_read[MAX_INTERFACE_NUM];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("Init_controller, do_mrs_phy=%d, is_ctrl64_bit=%d\n",
+ init_cntr_prm->do_mrs_phy,
+ init_cntr_prm->is_ctrl64_bit));
+
+ if (init_cntr_prm->init_phy == 1) {
+ CHECK_STATUS(ddr3_tip_configure_phy(dev_num));
+ }
+
+ if (generic_init_controller == 1) {
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("active IF %d\n", if_id));
+ mem_mask = 0;
+ for (bus_index = 0;
+ bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_index++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+ mem_mask |=
+ tm->interface_params[if_id].
+ as_bus_params[bus_index].mirror_enable_bitmask;
+ }
+
+ if (mem_mask != 0) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, CS_ENABLE_REG, 0,
+ 0x8));
+ }
+
+ memory_size =
+ tm->interface_params[if_id].
+ memory_size;
+ speed_bin_index =
+ tm->interface_params[if_id].
+ speed_bin_index;
+ freq = init_freq;
+ t_refi =
+ (tm->interface_params[if_id].
+ interface_temp ==
+ HWS_TEMP_HIGH) ? TREFI_HIGH : TREFI_LOW;
+ t_refi *= 1000; /* psec */
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("memy_size %d speed_bin_ind %d freq %d t_refi %d\n",
+ memory_size, speed_bin_index, freq,
+ t_refi));
+ /* HCLK & CK CLK in 2:1[ps] */
+ /* t_ckclk is external clock */
+ t_ckclk = (MEGA / freq_val[freq]);
+ /* t_hclk is internal clock */
+ t_hclk = 2 * t_ckclk;
+ refresh_interval_cnt = t_refi / t_hclk; /* no units */
+ bus_width =
+ (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask)
+ == 1) ? (16) : (32);
+
+ if (init_cntr_prm->is_ctrl64_bit)
+ bus_width = 64;
+
+ data_value =
+ (refresh_interval_cnt | 0x4000 |
+ ((bus_width ==
+ 32) ? 0x8000 : 0) | 0x1000000) & ~(1 << 26);
+
+ /* Interface Bus Width */
+ /* SRMode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_CONFIGURATION_REG, data_value,
+ 0x100ffff));
+
+ /* Interleave first command pre-charge enable (TBD) */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_OPEN_PAGE_CONTROL_REG, (1 << 10),
+ (1 << 10)));
+
+ /* PHY configuration */
+ /*
+ * Postamble Length = 1.5cc, Addresscntl to clk skew
+ * \BD, Preamble length normal, parralal ADLL enable
+ */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DRAM_PHY_CONFIGURATION, 0x28, 0x3e));
+ if (init_cntr_prm->is_ctrl64_bit) {
+ /* positive edge */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DRAM_PHY_CONFIGURATION, 0x0,
+ 0xff80));
+ }
+
+ /* calibration block disable */
+ /* Xbar Read buffer select (for Internal access) */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ CALIB_MACHINE_CTRL_REG, 0x1200c,
+ 0x7dffe01c));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ CALIB_MACHINE_CTRL_REG,
+ calibration_update_control << 3, 0x3 << 3));
+
+ /* Pad calibration control - enable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ CALIB_MACHINE_CTRL_REG, 0x1, 0x1));
+
+ cs_mask = 0;
+ data_value = 0x7;
+ /*
+ * Address ctrl \96 Part of the Generic code
+ * The next configuration is done:
+ * 1) Memory Size
+ * 2) Bus_width
+ * 3) CS#
+ * 4) Page Number
+ * 5) t_faw
+ * Per Dunit get from the Map_topology the parameters:
+ * Bus_width
+ * t_faw is per Dunit not per CS
+ */
+ page_size =
+ (tm->interface_params[if_id].
+ bus_width ==
+ BUS_WIDTH_8) ? page_param[memory_size].
+ page_size_8bit : page_param[memory_size].
+ page_size_16bit;
+
+ t_faw =
+ (page_size == 1) ? speed_bin_table(speed_bin_index,
+ SPEED_BIN_TFAW1K)
+ : speed_bin_table(speed_bin_index,
+ SPEED_BIN_TFAW2K);
+
+ data_value = TIME_2_CLOCK_CYCLES(t_faw, t_ckclk);
+ data_value = data_value << 24;
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_ACCESS_CONTROL_REG, data_value,
+ 0x7f000000));
+
+ data_value =
+ (tm->interface_params[if_id].
+ bus_width == BUS_WIDTH_8) ? 0 : 1;
+
+ /* create merge cs mask for all cs available in dunit */
+ for (bus_cnt = 0;
+ bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ cs_mask |=
+ tm->interface_params[if_id].
+ as_bus_params[bus_cnt].cs_bitmask;
+ }
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("Init_controller IF %d cs_mask %d\n",
+ if_id, cs_mask));
+ /*
+ * Configure the next upon the Map Topology \96 If the
+ * Dunit is CS0 Configure CS0 if it is multi CS
+ * configure them both: The Bust_width it\92s the
+ * Memory Bus width \96 x8 or x16
+ */
+ for (cs_cnt = 0; cs_cnt < NUM_OF_CS; cs_cnt++) {
+ ddr3_tip_configure_cs(dev_num, if_id, cs_cnt,
+ ((cs_mask & (1 << cs_cnt)) ? 1
+ : 0));
+ }
+
+ if (init_cntr_prm->do_mrs_phy) {
+ /*
+ * MR0 \96 Part of the Generic code
+ * The next configuration is done:
+ * 1) Burst Length
+ * 2) CAS Latency
+ * get for each dunit what is it Speed_bin &
+ * Target Frequency. From those both parameters
+ * get the appropriate Cas_l from the CL table
+ */
+ cl_value =
+ tm->interface_params[if_id].
+ cas_l;
+ cwl_val =
+ tm->interface_params[if_id].
+ cas_wl;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("cl_value 0x%x cwl_val 0x%x\n",
+ cl_value, cwl_val));
+
+ data_value =
+ ((cl_mask_table[cl_value] & 0x1) << 2) |
+ ((cl_mask_table[cl_value] & 0xe) << 3);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ MR0_REG, data_value,
+ (0x7 << 4) | (1 << 2)));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ MR0_REG, twr_mask_table[t_wr + 1],
+ 0xe00));
+
+ /*
+ * MR1: Set RTT and DIC Design GL values
+ * configured by user
+ */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, MR1_REG,
+ g_dic | g_rtt_nom, 0x266));
+
+ /* MR2 - Part of the Generic code */
+ /*
+ * The next configuration is done:
+ * 1) SRT
+ * 2) CAS Write Latency
+ */
+ data_value = (cwl_mask_table[cwl_val] << 3);
+ data_value |=
+ ((tm->interface_params[if_id].
+ interface_temp ==
+ HWS_TEMP_HIGH) ? (1 << 7) : 0);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ MR2_REG, data_value,
+ (0x7 << 3) | (0x1 << 7) | (0x3 <<
+ 9)));
+ }
+
+ ddr3_tip_write_odt(dev_num, access_type, if_id,
+ cl_value, cwl_val);
+ ddr3_tip_set_timing(dev_num, access_type, if_id, freq);
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DUNIT_CONTROL_HIGH_REG, 0x177,
+ 0x1000177));
+
+ if (init_cntr_prm->is_ctrl64_bit) {
+ /* disable 0.25 cc delay */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DUNIT_CONTROL_HIGH_REG, 0x0,
+ 0x800));
+ }
+
+ /* reset bit 7 */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DUNIT_CONTROL_HIGH_REG,
+ (init_cntr_prm->msys_init << 7), (1 << 7)));
+
+ if (mode2_t != 0xff) {
+ t2t = mode2_t;
+ } else {
+ /* calculate number of CS (per interface) */
+ CHECK_STATUS(calc_cs_num
+ (dev_num, if_id, &cs_num));
+ t2t = (cs_num == 1) ? 0 : 1;
+ }
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DDR_CONTROL_LOW_REG, t2t << 3,
+ 0x3 << 3));
+ /* move the block to ddr3_tip_set_timing - start */
+ t_pd = GET_MAX_VALUE(t_ckclk * 3,
+ speed_bin_table(speed_bin_index,
+ SPEED_BIN_TPD));
+ t_pd = TIME_2_CLOCK_CYCLES(t_pd, t_ckclk);
+ txpdll = GET_MAX_VALUE(t_ckclk * 10, 24);
+ txpdll = CEIL_DIVIDE((txpdll - 1), t_ckclk);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DDR_TIMING_REG, txpdll << 4,
+ 0x1f << 4));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DDR_TIMING_REG, 0x28 << 9, 0x3f << 9));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DDR_TIMING_REG, 0xa << 21, 0xff << 21));
+
+ /* move the block to ddr3_tip_set_timing - end */
+ /* AUTO_ZQC_TIMING */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ TIMING_REG, (AUTO_ZQC_TIMING | (2 << 20)),
+ 0x3fffff));
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, access_type, if_id,
+ DRAM_PHY_CONFIGURATION, data_read, 0x30));
+ data_value =
+ (data_read[if_id] == 0) ? (1 << 11) : 0;
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DUNIT_CONTROL_HIGH_REG, data_value,
+ (1 << 11)));
+
+ /* Set Active control for ODT write transactions */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, 0x1494, g_odt_config,
+ MASK_ALL_BITS));
+ }
+ } else {
+#ifdef STATIC_ALGO_SUPPORT
+ CHECK_STATUS(ddr3_tip_static_init_controller(dev_num));
+#if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X)
+ CHECK_STATUS(ddr3_tip_static_phy_init_controller(dev_num));
+#endif
+#endif /* STATIC_ALGO_SUPPORT */
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_rank_control(dev_num, if_id));
+
+ if (init_cntr_prm->do_mrs_phy) {
+ CHECK_STATUS(ddr3_tip_pad_inv(dev_num, if_id));
+ }
+
+ /* Pad calibration control - disable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ CALIB_MACHINE_CTRL_REG, 0x0, 0x1));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ CALIB_MACHINE_CTRL_REG,
+ calibration_update_control << 3, 0x3 << 3));
+ }
+
+ CHECK_STATUS(ddr3_tip_enable_init_sequence(dev_num));
+
+ if (delay_enable != 0) {
+ adll_tap = MEGA / (freq_val[freq] * 64);
+ ddr3_tip_cmd_addr_init_delay(dev_num, adll_tap);
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Load Topology map
+ */
+int hws_ddr3_tip_load_topology_map(u32 dev_num, struct hws_topology_map *tm)
+{
+ enum hws_speed_bin speed_bin_index;
+ enum hws_ddr_freq freq = DDR_FREQ_LIMIT;
+ u32 if_id;
+
+ freq_val[DDR_FREQ_LOW_FREQ] = dfs_low_freq;
+ tm = ddr3_get_topology_map();
+ CHECK_STATUS(ddr3_tip_get_first_active_if
+ ((u8)dev_num, tm->if_act_mask,
+ &first_active_if));
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("board IF_Mask=0x%x num_of_bus_per_interface=0x%x\n",
+ tm->if_act_mask,
+ tm->num_of_bus_per_interface));
+
+ /*
+ * if CL, CWL values are missing in topology map, then fill them
+ * according to speedbin tables
+ */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ speed_bin_index =
+ tm->interface_params[if_id].speed_bin_index;
+ /* TBD memory frequency of interface 0 only is used ! */
+ freq = tm->interface_params[first_active_if].memory_freq;
+
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("speed_bin_index =%d freq=%d cl=%d cwl=%d\n",
+ speed_bin_index, freq_val[freq],
+ tm->interface_params[if_id].
+ cas_l,
+ tm->interface_params[if_id].
+ cas_wl));
+
+ if (tm->interface_params[if_id].cas_l == 0) {
+ tm->interface_params[if_id].cas_l =
+ cas_latency_table[speed_bin_index].cl_val[freq];
+ }
+
+ if (tm->interface_params[if_id].cas_wl == 0) {
+ tm->interface_params[if_id].cas_wl =
+ cas_write_latency_table[speed_bin_index].cl_val[freq];
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * RANK Control Flow
+ */
+static int ddr3_tip_rank_control(u32 dev_num, u32 if_id)
+{
+ u32 data_value = 0, bus_cnt;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (bus_cnt = 1; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ if ((tm->interface_params[if_id].
+ as_bus_params[0].cs_bitmask !=
+ tm->interface_params[if_id].
+ as_bus_params[bus_cnt].cs_bitmask) ||
+ (tm->interface_params[if_id].
+ as_bus_params[0].mirror_enable_bitmask !=
+ tm->interface_params[if_id].
+ as_bus_params[bus_cnt].mirror_enable_bitmask))
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("WARNING:Wrong configuration for pup #%d CS mask and CS mirroring for all pups should be the same\n",
+ bus_cnt));
+ }
+
+ data_value |= tm->interface_params[if_id].
+ as_bus_params[0].cs_bitmask;
+ data_value |= tm->interface_params[if_id].
+ as_bus_params[0].mirror_enable_bitmask << 4;
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, RANK_CTRL_REG,
+ data_value, 0xff));
+
+ return MV_OK;
+}
+
+/*
+ * PAD Inverse Flow
+ */
+static int ddr3_tip_pad_inv(u32 dev_num, u32 if_id)
+{
+ u32 bus_cnt, data_value, ck_swap_pup_ctrl;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ if (tm->interface_params[if_id].
+ as_bus_params[bus_cnt].is_dqs_swap == 1) {
+ /* dqs swap */
+ ddr3_tip_bus_read_modify_write(dev_num, ACCESS_TYPE_UNICAST,
+ if_id, bus_cnt,
+ DDR_PHY_DATA,
+ PHY_CONTROL_PHY_REG, 0xc0,
+ 0xc0);
+ }
+
+ if (tm->interface_params[if_id].
+ as_bus_params[bus_cnt].is_ck_swap == 1) {
+ if (bus_cnt <= 1)
+ data_value = 0x5 << 2;
+ else
+ data_value = 0xa << 2;
+
+ /* mask equals data */
+ /* ck swap pup is only control pup #0 ! */
+ ck_swap_pup_ctrl = 0;
+ ddr3_tip_bus_read_modify_write(dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ck_swap_pup_ctrl,
+ DDR_PHY_CONTROL,
+ PHY_CONTROL_PHY_REG,
+ data_value, data_value);
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Run Training Flow
+ */
+int hws_ddr3_tip_run_alg(u32 dev_num, enum hws_algo_type algo_type)
+{
+ int ret = MV_OK, ret_tune = MV_OK;
+
+#ifdef ODT_TEST_SUPPORT
+ if (finger_test == 1)
+ return odt_test(dev_num, algo_type);
+#endif
+
+ if (algo_type == ALGO_TYPE_DYNAMIC) {
+ ret = ddr3_tip_ddr3_auto_tune(dev_num);
+ } else {
+#ifdef STATIC_ALGO_SUPPORT
+ {
+ enum hws_ddr_freq freq;
+ freq = init_freq;
+
+ /* add to mask */
+ if (is_adll_calib_before_init != 0) {
+ printf("with adll calib before init\n");
+ adll_calibration(dev_num, ACCESS_TYPE_MULTICAST,
+ 0, freq);
+ }
+ /*
+ * Frequency per interface is not relevant,
+ * only interface 0
+ */
+ ret = ddr3_tip_run_static_alg(dev_num,
+ freq);
+ }
+#endif
+ }
+
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Run_alg: tuning failed %d\n", ret_tune));
+ }
+
+ return ret;
+}
+
+#ifdef ODT_TEST_SUPPORT
+/*
+ * ODT Test
+ */
+static int odt_test(u32 dev_num, enum hws_algo_type algo_type)
+{
+ int ret = MV_OK, ret_tune = MV_OK;
+ int pfinger_val = 0, nfinger_val;
+
+ for (pfinger_val = p_finger_start; pfinger_val <= p_finger_end;
+ pfinger_val += p_finger_step) {
+ for (nfinger_val = n_finger_start; nfinger_val <= n_finger_end;
+ nfinger_val += n_finger_step) {
+ if (finger_test != 0) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("pfinger_val %d nfinger_val %d\n",
+ pfinger_val, nfinger_val));
+ p_finger = pfinger_val;
+ n_finger = nfinger_val;
+ }
+
+ if (algo_type == ALGO_TYPE_DYNAMIC) {
+ ret = ddr3_tip_ddr3_auto_tune(dev_num);
+ } else {
+ /*
+ * Frequency per interface is not relevant,
+ * only interface 0
+ */
+ ret = ddr3_tip_run_static_alg(dev_num,
+ init_freq);
+ }
+ }
+ }
+
+ if (ret_tune != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Run_alg: tuning failed %d\n", ret_tune));
+ ret = (ret == MV_OK) ? ret_tune : ret;
+ }
+
+ return ret;
+}
+#endif
+
+/*
+ * Select Controller
+ */
+int hws_ddr3_tip_select_ddr_controller(u32 dev_num, int enable)
+{
+ if (config_func_info[dev_num].tip_dunit_mux_select_func != NULL) {
+ return config_func_info[dev_num].
+ tip_dunit_mux_select_func((u8)dev_num, enable);
+ }
+
+ return MV_FAIL;
+}
+
+/*
+ * Dunit Register Write
+ */
+int ddr3_tip_if_write(u32 dev_num, enum hws_access_type interface_access,
+ u32 if_id, u32 reg_addr, u32 data_value, u32 mask)
+{
+ if (config_func_info[dev_num].tip_dunit_write_func != NULL) {
+ return config_func_info[dev_num].
+ tip_dunit_write_func((u8)dev_num, interface_access,
+ if_id, reg_addr,
+ data_value, mask);
+ }
+
+ return MV_FAIL;
+}
+
+/*
+ * Dunit Register Read
+ */
+int ddr3_tip_if_read(u32 dev_num, enum hws_access_type interface_access,
+ u32 if_id, u32 reg_addr, u32 *data, u32 mask)
+{
+ if (config_func_info[dev_num].tip_dunit_read_func != NULL) {
+ return config_func_info[dev_num].
+ tip_dunit_read_func((u8)dev_num, interface_access,
+ if_id, reg_addr,
+ data, mask);
+ }
+
+ return MV_FAIL;
+}
+
+/*
+ * Dunit Register Polling
+ */
+int ddr3_tip_if_polling(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, u32 exp_value, u32 mask, u32 offset,
+ u32 poll_tries)
+{
+ u32 poll_cnt = 0, interface_num = 0, start_if, end_if;
+ u32 read_data[MAX_INTERFACE_NUM];
+ int ret;
+ int is_fail = 0, is_if_fail;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (access_type == ACCESS_TYPE_MULTICAST) {
+ start_if = 0;
+ end_if = MAX_INTERFACE_NUM - 1;
+ } else {
+ start_if = if_id;
+ end_if = if_id;
+ }
+
+ for (interface_num = start_if; interface_num <= end_if; interface_num++) {
+ /* polling bit 3 for n times */
+ VALIDATE_ACTIVE(tm->if_act_mask, interface_num);
+
+ is_if_fail = 0;
+ for (poll_cnt = 0; poll_cnt < poll_tries; poll_cnt++) {
+ ret =
+ ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST,
+ interface_num, offset, read_data,
+ mask);
+ if (ret != MV_OK)
+ return ret;
+
+ if (read_data[interface_num] == exp_value)
+ break;
+ }
+
+ if (poll_cnt >= poll_tries) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("max poll IF #%d\n", interface_num));
+ is_fail = 1;
+ is_if_fail = 1;
+ }
+
+ training_result[training_stage][interface_num] =
+ (is_if_fail == 1) ? TEST_FAILED : TEST_SUCCESS;
+ }
+
+ return (is_fail == 0) ? MV_OK : MV_FAIL;
+}
+
+/*
+ * Bus read access
+ */
+int ddr3_tip_bus_read(u32 dev_num, u32 if_id,
+ enum hws_access_type phy_access, u32 phy_id,
+ enum hws_ddr_phy phy_type, u32 reg_addr, u32 *data)
+{
+ u32 bus_index = 0;
+ u32 data_read[MAX_INTERFACE_NUM];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (phy_access == ACCESS_TYPE_MULTICAST) {
+ for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_index++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+ CHECK_STATUS(ddr3_tip_bus_access
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ bus_index, phy_type, reg_addr, 0,
+ OPERATION_READ));
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ PHY_REG_FILE_ACCESS, data_read,
+ MASK_ALL_BITS));
+ data[bus_index] = (data_read[if_id] & 0xffff);
+ }
+ } else {
+ CHECK_STATUS(ddr3_tip_bus_access
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ phy_access, phy_id, phy_type, reg_addr, 0,
+ OPERATION_READ));
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ PHY_REG_FILE_ACCESS, data_read, MASK_ALL_BITS));
+
+ /*
+ * only 16 lsb bit are valid in Phy (each register is different,
+ * some can actually be less than 16 bits)
+ */
+ *data = (data_read[if_id] & 0xffff);
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Bus write access
+ */
+int ddr3_tip_bus_write(u32 dev_num, enum hws_access_type interface_access,
+ u32 if_id, enum hws_access_type phy_access,
+ u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
+ u32 data_value)
+{
+ CHECK_STATUS(ddr3_tip_bus_access
+ (dev_num, interface_access, if_id, phy_access,
+ phy_id, phy_type, reg_addr, data_value, OPERATION_WRITE));
+
+ return MV_OK;
+}
+
+/*
+ * Bus access routine (relevant for both read & write)
+ */
+static int ddr3_tip_bus_access(u32 dev_num, enum hws_access_type interface_access,
+ u32 if_id, enum hws_access_type phy_access,
+ u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
+ u32 data_value, enum hws_operation oper_type)
+{
+ u32 addr_low = 0x3f & reg_addr;
+ u32 addr_hi = ((0xc0 & reg_addr) >> 6);
+ u32 data_p1 =
+ (oper_type << 30) + (addr_hi << 28) + (phy_access << 27) +
+ (phy_type << 26) + (phy_id << 22) + (addr_low << 16) +
+ (data_value & 0xffff);
+ u32 data_p2 = data_p1 + (1 << 31);
+ u32 start_if, end_if;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, interface_access, if_id, PHY_REG_FILE_ACCESS,
+ data_p1, MASK_ALL_BITS));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, interface_access, if_id, PHY_REG_FILE_ACCESS,
+ data_p2, MASK_ALL_BITS));
+
+ if (interface_access == ACCESS_TYPE_UNICAST) {
+ start_if = if_id;
+ end_if = if_id;
+ } else {
+ start_if = 0;
+ end_if = MAX_INTERFACE_NUM - 1;
+ }
+
+ /* polling for read/write execution done */
+ for (if_id = start_if; if_id <= end_if; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(is_bus_access_done
+ (dev_num, if_id, PHY_REG_FILE_ACCESS, 31));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Check bus access done
+ */
+static int is_bus_access_done(u32 dev_num, u32 if_id, u32 dunit_reg_adrr,
+ u32 bit)
+{
+ u32 rd_data = 1;
+ u32 cnt = 0;
+ u32 data_read[MAX_INTERFACE_NUM];
+
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, dunit_reg_adrr,
+ data_read, MASK_ALL_BITS));
+ rd_data = data_read[if_id];
+ rd_data &= (1 << bit);
+
+ while (rd_data != 0) {
+ if (cnt++ >= MAX_POLLING_ITERATIONS)
+ break;
+
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ dunit_reg_adrr, data_read, MASK_ALL_BITS));
+ rd_data = data_read[if_id];
+ rd_data &= (1 << bit);
+ }
+
+ if (cnt < MAX_POLLING_ITERATIONS)
+ return MV_OK;
+ else
+ return MV_FAIL;
+}
+
+/*
+ * Phy read-modify-write
+ */
+int ddr3_tip_bus_read_modify_write(u32 dev_num, enum hws_access_type access_type,
+ u32 interface_id, u32 phy_id,
+ enum hws_ddr_phy phy_type, u32 reg_addr,
+ u32 data_value, u32 reg_mask)
+{
+ u32 data_val = 0, if_id, start_if, end_if;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (access_type == ACCESS_TYPE_MULTICAST) {
+ start_if = 0;
+ end_if = MAX_INTERFACE_NUM - 1;
+ } else {
+ start_if = interface_id;
+ end_if = interface_id;
+ }
+
+ for (if_id = start_if; if_id <= end_if; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST, phy_id,
+ phy_type, reg_addr, &data_val));
+ data_value = (data_val & (~reg_mask)) | (data_value & reg_mask);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, phy_id, phy_type, reg_addr,
+ data_value));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * ADLL Calibration
+ */
+int adll_calibration(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_ddr_freq frequency)
+{
+ struct hws_tip_freq_config_info freq_config_info;
+ u32 bus_cnt = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* Reset Diver_b assert -> de-assert */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
+ 0, 0x10000000));
+ mdelay(10);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
+ 0x10000000, 0x10000000));
+
+ if (config_func_info[dev_num].tip_get_freq_config_info_func != NULL) {
+ CHECK_STATUS(config_func_info[dev_num].
+ tip_get_freq_config_info_func((u8)dev_num, frequency,
+ &freq_config_info));
+ } else {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("tip_get_freq_config_info_func is NULL"));
+ return MV_NOT_INITIALIZED;
+ }
+
+ for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES(); bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, access_type, if_id, bus_cnt,
+ DDR_PHY_DATA, BW_PHY_REG,
+ freq_config_info.bw_per_freq << 8, 0x700));
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, access_type, if_id, bus_cnt,
+ DDR_PHY_DATA, RATE_PHY_REG,
+ freq_config_info.rate_per_freq, 0x7));
+ }
+
+ /* DUnit to Phy drive post edge, ADLL reset assert de-assert */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DRAM_PHY_CONFIGURATION,
+ 0, (0x80000000 | 0x40000000)));
+ mdelay(100 / (freq_val[frequency] / freq_val[DDR_FREQ_LOW_FREQ]));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DRAM_PHY_CONFIGURATION,
+ (0x80000000 | 0x40000000), (0x80000000 | 0x40000000)));
+
+ /* polling for ADLL Done */
+ if (ddr3_tip_if_polling(dev_num, access_type, if_id,
+ 0x3ff03ff, 0x3ff03ff, PHY_LOCK_STATUS_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Freq_set: DDR3 poll failed(1)"));
+ }
+
+ /* pup data_pup reset assert-> deassert */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
+ 0, 0x60000000));
+ mdelay(10);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, SDRAM_CONFIGURATION_REG,
+ 0x60000000, 0x60000000));
+
+ return MV_OK;
+}
+
+int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_ddr_freq frequency)
+{
+ u32 cl_value = 0, cwl_value = 0, mem_mask = 0, val = 0,
+ bus_cnt = 0, t_hclk = 0, t_wr = 0,
+ refresh_interval_cnt = 0, cnt_id;
+ u32 t_refi = 0, end_if, start_if;
+ u32 bus_index = 0;
+ int is_dll_off = 0;
+ enum hws_speed_bin speed_bin_index = 0;
+ struct hws_tip_freq_config_info freq_config_info;
+ enum hws_result *flow_result = training_result[training_stage];
+ u32 adll_tap = 0;
+ u32 cs_mask[MAX_INTERFACE_NUM];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("dev %d access %d IF %d freq %d\n", dev_num,
+ access_type, if_id, frequency));
+
+ if (frequency == DDR_FREQ_LOW_FREQ)
+ is_dll_off = 1;
+ if (access_type == ACCESS_TYPE_MULTICAST) {
+ start_if = 0;
+ end_if = MAX_INTERFACE_NUM - 1;
+ } else {
+ start_if = if_id;
+ end_if = if_id;
+ }
+
+ /* calculate interface cs mask - Oferb 4/11 */
+ /* speed bin can be different for each interface */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ /* cs enable is active low */
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ cs_mask[if_id] = CS_BIT_MASK;
+ training_result[training_stage][if_id] = TEST_SUCCESS;
+ ddr3_tip_calc_cs_mask(dev_num, if_id, effective_cs,
+ &cs_mask[if_id]);
+ }
+
+ /* speed bin can be different for each interface */
+ /*
+ * moti b - need to remove the loop for multicas access functions
+ * and loop the unicast access functions
+ */
+ for (if_id = start_if; if_id <= end_if; if_id++) {
+ if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
+ continue;
+
+ flow_result[if_id] = TEST_SUCCESS;
+ speed_bin_index =
+ tm->interface_params[if_id].speed_bin_index;
+ if (tm->interface_params[if_id].memory_freq ==
+ frequency) {
+ cl_value =
+ tm->interface_params[if_id].cas_l;
+ cwl_value =
+ tm->interface_params[if_id].cas_wl;
+ } else {
+ cl_value =
+ cas_latency_table[speed_bin_index].cl_val[frequency];
+ cwl_value =
+ cas_write_latency_table[speed_bin_index].
+ cl_val[frequency];
+ }
+
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("Freq_set dev 0x%x access 0x%x if 0x%x freq 0x%x speed %d:\n\t",
+ dev_num, access_type, if_id,
+ frequency, speed_bin_index));
+
+ for (cnt_id = 0; cnt_id < DDR_FREQ_LIMIT; cnt_id++) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE,
+ ("%d ",
+ cas_latency_table[speed_bin_index].
+ cl_val[cnt_id]));
+ }
+
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_TRACE, ("\n"));
+ mem_mask = 0;
+ for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_index++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+ mem_mask |=
+ tm->interface_params[if_id].
+ as_bus_params[bus_index].mirror_enable_bitmask;
+ }
+
+ if (mem_mask != 0) {
+ /* motib redundent in KW28 */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
+ if_id,
+ CS_ENABLE_REG, 0, 0x8));
+ }
+
+ /* dll state after exiting SR */
+ if (is_dll_off == 1) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DFS_REG, 0x1, 0x1));
+ } else {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DFS_REG, 0, 0x1));
+ }
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DUNIT_MMASK_REG, 0, 0x1));
+ /* DFS - block transactions */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DFS_REG, 0x2, 0x2));
+
+ /* disable ODT in case of dll off */
+ if (is_dll_off == 1) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ 0x1874, 0, 0x244));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ 0x1884, 0, 0x244));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ 0x1894, 0, 0x244));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ 0x18a4, 0, 0x244));
+ }
+
+ /* DFS - Enter Self-Refresh */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DFS_REG, 0x4,
+ 0x4));
+ /* polling on self refresh entry */
+ if (ddr3_tip_if_polling(dev_num, ACCESS_TYPE_UNICAST,
+ if_id, 0x8, 0x8, DFS_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Freq_set: DDR3 poll failed on SR entry\n"));
+ }
+
+ /* PLL configuration */
+ if (config_func_info[dev_num].tip_set_freq_divider_func != NULL) {
+ config_func_info[dev_num].
+ tip_set_freq_divider_func(dev_num, if_id,
+ frequency);
+ }
+
+ /* PLL configuration End */
+
+ /* adjust t_refi to new frequency */
+ t_refi = (tm->interface_params[if_id].interface_temp ==
+ HWS_TEMP_HIGH) ? TREFI_LOW : TREFI_HIGH;
+ t_refi *= 1000; /*psec */
+
+ /* HCLK in[ps] */
+ t_hclk = MEGA / (freq_val[frequency] / 2);
+ refresh_interval_cnt = t_refi / t_hclk; /* no units */
+ val = 0x4000 | refresh_interval_cnt;
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_CONFIGURATION_REG, val, 0x7fff));
+
+ /* DFS - CL/CWL/WR parameters after exiting SR */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DFS_REG,
+ (cl_mask_table[cl_value] << 8), 0xf00));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DFS_REG,
+ (cwl_mask_table[cwl_value] << 12), 0x7000));
+ t_wr = speed_bin_table(speed_bin_index, SPEED_BIN_TWR);
+ t_wr = (t_wr / 1000);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DFS_REG,
+ (twr_mask_table[t_wr + 1] << 16), 0x70000));
+
+ /* Restore original RTT values if returning from DLL OFF mode */
+ if (is_dll_off == 1) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, 0x1874,
+ g_dic | g_rtt_nom, 0x266));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, 0x1884,
+ g_dic | g_rtt_nom, 0x266));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, 0x1894,
+ g_dic | g_rtt_nom, 0x266));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, 0x18a4,
+ g_dic | g_rtt_nom, 0x266));
+ }
+
+ /* Reset Diver_b assert -> de-assert */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_CONFIGURATION_REG, 0, 0x10000000));
+ mdelay(10);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_CONFIGURATION_REG, 0x10000000, 0x10000000));
+
+ /* Adll configuration function of process and Frequency */
+ if (config_func_info[dev_num].tip_get_freq_config_info_func != NULL) {
+ CHECK_STATUS(config_func_info[dev_num].
+ tip_get_freq_config_info_func(dev_num, frequency,
+ &freq_config_info));
+ }
+ /* TBD check milo5 using device ID ? */
+ for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, bus_cnt, DDR_PHY_DATA,
+ 0x92,
+ freq_config_info.
+ bw_per_freq << 8
+ /*freq_mask[dev_num][frequency] << 8 */
+ , 0x700));
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ bus_cnt, DDR_PHY_DATA, 0x94,
+ freq_config_info.rate_per_freq, 0x7));
+ }
+
+ /* DUnit to Phy drive post edge, ADLL reset assert de-assert */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DRAM_PHY_CONFIGURATION, 0,
+ (0x80000000 | 0x40000000)));
+ mdelay(100 / (freq_val[frequency] / freq_val[DDR_FREQ_LOW_FREQ]));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ DRAM_PHY_CONFIGURATION, (0x80000000 | 0x40000000),
+ (0x80000000 | 0x40000000)));
+
+ /* polling for ADLL Done */
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x3ff03ff,
+ 0x3ff03ff, PHY_LOCK_STATUS_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Freq_set: DDR3 poll failed(1)\n"));
+ }
+
+ /* pup data_pup reset assert-> deassert */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_CONFIGURATION_REG, 0, 0x60000000));
+ mdelay(10);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_CONFIGURATION_REG, 0x60000000, 0x60000000));
+
+ /* Set proper timing params before existing Self-Refresh */
+ ddr3_tip_set_timing(dev_num, access_type, if_id, frequency);
+ if (delay_enable != 0) {
+ adll_tap = MEGA / (freq_val[frequency] * 64);
+ ddr3_tip_cmd_addr_init_delay(dev_num, adll_tap);
+ }
+
+ /* Exit SR */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DFS_REG, 0,
+ 0x4));
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x8, DFS_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Freq_set: DDR3 poll failed(2)"));
+ }
+
+ /* Refresh Command */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ SDRAM_OPERATION_REG, 0x2, 0xf1f));
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1f,
+ SDRAM_OPERATION_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Freq_set: DDR3 poll failed(3)"));
+ }
+
+ /* Release DFS Block */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DFS_REG, 0,
+ 0x2));
+ /* Controller to MBUS Retry - normal */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, DUNIT_MMASK_REG,
+ 0x1, 0x1));
+
+ /* MRO: Burst Length 8, CL , Auto_precharge 0x16cc */
+ val =
+ ((cl_mask_table[cl_value] & 0x1) << 2) |
+ ((cl_mask_table[cl_value] & 0xe) << 3);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id, MR0_REG,
+ val, (0x7 << 4) | (1 << 2)));
+ /* MR2: CWL = 10 , Auto Self-Refresh - disable */
+ val = (cwl_mask_table[cwl_value] << 3);
+ /*
+ * nklein 24.10.13 - should not be here - leave value as set in
+ * the init configuration val |= (1 << 9);
+ * val |= ((tm->interface_params[if_id].
+ * interface_temp == HWS_TEMP_HIGH) ? (1 << 7) : 0);
+ */
+ /* nklein 24.10.13 - see above comment */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
+ if_id, MR2_REG,
+ val, (0x7 << 3)));
+
+ /* ODT TIMING */
+ val = ((cl_value - cwl_value + 1) << 4) |
+ ((cl_value - cwl_value + 6) << 8) |
+ ((cl_value - 1) << 12) | ((cl_value + 6) << 16);
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
+ if_id, ODT_TIMING_LOW,
+ val, 0xffff0));
+ val = 0x71 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12);
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
+ if_id, ODT_TIMING_HI_REG,
+ val, 0xffff));
+
+ /* ODT Active */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
+ if_id,
+ DUNIT_ODT_CONTROL_REG,
+ 0xf, 0xf));
+
+ /* re-write CL */
+ val = ((cl_mask_table[cl_value] & 0x1) << 2) |
+ ((cl_mask_table[cl_value] & 0xe) << 3);
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ 0, MR0_REG, val,
+ (0x7 << 4) | (1 << 2)));
+
+ /* re-write CWL */
+ val = (cwl_mask_table[cwl_value] << 3);
+ CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask, MRS2_CMD,
+ val, (0x7 << 3)));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ 0, MR2_REG, val, (0x7 << 3)));
+
+ if (mem_mask != 0) {
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
+ if_id,
+ CS_ENABLE_REG,
+ 1 << 3, 0x8));
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Set ODT values
+ */
+static int ddr3_tip_write_odt(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, u32 cl_value, u32 cwl_value)
+{
+ /* ODT TIMING */
+ u32 val = (cl_value - cwl_value + 6);
+
+ val = ((cl_value - cwl_value + 1) << 4) | ((val & 0xf) << 8) |
+ (((cl_value - 1) & 0xf) << 12) |
+ (((cl_value + 6) & 0xf) << 16) | (((val & 0x10) >> 4) << 21);
+ val |= (((cl_value - 1) >> 4) << 22) | (((cl_value + 6) >> 4) << 23);
+
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ ODT_TIMING_LOW, val, 0xffff0));
+ val = 0x71 | ((cwl_value - 1) << 8) | ((cwl_value + 5) << 12);
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ ODT_TIMING_HI_REG, val, 0xffff));
+ if (odt_additional == 1) {
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type,
+ if_id,
+ SDRAM_ODT_CONTROL_HIGH_REG,
+ 0xf, 0xf));
+ }
+
+ /* ODT Active */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ DUNIT_ODT_CONTROL_REG, 0xf, 0xf));
+
+ return MV_OK;
+}
+
+/*
+ * Set Timing values for training
+ */
+static int ddr3_tip_set_timing(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_ddr_freq frequency)
+{
+ u32 t_ckclk = 0, t_ras = 0;
+ u32 t_rcd = 0, t_rp = 0, t_wr = 0, t_wtr = 0, t_rrd = 0, t_rtp = 0,
+ t_rfc = 0, t_mod = 0;
+ u32 val = 0, page_size = 0;
+ enum hws_speed_bin speed_bin_index;
+ enum hws_mem_size memory_size = MEM_2G;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ speed_bin_index = tm->interface_params[if_id].speed_bin_index;
+ memory_size = tm->interface_params[if_id].memory_size;
+ page_size =
+ (tm->interface_params[if_id].bus_width ==
+ BUS_WIDTH_8) ? page_param[memory_size].
+ page_size_8bit : page_param[memory_size].page_size_16bit;
+ t_ckclk = (MEGA / freq_val[frequency]);
+ t_rrd = (page_size == 1) ? speed_bin_table(speed_bin_index,
+ SPEED_BIN_TRRD1K) :
+ speed_bin_table(speed_bin_index, SPEED_BIN_TRRD2K);
+ t_rrd = GET_MAX_VALUE(t_ckclk * 4, t_rrd);
+ t_rtp = GET_MAX_VALUE(t_ckclk * 4, speed_bin_table(speed_bin_index,
+ SPEED_BIN_TRTP));
+ t_wtr = GET_MAX_VALUE(t_ckclk * 4, speed_bin_table(speed_bin_index,
+ SPEED_BIN_TWTR));
+ t_ras = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
+ SPEED_BIN_TRAS),
+ t_ckclk);
+ t_rcd = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
+ SPEED_BIN_TRCD),
+ t_ckclk);
+ t_rp = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
+ SPEED_BIN_TRP),
+ t_ckclk);
+ t_wr = TIME_2_CLOCK_CYCLES(speed_bin_table(speed_bin_index,
+ SPEED_BIN_TWR),
+ t_ckclk);
+ t_wtr = TIME_2_CLOCK_CYCLES(t_wtr, t_ckclk);
+ t_rrd = TIME_2_CLOCK_CYCLES(t_rrd, t_ckclk);
+ t_rtp = TIME_2_CLOCK_CYCLES(t_rtp, t_ckclk);
+ t_rfc = TIME_2_CLOCK_CYCLES(rfc_table[memory_size] * 1000, t_ckclk);
+ t_mod = GET_MAX_VALUE(t_ckclk * 24, 15000);
+ t_mod = TIME_2_CLOCK_CYCLES(t_mod, t_ckclk);
+
+ /* SDRAM Timing Low */
+ val = (t_ras & 0xf) | (t_rcd << 4) | (t_rp << 8) | (t_wr << 12) |
+ (t_wtr << 16) | (((t_ras & 0x30) >> 4) << 20) | (t_rrd << 24) |
+ (t_rtp << 28);
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_LOW_REG, val, 0xff3fffff));
+
+ /* SDRAM Timing High */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ t_rfc & 0x7f, 0x7f));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ 0x180, 0x180));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ 0x600, 0x600));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ 0x1800, 0xf800));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ ((t_rfc & 0x380) >> 7) << 16, 0x70000));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG, 0,
+ 0x380000));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ (t_mod & 0xf) << 25, 0x1e00000));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ (t_mod >> 4) << 30, 0xc0000000));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ 0x16000000, 0x1e000000));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ SDRAM_TIMING_HIGH_REG,
+ 0x40000000, 0xc0000000));
+
+ return MV_OK;
+}
+
+/*
+ * Mode Read
+ */
+int hws_ddr3_tip_mode_read(u32 dev_num, struct mode_info *mode_info)
+{
+ u32 ret;
+
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ MR0_REG, mode_info->reg_mr0, MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ MR1_REG, mode_info->reg_mr1, MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ MR2_REG, mode_info->reg_mr2, MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ MR3_REG, mode_info->reg_mr2, MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ READ_DATA_SAMPLE_DELAY, mode_info->read_data_sample,
+ MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ READ_DATA_READY_DELAY, mode_info->read_data_ready,
+ MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+
+ return MV_OK;
+}
+
+/*
+ * Get first active IF
+ */
+int ddr3_tip_get_first_active_if(u8 dev_num, u32 interface_mask,
+ u32 *interface_id)
+{
+ u32 if_id;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (interface_mask & (1 << if_id)) {
+ *interface_id = if_id;
+ break;
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Write CS Result
+ */
+int ddr3_tip_write_cs_result(u32 dev_num, u32 offset)
+{
+ u32 if_id, bus_num, cs_bitmask, data_val, cs_num;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_num = 0; bus_num < tm->num_of_bus_per_interface;
+ bus_num++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+ cs_bitmask =
+ tm->interface_params[if_id].
+ as_bus_params[bus_num].cs_bitmask;
+ if (cs_bitmask != effective_cs) {
+ cs_num = GET_CS_FROM_MASK(cs_bitmask);
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_num,
+ DDR_PHY_DATA,
+ offset +
+ CS_REG_VALUE(effective_cs),
+ &data_val);
+ ddr3_tip_bus_write(dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_num, DDR_PHY_DATA,
+ offset +
+ CS_REG_VALUE(cs_num),
+ data_val);
+ }
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Write MRS
+ */
+int ddr3_tip_write_mrs_cmd(u32 dev_num, u32 *cs_mask_arr, u32 cmd,
+ u32 data, u32 mask)
+{
+ u32 if_id, reg;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ reg = (cmd == MRS1_CMD) ? MR1_REG : MR2_REG;
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, reg, data, mask));
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ SDRAM_OPERATION_REG,
+ (cs_mask_arr[if_id] << 8) | cmd, 0xf1f));
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (ddr3_tip_if_polling(dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
+ 0x1f, SDRAM_OPERATION_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("write_mrs_cmd: Poll cmd fail"));
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Reset XSB Read FIFO
+ */
+int ddr3_tip_reset_fifo_ptr(u32 dev_num)
+{
+ u32 if_id = 0;
+
+ /* Configure PHY reset value to 0 in order to "clean" the FIFO */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, 0x15c8, 0, 0xff000000));
+ /*
+ * Move PHY to RL mode (only in RL mode the PHY overrides FIFO values
+ * during FIFO reset)
+ */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, TRAINING_SW_2_REG,
+ 0x1, 0x9));
+ /* In order that above configuration will influence the PHY */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, 0x15b0,
+ 0x80000000, 0x80000000));
+ /* Reset read fifo assertion */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, 0x1400, 0, 0x40000000));
+ /* Reset read fifo deassertion */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, 0x1400,
+ 0x40000000, 0x40000000));
+ /* Move PHY back to functional mode */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, TRAINING_SW_2_REG,
+ 0x8, 0x9));
+ /* Stop training machine */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, 0x15b4, 0x10000, 0x10000));
+
+ return MV_OK;
+}
+
+/*
+ * Reset Phy registers
+ */
+int ddr3_tip_ddr3_reset_phy_regs(u32 dev_num)
+{
+ u32 if_id, phy_id, cs;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (phy_id = 0; phy_id < tm->num_of_bus_per_interface;
+ phy_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, phy_id);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ phy_id, DDR_PHY_DATA,
+ WL_PHY_REG +
+ CS_REG_VALUE(effective_cs),
+ phy_reg0_val));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+ RL_PHY_REG + CS_REG_VALUE(effective_cs),
+ phy_reg2_val));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+ READ_CENTRALIZATION_PHY_REG +
+ CS_REG_VALUE(effective_cs), phy_reg3_val));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, phy_id, DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG +
+ CS_REG_VALUE(effective_cs), phy_reg3_val));
+ }
+ }
+
+ /* Set Receiver Calibration value */
+ for (cs = 0; cs < MAX_CS_NUM; cs++) {
+ /* PHY register 0xdb bits[5:0] - configure to 63 */
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ DDR_PHY_DATA, CSN_IOB_VREF_REG(cs), 63));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Restore Dunit registers
+ */
+int ddr3_tip_restore_dunit_regs(u32 dev_num)
+{
+ u32 index_cnt;
+
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, CALIB_MACHINE_CTRL_REG,
+ 0x1, 0x1));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, CALIB_MACHINE_CTRL_REG,
+ calibration_update_control << 3,
+ 0x3 << 3));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ ODPG_WRITE_READ_MODE_ENABLE_REG,
+ 0xffff, MASK_ALL_BITS));
+
+ for (index_cnt = 0; index_cnt < ARRAY_SIZE(odpg_default_value);
+ index_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ odpg_default_value[index_cnt].reg_addr,
+ odpg_default_value[index_cnt].reg_data,
+ odpg_default_value[index_cnt].reg_mask));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Auto tune main flow
+ */
+static int ddr3_tip_ddr3_training_main_flow(u32 dev_num)
+{
+ enum hws_ddr_freq freq = init_freq;
+ struct init_cntr_param init_cntr_prm;
+ int ret = MV_OK;
+ u32 if_id;
+ u32 max_cs = hws_ddr3_tip_max_cs_get();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+#ifndef EXCLUDE_SWITCH_DEBUG
+ if (debug_training == DEBUG_LEVEL_TRACE) {
+ CHECK_STATUS(print_device_info((u8)dev_num));
+ }
+#endif
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ CHECK_STATUS(ddr3_tip_ddr3_reset_phy_regs(dev_num));
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ freq = init_freq;
+ if (is_pll_before_init != 0) {
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ config_func_info[dev_num].tip_set_freq_divider_func(
+ (u8)dev_num, if_id, freq);
+ }
+ }
+
+ if (is_adll_calib_before_init != 0) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("with adll calib before init\n"));
+ adll_calibration(dev_num, ACCESS_TYPE_MULTICAST, 0, freq);
+ }
+
+ if (is_reg_dump != 0) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("Dump before init controller\n"));
+ ddr3_tip_reg_dump(dev_num);
+ }
+
+ if (mask_tune_func & INIT_CONTROLLER_MASK_BIT) {
+ training_stage = INIT_CONTROLLER;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("INIT_CONTROLLER_MASK_BIT\n"));
+ init_cntr_prm.do_mrs_phy = 1;
+ init_cntr_prm.is_ctrl64_bit = 0;
+ init_cntr_prm.init_phy = 1;
+ init_cntr_prm.msys_init = 0;
+ ret = hws_ddr3_tip_init_controller(dev_num, &init_cntr_prm);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("hws_ddr3_tip_init_controller failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+#ifdef STATIC_ALGO_SUPPORT
+ if (mask_tune_func & STATIC_LEVELING_MASK_BIT) {
+ training_stage = STATIC_LEVELING;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("STATIC_LEVELING_MASK_BIT\n"));
+ ret = ddr3_tip_run_static_alg(dev_num, freq);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_run_static_alg failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+#endif
+
+ if (mask_tune_func & SET_LOW_FREQ_MASK_BIT) {
+ training_stage = SET_LOW_FREQ;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("SET_LOW_FREQ_MASK_BIT %d\n",
+ freq_val[low_freq]));
+ ret = ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, low_freq);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_freq_set failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ if (mask_tune_func & LOAD_PATTERN_MASK_BIT) {
+ training_stage = LOAD_PATTERN;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("LOAD_PATTERN_MASK_BIT #%d\n",
+ effective_cs));
+ ret = ddr3_tip_load_all_pattern_to_mem(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_load_all_pattern_to_mem failure CS #%d\n",
+ effective_cs));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ if (mask_tune_func & SET_MEDIUM_FREQ_MASK_BIT) {
+ training_stage = SET_MEDIUM_FREQ;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("SET_MEDIUM_FREQ_MASK_BIT %d\n",
+ freq_val[medium_freq]));
+ ret =
+ ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, medium_freq);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_freq_set failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ if (mask_tune_func & WRITE_LEVELING_MASK_BIT) {
+ training_stage = WRITE_LEVELING;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("WRITE_LEVELING_MASK_BIT\n"));
+ if ((rl_mid_freq_wa == 0) || (freq_val[medium_freq] == 533)) {
+ ret = ddr3_tip_dynamic_write_leveling(dev_num);
+ } else {
+ /* Use old WL */
+ ret = ddr3_tip_legacy_dynamic_write_leveling(dev_num);
+ }
+
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_dynamic_write_leveling failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ if (mask_tune_func & LOAD_PATTERN_2_MASK_BIT) {
+ training_stage = LOAD_PATTERN_2;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("LOAD_PATTERN_2_MASK_BIT CS #%d\n",
+ effective_cs));
+ ret = ddr3_tip_load_all_pattern_to_mem(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_load_all_pattern_to_mem failure CS #%d\n",
+ effective_cs));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ if (mask_tune_func & READ_LEVELING_MASK_BIT) {
+ training_stage = READ_LEVELING;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("READ_LEVELING_MASK_BIT\n"));
+ if ((rl_mid_freq_wa == 0) || (freq_val[medium_freq] == 533)) {
+ ret = ddr3_tip_dynamic_read_leveling(dev_num, medium_freq);
+ } else {
+ /* Use old RL */
+ ret = ddr3_tip_legacy_dynamic_read_leveling(dev_num);
+ }
+
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_dynamic_read_leveling failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ if (mask_tune_func & WRITE_LEVELING_SUPP_MASK_BIT) {
+ training_stage = WRITE_LEVELING_SUPP;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("WRITE_LEVELING_SUPP_MASK_BIT\n"));
+ ret = ddr3_tip_dynamic_write_leveling_supp(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_dynamic_write_leveling_supp failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ if (mask_tune_func & PBS_RX_MASK_BIT) {
+ training_stage = PBS_RX;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("PBS_RX_MASK_BIT CS #%d\n",
+ effective_cs));
+ ret = ddr3_tip_pbs_rx(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_pbs_rx failure CS #%d\n",
+ effective_cs));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ }
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ if (mask_tune_func & PBS_TX_MASK_BIT) {
+ training_stage = PBS_TX;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("PBS_TX_MASK_BIT CS #%d\n",
+ effective_cs));
+ ret = ddr3_tip_pbs_tx(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_pbs_tx failure CS #%d\n",
+ effective_cs));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ if (mask_tune_func & SET_TARGET_FREQ_MASK_BIT) {
+ training_stage = SET_TARGET_FREQ;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("SET_TARGET_FREQ_MASK_BIT %d\n",
+ freq_val[tm->
+ interface_params[first_active_if].
+ memory_freq]));
+ ret = ddr3_tip_freq_set(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ tm->interface_params[first_active_if].
+ memory_freq);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_freq_set failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ if (mask_tune_func & WRITE_LEVELING_TF_MASK_BIT) {
+ training_stage = WRITE_LEVELING_TF;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("WRITE_LEVELING_TF_MASK_BIT\n"));
+ ret = ddr3_tip_dynamic_write_leveling(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_dynamic_write_leveling TF failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ if (mask_tune_func & LOAD_PATTERN_HIGH_MASK_BIT) {
+ training_stage = LOAD_PATTERN_HIGH;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("LOAD_PATTERN_HIGH\n"));
+ ret = ddr3_tip_load_all_pattern_to_mem(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_load_all_pattern_to_mem failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ if (mask_tune_func & READ_LEVELING_TF_MASK_BIT) {
+ training_stage = READ_LEVELING_TF;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("READ_LEVELING_TF_MASK_BIT\n"));
+ ret = ddr3_tip_dynamic_read_leveling(dev_num, tm->
+ interface_params[first_active_if].
+ memory_freq);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_dynamic_read_leveling TF failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ if (mask_tune_func & DM_PBS_TX_MASK_BIT) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("DM_PBS_TX_MASK_BIT\n"));
+ }
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ if (mask_tune_func & VREF_CALIBRATION_MASK_BIT) {
+ training_stage = VREF_CALIBRATION;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("VREF\n"));
+ ret = ddr3_tip_vref(dev_num);
+ if (is_reg_dump != 0) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("VREF Dump\n"));
+ ddr3_tip_reg_dump(dev_num);
+ }
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_vref failure\n"));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ if (mask_tune_func & CENTRALIZATION_RX_MASK_BIT) {
+ training_stage = CENTRALIZATION_RX;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("CENTRALIZATION_RX_MASK_BIT CS #%d\n",
+ effective_cs));
+ ret = ddr3_tip_centralization_rx(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_centralization_rx failure CS #%d\n",
+ effective_cs));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ if (mask_tune_func & WRITE_LEVELING_SUPP_TF_MASK_BIT) {
+ training_stage = WRITE_LEVELING_SUPP_TF;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("WRITE_LEVELING_SUPP_TF_MASK_BIT CS #%d\n",
+ effective_cs));
+ ret = ddr3_tip_dynamic_write_leveling_supp(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_dynamic_write_leveling_supp TF failure CS #%d\n",
+ effective_cs));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ if (mask_tune_func & CENTRALIZATION_TX_MASK_BIT) {
+ training_stage = CENTRALIZATION_TX;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("CENTRALIZATION_TX_MASK_BIT CS #%d\n",
+ effective_cs));
+ ret = ddr3_tip_centralization_tx(dev_num);
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_centralization_tx failure CS #%d\n",
+ effective_cs));
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO, ("restore registers to default\n"));
+ /* restore register values */
+ CHECK_STATUS(ddr3_tip_restore_dunit_regs(dev_num));
+
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+
+ return MV_OK;
+}
+
+/*
+ * DDR3 Dynamic training flow
+ */
+static int ddr3_tip_ddr3_auto_tune(u32 dev_num)
+{
+ u32 if_id, stage, ret;
+ int is_if_fail = 0, is_auto_tune_fail = 0;
+
+ training_stage = INIT_CONTROLLER;
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ for (stage = 0; stage < MAX_STAGE_LIMIT; stage++)
+ training_result[stage][if_id] = NO_TEST_DONE;
+ }
+
+ ret = ddr3_tip_ddr3_training_main_flow(dev_num);
+
+ /* activate XSB test */
+ if (xsb_validate_type != 0) {
+ run_xsb_test(dev_num, xsb_validation_base_address, 1, 1,
+ 0x1024);
+ }
+
+ if (is_reg_dump != 0)
+ ddr3_tip_reg_dump(dev_num);
+
+ /* print log */
+ CHECK_STATUS(ddr3_tip_print_log(dev_num, window_mem_addr));
+
+ if (ret != MV_OK) {
+ CHECK_STATUS(ddr3_tip_print_stability_log(dev_num));
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ is_if_fail = 0;
+ for (stage = 0; stage < MAX_STAGE_LIMIT; stage++) {
+ if (training_result[stage][if_id] == TEST_FAILED)
+ is_if_fail = 1;
+ }
+ if (is_if_fail == 1) {
+ is_auto_tune_fail = 1;
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_INFO,
+ ("Auto Tune failed for IF %d\n",
+ if_id));
+ }
+ }
+
+ if ((ret == MV_FAIL) || (is_auto_tune_fail == 1))
+ return MV_FAIL;
+ else
+ return MV_OK;
+}
+
+/*
+ * Enable init sequence
+ */
+int ddr3_tip_enable_init_sequence(u32 dev_num)
+{
+ int is_fail = 0;
+ u32 if_id = 0, mem_mask = 0, bus_index = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* Enable init sequence */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_MULTICAST, 0,
+ SDRAM_INIT_CONTROL_REG, 0x1, 0x1));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1,
+ SDRAM_INIT_CONTROL_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("polling failed IF %d\n",
+ if_id));
+ is_fail = 1;
+ continue;
+ }
+
+ mem_mask = 0;
+ for (bus_index = 0; bus_index < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_index++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+ mem_mask |=
+ tm->interface_params[if_id].
+ as_bus_params[bus_index].mirror_enable_bitmask;
+ }
+
+ if (mem_mask != 0) {
+ /* Disable Multi CS */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST,
+ if_id, CS_ENABLE_REG, 1 << 3,
+ 1 << 3));
+ }
+ }
+
+ return (is_fail == 0) ? MV_OK : MV_FAIL;
+}
+
+int ddr3_tip_register_dq_table(u32 dev_num, u32 *table)
+{
+ dq_map_table = table;
+
+ return MV_OK;
+}
+
+/*
+ * Check if pup search is locked
+ */
+int ddr3_tip_is_pup_lock(u32 *pup_buf, enum hws_training_result read_mode)
+{
+ u32 bit_start = 0, bit_end = 0, bit_id;
+
+ if (read_mode == RESULT_PER_BIT) {
+ bit_start = 0;
+ bit_end = BUS_WIDTH_IN_BITS - 1;
+ } else {
+ bit_start = 0;
+ bit_end = 0;
+ }
+
+ for (bit_id = bit_start; bit_id <= bit_end; bit_id++) {
+ if (GET_LOCK_RESULT(pup_buf[bit_id]) == 0)
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Get minimum buffer value
+ */
+u8 ddr3_tip_get_buf_min(u8 *buf_ptr)
+{
+ u8 min_val = 0xff;
+ u8 cnt = 0;
+
+ for (cnt = 0; cnt < BUS_WIDTH_IN_BITS; cnt++) {
+ if (buf_ptr[cnt] < min_val)
+ min_val = buf_ptr[cnt];
+ }
+
+ return min_val;
+}
+
+/*
+ * Get maximum buffer value
+ */
+u8 ddr3_tip_get_buf_max(u8 *buf_ptr)
+{
+ u8 max_val = 0;
+ u8 cnt = 0;
+
+ for (cnt = 0; cnt < BUS_WIDTH_IN_BITS; cnt++) {
+ if (buf_ptr[cnt] > max_val)
+ max_val = buf_ptr[cnt];
+ }
+
+ return max_val;
+}
+
+/*
+ * The following functions return memory parameters:
+ * bus and device width, device size
+ */
+
+u32 hws_ddr3_get_bus_width(void)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ return (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) ==
+ 1) ? 16 : 32;
+}
+
+u32 hws_ddr3_get_device_width(u32 if_id)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ return (tm->interface_params[if_id].bus_width ==
+ BUS_WIDTH_8) ? 8 : 16;
+}
+
+u32 hws_ddr3_get_device_size(u32 if_id)
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (tm->interface_params[if_id].memory_size >=
+ MEM_SIZE_LAST) {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Error: Wrong device size of Cs: %d",
+ tm->interface_params[if_id].memory_size));
+ return 0;
+ } else {
+ return 1 << tm->interface_params[if_id].memory_size;
+ }
+}
+
+int hws_ddr3_calc_mem_cs_size(u32 if_id, u32 cs, u32 *cs_size)
+{
+ u32 cs_mem_size, dev_size;
+
+ dev_size = hws_ddr3_get_device_size(if_id);
+ if (dev_size != 0) {
+ cs_mem_size = ((hws_ddr3_get_bus_width() /
+ hws_ddr3_get_device_width(if_id)) * dev_size);
+
+ /* the calculated result in Gbytex16 to avoid float using */
+
+ if (cs_mem_size == 2) {
+ *cs_size = _128M;
+ } else if (cs_mem_size == 4) {
+ *cs_size = _256M;
+ } else if (cs_mem_size == 8) {
+ *cs_size = _512M;
+ } else if (cs_mem_size == 16) {
+ *cs_size = _1G;
+ } else if (cs_mem_size == 32) {
+ *cs_size = _2G;
+ } else {
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Error: Wrong Memory size of Cs: %d", cs));
+ return MV_FAIL;
+ }
+ return MV_OK;
+ } else {
+ return MV_FAIL;
+ }
+}
+
+int hws_ddr3_cs_base_adr_calc(u32 if_id, u32 cs, u32 *cs_base_addr)
+{
+ u32 cs_mem_size = 0;
+#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
+ u32 physical_mem_size;
+ u32 max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE;
+#endif
+
+ if (hws_ddr3_calc_mem_cs_size(if_id, cs, &cs_mem_size) != MV_OK)
+ return MV_FAIL;
+
+#ifdef DEVICE_MAX_DRAM_ADDRESS_SIZE
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+ /*
+ * if number of address pins doesn't allow to use max mem size that
+ * is defined in topology mem size is defined by
+ * DEVICE_MAX_DRAM_ADDRESS_SIZE
+ */
+ physical_mem_size =
+ mv_hwsmem_size[tm->interface_params[0].memory_size];
+
+ if (hws_ddr3_get_device_width(cs) == 16) {
+ /*
+ * 16bit mem device can be twice more - no need in less
+ * significant pin
+ */
+ max_mem_size = DEVICE_MAX_DRAM_ADDRESS_SIZE * 2;
+ }
+
+ if (physical_mem_size > max_mem_size) {
+ cs_mem_size = max_mem_size *
+ (hws_ddr3_get_bus_width() /
+ hws_ddr3_get_device_width(if_id));
+ DEBUG_TRAINING_IP(DEBUG_LEVEL_ERROR,
+ ("Updated Physical Mem size is from 0x%x to %x\n",
+ physical_mem_size,
+ DEVICE_MAX_DRAM_ADDRESS_SIZE));
+ }
+#endif
+
+ /* calculate CS base addr */
+ *cs_base_addr = ((cs_mem_size) * cs) & 0xffff0000;
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+static u32 bist_offset = 32;
+enum hws_pattern sweep_pattern = PATTERN_KILLER_DQ0;
+
+static int ddr3_tip_bist_operation(u32 dev_num,
+ enum hws_access_type access_type,
+ u32 if_id,
+ enum hws_bist_operation oper_type);
+
+/*
+ * BIST activate
+ */
+int ddr3_tip_bist_activate(u32 dev_num, enum hws_pattern pattern,
+ enum hws_access_type access_type, u32 if_num,
+ enum hws_dir direction,
+ enum hws_stress_jump addr_stress_jump,
+ enum hws_pattern_duration duration,
+ enum hws_bist_operation oper_type,
+ u32 offset, u32 cs_num, u32 pattern_addr_length)
+{
+ u32 tx_burst_size;
+ u32 delay_between_burst;
+ u32 rd_mode, val;
+ u32 poll_cnt = 0, max_poll = 1000, i, start_if, end_if;
+ struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+ u32 read_data[MAX_INTERFACE_NUM];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* ODPG Write enable from BIST */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
+ ODPG_DATA_CONTROL_REG, 0x1, 0x1));
+ /* ODPG Read enable/disable from BIST */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
+ ODPG_DATA_CONTROL_REG,
+ (direction == OPER_READ) ?
+ 0x2 : 0, 0x2));
+ CHECK_STATUS(ddr3_tip_load_pattern_to_odpg(dev_num, access_type, if_num,
+ pattern, offset));
+
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
+ ODPG_DATA_BUF_SIZE_REG,
+ pattern_addr_length, MASK_ALL_BITS));
+ tx_burst_size = (direction == OPER_WRITE) ?
+ pattern_table[pattern].tx_burst_size : 0;
+ delay_between_burst = (direction == OPER_WRITE) ? 2 : 0;
+ rd_mode = (direction == OPER_WRITE) ? 1 : 0;
+ CHECK_STATUS(ddr3_tip_configure_odpg
+ (dev_num, access_type, if_num, direction,
+ pattern_table[pattern].num_of_phases_tx, tx_burst_size,
+ pattern_table[pattern].num_of_phases_rx,
+ delay_between_burst,
+ rd_mode, cs_num, addr_stress_jump, duration));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
+ ODPG_PATTERN_ADDR_OFFSET_REG,
+ offset, MASK_ALL_BITS));
+ if (oper_type == BIST_STOP) {
+ CHECK_STATUS(ddr3_tip_bist_operation(dev_num, access_type,
+ if_num, BIST_STOP));
+ } else {
+ CHECK_STATUS(ddr3_tip_bist_operation(dev_num, access_type,
+ if_num, BIST_START));
+ if (duration != DURATION_CONT) {
+ /*
+ * This pdelay is a WA, becuase polling fives "done"
+ * also the odpg did nmot finish its task
+ */
+ if (access_type == ACCESS_TYPE_MULTICAST) {
+ start_if = 0;
+ end_if = MAX_INTERFACE_NUM - 1;
+ } else {
+ start_if = if_num;
+ end_if = if_num;
+ }
+
+ for (i = start_if; i <= end_if; i++) {
+ VALIDATE_ACTIVE(tm->
+ if_act_mask, i);
+
+ for (poll_cnt = 0; poll_cnt < max_poll;
+ poll_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_num, ODPG_BIST_DONE,
+ read_data,
+ MASK_ALL_BITS));
+ val = read_data[i];
+ if ((val & 0x1) == 0x0) {
+ /*
+ * In SOC type devices this bit
+ * is self clear so, if it was
+ * cleared all good
+ */
+ break;
+ }
+ }
+
+ if (poll_cnt >= max_poll) {
+ DEBUG_TRAINING_BIST_ENGINE
+ (DEBUG_LEVEL_ERROR,
+ ("Bist poll failure 2\n"));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_num,
+ ODPG_DATA_CONTROL_REG, 0,
+ MASK_ALL_BITS));
+ return MV_FAIL;
+ }
+ }
+
+ CHECK_STATUS(ddr3_tip_bist_operation
+ (dev_num, access_type, if_num, BIST_STOP));
+ }
+ }
+
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_num,
+ ODPG_DATA_CONTROL_REG, 0,
+ MASK_ALL_BITS));
+
+ return MV_OK;
+}
+
+/*
+ * BIST read result
+ */
+int ddr3_tip_bist_read_result(u32 dev_num, u32 if_id,
+ struct bist_result *pst_bist_result)
+{
+ int ret;
+ u32 read_data[MAX_INTERFACE_NUM];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
+ return MV_NOT_SUPPORTED;
+ DEBUG_TRAINING_BIST_ENGINE(DEBUG_LEVEL_TRACE,
+ ("ddr3_tip_bist_read_result if_id %d\n",
+ if_id));
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ODPG_BIST_FAILED_DATA_HI_REG, read_data,
+ MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+ pst_bist_result->bist_fail_high = read_data[if_id];
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ODPG_BIST_FAILED_DATA_LOW_REG, read_data,
+ MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+ pst_bist_result->bist_fail_low = read_data[if_id];
+
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ODPG_BIST_LAST_FAIL_ADDR_REG, read_data,
+ MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+ pst_bist_result->bist_last_fail_addr = read_data[if_id];
+ ret = ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ODPG_BIST_DATA_ERROR_COUNTER_REG, read_data,
+ MASK_ALL_BITS);
+ if (ret != MV_OK)
+ return ret;
+ pst_bist_result->bist_error_cnt = read_data[if_id];
+
+ return MV_OK;
+}
+
+/*
+ * BIST flow - Activate & read result
+ */
+int hws_ddr3_run_bist(u32 dev_num, enum hws_pattern pattern, u32 *result,
+ u32 cs_num)
+{
+ int ret;
+ u32 i = 0;
+ u32 win_base;
+ struct bist_result st_bist_result;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (i = 0; i < MAX_INTERFACE_NUM; i++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, i);
+ hws_ddr3_cs_base_adr_calc(i, cs_num, &win_base);
+ ret = ddr3_tip_bist_activate(dev_num, pattern,
+ ACCESS_TYPE_UNICAST,
+ i, OPER_WRITE, STRESS_NONE,
+ DURATION_SINGLE, BIST_START,
+ bist_offset + win_base,
+ cs_num, 15);
+ if (ret != MV_OK) {
+ printf("ddr3_tip_bist_activate failed (0x%x)\n", ret);
+ return ret;
+ }
+
+ ret = ddr3_tip_bist_activate(dev_num, pattern,
+ ACCESS_TYPE_UNICAST,
+ i, OPER_READ, STRESS_NONE,
+ DURATION_SINGLE, BIST_START,
+ bist_offset + win_base,
+ cs_num, 15);
+ if (ret != MV_OK) {
+ printf("ddr3_tip_bist_activate failed (0x%x)\n", ret);
+ return ret;
+ }
+
+ ret = ddr3_tip_bist_read_result(dev_num, i, &st_bist_result);
+ if (ret != MV_OK) {
+ printf("ddr3_tip_bist_read_result failed\n");
+ return ret;
+ }
+ result[i] = st_bist_result.bist_error_cnt;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Set BIST Operation
+ */
+
+static int ddr3_tip_bist_operation(u32 dev_num,
+ enum hws_access_type access_type,
+ u32 if_id, enum hws_bist_operation oper_type)
+{
+ if (oper_type == BIST_STOP) {
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ ODPG_BIST_DONE, 1 << 8, 1 << 8));
+ } else {
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ ODPG_BIST_DONE, 1, 1));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Print BIST result
+ */
+void ddr3_tip_print_bist_res(void)
+{
+ u32 dev_num = 0;
+ u32 i;
+ struct bist_result st_bist_result[MAX_INTERFACE_NUM];
+ int res;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (i = 0; i < MAX_INTERFACE_NUM; i++) {
+ if (IS_ACTIVE(tm->if_act_mask, i) == 0)
+ continue;
+
+ res = ddr3_tip_bist_read_result(dev_num, i, &st_bist_result[i]);
+ if (res != MV_OK) {
+ DEBUG_TRAINING_BIST_ENGINE(
+ DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_bist_read_result failed\n"));
+ return;
+ }
+ }
+
+ DEBUG_TRAINING_BIST_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("interface | error_cnt | fail_low | fail_high | fail_addr\n"));
+
+ for (i = 0; i < MAX_INTERFACE_NUM; i++) {
+ if (IS_ACTIVE(tm->if_act_mask, i) ==
+ 0)
+ continue;
+
+ DEBUG_TRAINING_BIST_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("%d | 0x%08x | 0x%08x | 0x%08x | 0x%08x\n",
+ i, st_bist_result[i].bist_error_cnt,
+ st_bist_result[i].bist_fail_low,
+ st_bist_result[i].bist_fail_high,
+ st_bist_result[i].bist_last_fail_addr));
+ }
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#define VALIDATE_WIN_LENGTH(e1, e2, maxsize) \
+ (((e2) + 1 > (e1) + (u8)MIN_WINDOW_SIZE) && \
+ ((e2) + 1 < (e1) + (u8)maxsize))
+#define IS_WINDOW_OUT_BOUNDARY(e1, e2, maxsize) \
+ (((e1) == 0 && (e2) != 0) || \
+ ((e1) != (maxsize - 1) && (e2) == (maxsize - 1)))
+#define CENTRAL_TX 0
+#define CENTRAL_RX 1
+#define NUM_OF_CENTRAL_TYPES 2
+
+u32 start_pattern = PATTERN_KILLER_DQ0, end_pattern = PATTERN_KILLER_DQ7;
+u32 start_if = 0, end_if = (MAX_INTERFACE_NUM - 1);
+u8 bus_end_window[NUM_OF_CENTRAL_TYPES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u8 bus_start_window[NUM_OF_CENTRAL_TYPES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u8 centralization_state[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+static u8 ddr3_tip_special_rx_run_once_flag;
+
+static int ddr3_tip_centralization(u32 dev_num, u32 mode);
+
+/*
+ * Centralization RX Flow
+ */
+int ddr3_tip_centralization_rx(u32 dev_num)
+{
+ CHECK_STATUS(ddr3_tip_special_rx(dev_num));
+ CHECK_STATUS(ddr3_tip_centralization(dev_num, CENTRAL_RX));
+
+ return MV_OK;
+}
+
+/*
+ * Centralization TX Flow
+ */
+int ddr3_tip_centralization_tx(u32 dev_num)
+{
+ CHECK_STATUS(ddr3_tip_centralization(dev_num, CENTRAL_TX));
+
+ return MV_OK;
+}
+
+/*
+ * Centralization Flow
+ */
+static int ddr3_tip_centralization(u32 dev_num, u32 mode)
+{
+ enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
+ u32 if_id, pattern_id, bit_id;
+ u8 bus_id;
+ u8 cur_start_win[BUS_WIDTH_IN_BITS];
+ u8 centralization_result[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
+ u8 cur_end_win[BUS_WIDTH_IN_BITS];
+ u8 current_window[BUS_WIDTH_IN_BITS];
+ u8 opt_window, waste_window, start_window_skew, end_window_skew;
+ u8 final_pup_window[MAX_INTERFACE_NUM][BUS_WIDTH_IN_BITS];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+ enum hws_training_result result_type = RESULT_PER_BIT;
+ enum hws_dir direction;
+ u32 *result[HWS_SEARCH_DIR_LIMIT];
+ u32 reg_phy_off, reg;
+ u8 max_win_size;
+ int lock_success = 1;
+ u8 cur_end_win_min, cur_start_win_max;
+ u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
+ int is_if_fail = 0;
+ enum hws_result *flow_result = ddr3_tip_get_result_ptr(training_stage);
+ u32 pup_win_length = 0;
+ enum hws_search_dir search_dir_id;
+ u8 cons_tap = (mode == CENTRAL_TX) ? (64) : (0);
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* save current cs enable reg val */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
+ /* enable single cs */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, (1 << 3), (1 << 3)));
+ }
+
+ if (mode == CENTRAL_TX) {
+ max_win_size = MAX_WINDOW_SIZE_TX;
+ reg_phy_off = WRITE_CENTRALIZATION_PHY_REG + (effective_cs * 4);
+ direction = OPER_WRITE;
+ } else {
+ max_win_size = MAX_WINDOW_SIZE_RX;
+ reg_phy_off = READ_CENTRALIZATION_PHY_REG + (effective_cs * 4);
+ direction = OPER_READ;
+ }
+
+ /* DB initialization */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_id = 0;
+ bus_id < tm->num_of_bus_per_interface; bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ centralization_state[if_id][bus_id] = 0;
+ bus_end_window[mode][if_id][bus_id] =
+ (max_win_size - 1) + cons_tap;
+ bus_start_window[mode][if_id][bus_id] = 0;
+ centralization_result[if_id][bus_id] = 0;
+ }
+ }
+
+ /* start flow */
+ for (pattern_id = start_pattern; pattern_id <= end_pattern;
+ pattern_id++) {
+ ddr3_tip_ip_training_wrapper(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, result_type,
+ HWS_CONTROL_ELEMENT_ADLL,
+ PARAM_NOT_CARE, direction,
+ tm->
+ if_act_mask, 0x0,
+ max_win_size - 1,
+ max_win_size - 1,
+ pattern_id, EDGE_FPF, CS_SINGLE,
+ PARAM_NOT_CARE, training_result);
+
+ for (if_id = start_if; if_id <= end_if; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_id = 0;
+ bus_id <= tm->num_of_bus_per_interface - 1;
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+
+ for (search_dir_id = HWS_LOW2HIGH;
+ search_dir_id <= HWS_HIGH2LOW;
+ search_dir_id++) {
+ CHECK_STATUS
+ (ddr3_tip_read_training_result
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_id,
+ ALL_BITS_PER_PUP,
+ search_dir_id,
+ direction, result_type,
+ TRAINING_LOAD_OPERATION_UNLOAD,
+ CS_SINGLE,
+ &result[search_dir_id],
+ 1, 0, 0));
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("%s pat %d IF %d pup %d Regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ ((mode ==
+ CENTRAL_TX) ? "TX" : "RX"),
+ pattern_id, if_id, bus_id,
+ result[search_dir_id][0],
+ result[search_dir_id][1],
+ result[search_dir_id][2],
+ result[search_dir_id][3],
+ result[search_dir_id][4],
+ result[search_dir_id][5],
+ result[search_dir_id][6],
+ result[search_dir_id][7]));
+ }
+
+ for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
+ bit_id++) {
+ /* check if this code is valid for 2 edge, probably not :( */
+ cur_start_win[bit_id] =
+ GET_TAP_RESULT(result
+ [HWS_LOW2HIGH]
+ [bit_id],
+ EDGE_1);
+ cur_end_win[bit_id] =
+ GET_TAP_RESULT(result
+ [HWS_HIGH2LOW]
+ [bit_id],
+ EDGE_1);
+ /* window length */
+ current_window[bit_id] =
+ cur_end_win[bit_id] -
+ cur_start_win[bit_id] + 1;
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_TRACE,
+ ("cs %x patern %d IF %d pup %d cur_start_win %d cur_end_win %d current_window %d\n",
+ effective_cs, pattern_id,
+ if_id, bus_id,
+ cur_start_win[bit_id],
+ cur_end_win[bit_id],
+ current_window[bit_id]));
+ }
+
+ if ((ddr3_tip_is_pup_lock
+ (result[HWS_LOW2HIGH], result_type)) &&
+ (ddr3_tip_is_pup_lock
+ (result[HWS_HIGH2LOW], result_type))) {
+ /* read result success */
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("Pup locked, pat %d IF %d pup %d\n",
+ pattern_id, if_id, bus_id));
+ } else {
+ /* read result failure */
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("fail Lock, pat %d IF %d pup %d\n",
+ pattern_id, if_id, bus_id));
+ if (centralization_state[if_id][bus_id]
+ == 1) {
+ /* continue with next pup */
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_TRACE,
+ ("continue to next pup %d %d\n",
+ if_id, bus_id));
+ continue;
+ }
+
+ for (bit_id = 0;
+ bit_id < BUS_WIDTH_IN_BITS;
+ bit_id++) {
+ /*
+ * the next check is relevant
+ * only when using search
+ * machine 2 edges
+ */
+ if (cur_start_win[bit_id] > 0 &&
+ cur_end_win[bit_id] == 0) {
+ cur_end_win
+ [bit_id] =
+ max_win_size - 1;
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_TRACE,
+ ("fail, IF %d pup %d bit %d fail #1\n",
+ if_id, bus_id,
+ bit_id));
+ /* the next bit */
+ continue;
+ } else {
+ centralization_state
+ [if_id][bus_id] = 1;
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_TRACE,
+ ("fail, IF %d pup %d bit %d fail #2\n",
+ if_id, bus_id,
+ bit_id));
+ }
+ }
+
+ if (centralization_state[if_id][bus_id]
+ == 1) {
+ /* going to next pup */
+ continue;
+ }
+ } /*bit */
+
+ opt_window =
+ ddr3_tip_get_buf_min(current_window);
+ /* final pup window length */
+ final_pup_window[if_id][bus_id] =
+ ddr3_tip_get_buf_min(cur_end_win) -
+ ddr3_tip_get_buf_max(cur_start_win) +
+ 1;
+ waste_window =
+ opt_window -
+ final_pup_window[if_id][bus_id];
+ start_window_skew =
+ ddr3_tip_get_buf_max(cur_start_win) -
+ ddr3_tip_get_buf_min(
+ cur_start_win);
+ end_window_skew =
+ ddr3_tip_get_buf_max(
+ cur_end_win) -
+ ddr3_tip_get_buf_min(
+ cur_end_win);
+ /* min/max updated with pattern change */
+ cur_end_win_min =
+ ddr3_tip_get_buf_min(
+ cur_end_win);
+ cur_start_win_max =
+ ddr3_tip_get_buf_max(
+ cur_start_win);
+ bus_end_window[mode][if_id][bus_id] =
+ GET_MIN(bus_end_window[mode][if_id]
+ [bus_id],
+ cur_end_win_min);
+ bus_start_window[mode][if_id][bus_id] =
+ GET_MAX(bus_start_window[mode][if_id]
+ [bus_id],
+ cur_start_win_max);
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("pat %d IF %d pup %d opt_win %d final_win %d waste_win %d st_win_skew %d end_win_skew %d cur_st_win_max %d cur_end_win_min %d bus_st_win %d bus_end_win %d\n",
+ pattern_id, if_id, bus_id, opt_window,
+ final_pup_window[if_id][bus_id],
+ waste_window, start_window_skew,
+ end_window_skew,
+ cur_start_win_max,
+ cur_end_win_min,
+ bus_start_window[mode][if_id][bus_id],
+ bus_end_window[mode][if_id][bus_id]));
+
+ /* check if window is valid */
+ if (ddr3_tip_centr_skip_min_win_check == 0) {
+ if ((VALIDATE_WIN_LENGTH
+ (bus_start_window[mode][if_id]
+ [bus_id],
+ bus_end_window[mode][if_id]
+ [bus_id],
+ max_win_size) == 1) ||
+ (IS_WINDOW_OUT_BOUNDARY
+ (bus_start_window[mode][if_id]
+ [bus_id],
+ bus_end_window[mode][if_id]
+ [bus_id],
+ max_win_size) == 1)) {
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("win valid, pat %d IF %d pup %d\n",
+ pattern_id, if_id,
+ bus_id));
+ /* window is valid */
+ } else {
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("fail win, pat %d IF %d pup %d bus_st_win %d bus_end_win %d\n",
+ pattern_id, if_id, bus_id,
+ bus_start_window[mode]
+ [if_id][bus_id],
+ bus_end_window[mode]
+ [if_id][bus_id]));
+ centralization_state[if_id]
+ [bus_id] = 1;
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ } /* ddr3_tip_centr_skip_min_win_check */
+ } /* pup */
+ } /* interface */
+ } /* pattern */
+
+ for (if_id = start_if; if_id <= end_if; if_id++) {
+ if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
+ continue;
+
+ is_if_fail = 0;
+ flow_result[if_id] = TEST_SUCCESS;
+
+ for (bus_id = 0;
+ bus_id <= (tm->num_of_bus_per_interface - 1); bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+
+ /* continue only if lock */
+ if (centralization_state[if_id][bus_id] != 1) {
+ if (ddr3_tip_centr_skip_min_win_check == 0) {
+ if ((bus_end_window
+ [mode][if_id][bus_id] ==
+ (max_win_size - 1)) &&
+ ((bus_end_window
+ [mode][if_id][bus_id] -
+ bus_start_window[mode][if_id]
+ [bus_id]) < MIN_WINDOW_SIZE) &&
+ ((bus_end_window[mode][if_id]
+ [bus_id] - bus_start_window
+ [mode][if_id][bus_id]) > 2)) {
+ /* prevent false lock */
+ /* TBD change to enum */
+ centralization_state
+ [if_id][bus_id] = 2;
+ }
+
+ if ((bus_end_window[mode][if_id][bus_id]
+ == 0) &&
+ ((bus_end_window[mode][if_id]
+ [bus_id] -
+ bus_start_window[mode][if_id]
+ [bus_id]) < MIN_WINDOW_SIZE) &&
+ ((bus_end_window[mode][if_id]
+ [bus_id] -
+ bus_start_window[mode][if_id]
+ [bus_id]) > 2))
+ /*prevent false lock */
+ centralization_state[if_id]
+ [bus_id] = 3;
+ }
+
+ if ((bus_end_window[mode][if_id][bus_id] >
+ (max_win_size - 1)) && direction ==
+ OPER_WRITE) {
+ DEBUG_CENTRALIZATION_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("Tx special pattern\n"));
+ cons_tap = 64;
+ }
+ }
+
+ /* check states */
+ if (centralization_state[if_id][bus_id] == 3) {
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("SSW - TBD IF %d pup %d\n",
+ if_id, bus_id));
+ lock_success = 1;
+ } else if (centralization_state[if_id][bus_id] == 2) {
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("SEW - TBD IF %d pup %d\n",
+ if_id, bus_id));
+ lock_success = 1;
+ } else if (centralization_state[if_id][bus_id] == 0) {
+ lock_success = 1;
+ } else {
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_ERROR,
+ ("fail, IF %d pup %d\n",
+ if_id, bus_id));
+ lock_success = 0;
+ }
+
+ if (lock_success == 1) {
+ centralization_result[if_id][bus_id] =
+ (bus_end_window[mode][if_id][bus_id] +
+ bus_start_window[mode][if_id][bus_id])
+ / 2 - cons_tap;
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_TRACE,
+ (" bus_id %d Res= %d\n", bus_id,
+ centralization_result[if_id][bus_id]));
+ /* copy results to registers */
+ pup_win_length =
+ bus_end_window[mode][if_id][bus_id] -
+ bus_start_window[mode][if_id][bus_id] +
+ 1;
+
+ ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_id,
+ DDR_PHY_DATA,
+ RESULT_DB_PHY_REG_ADDR +
+ effective_cs, ®);
+ reg = (reg & (~0x1f <<
+ ((mode == CENTRAL_TX) ?
+ (RESULT_DB_PHY_REG_TX_OFFSET) :
+ (RESULT_DB_PHY_REG_RX_OFFSET))))
+ | pup_win_length <<
+ ((mode == CENTRAL_TX) ?
+ (RESULT_DB_PHY_REG_TX_OFFSET) :
+ (RESULT_DB_PHY_REG_RX_OFFSET));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ RESULT_DB_PHY_REG_ADDR +
+ effective_cs, reg));
+
+ /* offset per CS is calculated earlier */
+ CHECK_STATUS(
+ ddr3_tip_bus_write(dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_id,
+ DDR_PHY_DATA,
+ reg_phy_off,
+ centralization_result
+ [if_id]
+ [bus_id]));
+ } else {
+ is_if_fail = 1;
+ }
+ }
+
+ if (is_if_fail == 1)
+ flow_result[if_id] = TEST_FAILED;
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ /* restore cs enable value */
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_UNICAST,
+ if_id, CS_ENABLE_REG,
+ cs_enable_reg_val[if_id],
+ MASK_ALL_BITS));
+ }
+
+ return is_if_fail;
+}
+
+/*
+ * Centralization Flow
+ */
+int ddr3_tip_special_rx(u32 dev_num)
+{
+ enum hws_training_ip_stat training_result[MAX_INTERFACE_NUM];
+ u32 if_id, pup_id, pattern_id, bit_id;
+ u8 cur_start_win[BUS_WIDTH_IN_BITS];
+ u8 cur_end_win[BUS_WIDTH_IN_BITS];
+ enum hws_training_result result_type = RESULT_PER_BIT;
+ enum hws_dir direction;
+ enum hws_search_dir search_dir_id;
+ u32 *result[HWS_SEARCH_DIR_LIMIT];
+ u32 max_win_size;
+ u8 cur_end_win_min, cur_start_win_max;
+ u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
+ u32 temp = 0;
+ int pad_num = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (ddr3_tip_special_rx_run_once_flag != 0)
+ return MV_OK;
+
+ ddr3_tip_special_rx_run_once_flag = 1;
+
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* save current cs enable reg val */
+ CHECK_STATUS(ddr3_tip_if_read(dev_num, ACCESS_TYPE_UNICAST,
+ if_id, CS_ENABLE_REG,
+ cs_enable_reg_val,
+ MASK_ALL_BITS));
+ /* enable single cs */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, ACCESS_TYPE_UNICAST,
+ if_id, CS_ENABLE_REG,
+ (1 << 3), (1 << 3)));
+ }
+
+ max_win_size = MAX_WINDOW_SIZE_RX;
+ direction = OPER_READ;
+ pattern_id = PATTERN_VREF;
+
+ /* start flow */
+ ddr3_tip_ip_training_wrapper(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, result_type,
+ HWS_CONTROL_ELEMENT_ADLL,
+ PARAM_NOT_CARE, direction,
+ tm->if_act_mask, 0x0,
+ max_win_size - 1, max_win_size - 1,
+ pattern_id, EDGE_FPF, CS_SINGLE,
+ PARAM_NOT_CARE, training_result);
+
+ for (if_id = start_if; if_id <= end_if; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (pup_id = 0;
+ pup_id <= tm->num_of_bus_per_interface; pup_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
+
+ for (search_dir_id = HWS_LOW2HIGH;
+ search_dir_id <= HWS_HIGH2LOW;
+ search_dir_id++) {
+ CHECK_STATUS(ddr3_tip_read_training_result
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup_id,
+ ALL_BITS_PER_PUP, search_dir_id,
+ direction, result_type,
+ TRAINING_LOAD_OPERATION_UNLOAD,
+ CS_SINGLE, &result[search_dir_id],
+ 1, 0, 0));
+ DEBUG_CENTRALIZATION_ENGINE(DEBUG_LEVEL_INFO,
+ ("Special: pat %d IF %d pup %d Regs: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ pattern_id, if_id,
+ pup_id,
+ result
+ [search_dir_id][0],
+ result
+ [search_dir_id][1],
+ result
+ [search_dir_id][2],
+ result
+ [search_dir_id][3],
+ result
+ [search_dir_id][4],
+ result
+ [search_dir_id][5],
+ result
+ [search_dir_id][6],
+ result
+ [search_dir_id]
+ [7]));
+ }
+
+ for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS; bit_id++) {
+ /*
+ * check if this code is valid for 2 edge,
+ * probably not :(
+ */
+ cur_start_win[bit_id] =
+ GET_TAP_RESULT(result[HWS_LOW2HIGH]
+ [bit_id], EDGE_1);
+ cur_end_win[bit_id] =
+ GET_TAP_RESULT(result[HWS_HIGH2LOW]
+ [bit_id], EDGE_1);
+ }
+ if (!((ddr3_tip_is_pup_lock
+ (result[HWS_LOW2HIGH], result_type)) &&
+ (ddr3_tip_is_pup_lock
+ (result[HWS_HIGH2LOW], result_type)))) {
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_ERROR,
+ ("Special: Pup lock fail, pat %d IF %d pup %d\n",
+ pattern_id, if_id, pup_id));
+ return MV_FAIL;
+ }
+
+ cur_end_win_min =
+ ddr3_tip_get_buf_min(cur_end_win);
+ cur_start_win_max =
+ ddr3_tip_get_buf_max(cur_start_win);
+
+ if (cur_start_win_max <= 1) { /* Align left */
+ for (bit_id = 0; bit_id < BUS_WIDTH_IN_BITS;
+ bit_id++) {
+ pad_num =
+ dq_map_table[bit_id +
+ pup_id *
+ BUS_WIDTH_IN_BITS +
+ if_id *
+ BUS_WIDTH_IN_BITS *
+ tm->
+ num_of_bus_per_interface];
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST,
+ pup_id, DDR_PHY_DATA,
+ PBS_RX_PHY_REG + pad_num,
+ &temp));
+ temp = (temp + 0xa > 31) ?
+ (31) : (temp + 0xa);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ pup_id, DDR_PHY_DATA,
+ PBS_RX_PHY_REG + pad_num,
+ temp));
+ }
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("Special: PBS:: I/F# %d , Bus# %d fix align to the Left\n",
+ if_id, pup_id));
+ }
+
+ if (cur_end_win_min > 30) { /* Align right */
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup_id,
+ DDR_PHY_DATA, PBS_RX_PHY_REG + 4,
+ &temp));
+ temp += 0xa;
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ pup_id, DDR_PHY_DATA,
+ PBS_RX_PHY_REG + 4, temp));
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup_id,
+ DDR_PHY_DATA, PBS_RX_PHY_REG + 5,
+ &temp));
+ temp += 0xa;
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ pup_id, DDR_PHY_DATA,
+ PBS_RX_PHY_REG + 5, temp));
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("Special: PBS:: I/F# %d , Bus# %d fix align to the right\n",
+ if_id, pup_id));
+ }
+
+ vref_window_size[if_id][pup_id] =
+ cur_end_win_min -
+ cur_start_win_max + 1;
+ DEBUG_CENTRALIZATION_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("Special: Winsize I/F# %d , Bus# %d is %d\n",
+ if_id, pup_id, vref_window_size
+ [if_id][pup_id]));
+ } /* pup */
+ } /* end of interface */
+
+ return MV_OK;
+}
+
+/*
+ * Print Centralization Result
+ */
+int ddr3_tip_print_centralization_result(u32 dev_num)
+{
+ u32 if_id = 0, bus_id = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ dev_num = dev_num;
+
+ printf("Centralization Results\n");
+ printf("I/F0 Result[0 - success 1-fail 2 - state_2 3 - state_3] ...\n");
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ printf("%d ,\n", centralization_state[if_id][bus_id]);
+ }
+ }
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+/* List of allowed frequency listed in order of enum hws_ddr_freq */
+u32 freq_val[DDR_FREQ_LIMIT] = {
+ 0, /*DDR_FREQ_LOW_FREQ */
+ 400, /*DDR_FREQ_400, */
+ 533, /*DDR_FREQ_533, */
+ 666, /*DDR_FREQ_667, */
+ 800, /*DDR_FREQ_800, */
+ 933, /*DDR_FREQ_933, */
+ 1066, /*DDR_FREQ_1066, */
+ 311, /*DDR_FREQ_311, */
+ 333, /*DDR_FREQ_333, */
+ 467, /*DDR_FREQ_467, */
+ 850, /*DDR_FREQ_850, */
+ 600, /*DDR_FREQ_600 */
+ 300, /*DDR_FREQ_300 */
+ 900, /*DDR_FREQ_900 */
+ 360, /*DDR_FREQ_360 */
+ 1000 /*DDR_FREQ_1000 */
+};
+
+/* Table for CL values per frequency for each speed bin index */
+struct cl_val_per_freq cas_latency_table[] = {
+ /*
+ * 400M 667M 933M 311M 467M 600M 360
+ * 100M 533M 800M 1066M 333M 850M 900
+ * 1000 (the order is 100, 400, 533 etc.)
+ */
+ /* DDR3-800D */
+ { {6, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
+ /* DDR3-800E */
+ { {6, 6, 0, 0, 0, 0, 0, 6, 6, 0, 0, 0, 6, 0, 6, 0} },
+ /* DDR3-1066E */
+ { {6, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 0, 5, 0, 5, 0} },
+ /* DDR3-1066F */
+ { {6, 6, 7, 0, 0, 0, 0, 6, 6, 7, 0, 0, 6, 0, 6, 0} },
+ /* DDR3-1066G */
+ { {6, 6, 8, 0, 0, 0, 0, 6, 6, 8, 0, 0, 6, 0, 6, 0} },
+ /* DDR3-1333F* */
+ { {6, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1333G */
+ { {6, 5, 7, 8, 0, 0, 0, 5, 5, 7, 0, 8, 5, 0, 5, 0} },
+ /* DDR3-1333H */
+ { {6, 6, 8, 9, 0, 0, 0, 6, 6, 8, 0, 9, 6, 0, 6, 0} },
+ /* DDR3-1333J* */
+ { {6, 6, 8, 10, 0, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0}
+ /* DDR3-1600G* */},
+ { {6, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1600H */
+ { {6, 5, 6, 8, 9, 0, 0, 5, 5, 6, 0, 8, 5, 0, 5, 0} },
+ /* DDR3-1600J */
+ { {6, 5, 7, 9, 10, 0, 0, 5, 5, 7, 0, 9, 5, 0, 5, 0} },
+ /* DDR3-1600K */
+ { {6, 6, 8, 10, 11, 0, 0, 6, 6, 8, 0, 10, 6, 0, 6, 0 } },
+ /* DDR3-1866J* */
+ { {6, 5, 6, 8, 9, 11, 0, 5, 5, 6, 11, 8, 5, 0, 5, 0} },
+ /* DDR3-1866K */
+ { {6, 5, 7, 8, 10, 11, 0, 5, 5, 7, 11, 8, 5, 11, 5, 11} },
+ /* DDR3-1866L */
+ { {6, 6, 7, 9, 11, 12, 0, 6, 6, 7, 12, 9, 6, 12, 6, 12} },
+ /* DDR3-1866M* */
+ { {6, 6, 8, 10, 11, 13, 0, 6, 6, 8, 13, 10, 6, 13, 6, 13} },
+ /* DDR3-2133K* */
+ { {6, 5, 6, 7, 9, 10, 11, 5, 5, 6, 10, 7, 5, 11, 5, 11} },
+ /* DDR3-2133L */
+ { {6, 5, 6, 8, 9, 11, 12, 5, 5, 6, 11, 8, 5, 12, 5, 12} },
+ /* DDR3-2133M */
+ { {6, 5, 7, 9, 10, 12, 13, 5, 5, 7, 12, 9, 5, 13, 5, 13} },
+ /* DDR3-2133N* */
+ { {6, 6, 7, 9, 11, 13, 14, 6, 6, 7, 13, 9, 6, 14, 6, 14} },
+ /* DDR3-1333H-ext */
+ { {6, 6, 7, 9, 0, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
+ /* DDR3-1600K-ext */
+ { {6, 6, 7, 9, 11, 0, 0, 6, 6, 7, 0, 9, 6, 0, 6, 0} },
+ /* DDR3-1866M-ext */
+ { {6, 6, 7, 9, 11, 13, 0, 6, 6, 7, 13, 9, 6, 13, 6, 13} },
+};
+
+/* Table for CWL values per speedbin index */
+struct cl_val_per_freq cas_write_latency_table[] = {
+ /*
+ * 400M 667M 933M 311M 467M 600M 360
+ * 100M 533M 800M 1066M 333M 850M 900
+ * (the order is 100, 400, 533 etc.)
+ */
+ /* DDR3-800D */
+ { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
+ /* DDR3-800E */
+ { {5, 5, 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, 5, 0, 5, 0} },
+ /* DDR3-1066E */
+ { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1066F */
+ { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1066G */
+ { {5, 5, 6, 0, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1333F* */
+ { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1333G */
+ { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1333H */
+ { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1333J* */
+ { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1600G* */
+ { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1600H */
+ { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1600J */
+ { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1600K */
+ { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1866J* */
+ { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
+ /* DDR3-1866K */
+ { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 0, 5, 0} },
+ /* DDR3-1866L */
+ { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
+ /* DDR3-1866M* */
+ { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
+ /* DDR3-2133K* */
+ { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
+ /* DDR3-2133L */
+ { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
+ /* DDR3-2133M */
+ { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
+ /* DDR3-2133N* */
+ { {5, 5, 6, 7, 8, 9, 10, 5, 5, 6, 9, 7, 5, 9, 5, 10} },
+ /* DDR3-1333H-ext */
+ { {5, 5, 6, 7, 0, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1600K-ext */
+ { {5, 5, 6, 7, 8, 0, 0, 5, 5, 6, 0, 7, 5, 0, 5, 0} },
+ /* DDR3-1866M-ext */
+ { {5, 5, 6, 7, 8, 9, 0, 5, 5, 6, 9, 7, 5, 9, 5, 9} },
+};
+
+u8 twr_mask_table[] = {
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 1, /*5 */
+ 2, /*6 */
+ 3, /*7 */
+ 10,
+ 10,
+ 5, /*10 */
+ 10,
+ 6, /*12 */
+ 10,
+ 7, /*14 */
+ 10,
+ 0 /*16 */
+};
+
+u8 cl_mask_table[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x2,
+ 0x4,
+ 0x6,
+ 0x8,
+ 0xa,
+ 0xc,
+ 0xe,
+ 0x1,
+ 0x3,
+ 0x5,
+ 0x5
+};
+
+u8 cwl_mask_table[] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0x1,
+ 0x2,
+ 0x3,
+ 0x4,
+ 0x5,
+ 0x6,
+ 0x7,
+ 0x8,
+ 0x9,
+ 0x9
+};
+
+/* RFC values (in ns) */
+u16 rfc_table[] = {
+ 90, /* 512M */
+ 110, /* 1G */
+ 160, /* 2G */
+ 260, /* 4G */
+ 350 /* 8G */
+};
+
+u32 speed_bin_table_t_rc[] = {
+ 50000,
+ 52500,
+ 48750,
+ 50625,
+ 52500,
+ 46500,
+ 48000,
+ 49500,
+ 51000,
+ 45000,
+ 46250,
+ 47500,
+ 48750,
+ 44700,
+ 45770,
+ 46840,
+ 47910,
+ 43285,
+ 44220,
+ 45155,
+ 46900
+};
+
+u32 speed_bin_table_t_rcd_t_rp[] = {
+ 12500,
+ 15000,
+ 11250,
+ 13125,
+ 15000,
+ 10500,
+ 12000,
+ 13500,
+ 15000,
+ 10000,
+ 11250,
+ 12500,
+ 13750,
+ 10700,
+ 11770,
+ 12840,
+ 13910,
+ 10285,
+ 11022,
+ 12155,
+ 13090,
+};
+
+enum {
+ PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR = 0,
+ PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM
+};
+
+static u8 pattern_killer_pattern_table_map[KILLER_PATTERN_LENGTH * 2][2] = {
+ /*Aggressor / Victim */
+ {1, 0},
+ {0, 0},
+ {1, 0},
+ {1, 1},
+ {0, 1},
+ {0, 1},
+ {1, 0},
+ {0, 1},
+ {1, 0},
+ {0, 1},
+ {1, 0},
+ {1, 0},
+ {0, 1},
+ {1, 0},
+ {0, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {0, 0},
+ {0, 1},
+ {0, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {0, 0},
+ {0, 0},
+ {1, 1},
+ {0, 0},
+ {1, 1},
+ {0, 1},
+ {0, 0},
+ {0, 1},
+ {0, 1},
+ {0, 0},
+ {1, 1},
+ {1, 1},
+ {1, 0},
+ {1, 0},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1},
+ {1, 1}
+};
+
+static u8 pattern_vref_pattern_table_map[] = {
+ /* 1 means 0xffffffff, 0 is 0x0 */
+ 0xb8,
+ 0x52,
+ 0x55,
+ 0x8a,
+ 0x33,
+ 0xa6,
+ 0x6d,
+ 0xfe
+};
+
+/* Return speed Bin value for selected index and t* element */
+u32 speed_bin_table(u8 index, enum speed_bin_table_elements element)
+{
+ u32 result = 0;
+
+ switch (element) {
+ case SPEED_BIN_TRCD:
+ case SPEED_BIN_TRP:
+ result = speed_bin_table_t_rcd_t_rp[index];
+ break;
+ case SPEED_BIN_TRAS:
+ if (index < 6)
+ result = 37500;
+ else if (index < 10)
+ result = 36000;
+ else if (index < 14)
+ result = 35000;
+ else if (index < 18)
+ result = 34000;
+ else
+ result = 33000;
+ break;
+ case SPEED_BIN_TRC:
+ result = speed_bin_table_t_rc[index];
+ break;
+ case SPEED_BIN_TRRD1K:
+ if (index < 3)
+ result = 10000;
+ else if (index < 6)
+ result = 7005;
+ else if (index < 14)
+ result = 6000;
+ else
+ result = 5000;
+ break;
+ case SPEED_BIN_TRRD2K:
+ if (index < 6)
+ result = 10000;
+ else if (index < 14)
+ result = 7005;
+ else
+ result = 6000;
+ break;
+ case SPEED_BIN_TPD:
+ if (index < 3)
+ result = 7500;
+ else if (index < 10)
+ result = 5625;
+ else
+ result = 5000;
+ break;
+ case SPEED_BIN_TFAW1K:
+ if (index < 3)
+ result = 40000;
+ else if (index < 6)
+ result = 37500;
+ else if (index < 14)
+ result = 30000;
+ else if (index < 18)
+ result = 27000;
+ else
+ result = 25000;
+ break;
+ case SPEED_BIN_TFAW2K:
+ if (index < 6)
+ result = 50000;
+ else if (index < 10)
+ result = 45000;
+ else if (index < 14)
+ result = 40000;
+ else
+ result = 35000;
+ break;
+ case SPEED_BIN_TWTR:
+ result = 7500;
+ break;
+ case SPEED_BIN_TRTP:
+ result = 7500;
+ break;
+ case SPEED_BIN_TWR:
+ result = 15000;
+ break;
+ case SPEED_BIN_TMOD:
+ result = 15000;
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+static inline u32 pattern_table_get_killer_word(u8 dqs, u8 index)
+{
+ u8 i, byte = 0;
+ u8 role;
+
+ for (i = 0; i < 8; i++) {
+ role = (i == dqs) ?
+ (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
+ (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
+ byte |= pattern_killer_pattern_table_map[index][role] << i;
+ }
+
+ return byte | (byte << 8) | (byte << 16) | (byte << 24);
+}
+
+static inline u32 pattern_table_get_killer_word16(u8 dqs, u8 index)
+{
+ u8 i, byte0 = 0, byte1 = 0;
+ u8 role;
+
+ for (i = 0; i < 8; i++) {
+ role = (i == dqs) ?
+ (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
+ (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
+ byte0 |= pattern_killer_pattern_table_map[index * 2][role] << i;
+ }
+
+ for (i = 0; i < 8; i++) {
+ role = (i == dqs) ?
+ (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_AGGRESSOR) :
+ (PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM);
+ byte1 |= pattern_killer_pattern_table_map
+ [index * 2 + 1][role] << i;
+ }
+
+ return byte0 | (byte0 << 8) | (byte1 << 16) | (byte1 << 24);
+}
+
+static inline u32 pattern_table_get_sso_word(u8 sso, u8 index)
+{
+ u8 step = sso + 1;
+
+ if (0 == ((index / step) & 1))
+ return 0x0;
+ else
+ return 0xffffffff;
+}
+
+static inline u32 pattern_table_get_vref_word(u8 index)
+{
+ if (0 == ((pattern_vref_pattern_table_map[index / 8] >>
+ (index % 8)) & 1))
+ return 0x0;
+ else
+ return 0xffffffff;
+}
+
+static inline u32 pattern_table_get_vref_word16(u8 index)
+{
+ if (0 == pattern_killer_pattern_table_map
+ [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
+ 0 == pattern_killer_pattern_table_map
+ [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
+ return 0x00000000;
+ else if (1 == pattern_killer_pattern_table_map
+ [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
+ 0 == pattern_killer_pattern_table_map
+ [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
+ return 0xffff0000;
+ else if (0 == pattern_killer_pattern_table_map
+ [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2] &&
+ 1 == pattern_killer_pattern_table_map
+ [PATTERN_KILLER_PATTERN_TABLE_MAP_ROLE_VICTIM][index * 2 + 1])
+ return 0x0000ffff;
+ else
+ return 0xffffffff;
+}
+
+static inline u32 pattern_table_get_static_pbs_word(u8 index)
+{
+ u16 temp;
+
+ temp = ((0x00ff << (index / 3)) & 0xff00) >> 8;
+
+ return temp | (temp << 8) | (temp << 16) | (temp << 24);
+}
+
+inline u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index)
+{
+ u32 pattern;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0) {
+ /* 32bit patterns */
+ switch (type) {
+ case PATTERN_PBS1:
+ case PATTERN_PBS2:
+ if (index == 0 || index == 2 || index == 5 ||
+ index == 7)
+ pattern = PATTERN_55;
+ else
+ pattern = PATTERN_AA;
+ break;
+ case PATTERN_PBS3:
+ if (0 == (index & 1))
+ pattern = PATTERN_55;
+ else
+ pattern = PATTERN_AA;
+ break;
+ case PATTERN_RL:
+ if (index < 6)
+ pattern = PATTERN_00;
+ else
+ pattern = PATTERN_80;
+ break;
+ case PATTERN_STATIC_PBS:
+ pattern = pattern_table_get_static_pbs_word(index);
+ break;
+ case PATTERN_KILLER_DQ0:
+ case PATTERN_KILLER_DQ1:
+ case PATTERN_KILLER_DQ2:
+ case PATTERN_KILLER_DQ3:
+ case PATTERN_KILLER_DQ4:
+ case PATTERN_KILLER_DQ5:
+ case PATTERN_KILLER_DQ6:
+ case PATTERN_KILLER_DQ7:
+ pattern = pattern_table_get_killer_word(
+ (u8)(type - PATTERN_KILLER_DQ0), index);
+ break;
+ case PATTERN_RL2:
+ if (index < 6)
+ pattern = PATTERN_00;
+ else
+ pattern = PATTERN_01;
+ break;
+ case PATTERN_TEST:
+ if (index > 1 && index < 6)
+ pattern = PATTERN_20;
+ else
+ pattern = PATTERN_00;
+ break;
+ case PATTERN_FULL_SSO0:
+ case PATTERN_FULL_SSO1:
+ case PATTERN_FULL_SSO2:
+ case PATTERN_FULL_SSO3:
+ pattern = pattern_table_get_sso_word(
+ (u8)(type - PATTERN_FULL_SSO0), index);
+ break;
+ case PATTERN_VREF:
+ pattern = pattern_table_get_vref_word(index);
+ break;
+ default:
+ pattern = 0;
+ break;
+ }
+ } else {
+ /* 16bit patterns */
+ switch (type) {
+ case PATTERN_PBS1:
+ case PATTERN_PBS2:
+ case PATTERN_PBS3:
+ pattern = PATTERN_55AA;
+ break;
+ case PATTERN_RL:
+ if (index < 3)
+ pattern = PATTERN_00;
+ else
+ pattern = PATTERN_80;
+ break;
+ case PATTERN_STATIC_PBS:
+ pattern = PATTERN_00FF;
+ break;
+ case PATTERN_KILLER_DQ0:
+ case PATTERN_KILLER_DQ1:
+ case PATTERN_KILLER_DQ2:
+ case PATTERN_KILLER_DQ3:
+ case PATTERN_KILLER_DQ4:
+ case PATTERN_KILLER_DQ5:
+ case PATTERN_KILLER_DQ6:
+ case PATTERN_KILLER_DQ7:
+ pattern = pattern_table_get_killer_word16(
+ (u8)(type - PATTERN_KILLER_DQ0), index);
+ break;
+ case PATTERN_RL2:
+ if (index < 3)
+ pattern = PATTERN_00;
+ else
+ pattern = PATTERN_01;
+ break;
+ case PATTERN_TEST:
+ pattern = PATTERN_0080;
+ break;
+ case PATTERN_FULL_SSO0:
+ pattern = 0x0000ffff;
+ break;
+ case PATTERN_FULL_SSO1:
+ case PATTERN_FULL_SSO2:
+ case PATTERN_FULL_SSO3:
+ pattern = pattern_table_get_sso_word(
+ (u8)(type - PATTERN_FULL_SSO1), index);
+ break;
+ case PATTERN_VREF:
+ pattern = pattern_table_get_vref_word16(index);
+ break;
+ default:
+ pattern = 0;
+ break;
+ }
+ }
+
+ return pattern;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#define VREF_INITIAL_STEP 3
+#define VREF_SECOND_STEP 1
+#define VREF_MAX_INDEX 7
+#define MAX_VALUE (1024 - 1)
+#define MIN_VALUE (-MAX_VALUE)
+#define GET_RD_SAMPLE_DELAY(data, cs) ((data >> rd_sample_mask[cs]) & 0xf)
+
+u32 ck_delay = (u32)-1, ck_delay_16 = (u32)-1;
+u32 ca_delay;
+int ddr3_tip_centr_skip_min_win_check = 0;
+u8 current_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
+u8 last_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
+u16 current_valid_window[MAX_BUS_NUM][MAX_INTERFACE_NUM];
+u16 last_valid_window[MAX_BUS_NUM][MAX_INTERFACE_NUM];
+u8 lim_vref[MAX_BUS_NUM][MAX_INTERFACE_NUM];
+u8 interface_state[MAX_INTERFACE_NUM];
+u8 vref_window_size[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u8 vref_window_size_th = 12;
+
+static u8 pup_st[MAX_BUS_NUM][MAX_INTERFACE_NUM];
+
+static u32 rd_sample_mask[] = {
+ 0,
+ 8,
+ 16,
+ 24
+};
+
+#define VREF_STEP_1 0
+#define VREF_STEP_2 1
+#define VREF_CONVERGE 2
+
+/*
+ * ODT additional timing
+ */
+int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id)
+{
+ u32 cs_num = 0, max_read_sample = 0, min_read_sample = 0;
+ u32 data_read[MAX_INTERFACE_NUM] = { 0 };
+ u32 read_sample[MAX_CS_NUM];
+ u32 val;
+ u32 pup_index;
+ int max_phase = MIN_VALUE, current_phase;
+ enum hws_access_type access_type = ACCESS_TYPE_UNICAST;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ DUNIT_ODT_CONTROL_REG,
+ 0 << 8, 0x3 << 8));
+ CHECK_STATUS(ddr3_tip_if_read(dev_num, access_type, if_id,
+ READ_DATA_SAMPLE_DELAY,
+ data_read, MASK_ALL_BITS));
+ val = data_read[if_id];
+
+ for (cs_num = 0; cs_num < MAX_CS_NUM; cs_num++) {
+ read_sample[cs_num] = GET_RD_SAMPLE_DELAY(val, cs_num);
+
+ /* find maximum of read_samples */
+ if (read_sample[cs_num] >= max_read_sample) {
+ if (read_sample[cs_num] == max_read_sample)
+ max_phase = MIN_VALUE;
+ else
+ max_read_sample = read_sample[cs_num];
+
+ for (pup_index = 0;
+ pup_index < tm->num_of_bus_per_interface;
+ pup_index++) {
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup_index,
+ DDR_PHY_DATA,
+ RL_PHY_REG + CS_REG_VALUE(cs_num),
+ &val));
+
+ current_phase = ((int)val & 0xe0) >> 6;
+ if (current_phase >= max_phase)
+ max_phase = current_phase;
+ }
+ }
+
+ /* find minimum */
+ if (read_sample[cs_num] < min_read_sample)
+ min_read_sample = read_sample[cs_num];
+ }
+
+ min_read_sample = min_read_sample - 1;
+ max_read_sample = max_read_sample + 4 + (max_phase + 1) / 2 + 1;
+ if (min_read_sample >= 0xf)
+ min_read_sample = 0xf;
+ if (max_read_sample >= 0x1f)
+ max_read_sample = 0x1f;
+
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ ODT_TIMING_LOW,
+ ((min_read_sample - 1) << 12),
+ 0xf << 12));
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, if_id,
+ ODT_TIMING_LOW,
+ (max_read_sample << 16),
+ 0x1f << 16));
+
+ return MV_OK;
+}
+
+int get_valid_win_rx(u32 dev_num, u32 if_id, u8 res[4])
+{
+ u32 reg_pup = RESULT_DB_PHY_REG_ADDR;
+ u32 reg_data;
+ u32 cs_num;
+ int i;
+
+ cs_num = 0;
+
+ /* TBD */
+ reg_pup += cs_num;
+
+ for (i = 0; i < 4; i++) {
+ CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id,
+ ACCESS_TYPE_UNICAST, i,
+ DDR_PHY_DATA, reg_pup,
+ ®_data));
+ res[i] = (reg_data >> RESULT_DB_PHY_REG_RX_OFFSET) & 0x1f;
+ }
+
+ return 0;
+}
+
+/*
+ * This algorithm deals with the vertical optimum from Voltage point of view
+ * of the sample signal.
+ * Voltage sample point can improve the Eye / window size of the bit and the
+ * pup.
+ * The problem is that it is tune for all DQ the same so there isn't any
+ * PBS like code.
+ * It is more like centralization.
+ * But because we don't have The training SM support we do it a bit more
+ * smart search to save time.
+ */
+int ddr3_tip_vref(u32 dev_num)
+{
+ /*
+ * The Vref register have non linear order. Need to check what will be
+ * in future projects.
+ */
+ u32 vref_map[8] = {
+ 1, 2, 3, 4, 5, 6, 7, 0
+ };
+ /* State and parameter definitions */
+ u32 initial_step = VREF_INITIAL_STEP;
+ /* need to be assign with minus ????? */
+ u32 second_step = VREF_SECOND_STEP;
+ u32 algo_run_flag = 0, currrent_vref = 0;
+ u32 while_count = 0;
+ u32 pup = 0, if_id = 0, num_pup = 0, rep = 0;
+ u32 val = 0;
+ u32 reg_addr = 0xa8;
+ u32 copy_start_pattern, copy_end_pattern;
+ enum hws_result *flow_result = ddr3_tip_get_result_ptr(training_stage);
+ u8 res[4];
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ CHECK_STATUS(ddr3_tip_special_rx(dev_num));
+
+ /* save start/end pattern */
+ copy_start_pattern = start_pattern;
+ copy_end_pattern = end_pattern;
+
+ /* set vref as centralization pattern */
+ start_pattern = PATTERN_VREF;
+ end_pattern = PATTERN_VREF;
+
+ /* init params */
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (pup = 0;
+ pup < tm->num_of_bus_per_interface; pup++) {
+ current_vref[pup][if_id] = 0;
+ last_vref[pup][if_id] = 0;
+ lim_vref[pup][if_id] = 0;
+ current_valid_window[pup][if_id] = 0;
+ last_valid_window[pup][if_id] = 0;
+ if (vref_window_size[if_id][pup] >
+ vref_window_size_th) {
+ pup_st[pup][if_id] = VREF_CONVERGE;
+ DEBUG_TRAINING_HW_ALG(
+ DEBUG_LEVEL_INFO,
+ ("VREF config, IF[ %d ]pup[ %d ] - Vref tune not requered (%d)\n",
+ if_id, pup, __LINE__));
+ } else {
+ pup_st[pup][if_id] = VREF_STEP_1;
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr, &val));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ pup, DDR_PHY_DATA, reg_addr,
+ (val & (~0xf)) | vref_map[0]));
+ DEBUG_TRAINING_HW_ALG(
+ DEBUG_LEVEL_INFO,
+ ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
+ if_id, pup,
+ (val & (~0xf)) | vref_map[0],
+ __LINE__));
+ }
+ }
+ interface_state[if_id] = 0;
+ }
+
+ /* TODO: Set number of active interfaces */
+ num_pup = tm->num_of_bus_per_interface * MAX_INTERFACE_NUM;
+
+ while ((algo_run_flag <= num_pup) & (while_count < 10)) {
+ while_count++;
+ for (rep = 1; rep < 4; rep++) {
+ ddr3_tip_centr_skip_min_win_check = 1;
+ ddr3_tip_centralization_rx(dev_num);
+ ddr3_tip_centr_skip_min_win_check = 0;
+
+ /* Read Valid window results only for non converge pups */
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (interface_state[if_id] != 4) {
+ get_valid_win_rx(dev_num, if_id, res);
+ for (pup = 0;
+ pup < tm->num_of_bus_per_interface;
+ pup++) {
+ VALIDATE_ACTIVE
+ (tm->bus_act_mask, pup);
+ if (pup_st[pup]
+ [if_id] ==
+ VREF_CONVERGE)
+ continue;
+
+ current_valid_window[pup]
+ [if_id] =
+ (current_valid_window[pup]
+ [if_id] * (rep - 1) +
+ 1000 * res[pup]) / rep;
+ }
+ }
+ }
+ }
+
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ DEBUG_TRAINING_HW_ALG(
+ DEBUG_LEVEL_TRACE,
+ ("current_valid_window: IF[ %d ] - ", if_id));
+
+ for (pup = 0;
+ pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,
+ ("%d ",
+ current_valid_window
+ [pup][if_id]));
+ }
+ DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE, ("\n"));
+ }
+
+ /* Compare results and respond as function of state */
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (pup = 0;
+ pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,
+ ("I/F[ %d ], pup[ %d ] STATE #%d (%d)\n",
+ if_id, pup,
+ pup_st[pup]
+ [if_id], __LINE__));
+
+ if (pup_st[pup][if_id] == VREF_CONVERGE)
+ continue;
+
+ DEBUG_TRAINING_HW_ALG(DEBUG_LEVEL_TRACE,
+ ("I/F[ %d ], pup[ %d ] CHECK progress - Current %d Last %d, limit VREF %d (%d)\n",
+ if_id, pup,
+ current_valid_window[pup]
+ [if_id],
+ last_valid_window[pup]
+ [if_id], lim_vref[pup]
+ [if_id], __LINE__));
+
+ /*
+ * The -1 is for solution resolution +/- 1 tap
+ * of ADLL
+ */
+ if (current_valid_window[pup][if_id] + 200 >=
+ (last_valid_window[pup][if_id])) {
+ if (pup_st[pup][if_id] == VREF_STEP_1) {
+ /*
+ * We stay in the same state and
+ * step just update the window
+ * size (take the max) and Vref
+ */
+ if (current_vref[pup]
+ [if_id] == VREF_MAX_INDEX) {
+ /*
+ * If we step to the end
+ * and didn't converge
+ * to some particular
+ * better Vref value
+ * define the pup as
+ * converge and step
+ * back to nominal
+ * Vref.
+ */
+ pup_st[pup]
+ [if_id] =
+ VREF_CONVERGE;
+ algo_run_flag++;
+ interface_state
+ [if_id]++;
+ DEBUG_TRAINING_HW_ALG
+ (DEBUG_LEVEL_TRACE,
+ ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n",
+ if_id, pup,
+ current_vref[pup]
+ [if_id],
+ __LINE__));
+ } else {
+ /* continue to update the Vref index */
+ current_vref[pup]
+ [if_id] =
+ ((current_vref[pup]
+ [if_id] +
+ initial_step) >
+ VREF_MAX_INDEX) ?
+ VREF_MAX_INDEX
+ : (current_vref[pup]
+ [if_id] +
+ initial_step);
+ if (current_vref[pup]
+ [if_id] ==
+ VREF_MAX_INDEX) {
+ pup_st[pup]
+ [if_id]
+ =
+ VREF_STEP_2;
+ }
+ lim_vref[pup]
+ [if_id] =
+ last_vref[pup]
+ [if_id] =
+ current_vref[pup]
+ [if_id];
+ }
+
+ last_valid_window[pup]
+ [if_id] =
+ GET_MAX(current_valid_window
+ [pup][if_id],
+ last_valid_window
+ [pup]
+ [if_id]);
+
+ /* update the Vref for next stage */
+ currrent_vref =
+ current_vref[pup]
+ [if_id];
+ CHECK_STATUS
+ (ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ &val));
+ CHECK_STATUS
+ (ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ (val & (~0xf)) |
+ vref_map[currrent_vref]));
+ DEBUG_TRAINING_HW_ALG
+ (DEBUG_LEVEL_TRACE,
+ ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
+ if_id, pup,
+ (val & (~0xf)) |
+ vref_map[currrent_vref],
+ __LINE__));
+ } else if (pup_st[pup][if_id]
+ == VREF_STEP_2) {
+ /*
+ * We keep on search back with
+ * the same step size.
+ */
+ last_valid_window[pup]
+ [if_id] =
+ GET_MAX(current_valid_window
+ [pup][if_id],
+ last_valid_window
+ [pup]
+ [if_id]);
+ last_vref[pup][if_id] =
+ current_vref[pup]
+ [if_id];
+
+ /* we finish all search space */
+ if ((current_vref[pup]
+ [if_id] - second_step) == lim_vref[pup][if_id]) {
+ /*
+ * If we step to the end
+ * and didn't converge
+ * to some particular
+ * better Vref value
+ * define the pup as
+ * converge and step
+ * back to nominal
+ * Vref.
+ */
+ pup_st[pup]
+ [if_id] =
+ VREF_CONVERGE;
+ algo_run_flag++;
+
+ interface_state
+ [if_id]++;
+
+ current_vref[pup]
+ [if_id] =
+ (current_vref[pup]
+ [if_id] -
+ second_step);
+
+ DEBUG_TRAINING_HW_ALG
+ (DEBUG_LEVEL_TRACE,
+ ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n",
+ if_id, pup,
+ current_vref[pup]
+ [if_id],
+ __LINE__));
+ } else
+ /* we finish all search space */
+ if (current_vref[pup]
+ [if_id] ==
+ lim_vref[pup]
+ [if_id]) {
+ /*
+ * If we step to the end
+ * and didn't converge
+ * to some particular
+ * better Vref value
+ * define the pup as
+ * converge and step
+ * back to nominal
+ * Vref.
+ */
+ pup_st[pup]
+ [if_id] =
+ VREF_CONVERGE;
+
+ algo_run_flag++;
+ interface_state
+ [if_id]++;
+ DEBUG_TRAINING_HW_ALG
+ (DEBUG_LEVEL_TRACE,
+ ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n",
+ if_id, pup,
+ current_vref[pup]
+ [if_id],
+ __LINE__));
+ } else {
+ current_vref[pup]
+ [if_id] =
+ current_vref[pup]
+ [if_id] -
+ second_step;
+ }
+
+ /* Update the Vref for next stage */
+ currrent_vref =
+ current_vref[pup]
+ [if_id];
+ CHECK_STATUS
+ (ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ &val));
+ CHECK_STATUS
+ (ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ (val & (~0xf)) |
+ vref_map[currrent_vref]));
+ DEBUG_TRAINING_HW_ALG
+ (DEBUG_LEVEL_TRACE,
+ ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
+ if_id, pup,
+ (val & (~0xf)) |
+ vref_map[currrent_vref],
+ __LINE__));
+ }
+ } else {
+ /* we change state and change step */
+ if (pup_st[pup][if_id] == VREF_STEP_1) {
+ pup_st[pup][if_id] =
+ VREF_STEP_2;
+ lim_vref[pup][if_id] =
+ current_vref[pup]
+ [if_id] - initial_step;
+ last_valid_window[pup]
+ [if_id] =
+ current_valid_window[pup]
+ [if_id];
+ last_vref[pup][if_id] =
+ current_vref[pup]
+ [if_id];
+ current_vref[pup][if_id] =
+ last_vref[pup][if_id] -
+ second_step;
+
+ /* Update the Vref for next stage */
+ CHECK_STATUS
+ (ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ &val));
+ CHECK_STATUS
+ (ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ (val & (~0xf)) |
+ vref_map[current_vref[pup]
+ [if_id]]));
+ DEBUG_TRAINING_HW_ALG
+ (DEBUG_LEVEL_TRACE,
+ ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
+ if_id, pup,
+ (val & (~0xf)) |
+ vref_map[current_vref[pup]
+ [if_id]],
+ __LINE__));
+
+ } else if (pup_st[pup][if_id] == VREF_STEP_2) {
+ /*
+ * The last search was the max
+ * point set value and exit
+ */
+ CHECK_STATUS
+ (ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ &val));
+ CHECK_STATUS
+ (ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ (val & (~0xf)) |
+ vref_map[last_vref[pup]
+ [if_id]]));
+ DEBUG_TRAINING_HW_ALG
+ (DEBUG_LEVEL_TRACE,
+ ("VREF config, IF[ %d ]pup[ %d ] - Vref = %X (%d)\n",
+ if_id, pup,
+ (val & (~0xf)) |
+ vref_map[last_vref[pup]
+ [if_id]],
+ __LINE__));
+ pup_st[pup][if_id] =
+ VREF_CONVERGE;
+ algo_run_flag++;
+ interface_state[if_id]++;
+ DEBUG_TRAINING_HW_ALG
+ (DEBUG_LEVEL_TRACE,
+ ("I/F[ %d ], pup[ %d ] VREF_CONVERGE - Vref = %X (%d)\n",
+ if_id, pup,
+ current_vref[pup]
+ [if_id], __LINE__));
+ }
+ }
+ }
+ }
+ }
+
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (pup = 0;
+ pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr, &val));
+ DEBUG_TRAINING_HW_ALG(
+ DEBUG_LEVEL_INFO,
+ ("FINAL values: I/F[ %d ], pup[ %d ] - Vref = %X (%d)\n",
+ if_id, pup, val, __LINE__));
+ }
+ }
+
+ flow_result[if_id] = TEST_SUCCESS;
+
+ /* restore start/end pattern */
+ start_pattern = copy_start_pattern;
+ end_pattern = copy_end_pattern;
+
+ return 0;
+}
+
+/*
+ * CK/CA Delay
+ */
+int ddr3_tip_cmd_addr_init_delay(u32 dev_num, u32 adll_tap)
+{
+ u32 if_id = 0;
+ u32 ck_num_adll_tap = 0, ca_num_adll_tap = 0, data = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /*
+ * ck_delay_table is delaying the of the clock signal only.
+ * (to overcome timing issues between_c_k & command/address signals)
+ */
+ /*
+ * ca_delay is delaying the of the entire command & Address signals
+ * (include Clock signal to overcome DGL error on the Clock versus
+ * the DQS).
+ */
+
+ /* Calc ADLL Tap */
+ if ((ck_delay == -1) || (ck_delay_16 == -1)) {
+ DEBUG_TRAINING_HW_ALG(
+ DEBUG_LEVEL_ERROR,
+ ("ERROR: One of ck_delay values not initialized!!!\n"));
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* Calc delay ps in ADLL tap */
+ if (tm->interface_params[if_id].bus_width ==
+ BUS_WIDTH_16)
+ ck_num_adll_tap = ck_delay_16 / adll_tap;
+ else
+ ck_num_adll_tap = ck_delay / adll_tap;
+
+ ca_num_adll_tap = ca_delay / adll_tap;
+ data = (ck_num_adll_tap & 0x3f) +
+ ((ca_num_adll_tap & 0x3f) << 10);
+
+ /*
+ * Set the ADLL number to the CK ADLL for Interfaces for
+ * all Pup
+ */
+ DEBUG_TRAINING_HW_ALG(
+ DEBUG_LEVEL_TRACE,
+ ("ck_num_adll_tap %d ca_num_adll_tap %d adll_tap %d\n",
+ ck_num_adll_tap, ca_num_adll_tap, adll_tap));
+
+ CHECK_STATUS(ddr3_tip_bus_write(dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, DDR_PHY_CONTROL,
+ 0x0, data));
+ }
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_HW_ALGO_H_
+#define _DDR3_TRAINING_HW_ALGO_H_
+
+int ddr3_tip_vref(u32 dev_num);
+int ddr3_tip_write_additional_odt_setting(u32 dev_num, u32 if_id);
+int ddr3_tip_cmd_addr_init_delay(u32 dev_num, u32 adll_tap);
+
+#endif /* _DDR3_TRAINING_HW_ALGO_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_H_
+#define _DDR3_TRAINING_IP_H_
+
+#include "ddr3_training_ip_def.h"
+#include "ddr_topology_def.h"
+#include "ddr_training_ip_db.h"
+
+#define DDR3_TIP_VERSION_STRING "DDR3 Training Sequence - Ver TIP-1.29."
+
+#define MAX_CS_NUM 4
+#define MAX_TOTAL_BUS_NUM (MAX_INTERFACE_NUM * MAX_BUS_NUM)
+#define MAX_DQ_NUM 40
+
+#define GET_MIN(arg1, arg2) ((arg1) < (arg2)) ? (arg1) : (arg2)
+#define GET_MAX(arg1, arg2) ((arg1) < (arg2)) ? (arg2) : (arg1)
+
+#define INIT_CONTROLLER_MASK_BIT 0x00000001
+#define STATIC_LEVELING_MASK_BIT 0x00000002
+#define SET_LOW_FREQ_MASK_BIT 0x00000004
+#define LOAD_PATTERN_MASK_BIT 0x00000008
+#define SET_MEDIUM_FREQ_MASK_BIT 0x00000010
+#define WRITE_LEVELING_MASK_BIT 0x00000020
+#define LOAD_PATTERN_2_MASK_BIT 0x00000040
+#define READ_LEVELING_MASK_BIT 0x00000080
+#define SW_READ_LEVELING_MASK_BIT 0x00000100
+#define WRITE_LEVELING_SUPP_MASK_BIT 0x00000200
+#define PBS_RX_MASK_BIT 0x00000400
+#define PBS_TX_MASK_BIT 0x00000800
+#define SET_TARGET_FREQ_MASK_BIT 0x00001000
+#define ADJUST_DQS_MASK_BIT 0x00002000
+#define WRITE_LEVELING_TF_MASK_BIT 0x00004000
+#define LOAD_PATTERN_HIGH_MASK_BIT 0x00008000
+#define READ_LEVELING_TF_MASK_BIT 0x00010000
+#define WRITE_LEVELING_SUPP_TF_MASK_BIT 0x00020000
+#define DM_PBS_TX_MASK_BIT 0x00040000
+#define CENTRALIZATION_RX_MASK_BIT 0x00100000
+#define CENTRALIZATION_TX_MASK_BIT 0x00200000
+#define TX_EMPHASIS_MASK_BIT 0x00400000
+#define PER_BIT_READ_LEVELING_TF_MASK_BIT 0x00800000
+#define VREF_CALIBRATION_MASK_BIT 0x01000000
+
+enum hws_result {
+ TEST_FAILED = 0,
+ TEST_SUCCESS = 1,
+ NO_TEST_DONE = 2
+};
+
+enum hws_training_result {
+ RESULT_PER_BIT,
+ RESULT_PER_BYTE
+};
+
+enum auto_tune_stage {
+ INIT_CONTROLLER,
+ STATIC_LEVELING,
+ SET_LOW_FREQ,
+ LOAD_PATTERN,
+ SET_MEDIUM_FREQ,
+ WRITE_LEVELING,
+ LOAD_PATTERN_2,
+ READ_LEVELING,
+ WRITE_LEVELING_SUPP,
+ PBS_RX,
+ PBS_TX,
+ SET_TARGET_FREQ,
+ ADJUST_DQS,
+ WRITE_LEVELING_TF,
+ READ_LEVELING_TF,
+ WRITE_LEVELING_SUPP_TF,
+ DM_PBS_TX,
+ VREF_CALIBRATION,
+ CENTRALIZATION_RX,
+ CENTRALIZATION_TX,
+ TX_EMPHASIS,
+ LOAD_PATTERN_HIGH,
+ PER_BIT_READ_LEVELING_TF,
+ MAX_STAGE_LIMIT
+};
+
+enum hws_access_type {
+ ACCESS_TYPE_UNICAST = 0,
+ ACCESS_TYPE_MULTICAST = 1
+};
+
+enum hws_algo_type {
+ ALGO_TYPE_DYNAMIC,
+ ALGO_TYPE_STATIC
+};
+
+struct init_cntr_param {
+ int is_ctrl64_bit;
+ int do_mrs_phy;
+ int init_phy;
+ int msys_init;
+};
+
+struct pattern_info {
+ u8 num_of_phases_tx;
+ u8 tx_burst_size;
+ u8 delay_between_bursts;
+ u8 num_of_phases_rx;
+ u32 start_addr;
+ u8 pattern_len;
+};
+
+/* CL value for each frequency */
+struct cl_val_per_freq {
+ u8 cl_val[DDR_FREQ_LIMIT];
+};
+
+struct cs_element {
+ u8 cs_num;
+ u8 num_of_cs;
+};
+
+struct mode_info {
+ /* 32 bits representing MRS bits */
+ u32 reg_mr0[MAX_INTERFACE_NUM];
+ u32 reg_mr1[MAX_INTERFACE_NUM];
+ u32 reg_mr2[MAX_INTERFACE_NUM];
+ u32 reg_m_r3[MAX_INTERFACE_NUM];
+ /*
+ * Each element in array represent read_data_sample register delay for
+ * a specific interface.
+ * Each register, 4 bits[0+CS*8 to 4+CS*8] represent Number of DDR
+ * cycles from read command until data is ready to be fetched from
+ * the PHY, when accessing CS.
+ */
+ u32 read_data_sample[MAX_INTERFACE_NUM];
+ /*
+ * Each element in array represent read_data_sample register delay for
+ * a specific interface.
+ * Each register, 4 bits[0+CS*8 to 4+CS*8] represent the total delay
+ * from read command until opening the read mask, when accessing CS.
+ * This field defines the delay in DDR cycles granularity.
+ */
+ u32 read_data_ready[MAX_INTERFACE_NUM];
+};
+
+struct hws_tip_freq_config_info {
+ u8 is_supported;
+ u8 bw_per_freq;
+ u8 rate_per_freq;
+};
+
+struct hws_cs_config_info {
+ u32 cs_reg_value;
+ u32 cs_cbe_value;
+};
+
+struct dfx_access {
+ u8 pipe;
+ u8 client;
+};
+
+struct hws_xsb_info {
+ struct dfx_access *dfx_table;
+};
+
+int ddr3_tip_register_dq_table(u32 dev_num, u32 *table);
+int hws_ddr3_tip_select_ddr_controller(u32 dev_num, int enable);
+int hws_ddr3_tip_init_controller(u32 dev_num,
+ struct init_cntr_param *init_cntr_prm);
+int hws_ddr3_tip_load_topology_map(u32 dev_num,
+ struct hws_topology_map *topology);
+int hws_ddr3_tip_run_alg(u32 dev_num, enum hws_algo_type algo_type);
+int hws_ddr3_tip_mode_read(u32 dev_num, struct mode_info *mode_info);
+int hws_ddr3_tip_read_training_result(u32 dev_num,
+ enum hws_result result[MAX_STAGE_LIMIT][MAX_INTERFACE_NUM]);
+int ddr3_tip_is_pup_lock(u32 *pup_buf, enum hws_training_result read_mode);
+u8 ddr3_tip_get_buf_min(u8 *buf_ptr);
+u8 ddr3_tip_get_buf_max(u8 *buf_ptr);
+
+#endif /* _DDR3_TRAINING_IP_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_BIST_H_
+#define _DDR3_TRAINING_IP_BIST_H_
+
+#include "ddr3_training_ip.h"
+
+enum hws_bist_operation {
+ BIST_STOP = 0,
+ BIST_START = 1
+};
+
+enum hws_stress_jump {
+ STRESS_NONE = 0,
+ STRESS_ENABLE = 1
+};
+
+enum hws_pattern_duration {
+ DURATION_SINGLE = 0,
+ DURATION_STOP_AT_FAIL = 1,
+ DURATION_ADDRESS = 2,
+ DURATION_CONT = 4
+};
+
+struct bist_result {
+ u32 bist_error_cnt;
+ u32 bist_fail_low;
+ u32 bist_fail_high;
+ u32 bist_last_fail_addr;
+};
+
+int ddr3_tip_bist_read_result(u32 dev_num, u32 if_id,
+ struct bist_result *pst_bist_result);
+int ddr3_tip_bist_activate(u32 dev_num, enum hws_pattern pattern,
+ enum hws_access_type access_type,
+ u32 if_num, enum hws_dir direction,
+ enum hws_stress_jump addr_stress_jump,
+ enum hws_pattern_duration duration,
+ enum hws_bist_operation oper_type,
+ u32 offset, u32 cs_num, u32 pattern_addr_length);
+int hws_ddr3_run_bist(u32 dev_num, enum hws_pattern pattern, u32 *result,
+ u32 cs_num);
+int ddr3_tip_run_sweep_test(int dev_num, u32 repeat_num, u32 direction,
+ u32 mode);
+int ddr3_tip_print_regs(u32 dev_num);
+int ddr3_tip_reg_dump(u32 dev_num);
+int run_xsb_test(u32 dev_num, u32 mem_addr, u32 write_type, u32 read_type,
+ u32 burst_length);
+
+#endif /* _DDR3_TRAINING_IP_BIST_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_CENTRALIZATION_H
+#define _DDR3_TRAINING_IP_CENTRALIZATION_H
+
+int ddr3_tip_centralization_tx(u32 dev_num);
+int ddr3_tip_centralization_rx(u32 dev_num);
+int ddr3_tip_print_centralization_result(u32 dev_num);
+int ddr3_tip_special_rx(u32 dev_num);
+
+#endif /* _DDR3_TRAINING_IP_CENTRALIZATION_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_DB_H_
+#define _DDR3_TRAINING_IP_DB_H_
+
+enum hws_pattern {
+ PATTERN_PBS1,
+ PATTERN_PBS2,
+ PATTERN_RL,
+ PATTERN_STATIC_PBS,
+ PATTERN_KILLER_DQ0,
+ PATTERN_KILLER_DQ1,
+ PATTERN_KILLER_DQ2,
+ PATTERN_KILLER_DQ3,
+ PATTERN_KILLER_DQ4,
+ PATTERN_KILLER_DQ5,
+ PATTERN_KILLER_DQ6,
+ PATTERN_KILLER_DQ7,
+ PATTERN_PBS3,
+ PATTERN_RL2,
+ PATTERN_TEST,
+ PATTERN_FULL_SSO0,
+ PATTERN_FULL_SSO1,
+ PATTERN_FULL_SSO2,
+ PATTERN_FULL_SSO3,
+ PATTERN_VREF,
+ PATTERN_LIMIT
+};
+
+#endif /* _DDR3_TRAINING_IP_DB_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_DEF_H
+#define _DDR3_TRAINING_IP_DEF_H
+
+#include "silicon_if.h"
+
+#define PATTERN_55 0x55555555
+#define PATTERN_AA 0xaaaaaaaa
+#define PATTERN_80 0x80808080
+#define PATTERN_20 0x20202020
+#define PATTERN_01 0x01010101
+#define PATTERN_FF 0xffffffff
+#define PATTERN_00 0x00000000
+
+/* 16bit bus width patterns */
+#define PATTERN_55AA 0x5555aaaa
+#define PATTERN_00FF 0x0000ffff
+#define PATTERN_0080 0x00008080
+
+#define INVALID_VALUE 0xffffffff
+#define MAX_NUM_OF_DUNITS 32
+/*
+ * length *2 = length in words of pattern, first low address,
+ * second high address
+ */
+#define TEST_PATTERN_LENGTH 4
+#define KILLER_PATTERN_DQ_NUMBER 8
+#define SSO_DQ_NUMBER 4
+#define PATTERN_MAXIMUM_LENGTH 64
+#define ADLL_TX_LENGTH 64
+#define ADLL_RX_LENGTH 32
+
+#define PARAM_NOT_CARE 0
+
+#define READ_LEVELING_PHY_OFFSET 2
+#define WRITE_LEVELING_PHY_OFFSET 0
+
+#define MASK_ALL_BITS 0xffffffff
+
+#define CS_BIT_MASK 0xf
+
+/* DFX access */
+#define BROADCAST_ID 28
+#define MULTICAST_ID 29
+
+#define XSB_BASE_ADDR 0x00004000
+#define XSB_CTRL_0_REG 0x00000000
+#define XSB_CTRL_1_REG 0x00000004
+#define XSB_CMD_REG 0x00000008
+#define XSB_ADDRESS_REG 0x0000000c
+#define XSB_DATA_REG 0x00000010
+#define PIPE_ENABLE_ADDR 0x000f8000
+#define ENABLE_DDR_TUNING_ADDR 0x000f829c
+
+#define CLIENT_BASE_ADDR 0x00002000
+#define CLIENT_CTRL_REG 0x00000000
+
+#define TARGET_INT 0x1801
+#define TARGET_EXT 0x180e
+#define BYTE_EN 0
+#define CMD_READ 0
+#define CMD_WRITE 1
+
+#define INTERNAL_ACCESS_PORT 1
+#define EXECUTING 1
+#define ACCESS_EXT 1
+#define CS2_EXIST_BIT 2
+#define TRAINING_ID 0xf
+#define EXT_TRAINING_ID 1
+#define EXT_MODE 0x4
+
+#define GET_RESULT_STATE(res) (res)
+#define SET_RESULT_STATE(res, state) (res = state)
+
+#define _1K 0x00000400
+#define _4K 0x00001000
+#define _8K 0x00002000
+#define _16K 0x00004000
+#define _32K 0x00008000
+#define _64K 0x00010000
+#define _128K 0x00020000
+#define _256K 0x00040000
+#define _512K 0x00080000
+
+#define _1M 0x00100000
+#define _2M 0x00200000
+#define _4M 0x00400000
+#define _8M 0x00800000
+#define _16M 0x01000000
+#define _32M 0x02000000
+#define _64M 0x04000000
+#define _128M 0x08000000
+#define _256M 0x10000000
+#define _512M 0x20000000
+
+#define _1G 0x40000000
+#define _2G 0x80000000
+
+#define ADDR_SIZE_512MB 0x04000000
+#define ADDR_SIZE_1GB 0x08000000
+#define ADDR_SIZE_2GB 0x10000000
+#define ADDR_SIZE_4GB 0x20000000
+#define ADDR_SIZE_8GB 0x40000000
+
+enum hws_edge_compare {
+ EDGE_PF,
+ EDGE_FP,
+ EDGE_FPF,
+ EDGE_PFP
+};
+
+enum hws_control_element {
+ HWS_CONTROL_ELEMENT_ADLL, /* per bit 1 edge */
+ HWS_CONTROL_ELEMENT_DQ_SKEW,
+ HWS_CONTROL_ELEMENT_DQS_SKEW
+};
+
+enum hws_search_dir {
+ HWS_LOW2HIGH,
+ HWS_HIGH2LOW,
+ HWS_SEARCH_DIR_LIMIT
+};
+
+enum hws_page_size {
+ PAGE_SIZE_1K,
+ PAGE_SIZE_2K
+};
+
+enum hws_operation {
+ OPERATION_READ = 0,
+ OPERATION_WRITE = 1
+};
+
+enum hws_training_ip_stat {
+ HWS_TRAINING_IP_STATUS_FAIL,
+ HWS_TRAINING_IP_STATUS_SUCCESS,
+ HWS_TRAINING_IP_STATUS_TIMEOUT
+};
+
+enum hws_ddr_cs {
+ CS_SINGLE,
+ CS_NON_SINGLE
+};
+
+enum hws_ddr_phy {
+ DDR_PHY_DATA = 0,
+ DDR_PHY_CONTROL = 1
+};
+
+enum hws_dir {
+ OPER_WRITE,
+ OPER_READ,
+ OPER_WRITE_AND_READ
+};
+
+enum hws_wl_supp {
+ PHASE_SHIFT,
+ CLOCK_SHIFT,
+ ALIGN_SHIFT
+};
+
+struct reg_data {
+ u32 reg_addr;
+ u32 reg_data;
+ u32 reg_mask;
+};
+
+#endif /* _DDR3_TRAINING_IP_DEF_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#define PATTERN_1 0x55555555
+#define PATTERN_2 0xaaaaaaaa
+
+#define VALIDATE_TRAINING_LIMIT(e1, e2) \
+ ((((e2) - (e1) + 1) > 33) && ((e1) < 67))
+
+u32 phy_reg_bk[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
+
+u32 training_res[MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS *
+ HWS_SEARCH_DIR_LIMIT];
+
+u16 mask_results_dq_reg_map[] = {
+ RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
+ RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
+ RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
+ RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
+ RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
+ RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
+ RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
+ RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
+ RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
+ RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
+ RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
+ RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
+ RESULT_CONTROL_PUP_3_BIT_0_REG, RESULT_CONTROL_PUP_3_BIT_1_REG,
+ RESULT_CONTROL_PUP_3_BIT_2_REG, RESULT_CONTROL_PUP_3_BIT_3_REG,
+ RESULT_CONTROL_PUP_3_BIT_4_REG, RESULT_CONTROL_PUP_3_BIT_5_REG,
+ RESULT_CONTROL_PUP_3_BIT_6_REG, RESULT_CONTROL_PUP_3_BIT_7_REG,
+ RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
+ RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
+ RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
+ RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
+};
+
+u16 mask_results_pup_reg_map[] = {
+ RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
+ RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_3_REG,
+ RESULT_CONTROL_BYTE_PUP_4_REG
+};
+
+u16 mask_results_dq_reg_map_pup3_ecc[] = {
+ RESULT_CONTROL_PUP_0_BIT_0_REG, RESULT_CONTROL_PUP_0_BIT_1_REG,
+ RESULT_CONTROL_PUP_0_BIT_2_REG, RESULT_CONTROL_PUP_0_BIT_3_REG,
+ RESULT_CONTROL_PUP_0_BIT_4_REG, RESULT_CONTROL_PUP_0_BIT_5_REG,
+ RESULT_CONTROL_PUP_0_BIT_6_REG, RESULT_CONTROL_PUP_0_BIT_7_REG,
+ RESULT_CONTROL_PUP_1_BIT_0_REG, RESULT_CONTROL_PUP_1_BIT_1_REG,
+ RESULT_CONTROL_PUP_1_BIT_2_REG, RESULT_CONTROL_PUP_1_BIT_3_REG,
+ RESULT_CONTROL_PUP_1_BIT_4_REG, RESULT_CONTROL_PUP_1_BIT_5_REG,
+ RESULT_CONTROL_PUP_1_BIT_6_REG, RESULT_CONTROL_PUP_1_BIT_7_REG,
+ RESULT_CONTROL_PUP_2_BIT_0_REG, RESULT_CONTROL_PUP_2_BIT_1_REG,
+ RESULT_CONTROL_PUP_2_BIT_2_REG, RESULT_CONTROL_PUP_2_BIT_3_REG,
+ RESULT_CONTROL_PUP_2_BIT_4_REG, RESULT_CONTROL_PUP_2_BIT_5_REG,
+ RESULT_CONTROL_PUP_2_BIT_6_REG, RESULT_CONTROL_PUP_2_BIT_7_REG,
+ RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
+ RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
+ RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
+ RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
+ RESULT_CONTROL_PUP_4_BIT_0_REG, RESULT_CONTROL_PUP_4_BIT_1_REG,
+ RESULT_CONTROL_PUP_4_BIT_2_REG, RESULT_CONTROL_PUP_4_BIT_3_REG,
+ RESULT_CONTROL_PUP_4_BIT_4_REG, RESULT_CONTROL_PUP_4_BIT_5_REG,
+ RESULT_CONTROL_PUP_4_BIT_6_REG, RESULT_CONTROL_PUP_4_BIT_7_REG,
+};
+
+u16 mask_results_pup_reg_map_pup3_ecc[] = {
+ RESULT_CONTROL_BYTE_PUP_0_REG, RESULT_CONTROL_BYTE_PUP_1_REG,
+ RESULT_CONTROL_BYTE_PUP_2_REG, RESULT_CONTROL_BYTE_PUP_4_REG,
+ RESULT_CONTROL_BYTE_PUP_4_REG
+};
+
+struct pattern_info pattern_table_16[] = {
+ /*
+ * num tx phases, tx burst, delay between, rx pattern,
+ * start_address, pattern_len
+ */
+ {1, 1, 2, 1, 0x0080, 2}, /* PATTERN_PBS1 */
+ {1, 1, 2, 1, 0x00c0, 2}, /* PATTERN_PBS2 */
+ {1, 1, 2, 1, 0x0100, 2}, /* PATTERN_RL */
+ {0xf, 0x7, 2, 0x7, 0x0140, 16}, /* PATTERN_STATIC_PBS */
+ {0xf, 0x7, 2, 0x7, 0x0190, 16}, /* PATTERN_KILLER_DQ0 */
+ {0xf, 0x7, 2, 0x7, 0x01d0, 16}, /* PATTERN_KILLER_DQ1 */
+ {0xf, 0x7, 2, 0x7, 0x0210, 16}, /* PATTERN_KILLER_DQ2 */
+ {0xf, 0x7, 2, 0x7, 0x0250, 16}, /* PATTERN_KILLER_DQ3 */
+ {0xf, 0x7, 2, 0x7, 0x0290, 16}, /* PATTERN_KILLER_DQ4 */
+ {0xf, 0x7, 2, 0x7, 0x02d0, 16}, /* PATTERN_KILLER_DQ5 */
+ {0xf, 0x7, 2, 0x7, 0x0310, 16}, /* PATTERN_KILLER_DQ6 */
+ {0xf, 0x7, 2, 0x7, 0x0350, 16}, /* PATTERN_KILLER_DQ7 */
+ {1, 1, 2, 1, 0x0380, 2}, /* PATTERN_PBS3 */
+ {1, 1, 2, 1, 0x0000, 2}, /* PATTERN_RL2 */
+ {1, 1, 2, 1, 0x0040, 2}, /* PATTERN_TEST */
+ {0xf, 0x7, 2, 0x7, 0x03c0, 16}, /* PATTERN_FULL_SSO_1T */
+ {0xf, 0x7, 2, 0x7, 0x0400, 16}, /* PATTERN_FULL_SSO_2T */
+ {0xf, 0x7, 2, 0x7, 0x0440, 16}, /* PATTERN_FULL_SSO_3T */
+ {0xf, 0x7, 2, 0x7, 0x0480, 16}, /* PATTERN_FULL_SSO_4T */
+ {0xf, 0x7, 2, 0x7, 0x04c0, 16} /* PATTERN_VREF */
+ /*Note: actual start_address is <<3 of defined addess */
+};
+
+struct pattern_info pattern_table_32[] = {
+ /*
+ * num tx phases, tx burst, delay between, rx pattern,
+ * start_address, pattern_len
+ */
+ {3, 3, 2, 3, 0x0080, 4}, /* PATTERN_PBS1 */
+ {3, 3, 2, 3, 0x00c0, 4}, /* PATTERN_PBS2 */
+ {3, 3, 2, 3, 0x0100, 4}, /* PATTERN_RL */
+ {0x1f, 0xf, 2, 0xf, 0x0140, 32}, /* PATTERN_STATIC_PBS */
+ {0x1f, 0xf, 2, 0xf, 0x0190, 32}, /* PATTERN_KILLER_DQ0 */
+ {0x1f, 0xf, 2, 0xf, 0x01d0, 32}, /* PATTERN_KILLER_DQ1 */
+ {0x1f, 0xf, 2, 0xf, 0x0210, 32}, /* PATTERN_KILLER_DQ2 */
+ {0x1f, 0xf, 2, 0xf, 0x0250, 32}, /* PATTERN_KILLER_DQ3 */
+ {0x1f, 0xf, 2, 0xf, 0x0290, 32}, /* PATTERN_KILLER_DQ4 */
+ {0x1f, 0xf, 2, 0xf, 0x02d0, 32}, /* PATTERN_KILLER_DQ5 */
+ {0x1f, 0xf, 2, 0xf, 0x0310, 32}, /* PATTERN_KILLER_DQ6 */
+ {0x1f, 0xf, 2, 0xf, 0x0350, 32}, /* PATTERN_KILLER_DQ7 */
+ {3, 3, 2, 3, 0x0380, 4}, /* PATTERN_PBS3 */
+ {3, 3, 2, 3, 0x0000, 4}, /* PATTERN_RL2 */
+ {3, 3, 2, 3, 0x0040, 4}, /* PATTERN_TEST */
+ {0x1f, 0xf, 2, 0xf, 0x03c0, 32}, /* PATTERN_FULL_SSO_1T */
+ {0x1f, 0xf, 2, 0xf, 0x0400, 32}, /* PATTERN_FULL_SSO_2T */
+ {0x1f, 0xf, 2, 0xf, 0x0440, 32}, /* PATTERN_FULL_SSO_3T */
+ {0x1f, 0xf, 2, 0xf, 0x0480, 32}, /* PATTERN_FULL_SSO_4T */
+ {0x1f, 0xf, 2, 0xf, 0x04c0, 32} /* PATTERN_VREF */
+ /*Note: actual start_address is <<3 of defined addess */
+};
+
+u32 train_dev_num;
+enum hws_ddr_cs traintrain_cs_type;
+u32 train_pup_num;
+enum hws_training_result train_result_type;
+enum hws_control_element train_control_element;
+enum hws_search_dir traine_search_dir;
+enum hws_dir train_direction;
+u32 train_if_select;
+u32 train_init_value;
+u32 train_number_iterations;
+enum hws_pattern train_pattern;
+enum hws_edge_compare train_edge_compare;
+u32 train_cs_num;
+u32 train_if_acess, train_if_id, train_pup_access;
+u32 max_polling_for_done = 1000000;
+
+u32 *ddr3_tip_get_buf_ptr(u32 dev_num, enum hws_search_dir search,
+ enum hws_training_result result_type,
+ u32 interface_num)
+{
+ u32 *buf_ptr = NULL;
+
+ buf_ptr = &training_res
+ [MAX_INTERFACE_NUM * MAX_BUS_NUM * BUS_WIDTH_IN_BITS * search +
+ interface_num * MAX_BUS_NUM * BUS_WIDTH_IN_BITS];
+
+ return buf_ptr;
+}
+
+/*
+ * IP Training search
+ * Note: for one edge search only from fail to pass, else jitter can
+ * be be entered into solution.
+ */
+int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
+ u32 interface_num,
+ enum hws_access_type pup_access_type,
+ u32 pup_num, enum hws_training_result result_type,
+ enum hws_control_element control_element,
+ enum hws_search_dir search_dir, enum hws_dir direction,
+ u32 interface_mask, u32 init_value, u32 num_iter,
+ enum hws_pattern pattern,
+ enum hws_edge_compare edge_comp,
+ enum hws_ddr_cs cs_type, u32 cs_num,
+ enum hws_training_ip_stat *train_status)
+{
+ u32 mask_dq_num_of_regs, mask_pup_num_of_regs, index_cnt, poll_cnt,
+ reg_data, pup_id;
+ u32 tx_burst_size;
+ u32 delay_between_burst;
+ u32 rd_mode;
+ u32 read_data[MAX_INTERFACE_NUM];
+ struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+ u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
+ u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (pup_num >= tm->num_of_bus_per_interface) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("pup_num %d not valid\n", pup_num));
+ }
+ if (interface_num >= MAX_INTERFACE_NUM) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("if_id %d not valid\n",
+ interface_num));
+ }
+ if (train_status == NULL) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("error param 4\n"));
+ return MV_BAD_PARAM;
+ }
+
+ /* load pattern */
+ if (cs_type == CS_SINGLE) {
+ /* All CSs to CS0 */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ CS_ENABLE_REG, 1 << 3, 1 << 3));
+ /* All CSs to CS0 */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ ODPG_DATA_CONTROL_REG,
+ (0x3 | (effective_cs << 26)), 0xc000003));
+ } else {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ CS_ENABLE_REG, 0, 1 << 3));
+ /* CS select */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ ODPG_DATA_CONTROL_REG, 0x3 | cs_num << 26,
+ 0x3 | 3 << 26));
+ }
+
+ /* load pattern to ODPG */
+ ddr3_tip_load_pattern_to_odpg(dev_num, access_type, interface_num,
+ pattern,
+ pattern_table[pattern].start_addr);
+ tx_burst_size = (direction == OPER_WRITE) ?
+ pattern_table[pattern].tx_burst_size : 0;
+ delay_between_burst = (direction == OPER_WRITE) ? 2 : 0;
+ rd_mode = (direction == OPER_WRITE) ? 1 : 0;
+ CHECK_STATUS(ddr3_tip_configure_odpg
+ (dev_num, access_type, interface_num, direction,
+ pattern_table[pattern].num_of_phases_tx, tx_burst_size,
+ pattern_table[pattern].num_of_phases_rx,
+ delay_between_burst, rd_mode, effective_cs, STRESS_NONE,
+ DURATION_SINGLE));
+ reg_data = (direction == OPER_READ) ? 0 : (0x3 << 30);
+ reg_data |= (direction == OPER_READ) ? 0x60 : 0xfa;
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ ODPG_WRITE_READ_MODE_ENABLE_REG, reg_data,
+ MASK_ALL_BITS));
+ reg_data = (edge_comp == EDGE_PF || edge_comp == EDGE_FP) ? 0 : 1 << 6;
+ reg_data |= (edge_comp == EDGE_PF || edge_comp == EDGE_PFP) ?
+ (1 << 7) : 0;
+
+ /* change from Pass to Fail will lock the result */
+ if (pup_access_type == ACCESS_TYPE_MULTICAST)
+ reg_data |= 0xe << 14;
+ else
+ reg_data |= pup_num << 14;
+
+ if (edge_comp == EDGE_FP) {
+ /* don't search for readl edge change, only the state */
+ reg_data |= (0 << 20);
+ } else if (edge_comp == EDGE_FPF) {
+ reg_data |= (0 << 20);
+ } else {
+ reg_data |= (3 << 20);
+ }
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ ODPG_TRAINING_CONTROL_REG,
+ reg_data | (0x7 << 8) | (0x7 << 11),
+ (0x3 | (0x3 << 2) | (0x3 << 6) | (1 << 5) | (0x7 << 8) |
+ (0x7 << 11) | (0xf << 14) | (0x3 << 18) | (3 << 20))));
+ reg_data = (search_dir == HWS_LOW2HIGH) ? 0 : (1 << 8);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num, ODPG_OBJ1_OPCODE_REG,
+ 1 | reg_data | init_value << 9 | (1 << 25) | (1 << 26),
+ 0xff | (1 << 8) | (0xffff << 9) | (1 << 25) | (1 << 26)));
+
+ /*
+ * Write2_dunit(0x10b4, Number_iteration , [15:0])
+ * Max number of iterations
+ */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
+ ODPG_OBJ1_ITER_CNT_REG, num_iter,
+ 0xffff));
+ if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
+ direction == OPER_READ) {
+ /*
+ * Write2_dunit(0x10c0, 0x5f , [7:0])
+ * MC PBS Reg Address at DDR PHY
+ */
+ reg_data = 0x5f +
+ effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
+ } else if (control_element == HWS_CONTROL_ELEMENT_DQ_SKEW &&
+ direction == OPER_WRITE) {
+ reg_data = 0x1f +
+ effective_cs * CALIBRATED_OBJECTS_REG_ADDR_OFFSET;
+ } else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
+ direction == OPER_WRITE) {
+ /*
+ * LOOP 0x00000001 + 4*n:
+ * where n (0-3) represents M_CS number
+ */
+ /*
+ * Write2_dunit(0x10c0, 0x1 , [7:0])
+ * ADLL WR Reg Address at DDR PHY
+ */
+ reg_data = 1 + effective_cs * CS_REGISTER_ADDR_OFFSET;
+ } else if (control_element == HWS_CONTROL_ELEMENT_ADLL &&
+ direction == OPER_READ) {
+ /* ADLL RD Reg Address at DDR PHY */
+ reg_data = 3 + effective_cs * CS_REGISTER_ADDR_OFFSET;
+ } else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
+ direction == OPER_WRITE) {
+ /* TBD not defined in 0.5.0 requirement */
+ } else if (control_element == HWS_CONTROL_ELEMENT_DQS_SKEW &&
+ direction == OPER_READ) {
+ /* TBD not defined in 0.5.0 requirement */
+ }
+
+ reg_data |= (0x6 << 28);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num, CALIB_OBJ_PRFA_REG,
+ reg_data | (init_value << 8),
+ 0xff | (0xffff << 8) | (0xf << 24) | (u32) (0xf << 28)));
+
+ mask_dq_num_of_regs = tm->num_of_bus_per_interface * BUS_WIDTH_IN_BITS;
+ mask_pup_num_of_regs = tm->num_of_bus_per_interface;
+
+ if (result_type == RESULT_PER_BIT) {
+ for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
+ index_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ mask_results_dq_reg_map[index_cnt], 0,
+ 1 << 24));
+ }
+
+ /* Mask disabled buses */
+ for (pup_id = 0; pup_id < tm->num_of_bus_per_interface;
+ pup_id++) {
+ if (IS_ACTIVE(tm->bus_act_mask, pup_id) == 1)
+ continue;
+
+ for (index_cnt = (mask_dq_num_of_regs - pup_id * 8);
+ index_cnt <
+ (mask_dq_num_of_regs - (pup_id + 1) * 8);
+ index_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type,
+ interface_num,
+ mask_results_dq_reg_map
+ [index_cnt], (1 << 24), 1 << 24));
+ }
+ }
+
+ for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
+ index_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ mask_results_pup_reg_map[index_cnt],
+ (1 << 24), 1 << 24));
+ }
+ } else if (result_type == RESULT_PER_BYTE) {
+ /* write to adll */
+ for (index_cnt = 0; index_cnt < mask_pup_num_of_regs;
+ index_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ mask_results_pup_reg_map[index_cnt], 0,
+ 1 << 24));
+ }
+ for (index_cnt = 0; index_cnt < mask_dq_num_of_regs;
+ index_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, interface_num,
+ mask_results_dq_reg_map[index_cnt],
+ (1 << 24), (1 << 24)));
+ }
+ }
+
+ /* Start Training Trigger */
+ CHECK_STATUS(ddr3_tip_if_write(dev_num, access_type, interface_num,
+ ODPG_TRAINING_TRIGGER_REG, 1, 1));
+ /* wait for all RFU tests to finish (or timeout) */
+ /* WA for 16 bit mode, more investigation needed */
+ mdelay(1);
+
+ /* Training "Done ?" */
+ for (index_cnt = 0; index_cnt < MAX_INTERFACE_NUM; index_cnt++) {
+ if (IS_ACTIVE(tm->if_act_mask, index_cnt) == 0)
+ continue;
+
+ if (interface_mask & (1 << index_cnt)) {
+ /* need to check results for this Dunit */
+ for (poll_cnt = 0; poll_cnt < max_polling_for_done;
+ poll_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST,
+ index_cnt,
+ ODPG_TRAINING_STATUS_REG,
+ ®_data, MASK_ALL_BITS));
+ if ((reg_data & 0x2) != 0) {
+ /*done */
+ train_status[index_cnt] =
+ HWS_TRAINING_IP_STATUS_SUCCESS;
+ break;
+ }
+ }
+
+ if (poll_cnt == max_polling_for_done) {
+ train_status[index_cnt] =
+ HWS_TRAINING_IP_STATUS_TIMEOUT;
+ }
+ }
+ /* Be sure that ODPG done */
+ CHECK_STATUS(is_odpg_access_done(dev_num, index_cnt));
+ }
+
+ /* Write ODPG done in Dunit */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_STATUS_DONE_REG, 0, 0x1));
+
+ /* wait for all Dunit tests to finish (or timeout) */
+ /* Training "Done ?" */
+ /* Training "Pass ?" */
+ for (index_cnt = 0; index_cnt < MAX_INTERFACE_NUM; index_cnt++) {
+ if (IS_ACTIVE(tm->if_act_mask, index_cnt) == 0)
+ continue;
+
+ if (interface_mask & (1 << index_cnt)) {
+ /* need to check results for this Dunit */
+ for (poll_cnt = 0; poll_cnt < max_polling_for_done;
+ poll_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST,
+ index_cnt,
+ ODPG_TRAINING_TRIGGER_REG,
+ read_data, MASK_ALL_BITS));
+ reg_data = read_data[index_cnt];
+ if ((reg_data & 0x2) != 0) {
+ /* done */
+ if ((reg_data & 0x4) == 0) {
+ train_status[index_cnt] =
+ HWS_TRAINING_IP_STATUS_SUCCESS;
+ } else {
+ train_status[index_cnt] =
+ HWS_TRAINING_IP_STATUS_FAIL;
+ }
+ break;
+ }
+ }
+
+ if (poll_cnt == max_polling_for_done) {
+ train_status[index_cnt] =
+ HWS_TRAINING_IP_STATUS_TIMEOUT;
+ }
+ }
+ }
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
+
+ return MV_OK;
+}
+
+/*
+ * Load expected Pattern to ODPG
+ */
+int ddr3_tip_load_pattern_to_odpg(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_pattern pattern,
+ u32 load_addr)
+{
+ u32 pattern_length_cnt = 0;
+ struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+
+ for (pattern_length_cnt = 0;
+ pattern_length_cnt < pattern_table[pattern].pattern_len;
+ pattern_length_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ ODPG_PATTERN_DATA_LOW_REG,
+ pattern_table_get_word(dev_num, pattern,
+ (u8) (pattern_length_cnt *
+ 2)), MASK_ALL_BITS));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ ODPG_PATTERN_DATA_HI_REG,
+ pattern_table_get_word(dev_num, pattern,
+ (u8) (pattern_length_cnt *
+ 2 + 1)),
+ MASK_ALL_BITS));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ ODPG_PATTERN_ADDR_REG, pattern_length_cnt,
+ MASK_ALL_BITS));
+ }
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, access_type, if_id,
+ ODPG_PATTERN_ADDR_OFFSET_REG, load_addr, MASK_ALL_BITS));
+
+ return MV_OK;
+}
+
+/*
+ * Configure ODPG
+ */
+int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_dir direction, u32 tx_phases,
+ u32 tx_burst_size, u32 rx_phases,
+ u32 delay_between_burst, u32 rd_mode, u32 cs_num,
+ u32 addr_stress_jump, u32 single_pattern)
+{
+ u32 data_value = 0;
+ int ret;
+
+ data_value = ((single_pattern << 2) | (tx_phases << 5) |
+ (tx_burst_size << 11) | (delay_between_burst << 15) |
+ (rx_phases << 21) | (rd_mode << 25) | (cs_num << 26) |
+ (addr_stress_jump << 29));
+ ret = ddr3_tip_if_write(dev_num, access_type, if_id,
+ ODPG_DATA_CONTROL_REG, data_value, 0xaffffffc);
+ if (ret != MV_OK)
+ return ret;
+
+ return MV_OK;
+}
+
+int ddr3_tip_process_result(u32 *ar_result, enum hws_edge e_edge,
+ enum hws_edge_search e_edge_search,
+ u32 *edge_result)
+{
+ u32 i, res;
+ int tap_val, max_val = -10000, min_val = 10000;
+ int lock_success = 1;
+
+ for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
+ res = GET_LOCK_RESULT(ar_result[i]);
+ if (res == 0) {
+ lock_success = 0;
+ break;
+ }
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("lock failed for bit %d\n", i));
+ }
+
+ if (lock_success == 1) {
+ for (i = 0; i < BUS_WIDTH_IN_BITS; i++) {
+ tap_val = GET_TAP_RESULT(ar_result[i], e_edge);
+ if (tap_val > max_val)
+ max_val = tap_val;
+ if (tap_val < min_val)
+ min_val = tap_val;
+ if (e_edge_search == TRAINING_EDGE_MAX)
+ *edge_result = (u32) max_val;
+ else
+ *edge_result = (u32) min_val;
+
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("i %d ar_result[i] 0x%x tap_val %d max_val %d min_val %d Edge_result %d\n",
+ i, ar_result[i], tap_val,
+ max_val, min_val,
+ *edge_result));
+ }
+ } else {
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Read training search result
+ */
+int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
+ enum hws_access_type pup_access_type,
+ u32 pup_num, u32 bit_num,
+ enum hws_search_dir search,
+ enum hws_dir direction,
+ enum hws_training_result result_type,
+ enum hws_training_load_op operation,
+ u32 cs_num_type, u32 **load_res,
+ int is_read_from_db, u8 cons_tap,
+ int is_check_result_validity)
+{
+ u32 reg_offset, pup_cnt, start_pup, end_pup, start_reg, end_reg;
+ u32 *interface_train_res = NULL;
+ u16 *reg_addr = NULL;
+ u32 read_data[MAX_INTERFACE_NUM];
+ u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
+ u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /*
+ * Agreed assumption: all CS mask contain same number of bits,
+ * i.e. in multi CS, the number of CS per memory is the same for
+ * all pups
+ */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, CS_ENABLE_REG,
+ (cs_num_type == 0) ? 1 << 3 : 0, (1 << 3)));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ODPG_DATA_CONTROL_REG, (cs_num_type << 26), (3 << 26)));
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
+ ("Read_from_d_b %d cs_type %d oper %d result_type %d direction %d search %d pup_num %d if_id %d pup_access_type %d\n",
+ is_read_from_db, cs_num_type, operation,
+ result_type, direction, search, pup_num,
+ if_id, pup_access_type));
+
+ if ((load_res == NULL) && (is_read_from_db == 1)) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("ddr3_tip_read_training_result load_res = NULL"));
+ return MV_FAIL;
+ }
+ if (pup_num >= tm->num_of_bus_per_interface) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("pup_num %d not valid\n", pup_num));
+ }
+ if (if_id >= MAX_INTERFACE_NUM) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("if_id %d not valid\n", if_id));
+ }
+ if (result_type == RESULT_PER_BIT)
+ reg_addr = mask_results_dq_reg_map;
+ else
+ reg_addr = mask_results_pup_reg_map;
+ if (pup_access_type == ACCESS_TYPE_UNICAST) {
+ start_pup = pup_num;
+ end_pup = pup_num;
+ } else { /*pup_access_type == ACCESS_TYPE_MULTICAST) */
+
+ start_pup = 0;
+ end_pup = tm->num_of_bus_per_interface - 1;
+ }
+
+ for (pup_cnt = start_pup; pup_cnt <= end_pup; pup_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup_cnt);
+ DEBUG_TRAINING_IP_ENGINE(
+ DEBUG_LEVEL_TRACE,
+ ("if_id %d start_pup %d end_pup %d pup_cnt %d\n",
+ if_id, start_pup, end_pup, pup_cnt));
+ if (result_type == RESULT_PER_BIT) {
+ if (bit_num == ALL_BITS_PER_PUP) {
+ start_reg = pup_cnt * BUS_WIDTH_IN_BITS;
+ end_reg = (pup_cnt + 1) * BUS_WIDTH_IN_BITS - 1;
+ } else {
+ start_reg =
+ pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
+ end_reg = pup_cnt * BUS_WIDTH_IN_BITS + bit_num;
+ }
+ } else {
+ start_reg = pup_cnt;
+ end_reg = pup_cnt;
+ }
+
+ interface_train_res =
+ ddr3_tip_get_buf_ptr(dev_num, search, result_type,
+ if_id);
+ DEBUG_TRAINING_IP_ENGINE(
+ DEBUG_LEVEL_TRACE,
+ ("start_reg %d end_reg %d interface %p\n",
+ start_reg, end_reg, interface_train_res));
+ if (interface_train_res == NULL) {
+ DEBUG_TRAINING_IP_ENGINE(
+ DEBUG_LEVEL_ERROR,
+ ("interface_train_res is NULL\n"));
+ return MV_FAIL;
+ }
+
+ for (reg_offset = start_reg; reg_offset <= end_reg;
+ reg_offset++) {
+ if (operation == TRAINING_LOAD_OPERATION_UNLOAD) {
+ if (is_read_from_db == 0) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ reg_addr[reg_offset],
+ read_data,
+ MASK_ALL_BITS));
+ if (is_check_result_validity == 1) {
+ if ((read_data[if_id] &
+ 0x02000000) == 0) {
+ interface_train_res
+ [reg_offset] =
+ 0x02000000 +
+ 64 + cons_tap;
+ } else {
+ interface_train_res
+ [reg_offset] =
+ read_data
+ [if_id] +
+ cons_tap;
+ }
+ } else {
+ interface_train_res[reg_offset]
+ = read_data[if_id] +
+ cons_tap;
+ }
+ DEBUG_TRAINING_IP_ENGINE
+ (DEBUG_LEVEL_TRACE,
+ ("reg_offset %d value 0x%x addr %p\n",
+ reg_offset,
+ interface_train_res
+ [reg_offset],
+ &interface_train_res
+ [reg_offset]));
+ } else {
+ *load_res =
+ &interface_train_res[start_reg];
+ DEBUG_TRAINING_IP_ENGINE
+ (DEBUG_LEVEL_TRACE,
+ ("*load_res %p\n", *load_res));
+ }
+ } else {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_TRACE,
+ ("not supported\n"));
+ }
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Load all pattern to memory using ODPG
+ */
+int ddr3_tip_load_all_pattern_to_mem(u32 dev_num)
+{
+ u32 pattern = 0, if_id;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ training_result[training_stage][if_id] = TEST_SUCCESS;
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* enable single cs */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, (1 << 3), (1 << 3)));
+ }
+
+ for (pattern = 0; pattern < PATTERN_LIMIT; pattern++)
+ ddr3_tip_load_pattern_to_mem(dev_num, pattern);
+
+ return MV_OK;
+}
+
+/*
+ * Wait till ODPG access is ready
+ */
+int is_odpg_access_done(u32 dev_num, u32 if_id)
+{
+ u32 poll_cnt = 0, data_value;
+ u32 read_data[MAX_INTERFACE_NUM];
+
+ for (poll_cnt = 0; poll_cnt < MAX_POLLING_ITERATIONS; poll_cnt++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ODPG_BIST_DONE, read_data, MASK_ALL_BITS));
+ data_value = read_data[if_id];
+ if (((data_value >> ODPG_BIST_DONE_BIT_OFFS) & 0x1) ==
+ ODPG_BIST_DONE_BIT_VALUE) {
+ data_value = data_value & 0xfffffffe;
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ODPG_BIST_DONE, data_value,
+ MASK_ALL_BITS));
+ break;
+ }
+ }
+
+ if (poll_cnt >= MAX_POLLING_ITERATIONS) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("Bist Activate: poll failure 2\n"));
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Load specific pattern to memory using ODPG
+ */
+int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern)
+{
+ u32 reg_data, if_id;
+ struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* load pattern to memory */
+ /*
+ * Write Tx mode, CS0, phases, Tx burst size, delay between burst,
+ * rx pattern phases
+ */
+ reg_data =
+ 0x1 | (pattern_table[pattern].num_of_phases_tx << 5) |
+ (pattern_table[pattern].tx_burst_size << 11) |
+ (pattern_table[pattern].delay_between_bursts << 15) |
+ (pattern_table[pattern].num_of_phases_rx << 21) | (0x1 << 25) |
+ (effective_cs << 26);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, reg_data, MASK_ALL_BITS));
+ /* ODPG Write enable from BIST */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, (0x1 | (effective_cs << 26)),
+ 0xc000003));
+ /* disable error injection */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_WRITE_DATA_ERROR_REG, 0, 0x1));
+ /* load pattern to ODPG */
+ ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, pattern,
+ pattern_table[pattern].start_addr);
+
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ if (IS_ACTIVE(tm->if_act_mask, if_id) == 0)
+ continue;
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0x1498,
+ 0x3, 0xf));
+ }
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_ENABLE_REG, 0x1 << ODPG_ENABLE_OFFS,
+ (0x1 << ODPG_ENABLE_OFFS)));
+
+ mdelay(1);
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(is_odpg_access_done(dev_num, if_id));
+ }
+
+ /* Disable ODPG and stop write to memory */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, (0x1 << 30), (u32) (0x3 << 30)));
+
+ /* return to default */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
+
+ /* Disable odt0 for CS0 training - need to adjust for multy CS */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498,
+ 0x0, 0xf));
+
+ /* temporary added */
+ mdelay(1);
+
+ return MV_OK;
+}
+
+/*
+ * Load specific pattern to memory using CPU
+ */
+int ddr3_tip_load_pattern_to_mem_by_cpu(u32 dev_num, enum hws_pattern pattern,
+ u32 offset)
+{
+ /* eranba - TBD */
+ return MV_OK;
+}
+
+/*
+ * Training search routine
+ */
+int ddr3_tip_ip_training_wrapper_int(u32 dev_num,
+ enum hws_access_type access_type,
+ u32 if_id,
+ enum hws_access_type pup_access_type,
+ u32 pup_num, u32 bit_num,
+ enum hws_training_result result_type,
+ enum hws_control_element control_element,
+ enum hws_search_dir search_dir,
+ enum hws_dir direction,
+ u32 interface_mask, u32 init_value_l2h,
+ u32 init_value_h2l, u32 num_iter,
+ enum hws_pattern pattern,
+ enum hws_edge_compare edge_comp,
+ enum hws_ddr_cs train_cs_type, u32 cs_num,
+ enum hws_training_ip_stat *train_status)
+{
+ u32 interface_num = 0, start_if, end_if, init_value_used;
+ enum hws_search_dir search_dir_id, start_search, end_search;
+ enum hws_edge_compare edge_comp_used;
+ u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (train_status == NULL) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("train_status is NULL\n"));
+ return MV_FAIL;
+ }
+
+ if ((train_cs_type > CS_NON_SINGLE) ||
+ (edge_comp >= EDGE_PFP) ||
+ (pattern >= PATTERN_LIMIT) ||
+ (direction > OPER_WRITE_AND_READ) ||
+ (search_dir > HWS_HIGH2LOW) ||
+ (control_element > HWS_CONTROL_ELEMENT_DQS_SKEW) ||
+ (result_type > RESULT_PER_BYTE) ||
+ (pup_num >= tm->num_of_bus_per_interface) ||
+ (pup_access_type > ACCESS_TYPE_MULTICAST) ||
+ (if_id > 11) || (access_type > ACCESS_TYPE_MULTICAST)) {
+ DEBUG_TRAINING_IP_ENGINE(
+ DEBUG_LEVEL_ERROR,
+ ("wrong parameter train_cs_type %d edge_comp %d pattern %d direction %d search_dir %d control_element %d result_type %d pup_num %d pup_access_type %d if_id %d access_type %d\n",
+ train_cs_type, edge_comp, pattern, direction,
+ search_dir, control_element, result_type, pup_num,
+ pup_access_type, if_id, access_type));
+ return MV_FAIL;
+ }
+
+ if (edge_comp == EDGE_FPF) {
+ start_search = HWS_LOW2HIGH;
+ end_search = HWS_HIGH2LOW;
+ edge_comp_used = EDGE_FP;
+ } else {
+ start_search = search_dir;
+ end_search = search_dir;
+ edge_comp_used = edge_comp;
+ }
+
+ for (search_dir_id = start_search; search_dir_id <= end_search;
+ search_dir_id++) {
+ init_value_used = (search_dir_id == HWS_LOW2HIGH) ?
+ init_value_l2h : init_value_h2l;
+ DEBUG_TRAINING_IP_ENGINE(
+ DEBUG_LEVEL_TRACE,
+ ("dev_num %d, access_type %d, if_id %d, pup_access_type %d,pup_num %d, result_type %d, control_element %d search_dir_id %d, direction %d, interface_mask %d,init_value_used %d, num_iter %d, pattern %d, edge_comp_used %d, train_cs_type %d, cs_num %d\n",
+ dev_num, access_type, if_id, pup_access_type, pup_num,
+ result_type, control_element, search_dir_id,
+ direction, interface_mask, init_value_used, num_iter,
+ pattern, edge_comp_used, train_cs_type, cs_num));
+
+ ddr3_tip_ip_training(dev_num, access_type, if_id,
+ pup_access_type, pup_num, result_type,
+ control_element, search_dir_id, direction,
+ interface_mask, init_value_used, num_iter,
+ pattern, edge_comp_used, train_cs_type,
+ cs_num, train_status);
+ if (access_type == ACCESS_TYPE_MULTICAST) {
+ start_if = 0;
+ end_if = MAX_INTERFACE_NUM - 1;
+ } else {
+ start_if = if_id;
+ end_if = if_id;
+ }
+
+ for (interface_num = start_if; interface_num <= end_if;
+ interface_num++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, interface_num);
+ cs_num = 0;
+ CHECK_STATUS(ddr3_tip_read_training_result
+ (dev_num, interface_num, pup_access_type,
+ pup_num, bit_num, search_dir_id,
+ direction, result_type,
+ TRAINING_LOAD_OPERATION_UNLOAD,
+ train_cs_type, NULL, 0, cons_tap,
+ 0));
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Training search & read result routine
+ */
+int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id,
+ enum hws_access_type pup_access_type,
+ u32 pup_num,
+ enum hws_training_result result_type,
+ enum hws_control_element control_element,
+ enum hws_search_dir search_dir,
+ enum hws_dir direction, u32 interface_mask,
+ u32 init_value_l2h, u32 init_value_h2l,
+ u32 num_iter, enum hws_pattern pattern,
+ enum hws_edge_compare edge_comp,
+ enum hws_ddr_cs train_cs_type, u32 cs_num,
+ enum hws_training_ip_stat *train_status)
+{
+ u8 e1, e2;
+ u32 interface_cnt, bit_id, start_if, end_if, bit_end = 0;
+ u32 *result[HWS_SEARCH_DIR_LIMIT] = { 0 };
+ u8 cons_tap = (direction == OPER_WRITE) ? (64) : (0);
+ u8 bit_bit_mask[MAX_BUS_NUM] = { 0 }, bit_bit_mask_active = 0;
+ u8 pup_id;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (pup_num >= tm->num_of_bus_per_interface) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("pup_num %d not valid\n", pup_num));
+ }
+
+ if (if_id >= MAX_INTERFACE_NUM) {
+ DEBUG_TRAINING_IP_ENGINE(DEBUG_LEVEL_ERROR,
+ ("if_id %d not valid\n", if_id));
+ }
+
+ CHECK_STATUS(ddr3_tip_ip_training_wrapper_int
+ (dev_num, access_type, if_id, pup_access_type, pup_num,
+ ALL_BITS_PER_PUP, result_type, control_element,
+ search_dir, direction, interface_mask, init_value_l2h,
+ init_value_h2l, num_iter, pattern, edge_comp,
+ train_cs_type, cs_num, train_status));
+
+ if (access_type == ACCESS_TYPE_MULTICAST) {
+ start_if = 0;
+ end_if = MAX_INTERFACE_NUM - 1;
+ } else {
+ start_if = if_id;
+ end_if = if_id;
+ }
+
+ for (interface_cnt = start_if; interface_cnt <= end_if;
+ interface_cnt++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, interface_cnt);
+ for (pup_id = 0;
+ pup_id <= (tm->num_of_bus_per_interface - 1); pup_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
+ if (result_type == RESULT_PER_BIT)
+ bit_end = BUS_WIDTH_IN_BITS - 1;
+ else
+ bit_end = 0;
+
+ bit_bit_mask[pup_id] = 0;
+ for (bit_id = 0; bit_id <= bit_end; bit_id++) {
+ enum hws_search_dir search_dir_id;
+ for (search_dir_id = HWS_LOW2HIGH;
+ search_dir_id <= HWS_HIGH2LOW;
+ search_dir_id++) {
+ CHECK_STATUS
+ (ddr3_tip_read_training_result
+ (dev_num, interface_cnt,
+ ACCESS_TYPE_UNICAST, pup_id,
+ bit_id, search_dir_id,
+ direction, result_type,
+ TRAINING_LOAD_OPERATION_UNLOAD,
+ CS_SINGLE,
+ &result[search_dir_id],
+ 1, 0, 0));
+ }
+ e1 = GET_TAP_RESULT(result[HWS_LOW2HIGH][0],
+ EDGE_1);
+ e2 = GET_TAP_RESULT(result[HWS_HIGH2LOW][0],
+ EDGE_1);
+ DEBUG_TRAINING_IP_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("wrapper if_id %d pup_id %d bit %d l2h 0x%x (e1 0x%x) h2l 0x%x (e2 0x%x)\n",
+ interface_cnt, pup_id, bit_id,
+ result[HWS_LOW2HIGH][0], e1,
+ result[HWS_HIGH2LOW][0], e2));
+ /* TBD validate is valid only for tx */
+ if (VALIDATE_TRAINING_LIMIT(e1, e2) == 1 &&
+ GET_LOCK_RESULT(result[HWS_LOW2HIGH][0]) &&
+ GET_LOCK_RESULT(result[HWS_LOW2HIGH][0])) {
+ /* Mark problem bits */
+ bit_bit_mask[pup_id] |= 1 << bit_id;
+ bit_bit_mask_active = 1;
+ }
+ } /* For all bits */
+ } /* For all PUPs */
+
+ /* Fix problem bits */
+ if (bit_bit_mask_active != 0) {
+ u32 *l2h_if_train_res = NULL;
+ u32 *h2l_if_train_res = NULL;
+ l2h_if_train_res =
+ ddr3_tip_get_buf_ptr(dev_num, HWS_LOW2HIGH,
+ result_type,
+ interface_cnt);
+ h2l_if_train_res =
+ ddr3_tip_get_buf_ptr(dev_num, HWS_HIGH2LOW,
+ result_type,
+ interface_cnt);
+
+ ddr3_tip_ip_training(dev_num, ACCESS_TYPE_UNICAST,
+ interface_cnt,
+ ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, result_type,
+ control_element, HWS_LOW2HIGH,
+ direction, interface_mask,
+ num_iter / 2, num_iter / 2,
+ pattern, EDGE_FP, train_cs_type,
+ cs_num, train_status);
+
+ for (pup_id = 0;
+ pup_id <= (tm->num_of_bus_per_interface - 1);
+ pup_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
+
+ if (bit_bit_mask[pup_id] == 0)
+ continue;
+
+ for (bit_id = 0; bit_id <= bit_end; bit_id++) {
+ if ((bit_bit_mask[pup_id] &
+ (1 << bit_id)) == 0)
+ continue;
+ CHECK_STATUS
+ (ddr3_tip_read_training_result
+ (dev_num, interface_cnt,
+ ACCESS_TYPE_UNICAST, pup_id,
+ bit_id, HWS_LOW2HIGH,
+ direction,
+ result_type,
+ TRAINING_LOAD_OPERATION_UNLOAD,
+ CS_SINGLE, &l2h_if_train_res,
+ 0, 0, 1));
+ }
+ }
+
+ ddr3_tip_ip_training(dev_num, ACCESS_TYPE_UNICAST,
+ interface_cnt,
+ ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, result_type,
+ control_element, HWS_HIGH2LOW,
+ direction, interface_mask,
+ num_iter / 2, num_iter / 2,
+ pattern, EDGE_FP, train_cs_type,
+ cs_num, train_status);
+
+ for (pup_id = 0;
+ pup_id <= (tm->num_of_bus_per_interface - 1);
+ pup_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup_id);
+
+ if (bit_bit_mask[pup_id] == 0)
+ continue;
+
+ for (bit_id = 0; bit_id <= bit_end; bit_id++) {
+ if ((bit_bit_mask[pup_id] &
+ (1 << bit_id)) == 0)
+ continue;
+ CHECK_STATUS
+ (ddr3_tip_read_training_result
+ (dev_num, interface_cnt,
+ ACCESS_TYPE_UNICAST, pup_id,
+ bit_id, HWS_HIGH2LOW, direction,
+ result_type,
+ TRAINING_LOAD_OPERATION_UNLOAD,
+ CS_SINGLE, &h2l_if_train_res,
+ 0, cons_tap, 1));
+ }
+ }
+ } /* if bit_bit_mask_active */
+ } /* For all Interfacess */
+
+ return MV_OK;
+}
+
+/*
+ * Load phy values
+ */
+int ddr3_tip_load_phy_values(int b_load)
+{
+ u32 bus_cnt = 0, if_id, dev_num = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_cnt = 0; bus_cnt < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ if (b_load == 1) {
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_cnt,
+ DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG +
+ (effective_cs *
+ CS_REGISTER_ADDR_OFFSET),
+ &phy_reg_bk[if_id][bus_cnt]
+ [0]));
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_cnt,
+ DDR_PHY_DATA,
+ RL_PHY_REG +
+ (effective_cs *
+ CS_REGISTER_ADDR_OFFSET),
+ &phy_reg_bk[if_id][bus_cnt]
+ [1]));
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, bus_cnt,
+ DDR_PHY_DATA,
+ READ_CENTRALIZATION_PHY_REG +
+ (effective_cs *
+ CS_REGISTER_ADDR_OFFSET),
+ &phy_reg_bk[if_id][bus_cnt]
+ [2]));
+ } else {
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ bus_cnt, DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG +
+ (effective_cs *
+ CS_REGISTER_ADDR_OFFSET),
+ phy_reg_bk[if_id][bus_cnt]
+ [0]));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ bus_cnt, DDR_PHY_DATA,
+ RL_PHY_REG +
+ (effective_cs *
+ CS_REGISTER_ADDR_OFFSET),
+ phy_reg_bk[if_id][bus_cnt]
+ [1]));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST,
+ bus_cnt, DDR_PHY_DATA,
+ READ_CENTRALIZATION_PHY_REG +
+ (effective_cs *
+ CS_REGISTER_ADDR_OFFSET),
+ phy_reg_bk[if_id][bus_cnt]
+ [2]));
+ }
+ }
+ }
+
+ return MV_OK;
+}
+
+int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
+ enum hws_search_dir search_dir,
+ enum hws_dir direction,
+ enum hws_edge_compare edge,
+ u32 init_val1, u32 init_val2,
+ u32 num_of_iterations,
+ u32 start_pattern, u32 end_pattern)
+{
+ u32 pattern, if_id, pup_id;
+ enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
+ u32 *res = NULL;
+ u32 search_state = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ ddr3_tip_load_phy_values(1);
+
+ for (pattern = start_pattern; pattern <= end_pattern; pattern++) {
+ for (search_state = 0; search_state < HWS_SEARCH_DIR_LIMIT;
+ search_state++) {
+ ddr3_tip_ip_training_wrapper(dev_num,
+ ACCESS_TYPE_MULTICAST, 0,
+ ACCESS_TYPE_MULTICAST, 0,
+ result_type,
+ HWS_CONTROL_ELEMENT_ADLL,
+ search_dir, direction,
+ 0xfff, init_val1,
+ init_val2,
+ num_of_iterations, pattern,
+ edge, CS_SINGLE,
+ PARAM_NOT_CARE,
+ train_status);
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (pup_id = 0; pup_id <
+ tm->num_of_bus_per_interface;
+ pup_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask,
+ pup_id);
+ CHECK_STATUS
+ (ddr3_tip_read_training_result
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup_id,
+ ALL_BITS_PER_PUP,
+ search_state,
+ direction, result_type,
+ TRAINING_LOAD_OPERATION_UNLOAD,
+ CS_SINGLE, &res, 1, 0,
+ 0));
+ if (result_type == RESULT_PER_BYTE) {
+ DEBUG_TRAINING_IP_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("search_state %d if_id %d pup_id %d 0x%x\n",
+ search_state, if_id,
+ pup_id, res[0]));
+ } else {
+ DEBUG_TRAINING_IP_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("search_state %d if_id %d pup_id %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ search_state, if_id,
+ pup_id, res[0],
+ res[1], res[2],
+ res[3], res[4],
+ res[5], res[6],
+ res[7]));
+ }
+ }
+ } /* interface */
+ } /* search */
+ } /* pattern */
+
+ ddr3_tip_load_phy_values(0);
+
+ return MV_OK;
+}
+
+struct pattern_info *ddr3_tip_get_pattern_table()
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (DDR3_IS_16BIT_DRAM_MODE(tm->bus_act_mask) == 0)
+ return pattern_table_32;
+ else
+ return pattern_table_16;
+}
+
+u16 *ddr3_tip_get_mask_results_dq_reg()
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
+ return mask_results_dq_reg_map_pup3_ecc;
+ else
+ return mask_results_dq_reg_map;
+}
+
+u16 *ddr3_tip_get_mask_results_pup_reg_map()
+{
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (DDR3_IS_ECC_PUP3_MODE(tm->bus_act_mask))
+ return mask_results_pup_reg_map_pup3_ecc;
+ else
+ return mask_results_pup_reg_map;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_ENGINE_H_
+#define _DDR3_TRAINING_IP_ENGINE_H_
+
+#include "ddr3_training_ip_def.h"
+#include "ddr3_training_ip_flow.h"
+
+#define EDGE_1 0
+#define EDGE_2 1
+#define ALL_PUP_TRAINING 0xe
+#define PUP_RESULT_EDGE_1_MASK 0xff
+#define PUP_RESULT_EDGE_2_MASK (0xff << 8)
+#define PUP_LOCK_RESULT_BIT 25
+
+#define GET_TAP_RESULT(reg, edge) \
+ (((edge) == EDGE_1) ? ((reg) & PUP_RESULT_EDGE_1_MASK) : \
+ (((reg) & PUP_RESULT_EDGE_2_MASK) >> 8));
+#define GET_LOCK_RESULT(reg) \
+ (((reg) & (1<<PUP_LOCK_RESULT_BIT)) >> PUP_LOCK_RESULT_BIT)
+
+#define EDGE_FAILURE 128
+#define ALL_BITS_PER_PUP 128
+
+#define MIN_WINDOW_SIZE 6
+#define MAX_WINDOW_SIZE_RX 32
+#define MAX_WINDOW_SIZE_TX 64
+
+int ddr3_tip_training_ip_test(u32 dev_num, enum hws_training_result result_type,
+ enum hws_search_dir search_dir,
+ enum hws_dir direction,
+ enum hws_edge_compare edge,
+ u32 init_val1, u32 init_val2,
+ u32 num_of_iterations, u32 start_pattern,
+ u32 end_pattern);
+int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern pattern);
+int ddr3_tip_load_pattern_to_mem_by_cpu(u32 dev_num, enum hws_pattern pattern,
+ u32 offset);
+int ddr3_tip_load_all_pattern_to_mem(u32 dev_num);
+int ddr3_tip_read_training_result(u32 dev_num, u32 if_id,
+ enum hws_access_type pup_access_type,
+ u32 pup_num, u32 bit_num,
+ enum hws_search_dir search,
+ enum hws_dir direction,
+ enum hws_training_result result_type,
+ enum hws_training_load_op operation,
+ u32 cs_num_type, u32 **load_res,
+ int is_read_from_db, u8 cons_tap,
+ int is_check_result_validity);
+int ddr3_tip_ip_training(u32 dev_num, enum hws_access_type access_type,
+ u32 interface_num,
+ enum hws_access_type pup_access_type,
+ u32 pup_num, enum hws_training_result result_type,
+ enum hws_control_element control_element,
+ enum hws_search_dir search_dir, enum hws_dir direction,
+ u32 interface_mask, u32 init_value, u32 num_iter,
+ enum hws_pattern pattern,
+ enum hws_edge_compare edge_comp,
+ enum hws_ddr_cs cs_type, u32 cs_num,
+ enum hws_training_ip_stat *train_status);
+int ddr3_tip_ip_training_wrapper(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id,
+ enum hws_access_type pup_access_type,
+ u32 pup_num,
+ enum hws_training_result result_type,
+ enum hws_control_element control_element,
+ enum hws_search_dir search_dir,
+ enum hws_dir direction,
+ u32 interface_mask, u32 init_value1,
+ u32 init_value2, u32 num_iter,
+ enum hws_pattern pattern,
+ enum hws_edge_compare edge_comp,
+ enum hws_ddr_cs train_cs_type, u32 cs_num,
+ enum hws_training_ip_stat *train_status);
+int is_odpg_access_done(u32 dev_num, u32 if_id);
+void ddr3_tip_print_bist_res(void);
+struct pattern_info *ddr3_tip_get_pattern_table(void);
+u16 *ddr3_tip_get_mask_results_dq_reg(void);
+u16 *ddr3_tip_get_mask_results_pup_reg_map(void);
+
+#endif /* _DDR3_TRAINING_IP_ENGINE_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_FLOW_H_
+#define _DDR3_TRAINING_IP_FLOW_H_
+
+#include "ddr3_training_ip.h"
+#include "ddr3_training_ip_pbs.h"
+
+#define MRS0_CMD 0x3
+#define MRS1_CMD 0x4
+#define MRS2_CMD 0x8
+#define MRS3_CMD 0x9
+
+/*
+ * Definitions of INTERFACE registers
+ */
+
+#define READ_BUFFER_SELECT 0x14a4
+
+/*
+ * Definitions of PHY registers
+ */
+
+#define KILLER_PATTERN_LENGTH 32
+#define EXT_ACCESS_BURST_LENGTH 8
+
+#define IS_ACTIVE(if_mask , if_id) \
+ ((if_mask) & (1 << (if_id)))
+#define VALIDATE_ACTIVE(mask, id) \
+ { \
+ if (IS_ACTIVE(mask, id) == 0) \
+ continue; \
+ }
+
+#define GET_TOPOLOGY_NUM_OF_BUSES() \
+ (ddr3_get_topology_map()->num_of_bus_per_interface)
+
+#define DDR3_IS_ECC_PUP3_MODE(if_mask) \
+ (((if_mask) == 0xb) ? 1 : 0)
+#define DDR3_IS_ECC_PUP4_MODE(if_mask) \
+ (((((if_mask) & 0x10) == 0)) ? 0 : 1)
+#define DDR3_IS_16BIT_DRAM_MODE(mask) \
+ (((((mask) & 0x4) == 0)) ? 1 : 0)
+
+#define MEGA 1000000
+#define BUS_WIDTH_IN_BITS 8
+
+/*
+ * DFX address Space
+ * Table 2: DFX address space
+ * Address Bits Value Description
+ * [31 : 20] 0x? DFX base address bases PCIe mapping
+ * [19 : 15] 0...Number_of_client-1 Client Index inside pipe.
+ * See also Table 1 Multi_cast = 29 Broadcast = 28
+ * [14 : 13] 2'b01 Access to Client Internal Register
+ * [12 : 0] Client Internal Register offset See related Client Registers
+ * [14 : 13] 2'b00 Access to Ram Wrappers Internal Register
+ * [12 : 6] 0 Number_of_rams-1 Ram Index inside Client
+ * [5 : 0] Ram Wrapper Internal Register offset See related Ram Wrappers
+ * Registers
+ */
+
+/* nsec */
+#define TREFI_LOW 7800
+#define TREFI_HIGH 3900
+
+#define TR2R_VALUE_REG 0x180
+#define TR2R_MASK_REG 0x180
+#define TRFC_MASK_REG 0x7f
+#define TR2W_MASK_REG 0x600
+#define TW2W_HIGH_VALUE_REG 0x1800
+#define TW2W_HIGH_MASK_REG 0xf800
+#define TRFC_HIGH_VALUE_REG 0x20000
+#define TRFC_HIGH_MASK_REG 0x70000
+#define TR2R_HIGH_VALUE_REG 0x0
+#define TR2R_HIGH_MASK_REG 0x380000
+#define TMOD_VALUE_REG 0x16000000
+#define TMOD_MASK_REG 0x1e000000
+#define T_VALUE_REG 0x40000000
+#define T_MASK_REG 0xc0000000
+#define AUTO_ZQC_TIMING 15384
+#define WRITE_XBAR_PORT1 0xc03f8077
+#define READ_XBAR_PORT1 0xc03f8073
+#define DISABLE_DDR_TUNING_DATA 0x02294285
+#define ENABLE_DDR_TUNING_DATA 0x12294285
+
+#define ODPG_TRAINING_STATUS_REG 0x18488
+#define ODPG_TRAINING_TRIGGER_REG 0x1030
+#define ODPG_STATUS_DONE_REG 0x16fc
+#define ODPG_ENABLE_REG 0x186d4
+#define ODPG_ENABLE_OFFS 0
+#define ODPG_DISABLE_OFFS 8
+
+#define ODPG_TRAINING_CONTROL_REG 0x1034
+#define ODPG_OBJ1_OPCODE_REG 0x103c
+#define ODPG_OBJ1_ITER_CNT_REG 0x10b4
+#define CALIB_OBJ_PRFA_REG 0x10c4
+#define ODPG_WRITE_LEVELING_DONE_CNTR_REG 0x10f8
+#define ODPG_WRITE_READ_MODE_ENABLE_REG 0x10fc
+#define TRAINING_OPCODE_1_REG 0x10b4
+#define SDRAM_CONFIGURATION_REG 0x1400
+#define DDR_CONTROL_LOW_REG 0x1404
+#define SDRAM_TIMING_LOW_REG 0x1408
+#define SDRAM_TIMING_HIGH_REG 0x140c
+#define SDRAM_ACCESS_CONTROL_REG 0x1410
+#define SDRAM_OPEN_PAGE_CONTROL_REG 0x1414
+#define SDRAM_OPERATION_REG 0x1418
+#define DUNIT_CONTROL_HIGH_REG 0x1424
+#define ODT_TIMING_LOW 0x1428
+#define DDR_TIMING_REG 0x142c
+#define ODT_TIMING_HI_REG 0x147c
+#define SDRAM_INIT_CONTROL_REG 0x1480
+#define SDRAM_ODT_CONTROL_HIGH_REG 0x1498
+#define DUNIT_ODT_CONTROL_REG 0x149c
+#define READ_BUFFER_SELECT_REG 0x14a4
+#define DUNIT_MMASK_REG 0x14b0
+#define CALIB_MACHINE_CTRL_REG 0x14cc
+#define DRAM_DLL_TIMING_REG 0x14e0
+#define DRAM_ZQ_INIT_TIMIMG_REG 0x14e4
+#define DRAM_ZQ_TIMING_REG 0x14e8
+#define DFS_REG 0x1528
+#define READ_DATA_SAMPLE_DELAY 0x1538
+#define READ_DATA_READY_DELAY 0x153c
+#define TRAINING_REG 0x15b0
+#define TRAINING_SW_1_REG 0x15b4
+#define TRAINING_SW_2_REG 0x15b8
+#define TRAINING_PATTERN_BASE_ADDRESS_REG 0x15bc
+#define TRAINING_DBG_1_REG 0x15c0
+#define TRAINING_DBG_2_REG 0x15c4
+#define TRAINING_DBG_3_REG 0x15c8
+#define RANK_CTRL_REG 0x15e0
+#define TIMING_REG 0x15e4
+#define DRAM_PHY_CONFIGURATION 0x15ec
+#define MR0_REG 0x15d0
+#define MR1_REG 0x15d4
+#define MR2_REG 0x15d8
+#define MR3_REG 0x15dc
+#define TIMING_REG 0x15e4
+#define ODPG_CTRL_CONTROL_REG 0x1600
+#define ODPG_DATA_CONTROL_REG 0x1630
+#define ODPG_PATTERN_ADDR_OFFSET_REG 0x1638
+#define ODPG_DATA_BUF_SIZE_REG 0x163c
+#define PHY_LOCK_STATUS_REG 0x1674
+#define PHY_REG_FILE_ACCESS 0x16a0
+#define TRAINING_WRITE_LEVELING_REG 0x16ac
+#define ODPG_PATTERN_ADDR_REG 0x16b0
+#define ODPG_PATTERN_DATA_HI_REG 0x16b4
+#define ODPG_PATTERN_DATA_LOW_REG 0x16b8
+#define ODPG_BIST_LAST_FAIL_ADDR_REG 0x16bc
+#define ODPG_BIST_DATA_ERROR_COUNTER_REG 0x16c0
+#define ODPG_BIST_FAILED_DATA_HI_REG 0x16c4
+#define ODPG_BIST_FAILED_DATA_LOW_REG 0x16c8
+#define ODPG_WRITE_DATA_ERROR_REG 0x16cc
+#define CS_ENABLE_REG 0x16d8
+#define WR_LEVELING_DQS_PATTERN_REG 0x16dc
+
+#define ODPG_BIST_DONE 0x186d4
+#define ODPG_BIST_DONE_BIT_OFFS 0
+#define ODPG_BIST_DONE_BIT_VALUE 0
+
+#define RESULT_CONTROL_BYTE_PUP_0_REG 0x1830
+#define RESULT_CONTROL_BYTE_PUP_1_REG 0x1834
+#define RESULT_CONTROL_BYTE_PUP_2_REG 0x1838
+#define RESULT_CONTROL_BYTE_PUP_3_REG 0x183c
+#define RESULT_CONTROL_BYTE_PUP_4_REG 0x18b0
+
+#define RESULT_CONTROL_PUP_0_BIT_0_REG 0x18b4
+#define RESULT_CONTROL_PUP_0_BIT_1_REG 0x18b8
+#define RESULT_CONTROL_PUP_0_BIT_2_REG 0x18bc
+#define RESULT_CONTROL_PUP_0_BIT_3_REG 0x18c0
+#define RESULT_CONTROL_PUP_0_BIT_4_REG 0x18c4
+#define RESULT_CONTROL_PUP_0_BIT_5_REG 0x18c8
+#define RESULT_CONTROL_PUP_0_BIT_6_REG 0x18cc
+#define RESULT_CONTROL_PUP_0_BIT_7_REG 0x18f0
+#define RESULT_CONTROL_PUP_1_BIT_0_REG 0x18f4
+#define RESULT_CONTROL_PUP_1_BIT_1_REG 0x18f8
+#define RESULT_CONTROL_PUP_1_BIT_2_REG 0x18fc
+#define RESULT_CONTROL_PUP_1_BIT_3_REG 0x1930
+#define RESULT_CONTROL_PUP_1_BIT_4_REG 0x1934
+#define RESULT_CONTROL_PUP_1_BIT_5_REG 0x1938
+#define RESULT_CONTROL_PUP_1_BIT_6_REG 0x193c
+#define RESULT_CONTROL_PUP_1_BIT_7_REG 0x19b0
+#define RESULT_CONTROL_PUP_2_BIT_0_REG 0x19b4
+#define RESULT_CONTROL_PUP_2_BIT_1_REG 0x19b8
+#define RESULT_CONTROL_PUP_2_BIT_2_REG 0x19bc
+#define RESULT_CONTROL_PUP_2_BIT_3_REG 0x19c0
+#define RESULT_CONTROL_PUP_2_BIT_4_REG 0x19c4
+#define RESULT_CONTROL_PUP_2_BIT_5_REG 0x19c8
+#define RESULT_CONTROL_PUP_2_BIT_6_REG 0x19cc
+#define RESULT_CONTROL_PUP_2_BIT_7_REG 0x19f0
+#define RESULT_CONTROL_PUP_3_BIT_0_REG 0x19f4
+#define RESULT_CONTROL_PUP_3_BIT_1_REG 0x19f8
+#define RESULT_CONTROL_PUP_3_BIT_2_REG 0x19fc
+#define RESULT_CONTROL_PUP_3_BIT_3_REG 0x1a30
+#define RESULT_CONTROL_PUP_3_BIT_4_REG 0x1a34
+#define RESULT_CONTROL_PUP_3_BIT_5_REG 0x1a38
+#define RESULT_CONTROL_PUP_3_BIT_6_REG 0x1a3c
+#define RESULT_CONTROL_PUP_3_BIT_7_REG 0x1ab0
+#define RESULT_CONTROL_PUP_4_BIT_0_REG 0x1ab4
+#define RESULT_CONTROL_PUP_4_BIT_1_REG 0x1ab8
+#define RESULT_CONTROL_PUP_4_BIT_2_REG 0x1abc
+#define RESULT_CONTROL_PUP_4_BIT_3_REG 0x1ac0
+#define RESULT_CONTROL_PUP_4_BIT_4_REG 0x1ac4
+#define RESULT_CONTROL_PUP_4_BIT_5_REG 0x1ac8
+#define RESULT_CONTROL_PUP_4_BIT_6_REG 0x1acc
+#define RESULT_CONTROL_PUP_4_BIT_7_REG 0x1af0
+
+#define WL_PHY_REG 0x0
+#define WRITE_CENTRALIZATION_PHY_REG 0x1
+#define RL_PHY_REG 0x2
+#define READ_CENTRALIZATION_PHY_REG 0x3
+#define PBS_RX_PHY_REG 0x50
+#define PBS_TX_PHY_REG 0x10
+#define PHY_CONTROL_PHY_REG 0x90
+#define BW_PHY_REG 0x92
+#define RATE_PHY_REG 0x94
+#define CMOS_CONFIG_PHY_REG 0xa2
+#define PAD_ZRI_CALIB_PHY_REG 0xa4
+#define PAD_ODT_CALIB_PHY_REG 0xa6
+#define PAD_CONFIG_PHY_REG 0xa8
+#define PAD_PRE_DISABLE_PHY_REG 0xa9
+#define TEST_ADLL_REG 0xbf
+#define CSN_IOB_VREF_REG(cs) (0xdb + (cs * 12))
+#define CSN_IO_BASE_VREF_REG(cs) (0xd0 + (cs * 12))
+
+#define RESULT_DB_PHY_REG_ADDR 0xc0
+#define RESULT_DB_PHY_REG_RX_OFFSET 5
+#define RESULT_DB_PHY_REG_TX_OFFSET 0
+
+/* TBD - for NP5 use only CS 0 */
+#define PHY_WRITE_DELAY(cs) WL_PHY_REG
+/*( ( _cs_ == 0 ) ? 0x0 : 0x4 )*/
+/* TBD - for NP5 use only CS 0 */
+#define PHY_READ_DELAY(cs) RL_PHY_REG
+
+#define DDR0_ADDR_1 0xf8258
+#define DDR0_ADDR_2 0xf8254
+#define DDR1_ADDR_1 0xf8270
+#define DDR1_ADDR_2 0xf8270
+#define DDR2_ADDR_1 0xf825c
+#define DDR2_ADDR_2 0xf825c
+#define DDR3_ADDR_1 0xf8264
+#define DDR3_ADDR_2 0xf8260
+#define DDR4_ADDR_1 0xf8274
+#define DDR4_ADDR_2 0xf8274
+
+#define GENERAL_PURPOSE_RESERVED0_REG 0x182e0
+
+#define GET_BLOCK_ID_MAX_FREQ(dev_num, block_id) 800000
+#define CS0_RD_LVL_REF_DLY_OFFS 0
+#define CS0_RD_LVL_REF_DLY_LEN 0
+#define CS0_RD_LVL_PH_SEL_OFFS 0
+#define CS0_RD_LVL_PH_SEL_LEN 0
+
+#define CS_REGISTER_ADDR_OFFSET 4
+#define CALIBRATED_OBJECTS_REG_ADDR_OFFSET 0x10
+
+#define MAX_POLLING_ITERATIONS 100000
+
+#define PHASE_REG_OFFSET 32
+#define NUM_BYTES_IN_BURST 31
+#define NUM_OF_CS 4
+#define CS_REG_VALUE(cs_num) (cs_mask_reg[cs_num])
+#define ADLL_LENGTH 32
+
+struct write_supp_result {
+ enum hws_wl_supp stage;
+ int is_pup_fail;
+};
+
+struct page_element {
+ enum hws_page_size page_size_8bit;
+ /* page size in 8 bits bus width */
+ enum hws_page_size page_size_16bit;
+ /* page size in 16 bits bus width */
+ u32 ui_page_mask;
+ /* Mask used in register */
+};
+
+int ddr3_tip_write_leveling_static_config(u32 dev_num, u32 if_id,
+ enum hws_ddr_freq frequency,
+ u32 *round_trip_delay_arr);
+int ddr3_tip_read_leveling_static_config(u32 dev_num, u32 if_id,
+ enum hws_ddr_freq frequency,
+ u32 *total_round_trip_delay_arr);
+int ddr3_tip_if_write(u32 dev_num, enum hws_access_type interface_access,
+ u32 if_id, u32 reg_addr, u32 data_value, u32 mask);
+int ddr3_tip_if_polling(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, u32 exp_value, u32 mask, u32 offset,
+ u32 poll_tries);
+int ddr3_tip_if_read(u32 dev_num, enum hws_access_type interface_access,
+ u32 if_id, u32 reg_addr, u32 *data, u32 mask);
+int ddr3_tip_bus_read_modify_write(u32 dev_num,
+ enum hws_access_type access_type,
+ u32 if_id, u32 phy_id,
+ enum hws_ddr_phy phy_type,
+ u32 reg_addr, u32 data_value, u32 reg_mask);
+int ddr3_tip_bus_read(u32 dev_num, u32 if_id, enum hws_access_type phy_access,
+ u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr,
+ u32 *data);
+int ddr3_tip_bus_write(u32 dev_num, enum hws_access_type e_interface_access,
+ u32 if_id, enum hws_access_type e_phy_access, u32 phy_id,
+ enum hws_ddr_phy e_phy_type, u32 reg_addr,
+ u32 data_value);
+int ddr3_tip_freq_set(u32 dev_num, enum hws_access_type e_access, u32 if_id,
+ enum hws_ddr_freq memory_freq);
+int ddr3_tip_adjust_dqs(u32 dev_num);
+int ddr3_tip_init_controller(u32 dev_num);
+int ddr3_tip_ext_read(u32 dev_num, u32 if_id, u32 reg_addr,
+ u32 num_of_bursts, u32 *addr);
+int ddr3_tip_ext_write(u32 dev_num, u32 if_id, u32 reg_addr,
+ u32 num_of_bursts, u32 *addr);
+int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 ui_freq);
+int ddr3_tip_legacy_dynamic_read_leveling(u32 dev_num);
+int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 ui_freq);
+int ddr3_tip_legacy_dynamic_write_leveling(u32 dev_num);
+int ddr3_tip_dynamic_write_leveling(u32 dev_num);
+int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num);
+int ddr3_tip_static_init_controller(u32 dev_num);
+int ddr3_tip_configure_phy(u32 dev_num);
+int ddr3_tip_load_pattern_to_odpg(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_pattern pattern,
+ u32 load_addr);
+int ddr3_tip_load_pattern_to_mem(u32 dev_num, enum hws_pattern e_pattern);
+int ddr3_tip_configure_odpg(u32 dev_num, enum hws_access_type access_type,
+ u32 if_id, enum hws_dir direction, u32 tx_phases,
+ u32 tx_burst_size, u32 rx_phases,
+ u32 delay_between_burst, u32 rd_mode, u32 cs_num,
+ u32 addr_stress_jump, u32 single_pattern);
+int ddr3_tip_set_atr(u32 dev_num, u32 flag_id, u32 value);
+int ddr3_tip_write_mrs_cmd(u32 dev_num, u32 *cs_mask_arr, u32 cmd, u32 data,
+ u32 mask);
+int ddr3_tip_write_cs_result(u32 dev_num, u32 offset);
+int ddr3_tip_get_first_active_if(u8 dev_num, u32 interface_mask, u32 *if_id);
+int ddr3_tip_reset_fifo_ptr(u32 dev_num);
+int read_pup_value(int pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+ int reg_addr, u32 mask);
+int read_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+ int reg_addr, u32 mask);
+int write_adll_value(u32 pup_values[MAX_INTERFACE_NUM * MAX_BUS_NUM],
+ int reg_addr);
+int ddr3_tip_tune_training_params(u32 dev_num,
+ struct tune_train_params *params);
+
+#endif /* _DDR3_TRAINING_IP_FLOW_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_PBS_H_
+#define _DDR3_TRAINING_IP_PBS_H_
+
+enum {
+ EBA_CONFIG,
+ EEBA_CONFIG,
+ SBA_CONFIG
+};
+
+enum hws_training_load_op {
+ TRAINING_LOAD_OPERATION_UNLOAD,
+ TRAINING_LOAD_OPERATION_LOAD
+};
+
+enum hws_edge {
+ TRAINING_EDGE_1,
+ TRAINING_EDGE_2
+};
+
+enum hws_edge_search {
+ TRAINING_EDGE_MAX,
+ TRAINING_EDGE_MIN
+};
+
+enum pbs_dir {
+ PBS_TX_MODE = 0,
+ PBS_RX_MODE,
+ NUM_OF_PBS_MODES
+};
+
+int ddr3_tip_pbs_rx(u32 dev_num);
+int ddr3_tip_print_all_pbs_result(u32 dev_num);
+int ddr3_tip_pbs_tx(u32 dev_num);
+
+#endif /* _DDR3_TRAINING_IP_PBS_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_PRV_IF_H
+#define _DDR3_TRAINING_IP_PRV_IF_H
+
+#include "ddr3_training_ip.h"
+#include "ddr3_training_ip_flow.h"
+#include "ddr3_training_ip_bist.h"
+
+enum hws_static_config_type {
+ WRITE_LEVELING_STATIC,
+ READ_LEVELING_STATIC
+};
+
+struct ddr3_device_info {
+ u32 device_id;
+ u32 ck_delay;
+};
+
+typedef int (*HWS_TIP_DUNIT_MUX_SELECT_FUNC_PTR)(u8 dev_num, int enable);
+typedef int (*HWS_TIP_DUNIT_REG_READ_FUNC_PTR)(
+ u8 dev_num, enum hws_access_type interface_access, u32 if_id,
+ u32 offset, u32 *data, u32 mask);
+typedef int (*HWS_TIP_DUNIT_REG_WRITE_FUNC_PTR)(
+ u8 dev_num, enum hws_access_type interface_access, u32 if_id,
+ u32 offset, u32 data, u32 mask);
+typedef int (*HWS_TIP_GET_FREQ_CONFIG_INFO)(
+ u8 dev_num, enum hws_ddr_freq freq,
+ struct hws_tip_freq_config_info *freq_config_info);
+typedef int (*HWS_TIP_GET_DEVICE_INFO)(
+ u8 dev_num, struct ddr3_device_info *info_ptr);
+typedef int (*HWS_GET_CS_CONFIG_FUNC_PTR)(
+ u8 dev_num, u32 cs_mask, struct hws_cs_config_info *cs_info);
+typedef int (*HWS_SET_FREQ_DIVIDER_FUNC_PTR)(
+ u8 dev_num, u32 if_id, enum hws_ddr_freq freq);
+typedef int (*HWS_GET_INIT_FREQ)(u8 dev_num, enum hws_ddr_freq *freq);
+typedef int (*HWS_TRAINING_IP_IF_WRITE_FUNC_PTR)(
+ u32 dev_num, enum hws_access_type access_type, u32 dunit_id,
+ u32 reg_addr, u32 data, u32 mask);
+typedef int (*HWS_TRAINING_IP_IF_READ_FUNC_PTR)(
+ u32 dev_num, enum hws_access_type access_type, u32 dunit_id,
+ u32 reg_addr, u32 *data, u32 mask);
+typedef int (*HWS_TRAINING_IP_BUS_WRITE_FUNC_PTR)(
+ u32 dev_num, enum hws_access_type dunit_access_type, u32 if_id,
+ enum hws_access_type phy_access_type, u32 phy_id,
+ enum hws_ddr_phy phy_type, u32 reg_addr, u32 data);
+typedef int (*HWS_TRAINING_IP_BUS_READ_FUNC_PTR)(
+ u32 dev_num, u32 if_id, enum hws_access_type phy_access_type,
+ u32 phy_id, enum hws_ddr_phy phy_type, u32 reg_addr, u32 *data);
+typedef int (*HWS_TRAINING_IP_ALGO_RUN_FUNC_PTR)(
+ u32 dev_num, enum hws_algo_type algo_type);
+typedef int (*HWS_TRAINING_IP_SET_FREQ_FUNC_PTR)(
+ u32 dev_num, enum hws_access_type access_type, u32 if_id,
+ enum hws_ddr_freq frequency);
+typedef int (*HWS_TRAINING_IP_INIT_CONTROLLER_FUNC_PTR)(
+ u32 dev_num, struct init_cntr_param *init_cntr_prm);
+typedef int (*HWS_TRAINING_IP_PBS_RX_FUNC_PTR)(u32 dev_num);
+typedef int (*HWS_TRAINING_IP_PBS_TX_FUNC_PTR)(u32 dev_num);
+typedef int (*HWS_TRAINING_IP_SELECT_CONTROLLER_FUNC_PTR)(
+ u32 dev_num, int enable);
+typedef int (*HWS_TRAINING_IP_TOPOLOGY_MAP_LOAD_FUNC_PTR)(
+ u32 dev_num, struct hws_topology_map *topology_map);
+typedef int (*HWS_TRAINING_IP_STATIC_CONFIG_FUNC_PTR)(
+ u32 dev_num, enum hws_ddr_freq frequency,
+ enum hws_static_config_type static_config_type, u32 if_id);
+typedef int (*HWS_TRAINING_IP_EXTERNAL_READ_PTR)(
+ u32 dev_num, u32 if_id, u32 ddr_addr, u32 num_bursts, u32 *data);
+typedef int (*HWS_TRAINING_IP_EXTERNAL_WRITE_PTR)(
+ u32 dev_num, u32 if_id, u32 ddr_addr, u32 num_bursts, u32 *data);
+typedef int (*HWS_TRAINING_IP_BIST_ACTIVATE)(
+ u32 dev_num, enum hws_pattern pattern, enum hws_access_type access_type,
+ u32 if_num, enum hws_dir direction,
+ enum hws_stress_jump addr_stress_jump,
+ enum hws_pattern_duration duration,
+ enum hws_bist_operation oper_type, u32 offset, u32 cs_num,
+ u32 pattern_addr_length);
+typedef int (*HWS_TRAINING_IP_BIST_READ_RESULT)(
+ u32 dev_num, u32 if_id, struct bist_result *pst_bist_result);
+typedef int (*HWS_TRAINING_IP_LOAD_TOPOLOGY)(u32 dev_num, u32 config_num);
+typedef int (*HWS_TRAINING_IP_READ_LEVELING)(u32 dev_num, u32 config_num);
+typedef int (*HWS_TRAINING_IP_WRITE_LEVELING)(u32 dev_num, u32 config_num);
+typedef u32 (*HWS_TRAINING_IP_GET_TEMP)(u8 dev_num);
+
+struct hws_tip_config_func_db {
+ HWS_TIP_DUNIT_MUX_SELECT_FUNC_PTR tip_dunit_mux_select_func;
+ HWS_TIP_DUNIT_REG_READ_FUNC_PTR tip_dunit_read_func;
+ HWS_TIP_DUNIT_REG_WRITE_FUNC_PTR tip_dunit_write_func;
+ HWS_TIP_GET_FREQ_CONFIG_INFO tip_get_freq_config_info_func;
+ HWS_TIP_GET_DEVICE_INFO tip_get_device_info_func;
+ HWS_SET_FREQ_DIVIDER_FUNC_PTR tip_set_freq_divider_func;
+ HWS_GET_CS_CONFIG_FUNC_PTR tip_get_cs_config_info;
+ HWS_TRAINING_IP_GET_TEMP tip_get_temperature;
+};
+
+int ddr3_tip_init_config_func(u32 dev_num,
+ struct hws_tip_config_func_db *config_func);
+int ddr3_tip_register_xsb_info(u32 dev_num,
+ struct hws_xsb_info *xsb_info_table);
+enum hws_result *ddr3_tip_get_result_ptr(u32 stage);
+int ddr3_set_freq_config_info(struct hws_tip_freq_config_info *table);
+int print_device_info(u8 dev_num);
+
+#endif /* _DDR3_TRAINING_IP_PRV_IF_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_IP_STATIC_H_
+#define _DDR3_TRAINING_IP_STATIC_H_
+
+#include "ddr3_training_ip_def.h"
+#include "ddr3_training_ip.h"
+
+struct trip_delay_element {
+ u32 dqs_delay; /* DQS delay (m_sec) */
+ u32 ck_delay; /* CK Delay (m_sec) */
+};
+
+struct hws_tip_static_config_info {
+ u32 silicon_delay;
+ struct trip_delay_element *package_trace_arr;
+ struct trip_delay_element *board_trace_arr;
+};
+
+int ddr3_tip_run_static_alg(u32 dev_num, enum hws_ddr_freq freq);
+int ddr3_tip_init_static_config_db(
+ u32 dev_num, struct hws_tip_static_config_info *static_config_info);
+int ddr3_tip_init_specific_reg_config(u32 dev_num,
+ struct reg_data *reg_config_arr);
+int ddr3_tip_static_phy_init_controller(u32 dev_num);
+
+#endif /* _DDR3_TRAINING_IP_STATIC_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#define WL_ITERATION_NUM 10
+#define ONE_CLOCK_ERROR_SHIFT 2
+#define ALIGN_ERROR_SHIFT -2
+
+static u32 pup_mask_table[] = {
+ 0x000000ff,
+ 0x0000ff00,
+ 0x00ff0000,
+ 0xff000000
+};
+
+static struct write_supp_result wr_supp_res[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+
+static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num);
+static int ddr3_tip_dynamic_read_leveling_seq(u32 dev_num);
+static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num);
+static int ddr3_tip_wl_supp_align_err_shift(u32 dev_num, u32 if_id, u32 bus_id,
+ u32 bus_id_delta);
+static int ddr3_tip_wl_supp_align_phase_shift(u32 dev_num, u32 if_id,
+ u32 bus_id, u32 offset,
+ u32 bus_id_delta);
+static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id,
+ u32 edge_offset, u32 bus_id_delta);
+static int ddr3_tip_wl_supp_one_clk_err_shift(u32 dev_num, u32 if_id,
+ u32 bus_id, u32 bus_id_delta);
+
+u32 hws_ddr3_tip_max_cs_get(void)
+{
+ u32 c_cs;
+ static u32 max_cs;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (!max_cs) {
+ for (c_cs = 0; c_cs < NUM_OF_CS; c_cs++) {
+ VALIDATE_ACTIVE(tm->
+ interface_params[0].as_bus_params[0].
+ cs_bitmask, c_cs);
+ max_cs++;
+ }
+ }
+
+ return max_cs;
+}
+
+/*****************************************************************************
+Dynamic read leveling
+******************************************************************************/
+int ddr3_tip_dynamic_read_leveling(u32 dev_num, u32 freq)
+{
+ u32 data, mask;
+ u32 max_cs = hws_ddr3_tip_max_cs_get();
+ u32 bus_num, if_id, cl_val;
+ enum hws_speed_bin speed_bin_index;
+ /* save current CS value */
+ u32 cs_enable_reg_val[MAX_INTERFACE_NUM] = { 0 };
+ int is_any_pup_fail = 0;
+ u32 data_read[MAX_INTERFACE_NUM + 1] = { 0 };
+ u8 rl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM];
+ struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+ u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ if (rl_version == 0) {
+ /* OLD RL machine */
+ data = 0x40;
+ data |= (1 << 20);
+
+ /* TBD multi CS */
+ CHECK_STATUS(ddr3_tip_if_write(
+ dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, TRAINING_REG,
+ data, 0x11ffff));
+ CHECK_STATUS(ddr3_tip_if_write(
+ dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ TRAINING_PATTERN_BASE_ADDRESS_REG,
+ 0, 0xfffffff8));
+ CHECK_STATUS(ddr3_tip_if_write(
+ dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, TRAINING_REG,
+ (u32)(1 << 31), (u32)(1 << 31)));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ training_result[training_stage][if_id] = TEST_SUCCESS;
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
+ (u32)(1 << 31), TRAINING_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_ERROR,
+ ("RL: DDR3 poll failed(1) IF %d\n",
+ if_id));
+ training_result[training_stage][if_id] =
+ TEST_FAILED;
+
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ /* read read-leveling result */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_REG, data_read, 1 << 30));
+ /* exit read leveling mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x8, 0x9));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_1_REG, 1 << 16, 1 << 16));
+
+ /* disable RL machine all Trn_CS[3:0] , [16:0] */
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_REG, 0, 0xf1ffff));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if ((data_read[if_id] & (1 << 30)) == 0) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_ERROR,
+ ("\n_read Leveling failed for IF %d\n",
+ if_id));
+ training_result[training_stage][if_id] =
+ TEST_FAILED;
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ return MV_OK;
+ }
+
+ /* NEW RL machine */
+ for (effective_cs = 0; effective_cs < NUM_OF_CS; effective_cs++)
+ for (bus_num = 0; bus_num < MAX_BUS_NUM; bus_num++)
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++)
+ rl_values[effective_cs][bus_num][if_id] = 0;
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ training_result[training_stage][if_id] = TEST_SUCCESS;
+
+ /* save current cs enable reg val */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, cs_enable_reg_val,
+ MASK_ALL_BITS));
+ /* enable single cs */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, (1 << 3), (1 << 3)));
+ }
+
+ ddr3_tip_reset_fifo_ptr(dev_num);
+
+ /*
+ * Phase 1: Load pattern (using ODPG)
+ *
+ * enter Read Leveling mode
+ * only 27 bits are masked
+ * assuming non multi-CS configuration
+ * write to CS = 0 for the non multi CS configuration, note
+ * that the results shall be read back to the required CS !!!
+ */
+
+ /* BUS count is 0 shifted 26 */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0x3, 0x3));
+ CHECK_STATUS(ddr3_tip_configure_odpg
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0,
+ pattern_table[PATTERN_RL].num_of_phases_tx, 0,
+ pattern_table[PATTERN_RL].num_of_phases_rx, 0, 0,
+ effective_cs, STRESS_NONE, DURATION_SINGLE));
+
+ /* load pattern to ODPG */
+ ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, PATTERN_RL,
+ pattern_table[PATTERN_RL].
+ start_addr);
+
+ /*
+ * Phase 2: ODPG to Read Leveling mode
+ */
+
+ /* General Training Opcode register */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_WRITE_READ_MODE_ENABLE_REG, 0,
+ MASK_ALL_BITS));
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_TRAINING_CONTROL_REG,
+ (0x301b01 | effective_cs << 2), 0x3c3fef));
+
+ /* Object1 opcode register 0 & 1 */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ speed_bin_index =
+ tm->interface_params[if_id].speed_bin_index;
+ cl_val =
+ cas_latency_table[speed_bin_index].cl_val[freq];
+ data = (cl_val << 17) | (0x3 << 25);
+ mask = (0xff << 9) | (0x1f << 17) | (0x3 << 25);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ODPG_OBJ1_OPCODE_REG, data, mask));
+ }
+
+ /* Set iteration count to max value */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_OPCODE_1_REG, 0xd00, 0xd00));
+
+ /*
+ * Phase 2: Mask config
+ */
+
+ ddr3_tip_dynamic_read_leveling_seq(dev_num);
+
+ /*
+ * Phase 3: Read Leveling execution
+ */
+
+ /* temporary jira dunit=14751 */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_DBG_1_REG, 0, (u32)(1 << 31)));
+ /* configure phy reset value */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_DBG_3_REG, (0x7f << 24),
+ (u32)(0xff << 24)));
+ /* data pup rd reset enable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ SDRAM_CONFIGURATION_REG, 0, (1 << 30)));
+ /* data pup rd reset disable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ SDRAM_CONFIGURATION_REG, (1 << 30), (1 << 30)));
+ /* training SW override & training RL mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x1, 0x9));
+ /* training enable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_REG, (1 << 24) | (1 << 20),
+ (1 << 24) | (1 << 20)));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_REG, (u32)(1 << 31), (u32)(1 << 31)));
+
+ /********* trigger training *******************/
+ /* Trigger, poll on status and disable ODPG */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
+
+ /* check for training done + results pass */
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2,
+ ODPG_TRAINING_STATUS_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("Training Done Failed\n"));
+ return MV_FAIL;
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id,
+ ODPG_TRAINING_TRIGGER_REG, data_read,
+ 0x4));
+ data = data_read[if_id];
+ if (data != 0x0) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("Training Result Failed\n"));
+ }
+ }
+
+ /*disable ODPG - Back to functional mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,
+ (0x1 << ODPG_DISABLE_OFFS)));
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1,
+ ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("ODPG disable failed "));
+ return MV_FAIL;
+ }
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
+
+ /* double loop on bus, pup */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* check training done */
+ is_any_pup_fail = 0;
+ for (bus_num = 0;
+ bus_num < tm->num_of_bus_per_interface;
+ bus_num++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, (1 << 25), (1 << 25),
+ mask_results_pup_reg_map[bus_num],
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("\n_r_l: DDR3 poll failed(2) for bus %d",
+ bus_num));
+ is_any_pup_fail = 1;
+ } else {
+ /* read result per pup */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ mask_results_pup_reg_map
+ [bus_num], data_read,
+ 0xff));
+ rl_values[effective_cs][bus_num]
+ [if_id] = (u8)data_read[if_id];
+ }
+ }
+
+ if (is_any_pup_fail == 1) {
+ training_result[training_stage][if_id] =
+ TEST_FAILED;
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+
+ DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("RL exit read leveling\n"));
+
+ /*
+ * Phase 3: Exit Read Leveling
+ */
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, (1 << 3), (1 << 3)));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_1_REG, (1 << 16), (1 << 16)));
+ /* set ODPG to functional */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
+
+ /*
+ * Copy the result from the effective CS search to the
+ * real Functional CS
+ */
+ /*ddr3_tip_write_cs_result(dev_num, RL_PHY_REG); */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
+ }
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ /* double loop on bus, pup */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_num = 0;
+ bus_num < tm->num_of_bus_per_interface;
+ bus_num++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+ /* read result per pup from arry */
+ data = rl_values[effective_cs][bus_num][if_id];
+ data = (data & 0x1f) |
+ (((data & 0xe0) >> 5) << 6);
+ ddr3_tip_bus_write(dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_num, DDR_PHY_DATA,
+ RL_PHY_REG +
+ ((effective_cs ==
+ 0) ? 0x0 : 0x4), data);
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* restore cs enable value */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, cs_enable_reg_val[if_id],
+ MASK_ALL_BITS));
+ if (odt_config != 0) {
+ CHECK_STATUS(ddr3_tip_write_additional_odt_setting
+ (dev_num, if_id));
+ }
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (training_result[training_stage][if_id] == TEST_FAILED)
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Legacy Dynamic write leveling
+ */
+int ddr3_tip_legacy_dynamic_write_leveling(u32 dev_num)
+{
+ u32 c_cs, if_id, cs_mask = 0;
+ u32 max_cs = hws_ddr3_tip_max_cs_get();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /*
+ * In TRAINIUNG reg (0x15b0) write 0x80000008 | cs_mask:
+ * Trn_start
+ * cs_mask = 0x1 <<20 Trn_CS0 - CS0 is included in the DDR3 training
+ * cs_mask = 0x1 <<21 Trn_CS1 - CS1 is included in the DDR3 training
+ * cs_mask = 0x1 <<22 Trn_CS2 - CS2 is included in the DDR3 training
+ * cs_mask = 0x1 <<23 Trn_CS3 - CS3 is included in the DDR3 training
+ * Trn_auto_seq = write leveling
+ */
+ for (c_cs = 0; c_cs < max_cs; c_cs++)
+ cs_mask = cs_mask | 1 << (20 + c_cs);
+
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, 0,
+ TRAINING_REG, (0x80000008 | cs_mask),
+ 0xffffffff));
+ mdelay(20);
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
+ (u32)0x80000000, TRAINING_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("polling failed for Old WL result\n"));
+ return MV_FAIL;
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Legacy Dynamic read leveling
+ */
+int ddr3_tip_legacy_dynamic_read_leveling(u32 dev_num)
+{
+ u32 c_cs, if_id, cs_mask = 0;
+ u32 max_cs = hws_ddr3_tip_max_cs_get();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /*
+ * In TRAINIUNG reg (0x15b0) write 0x80000040 | cs_mask:
+ * Trn_start
+ * cs_mask = 0x1 <<20 Trn_CS0 - CS0 is included in the DDR3 training
+ * cs_mask = 0x1 <<21 Trn_CS1 - CS1 is included in the DDR3 training
+ * cs_mask = 0x1 <<22 Trn_CS2 - CS2 is included in the DDR3 training
+ * cs_mask = 0x1 <<23 Trn_CS3 - CS3 is included in the DDR3 training
+ * Trn_auto_seq = Read Leveling using training pattern
+ */
+ for (c_cs = 0; c_cs < max_cs; c_cs++)
+ cs_mask = cs_mask | 1 << (20 + c_cs);
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, 0, TRAINING_REG,
+ (0x80000040 | cs_mask), 0xffffffff));
+ mdelay(100);
+
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0,
+ (u32)0x80000000, TRAINING_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("polling failed for Old RL result\n"));
+ return MV_FAIL;
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Dynamic per bit read leveling
+ */
+int ddr3_tip_dynamic_per_bit_read_leveling(u32 dev_num, u32 freq)
+{
+ u32 data, mask;
+ u32 bus_num, if_id, cl_val, bit_num;
+ u32 curr_numb, curr_min_delay;
+ int adll_array[3] = { 0, -0xa, 0x14 };
+ u32 phyreg3_arr[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+ enum hws_speed_bin speed_bin_index;
+ int is_any_pup_fail = 0;
+ int break_loop = 0;
+ u32 cs_enable_reg_val[MAX_INTERFACE_NUM]; /* save current CS value */
+ u32 data_read[MAX_INTERFACE_NUM];
+ int per_bit_rl_pup_status[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+ u32 data2_write[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+ struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+ u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_num = 0;
+ bus_num <= tm->num_of_bus_per_interface; bus_num++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+ per_bit_rl_pup_status[if_id][bus_num] = 0;
+ data2_write[if_id][bus_num] = 0;
+ /* read current value of phy register 0x3 */
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST,
+ bus_num, DDR_PHY_DATA,
+ READ_CENTRALIZATION_PHY_REG,
+ &phyreg3_arr[if_id][bus_num]));
+ }
+ }
+
+ /* NEW RL machine */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ training_result[training_stage][if_id] = TEST_SUCCESS;
+
+ /* save current cs enable reg val */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, &cs_enable_reg_val[if_id],
+ MASK_ALL_BITS));
+ /* enable single cs */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, (1 << 3), (1 << 3)));
+ }
+
+ ddr3_tip_reset_fifo_ptr(dev_num);
+ for (curr_numb = 0; curr_numb < 3; curr_numb++) {
+ /*
+ * Phase 1: Load pattern (using ODPG)
+ *
+ * enter Read Leveling mode
+ * only 27 bits are masked
+ * assuming non multi-CS configuration
+ * write to CS = 0 for the non multi CS configuration, note that
+ * the results shall be read back to the required CS !!!
+ */
+
+ /* BUS count is 0 shifted 26 */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0x3, 0x3));
+ CHECK_STATUS(ddr3_tip_configure_odpg
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0,
+ pattern_table[PATTERN_TEST].num_of_phases_tx, 0,
+ pattern_table[PATTERN_TEST].num_of_phases_rx, 0,
+ 0, 0, STRESS_NONE, DURATION_SINGLE));
+
+ /* load pattern to ODPG */
+ ddr3_tip_load_pattern_to_odpg(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, PATTERN_TEST,
+ pattern_table[PATTERN_TEST].
+ start_addr);
+
+ /*
+ * Phase 2: ODPG to Read Leveling mode
+ */
+
+ /* General Training Opcode register */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_WRITE_READ_MODE_ENABLE_REG, 0,
+ MASK_ALL_BITS));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_TRAINING_CONTROL_REG, 0x301b01, 0x3c3fef));
+
+ /* Object1 opcode register 0 & 1 */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ speed_bin_index =
+ tm->interface_params[if_id].speed_bin_index;
+ cl_val =
+ cas_latency_table[speed_bin_index].cl_val[freq];
+ data = (cl_val << 17) | (0x3 << 25);
+ mask = (0xff << 9) | (0x1f << 17) | (0x3 << 25);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ODPG_OBJ1_OPCODE_REG, data, mask));
+ }
+
+ /* Set iteration count to max value */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_OPCODE_1_REG, 0xd00, 0xd00));
+
+ /*
+ * Phase 2: Mask config
+ */
+
+ ddr3_tip_dynamic_per_bit_read_leveling_seq(dev_num);
+
+ /*
+ * Phase 3: Read Leveling execution
+ */
+
+ /* temporary jira dunit=14751 */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_DBG_1_REG, 0, (u32)(1 << 31)));
+ /* configure phy reset value */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_DBG_3_REG, (0x7f << 24),
+ (u32)(0xff << 24)));
+ /* data pup rd reset enable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ SDRAM_CONFIGURATION_REG, 0, (1 << 30)));
+ /* data pup rd reset disable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ SDRAM_CONFIGURATION_REG, (1 << 30), (1 << 30)));
+ /* training SW override & training RL mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x1, 0x9));
+ /* training enable */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_REG, (1 << 24) | (1 << 20),
+ (1 << 24) | (1 << 20)));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_REG, (u32)(1 << 31), (u32)(1 << 31)));
+
+ /********* trigger training *******************/
+ /* Trigger, poll on status and disable ODPG */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_TRAINING_STATUS_REG, 0x1, 0x1));
+
+ /*check for training done + results pass */
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x2, 0x2,
+ ODPG_TRAINING_STATUS_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("Training Done Failed\n"));
+ return MV_FAIL;
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id,
+ ODPG_TRAINING_TRIGGER_REG, data_read,
+ 0x4));
+ data = data_read[if_id];
+ if (data != 0x0) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("Training Result Failed\n"));
+ }
+ }
+
+ /*disable ODPG - Back to functional mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_ENABLE_REG, 0x1 << ODPG_DISABLE_OFFS,
+ (0x1 << ODPG_DISABLE_OFFS)));
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x0, 0x1,
+ ODPG_ENABLE_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("ODPG disable failed "));
+ return MV_FAIL;
+ }
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0, MASK_ALL_BITS));
+
+ /* double loop on bus, pup */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* check training done */
+ for (bus_num = 0;
+ bus_num < tm->num_of_bus_per_interface;
+ bus_num++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+
+ if (per_bit_rl_pup_status[if_id][bus_num]
+ == 0) {
+ curr_min_delay = 0;
+ for (bit_num = 0; bit_num < 8;
+ bit_num++) {
+ if (ddr3_tip_if_polling
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id, (1 << 25),
+ (1 << 25),
+ mask_results_dq_reg_map
+ [bus_num * 8 + bit_num],
+ MAX_POLLING_ITERATIONS) !=
+ MV_OK) {
+ DEBUG_LEVELING
+ (DEBUG_LEVEL_ERROR,
+ ("\n_r_l: DDR3 poll failed(2) for bus %d bit %d\n",
+ bus_num,
+ bit_num));
+ } else {
+ /* read result per pup */
+ CHECK_STATUS
+ (ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ mask_results_dq_reg_map
+ [bus_num * 8 +
+ bit_num],
+ data_read,
+ MASK_ALL_BITS));
+ data =
+ (data_read
+ [if_id] &
+ 0x1f) |
+ ((data_read
+ [if_id] &
+ 0xe0) << 1);
+ if (curr_min_delay == 0)
+ curr_min_delay =
+ data;
+ else if (data <
+ curr_min_delay)
+ curr_min_delay =
+ data;
+ if (data > data2_write[if_id][bus_num])
+ data2_write
+ [if_id]
+ [bus_num] =
+ data;
+ }
+ }
+
+ if (data2_write[if_id][bus_num] <=
+ (curr_min_delay +
+ MAX_DQ_READ_LEVELING_DELAY)) {
+ per_bit_rl_pup_status[if_id]
+ [bus_num] = 1;
+ }
+ }
+ }
+ }
+
+ /* check if there is need to search new phyreg3 value */
+ if (curr_numb < 2) {
+ /* if there is DLL that is not checked yet */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_num = 0;
+ bus_num < tm->num_of_bus_per_interface;
+ bus_num++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask,
+ bus_num);
+ if (per_bit_rl_pup_status[if_id]
+ [bus_num] != 1) {
+ /* go to next ADLL value */
+ CHECK_STATUS
+ (ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_num, DDR_PHY_DATA,
+ READ_CENTRALIZATION_PHY_REG,
+ (phyreg3_arr[if_id]
+ [bus_num] +
+ adll_array[curr_numb])));
+ break_loop = 1;
+ break;
+ }
+ }
+ if (break_loop)
+ break;
+ }
+ } /* if (curr_numb < 2) */
+ if (!break_loop)
+ break;
+ } /* for ( curr_numb = 0; curr_numb <3; curr_numb++) */
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_num = 0; bus_num < tm->num_of_bus_per_interface;
+ bus_num++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_num);
+ if (per_bit_rl_pup_status[if_id][bus_num] == 1)
+ ddr3_tip_bus_write(dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_num, DDR_PHY_DATA,
+ RL_PHY_REG +
+ CS_REG_VALUE(effective_cs),
+ data2_write[if_id]
+ [bus_num]);
+ else
+ is_any_pup_fail = 1;
+ }
+
+ /* TBD flow does not support multi CS */
+ /*
+ * cs_bitmask = tm->interface_params[if_id].
+ * as_bus_params[bus_num].cs_bitmask;
+ */
+ /* divide by 4 is used for retrieving the CS number */
+ /*
+ * TBD BC2 - what is the PHY address for other
+ * CS ddr3_tip_write_cs_result() ???
+ */
+ /*
+ * find what should be written to PHY
+ * - max delay that is less than threshold
+ */
+ if (is_any_pup_fail == 1) {
+ training_result[training_stage][if_id] = TEST_FAILED;
+ if (debug_mode == 0)
+ return MV_FAIL;
+ }
+ }
+ DEBUG_LEVELING(DEBUG_LEVEL_INFO, ("RL exit read leveling\n"));
+
+ /*
+ * Phase 3: Exit Read Leveling
+ */
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, (1 << 3), (1 << 3)));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_1_REG, (1 << 16), (1 << 16)));
+ /* set ODPG to functional */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
+ /*
+ * Copy the result from the effective CS search to the real
+ * Functional CS
+ */
+ ddr3_tip_write_cs_result(dev_num, RL_PHY_REG);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_DATA_CONTROL_REG, 0x0, MASK_ALL_BITS));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* restore cs enable value */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, cs_enable_reg_val[if_id],
+ MASK_ALL_BITS));
+ if (odt_config != 0) {
+ CHECK_STATUS(ddr3_tip_write_additional_odt_setting
+ (dev_num, if_id));
+ }
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (training_result[training_stage][if_id] == TEST_FAILED)
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+int ddr3_tip_calc_cs_mask(u32 dev_num, u32 if_id, u32 effective_cs,
+ u32 *cs_mask)
+{
+ u32 all_bus_cs = 0, same_bus_cs;
+ u32 bus_cnt;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ *cs_mask = same_bus_cs = CS_BIT_MASK;
+
+ /*
+ * In some of the devices (such as BC2), the CS is per pup and there
+ * for mixed mode is valid on like other devices where CS configuration
+ * is per interface.
+ * In order to know that, we do 'Or' and 'And' operation between all
+ * CS (of the pups).
+ * If they are they are not the same then it's mixed mode so all CS
+ * should be configured (when configuring the MRS)
+ */
+ for (bus_cnt = 0; bus_cnt < tm->num_of_bus_per_interface; bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+
+ all_bus_cs |= tm->interface_params[if_id].
+ as_bus_params[bus_cnt].cs_bitmask;
+ same_bus_cs &= tm->interface_params[if_id].
+ as_bus_params[bus_cnt].cs_bitmask;
+
+ /* cs enable is active low */
+ *cs_mask &= ~tm->interface_params[if_id].
+ as_bus_params[bus_cnt].cs_bitmask;
+ }
+
+ if (all_bus_cs == same_bus_cs)
+ *cs_mask = (*cs_mask | (~(1 << effective_cs))) & CS_BIT_MASK;
+
+ return MV_OK;
+}
+
+/*
+ * Dynamic write leveling
+ */
+int ddr3_tip_dynamic_write_leveling(u32 dev_num)
+{
+ u32 reg_data = 0, iter, if_id, bus_cnt;
+ u32 cs_enable_reg_val[MAX_INTERFACE_NUM] = { 0 };
+ u32 cs_mask[MAX_INTERFACE_NUM];
+ u32 read_data_sample_delay_vals[MAX_INTERFACE_NUM] = { 0 };
+ u32 read_data_ready_delay_vals[MAX_INTERFACE_NUM] = { 0 };
+ /* 0 for failure */
+ u32 res_values[MAX_INTERFACE_NUM * MAX_BUS_NUM] = { 0 };
+ u32 test_res = 0; /* 0 - success for all pup */
+ u32 data_read[MAX_INTERFACE_NUM];
+ u8 wl_values[NUM_OF_CS][MAX_BUS_NUM][MAX_INTERFACE_NUM];
+ u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
+ u32 cs_mask0[MAX_INTERFACE_NUM] = { 0 };
+ u32 max_cs = hws_ddr3_tip_max_cs_get();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+
+ training_result[training_stage][if_id] = TEST_SUCCESS;
+
+ /* save Read Data Sample Delay */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ READ_DATA_SAMPLE_DELAY,
+ read_data_sample_delay_vals, MASK_ALL_BITS));
+ /* save Read Data Ready Delay */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ READ_DATA_READY_DELAY, read_data_ready_delay_vals,
+ MASK_ALL_BITS));
+ /* save current cs reg val */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
+ }
+
+ /*
+ * Phase 1: DRAM 2 Write Leveling mode
+ */
+
+ /*Assert 10 refresh commands to DRAM to all CS */
+ for (iter = 0; iter < WL_ITERATION_NUM; iter++) {
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, SDRAM_OPERATION_REG,
+ (u32)((~(0xf) << 8) | 0x2), 0xf1f));
+ }
+ }
+ /* check controller back to normal */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, 0, 0x1f,
+ SDRAM_OPERATION_REG, MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("WL: DDR3 poll failed(3)"));
+ }
+ }
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ /*enable write leveling to all cs - Q off , WL n */
+ /* calculate interface cs mask */
+ CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MRS1_CMD,
+ 0x1000, 0x1080));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* cs enable is active low */
+ ddr3_tip_calc_cs_mask(dev_num, if_id, effective_cs,
+ &cs_mask[if_id]);
+ }
+
+ /* Enable Output buffer to relevant CS - Q on , WL on */
+ CHECK_STATUS(ddr3_tip_write_mrs_cmd
+ (dev_num, cs_mask, MRS1_CMD, 0x80, 0x1080));
+
+ /*enable odt for relevant CS */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ 0x1498, (0x3 << (effective_cs * 2)), 0xf));
+
+ /*
+ * Phase 2: Set training IP to write leveling mode
+ */
+
+ CHECK_STATUS(ddr3_tip_dynamic_write_leveling_seq(dev_num));
+
+ /*
+ * Phase 3: Trigger training
+ */
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_TRAINING_TRIGGER_REG, 0x1, 0x1));
+
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+
+ /* training done */
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ (1 << 1), (1 << 1), ODPG_TRAINING_STATUS_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_ERROR,
+ ("WL: DDR3 poll (4) failed (Data: 0x%x)\n",
+ reg_data));
+ }
+#if !defined(CONFIG_ARMADA_38X) /*Disabled. JIRA #1498 */
+ else {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id,
+ ODPG_TRAINING_TRIGGER_REG,
+ ®_data, (1 << 2)));
+ if (reg_data != 0) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_ERROR,
+ ("WL: WL failed IF %d reg_data=0x%x\n",
+ if_id, reg_data));
+ }
+ }
+#endif
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* training done */
+ if (ddr3_tip_if_polling
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ (1 << 1), (1 << 1), ODPG_TRAINING_STATUS_REG,
+ MAX_POLLING_ITERATIONS) != MV_OK) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_ERROR,
+ ("WL: DDR3 poll (4) failed (Data: 0x%x)\n",
+ reg_data));
+ } else {
+#if !defined(CONFIG_ARMADA_38X) /*Disabled. JIRA #1498 */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id,
+ ODPG_TRAINING_STATUS_REG,
+ data_read, (1 << 2)));
+ reg_data = data_read[if_id];
+ if (reg_data != 0) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_ERROR,
+ ("WL: WL failed IF %d reg_data=0x%x\n",
+ if_id, reg_data));
+ }
+#endif
+
+ /* check for training completion per bus */
+ for (bus_cnt = 0;
+ bus_cnt < tm->num_of_bus_per_interface;
+ bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask,
+ bus_cnt);
+ /* training status */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ mask_results_pup_reg_map
+ [bus_cnt], data_read,
+ (1 << 25)));
+ reg_data = data_read[if_id];
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("WL: IF %d BUS %d reg 0x%x\n",
+ if_id, bus_cnt, reg_data));
+ if (reg_data == 0) {
+ res_values[
+ (if_id *
+ tm->num_of_bus_per_interface)
+ + bus_cnt] = 1;
+ }
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ mask_results_pup_reg_map
+ [bus_cnt], data_read,
+ 0xff));
+ /*
+ * Save the read value that should be
+ * write to PHY register
+ */
+ wl_values[effective_cs]
+ [bus_cnt][if_id] =
+ (u8)data_read[if_id];
+ }
+ }
+ }
+
+ /*
+ * Phase 4: Exit write leveling mode
+ */
+
+ /* disable DQs toggling */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ WR_LEVELING_DQS_PATTERN_REG, 0x0, 0x1));
+
+ /* Update MRS 1 (WL off) */
+ CHECK_STATUS(ddr3_tip_write_mrs_cmd(dev_num, cs_mask0, MRS1_CMD,
+ 0x1000, 0x1080));
+
+ /* Update MRS 1 (return to functional mode - Q on , WL off) */
+ CHECK_STATUS(ddr3_tip_write_mrs_cmd
+ (dev_num, cs_mask0, MRS1_CMD, 0x0, 0x1080));
+
+ /* set phy to normal mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x5, 0x7));
+
+ /* exit sw override mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x4, 0x7));
+ }
+
+ /*
+ * Phase 5: Load WL values to each PHY
+ */
+
+ for (effective_cs = 0; effective_cs < max_cs; effective_cs++) {
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ test_res = 0;
+ for (bus_cnt = 0;
+ bus_cnt < tm->num_of_bus_per_interface;
+ bus_cnt++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_cnt);
+ /* check if result == pass */
+ if (res_values
+ [(if_id *
+ tm->num_of_bus_per_interface) +
+ bus_cnt] == 0) {
+ /*
+ * read result control register
+ * according to pup
+ */
+ reg_data =
+ wl_values[effective_cs][bus_cnt]
+ [if_id];
+ /*
+ * Write into write leveling register
+ * ([4:0] ADLL, [8:6] Phase, [15:10]
+ * (centralization) ADLL + 0x10)
+ */
+ reg_data =
+ (reg_data & 0x1f) |
+ (((reg_data & 0xe0) >> 5) << 6) |
+ (((reg_data & 0x1f) +
+ phy_reg1_val) << 10);
+ ddr3_tip_bus_write(
+ dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST,
+ bus_cnt,
+ DDR_PHY_DATA,
+ WL_PHY_REG +
+ effective_cs *
+ CS_REGISTER_ADDR_OFFSET,
+ reg_data);
+ } else {
+ test_res = 1;
+ /*
+ * read result control register
+ * according to pup
+ */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ mask_results_pup_reg_map
+ [bus_cnt], data_read,
+ 0xff));
+ reg_data = data_read[if_id];
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_ERROR,
+ ("WL: IF %d BUS %d failed, reg 0x%x\n",
+ if_id, bus_cnt, reg_data));
+ }
+ }
+
+ if (test_res != 0) {
+ training_result[training_stage][if_id] =
+ TEST_FAILED;
+ }
+ }
+ }
+ /* Set to 0 after each loop to avoid illegal value may be used */
+ effective_cs = 0;
+
+ /*
+ * Copy the result from the effective CS search to the real
+ * Functional CS
+ */
+ /* ddr3_tip_write_cs_result(dev_num, WL_PHY_REG); */
+ /* restore saved values */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* restore Read Data Sample Delay */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ READ_DATA_SAMPLE_DELAY,
+ read_data_sample_delay_vals[if_id],
+ MASK_ALL_BITS));
+
+ /* restore Read Data Ready Delay */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ READ_DATA_READY_DELAY,
+ read_data_ready_delay_vals[if_id],
+ MASK_ALL_BITS));
+
+ /* enable multi cs */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, cs_enable_reg_val[if_id],
+ MASK_ALL_BITS));
+ }
+
+ /* Disable modt0 for CS0 training - need to adjust for multy CS */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, 0x1498,
+ 0x0, 0xf));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (training_result[training_stage][if_id] == TEST_FAILED)
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Dynamic write leveling supplementary
+ */
+int ddr3_tip_dynamic_write_leveling_supp(u32 dev_num)
+{
+ int adll_offset;
+ u32 if_id, bus_id, data, data_tmp;
+ int is_if_fail = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ is_if_fail = 0;
+
+ for (bus_id = 0; bus_id < GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ wr_supp_res[if_id][bus_id].is_pup_fail = 1;
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG +
+ effective_cs * CS_REGISTER_ADDR_OFFSET,
+ &data));
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("WL Supp: adll_offset=0 data delay = %d\n",
+ data));
+ if (ddr3_tip_wl_supp_align_phase_shift
+ (dev_num, if_id, bus_id, 0, 0) == MV_OK) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("WL Supp: IF %d bus_id %d adll_offset=0 Success !\n",
+ if_id, bus_id));
+ continue;
+ }
+
+ /* change adll */
+ adll_offset = 5;
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG +
+ effective_cs * CS_REGISTER_ADDR_OFFSET,
+ data + adll_offset));
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG +
+ effective_cs * CS_REGISTER_ADDR_OFFSET,
+ &data_tmp));
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("WL Supp: adll_offset= %d data delay = %d\n",
+ adll_offset, data_tmp));
+
+ if (ddr3_tip_wl_supp_align_phase_shift
+ (dev_num, if_id, bus_id, adll_offset, 0) == MV_OK) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("WL Supp: IF %d bus_id %d adll_offset= %d Success !\n",
+ if_id, bus_id, adll_offset));
+ continue;
+ }
+
+ /* change adll */
+ adll_offset = -5;
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, bus_id, DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG +
+ effective_cs * CS_REGISTER_ADDR_OFFSET,
+ data + adll_offset));
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA,
+ WRITE_CENTRALIZATION_PHY_REG +
+ effective_cs * CS_REGISTER_ADDR_OFFSET,
+ &data_tmp));
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("WL Supp: adll_offset= %d data delay = %d\n",
+ adll_offset, data_tmp));
+ if (ddr3_tip_wl_supp_align_phase_shift
+ (dev_num, if_id, bus_id, adll_offset, 0) == MV_OK) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("WL Supp: IF %d bus_id %d adll_offset= %d Success !\n",
+ if_id, bus_id, adll_offset));
+ continue;
+ } else {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_ERROR,
+ ("WL Supp: IF %d bus_id %d Failed !\n",
+ if_id, bus_id));
+ is_if_fail = 1;
+ }
+ }
+ DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+ ("WL Supp: IF %d bus_id %d is_pup_fail %d\n",
+ if_id, bus_id, is_if_fail));
+
+ if (is_if_fail == 1) {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("WL Supp: IF %d failed\n", if_id));
+ training_result[training_stage][if_id] = TEST_FAILED;
+ } else {
+ training_result[training_stage][if_id] = TEST_SUCCESS;
+ }
+ }
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (training_result[training_stage][if_id] == TEST_FAILED)
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Phase Shift
+ */
+static int ddr3_tip_wl_supp_align_phase_shift(u32 dev_num, u32 if_id,
+ u32 bus_id, u32 offset,
+ u32 bus_id_delta)
+{
+ wr_supp_res[if_id][bus_id].stage = PHASE_SHIFT;
+ if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
+ 0, bus_id_delta) == MV_OK) {
+ wr_supp_res[if_id][bus_id].is_pup_fail = 0;
+ return MV_OK;
+ } else if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
+ ONE_CLOCK_ERROR_SHIFT,
+ bus_id_delta) == MV_OK) {
+ /* 1 clock error */
+ wr_supp_res[if_id][bus_id].stage = CLOCK_SHIFT;
+ DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+ ("Supp: 1 error clock for if %d pup %d with ofsset %d success\n",
+ if_id, bus_id, offset));
+ ddr3_tip_wl_supp_one_clk_err_shift(dev_num, if_id, bus_id, 0);
+ wr_supp_res[if_id][bus_id].is_pup_fail = 0;
+ return MV_OK;
+ } else if (ddr3_tip_xsb_compare_test(dev_num, if_id, bus_id,
+ ALIGN_ERROR_SHIFT,
+ bus_id_delta) == MV_OK) {
+ /* align error */
+ DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+ ("Supp: align error for if %d pup %d with ofsset %d success\n",
+ if_id, bus_id, offset));
+ wr_supp_res[if_id][bus_id].stage = ALIGN_SHIFT;
+ ddr3_tip_wl_supp_align_err_shift(dev_num, if_id, bus_id, 0);
+ wr_supp_res[if_id][bus_id].is_pup_fail = 0;
+ return MV_OK;
+ } else {
+ wr_supp_res[if_id][bus_id].is_pup_fail = 1;
+ return MV_FAIL;
+ }
+}
+
+/*
+ * Compare Test
+ */
+static int ddr3_tip_xsb_compare_test(u32 dev_num, u32 if_id, u32 bus_id,
+ u32 edge_offset, u32 bus_id_delta)
+{
+ u32 num_of_succ_byte_compare, word_in_pattern, abs_offset;
+ u32 word_offset, i;
+ u32 read_pattern[TEST_PATTERN_LENGTH * 2];
+ struct pattern_info *pattern_table = ddr3_tip_get_pattern_table();
+ u32 pattern_test_pattern_table[8];
+
+ for (i = 0; i < 8; i++) {
+ pattern_test_pattern_table[i] =
+ pattern_table_get_word(dev_num, PATTERN_TEST, (u8)i);
+ }
+
+ /* extern write, than read and compare */
+ CHECK_STATUS(ddr3_tip_ext_write
+ (dev_num, if_id,
+ (pattern_table[PATTERN_TEST].start_addr +
+ ((SDRAM_CS_SIZE + 1) * effective_cs)), 1,
+ pattern_test_pattern_table));
+
+ CHECK_STATUS(ddr3_tip_reset_fifo_ptr(dev_num));
+
+ CHECK_STATUS(ddr3_tip_ext_read
+ (dev_num, if_id,
+ (pattern_table[PATTERN_TEST].start_addr +
+ ((SDRAM_CS_SIZE + 1) * effective_cs)), 1, read_pattern));
+
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("XSB-compt: IF %d bus_id %d 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ if_id, bus_id, read_pattern[0], read_pattern[1],
+ read_pattern[2], read_pattern[3], read_pattern[4],
+ read_pattern[5], read_pattern[6], read_pattern[7]));
+
+ /* compare byte per pup */
+ num_of_succ_byte_compare = 0;
+ for (word_in_pattern = start_xsb_offset;
+ word_in_pattern < (TEST_PATTERN_LENGTH * 2); word_in_pattern++) {
+ word_offset = word_in_pattern + edge_offset;
+ if ((word_offset > (TEST_PATTERN_LENGTH * 2 - 1)) ||
+ (word_offset < 0))
+ continue;
+
+ if ((read_pattern[word_in_pattern] & pup_mask_table[bus_id]) ==
+ (pattern_test_pattern_table[word_offset] &
+ pup_mask_table[bus_id]))
+ num_of_succ_byte_compare++;
+ }
+
+ abs_offset = (edge_offset > 0) ? edge_offset : -edge_offset;
+ if (num_of_succ_byte_compare == ((TEST_PATTERN_LENGTH * 2) -
+ abs_offset - start_xsb_offset)) {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Success\n",
+ if_id, bus_id, num_of_succ_byte_compare));
+ return MV_OK;
+ } else {
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Fail !\n",
+ if_id, bus_id, num_of_succ_byte_compare));
+
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("XSB-compt: expected 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ pattern_test_pattern_table[0],
+ pattern_test_pattern_table[1],
+ pattern_test_pattern_table[2],
+ pattern_test_pattern_table[3],
+ pattern_test_pattern_table[4],
+ pattern_test_pattern_table[5],
+ pattern_test_pattern_table[6],
+ pattern_test_pattern_table[7]));
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("XSB-compt: recieved 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
+ read_pattern[0], read_pattern[1],
+ read_pattern[2], read_pattern[3],
+ read_pattern[4], read_pattern[5],
+ read_pattern[6], read_pattern[7]));
+
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("XSB-compt: IF %d bus_id %d num_of_succ_byte_compare %d - Fail !\n",
+ if_id, bus_id, num_of_succ_byte_compare));
+
+ return MV_FAIL;
+ }
+}
+
+/*
+ * Clock error shift - function moves the write leveling delay 1cc forward
+ */
+static int ddr3_tip_wl_supp_one_clk_err_shift(u32 dev_num, u32 if_id,
+ u32 bus_id, u32 bus_id_delta)
+{
+ int phase, adll;
+ u32 data;
+ DEBUG_LEVELING(DEBUG_LEVEL_TRACE, ("One_clk_err_shift\n"));
+
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id, ACCESS_TYPE_UNICAST, bus_id,
+ DDR_PHY_DATA, WL_PHY_REG, &data));
+ phase = ((data >> 6) & 0x7);
+ adll = data & 0x1f;
+ DEBUG_LEVELING(DEBUG_LEVEL_TRACE,
+ ("One_clk_err_shift: IF %d bus_id %d phase %d adll %d\n",
+ if_id, bus_id, phase, adll));
+
+ if ((phase == 0) || (phase == 1)) {
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, bus_id,
+ DDR_PHY_DATA, 0, (phase + 2), 0x1f));
+ } else if (phase == 2) {
+ if (adll < 6) {
+ data = (3 << 6) + (0x1f);
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ bus_id, DDR_PHY_DATA, 0, data,
+ (0x7 << 6 | 0x1f)));
+ data = 0x2f;
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ bus_id, DDR_PHY_DATA, 1, data, 0x3f));
+ }
+ } else {
+ /* phase 3 */
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Align error shift
+ */
+static int ddr3_tip_wl_supp_align_err_shift(u32 dev_num, u32 if_id,
+ u32 bus_id, u32 bus_id_delta)
+{
+ int phase, adll;
+ u32 data;
+
+ /* Shift WL result 1 phase back */
+ CHECK_STATUS(ddr3_tip_bus_read(dev_num, if_id, ACCESS_TYPE_UNICAST,
+ bus_id, DDR_PHY_DATA, WL_PHY_REG,
+ &data));
+ phase = ((data >> 6) & 0x7);
+ adll = data & 0x1f;
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_TRACE,
+ ("Wl_supp_align_err_shift: IF %d bus_id %d phase %d adll %d\n",
+ if_id, bus_id, phase, adll));
+
+ if (phase < 2) {
+ if (adll > 0x1a) {
+ if (phase == 0)
+ return MV_FAIL;
+
+ if (phase == 1) {
+ data = 0;
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, bus_id, DDR_PHY_DATA,
+ 0, data, (0x7 << 6 | 0x1f)));
+ data = 0xf;
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, bus_id, DDR_PHY_DATA,
+ 1, data, 0x1f));
+ return MV_OK;
+ }
+ } else {
+ return MV_FAIL;
+ }
+ } else if ((phase == 2) || (phase == 3)) {
+ phase = phase - 2;
+ data = (phase << 6) + (adll & 0x1f);
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id, bus_id,
+ DDR_PHY_DATA, 0, data, (0x7 << 6 | 0x1f)));
+ return MV_OK;
+ } else {
+ DEBUG_LEVELING(DEBUG_LEVEL_ERROR,
+ ("Wl_supp_align_err_shift: unexpected phase\n"));
+
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Dynamic write leveling sequence
+ */
+static int ddr3_tip_dynamic_write_leveling_seq(u32 dev_num)
+{
+ u32 bus_id, dq_id;
+ u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
+ u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_SW_2_REG, 0x1, 0x5));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_WRITE_LEVELING_REG, 0x50, 0xff));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_WRITE_LEVELING_REG, 0x5c, 0xff));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_TRAINING_CONTROL_REG, 0x381b82, 0x3c3faf));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_OBJ1_OPCODE_REG, (0x3 << 25), (0x3ffff << 9)));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_OBJ1_ITER_CNT_REG, 0x80, 0xffff));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_WRITE_LEVELING_DONE_CNTR_REG, 0x14, 0xff));
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ TRAINING_WRITE_LEVELING_REG, 0xff5c, 0xffff));
+
+ /* mask PBS */
+ for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_dq_reg_map[dq_id], 0x1 << 24,
+ 0x1 << 24));
+ }
+
+ /* Mask all results */
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_pup_reg_map[bus_id], 0x1 << 24,
+ 0x1 << 24));
+ }
+
+ /* Unmask only wanted */
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_pup_reg_map[bus_id], 0, 0x1 << 24));
+ }
+
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ WR_LEVELING_DQS_PATTERN_REG, 0x1, 0x1));
+
+ return MV_OK;
+}
+
+/*
+ * Dynamic read leveling sequence
+ */
+static int ddr3_tip_dynamic_read_leveling_seq(u32 dev_num)
+{
+ u32 bus_id, dq_id;
+ u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
+ u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* mask PBS */
+ for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_dq_reg_map[dq_id], 0x1 << 24,
+ 0x1 << 24));
+ }
+
+ /* Mask all results */
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_pup_reg_map[bus_id], 0x1 << 24,
+ 0x1 << 24));
+ }
+
+ /* Unmask only wanted */
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_pup_reg_map[bus_id], 0, 0x1 << 24));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Dynamic read leveling sequence
+ */
+static int ddr3_tip_dynamic_per_bit_read_leveling_seq(u32 dev_num)
+{
+ u32 bus_id, dq_id;
+ u16 *mask_results_pup_reg_map = ddr3_tip_get_mask_results_pup_reg_map();
+ u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* mask PBS */
+ for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_dq_reg_map[dq_id], 0x1 << 24,
+ 0x1 << 24));
+ }
+
+ /* Mask all results */
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface; bus_id++) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_pup_reg_map[bus_id], 0x1 << 24,
+ 0x1 << 24));
+ }
+
+ /* Unmask only wanted */
+ for (dq_id = 0; dq_id < MAX_DQ_NUM; dq_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, dq_id / 8);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ mask_results_dq_reg_map[dq_id], 0x0 << 24,
+ 0x1 << 24));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Print write leveling supplementary results
+ */
+int ddr3_tip_print_wl_supp_result(u32 dev_num)
+{
+ u32 bus_id = 0, if_id = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ DEBUG_LEVELING(DEBUG_LEVEL_INFO,
+ ("I/F0 PUP0 Result[0 - success, 1-fail] ...\n"));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ DEBUG_LEVELING(DEBUG_LEVEL_INFO,
+ ("%d ,", wr_supp_res[if_id]
+ [bus_id].is_pup_fail));
+ }
+ }
+ DEBUG_LEVELING(
+ DEBUG_LEVEL_INFO,
+ ("I/F0 PUP0 Stage[0-phase_shift, 1-clock_shift, 2-align_shift] ...\n"));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_id = 0; bus_id < tm->num_of_bus_per_interface;
+ bus_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_id);
+ DEBUG_LEVELING(DEBUG_LEVEL_INFO,
+ ("%d ,", wr_supp_res[if_id]
+ [bus_id].stage));
+ }
+ }
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR3_TRAINING_LEVELING_H_
+#define _DDR3_TRAINING_LEVELING_H_
+
+#define MAX_DQ_READ_LEVELING_DELAY 15
+
+int ddr3_tip_print_wl_supp_result(u32 dev_num);
+int ddr3_tip_calc_cs_mask(u32 dev_num, u32 if_id, u32 effective_cs,
+ u32 *cs_mask);
+u32 hws_ddr3_tip_max_cs_get(void);
+
+#endif /* _DDR3_TRAINING_LEVELING_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+#define TYPICAL_PBS_VALUE 12
+
+u32 nominal_adll[MAX_INTERFACE_NUM * MAX_BUS_NUM];
+enum hws_training_ip_stat train_status[MAX_INTERFACE_NUM];
+u8 result_mat[MAX_INTERFACE_NUM][MAX_BUS_NUM][BUS_WIDTH_IN_BITS];
+u8 result_mat_rx_dqs[MAX_INTERFACE_NUM][MAX_BUS_NUM][MAX_CS_NUM];
+/* 4-EEWA, 3-EWA, 2-SWA, 1-Fail, 0-Pass */
+u8 result_all_bit[MAX_BUS_NUM * BUS_WIDTH_IN_BITS * MAX_INTERFACE_NUM];
+u8 max_pbs_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u8 min_pbs_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u8 max_adll_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u8 min_adll_per_pup[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u32 pbsdelay_per_pup[NUM_OF_PBS_MODES][MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u8 adll_shift_lock[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+u8 adll_shift_val[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+enum hws_pattern pbs_pattern = PATTERN_VREF;
+static u8 pup_state[MAX_INTERFACE_NUM][MAX_BUS_NUM];
+
+/*
+ * Name: ddr3_tip_pbs
+ * Desc: PBS
+ * Args: TBD
+ * Notes:
+ * Returns: OK if success, other error code if fail.
+ */
+int ddr3_tip_pbs(u32 dev_num, enum pbs_dir pbs_mode)
+{
+ u32 res0[MAX_INTERFACE_NUM];
+ int adll_tap = MEGA / freq_val[medium_freq] / 64;
+ int pad_num = 0;
+ enum hws_search_dir search_dir =
+ (pbs_mode == PBS_RX_MODE) ? HWS_HIGH2LOW : HWS_LOW2HIGH;
+ enum hws_dir dir = (pbs_mode == PBS_RX_MODE) ? OPER_READ : OPER_WRITE;
+ int iterations = (pbs_mode == PBS_RX_MODE) ? 31 : 63;
+ u32 res_valid_mask = (pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
+ int init_val = (search_dir == HWS_LOW2HIGH) ? 0 : iterations;
+ enum hws_edge_compare search_edge = EDGE_FP;
+ u32 pup = 0, bit = 0, if_id = 0, all_lock = 0, cs_num = 0;
+ int reg_addr = 0;
+ u32 validation_val = 0;
+ u32 cs_enable_reg_val[MAX_INTERFACE_NUM];
+ u16 *mask_results_dq_reg_map = ddr3_tip_get_mask_results_dq_reg();
+ u8 temp = 0;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /* save current cs enable reg val */
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+
+ /* save current cs enable reg val */
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, cs_enable_reg_val, MASK_ALL_BITS));
+
+ /* enable single cs */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, (1 << 3), (1 << 3)));
+ }
+
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (READ_CENTRALIZATION_PHY_REG +
+ (effective_cs * CS_REGISTER_ADDR_OFFSET)) :
+ (WRITE_CENTRALIZATION_PHY_REG +
+ (effective_cs * CS_REGISTER_ADDR_OFFSET));
+ read_adll_value(nominal_adll, reg_addr, MASK_ALL_BITS);
+
+ /* stage 1 shift ADLL */
+ ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, RESULT_PER_BIT,
+ HWS_CONTROL_ELEMENT_ADLL, search_dir, dir,
+ tm->if_act_mask, init_val, iterations,
+ pbs_pattern, search_edge, CS_SINGLE, cs_num,
+ train_status);
+ validation_val = (pbs_mode == PBS_RX_MODE) ? 0x1f : 0;
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ min_adll_per_pup[if_id][pup] =
+ (pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
+ pup_state[if_id][pup] = 0x3;
+ adll_shift_lock[if_id][pup] = 1;
+ max_adll_per_pup[if_id][pup] = 0x0;
+ }
+ }
+
+ /* EBA */
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ mask_results_dq_reg_map[
+ bit + pup * BUS_WIDTH_IN_BITS],
+ res0, MASK_ALL_BITS));
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
+ if_id, bit, pup,
+ res0[if_id]));
+ if (pup_state[if_id][pup] != 3)
+ continue;
+ /* if not EBA state than move to next pup */
+
+ if ((res0[if_id] & 0x2000000) == 0) {
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ ("-- Fail Training IP\n"));
+ /* training machine failed */
+ pup_state[if_id][pup] = 1;
+ adll_shift_lock[if_id][pup] = 0;
+ continue;
+ }
+
+ else if ((res0[if_id] & res_valid_mask) ==
+ validation_val) {
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ ("-- FAIL EBA %d %d %d %d\n",
+ if_id, bit, pup,
+ res0[if_id]));
+ pup_state[if_id][pup] = 4;
+ /* this pup move to EEBA */
+ adll_shift_lock[if_id][pup] = 0;
+ continue;
+ } else {
+ /*
+ * The search ended in Pass we need
+ * Fail
+ */
+ res0[if_id] =
+ (pbs_mode == PBS_RX_MODE) ?
+ ((res0[if_id] &
+ res_valid_mask) + 1) :
+ ((res0[if_id] &
+ res_valid_mask) - 1);
+ max_adll_per_pup[if_id][pup] =
+ (max_adll_per_pup[if_id][pup] <
+ res0[if_id]) ?
+ (u8)res0[if_id] :
+ max_adll_per_pup[if_id][pup];
+ min_adll_per_pup[if_id][pup] =
+ (res0[if_id] >
+ min_adll_per_pup[if_id][pup]) ?
+ min_adll_per_pup[if_id][pup] :
+ (u8)
+ res0[if_id];
+ /*
+ * vs the Rx we are searching for the
+ * smallest value of DQ shift so all
+ * Bus would fail
+ */
+ adll_shift_val[if_id][pup] =
+ (pbs_mode == PBS_RX_MODE) ?
+ max_adll_per_pup[if_id][pup] :
+ min_adll_per_pup[if_id][pup];
+ }
+ }
+ }
+ }
+
+ /* EEBA */
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+
+ if (pup_state[if_id][pup] != 4)
+ continue;
+ /*
+ * if pup state different from EEBA than move to
+ * next pup
+ */
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x54 + effective_cs * 0x10) :
+ (0x14 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
+ reg_addr, 0x1f));
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x55 + effective_cs * 0x10) :
+ (0x15 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
+ reg_addr, 0x1f));
+ /* initialize the Edge2 Max. */
+ adll_shift_val[if_id][pup] = 0;
+ min_adll_per_pup[if_id][pup] =
+ (pbs_mode == PBS_RX_MODE) ? 0x1f : 0x3f;
+ max_adll_per_pup[if_id][pup] = 0x0;
+
+ ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, RESULT_PER_BIT,
+ HWS_CONTROL_ELEMENT_ADLL,
+ search_dir, dir,
+ tm->if_act_mask, init_val,
+ iterations, pbs_pattern,
+ search_edge, CS_SINGLE, cs_num,
+ train_status);
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
+ ("ADLL shift results:\n"));
+
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ mask_results_dq_reg_map[
+ bit + pup *
+ BUS_WIDTH_IN_BITS],
+ res0, MASK_ALL_BITS));
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
+ if_id, bit, pup,
+ res0[if_id]));
+
+ if ((res0[if_id] & 0x2000000) == 0) {
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ (" -- EEBA Fail\n"));
+ bit = BUS_WIDTH_IN_BITS;
+ /* exit bit loop */
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ ("-- EEBA Fail Training IP\n"));
+ /*
+ * training machine failed but pass
+ * before in the EBA so maybe the DQS
+ * shift change env.
+ */
+ pup_state[if_id][pup] = 2;
+ adll_shift_lock[if_id][pup] = 0;
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x54 + effective_cs * 0x10) :
+ (0x14 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ 0x0));
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x55 + effective_cs * 0x10) :
+ (0x15 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ 0x0));
+ continue;
+ } else if ((res0[if_id] & res_valid_mask) ==
+ validation_val) {
+ /* exit bit loop */
+ bit = BUS_WIDTH_IN_BITS;
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ ("-- FAIL EEBA\n"));
+ /* this pup move to SBA */
+ pup_state[if_id][pup] = 2;
+ adll_shift_lock[if_id][pup] = 0;
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x54 + effective_cs * 0x10) :
+ (0x14 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ 0x0));
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x55 + effective_cs * 0x10) :
+ (0x15 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num,
+ ACCESS_TYPE_UNICAST,
+ if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ 0x0));
+ continue;
+ } else {
+ adll_shift_lock[if_id][pup] = 1;
+ /*
+ * The search ended in Pass we need
+ * Fail
+ */
+ res0[if_id] =
+ (pbs_mode == PBS_RX_MODE) ?
+ ((res0[if_id] &
+ res_valid_mask) + 1) :
+ ((res0[if_id] &
+ res_valid_mask) - 1);
+ max_adll_per_pup[if_id][pup] =
+ (max_adll_per_pup[if_id][pup] <
+ res0[if_id]) ?
+ (u8)res0[if_id] :
+ max_adll_per_pup[if_id][pup];
+ min_adll_per_pup[if_id][pup] =
+ (res0[if_id] >
+ min_adll_per_pup[if_id][pup]) ?
+ min_adll_per_pup[if_id][pup] :
+ (u8)res0[if_id];
+ /*
+ * vs the Rx we are searching for the
+ * smallest value of DQ shift so all Bus
+ * would fail
+ */
+ adll_shift_val[if_id][pup] =
+ (pbs_mode == PBS_RX_MODE) ?
+ max_adll_per_pup[if_id][pup] :
+ min_adll_per_pup[if_id][pup];
+ }
+ }
+ }
+ }
+
+ /* Print Stage result */
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ ("FP I/F %d, ADLL Shift for EBA: pup[%d] Lock status = %d Lock Val = %d,%d\n",
+ if_id, pup,
+ adll_shift_lock[if_id][pup],
+ max_adll_per_pup[if_id][pup],
+ min_adll_per_pup[if_id][pup]));
+ }
+ }
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
+ ("Update ADLL Shift of all pups:\n"));
+
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (adll_shift_lock[if_id][pup] != 1)
+ continue;
+ /* if pup not locked continue to next pup */
+
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x3 + effective_cs * 4) :
+ (0x1 + effective_cs * 4);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA,
+ reg_addr, adll_shift_val[if_id][pup]));
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_TRACE,
+ ("FP I/F %d, Pup[%d] = %d\n", if_id,
+ pup, adll_shift_val[if_id][pup]));
+ }
+ }
+
+ /* PBS EEBA&EBA */
+ /* Start the Per Bit Skew search */
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ max_pbs_per_pup[if_id][pup] = 0x0;
+ min_pbs_per_pup[if_id][pup] = 0x1f;
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ /* reset result for PBS */
+ result_all_bit[bit + pup * BUS_WIDTH_IN_BITS +
+ if_id * MAX_BUS_NUM *
+ BUS_WIDTH_IN_BITS] = 0;
+ }
+ }
+ }
+
+ iterations = 31;
+ search_dir = HWS_LOW2HIGH;
+ /* !!!!! ran sh (search_dir == HWS_LOW2HIGH)?0:iterations; */
+ init_val = 0;
+
+ ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ RESULT_PER_BIT, HWS_CONTROL_ELEMENT_DQ_SKEW,
+ search_dir, dir, tm->if_act_mask, init_val,
+ iterations, pbs_pattern, search_edge,
+ CS_SINGLE, cs_num, train_status);
+
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (adll_shift_lock[if_id][pup] != 1) {
+ /* if pup not lock continue to next pup */
+ continue;
+ }
+
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ mask_results_dq_reg_map[
+ bit +
+ pup * BUS_WIDTH_IN_BITS],
+ res0, MASK_ALL_BITS));
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
+ ("Per Bit Skew search, FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
+ if_id, bit, pup,
+ res0[if_id]));
+ if ((res0[if_id] & 0x2000000) == 0) {
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
+ ("--EBA PBS Fail - Training IP machine\n"));
+ /* exit the bit loop */
+ bit = BUS_WIDTH_IN_BITS;
+ /*
+ * ADLL is no long in lock need new
+ * search
+ */
+ adll_shift_lock[if_id][pup] = 0;
+ /* Move to SBA */
+ pup_state[if_id][pup] = 2;
+ max_pbs_per_pup[if_id][pup] = 0x0;
+ min_pbs_per_pup[if_id][pup] = 0x1f;
+ continue;
+ } else {
+ temp = (u8)(res0[if_id] &
+ res_valid_mask);
+ max_pbs_per_pup[if_id][pup] =
+ (temp >
+ max_pbs_per_pup[if_id][pup]) ?
+ temp :
+ max_pbs_per_pup[if_id][pup];
+ min_pbs_per_pup[if_id][pup] =
+ (temp <
+ min_pbs_per_pup[if_id][pup]) ?
+ temp :
+ min_pbs_per_pup[if_id][pup];
+ result_all_bit[bit +
+ pup * BUS_WIDTH_IN_BITS +
+ if_id * MAX_BUS_NUM *
+ BUS_WIDTH_IN_BITS] =
+ temp;
+ }
+ }
+ }
+ }
+
+ /* Check all Pup lock */
+ all_lock = 1;
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ all_lock = all_lock * adll_shift_lock[if_id][pup];
+ }
+ }
+
+ /* Only if not all Pups Lock */
+ if (all_lock == 0) {
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
+ ("##########ADLL shift for SBA###########\n"));
+
+ /* ADLL shift for SBA */
+ search_dir = (pbs_mode == PBS_RX_MODE) ? HWS_LOW2HIGH :
+ HWS_HIGH2LOW;
+ init_val = (search_dir == HWS_LOW2HIGH) ? 0 : iterations;
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ if (adll_shift_lock[if_id][pup] == 1) {
+ /*if pup lock continue to next pup */
+ continue;
+ }
+ /*init the var altogth init before */
+ adll_shift_lock[if_id][pup] = 0;
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x54 + effective_cs * 0x10) :
+ (0x14 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr, 0));
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x55 + effective_cs * 0x10) :
+ (0x15 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr, 0));
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x5f + effective_cs * 0x10) :
+ (0x1f + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr, 0));
+ /* initilaze the Edge2 Max. */
+ adll_shift_val[if_id][pup] = 0;
+ min_adll_per_pup[if_id][pup] = 0x1f;
+ max_adll_per_pup[if_id][pup] = 0x0;
+
+ ddr3_tip_ip_training(dev_num,
+ ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ RESULT_PER_BIT,
+ HWS_CONTROL_ELEMENT_ADLL,
+ search_dir, dir,
+ tm->if_act_mask,
+ init_val, iterations,
+ pbs_pattern,
+ search_edge, CS_SINGLE,
+ cs_num, train_status);
+
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ mask_results_dq_reg_map
+ [bit +
+ pup *
+ BUS_WIDTH_IN_BITS],
+ res0, MASK_ALL_BITS));
+ DEBUG_PBS_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("FP I/F %d, bit:%d, pup:%d res0 0x%x\n",
+ if_id, bit, pup, res0[if_id]));
+ if ((res0[if_id] & 0x2000000) == 0) {
+ /* exit the bit loop */
+ bit = BUS_WIDTH_IN_BITS;
+ /* Fail SBA --> Fail PBS */
+ pup_state[if_id][pup] = 1;
+ DEBUG_PBS_ENGINE
+ (DEBUG_LEVEL_INFO,
+ (" SBA Fail\n"));
+ continue;
+ } else {
+ /*
+ * - increment to get all
+ * 8 bit lock.
+ */
+ adll_shift_lock[if_id][pup]++;
+ /*
+ * The search ended in Pass
+ * we need Fail
+ */
+ res0[if_id] =
+ (pbs_mode == PBS_RX_MODE) ?
+ ((res0[if_id] & res_valid_mask) + 1) :
+ ((res0[if_id] & res_valid_mask) - 1);
+ max_adll_per_pup[if_id][pup] =
+ (max_adll_per_pup[if_id]
+ [pup] < res0[if_id]) ?
+ (u8)res0[if_id] :
+ max_adll_per_pup[if_id][pup];
+ min_adll_per_pup[if_id][pup] =
+ (res0[if_id] >
+ min_adll_per_pup[if_id]
+ [pup]) ?
+ min_adll_per_pup[if_id][pup] :
+ (u8)res0[if_id];
+ /*
+ * vs the Rx we are searching for
+ * the smallest value of DQ shift
+ * so all Bus would fail
+ */
+ adll_shift_val[if_id][pup] =
+ (pbs_mode == PBS_RX_MODE) ?
+ max_adll_per_pup[if_id][pup] :
+ min_adll_per_pup[if_id][pup];
+ }
+ }
+ /* 1 is lock */
+ adll_shift_lock[if_id][pup] =
+ (adll_shift_lock[if_id][pup] == 8) ?
+ 1 : 0;
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x3 + effective_cs * 4) :
+ (0x1 + effective_cs * 4);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ adll_shift_val[if_id][pup]));
+ DEBUG_PBS_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("adll_shift_lock[%x][%x] = %x\n",
+ if_id, pup,
+ adll_shift_lock[if_id][pup]));
+ }
+ }
+
+ /* End ADLL Shift for SBA */
+ /* Start the Per Bit Skew search */
+ /* The ADLL shift finished with a Pass */
+ search_edge = (pbs_mode == PBS_RX_MODE) ? EDGE_PF : EDGE_FP;
+ search_dir = (pbs_mode == PBS_RX_MODE) ?
+ HWS_LOW2HIGH : HWS_HIGH2LOW;
+ iterations = 0x1f;
+ /* - The initial value is different in Rx and Tx mode */
+ init_val = (pbs_mode == PBS_RX_MODE) ? 0 : iterations;
+
+ ddr3_tip_ip_training(dev_num, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE, RESULT_PER_BIT,
+ HWS_CONTROL_ELEMENT_DQ_SKEW,
+ search_dir, dir, tm->if_act_mask,
+ init_val, iterations, pbs_pattern,
+ search_edge, CS_SINGLE, cs_num,
+ train_status);
+
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ CHECK_STATUS(ddr3_tip_if_read
+ (dev_num,
+ ACCESS_TYPE_MULTICAST,
+ PARAM_NOT_CARE,
+ mask_results_dq_reg_map
+ [bit +
+ pup *
+ BUS_WIDTH_IN_BITS],
+ res0, MASK_ALL_BITS));
+ if (pup_state[if_id][pup] != 2) {
+ /*
+ * if pup is not SBA continue
+ * to next pup
+ */
+ bit = BUS_WIDTH_IN_BITS;
+ continue;
+ }
+ DEBUG_PBS_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("Per Bit Skew search, PF I/F %d, bit:%d, pup:%d res0 0x%x\n",
+ if_id, bit, pup, res0[if_id]));
+ if ((res0[if_id] & 0x2000000) == 0) {
+ DEBUG_PBS_ENGINE
+ (DEBUG_LEVEL_INFO,
+ ("SBA Fail\n"));
+
+ max_pbs_per_pup[if_id][pup] =
+ 0x1f;
+ result_all_bit[
+ bit + pup *
+ BUS_WIDTH_IN_BITS +
+ if_id * MAX_BUS_NUM *
+ BUS_WIDTH_IN_BITS] =
+ 0x1f;
+ } else {
+ temp = (u8)(res0[if_id] &
+ res_valid_mask);
+ max_pbs_per_pup[if_id][pup] =
+ (temp >
+ max_pbs_per_pup[if_id]
+ [pup]) ? temp :
+ max_pbs_per_pup
+ [if_id][pup];
+ min_pbs_per_pup[if_id][pup] =
+ (temp <
+ min_pbs_per_pup[if_id]
+ [pup]) ? temp :
+ min_pbs_per_pup
+ [if_id][pup];
+ result_all_bit[
+ bit + pup *
+ BUS_WIDTH_IN_BITS +
+ if_id * MAX_BUS_NUM *
+ BUS_WIDTH_IN_BITS] =
+ temp;
+ adll_shift_lock[if_id][pup] = 1;
+ }
+ }
+ }
+ }
+
+ /* Check all Pup state */
+ all_lock = 1;
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ /*
+ * DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
+ * ("pup_state[%d][%d] = %d\n",if_id,pup,pup_state
+ * [if_id][pup]));
+ */
+ }
+ }
+
+ /* END OF SBA */
+ /* Norm */
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1;
+ if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /* if pup not lock continue to next pup */
+ if (adll_shift_lock[if_id][pup] != 1) {
+ DEBUG_PBS_ENGINE(
+ DEBUG_LEVEL_ERROR,
+ ("PBS failed for IF #%d\n",
+ if_id));
+ training_result[training_stage][if_id]
+ = TEST_FAILED;
+
+ result_mat[if_id][pup][bit] = 0;
+ max_pbs_per_pup[if_id][pup] = 0;
+ min_pbs_per_pup[if_id][pup] = 0;
+ } else {
+ training_result[
+ training_stage][if_id] =
+ (training_result[training_stage]
+ [if_id] == TEST_FAILED) ?
+ TEST_FAILED : TEST_SUCCESS;
+ result_mat[if_id][pup][bit] =
+ result_all_bit[
+ bit + pup *
+ BUS_WIDTH_IN_BITS +
+ if_id * MAX_BUS_NUM *
+ BUS_WIDTH_IN_BITS] -
+ min_pbs_per_pup[if_id][pup];
+ }
+ DEBUG_PBS_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("The abs min_pbs[%d][%d] = %d\n",
+ if_id, pup,
+ min_pbs_per_pup[if_id][pup]));
+ }
+ }
+ }
+
+ /* Clean all results */
+ ddr3_tip_clean_pbs_result(dev_num, pbs_mode);
+
+ /* DQ PBS register update with the final result */
+ for (if_id = 0; if_id < MAX_INTERFACE_NUM; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (pup = 0; pup < tm->num_of_bus_per_interface; pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+
+ DEBUG_PBS_ENGINE(
+ DEBUG_LEVEL_INFO,
+ ("Final Results: if_id %d, pup %d, Pup State: %d\n",
+ if_id, pup, pup_state[if_id][pup]));
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ if (dq_map_table == NULL) {
+ DEBUG_PBS_ENGINE(
+ DEBUG_LEVEL_ERROR,
+ ("dq_map_table not initialized\n"));
+ return MV_FAIL;
+ }
+ pad_num = dq_map_table[
+ bit + pup * BUS_WIDTH_IN_BITS +
+ if_id * BUS_WIDTH_IN_BITS *
+ tm->num_of_bus_per_interface];
+ DEBUG_PBS_ENGINE(DEBUG_LEVEL_INFO,
+ ("result_mat: %d ",
+ result_mat[if_id][pup]
+ [bit]));
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (PBS_RX_PHY_REG + effective_cs * 0x10) :
+ (PBS_TX_PHY_REG + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr + pad_num,
+ result_mat[if_id][pup][bit]));
+ }
+ pbsdelay_per_pup[pbs_mode][if_id][pup] =
+ (max_pbs_per_pup[if_id][pup] ==
+ min_pbs_per_pup[if_id][pup]) ?
+ TYPICAL_PBS_VALUE :
+ ((max_adll_per_pup[if_id][pup] -
+ min_adll_per_pup[if_id][pup]) * adll_tap /
+ (max_pbs_per_pup[if_id][pup] -
+ min_pbs_per_pup[if_id][pup]));
+
+ /* RX results ready, write RX also */
+ if (pbs_mode == PBS_TX_MODE) {
+ /* Write TX results */
+ reg_addr = (0x14 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ (max_pbs_per_pup[if_id][pup] -
+ min_pbs_per_pup[if_id][pup]) /
+ 2));
+ reg_addr = (0x15 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ (max_pbs_per_pup[if_id][pup] -
+ min_pbs_per_pup[if_id][pup]) /
+ 2));
+
+ /* Write previously stored RX results */
+ reg_addr = (0x54 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ result_mat_rx_dqs[if_id][pup]
+ [effective_cs]));
+ reg_addr = (0x55 + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr,
+ result_mat_rx_dqs[if_id][pup]
+ [effective_cs]));
+ } else {
+ /*
+ * RX results may affect RL results correctess,
+ * so just store the results that will written
+ * in TX stage
+ */
+ result_mat_rx_dqs[if_id][pup][effective_cs] =
+ (max_pbs_per_pup[if_id][pup] -
+ min_pbs_per_pup[if_id][pup]) / 2;
+ }
+ DEBUG_PBS_ENGINE(
+ DEBUG_LEVEL_INFO,
+ (", PBS tap=%d [psec] ==> skew observed = %d\n",
+ pbsdelay_per_pup[pbs_mode][if_id][pup],
+ ((max_pbs_per_pup[if_id][pup] -
+ min_pbs_per_pup[if_id][pup]) *
+ pbsdelay_per_pup[pbs_mode][if_id][pup])));
+ }
+ }
+
+ /* Write back to the phy the default values */
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (READ_CENTRALIZATION_PHY_REG + effective_cs * 4) :
+ (WRITE_CENTRALIZATION_PHY_REG + effective_cs * 4);
+ write_adll_value(nominal_adll, reg_addr);
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (0x5a + effective_cs * 0x10) :
+ (0x1a + effective_cs * 0x10);
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, pup, DDR_PHY_DATA, reg_addr,
+ 0));
+
+ /* restore cs enable value */
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ CS_ENABLE_REG, cs_enable_reg_val[if_id],
+ MASK_ALL_BITS));
+ }
+
+ /* exit test mode */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ODPG_WRITE_READ_MODE_ENABLE_REG, 0xffff, MASK_ALL_BITS));
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ /*
+ * meaning that there is no VW exist at all (No lock at
+ * the EBA ADLL shift at EBS)
+ */
+ if (pup_state[if_id][pup] == 1)
+ return MV_FAIL;
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Name: ddr3_tip_pbs_rx.
+ * Desc: PBS TX
+ * Args: TBD
+ * Notes:
+ * Returns: OK if success, other error code if fail.
+ */
+int ddr3_tip_pbs_rx(u32 uidev_num)
+{
+ return ddr3_tip_pbs(uidev_num, PBS_RX_MODE);
+}
+
+/*
+ * Name: ddr3_tip_pbs_tx.
+ * Desc: PBS TX
+ * Args: TBD
+ * Notes:
+ * Returns: OK if success, other error code if fail.
+ */
+int ddr3_tip_pbs_tx(u32 uidev_num)
+{
+ return ddr3_tip_pbs(uidev_num, PBS_TX_MODE);
+}
+
+#ifndef EXCLUDE_SWITCH_DEBUG
+/*
+ * Print PBS Result
+ */
+int ddr3_tip_print_all_pbs_result(u32 dev_num)
+{
+ u32 curr_cs;
+ u32 max_cs = hws_ddr3_tip_max_cs_get();
+
+ for (curr_cs = 0; curr_cs < max_cs; curr_cs++) {
+ ddr3_tip_print_pbs_result(dev_num, curr_cs, PBS_RX_MODE);
+ ddr3_tip_print_pbs_result(dev_num, curr_cs, PBS_TX_MODE);
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Print PBS Result
+ */
+int ddr3_tip_print_pbs_result(u32 dev_num, u32 cs_num, enum pbs_dir pbs_mode)
+{
+ u32 data_value = 0, bit = 0, if_id = 0, pup = 0;
+ u32 reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (PBS_RX_PHY_REG + cs_num * 0x10) :
+ (PBS_TX_PHY_REG + cs_num * 0x10);
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ printf("CS%d, %s ,PBS\n", cs_num,
+ (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx");
+
+ for (bit = 0; bit < BUS_WIDTH_IN_BITS; bit++) {
+ printf("%s, DQ", (pbs_mode == PBS_RX_MODE) ? "Rx" : "Tx");
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ printf("%d ,PBS,,, ", bit);
+ for (pup = 0; pup <= tm->num_of_bus_per_interface;
+ pup++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, pup);
+ CHECK_STATUS(ddr3_tip_bus_read
+ (dev_num, if_id,
+ ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr + bit,
+ &data_value));
+ printf("%d , ", data_value);
+ }
+ }
+ printf("\n");
+ }
+ printf("\n");
+
+ return MV_OK;
+}
+#endif
+
+/*
+ * Fixup PBS Result
+ */
+int ddr3_tip_clean_pbs_result(u32 dev_num, enum pbs_dir pbs_mode)
+{
+ u32 if_id, pup, bit;
+ u32 reg_addr = (pbs_mode == PBS_RX_MODE) ?
+ (PBS_RX_PHY_REG + effective_cs * 0x10) :
+ (PBS_TX_PHY_REG + effective_cs * 0x10);
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (pup = 0; pup <= tm->num_of_bus_per_interface; pup++) {
+ for (bit = 0; bit <= BUS_WIDTH_IN_BITS + 3; bit++) {
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, ACCESS_TYPE_UNICAST, pup,
+ DDR_PHY_DATA, reg_addr + bit, 0));
+ }
+ }
+ }
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+
+/* Design Guidelines parameters */
+u32 g_zpri_data = 123; /* controller data - P drive strength */
+u32 g_znri_data = 123; /* controller data - N drive strength */
+u32 g_zpri_ctrl = 74; /* controller C/A - P drive strength */
+u32 g_znri_ctrl = 74; /* controller C/A - N drive strength */
+u32 g_zpodt_data = 45; /* controller data - P ODT */
+u32 g_znodt_data = 45; /* controller data - N ODT */
+u32 g_zpodt_ctrl = 45; /* controller data - P ODT */
+u32 g_znodt_ctrl = 45; /* controller data - N ODT */
+u32 g_odt_config = 0x120012;
+u32 g_rtt_nom = 0x44;
+u32 g_dic = 0x2;
+
+#ifdef STATIC_ALGO_SUPPORT
+
+#define PARAM_NOT_CARE 0
+#define MAX_STATIC_SEQ 48
+
+u32 silicon_delay[HWS_MAX_DEVICE_NUM];
+struct hws_tip_static_config_info static_config[HWS_MAX_DEVICE_NUM];
+static reg_data *static_init_controller_config[HWS_MAX_DEVICE_NUM];
+
+/* debug delay in write leveling */
+int wl_debug_delay = 0;
+/* pup register #3 for functional board */
+int function_reg_value = 8;
+u32 silicon;
+
+u32 read_ready_delay_phase_offset[] = { 4, 4, 4, 4, 6, 6, 6, 6 };
+
+static struct cs_element chip_select_map[] = {
+ /* CS Value (single only) Num_CS */
+ {0, 0},
+ {0, 1},
+ {1, 1},
+ {0, 2},
+ {2, 1},
+ {0, 2},
+ {0, 2},
+ {0, 3},
+ {3, 1},
+ {0, 2},
+ {0, 2},
+ {0, 3},
+ {0, 2},
+ {0, 3},
+ {0, 3},
+ {0, 4}
+};
+
+/*
+ * Register static init controller DB
+ */
+int ddr3_tip_init_specific_reg_config(u32 dev_num, reg_data *reg_config_arr)
+{
+ static_init_controller_config[dev_num] = reg_config_arr;
+ return MV_OK;
+}
+
+/*
+ * Register static info DB
+ */
+int ddr3_tip_init_static_config_db(
+ u32 dev_num, struct hws_tip_static_config_info *static_config_info)
+{
+ static_config[dev_num].board_trace_arr =
+ static_config_info->board_trace_arr;
+ static_config[dev_num].package_trace_arr =
+ static_config_info->package_trace_arr;
+ silicon_delay[dev_num] = static_config_info->silicon_delay;
+
+ return MV_OK;
+}
+
+/*
+ * Static round trip flow - Calculates the total round trip delay.
+ */
+int ddr3_tip_static_round_trip_arr_build(u32 dev_num,
+ struct trip_delay_element *table_ptr,
+ int is_wl, u32 *round_trip_delay_arr)
+{
+ u32 bus_index, global_bus;
+ u32 if_id;
+ u32 bus_per_interface;
+ int sign;
+ u32 temp;
+ u32 board_trace;
+ struct trip_delay_element *pkg_delay_ptr;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ /*
+ * In WL we calc the diff between Clock to DQs in RL we sum the round
+ * trip of Clock and DQs
+ */
+ sign = (is_wl) ? -1 : 1;
+
+ bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ for (bus_index = 0; bus_index < bus_per_interface;
+ bus_index++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+ global_bus = (if_id * bus_per_interface) + bus_index;
+
+ /* calculate total trip delay (package and board) */
+ board_trace = (table_ptr[global_bus].dqs_delay * sign) +
+ table_ptr[global_bus].ck_delay;
+ temp = (board_trace * 163) / 1000;
+
+ /* Convert the length to delay in psec units */
+ pkg_delay_ptr =
+ static_config[dev_num].package_trace_arr;
+ round_trip_delay_arr[global_bus] = temp +
+ (int)(pkg_delay_ptr[global_bus].dqs_delay *
+ sign) +
+ (int)pkg_delay_ptr[global_bus].ck_delay +
+ (int)((is_wl == 1) ? wl_debug_delay :
+ (int)silicon_delay[dev_num]);
+ DEBUG_TRAINING_STATIC_IP(
+ DEBUG_LEVEL_TRACE,
+ ("Round Trip Build round_trip_delay_arr[0x%x]: 0x%x temp 0x%x\n",
+ global_bus, round_trip_delay_arr[global_bus],
+ temp));
+ }
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Write leveling for static flow - calculating the round trip delay of the
+ * DQS signal.
+ */
+int ddr3_tip_write_leveling_static_config(u32 dev_num, u32 if_id,
+ enum hws_ddr_freq frequency,
+ u32 *round_trip_delay_arr)
+{
+ u32 bus_index; /* index to the bus loop */
+ u32 bus_start_index;
+ u32 bus_per_interface;
+ u32 phase = 0;
+ u32 adll = 0, adll_cen, adll_inv, adll_final;
+ u32 adll_period = MEGA / freq_val[frequency] / 64;
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("ddr3_tip_write_leveling_static_config\n"));
+ DEBUG_TRAINING_STATIC_IP(
+ DEBUG_LEVEL_TRACE,
+ ("dev_num 0x%x IF 0x%x freq %d (adll_period 0x%x)\n",
+ dev_num, if_id, frequency, adll_period));
+
+ bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
+ bus_start_index = if_id * bus_per_interface;
+ for (bus_index = bus_start_index;
+ bus_index < (bus_start_index + bus_per_interface); bus_index++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+ phase = round_trip_delay_arr[bus_index] / (32 * adll_period);
+ adll = (round_trip_delay_arr[bus_index] -
+ (phase * 32 * adll_period)) / adll_period;
+ adll = (adll > 31) ? 31 : adll;
+ adll_cen = 16 + adll;
+ adll_inv = adll_cen / 32;
+ adll_final = adll_cen - (adll_inv * 32);
+ adll_final = (adll_final > 31) ? 31 : adll_final;
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("\t%d - phase 0x%x adll 0x%x\n",
+ bus_index, phase, adll));
+ /*
+ * Writing to all 4 phy of Interface number,
+ * bit 0 \96 4 \96 ADLL, bit 6-8 phase
+ */
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ (bus_index % 4), DDR_PHY_DATA,
+ PHY_WRITE_DELAY(cs),
+ ((phase << 6) + (adll & 0x1f)), 0x1df));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ACCESS_TYPE_UNICAST, (bus_index % 4),
+ DDR_PHY_DATA, WRITE_CENTRALIZATION_PHY_REG,
+ ((adll_inv & 0x1) << 5) + adll_final));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Read leveling for static flow
+ */
+int ddr3_tip_read_leveling_static_config(u32 dev_num,
+ u32 if_id,
+ enum hws_ddr_freq frequency,
+ u32 *total_round_trip_delay_arr)
+{
+ u32 cs, data0, data1, data3 = 0;
+ u32 bus_index; /* index to the bus loop */
+ u32 bus_start_index;
+ u32 phase0, phase1, max_phase;
+ u32 adll0, adll1;
+ u32 cl_value;
+ u32 min_delay;
+ u32 sdr_period = MEGA / freq_val[frequency];
+ u32 ddr_period = MEGA / freq_val[frequency] / 2;
+ u32 adll_period = MEGA / freq_val[frequency] / 64;
+ enum hws_speed_bin speed_bin_index;
+ u32 rd_sample_dly[MAX_CS_NUM] = { 0 };
+ u32 rd_ready_del[MAX_CS_NUM] = { 0 };
+ u32 bus_per_interface = GET_TOPOLOGY_NUM_OF_BUSES();
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("ddr3_tip_read_leveling_static_config\n"));
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("dev_num 0x%x ifc 0x%x freq %d\n", dev_num,
+ if_id, frequency));
+ DEBUG_TRAINING_STATIC_IP(
+ DEBUG_LEVEL_TRACE,
+ ("Sdr_period 0x%x Ddr_period 0x%x adll_period 0x%x\n",
+ sdr_period, ddr_period, adll_period));
+
+ if (tm->interface_params[first_active_if].memory_freq ==
+ frequency) {
+ cl_value = tm->interface_params[first_active_if].cas_l;
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("cl_value 0x%x\n", cl_value));
+ } else {
+ speed_bin_index = tm->interface_params[if_id].speed_bin_index;
+ cl_value = cas_latency_table[speed_bin_index].cl_val[frequency];
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("cl_value 0x%x speed_bin_index %d\n",
+ cl_value, speed_bin_index));
+ }
+
+ bus_start_index = if_id * bus_per_interface;
+
+ for (bus_index = bus_start_index;
+ bus_index < (bus_start_index + bus_per_interface);
+ bus_index += 2) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+ cs = chip_select_map[
+ tm->interface_params[if_id].as_bus_params[
+ (bus_index % 4)].cs_bitmask].cs_num;
+
+ /* read sample delay calculation */
+ min_delay = (total_round_trip_delay_arr[bus_index] <
+ total_round_trip_delay_arr[bus_index + 1]) ?
+ total_round_trip_delay_arr[bus_index] :
+ total_round_trip_delay_arr[bus_index + 1];
+ /* round down */
+ rd_sample_dly[cs] = 2 * (min_delay / (sdr_period * 2));
+ DEBUG_TRAINING_STATIC_IP(
+ DEBUG_LEVEL_TRACE,
+ ("\t%d - min_delay 0x%x cs 0x%x rd_sample_dly[cs] 0x%x\n",
+ bus_index, min_delay, cs, rd_sample_dly[cs]));
+
+ /* phase calculation */
+ phase0 = (total_round_trip_delay_arr[bus_index] -
+ (sdr_period * rd_sample_dly[cs])) / (ddr_period);
+ phase1 = (total_round_trip_delay_arr[bus_index + 1] -
+ (sdr_period * rd_sample_dly[cs])) / (ddr_period);
+ max_phase = (phase0 > phase1) ? phase0 : phase1;
+ DEBUG_TRAINING_STATIC_IP(
+ DEBUG_LEVEL_TRACE,
+ ("\tphase0 0x%x phase1 0x%x max_phase 0x%x\n",
+ phase0, phase1, max_phase));
+
+ /* ADLL calculation */
+ adll0 = (u32)((total_round_trip_delay_arr[bus_index] -
+ (sdr_period * rd_sample_dly[cs]) -
+ (ddr_period * phase0)) / adll_period);
+ adll0 = (adll0 > 31) ? 31 : adll0;
+ adll1 = (u32)((total_round_trip_delay_arr[bus_index + 1] -
+ (sdr_period * rd_sample_dly[cs]) -
+ (ddr_period * phase1)) / adll_period);
+ adll1 = (adll1 > 31) ? 31 : adll1;
+
+ /* The Read delay close the Read FIFO */
+ rd_ready_del[cs] = rd_sample_dly[cs] +
+ read_ready_delay_phase_offset[max_phase];
+ DEBUG_TRAINING_STATIC_IP(
+ DEBUG_LEVEL_TRACE,
+ ("\tadll0 0x%x adll1 0x%x rd_ready_del[cs] 0x%x\n",
+ adll0, adll1, rd_ready_del[cs]));
+
+ /*
+ * Write to the phy of Interface (bit 0 \96 4 \96 ADLL,
+ * bit 6-8 phase)
+ */
+ data0 = ((phase0 << 6) + (adll0 & 0x1f));
+ data1 = ((phase1 << 6) + (adll1 & 0x1f));
+
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ (bus_index % 4), DDR_PHY_DATA, PHY_READ_DELAY(cs),
+ data0, 0x1df));
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ ((bus_index + 1) % 4), DDR_PHY_DATA,
+ PHY_READ_DELAY(cs), data1, 0x1df));
+ }
+
+ for (bus_index = 0; bus_index < bus_per_interface; bus_index++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, bus_index);
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ bus_index, DDR_PHY_DATA, 0x3, data3, 0x1f));
+ }
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ READ_DATA_SAMPLE_DELAY,
+ (rd_sample_dly[0] + cl_value) + (rd_sample_dly[1] << 8),
+ MASK_ALL_BITS));
+
+ /* Read_ready_del0 bit 0-4 , CS bits 8-12 */
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_UNICAST, if_id,
+ READ_DATA_READY_DELAY,
+ rd_ready_del[0] + (rd_ready_del[1] << 8) + cl_value,
+ MASK_ALL_BITS));
+
+ return MV_OK;
+}
+
+/*
+ * DDR3 Static flow
+ */
+int ddr3_tip_run_static_alg(u32 dev_num, enum hws_ddr_freq freq)
+{
+ u32 if_id = 0;
+ struct trip_delay_element *table_ptr;
+ u32 wl_total_round_trip_delay_arr[MAX_TOTAL_BUS_NUM];
+ u32 rl_total_round_trip_delay_arr[MAX_TOTAL_BUS_NUM];
+ struct init_cntr_param init_cntr_prm;
+ int ret;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("ddr3_tip_run_static_alg"));
+
+ init_cntr_prm.do_mrs_phy = 1;
+ init_cntr_prm.is_ctrl64_bit = 0;
+ init_cntr_prm.init_phy = 1;
+ ret = hws_ddr3_tip_init_controller(dev_num, &init_cntr_prm);
+ if (ret != MV_OK) {
+ DEBUG_TRAINING_STATIC_IP(
+ DEBUG_LEVEL_ERROR,
+ ("hws_ddr3_tip_init_controller failure\n"));
+ }
+
+ /* calculate the round trip delay for Write Leveling */
+ table_ptr = static_config[dev_num].board_trace_arr;
+ CHECK_STATUS(ddr3_tip_static_round_trip_arr_build
+ (dev_num, table_ptr, 1,
+ wl_total_round_trip_delay_arr));
+ /* calculate the round trip delay for Read Leveling */
+ CHECK_STATUS(ddr3_tip_static_round_trip_arr_build
+ (dev_num, table_ptr, 0,
+ rl_total_round_trip_delay_arr));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ /* check if the interface is enabled */
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+ /*
+ * Static frequency is defined according to init-frequency
+ * (not target)
+ */
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("Static IF %d freq %d\n",
+ if_id, freq));
+ CHECK_STATUS(ddr3_tip_write_leveling_static_config
+ (dev_num, if_id, freq,
+ wl_total_round_trip_delay_arr));
+ CHECK_STATUS(ddr3_tip_read_leveling_static_config
+ (dev_num, if_id, freq,
+ rl_total_round_trip_delay_arr));
+ }
+
+ return MV_OK;
+}
+
+/*
+ * Init controller for static flow
+ */
+int ddr3_tip_static_init_controller(u32 dev_num)
+{
+ u32 index_cnt = 0;
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("ddr3_tip_static_init_controller\n"));
+ while (static_init_controller_config[dev_num][index_cnt].reg_addr !=
+ 0) {
+ CHECK_STATUS(ddr3_tip_if_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ static_init_controller_config[dev_num][index_cnt].
+ reg_addr,
+ static_init_controller_config[dev_num][index_cnt].
+ reg_data,
+ static_init_controller_config[dev_num][index_cnt].
+ reg_mask));
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("Init_controller index_cnt %d\n",
+ index_cnt));
+ index_cnt++;
+ }
+
+ return MV_OK;
+}
+
+int ddr3_tip_static_phy_init_controller(u32 dev_num)
+{
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("Phy Init Controller 2\n"));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa4,
+ 0x3dfe));
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("Phy Init Controller 3\n"));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa6,
+ 0xcb2));
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("Phy Init Controller 4\n"));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa9,
+ 0));
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("Static Receiver Calibration\n"));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xd0,
+ 0x1f));
+
+ DEBUG_TRAINING_STATIC_IP(DEBUG_LEVEL_TRACE,
+ ("Static V-REF Calibration\n"));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0xa8,
+ 0x434));
+
+ return MV_OK;
+}
+#endif
+
+/*
+ * Configure phy (called by static init controller) for static flow
+ */
+int ddr3_tip_configure_phy(u32 dev_num)
+{
+ u32 if_id, phy_id;
+ struct hws_topology_map *tm = ddr3_get_topology_map();
+
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
+ PAD_ZRI_CALIB_PHY_REG,
+ ((0x7f & g_zpri_data) << 7 | (0x7f & g_znri_data))));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
+ PAD_ZRI_CALIB_PHY_REG,
+ ((0x7f & g_zpri_ctrl) << 7 | (0x7f & g_znri_ctrl))));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
+ PAD_ODT_CALIB_PHY_REG,
+ ((0x3f & g_zpodt_data) << 6 | (0x3f & g_znodt_data))));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
+ PAD_ODT_CALIB_PHY_REG,
+ ((0x3f & g_zpodt_ctrl) << 6 | (0x3f & g_znodt_ctrl))));
+
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
+ PAD_PRE_DISABLE_PHY_REG, 0));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA,
+ CMOS_CONFIG_PHY_REG, 0));
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_CONTROL,
+ CMOS_CONFIG_PHY_REG, 0));
+
+ for (if_id = 0; if_id <= MAX_INTERFACE_NUM - 1; if_id++) {
+ /* check if the interface is enabled */
+ VALIDATE_ACTIVE(tm->if_act_mask, if_id);
+
+ for (phy_id = 0;
+ phy_id < tm->num_of_bus_per_interface;
+ phy_id++) {
+ VALIDATE_ACTIVE(tm->bus_act_mask, phy_id);
+ /* Vref & clamp */
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, phy_id, DDR_PHY_DATA,
+ PAD_CONFIG_PHY_REG,
+ ((clamp_tbl[if_id] << 4) | vref),
+ ((0x7 << 4) | 0x7)));
+ /* clamp not relevant for control */
+ CHECK_STATUS(ddr3_tip_bus_read_modify_write
+ (dev_num, ACCESS_TYPE_UNICAST,
+ if_id, phy_id, DDR_PHY_CONTROL,
+ PAD_CONFIG_PHY_REG, 0x4, 0x7));
+ }
+ }
+
+ CHECK_STATUS(ddr3_tip_bus_write
+ (dev_num, ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE,
+ ACCESS_TYPE_MULTICAST, PARAM_NOT_CARE, DDR_PHY_DATA, 0x90,
+ 0x6002));
+
+ return MV_OK;
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR_TOPOLOGY_DEF_H
+#define _DDR_TOPOLOGY_DEF_H
+
+#include "ddr3_training_ip_def.h"
+#include "ddr3_topology_def.h"
+
+#if defined(CONFIG_ARMADA_38X)
+#include "ddr3_a38x.h"
+#endif
+
+/* bus width in bits */
+enum hws_bus_width {
+ BUS_WIDTH_4,
+ BUS_WIDTH_8,
+ BUS_WIDTH_16,
+ BUS_WIDTH_32
+};
+
+enum hws_temperature {
+ HWS_TEMP_LOW,
+ HWS_TEMP_NORMAL,
+ HWS_TEMP_HIGH
+};
+
+enum hws_mem_size {
+ MEM_512M,
+ MEM_1G,
+ MEM_2G,
+ MEM_4G,
+ MEM_8G,
+ MEM_SIZE_LAST
+};
+
+struct bus_params {
+ /* Chip Select (CS) bitmask (bits 0-CS0, bit 1- CS1 ...) */
+ u8 cs_bitmask;
+
+ /*
+ * mirror enable/disable
+ * (bits 0-CS0 mirroring, bit 1- CS1 mirroring ...)
+ */
+ int mirror_enable_bitmask;
+
+ /* DQS Swap (polarity) - true if enable */
+ int is_dqs_swap;
+
+ /* CK swap (polarity) - true if enable */
+ int is_ck_swap;
+};
+
+struct if_params {
+ /* bus configuration */
+ struct bus_params as_bus_params[MAX_BUS_NUM];
+
+ /* Speed Bin Table */
+ enum hws_speed_bin speed_bin_index;
+
+ /* bus width of memory */
+ enum hws_bus_width bus_width;
+
+ /* Bus memory size (MBit) */
+ enum hws_mem_size memory_size;
+
+ /* The DDR frequency for each interfaces */
+ enum hws_ddr_freq memory_freq;
+
+ /*
+ * delay CAS Write Latency
+ * - 0 for using default value (jedec suggested)
+ */
+ u8 cas_wl;
+
+ /*
+ * delay CAS Latency
+ * - 0 for using default value (jedec suggested)
+ */
+ u8 cas_l;
+
+ /* operation temperature */
+ enum hws_temperature interface_temp;
+};
+
+struct hws_topology_map {
+ /* Number of interfaces (default is 12) */
+ u8 if_act_mask;
+
+ /* Controller configuration per interface */
+ struct if_params interface_params[MAX_INTERFACE_NUM];
+
+ /* BUS per interface (default is 4) */
+ u8 num_of_bus_per_interface;
+
+ /* Bit mask for active buses */
+ u8 bus_act_mask;
+};
+
+/* DDR3 training global configuration parameters */
+struct tune_train_params {
+ u32 ck_delay;
+ u32 ck_delay_16;
+ u32 p_finger;
+ u32 n_finger;
+ u32 phy_reg3_val;
+};
+
+#endif /* _DDR_TOPOLOGY_DEF_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _DDR_TRAINING_IP_DB_H_
+#define _DDR_TRAINING_IP_DB_H_
+
+#include "ddr_topology_def.h"
+#include "ddr3_training_ip_db.h"
+
+u32 speed_bin_table(u8 index, enum speed_bin_table_elements element);
+u32 pattern_table_get_word(u32 dev_num, enum hws_pattern type, u8 index);
+
+#endif /* _DDR3_TRAINING_IP_DB_H_ */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __silicon_if_H
+#define __silicon_if_H
+
+/* max number of devices supported by driver */
+#ifdef CO_CPU_RUN
+#define HWS_MAX_DEVICE_NUM (1)
+#else
+#define HWS_MAX_DEVICE_NUM (16)
+#endif
+
+#endif /* __silicon_if_H */
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <spl.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/soc.h>
+
+#include "ddr3_init.h"
+#include "xor_regs.h"
+
+/* defines */
+#ifdef MV_DEBUG
+#define DB(x) x
+#else
+#define DB(x)
+#endif
+
+static u32 ui_xor_regs_ctrl_backup;
+static u32 ui_xor_regs_base_backup[MAX_CS];
+static u32 ui_xor_regs_mask_backup[MAX_CS];
+
+void mv_sys_xor_init(u32 num_of_cs, u32 cs_ena, u32 cs_size, u32 base_delta)
+{
+ u32 reg, ui, base, cs_count;
+
+ ui_xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0));
+ for (ui = 0; ui < MAX_CS; ui++)
+ ui_xor_regs_base_backup[ui] =
+ reg_read(XOR_BASE_ADDR_REG(0, ui));
+ for (ui = 0; ui < MAX_CS; ui++)
+ ui_xor_regs_mask_backup[ui] =
+ reg_read(XOR_SIZE_MASK_REG(0, ui));
+
+ reg = 0;
+ for (ui = 0; ui < (num_of_cs); ui++) {
+ /* Enable Window x for each CS */
+ reg |= (0x1 << (ui));
+ /* Enable Window x for each CS */
+ reg |= (0x3 << ((ui * 2) + 16));
+ }
+
+ reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);
+
+ cs_count = 0;
+ for (ui = 0; ui < num_of_cs; ui++) {
+ if (cs_ena & (1 << ui)) {
+ /*
+ * window x - Base - 0x00000000,
+ * Attribute 0x0e - DRAM
+ */
+ base = cs_size * ui + base_delta;
+ switch (ui) {
+ case 0:
+ base |= 0xe00;
+ break;
+ case 1:
+ base |= 0xd00;
+ break;
+ case 2:
+ base |= 0xb00;
+ break;
+ case 3:
+ base |= 0x700;
+ break;
+ }
+
+ reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);
+
+ /* window x - Size */
+ reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x7fff0000);
+ cs_count++;
+ }
+ }
+
+ mv_xor_hal_init(1);
+
+ return;
+}
+
+void mv_sys_xor_finish(void)
+{
+ u32 ui;
+
+ reg_write(XOR_WINDOW_CTRL_REG(0, 0), ui_xor_regs_ctrl_backup);
+ for (ui = 0; ui < MAX_CS; ui++)
+ reg_write(XOR_BASE_ADDR_REG(0, ui),
+ ui_xor_regs_base_backup[ui]);
+ for (ui = 0; ui < MAX_CS; ui++)
+ reg_write(XOR_SIZE_MASK_REG(0, ui),
+ ui_xor_regs_mask_backup[ui]);
+
+ reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
+}
+
+/*
+ * mv_xor_hal_init - Initialize XOR engine
+ *
+ * DESCRIPTION:
+ * This function initialize XOR unit.
+ * INPUT:
+ * None.
+ *
+ * OUTPUT:
+ * None.
+ *
+ * RETURN:
+ * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
+ */
+void mv_xor_hal_init(u32 xor_chan_num)
+{
+ u32 i;
+
+ /* Abort any XOR activity & set default configuration */
+ for (i = 0; i < xor_chan_num; i++) {
+ mv_xor_command_set(i, MV_STOP);
+ mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) |
+ (4 << XEXCR_DST_BURST_LIMIT_OFFS) |
+ (4 << XEXCR_SRC_BURST_LIMIT_OFFS));
+ }
+}
+
+/*
+ * mv_xor_ctrl_set - Set XOR channel control registers
+ *
+ * DESCRIPTION:
+ *
+ * INPUT:
+ *
+ * OUTPUT:
+ * None.
+ *
+ * RETURN:
+ * MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
+ * NOTE:
+ * This function does not modify the Operation_mode field of control register.
+ */
+int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
+{
+ u32 old_value;
+
+ /* update the XOR Engine [0..1] Configuration Registers (XEx_c_r) */
+ old_value = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan))) &
+ XEXCR_OPERATION_MODE_MASK;
+ xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK;
+ xor_ctrl |= old_value;
+ reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl);
+
+ return MV_OK;
+}
+
+int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size,
+ u32 init_val_high, u32 init_val_low)
+{
+ u32 temp;
+
+ /* Parameter checking */
+ if (chan >= MV_XOR_MAX_CHAN)
+ return MV_BAD_PARAM;
+
+ if (MV_ACTIVE == mv_xor_state_get(chan))
+ return MV_BUSY;
+
+ if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
+ (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE))
+ return MV_BAD_PARAM;
+
+ /* set the operation mode to Memory Init */
+ temp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
+ temp &= ~XEXCR_OPERATION_MODE_MASK;
+ temp |= XEXCR_OPERATION_MODE_MEM_INIT;
+ reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), temp);
+
+ /*
+ * update the start_ptr field in XOR Engine [0..1] Destination Pointer
+ * Register
+ */
+ reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr);
+
+ /*
+ * update the Block_size field in the XOR Engine[0..1] Block Size
+ * Registers
+ */
+ reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
+ block_size);
+
+ /*
+ * update the field Init_val_l in the XOR Engine Initial Value Register
+ * Low (XEIVRL)
+ */
+ reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low);
+
+ /*
+ * update the field Init_val_h in the XOR Engine Initial Value Register
+ * High (XEIVRH)
+ */
+ reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high);
+
+ /* start transfer */
+ reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
+ XEXACTR_XESTART_MASK);
+
+ return MV_OK;
+}
+
+/*
+ * mv_xor_state_get - Get XOR channel state.
+ *
+ * DESCRIPTION:
+ * XOR channel activity state can be active, idle, paused.
+ * This function retrunes the channel activity state.
+ *
+ * INPUT:
+ * chan - the channel number
+ *
+ * OUTPUT:
+ * None.
+ *
+ * RETURN:
+ * XOR_CHANNEL_IDLE - If the engine is idle.
+ * XOR_CHANNEL_ACTIVE - If the engine is busy.
+ * XOR_CHANNEL_PAUSED - If the engine is paused.
+ * MV_UNDEFINED_STATE - If the engine state is undefind or there is no
+ * such engine
+ */
+enum mv_state mv_xor_state_get(u32 chan)
+{
+ u32 state;
+
+ /* Parameter checking */
+ if (chan >= MV_XOR_MAX_CHAN) {
+ DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
+ return MV_UNDEFINED_STATE;
+ }
+
+ /* read the current state */
+ state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
+ state &= XEXACTR_XESTATUS_MASK;
+
+ /* return the state */
+ switch (state) {
+ case XEXACTR_XESTATUS_IDLE:
+ return MV_IDLE;
+ case XEXACTR_XESTATUS_ACTIVE:
+ return MV_ACTIVE;
+ case XEXACTR_XESTATUS_PAUSED:
+ return MV_PAUSED;
+ }
+
+ return MV_UNDEFINED_STATE;
+}
+
+/*
+ * mv_xor_command_set - Set command of XOR channel
+ *
+ * DESCRIPTION:
+ * XOR channel can be started, idle, paused and restarted.
+ * Paused can be set only if channel is active.
+ * Start can be set only if channel is idle or paused.
+ * Restart can be set only if channel is paused.
+ * Stop can be set only if channel is active.
+ *
+ * INPUT:
+ * chan - The channel number
+ * command - The command type (start, stop, restart, pause)
+ *
+ * OUTPUT:
+ * None.
+ *
+ * RETURN:
+ * MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on
+ * undefind XOR engine mode
+ */
+int mv_xor_command_set(u32 chan, enum mv_command command)
+{
+ enum mv_state state;
+
+ /* Parameter checking */
+ if (chan >= MV_XOR_MAX_CHAN) {
+ DB(printf("%s: ERR. Invalid chan num %d\n", __func__, chan));
+ return MV_BAD_PARAM;
+ }
+
+ /* get the current state */
+ state = mv_xor_state_get(chan);
+
+ if ((command == MV_START) && (state == MV_IDLE)) {
+ /* command is start and current state is idle */
+ reg_bit_set(XOR_ACTIVATION_REG
+ (XOR_UNIT(chan), XOR_CHAN(chan)),
+ XEXACTR_XESTART_MASK);
+ return MV_OK;
+ } else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
+ /* command is stop and current state is active */
+ reg_bit_set(XOR_ACTIVATION_REG
+ (XOR_UNIT(chan), XOR_CHAN(chan)),
+ XEXACTR_XESTOP_MASK);
+ return MV_OK;
+ } else if (((enum mv_state)command == MV_PAUSED) &&
+ (state == MV_ACTIVE)) {
+ /* command is paused and current state is active */
+ reg_bit_set(XOR_ACTIVATION_REG
+ (XOR_UNIT(chan), XOR_CHAN(chan)),
+ XEXACTR_XEPAUSE_MASK);
+ return MV_OK;
+ } else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
+ /* command is restart and current state is paused */
+ reg_bit_set(XOR_ACTIVATION_REG
+ (XOR_UNIT(chan), XOR_CHAN(chan)),
+ XEXACTR_XERESTART_MASK);
+ return MV_OK;
+ } else if ((command == MV_STOP) && (state == MV_IDLE)) {
+ /* command is stop and current state is active */
+ return MV_OK;
+ }
+
+ /* illegal command */
+ DB(printf("%s: ERR. Illegal command\n", __func__));
+
+ return MV_BAD_PARAM;
+}
+
+void ddr3_new_tip_ecc_scrub(void)
+{
+ u32 cs_c, max_cs;
+ u32 cs_ena = 0;
+
+ printf("DDR3 Training Sequence - Start scrubbing\n");
+
+ max_cs = hws_ddr3_tip_max_cs_get();
+ for (cs_c = 0; cs_c < max_cs; cs_c++)
+ cs_ena |= 1 << cs_c;
+
+ mv_sys_xor_init(max_cs, cs_ena, 0x80000000, 0);
+
+ mv_xor_mem_init(0, 0x00000000, 0x80000000, 0xdeadbeef, 0xdeadbeef);
+ /* wait for previous transfer completion */
+ while (mv_xor_state_get(0) != MV_IDLE)
+ ;
+
+ mv_xor_mem_init(0, 0x80000000, 0x40000000, 0xdeadbeef, 0xdeadbeef);
+
+ /* wait for previous transfer completion */
+ while (mv_xor_state_get(0) != MV_IDLE)
+ ;
+
+ /* Return XOR State */
+ mv_sys_xor_finish();
+
+ printf("DDR3 Training Sequence - End scrubbing\n");
+}
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _XOR_H
+#define _XOR_H
+
+#define SRAM_BASE 0x40000000
+
+#include "ddr3_hws_hw_training_def.h"
+
+#define MV_XOR_MAX_UNIT 2 /* XOR unit == XOR engine */
+#define MV_XOR_MAX_CHAN 4 /* total channels for all units */
+#define MV_XOR_MAX_CHAN_PER_UNIT 2 /* channels for units */
+
+#define MV_IS_POWER_OF_2(num) (((num) != 0) && (((num) & ((num) - 1)) == 0))
+
+/*
+ * This structure describes address space window. Window base can be
+ * 64 bit, window size up to 4GB
+ */
+struct addr_win {
+ u32 base_low; /* 32bit base low */
+ u32 base_high; /* 32bit base high */
+ u32 size; /* 32bit size */
+};
+
+/* This structure describes SoC units address decode window */
+struct unit_win_info {
+ struct addr_win addr_win; /* An address window */
+ int enable; /* Address decode window is enabled/disabled */
+ u8 attrib; /* chip select attributes */
+ u8 target_id; /* Target Id of this MV_TARGET */
+};
+
+/*
+ * This enumerator describes the type of functionality the XOR channel
+ * can have while using the same data structures.
+ */
+enum xor_type {
+ MV_XOR, /* XOR channel functions as XOR accelerator */
+ MV_DMA, /* XOR channel functions as IDMA channel */
+ MV_CRC32 /* XOR channel functions as CRC 32 calculator */
+};
+
+enum mv_state {
+ MV_IDLE,
+ MV_ACTIVE,
+ MV_PAUSED,
+ MV_UNDEFINED_STATE
+};
+
+/*
+ * This enumerator describes the set of commands that can be applied on
+ * an engine (e.g. IDMA, XOR). Appling a comman depends on the current
+ * status (see MV_STATE enumerator)
+ *
+ * Start can be applied only when status is IDLE
+ * Stop can be applied only when status is IDLE, ACTIVE or PAUSED
+ * Pause can be applied only when status is ACTIVE
+ * Restart can be applied only when status is PAUSED
+ */
+enum mv_command {
+ MV_START, /* Start */
+ MV_STOP, /* Stop */
+ MV_PAUSE, /* Pause */
+ MV_RESTART /* Restart */
+};
+
+enum xor_override_target {
+ SRC_ADDR0, /* Source Address #0 Control */
+ SRC_ADDR1, /* Source Address #1 Control */
+ SRC_ADDR2, /* Source Address #2 Control */
+ SRC_ADDR3, /* Source Address #3 Control */
+ SRC_ADDR4, /* Source Address #4 Control */
+ SRC_ADDR5, /* Source Address #5 Control */
+ SRC_ADDR6, /* Source Address #6 Control */
+ SRC_ADDR7, /* Source Address #7 Control */
+ XOR_DST_ADDR, /* Destination Address Control */
+ XOR_NEXT_DESC /* Next Descriptor Address Control */
+};
+
+enum mv_state mv_xor_state_get(u32 chan);
+void mv_xor_hal_init(u32 xor_chan_num);
+int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl);
+int mv_xor_command_set(u32 chan, enum mv_command command);
+int mv_xor_override_set(u32 chan, enum xor_override_target target, u32 win_num,
+ int enable);
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) Marvell International Ltd. and its affiliates
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef _XOR_REGS_h
+#define _XOR_REGS_h
+
+/*
+ * For controllers that have two XOR units, then chans 2 & 3 will be
+ * mapped to channels 0 & 1 of unit 1
+ */
+#define XOR_UNIT(chan) ((chan) >> 1)
+#define XOR_CHAN(chan) ((chan) & 1)
+
+#define MV_XOR_REGS_OFFSET(unit) (0x60900)
+#define MV_XOR_REGS_BASE(unit) (MV_XOR_REGS_OFFSET(unit))
+
+/* XOR Engine Control Register Map */
+#define XOR_CHANNEL_ARBITER_REG(unit) (MV_XOR_REGS_BASE(unit))
+#define XOR_CONFIG_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + \
+ (0x10 + ((chan) * 4)))
+#define XOR_ACTIVATION_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + \
+ (0x20 + ((chan) * 4)))
+
+/* XOR Engine Interrupt Register Map */
+#define XOR_CAUSE_REG(unit) (MV_XOR_REGS_BASE(unit)+(0x30))
+#define XOR_MASK_REG(unit) (MV_XOR_REGS_BASE(unit)+(0x40))
+#define XOR_ERROR_CAUSE_REG(unit) (MV_XOR_REGS_BASE(unit)+(0x50))
+#define XOR_ERROR_ADDR_REG(unit) (MV_XOR_REGS_BASE(unit)+(0x60))
+
+/* XOR Engine Descriptor Register Map */
+#define XOR_NEXT_DESC_PTR_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + \
+ (0x200 + ((chan) * 4)))
+#define XOR_CURR_DESC_PTR_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + \
+ (0x210 + ((chan) * 4)))
+#define XOR_BYTE_COUNT_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + \
+ (0x220 + ((chan) * 4)))
+
+/* XOR Engine ECC/Mem_init Register Map */
+#define XOR_DST_PTR_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + \
+ (0x2b0 + ((chan) * 4)))
+#define XOR_BLOCK_SIZE_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + \
+ (0x2c0 + ((chan) * 4)))
+#define XOR_TIMER_MODE_CTRL_REG(unit) (MV_XOR_REGS_BASE(unit) + (0x2d0))
+#define XOR_TIMER_MODE_INIT_VAL_REG(unit) (MV_XOR_REGS_BASE(unit) + (0x2d4))
+#define XOR_TIMER_MODE_CURR_VAL_REG(unit) (MV_XOR_REGS_BASE(unit) + (0x2d8))
+#define XOR_INIT_VAL_LOW_REG(unit) (MV_XOR_REGS_BASE(unit) + (0x2e0))
+#define XOR_INIT_VAL_HIGH_REG(unit) (MV_XOR_REGS_BASE(unit) + (0x2e4))
+
+/* XOR Engine Debug Register Map */
+#define XOR_DEBUG_REG(unit) (MV_XOR_REGS_BASE(unit) + (0x70))
+
+/* XOR register fileds */
+
+/* XOR Engine Channel Arbiter Register */
+#define XECAR_SLICE_OFFS(slice_num) (slice_num)
+#define XECAR_SLICE_MASK(slice_num) (1 << (XECAR_SLICE_OFFS(slice_num)))
+
+/* XOR Engine [0..1] Configuration Registers */
+#define XEXCR_OPERATION_MODE_OFFS (0)
+#define XEXCR_OPERATION_MODE_MASK (7 << XEXCR_OPERATION_MODE_OFFS)
+#define XEXCR_OPERATION_MODE_XOR (0 << XEXCR_OPERATION_MODE_OFFS)
+#define XEXCR_OPERATION_MODE_CRC (1 << XEXCR_OPERATION_MODE_OFFS)
+#define XEXCR_OPERATION_MODE_DMA (2 << XEXCR_OPERATION_MODE_OFFS)
+#define XEXCR_OPERATION_MODE_ECC (3 << XEXCR_OPERATION_MODE_OFFS)
+#define XEXCR_OPERATION_MODE_MEM_INIT (4 << XEXCR_OPERATION_MODE_OFFS)
+
+#define XEXCR_SRC_BURST_LIMIT_OFFS (4)
+#define XEXCR_SRC_BURST_LIMIT_MASK (7 << XEXCR_SRC_BURST_LIMIT_OFFS)
+#define XEXCR_DST_BURST_LIMIT_OFFS (8)
+#define XEXCR_DST_BURST_LIMIT_MASK (7 << XEXCR_DST_BURST_LIMIT_OFFS)
+#define XEXCR_DRD_RES_SWP_OFFS (12)
+#define XEXCR_DRD_RES_SWP_MASK (1 << XEXCR_DRD_RES_SWP_OFFS)
+#define XEXCR_DWR_REQ_SWP_OFFS (13)
+#define XEXCR_DWR_REQ_SWP_MASK (1 << XEXCR_DWR_REQ_SWP_OFFS)
+#define XEXCR_DES_SWP_OFFS (14)
+#define XEXCR_DES_SWP_MASK (1 << XEXCR_DES_SWP_OFFS)
+#define XEXCR_REG_ACC_PROTECT_OFFS (15)
+#define XEXCR_REG_ACC_PROTECT_MASK (1 << XEXCR_REG_ACC_PROTECT_OFFS)
+
+/* XOR Engine [0..1] Activation Registers */
+#define XEXACTR_XESTART_OFFS (0)
+#define XEXACTR_XESTART_MASK (1 << XEXACTR_XESTART_OFFS)
+#define XEXACTR_XESTOP_OFFS (1)
+#define XEXACTR_XESTOP_MASK (1 << XEXACTR_XESTOP_OFFS)
+#define XEXACTR_XEPAUSE_OFFS (2)
+#define XEXACTR_XEPAUSE_MASK (1 << XEXACTR_XEPAUSE_OFFS)
+#define XEXACTR_XERESTART_OFFS (3)
+#define XEXACTR_XERESTART_MASK (1 << XEXACTR_XERESTART_OFFS)
+#define XEXACTR_XESTATUS_OFFS (4)
+#define XEXACTR_XESTATUS_MASK (3 << XEXACTR_XESTATUS_OFFS)
+#define XEXACTR_XESTATUS_IDLE (0 << XEXACTR_XESTATUS_OFFS)
+#define XEXACTR_XESTATUS_ACTIVE (1 << XEXACTR_XESTATUS_OFFS)
+#define XEXACTR_XESTATUS_PAUSED (2 << XEXACTR_XESTATUS_OFFS)
+
+/* XOR Engine Interrupt Cause Register (XEICR) */
+#define XEICR_CHAN_OFFS 16
+#define XEICR_CAUSE_OFFS(chan) (chan * XEICR_CHAN_OFFS)
+#define XEICR_CAUSE_MASK(chan, cause) (1 << (cause + XEICR_CAUSE_OFFS(chan)))
+#define XEICR_COMP_MASK_ALL 0x000f000f
+#define XEICR_COMP_MASK(chan) (0x000f << XEICR_CAUSE_OFFS(chan))
+#define XEICR_ERR_MASK 0x03800380
+
+/* XOR Engine Error Cause Register (XEECR) */
+#define XEECR_ERR_TYPE_OFFS 0
+#define XEECR_ERR_TYPE_MASK (0x1f << XEECR_ERR_TYPE_OFFS)
+
+/* XOR Engine Error Address Register (XEEAR) */
+#define XEEAR_ERR_ADDR_OFFS (0)
+#define XEEAR_ERR_ADDR_MASK (0xffffffff << XEEAR_ERR_ADDR_OFFS)
+
+/* XOR Engine [0..1] Next Descriptor Pointer Register */
+#define XEXNDPR_NEXT_DESC_PTR_OFFS (0)
+#define XEXNDPR_NEXT_DESC_PTR_MASK (0xffffffff << \
+ XEXNDPR_NEXT_DESC_PTR_OFFS)
+
+/* XOR Engine [0..1] Current Descriptor Pointer Register */
+#define XEXCDPR_CURRENT_DESC_PTR_OFFS (0)
+#define XEXCDPR_CURRENT_DESC_PTR_MASK (0xffffffff << \
+ XEXCDPR_CURRENT_DESC_PTR_OFFS)
+
+/* XOR Engine [0..1] Byte Count Register */
+#define XEXBCR_BYTE_CNT_OFFS (0)
+#define XEXBCR_BYTE_CNT_MASK (0xffffffff << XEXBCR_BYTE_CNT_OFFS)
+
+/* XOR Engine [0..1] Destination Pointer Register */
+#define XEXDPR_DST_PTR_OFFS (0)
+#define XEXDPR_DST_PTR_MASK (0xffffffff << XEXDPR_DST_PTR_OFFS)
+#define XEXDPR_DST_PTR_XOR_MASK (0x3f)
+#define XEXDPR_DST_PTR_DMA_MASK (0x1f)
+#define XEXDPR_DST_PTR_CRC_MASK (0x1f)
+
+/* XOR Engine[0..1] Block Size Registers */
+#define XEXBSR_BLOCK_SIZE_OFFS (0)
+#define XEXBSR_BLOCK_SIZE_MASK (0xffffffff << XEXBSR_BLOCK_SIZE_OFFS)
+#define XEXBSR_BLOCK_SIZE_MIN_VALUE (128)
+#define XEXBSR_BLOCK_SIZE_MAX_VALUE (0xffffffff)
+
+/* XOR Engine Timer Mode Control Register (XETMCR) */
+#define XETMCR_TIMER_EN_OFFS (0)
+#define XETMCR_TIMER_EN_MASK (1 << XETMCR_TIMER_EN_OFFS)
+#define XETMCR_TIMER_EN_ENABLE (1 << XETMCR_TIMER_EN_OFFS)
+#define XETMCR_TIMER_EN_DISABLE (0 << XETMCR_TIMER_EN_OFFS)
+#define XETMCR_SECTION_SIZE_CTRL_OFFS (8)
+#define XETMCR_SECTION_SIZE_CTRL_MASK (0x1f << XETMCR_SECTION_SIZE_CTRL_OFFS)
+#define XETMCR_SECTION_SIZE_MIN_VALUE (7)
+#define XETMCR_SECTION_SIZE_MAX_VALUE (31)
+
+/* XOR Engine Timer Mode Initial Value Register (XETMIVR) */
+#define XETMIVR_TIMER_INIT_VAL_OFFS (0)
+#define XETMIVR_TIMER_INIT_VAL_MASK (0xffffffff << \
+ XETMIVR_TIMER_INIT_VAL_OFFS)
+
+/* XOR Engine Timer Mode Current Value Register (XETMCVR) */
+#define XETMCVR_TIMER_CRNT_VAL_OFFS (0)
+#define XETMCVR_TIMER_CRNT_VAL_MASK (0xffffffff << \
+ XETMCVR_TIMER_CRNT_VAL_OFFS)
+
+/* XOR Engine Initial Value Register Low (XEIVRL) */
+#define XEIVRL_INIT_VAL_L_OFFS (0)
+#define XEIVRL_INIT_VAL_L_MASK (0xffffffff << XEIVRL_INIT_VAL_L_OFFS)
+
+/* XOR Engine Initial Value Register High (XEIVRH) */
+#define XEIVRH_INIT_VAL_H_OFFS (0)
+#define XEIVRH_INIT_VAL_H_MASK (0xffffffff << XEIVRH_INIT_VAL_H_OFFS)
+
+/* XOR Engine Debug Register (XEDBR) */
+#define XEDBR_PARITY_ERR_INSR_OFFS (0)
+#define XEDBR_PARITY_ERR_INSR_MASK (1 << XEDBR_PARITY_ERR_INSR_OFFS)
+#define XEDBR_XBAR_ERR_INSR_OFFS (1)
+#define XEDBR_XBAR_ERR_INSR_MASK (1 << XEDBR_XBAR_ERR_INSR_OFFS)
+
+/* XOR Engine address decode registers. */
+/* Maximum address decode windows */
+#define XOR_MAX_ADDR_DEC_WIN 8
+/* Maximum address arbiter windows */
+#define XOR_MAX_REMAP_WIN 4
+
+/* XOR Engine Address Decoding Register Map */
+#define XOR_WINDOW_CTRL_REG(unit, chan) (MV_XOR_REGS_BASE(unit) + \
+ (0x240 + ((chan) * 4)))
+#define XOR_BASE_ADDR_REG(unit, win_num) (MV_XOR_REGS_BASE(unit) + \
+ (0x250 + ((win_num) * 4)))
+#define XOR_SIZE_MASK_REG(unit, win_num) (MV_XOR_REGS_BASE(unit) + \
+ (0x270 + ((win_num) * 4)))
+#define XOR_HIGH_ADDR_REMAP_REG(unit, win_num) (MV_XOR_REGS_BASE(unit) + \
+ (0x290 + ((win_num) * 4)))
+#define XOR_ADDR_OVRD_REG(unit, win_num) (MV_XOR_REGS_BASE(unit) + \
+ (0x2a0 + ((win_num) * 4)))
+
+/* XOR Engine [0..1] Window Control Registers */
+#define XEXWCR_WIN_EN_OFFS(win_num) (win_num)
+#define XEXWCR_WIN_EN_MASK(win_num) (1 << (XEXWCR_WIN_EN_OFFS(win_num)))
+#define XEXWCR_WIN_EN_ENABLE(win_num) (1 << (XEXWCR_WIN_EN_OFFS(win_num)))
+#define XEXWCR_WIN_EN_DISABLE(win_num) (0 << (XEXWCR_WIN_EN_OFFS(win_num)))
+
+#define XEXWCR_WIN_ACC_OFFS(win_num) ((2 * win_num) + 16)
+#define XEXWCR_WIN_ACC_MASK(win_num) (3 << (XEXWCR_WIN_ACC_OFFS(win_num)))
+#define XEXWCR_WIN_ACC_NO_ACC(win_num) (0 << (XEXWCR_WIN_ACC_OFFS(win_num)))
+#define XEXWCR_WIN_ACC_RO(win_num) (1 << (XEXWCR_WIN_ACC_OFFS(win_num)))
+#define XEXWCR_WIN_ACC_RW(win_num) (3 << (XEXWCR_WIN_ACC_OFFS(win_num)))
+
+/* XOR Engine Base Address Registers (XEBARx) */
+#define XEBARX_TARGET_OFFS (0)
+#define XEBARX_TARGET_MASK (0xf << XEBARX_TARGET_OFFS)
+#define XEBARX_ATTR_OFFS (8)
+#define XEBARX_ATTR_MASK (0xff << XEBARX_ATTR_OFFS)
+#define XEBARX_BASE_OFFS (16)
+#define XEBARX_BASE_MASK (0xffff << XEBARX_BASE_OFFS)
+
+/* XOR Engine Size Mask Registers (XESMRx) */
+#define XESMRX_SIZE_MASK_OFFS (16)
+#define XESMRX_SIZE_MASK_MASK (0xffff << XESMRX_SIZE_MASK_OFFS)
+#define XOR_WIN_SIZE_ALIGN _64K
+
+/* XOR Engine High Address Remap Register (XEHARRx1) */
+#define XEHARRX_REMAP_OFFS (0)
+#define XEHARRX_REMAP_MASK (0xffffffff << XEHARRX_REMAP_OFFS)
+
+#define XOR_OVERRIDE_CTRL_REG(chan) (MV_XOR_REGS_BASE(XOR_UNIT(chan)) + \
+ (0x2a0 + ((XOR_CHAN(chan)) * 4)))
+
+/* XOR Engine [0..1] Address Override Control Register */
+#define XEXAOCR_OVR_EN_OFFS(target) (3 * target)
+#define XEXAOCR_OVR_EN_MASK(target) (1 << (XEXAOCR_OVR_EN_OFFS(target)))
+#define XEXAOCR_OVR_PTR_OFFS(target) ((3 * target) + 1)
+#define XEXAOCR_OVR_PTR_MASK(target) (3 << (XEXAOCR_OVR_PTR_OFFS(target)))
+#define XEXAOCR_OVR_BAR(win_num, target) (win_num << \
+ (XEXAOCR_OVR_PTR_OFFS(target)))
+
+/* Maximum address override windows */
+#define XOR_MAX_OVERRIDE_WIN 4
+
+#endif /* _XOR_REGS_h */
# SPDX-License-Identifier: GPL-2.0+
#
-obj-$(CONFIG_DFU_FUNCTION) += dfu.o
+obj-$(CONFIG_USB_FUNCTION_DFU) += dfu.o
obj-$(CONFIG_DFU_MMC) += dfu_mmc.o
obj-$(CONFIG_DFU_NAND) += dfu_nand.o
obj-$(CONFIG_DFU_RAM) += dfu_ram.o
{
int ret;
- debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x offset: 0x%llx bufoffset: 0x%x\n",
+ debug("%s: name: %s buf: 0x%p size: 0x%x p_num: 0x%x offset: 0x%llx bufoffset: 0x%lx\n",
__func__, dfu->name, buf, size, blk_seq_num, dfu->offset,
- dfu->i_buf - dfu->i_buf_start);
+ (unsigned long)(dfu->i_buf - dfu->i_buf_start));
if (!dfu->inited) {
/* initial state */
dfu->data.mmc.dev, dfu->data.mmc.part);
if (op != DFU_OP_SIZE)
- sprintf(cmd_buf + strlen(cmd_buf), " 0x%x", (unsigned int)buf);
+ sprintf(cmd_buf + strlen(cmd_buf), " %p", buf);
sprintf(cmd_buf + strlen(cmd_buf), " %s", dfu->name);
#
ifndef CONFIG_SPL_BUILD
-obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
obj-$(CONFIG_AXP_GPIO) += axp_gpio.o
endif
-/* TODO(sjg@chromium.org): Only tegra supports driver model in SPL */
-ifdef CONFIG_TEGRA_GPIO
obj-$(CONFIG_DM_GPIO) += gpio-uclass.o
-endif
obj-$(CONFIG_AT91_GPIO) += at91_gpio.o
obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
return ret ? ret : -ENOENT;
}
-int gpio_lookup_name(const char *name, struct udevice **devp,
- unsigned int *offsetp, unsigned int *gpiop)
+int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc)
{
struct gpio_dev_priv *uc_priv = NULL;
struct udevice *dev;
int numeric;
int ret;
- if (devp)
- *devp = NULL;
numeric = isdigit(*name) ? simple_strtoul(name, NULL, 10) : -1;
for (ret = uclass_first_device(UCLASS_GPIO, &dev);
dev;
if (!dev)
return ret ? ret : -EINVAL;
+ desc->dev = dev;
+ desc->offset = offset;
+
+ return 0;
+}
+
+int gpio_lookup_name(const char *name, struct udevice **devp,
+ unsigned int *offsetp, unsigned int *gpiop)
+{
+ struct gpio_desc desc;
+ int ret;
+
+ if (devp)
+ *devp = NULL;
+ ret = dm_gpio_lookup_name(name, &desc);
+ if (ret)
+ return ret;
+
if (devp)
- *devp = dev;
+ *devp = desc.dev;
if (offsetp)
- *offsetp = offset;
- if (gpiop)
- *gpiop = uc_priv->gpio_base + offset;
+ *offsetp = desc.offset;
+ if (gpiop) {
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc.dev);
+
+ *gpiop = uc_priv->gpio_base + desc.offset;
+ }
return 0;
}
return ops->xlate ? ops->xlate(desc->dev, desc, args) : 0;
}
-static int dm_gpio_request(struct gpio_desc *desc, const char *label)
+int dm_gpio_request(struct gpio_desc *desc, const char *label)
{
struct udevice *dev = desc->dev;
struct gpio_dev_priv *uc_priv;
if ((words == 1) && last_bytes) {
local = 0;
memcpy(&local, dptr, last_bytes);
- } else if ((unsigned)dptr & 3) {
+ } else if ((unsigned long)dptr & 3) {
memcpy(&local, dptr, sizeof(u32));
} else {
local = *wptr;
local = readl(&control->rx_fifo);
if ((words == 1) && last_bytes)
memcpy(dptr, (char *)&local, last_bytes);
- else if ((unsigned)dptr & 3)
+ else if ((unsigned long)dptr & 3)
memcpy(dptr, &local, sizeof(u32));
else
*wptr = local;
--- /dev/null
+config LED
+ bool "Enable LED support"
+ depends on DM
+ help
+ Many boards have LEDs which can be used to signal status or alerts.
+ U-Boot provides a uclass API to implement this feature. LED drivers
+ can provide access to board-specific LEDs. Use of the device tree
+ for configuration is encouraged.
+
+config SPL_LED_SUPPORT
+ bool "Enable LED support in SPL"
+ depends on LED
+ help
+ The LED subsystem adds a small amount of overhead to the image.
+ If this is acceptable and you have a need to use LEDs in SPL,
+ enable this option. You will need to enable device tree in SPL
+ for this to work.
+
+config LED_GPIO
+ bool "LED support for GPIO-connected LEDs"
+ depends on LED && DM_GPIO
+ help
+ Enable support for LEDs which are connected to GPIO lines. These
+ GPIOs may be on the SoC or some other device which provides GPIOs.
+ The GPIO driver must used driver model. LEDs are configured using
+ the device tree.
--- /dev/null
+#
+# Copyright (c) 2015 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_LED) += led-uclass.o
+obj-$(CONFIG_LED_GPIO) += led_gpio.o
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <dm/root.h>
+#include <dm/uclass-internal.h>
+
+int led_get_by_label(const char *label, struct udevice **devp)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_LED, &uc);
+ if (ret)
+ return ret;
+ uclass_foreach_dev(dev, uc) {
+ struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+
+ /* Ignore the top-level LED node */
+ if (uc_plat->label && !strcmp(label, uc_plat->label))
+ return uclass_get_device_tail(dev, 0, devp);
+ }
+
+ return -ENODEV;
+}
+
+int led_set_on(struct udevice *dev, int on)
+{
+ struct led_ops *ops = led_get_ops(dev);
+
+ if (!ops->set_on)
+ return -ENOSYS;
+
+ return ops->set_on(dev, on);
+}
+
+UCLASS_DRIVER(led) = {
+ .id = UCLASS_LED,
+ .name = "led",
+ .per_device_platdata_auto_alloc_size = sizeof(struct led_uclass_plat),
+};
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <led.h>
+#include <asm/gpio.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct led_gpio_priv {
+ struct gpio_desc gpio;
+};
+
+static int gpio_led_set_on(struct udevice *dev, int on)
+{
+ struct led_gpio_priv *priv = dev_get_priv(dev);
+
+ if (!dm_gpio_is_valid(&priv->gpio))
+ return -EREMOTEIO;
+
+ return dm_gpio_set_value(&priv->gpio, on);
+}
+
+static int led_gpio_probe(struct udevice *dev)
+{
+ struct led_uclass_plat *uc_plat = dev_get_uclass_platdata(dev);
+ struct led_gpio_priv *priv = dev_get_priv(dev);
+
+ /* Ignore the top-level LED node */
+ if (!uc_plat->label)
+ return 0;
+ return gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT);
+}
+
+static int led_gpio_remove(struct udevice *dev)
+{
+ /*
+ * The GPIO driver may have already been removed. We will need to
+ * address this more generally.
+ */
+#ifndef CONFIG_SANDBOX
+ struct led_gpio_priv *priv = dev_get_priv(dev);
+
+ if (dm_gpio_is_valid(&priv->gpio))
+ dm_gpio_free(dev, &priv->gpio);
+#endif
+
+ return 0;
+}
+
+static int led_gpio_bind(struct udevice *parent)
+{
+ const void *blob = gd->fdt_blob;
+ struct udevice *dev;
+ int node;
+ int ret;
+
+ for (node = fdt_first_subnode(blob, parent->of_offset);
+ node > 0;
+ node = fdt_next_subnode(blob, node)) {
+ struct led_uclass_plat *uc_plat;
+ const char *label;
+
+ label = fdt_getprop(blob, node, "label", NULL);
+ if (!label) {
+ debug("%s: node %s has no label\n", __func__,
+ fdt_get_name(blob, node, NULL));
+ return -EINVAL;
+ }
+ ret = device_bind_driver_to_node(parent, "gpio_led",
+ fdt_get_name(blob, node, NULL),
+ node, &dev);
+ if (ret)
+ return ret;
+ uc_plat = dev_get_uclass_platdata(dev);
+ uc_plat->label = label;
+ }
+
+ return 0;
+}
+
+static const struct led_ops gpio_led_ops = {
+ .set_on = gpio_led_set_on,
+};
+
+static const struct udevice_id led_gpio_ids[] = {
+ { .compatible = "gpio-leds" },
+ { }
+};
+
+U_BOOT_DRIVER(led_gpio) = {
+ .name = "gpio_led",
+ .id = UCLASS_LED,
+ .of_match = led_gpio_ids,
+ .ops = &gpio_led_ops,
+ .priv_auto_alloc_size = sizeof(struct led_gpio_priv),
+ .bind = led_gpio_bind,
+ .probe = led_gpio_probe,
+ .remove = led_gpio_remove,
+};
default 0x60
help
The I2C address of the PCA9551 LED controller.
+
+config RESET
+ bool "Enable support for reset drivers"
+ depends on DM
+ help
+ Enable reset drivers which can be used to reset the CPU or board.
+ Each driver can provide a reset method which will be called to
+ effect a reset. The uclass will try all available drivers when
+ reset_walk() is called.
obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
obj-$(CONFIG_NS87308) += ns87308.o
obj-$(CONFIG_PDSP188x) += pdsp188x.o
+obj-$(CONFIG_SANDBOX) += reset_sandbox.o
ifdef CONFIG_DM_I2C
obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
endif
obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
obj-$(CONFIG_STATUS_LED) += status_led.o
obj-$(CONFIG_SANDBOX) += swap_case.o
+obj-$(CONFIG_SANDBOX) += syscon_sandbox.o
obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
obj-$(CONFIG_PCA9551_LED) += pca9551_led.o
+obj-$(CONFIG_RESET) += reset-uclass.o
#include <asm/system.h>
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+#include <fsl-mc/fsl_mc.h>
#include <fsl_debug_server.h>
DECLARE_GLOBAL_DATA_PTR;
debug_server_ram_addr =
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
+#ifdef CONFIG_FSL_MC_ENET
+ debug_server_ram_addr += mc_get_dram_block_size();
+#endif
+
error = debug_server_parse_firmware_fit_image(&raw_image_addr,
&raw_image_size);
if (error != 0)
u8 pwm; /* Pulse width modulation, see PCA9551_7.pdf p. 6 */
};
-static int freq0, freq1;
+static int freq_last = -1;
+static int mask_last = -1;
+static int idx_last = -1;
+static int mode_last;
static int pca9551_led_get_state(int led, int *state)
{
{
struct pca9551_blink_rate rate;
int mode;
- int blink;
+ int idx;
- if ((freq0 == 0) || (freq == freq0)) {
- blink = 0;
- mode = PCA9551_LED_STATE_BLINK0;
- freq0 = freq;
+ if ((freq == freq_last) || (mask == mask_last)) {
+ idx = idx_last;
+ mode = mode_last;
} else {
- blink = 1;
- mode = PCA9551_LED_STATE_BLINK1;
- freq1 = freq;
+ /* Toggle blink index */
+ if (idx_last == 0) {
+ idx = 1;
+ mode = PCA9551_LED_STATE_BLINK1;
+ } else {
+ idx = 0;
+ mode = PCA9551_LED_STATE_BLINK0;
+ }
+
+ idx_last = idx;
+ mode_last = mode;
}
+ freq_last = freq;
+ mask_last = mask;
rate.psc = ((freq * 38) / 1000) - 1;
rate.pwm = 128; /* 50% duty cycle */
- pca9551_led_set_blink_rate(blink, rate);
+ pca9551_led_set_blink_rate(idx, rate);
pca9551_led_set_state(mask, mode);
}
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <reset.h>
+#include <dm.h>
+#include <errno.h>
+#include <regmap.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <linux/err.h>
+
+int reset_request(struct udevice *dev, enum reset_t type)
+{
+ struct reset_ops *ops = reset_get_ops(dev);
+
+ if (!ops->request)
+ return -ENOSYS;
+
+ return ops->request(dev, type);
+}
+
+int reset_walk(enum reset_t type)
+{
+ struct udevice *dev;
+ int ret = -ENOSYS;
+
+ while (ret != -EINPROGRESS && type < RESET_COUNT) {
+ for (uclass_first_device(UCLASS_RESET, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ ret = reset_request(dev, type);
+ if (ret == -EINPROGRESS)
+ break;
+ }
+ type++;
+ }
+
+ return ret;
+}
+
+void reset_walk_halt(enum reset_t type)
+{
+ int ret;
+
+ ret = reset_walk(type);
+
+ /* Wait for the reset to take effect */
+ if (ret == -EINPROGRESS)
+ mdelay(100);
+
+ /* Still no reset? Give up */
+ printf("Reset not supported on this platform\n");
+ hang();
+}
+
+/**
+ * reset_cpu() - calls reset_walk(RESET_WARM)
+ */
+void reset_cpu(ulong addr)
+{
+ reset_walk_halt(RESET_WARM);
+}
+
+
+int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ reset_walk_halt(RESET_WARM);
+
+ return 0;
+}
+
+UCLASS_DRIVER(reset) = {
+ .id = UCLASS_RESET,
+ .name = "reset",
+};
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <reset.h>
+#include <asm/state.h>
+#include <asm/test.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_warm_reset_request(struct udevice *dev, enum reset_t type)
+{
+ struct sandbox_state *state = state_get_current();
+
+ switch (type) {
+ case RESET_WARM:
+ state->last_reset = type;
+ break;
+ default:
+ return -ENOSYS;
+ }
+ if (!state->reset_allowed[type])
+ return -EACCES;
+
+ return -EINPROGRESS;
+}
+
+static int sandbox_reset_request(struct udevice *dev, enum reset_t type)
+{
+ struct sandbox_state *state = state_get_current();
+
+ /*
+ * If we have a device tree, the device we created from platform data
+ * (see the U_BOOT_DEVICE() declaration below) should not do anything.
+ * If we are that device, return an error.
+ */
+ if (gd->fdt_blob && dev->of_offset == -1)
+ return -ENODEV;
+
+ switch (type) {
+ case RESET_COLD:
+ state->last_reset = type;
+ break;
+ case RESET_POWER:
+ state->last_reset = type;
+ if (!state->reset_allowed[type])
+ return -EACCES;
+ sandbox_exit();
+ break;
+ default:
+ return -ENOSYS;
+ }
+ if (!state->reset_allowed[type])
+ return -EACCES;
+
+ return -EINPROGRESS;
+}
+
+static struct reset_ops sandbox_reset_ops = {
+ .request = sandbox_reset_request,
+};
+
+static const struct udevice_id sandbox_reset_ids[] = {
+ { .compatible = "sandbox,reset" },
+ { }
+};
+
+U_BOOT_DRIVER(reset_sandbox) = {
+ .name = "reset_sandbox",
+ .id = UCLASS_RESET,
+ .of_match = sandbox_reset_ids,
+ .ops = &sandbox_reset_ops,
+};
+
+static struct reset_ops sandbox_warm_reset_ops = {
+ .request = sandbox_warm_reset_request,
+};
+
+static const struct udevice_id sandbox_warm_reset_ids[] = {
+ { .compatible = "sandbox,warm-reset" },
+ { }
+};
+
+U_BOOT_DRIVER(warm_reset_sandbox) = {
+ .name = "warm_reset_sandbox",
+ .id = UCLASS_RESET,
+ .of_match = sandbox_warm_reset_ids,
+ .ops = &sandbox_warm_reset_ops,
+};
+
+/* This is here in case we don't have a device tree */
+U_BOOT_DEVICE(reset_sandbox_non_fdt) = {
+ .name = "reset_sandbox",
+};
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <syscon.h>
+#include <asm/test.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct udevice_id sandbox_syscon_ids[] = {
+ { .compatible = "sandbox,syscon0", .data = SYSCON0 },
+ { .compatible = "sandbox,syscon1", .data = SYSCON1 },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_syscon) = {
+ .name = "sandbox_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = sandbox_syscon_ids,
+};
menu "MMC Host controller Support"
+config DM_MMC
+ bool "Enable MMC controllers using Driver Model"
+ depends on DM
+ help
+ This enables the MultiMediaCard (MMC) uclass which suports MMC and
+ Secure Digital I/O (SDIO) cards. Both removable (SD, micro-SD, etc.)
+ and non-removable (e.g. eMMC chip) devices are supported. These
+ appear as block devices in U-Boot and can support filesystems such
+ as EXT4 and FAT.
+
config SH_SDHI
bool "SuperH/Renesas ARM SoCs on-chip SDHI host controller support"
depends on RMOBILE
# SPDX-License-Identifier: GPL-2.0+
#
+obj-$(CONFIG_DM_MMC) += mmc-uclass.o
+
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
obj-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o
obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o
obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o
obj-$(CONFIG_S3C_SDI) += s3c_sdi.o
obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
+obj-$(CONFIG_SANDBOX) += sandbox_mmc.o
obj-$(CONFIG_SDHCI) += sdhci.o
obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+struct mmc *mmc_get_mmc_dev(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv;
+
+ if (!device_active(dev))
+ return NULL;
+ upriv = dev_get_uclass_priv(dev);
+ return upriv->mmc;
+}
+
+U_BOOT_DRIVER(mmc) = {
+ .name = "mmc",
+ .id = UCLASS_MMC,
+};
+
+UCLASS_DRIVER(mmc) = {
+ .id = UCLASS_MMC,
+ .name = "mmc",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+ .per_device_auto_alloc_size = sizeof(struct mmc_uclass_priv),
+};
return 0;
}
- if (mmc_set_blocklen(mmc, mmc->read_bl_len))
+ if (mmc_set_blocklen(mmc, mmc->read_bl_len)) {
+ debug("%s: Failed to set blocklen\n", __func__);
return 0;
+ }
do {
cur = (blocks_todo > mmc->cfg->b_max) ?
mmc->cfg->b_max : blocks_todo;
- if(mmc_read_blocks(mmc, dst, start, cur) != cur)
+ if (mmc_read_blocks(mmc, dst, start, cur) != cur) {
+ debug("%s: Failed to read blocks\n", __func__);
return 0;
+ }
blocks_todo -= cur;
start += cur;
dst += cur * mmc->read_bl_len;
int mmc_initialize(bd_t *bis)
{
+ static int initialized = 0;
+ if (initialized) /* Avoid initializing mmc multiple times */
+ return 0;
+ initialized = 1;
+
INIT_LIST_HEAD (&mmc_devices);
cur_dev_num = 0;
+#ifndef CONFIG_DM_MMC
if (board_mmc_init(bis) < 0)
cpu_mmc_init(bis);
+#endif
#ifndef CONFIG_SPL_BUILD
print_mmc_devices(',');
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <mmc.h>
+#include <asm/test.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct udevice_id sandbox_mmc_ids[] = {
+ { .compatible = "sandbox,mmc" },
+ { }
+};
+
+U_BOOT_DRIVER(warm_mmc_sandbox) = {
+ .name = "mmc_sandbox",
+ .id = UCLASS_MMC,
+ .of_match = sandbox_mmc_ids,
+};
return !gpio_get_value(cd_pin);
}
+int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc)
+{
+ char *buf = malloc(512);
+ int valid_signature = 0;
+
+ if (buf == NULL)
+ panic("Failed to allocate memory\n");
+
+ if (mmc_getcd(mmc) && mmc_init(mmc) == 0 &&
+ mmc->block_dev.block_read(mmc->block_dev.dev, 16, 1, buf) == 1 &&
+ strncmp(&buf[4], "eGON.BT0", 8) == 0)
+ valid_signature = 1;
+
+ free(buf);
+ return valid_signature;
+}
+
static const struct mmc_ops sunxi_mmc_ops = {
.send_cmd = sunxi_mmc_send_cmd,
.set_ios = sunxi_mmc_set_ios,
* (C) Copyright 2009 SAMSUNG Electronics
* Minkyu Kang <mk7.kang@samsung.com>
* Jaehoon Chung <jh80.chung@samsung.com>
- * Portions Copyright 2011-2013 NVIDIA Corporation
+ * Portions Copyright 2011-2015 NVIDIA Corporation
*
* SPDX-License-Identifier: GPL-2.0+
*/
bbstate->bounce_buffer, bbstate->user_buffer, data->blocks,
data->blocksize);
- writel((u32)bbstate->bounce_buffer, &host->reg->sysad);
+ writel((u32)(unsigned long)bbstate->bounce_buffer, &host->reg->sysad);
/*
* DMASEL[4:3]
* 00 = Selects SDMA
if (cmd->resp_type & MMC_RSP_136) {
/* CRC is stripped so we need to do some shifting. */
for (i = 0; i < 4; i++) {
- unsigned int offset =
- (unsigned int)(&host->reg->rspreg3 - i);
+ unsigned long offset =
+ (unsigned long)(&host->reg->rspreg3 - i);
cmd->response[i] = readl(offset) << 8;
if (i != 3) {
const void *blob = gd->fdt_blob;
debug("%s entry\n", __func__);
+ /* See if any Tegra210 MMC controllers are present */
+ count = fdtdec_find_aliases_for_id(blob, "sdhci",
+ COMPAT_NVIDIA_TEGRA210_SDMMC, node_list,
+ CONFIG_SYS_MMC_MAX_DEVICE);
+ debug("%s: count of Tegra210 sdhci nodes is %d\n", __func__, count);
+ if (process_nodes(blob, node_list, count)) {
+ printf("%s: Error processing T30 mmc node(s)!\n", __func__);
+ return;
+ }
+
/* See if any Tegra124 MMC controllers are present */
count = fdtdec_find_aliases_for_id(blob, "sdhci",
COMPAT_NVIDIA_TEGRA124_SDMMC, node_list,
return _dw_eth_send(priv, packet, length);
}
-static int designware_eth_recv(struct udevice *dev, uchar **packetp)
+static int designware_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct dw_eth_dev *priv = dev_get_priv(dev);
struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
{
int ret;
- struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+ struct qbman_swp *p = malloc(sizeof(struct qbman_swp));
if (!p)
return NULL;
qb_attr_code_encode(&code_sdqcr_dct, &p->sdq, qbman_sdqcr_dct_prio_ics);
qb_attr_code_encode(&code_sdqcr_fc, &p->sdq, qbman_sdqcr_fc_up_to_3);
qb_attr_code_encode(&code_sdqcr_tok, &p->sdq, 0xbb);
- p->vdq.busy = 0; /* TODO: convert to atomic_t */
+ atomic_set(&p->vdq.busy, 1);
p->vdq.valid_bit = QB_VALID_BIT;
p->dqrr.next_idx = 0;
p->dqrr.valid_bit = QB_VALID_BIT;
static struct qb_attr_code code_eq_qd_pri = QB_CODE(4, 16, 4);
static struct qb_attr_code code_eq_rsp_stash = QB_CODE(5, 16, 1);
static struct qb_attr_code code_eq_rsp_lo = QB_CODE(6, 0, 32);
-static struct qb_attr_code code_eq_rsp_hi = QB_CODE(7, 0, 32);
enum qbman_eq_cmd_e {
/* No enqueue, primarily for plugging ORP gaps for dropped frames */
{
uint32_t *cl = qb_cl(d);
- qb_attr_code_encode(&code_eq_rsp_lo, cl, lower32(storage_phys));
- qb_attr_code_encode(&code_eq_rsp_hi, cl, upper32(storage_phys));
+ qb_attr_code_encode_64(&code_eq_rsp_lo, (uint64_t *)cl, storage_phys);
qb_attr_code_encode(&code_eq_rsp_stash, cl, !!stash);
}
static struct qb_attr_code code_pull_token = QB_CODE(0, 16, 8);
static struct qb_attr_code code_pull_dqsource = QB_CODE(1, 0, 24);
static struct qb_attr_code code_pull_rsp_lo = QB_CODE(2, 0, 32);
-static struct qb_attr_code code_pull_rsp_hi = QB_CODE(3, 0, 32);
enum qb_pull_dt_e {
qb_pull_dt_channel,
}
qb_attr_code_encode(&code_pull_rls, cl, 1);
qb_attr_code_encode(&code_pull_stash, cl, !!stash);
- qb_attr_code_encode(&code_pull_rsp_lo, cl, lower32(storage_phys));
- qb_attr_code_encode(&code_pull_rsp_hi, cl, upper32(storage_phys));
+ qb_attr_code_encode_64(&code_pull_rsp_lo, (uint64_t *)cl, storage_phys);
}
void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
uint32_t *p;
uint32_t *cl = qb_cl(d);
- /* TODO: convert to atomic_t */
- if (s->vdq.busy)
+ if (!atomic_dec_and_test(&s->vdq.busy)) {
+ atomic_inc(&s->vdq.busy);
return -EBUSY;
- s->vdq.busy = 1;
+ }
s->vdq.storage = *(void **)&cl[4];
s->vdq.token = qb_attr_code_decode(&code_pull_token, cl);
p = qbman_cena_write_start(&s->sys, QBMAN_CENA_SWP_VDQCR);
{
uint32_t verb;
uint32_t response_verb;
- const struct ldpaa_dq *dq = qbman_cena_read(&s->sys,
- QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
- const uint32_t *p = qb_cl(dq);
+ uint32_t flags;
+ const struct ldpaa_dq *dq;
+ const uint32_t *p;
+ dq = qbman_cena_read(&s->sys, QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ p = qb_cl(dq);
verb = qb_attr_code_decode(&code_dqrr_verb, p);
- /* If the valid-bit isn't of the expected polarity, nothing there */
+
+ /* If the valid-bit isn't of the expected polarity, nothing there. Note,
+ * in the DQRR reset bug workaround, we shouldn't need to skip these
+ * check, because we've already determined that a new entry is available
+ * and we've invalidated the cacheline before reading it, so the
+ * valid-bit behaviour is repaired and should tell us what we already
+ * knew from reading PI.
+ */
if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
qbman_cena_invalidate_prefetch(&s->sys,
- QBMAN_CENA_SWP_DQRR(
- s->dqrr.next_idx));
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
return NULL;
}
/* There's something there. Move "next_idx" attention to the next ring
* entry (and prefetch it) before returning what we found. */
s->dqrr.next_idx++;
- s->dqrr.next_idx &= 3; /* Wrap around at 4 */
+ s->dqrr.next_idx &= QBMAN_DQRR_SIZE - 1; /* Wrap around at 4 */
/* TODO: it's possible to do all this without conditionals, optimise it
* later. */
if (!s->dqrr.next_idx)
s->dqrr.valid_bit ^= QB_VALID_BIT;
- /* VDQCR "no longer busy" hook - if VDQCR shows "busy" and this is a
- * VDQCR result, mark it as non-busy. */
- if (s->vdq.busy) {
- uint32_t flags = ldpaa_dq_flags(dq);
-
- response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
- if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) &&
- (flags & LDPAA_DQ_STAT_VOLATILE))
- s->vdq.busy = 0;
- }
+
+ /* If this is the final response to a volatile dequeue command
+ indicate that the vdq is no longer busy */
+ flags = ldpaa_dq_flags(dq);
+ response_verb = qb_attr_code_decode(&code_dqrr_response, &verb);
+ if ((response_verb == QBMAN_DQRR_RESPONSE_DQ) &&
+ (flags & LDPAA_DQ_STAT_VOLATILE) &&
+ (flags & LDPAA_DQ_STAT_EXPIRED))
+ atomic_inc(&s->vdq.busy);
+
qbman_cena_invalidate_prefetch(&s->sys,
QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
return dq;
* reset "busy". We instead base the decision on whether the current
* result is sitting at the first 'storage' location of the busy
* command. */
- if (s->vdq.busy && (s->vdq.storage == dq))
- s->vdq.busy = 0;
+ if (s->vdq.storage == dq) {
+ s->vdq.storage = NULL;
+ atomic_inc(&s->vdq.busy);
+ }
return 1;
}
/* Management command result codes */
#define QBMAN_MC_RSLT_OK 0xf0
+/* TBD: as of QBMan 4.1, DQRR will be 8 rather than 4! */
+#define QBMAN_DQRR_SIZE 4
+
+
/* --------------------- */
/* portal data structure */
/* --------------------- */
* to whether or not a command can be submitted, not whether or
* not a previously-submitted command is still executing. In
* other words, once proof is seen that the previously-submitted
- * command is executing, "vdq" is no longer "busy". TODO:
- * convert this to "atomic_t" so that it is thread-safe (without
- * locking). */
- int busy;
+ * command is executing, "vdq" is no longer "busy".
+ */
+ atomic_t busy;
uint32_t valid_bit; /* 0x00 or 0x80 */
/* We need to determine when vdq is no longer busy. This depends
* on whether the "busy" (last-submitted) dequeue command is
- * targetting DQRR or main-memory, and detected is based on the
+ * targeting DQRR or main-memory, and detected is based on the
* presence of the dequeue command's "token" showing up in
* dequeue entries in DQRR or main-memory (respectively). Debug
* builds will, when submitting vdq commands, verify that the
return d32_uint32_t(code->lsoffset, code->width, cacheline[code->word]);
}
+
/* encode a field to a cacheline */
static inline void qb_attr_code_encode(const struct qb_attr_code *code,
uint32_t *cacheline, uint32_t val)
| e32_uint32_t(code->lsoffset, code->width, val);
}
+static inline void qb_attr_code_encode_64(const struct qb_attr_code *code,
+ uint64_t *cacheline, uint64_t val)
+{
+ cacheline[code->word / 2] = val;
+}
+
/* ---------------------- */
/* Descriptors/cachelines */
/* ---------------------- */
* a "descriptor" type that the caller can instantiate however they like.
* Ultimately though, it is just a cacheline of binary storage (or something
* smaller when it is known that the descriptor doesn't need all 64 bytes) for
- * holding pre-formatted pieces of harware commands. The performance-critical
+ * holding pre-formatted pieces of hardware commands. The performance-critical
* code can then copy these descriptors directly into hardware command
* registers more efficiently than trying to construct/format commands
* on-the-fly. The API user sees the descriptor as an array of 32-bit words in
#include <errno.h>
#include <asm/io.h>
#include <linux/types.h>
-#include <linux/compat.h>
+#include <asm/atomic.h>
#include <malloc.h>
#include <fsl-mc/fsl_qbman_base.h>
int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
uint16_t token,
- struct dpni_link_cfg *cfg)
+ const struct dpni_link_cfg *cfg)
{
struct mc_command cmd = { 0 };
*
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <common.h>
#include <errno.h>
#include <asm/io.h>
+#include <libfdt.h>
+#include <fdt_support.h>
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/fsl_mc_sys.h>
#include <fsl-mc/fsl_mc_private.h>
#include <fsl-mc/fsl_dpmng.h>
-#include <fsl_debug_server.h>
#include <fsl-mc/fsl_dprc.h>
#include <fsl-mc/fsl_dpio.h>
#include <fsl-mc/fsl_qbman_portal.h>
return 0;
}
+static int mc_fixup_dpc(u64 dpc_addr)
+{
+ void *blob = (void *)dpc_addr;
+ int nodeoffset;
+
+ /* delete any existing ICID pools */
+ nodeoffset = fdt_path_offset(blob, "/resources/icid_pools");
+ if (fdt_del_node(blob, nodeoffset) < 0)
+ printf("\nfsl-mc: WARNING: could not delete ICID pool\n");
+
+ /* add a new pool */
+ nodeoffset = fdt_path_offset(blob, "/resources");
+ if (nodeoffset < 0) {
+ printf("\nfsl-mc: ERROR: DPC is missing /resources\n");
+ return -EINVAL;
+ }
+ nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pools");
+ nodeoffset = fdt_add_subnode(blob, nodeoffset, "icid_pool@0");
+ do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
+ "base_icid", FSL_DPAA2_STREAM_ID_START, 1);
+ do_fixup_by_path_u32(blob, "/resources/icid_pools/icid_pool@0",
+ "num",
+ FSL_DPAA2_STREAM_ID_END -
+ FSL_DPAA2_STREAM_ID_START + 1, 1);
+
+ flush_dcache_range(dpc_addr, dpc_addr + fdt_totalsize(blob));
+
+ return 0;
+}
+
static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
{
u64 mc_dpc_offset;
* Don't return with error here, since the MC firmware can
* still boot without a DPC
*/
- printf("fsl-mc: WARNING: No DPC image found\n");
+ printf("\nfsl-mc: WARNING: No DPC image found");
return 0;
}
dpc_size = fdt_totalsize(dpc_fdt_hdr);
if (dpc_size > CONFIG_SYS_LS_MC_DPC_MAX_LENGTH) {
- printf("fsl-mc: ERROR: Bad DPC image (too large: %d)\n",
+ printf("\nfsl-mc: ERROR: Bad DPC image (too large: %d)\n",
dpc_size);
return -EINVAL;
}
(u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);
#endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */
+ if (mc_fixup_dpc(mc_ram_addr + mc_dpc_offset))
+ return -EINVAL;
+
dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset));
return 0;
}
error = fdt_check_header(dpl_fdt_hdr);
if (error != 0) {
- printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
+ printf("\nfsl-mc: ERROR: Bad DPL image (bad header)\n");
return error;
}
dpl_size = fdt_totalsize(dpl_fdt_hdr);
if (dpl_size > CONFIG_SYS_LS_MC_DPL_MAX_LENGTH) {
- printf("fsl-mc: ERROR: Bad DPL image (too large: %d)\n",
+ printf("\nfsl-mc: ERROR: Bad DPL image (too large: %d)\n",
dpl_size);
return -EINVAL;
}
return timeout_ms;
}
+#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
+static int load_mc_aiop_img(u64 mc_ram_addr, size_t mc_ram_size)
+{
+ void *aiop_img;
+
+ /*
+ * Load the MC AIOP image in the MC private DRAM block:
+ */
+
+ aiop_img = (void *)CONFIG_SYS_LS_MC_AIOP_IMG_ADDR;
+ mc_copy_image("MC AIOP image",
+ (u64)aiop_img, CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH,
+ mc_ram_addr + CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET);
+
+ return 0;
+}
+#endif
static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
{
u32 reg_gsr;
struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
dmb();
- debug("Polling mc_ccsr_regs->reg_gsr ...\n");
assert(timeout_ms > 0);
for (;;) {
udelay(1000); /* throttle polling */
}
if (timeout_ms == 0) {
- if (booting_mc)
- printf("fsl-mc: timeout booting management complex firmware\n");
- else
- printf("fsl-mc: timeout deploying data path layout\n");
+ printf("ERROR: timeout\n");
/* TODO: Get an error status from an MC CCSR register */
return -ETIMEDOUT;
* appropriate errno, so that the status property is set to
* failure in the fsl,dprc device tree node.
*/
- if (booting_mc) {
- printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
- reg_gsr);
- } else {
- printf("fsl-mc: WARNING: Data path layout deployed with error (GSR: %#x)\n",
- reg_gsr);
- }
+ printf("WARNING: Firmware returned an error (GSR: %#x)\n",
+ reg_gsr);
+ } else {
+ printf("SUCCESS\n");
}
+
*final_reg_gsr = reg_gsr;
return 0;
}
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
}
-#ifdef CONFIG_FSL_DEBUG_SERVER
- /*
- * FIXME: I don't think this is right. See get_dram_size_to_hide()
- */
- mc_ram_addr -= debug_server_get_dram_block_size();
-#endif
-
error = calculate_mc_private_ram_params(mc_ram_addr,
mc_ram_size,
&mc_ram_aligned_base_addr,
if (error != 0)
goto out;
+#ifdef CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
+ error = load_mc_aiop_img(mc_ram_addr, mc_ram_size);
+ if (error != 0)
+ goto out;
+#endif
+
debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
dump_mc_ccsr_regs(mc_ccsr_regs);
out_le32(&mc_ccsr_regs->reg_mcfbalr, reg_mcfbalr);
out_le32(&mc_ccsr_regs->reg_mcfbahr,
(u32)(mc_ram_aligned_base_addr >> 32));
- out_le32(&mc_ccsr_regs->reg_mcfapr, MCFAPR_BYPASS_ICID_MASK);
+ out_le32(&mc_ccsr_regs->reg_mcfapr, FSL_BYPASS_AMQ);
/*
* Tell the MC that we want delayed DPL deployment.
*/
out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00);
- printf("\nfsl-mc: Booting Management Complex ...\n");
+ printf("\nfsl-mc: Booting Management Complex ... ");
/*
* Deassert reset and release MC core 0 to run
goto out;
}
- if (MC_VER_MAJOR != mc_ver_info.major)
+ if (MC_VER_MAJOR != mc_ver_info.major) {
printf("fsl-mc: ERROR: Firmware major version mismatch (found: %d, expected: %d)\n",
mc_ver_info.major, MC_VER_MAJOR);
+ printf("fsl-mc: Update the Management Complex firmware\n");
+
+ error = -ENODEV;
+ goto out;
+ }
if (MC_VER_MINOR != mc_ver_info.minor)
printf("fsl-mc: WARNING: Firmware minor version mismatch (found: %d, expected: %d)\n",
* Tell the MC to deploy the DPL:
*/
out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
- printf("\nfsl-mc: Deploying data path layout ...\n");
+ printf("fsl-mc: Deploying data path layout ... ");
error = wait_for_mc(false, ®_gsr);
if (error != 0)
goto out;
+
out:
if (error != 0)
- mc_boot_status = -error;
+ mc_boot_status = error;
else
mc_boot_status = 0;
printf("dpio_enable() failed %d\n", err);
goto err_get_enable;
}
- debug("ce_paddr=0x%llx, ci_paddr=0x%llx, portalid=%d, prios=%d\n",
- attr.qbman_portal_ce_paddr,
- attr.qbman_portal_ci_paddr,
+ debug("ce_offset=0x%llx, ci_offset=0x%llx, portalid=%d, prios=%d\n",
+ attr.qbman_portal_ce_offset,
+ attr.qbman_portal_ci_offset,
attr.qbman_portal_id,
attr.num_priorities);
- p_des.cena_bar = (void *)attr.qbman_portal_ce_paddr;
- p_des.cinh_bar = (void *)attr.qbman_portal_ci_paddr;
+ p_des.cena_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
+ + attr.qbman_portal_ce_offset);
+ p_des.cinh_bar = (void *)(SOC_QBMAN_PORTALS_BASE_ADDR
+ + attr.qbman_portal_ci_offset);
dflt_dpio->sw_portal = qbman_swp_init(&p_des);
if (dflt_dpio->sw_portal == NULL) {
return pkt_size;
}
+#ifdef CONFIG_MCAST_TFTP
+static int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set)
+{
+ return 0;
+}
+#endif
+
/*
* This function initializes the EMAC hardware.
*/
dev->halt = keystone2_eth_close;
dev->send = keystone2_eth_send_packet;
dev->recv = keystone2_eth_rcv_packet;
+#ifdef CONFIG_MCAST_TFTP
+ dev->mcast = keystone2_eth_bcast_addr;
+#endif
eth_register(dev);
uint32_t fd_length;
struct ldpaa_fas *fas;
uint32_t status, err;
+ u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
+ u32 time_start;
struct qbman_release_desc releasedesc;
struct qbman_swp *swp = dflt_dpio->sw_portal;
flush_dcache_range(fd_addr, fd_addr + LDPAA_ETH_RX_BUFFER_SIZE);
qbman_release_desc_clear(&releasedesc);
qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
+ time_start = get_timer(0);
do {
/* Release buffer into the QBMAN */
err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
- } while (err == -EBUSY);
+ } while (get_timer(time_start) < timeo && err == -EBUSY);
+
+ if (err == -EBUSY)
+ printf("Rx frame: QBMAN buffer release fails\n");
+
return;
}
struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
const struct ldpaa_dq *dq;
const struct dpaa_fd *fd;
- int i = 5, err = 0, status, loop = 20;
+ int i = 5, err = 0, status;
+ u32 timeo = (CONFIG_SYS_HZ * 2) / 1000;
+ u32 time_start;
static struct qbman_pull_desc pulldesc;
struct qbman_swp *swp = dflt_dpio->sw_portal;
continue;
}
- do {
- loop--;
- dq = qbman_swp_dqrr_next(swp);
+ time_start = get_timer(0);
- if (!loop)
- break;
- } while (!dq);
+ do {
+ dq = qbman_swp_dqrr_next(swp);
+ } while (get_timer(time_start) < timeo && !dq);
if (dq) {
/* Check for valid frame. If not sent a consume
debug("No frame delivered\n");
qbman_swp_dqrr_consume(swp, dq);
- break;
+ continue;
}
fd = ldpaa_dq_fd(dq);
ldpaa_eth_rx(priv, fd);
qbman_swp_dqrr_consume(swp, dq);
break;
- }
- }
-
- return err;
-}
-
-static void ldpaa_eth_tx_conf(struct ldpaa_eth_priv *priv,
- const struct dpaa_fd *fd)
-{
- uint64_t fd_addr;
- struct ldpaa_fas *fas;
- uint32_t status, err;
- struct qbman_release_desc releasedesc;
- struct qbman_swp *swp = dflt_dpio->sw_portal;
-
- fd_addr = ldpaa_fd_get_addr(fd);
-
-
- debug("TX Conf frame:data addr=0x%p\n", (u64 *)fd_addr);
-
- /* Check the status from the Frame Annotation */
- if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
- fas = (struct ldpaa_fas *)
- ((uint8_t *)(fd_addr) +
- priv->buf_layout.private_data_size);
- status = le32_to_cpu(fas->status);
- if (status & LDPAA_ETH_TXCONF_ERR_MASK) {
- printf("TxConf frame error(s): 0x%08x\n",
- status & LDPAA_ETH_TXCONF_ERR_MASK);
- }
- }
-
- qbman_release_desc_clear(&releasedesc);
- qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
- do {
- /* Release buffer into the QBMAN */
- err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
- } while (err == -EBUSY);
-}
-
-static int ldpaa_eth_pull_dequeue_tx_conf(struct ldpaa_eth_priv *priv)
-{
- const struct ldpaa_dq *dq;
- const struct dpaa_fd *fd;
- int err = 0;
- int i = 5, status, loop = 20;
- static struct qbman_pull_desc pulldesc;
- struct qbman_swp *swp = dflt_dpio->sw_portal;
-
- while (--i) {
- qbman_pull_desc_clear(&pulldesc);
- qbman_pull_desc_set_numframes(&pulldesc, 1);
- qbman_pull_desc_set_fq(&pulldesc, priv->tx_conf_fqid);
-
- err = qbman_swp_pull(swp, &pulldesc);
- if (err < 0) {
- printf("Dequeue TX conf frames error:0x%08x\n", err);
- continue;
- }
-
- do {
- loop--;
- dq = qbman_swp_dqrr_next(swp);
-
- if (!loop)
- break;
- } while (!dq);
-
- if (dq) {
- /* Check for valid frame. If not sent a consume
- * confirmation to QBMAN otherwise give it to NADK
- * application and then send consume confirmation to
- * QBMAN.
- */
- status = (uint8_t)ldpaa_dq_flags(dq);
- if ((status & LDPAA_DQ_STAT_VALIDFRAME) == 0) {
- debug("Dequeue TX conf frames:");
- debug("No frame is delivered\n");
-
- qbman_swp_dqrr_consume(swp, dq);
- break;
- }
- fd = ldpaa_dq_fd(dq);
-
- ldpaa_eth_tx_conf(priv, fd);
- qbman_swp_dqrr_consume(swp, dq);
+ } else {
+ err = -ENODATA;
+ debug("No DQRR entries\n");
break;
}
}
struct dpaa_fd fd;
u64 buffer_start;
int data_offset, err;
+ u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
+ u32 time_start;
struct qbman_swp *swp = dflt_dpio->sw_portal;
struct qbman_eq_desc ed;
+ struct qbman_release_desc releasedesc;
/* Setup the FD fields */
memset(&fd, 0, sizeof(fd));
qbman_eq_desc_clear(&ed);
qbman_eq_desc_set_no_orp(&ed, 0);
qbman_eq_desc_set_qd(&ed, priv->tx_qdid, priv->tx_flow_id, 0);
- err = qbman_swp_enqueue(swp, &ed, (const struct qbman_fd *)(&fd));
- if (err < 0)
+
+ time_start = get_timer(0);
+
+ while (get_timer(time_start) < timeo) {
+ err = qbman_swp_enqueue(swp, &ed,
+ (const struct qbman_fd *)(&fd));
+ if (err != -EBUSY)
+ break;
+ }
+
+ if (err < 0) {
printf("error enqueueing Tx frame\n");
+ goto error;
+ }
+
+ return err;
- mdelay(1);
+error:
+ qbman_release_desc_clear(&releasedesc);
+ qbman_release_desc_set_bpid(&releasedesc, dflt_dpbp->dpbp_attr.bpid);
+ time_start = get_timer(0);
+ do {
+ /* Release buffer into the QBMAN */
+ err = qbman_swp_release(swp, &releasedesc, &buffer_start, 1);
+ } while (get_timer(time_start) < timeo && err == -EBUSY);
- err = ldpaa_eth_pull_dequeue_tx_conf(priv);
- if (err < 0)
- printf("error Tx Conf frame\n");
+ if (err == -EBUSY)
+ printf("TX data: QBMAN buffer release fails\n");
return err;
}
{
struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
struct dpni_queue_attr rx_queue_attr;
- struct dpni_tx_flow_attr tx_flow_attr;
uint8_t mac_addr[6];
int err;
goto err_qdid;
}
- err = dpni_get_tx_flow(dflt_mc_io, priv->dpni_handle, priv->tx_flow_id,
- &tx_flow_attr);
- if (err) {
- printf("dpni_get_tx_flow() failed\n");
- goto err_tx_flow;
- }
-
- priv->tx_conf_fqid = tx_flow_attr.conf_err_attr.queue_attr.fqid;
-
if (!priv->phydev->link)
printf("%s: No link.\n", priv->phydev->dev->name);
return priv->phydev->link ? 0 : -1;
-err_tx_flow:
err_qdid:
err_rx_flow:
dpni_disable(dflt_mc_io, priv->dpni_handle);
priv->tx_flow_id = DPNI_NEW_FLOW_ID;
memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
+ dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR;
+ dflt_tx_flow.conf_err_cfg.use_default_queue = 0;
+ dflt_tx_flow.conf_err_cfg.errors_only = 1;
err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle,
&priv->tx_flow_id, &dflt_tx_flow);
if (err) {
uint32_t rx_dflt_fqid;
uint16_t tx_qdid;
- uint32_t tx_conf_fqid;
uint16_t tx_flow_id;
enum ldpaa_eth_type type; /* 1G or 10G ethernet */
* Modified to use le32_to_cpu and cpu_to_le32 properly
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <net.h>
+#ifndef CONFIG_DM_ETH
#include <netdev.h>
+#endif
#include <asm/io.h>
#include <pci.h>
u32 buf_Haddr;
};
+static unsigned char rxdata[RX_BUF_LEN];
+
#define RTL8169_DESC_SIZE 16
#if ARCH_DMA_MINALIGN > 256
* the driver to allocate descriptors from a pool of non-cached memory.
*/
#if RTL8169_DESC_SIZE < ARCH_DMA_MINALIGN
-#if !defined(CONFIG_SYS_NONCACHED_MEMORY) && !defined(CONFIG_SYS_DCACHE_OFF)
+#if !defined(CONFIG_SYS_NONCACHED_MEMORY) && \
+ !defined(CONFIG_SYS_DCACHE_OFF) && !defined(CONFIG_X86)
#warning cache-line size is larger than descriptor size
#endif
#endif
DEFINE_ALIGN_BUFFER(u8, rxb, NUM_RX_DESC * RX_BUF_SIZE, RTL8169_ALIGN);
struct rtl8169_private {
+ ulong iobase;
void *mmio_addr; /* memory map physical address */
int chipset;
unsigned long cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
static struct pci_device_id supported[] = {
- {PCI_VENDOR_ID_REALTEK, 0x8167},
- {PCI_VENDOR_ID_REALTEK, 0x8168},
- {PCI_VENDOR_ID_REALTEK, 0x8169},
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167) },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168) },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169) },
{}
};
return value;
}
-static int rtl8169_init_board(struct eth_device *dev)
+static int rtl8169_init_board(unsigned long dev_iobase, const char *name)
{
int i;
u32 tmp;
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
- ioaddr = dev->iobase;
+ ioaddr = dev_iobase;
/* Soft reset the chip. */
RTL_W8(ChipCmd, CmdReset);
}
/* if unknown chip, assume array element #0, original RTL-8169 in this case */
- printf("PCI device %s: unknown chip version, assuming RTL-8169\n", dev->name);
+ printf("PCI device %s: unknown chip version, assuming RTL-8169\n",
+ name);
printf("PCI device: TxConfig = 0x%lX\n", (unsigned long) RTL_R32(TxConfig));
tpc->chipset = 0;
/**************************************************************************
RECV - Receive a frame
***************************************************************************/
-static int rtl_recv(struct eth_device *dev)
+static int rtl_recv_common(pci_dev_t bdf, unsigned long dev_iobase,
+ uchar **packetp)
{
/* return true if there's an ethernet packet ready to read */
/* nic->packet should contain data on return */
#ifdef DEBUG_RTL8169_RX
printf ("%s\n", __FUNCTION__);
#endif
- ioaddr = dev->iobase;
+ ioaddr = dev_iobase;
cur_rx = tpc->cur_rx;
if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) {
if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) {
- unsigned char rxdata[RX_BUF_LEN];
length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx].
status) & 0x00001FFF) - 4;
else
tpc->RxDescArray[cur_rx].status =
cpu_to_le32(OWNbit + RX_BUF_SIZE);
- tpc->RxDescArray[cur_rx].buf_addr =
- cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx]));
+ tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(
+ pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)
+ tpc->RxBufferRing[cur_rx]));
rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);
-
+#ifdef CONFIG_DM_ETH
+ *packetp = rxdata;
+#else
net_process_received_packet(rxdata, length);
+#endif
} else {
puts("Error Rx");
+ length = -EIO;
}
cur_rx = (cur_rx + 1) % NUM_RX_DESC;
tpc->cur_rx = cur_rx;
- return 1;
+ return length;
} else {
ushort sts = RTL_R8(IntrStatus);
return (0); /* initially as this is called to flush the input */
}
+#ifdef CONFIG_DM_ETH
+int rtl8169_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct rtl8169_private *priv = dev_get_priv(dev);
+
+ return rtl_recv_common(pci_get_bdf(dev), priv->iobase, packetp);
+}
+#else
+static int rtl_recv(struct eth_device *dev)
+{
+ return rtl_recv_common((pci_dev_t)dev->priv, dev->iobase, NULL);
+}
+#endif /* nCONFIG_DM_ETH */
+
#define HZ 1000
/**************************************************************************
SEND - Transmit a frame
***************************************************************************/
-static int rtl_send(struct eth_device *dev, void *packet, int length)
+static int rtl_send_common(pci_dev_t bdf, unsigned long dev_iobase,
+ void *packet, int length)
{
/* send the packet to destination */
printf("sending %d bytes\n", len);
#endif
- ioaddr = dev->iobase;
+ ioaddr = dev_iobase;
/* point to the current txb incase multiple tx_rings are used */
ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE];
ptxb[len++] = '\0';
tpc->TxDescArray[entry].buf_Haddr = 0;
- tpc->TxDescArray[entry].buf_addr = cpu_to_le32(bus_to_phys(ptxb));
+ tpc->TxDescArray[entry].buf_addr = cpu_to_le32(
+ pci_mem_to_phys(bdf, (pci_addr_t)(unsigned long)ptxb));
if (entry != (NUM_TX_DESC - 1)) {
tpc->TxDescArray[entry].status =
cpu_to_le32((OWNbit | FSbit | LSbit) |
return ret;
}
-static void rtl8169_set_rx_mode(struct eth_device *dev)
+#ifdef CONFIG_DM_ETH
+int rtl8169_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct rtl8169_private *priv = dev_get_priv(dev);
+
+ return rtl_send_common(pci_get_bdf(dev), priv->iobase, packet, length);
+}
+
+#else
+static int rtl_send(struct eth_device *dev, void *packet, int length)
+{
+ return rtl_send_common((pci_dev_t)dev->priv, dev->iobase, packet,
+ length);
+}
+#endif
+
+static void rtl8169_set_rx_mode(void)
{
u32 mc_filter[2]; /* Multicast hash filter */
int rx_mode;
RTL_W32(MAR0 + 4, mc_filter[1]);
}
-static void rtl8169_hw_start(struct eth_device *dev)
+static void rtl8169_hw_start(pci_dev_t bdf)
{
u32 i;
tpc->cur_rx = 0;
- RTL_W32(TxDescStartAddrLow, bus_to_phys(tpc->TxDescArray));
+ RTL_W32(TxDescStartAddrLow, pci_mem_to_phys(bdf,
+ (pci_addr_t)(unsigned long)tpc->TxDescArray));
RTL_W32(TxDescStartAddrHigh, (unsigned long)0);
- RTL_W32(RxDescStartAddrLow, bus_to_phys(tpc->RxDescArray));
+ RTL_W32(RxDescStartAddrLow, pci_mem_to_phys(
+ bdf, (pci_addr_t)(unsigned long)tpc->RxDescArray));
RTL_W32(RxDescStartAddrHigh, (unsigned long)0);
/* RTL-8169sc/8110sc or later version */
RTL_W32(RxMissed, 0);
- rtl8169_set_rx_mode(dev);
+ rtl8169_set_rx_mode();
/* no early-rx interrupts */
RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000);
#endif
}
-static void rtl8169_init_ring(struct eth_device *dev)
+static void rtl8169_init_ring(pci_dev_t bdf)
{
int i;
cpu_to_le32(OWNbit + RX_BUF_SIZE);
tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE];
- tpc->RxDescArray[i].buf_addr =
- cpu_to_le32(bus_to_phys(tpc->RxBufferRing[i]));
+ tpc->RxDescArray[i].buf_addr = cpu_to_le32(pci_mem_to_phys(
+ bdf, (pci_addr_t)(unsigned long)tpc->RxBufferRing[i]));
rtl_flush_rx_desc(&tpc->RxDescArray[i]);
}
#endif
}
-/**************************************************************************
-RESET - Finish setting up the ethernet interface
-***************************************************************************/
-static int rtl_reset(struct eth_device *dev, bd_t *bis)
+static void rtl8169_common_start(pci_dev_t bdf, unsigned char *enetaddr)
{
int i;
printf ("%s\n", __FUNCTION__);
#endif
- rtl8169_init_ring(dev);
- rtl8169_hw_start(dev);
+ rtl8169_init_ring(bdf);
+ rtl8169_hw_start(bdf);
/* Construct a perfect filter frame with the mac address as first match
* and broadcast for all others */
for (i = 0; i < 192; i++)
txb[i] = 0xFF;
- txb[0] = dev->enetaddr[0];
- txb[1] = dev->enetaddr[1];
- txb[2] = dev->enetaddr[2];
- txb[3] = dev->enetaddr[3];
- txb[4] = dev->enetaddr[4];
- txb[5] = dev->enetaddr[5];
+ txb[0] = enetaddr[0];
+ txb[1] = enetaddr[1];
+ txb[2] = enetaddr[2];
+ txb[3] = enetaddr[3];
+ txb[4] = enetaddr[4];
+ txb[5] = enetaddr[5];
#ifdef DEBUG_RTL8169
printf("%s elapsed time : %lu\n", __func__, currticks()-stime);
#endif
- return 0;
}
+#ifdef CONFIG_DM_ETH
+static int rtl8169_eth_start(struct udevice *dev)
+{
+ struct eth_pdata *plat = dev_get_platdata(dev);
+
+ rtl8169_common_start(pci_get_bdf(dev), plat->enetaddr);
+
+ return 0;
+}
+#else
/**************************************************************************
-HALT - Turn off ethernet interface
+RESET - Finish setting up the ethernet interface
***************************************************************************/
-static void rtl_halt(struct eth_device *dev)
+static int rtl_reset(struct eth_device *dev, bd_t *bis)
+{
+ rtl8169_common_start((pci_dev_t)dev->priv, dev->enetaddr);
+
+ return 0;
+}
+#endif /* nCONFIG_DM_ETH */
+
+static void rtl_halt_common(unsigned long dev_iobase)
{
int i;
printf ("%s\n", __FUNCTION__);
#endif
- ioaddr = dev->iobase;
+ ioaddr = dev_iobase;
/* Stop the chip's Tx and Rx DMA processes. */
RTL_W8(ChipCmd, 0x00);
}
}
+#ifdef CONFIG_DM_ETH
+void rtl8169_eth_stop(struct udevice *dev)
+{
+ struct rtl8169_private *priv = dev_get_priv(dev);
+
+ rtl_halt_common(priv->iobase);
+}
+#else
+/**************************************************************************
+HALT - Turn off ethernet interface
+***************************************************************************/
+static void rtl_halt(struct eth_device *dev)
+{
+ rtl_halt_common(dev->iobase);
+}
+#endif
+
/**************************************************************************
INIT - Look for an adapter, this routine's visible to the outside
***************************************************************************/
#define board_found 1
#define valid_link 0
-static int rtl_init(struct eth_device *dev, bd_t *bis)
+static int rtl_init(unsigned long dev_ioaddr, const char *name,
+ unsigned char *enetaddr)
{
static int board_idx = -1;
int i, rc;
#ifdef DEBUG_RTL8169
printf ("%s\n", __FUNCTION__);
#endif
-
- ioaddr = dev->iobase;
+ ioaddr = dev_ioaddr;
board_idx++;
/* point to private storage */
tpc = &tpx;
- rc = rtl8169_init_board(dev);
+ rc = rtl8169_init_board(ioaddr, name);
if (rc)
return rc;
/* Get MAC address. FIXME: read EEPROM */
for (i = 0; i < MAC_ADDR_LEN; i++)
- dev->enetaddr[i] = RTL_R8(MAC0 + i);
+ enetaddr[i] = RTL_R8(MAC0 + i);
#ifdef DEBUG_RTL8169
printf("chipset = %d\n", tpc->chipset);
printf("MAC Address");
for (i = 0; i < MAC_ADDR_LEN; i++)
- printf(":%02x", dev->enetaddr[i]);
+ printf(":%02x", enetaddr[i]);
putc('\n');
#endif
#ifdef DEBUG_RTL8169
/* Print out some hardware info */
- printf("%s: at ioaddr 0x%lx\n", dev->name, ioaddr);
+ printf("%s: at ioaddr 0x%lx\n", name, ioaddr);
#endif
/* if TBI is not endbled */
return 0;
}
+#ifndef CONFIG_DM_ETH
int rtl8169_initialize(bd_t *bis)
{
pci_dev_t devno;
dev->send = rtl_send;
dev->recv = rtl_recv;
- err = rtl_init(dev, bis);
+ err = rtl_init(dev->iobase, dev->name, dev->enetaddr);
if (err < 0) {
printf(pr_fmt("failed to initialize card: %d\n"), err);
free(dev);
}
return card_number;
}
+#endif
+
+#ifdef CONFIG_DM_ETH
+static int rtl8169_eth_probe(struct udevice *dev)
+{
+ struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
+ struct rtl8169_private *priv = dev_get_priv(dev);
+ struct eth_pdata *plat = dev_get_platdata(dev);
+ u32 iobase;
+ int region;
+ int ret;
+
+ debug("rtl8169: REALTEK RTL8169 @0x%x\n", iobase);
+ switch (pplat->device) {
+ case 0x8168:
+ region = 2;
+ break;
+ default:
+ region = 1;
+ break;
+ }
+ pci_read_config32(pci_get_bdf(dev), PCI_BASE_ADDRESS_0 + region * 4,
+ &iobase);
+ iobase &= ~0xf;
+ priv->iobase = (int)pci_mem_to_phys(pci_get_bdf(dev), iobase);
+
+ ret = rtl_init(priv->iobase, dev->name, plat->enetaddr);
+ if (ret < 0) {
+ printf(pr_fmt("failed to initialize card: %d\n"), ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct eth_ops rtl8169_eth_ops = {
+ .start = rtl8169_eth_start,
+ .send = rtl8169_eth_send,
+ .recv = rtl8169_eth_recv,
+ .stop = rtl8169_eth_stop,
+};
+
+static const struct udevice_id rtl8169_eth_ids[] = {
+ { .compatible = "realtek,rtl8169" },
+ { }
+};
+
+U_BOOT_DRIVER(eth_rtl8169) = {
+ .name = "eth_rtl8169",
+ .id = UCLASS_ETH,
+ .of_match = rtl8169_eth_ids,
+ .probe = rtl8169_eth_probe,
+ .ops = &rtl8169_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct rtl8169_private),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
+
+U_BOOT_PCI_DEVICE(eth_rtl8169, supported);
+#endif
return sandbox_eth_raw_os_send(packet, length, priv);
}
-static int sb_eth_raw_recv(struct udevice *dev, uchar **packetp)
+static int sb_eth_raw_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
return 0;
}
-static int sb_eth_recv(struct udevice *dev, uchar **packetp)
+static int sb_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct eth_sandbox_priv *priv = dev_get_priv(dev);
return _sunxi_emac_eth_send(priv, packet, length);
}
-static int sunxi_emac_eth_recv(struct udevice *dev, uchar **packetp)
+static int sunxi_emac_eth_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct emac_eth_dev *priv = dev_get_priv(dev);
int rx_len;
#include <phy.h>
#include <miiphy.h>
#include <watchdog.h>
+#include <asm/system.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000080000 /* Div pclk by 32, 80MHz */
#define ZYNQ_GEM_NWCFG_MDCCLKDIV2 0x0000c0000 /* Div pclk by 48, 120MHz */
-#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_NWCFG_FDEN | \
+#ifdef CONFIG_ARM64
+# define ZYNQ_GEM_DBUS_WIDTH (1 << 21) /* 64 bit bus */
+#else
+# define ZYNQ_GEM_DBUS_WIDTH (0 << 21) /* 32 bit bus */
+#endif
+
+#define ZYNQ_GEM_NWCFG_INIT (ZYNQ_GEM_DBUS_WIDTH | \
+ ZYNQ_GEM_NWCFG_FDEN | \
ZYNQ_GEM_NWCFG_FSREM | \
ZYNQ_GEM_NWCFG_MDCCLKDIV)
u32 status;
};
-#define RX_BUF 3
+#define RX_BUF 32
/* Page table entries are set to 1MB, or multiples of 1MB
* (not < 1MB). driver uses less bd's so use 1MB bdspace.
*/
static inline int mdio_wait(struct eth_device *dev)
{
struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
- u32 timeout = 200;
+ u32 timeout = 20000;
/* Wait till MDIO interface is ready to accept a new transaction. */
while (--timeout) {
priv->tx_bd->addr = (u32)ptr;
priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
- ZYNQ_GEM_TXBUF_LAST_MASK;
+ ZYNQ_GEM_TXBUF_LAST_MASK |
+ ZYNQ_GEM_TXBUF_WRAP_MASK;
addr = (u32) ptr;
addr &= ~(ARCH_DMA_MINALIGN - 1);
size = roundup(len, ARCH_DMA_MINALIGN);
flush_dcache_range(addr, addr + size);
+
+ addr = (u32)priv->rxbuffers;
+ addr &= ~(ARCH_DMA_MINALIGN - 1);
+ size = roundup((RX_BUF * PKTSIZE_ALIGN), ARCH_DMA_MINALIGN);
+ flush_dcache_range(addr, addr + size);
barrier();
/* Start transmit */
if (frame_len) {
u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK;
addr &= ~(ARCH_DMA_MINALIGN - 1);
- u32 size = roundup(frame_len, ARCH_DMA_MINALIGN);
- invalidate_dcache_range(addr, addr + size);
net_process_received_packet((u8 *)addr, frame_len);
priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN);
memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN);
- /* Align bd_space to 1MB */
+ /* Align bd_space to MMU_SECTION_SHIFT */
bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE);
mmu_set_region_dcache_behaviour((phys_addr_t)bd_space,
BD_SPACE, DCACHE_OFF);
return dev_get_uclass_priv(bus);
}
+pci_dev_t pci_get_bdf(struct udevice *dev)
+{
+ struct pci_child_platdata *pplat = dev_get_parent_platdata(dev);
+ struct udevice *bus = dev->parent;
+
+ return PCI_ADD_BUS(bus->seq, pplat->devfn);
+}
+
/**
* pci_get_bus_max() - returns the bus number of the last active bus
*
if (ret)
return ret;
- return pci_bus_write_config(bus, PCI_MASK_BUS(bdf), offset, value,
- size);
+ return pci_bus_write_config(bus, bdf, offset, value, size);
}
int pci_write_config32(pci_dev_t bdf, int offset, u32 value)
if (ret)
return ret;
- return pci_bus_read_config(bus, PCI_MASK_BUS(bdf), offset, valuep,
- size);
+ return pci_bus_read_config(bus, bdf, offset, valuep, size);
}
int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep)
for (ret = device_find_first_child(bus, &dev);
!ret && dev;
ret = device_find_next_child(&dev)) {
- struct pci_child_platdata *pplat;
- struct pci_controller *ctlr_hose;
-
- pplat = dev_get_parent_platdata(dev);
unsigned int max_bus;
- pci_dev_t bdf;
- bdf = PCI_ADD_BUS(bus->seq, pplat->devfn);
debug("%s: device %s\n", __func__, dev->name);
-
- /* The root controller has the region information */
- ctlr_hose = hose->ctlr->uclass_priv;
- max_bus = pciauto_config_device(ctlr_hose, bdf);
+ max_bus = pciauto_config_device(hose, pci_get_bdf(dev));
sub_bus = max(sub_bus, max_bus);
}
debug("%s: done\n", __func__);
parent = hose->bus;
/* Find the bus within the parent */
- ret = pci_bus_find_devfn(parent, bdf, &bus);
+ ret = pci_bus_find_devfn(parent, PCI_MASK_BUS(bdf), &bus);
if (ret) {
debug("%s: Cannot find device %x on bus %s: %d\n", __func__,
bdf, parent->name, ret);
return sub_bus;
}
+/**
+ * pci_match_one_device - Tell if a PCI device structure has a matching
+ * PCI device id structure
+ * @id: single PCI device id structure to match
+ * @dev: the PCI device structure to match against
+ *
+ * Returns the matching pci_device_id structure or %NULL if there is no match.
+ */
+static bool pci_match_one_id(const struct pci_device_id *id,
+ const struct pci_device_id *find)
+{
+ if ((id->vendor == PCI_ANY_ID || id->vendor == find->vendor) &&
+ (id->device == PCI_ANY_ID || id->device == find->device) &&
+ (id->subvendor == PCI_ANY_ID || id->subvendor == find->subvendor) &&
+ (id->subdevice == PCI_ANY_ID || id->subdevice == find->subdevice) &&
+ !((id->class ^ find->class) & id->class_mask))
+ return true;
+
+ return false;
+}
+
+/**
+ * pci_find_and_bind_driver() - Find and bind the right PCI driver
+ *
+ * This only looks at certain fields in the descriptor.
+ */
+static int pci_find_and_bind_driver(struct udevice *parent,
+ struct pci_device_id *find_id, pci_dev_t bdf,
+ struct udevice **devp)
+{
+ struct pci_driver_entry *start, *entry;
+ const char *drv;
+ int n_ents;
+ int ret;
+ char name[30], *str;
+
+ *devp = NULL;
+
+ debug("%s: Searching for driver: vendor=%x, device=%x\n", __func__,
+ find_id->vendor, find_id->device);
+ start = ll_entry_start(struct pci_driver_entry, pci_driver_entry);
+ n_ents = ll_entry_count(struct pci_driver_entry, pci_driver_entry);
+ for (entry = start; entry != start + n_ents; entry++) {
+ const struct pci_device_id *id;
+ struct udevice *dev;
+ const struct driver *drv;
+
+ for (id = entry->match;
+ id->vendor || id->subvendor || id->class_mask;
+ id++) {
+ if (!pci_match_one_id(id, find_id))
+ continue;
+
+ drv = entry->driver;
+ /*
+ * We could pass the descriptor to the driver as
+ * platdata (instead of NULL) and allow its bind()
+ * method to return -ENOENT if it doesn't support this
+ * device. That way we could continue the search to
+ * find another driver. For now this doesn't seem
+ * necesssary, so just bind the first match.
+ */
+ ret = device_bind(parent, drv, drv->name, NULL, -1,
+ &dev);
+ if (ret)
+ goto error;
+ debug("%s: Match found: %s\n", __func__, drv->name);
+ dev->driver_data = find_id->driver_data;
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ /* Bind a generic driver so that the device can be used */
+ sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf),
+ PCI_FUNC(bdf));
+ str = strdup(name);
+ if (!str)
+ return -ENOMEM;
+ drv = (find_id->class >> 8) == PCI_CLASS_BRIDGE_PCI ? "pci_bridge_drv" :
+ "pci_generic_drv";
+ ret = device_bind_driver(parent, drv, str, devp);
+ if (ret) {
+ debug("%s: Failed to bind generic driver: %d", __func__, ret);
+ return ret;
+ }
+ debug("%s: No match found: bound generic driver instead\n", __func__);
+
+ return 0;
+
+error:
+ debug("%s: No match found: error %d\n", __func__, ret);
+ return ret;
+}
+
int pci_bind_bus_devices(struct udevice *bus)
{
ulong vendor, device;
ulong header_type;
- pci_dev_t devfn, end;
+ pci_dev_t bdf, end;
bool found_multi;
int ret;
found_multi = false;
- end = PCI_DEVFN(PCI_MAX_PCI_DEVICES - 1, PCI_MAX_PCI_FUNCTIONS - 1);
- for (devfn = PCI_DEVFN(0, 0); devfn < end; devfn += PCI_DEVFN(0, 1)) {
+ end = PCI_BDF(bus->seq, PCI_MAX_PCI_DEVICES - 1,
+ PCI_MAX_PCI_FUNCTIONS - 1);
+ for (bdf = PCI_BDF(bus->seq, 0, 0); bdf < end;
+ bdf += PCI_BDF(0, 0, 1)) {
struct pci_child_platdata *pplat;
struct udevice *dev;
ulong class;
- if (PCI_FUNC(devfn) && !found_multi)
+ if (PCI_FUNC(bdf) && !found_multi)
continue;
/* Check only the first access, we don't expect problems */
- ret = pci_bus_read_config(bus, devfn, PCI_HEADER_TYPE,
+ ret = pci_bus_read_config(bus, bdf, PCI_HEADER_TYPE,
&header_type, PCI_SIZE_8);
if (ret)
goto error;
- pci_bus_read_config(bus, devfn, PCI_VENDOR_ID, &vendor,
+ pci_bus_read_config(bus, bdf, PCI_VENDOR_ID, &vendor,
PCI_SIZE_16);
if (vendor == 0xffff || vendor == 0x0000)
continue;
- if (!PCI_FUNC(devfn))
+ if (!PCI_FUNC(bdf))
found_multi = header_type & 0x80;
debug("%s: bus %d/%s: found device %x, function %d\n", __func__,
- bus->seq, bus->name, PCI_DEV(devfn), PCI_FUNC(devfn));
- pci_bus_read_config(bus, devfn, PCI_DEVICE_ID, &device,
- PCI_SIZE_16);
- pci_bus_read_config(bus, devfn, PCI_CLASS_DEVICE, &class,
+ bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf));
+ pci_bus_read_config(bus, bdf, PCI_DEVICE_ID, &device,
PCI_SIZE_16);
+ pci_bus_read_config(bus, bdf, PCI_CLASS_REVISION, &class,
+ PCI_SIZE_32);
+ class >>= 8;
/* Find this device in the device tree */
- ret = pci_bus_find_devfn(bus, devfn, &dev);
+ ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev);
+
+ /* Search for a driver */
/* If nothing in the device tree, bind a generic device */
if (ret == -ENODEV) {
- char name[30], *str;
- const char *drv;
-
- sprintf(name, "pci_%x:%x.%x", bus->seq,
- PCI_DEV(devfn), PCI_FUNC(devfn));
- str = strdup(name);
- if (!str)
- return -ENOMEM;
- drv = class == PCI_CLASS_BRIDGE_PCI ?
- "pci_bridge_drv" : "pci_generic_drv";
- ret = device_bind_driver(bus, drv, str, &dev);
+ struct pci_device_id find_id;
+ ulong val;
+
+ memset(&find_id, '\0', sizeof(find_id));
+ find_id.vendor = vendor;
+ find_id.device = device;
+ find_id.class = class;
+ if ((header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) {
+ pci_bus_read_config(bus, bdf,
+ PCI_SUBSYSTEM_VENDOR_ID,
+ &val, PCI_SIZE_32);
+ find_id.subvendor = val & 0xffff;
+ find_id.subdevice = val >> 16;
+ }
+ ret = pci_find_and_bind_driver(bus, &find_id, bdf,
+ &dev);
}
if (ret)
return ret;
/* Update the platform data */
pplat = dev_get_parent_platdata(dev);
- pplat->devfn = devfn;
+ pplat->devfn = PCI_MASK_BUS(bdf);
pplat->vendor = vendor;
pplat->device = device;
pplat->class = class;
return 0;
}
-int pci_bridge_read_config(struct udevice *bus, pci_dev_t devfn, uint offset,
- ulong *valuep, enum pci_size_t size)
+static int pci_bridge_read_config(struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong *valuep,
+ enum pci_size_t size)
{
struct pci_controller *hose = bus->uclass_priv;
- pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn);
return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size);
}
-int pci_bridge_write_config(struct udevice *bus, pci_dev_t devfn, uint offset,
- ulong value, enum pci_size_t size)
+static int pci_bridge_write_config(struct udevice *bus, pci_dev_t bdf,
+ uint offset, ulong value,
+ enum pci_size_t size)
{
struct pci_controller *hose = bus->uclass_priv;
- pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn);
return pci_bus_write_config(hose->ctlr, bdf, offset, value, size);
}
void pciauto_prescan_setup_bridge(struct pci_controller *hose,
pci_dev_t dev, int sub_bus)
{
- struct pci_region *pci_mem = hose->pci_mem;
- struct pci_region *pci_prefetch = hose->pci_prefetch;
- struct pci_region *pci_io = hose->pci_io;
+ struct pci_region *pci_mem;
+ struct pci_region *pci_prefetch;
+ struct pci_region *pci_io;
u16 cmdstat, prefechable_64;
+#ifdef CONFIG_DM_PCI
+ /* The root controller has the region information */
+ struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
+
+ pci_mem = ctlr_hose->pci_mem;
+ pci_prefetch = ctlr_hose->pci_prefetch;
+ pci_io = ctlr_hose->pci_io;
+#else
+ pci_mem = hose->pci_mem;
+ pci_prefetch = hose->pci_prefetch;
+ pci_io = hose->pci_io;
+#endif
+
pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);
pci_hose_read_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
&prefechable_64);
prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK;
/* Configure bus number registers */
+#ifdef CONFIG_DM_PCI
+ pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, PCI_BUS(dev));
+ pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS, sub_bus);
+#else
pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS,
PCI_BUS(dev) - hose->first_busno);
pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS,
sub_bus - hose->first_busno);
+#endif
pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
if (pci_mem) {
void pciauto_postscan_setup_bridge(struct pci_controller *hose,
pci_dev_t dev, int sub_bus)
{
- struct pci_region *pci_mem = hose->pci_mem;
- struct pci_region *pci_prefetch = hose->pci_prefetch;
- struct pci_region *pci_io = hose->pci_io;
+ struct pci_region *pci_mem;
+ struct pci_region *pci_prefetch;
+ struct pci_region *pci_io;
+
+#ifdef CONFIG_DM_PCI
+ /* The root controller has the region information */
+ struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
+
+ pci_mem = ctlr_hose->pci_mem;
+ pci_prefetch = ctlr_hose->pci_prefetch;
+ pci_io = ctlr_hose->pci_io;
+#else
+ pci_mem = hose->pci_mem;
+ pci_prefetch = hose->pci_prefetch;
+ pci_io = hose->pci_io;
+#endif
/* Configure bus number registers */
+#ifdef CONFIG_DM_PCI
+ pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, sub_bus);
+#else
pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS,
sub_bus - hose->first_busno);
+#endif
if (pci_mem) {
/* Round memory allocator to 1MB boundary */
*/
int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
{
+ struct pci_region *pci_mem;
+ struct pci_region *pci_prefetch;
+ struct pci_region *pci_io;
unsigned int sub_bus = PCI_BUS(dev);
unsigned short class;
int n;
+#ifdef CONFIG_DM_PCI
+ /* The root controller has the region information */
+ struct pci_controller *ctlr_hose = pci_bus_to_hose(0);
+
+ pci_mem = ctlr_hose->pci_mem;
+ pci_prefetch = ctlr_hose->pci_prefetch;
+ pci_io = ctlr_hose->pci_io;
+#else
+ pci_mem = hose->pci_mem;
+ pci_prefetch = hose->pci_prefetch;
+ pci_io = hose->pci_io;
+#endif
+
pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
switch (class) {
DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n",
PCI_DEV(dev));
- pciauto_setup_device(hose, dev, 2, hose->pci_mem,
- hose->pci_prefetch, hose->pci_io);
+ pciauto_setup_device(hose, dev, 2, pci_mem,
+ pci_prefetch, pci_io);
#ifdef CONFIG_DM_PCI
n = dm_pci_hose_probe_bus(hose, dev);
* just do a minimal setup of the bridge,
* let the OS take care of the rest
*/
- pciauto_setup_device(hose, dev, 0, hose->pci_mem,
- hose->pci_prefetch, hose->pci_io);
+ pciauto_setup_device(hose, dev, 0, pci_mem,
+ pci_prefetch, pci_io);
DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
PCI_DEV(dev));
DEBUGF("PCI AutoConfig: Found PowerPC device\n");
default:
- pciauto_setup_device(hose, dev, 6, hose->pci_mem,
- hose->pci_prefetch, hose->pci_io);
+ pciauto_setup_device(hose, dev, 6, pci_mem,
+ pci_prefetch, pci_io);
break;
}
#ifdef CONFIG_DM_PCI
/* The root controller has the region information */
- hose = hose->ctlr->uclass_priv;
+ hose = pci_bus_to_hose(0);
#endif
/*
return bus_addr;
}
+#ifdef CONFIG_DM_PCI
+ /* The root controller has the region information */
+ hose = pci_bus_to_hose(0);
+#endif
+
/*
* if PCI_REGION_MEM is set we do a two pass search with preference
* on matches that don't have PCI_REGION_SYS_MEMORY set
pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
{
- struct pci_child_platdata *pplat;
- struct udevice *bus, *dev;
+ struct udevice *dev;
if (pci_find_device_id(ids, index, &dev))
return -1;
- bus = dev->parent;
- pplat = dev_get_parent_platdata(dev);
-
- return PCI_ADD_BUS(bus->seq, pplat->devfn);
+ return pci_get_bdf(dev);
}
#include <asm/io.h>
#include <errno.h>
#include <malloc.h>
+#include <asm/arch-fsl-lsch3/fdt.h>
#ifndef CONFIG_SYS_PCI_MEMORY_BUS
#define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE
{
}
#endif
+
+#ifdef CONFIG_LS2085A
+
+void pcie_set_available_streamids(void *blob, const char *pcie_path,
+ u32 *stream_ids, int count)
+{
+ int nodeoffset;
+ int i;
+
+ nodeoffset = fdt_path_offset(blob, pcie_path);
+ if (nodeoffset < 0) {
+ printf("\n%s: ERROR: unable to update PCIe node\n", __func__);
+ return;
+ }
+
+ /* for each stream ID, append to mmu-masters */
+ for (i = 0; i < count; i++) {
+ fdt_appendprop_u32(blob, nodeoffset, "available-stream-ids",
+ stream_ids[i]);
+ }
+}
+
+#define MAX_STREAM_IDS 4
+void fdt_fixup_smmu_pcie(void *blob)
+{
+ int count;
+ u32 stream_ids[MAX_STREAM_IDS];
+
+ #ifdef CONFIG_PCIE1
+ /* PEX1 stream ID fixup */
+ count = FSL_PEX1_STREAM_ID_END - FSL_PEX1_STREAM_ID_START + 1;
+ alloc_stream_ids(FSL_PEX1_STREAM_ID_START, count, stream_ids,
+ MAX_STREAM_IDS);
+ pcie_set_available_streamids(blob, "/pcie@3400000", stream_ids, count);
+ #endif
+
+ #ifdef CONFIG_PCIE2
+ /* PEX2 stream ID fixup */
+ count = FSL_PEX2_STREAM_ID_END - FSL_PEX2_STREAM_ID_START + 1;
+ alloc_stream_ids(FSL_PEX2_STREAM_ID_START, count, stream_ids,
+ MAX_STREAM_IDS);
+ pcie_set_available_streamids(blob, "/pcie@3500000", stream_ids, count);
+ #endif
+
+ #ifdef CONFIG_PCIE3
+ /* PEX3 stream ID fixup */
+ count = FSL_PEX3_STREAM_ID_END - FSL_PEX3_STREAM_ID_START + 1;
+ alloc_stream_ids(FSL_PEX3_STREAM_ID_START, count, stream_ids,
+ MAX_STREAM_IDS);
+ pcie_set_available_streamids(blob, "/pcie@3600000", stream_ids, count);
+ #endif
+
+ #ifdef CONFIG_PCIE4
+ /* PEX4 stream ID fixup */
+ count = FSL_PEX4_STREAM_ID_END - FSL_PEX4_STREAM_ID_START + 1;
+ alloc_stream_ids(FSL_PEX4_STREAM_ID_START, count, stream_ids,
+ MAX_STREAM_IDS);
+ pcie_set_available_streamids(blob, "/pcie@3700000", stream_ids, count);
+ #endif
+}
+#endif
#include <fdtdec.h>
#include <errno.h>
#include <dm.h>
+#include <vsprintf.h>
#include <dm/lists.h>
#include <dm/device-internal.h>
#include <dm/uclass-internal.h>
DECLARE_GLOBAL_DATA_PTR;
-static ulong str_get_num(const char *ptr, const char *maxptr)
-{
- if (!ptr || !maxptr)
- return 0;
-
- while (!isdigit(*ptr) && ptr++ < maxptr);
-
- return simple_strtoul(ptr, NULL, 0);
-}
-
int pmic_bind_children(struct udevice *pmic, int offset,
const struct pmic_child_info *child_info)
{
struct driver *drv;
struct udevice *child;
const char *node_name;
- int node_name_len;
int bind_count = 0;
int node;
int prefix_len;
for (node = fdt_first_subnode(blob, offset);
node > 0;
node = fdt_next_subnode(blob, node)) {
- node_name = fdt_get_name(blob, node, &node_name_len);
+ node_name = fdt_get_name(blob, node, NULL);
debug("* Found child node: '%s' at offset:%d\n", node_name,
node);
child = NULL;
for (info = child_info; info->prefix && info->driver; info++) {
+ debug(" - compatible prefix: '%s'\n", info->prefix);
+
prefix_len = strlen(info->prefix);
- if (strncasecmp(info->prefix, node_name, prefix_len))
+ if (strncmp(info->prefix, node_name, prefix_len))
continue;
- debug(" - compatible prefix: '%s'\n", info->prefix);
-
drv = lists_driver_lookup_name(info->driver);
if (!drv) {
debug(" - driver: '%s' not found!\n",
debug(" - bound child device: '%s'\n", child->name);
- child->driver_data = str_get_num(node_name +
- prefix_len,
- node_name +
- node_name_len);
+ child->driver_data = trailing_strtol(node_name);
debug(" - set 'child->driver_data': %lu\n",
child->driver_data);
return ops->write(dev, reg, buffer, len);
}
+int pmic_reg_read(struct udevice *dev, uint reg)
+{
+ u8 byte;
+ int ret;
+
+ ret = pmic_read(dev, reg, &byte, 1);
+ debug("%s: reg=%x, value=%x\n", __func__, reg, byte);
+
+ return ret ? ret : byte;
+}
+
+int pmic_reg_write(struct udevice *dev, uint reg, uint value)
+{
+ u8 byte = value;
+
+ debug("%s: reg=%x, value=%x\n", __func__, reg, value);
+ return pmic_read(dev, reg, &byte, 1);
+}
+
+int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set)
+{
+ u8 byte;
+ int ret;
+
+ ret = pmic_reg_read(dev, reg);
+ if (ret < 0)
+ return ret;
+ byte = (ret & ~clr) | set;
+
+ return pmic_reg_write(dev, reg, byte);
+}
+
UCLASS_DRIVER(pmic) = {
.id = UCLASS_PMIC,
.name = "pmic",
return uclass_get_device_by_name(UCLASS_REGULATOR, devname, devp);
}
-static int failed(int ret, bool verbose, const char *fmt, ...)
+int regulator_autoset(struct udevice *dev)
{
- va_list args;
- char buf[64];
-
- if (verbose == false)
- return ret;
+ struct dm_regulator_uclass_platdata *uc_pdata;
+ int ret = 0;
- va_start(args, fmt);
- vscnprintf(buf, sizeof(buf), fmt, args);
- va_end(args);
+ uc_pdata = dev_get_uclass_platdata(dev);
+ if (!uc_pdata->always_on && !uc_pdata->boot_on)
+ return -EMEDIUMTYPE;
- printf(buf);
+ if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
+ ret = regulator_set_value(dev, uc_pdata->min_uV);
+ if (!ret && (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA))
+ ret = regulator_set_current(dev, uc_pdata->min_uA);
if (!ret)
- return 0;
-
- printf(" (ret: %d)", ret);
+ ret = regulator_set_enable(dev, true);
return ret;
}
-int regulator_autoset(const char *platname,
- struct udevice **devp,
- bool verbose)
+static void regulator_show(struct udevice *dev, int ret)
{
struct dm_regulator_uclass_platdata *uc_pdata;
- struct udevice *dev;
- int ret;
-
- if (devp)
- *devp = NULL;
-
- ret = regulator_get_by_platname(platname, &dev);
- if (ret) {
- error("Can get the regulator: %s!", platname);
- return ret;
- }
uc_pdata = dev_get_uclass_platdata(dev);
- if (!uc_pdata) {
- error("Can get the regulator %s uclass platdata!", platname);
- return -ENXIO;
- }
- if (!uc_pdata->always_on && !uc_pdata->boot_on)
- goto retdev;
-
- if (verbose)
- printf("%s@%s: ", dev->name, uc_pdata->name);
-
- /* Those values are optional (-ENODATA if unset) */
- if ((uc_pdata->min_uV != -ENODATA) &&
- (uc_pdata->max_uV != -ENODATA) &&
- (uc_pdata->min_uV == uc_pdata->max_uV)) {
- ret = regulator_set_value(dev, uc_pdata->min_uV);
- if (failed(ret, verbose, "set %d uV", uc_pdata->min_uV))
- goto exit;
- }
-
- /* Those values are optional (-ENODATA if unset) */
- if ((uc_pdata->min_uA != -ENODATA) &&
- (uc_pdata->max_uA != -ENODATA) &&
- (uc_pdata->min_uA == uc_pdata->max_uA)) {
- ret = regulator_set_current(dev, uc_pdata->min_uA);
- if (failed(ret, verbose, "; set %d uA", uc_pdata->min_uA))
- goto exit;
- }
+ printf("%s@%s: ", dev->name, uc_pdata->name);
+ if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UV)
+ printf("set %d uV", uc_pdata->min_uV);
+ if (uc_pdata->flags & REGULATOR_FLAG_AUTOSET_UA)
+ printf("; set %d uA", uc_pdata->min_uA);
+ printf("; enabling");
+ if (ret)
+ printf(" (ret: %d)\n", ret);
+ printf("\n");
+}
- ret = regulator_set_enable(dev, true);
- if (failed(ret, verbose, "; enabling", uc_pdata->min_uA))
- goto exit;
+int regulator_autoset_by_name(const char *platname, struct udevice **devp)
+{
+ struct udevice *dev;
+ int ret;
-retdev:
+ ret = regulator_get_by_platname(platname, &dev);
if (devp)
*devp = dev;
-exit:
- if (verbose)
- printf("\n");
+ if (ret) {
+ debug("Can get the regulator: %s!", platname);
+ return ret;
+ }
- return ret;
+ return regulator_autoset(dev);
}
int regulator_list_autoset(const char *list_platname[],
int error = 0, i = 0, ret;
while (list_platname[i]) {
- ret = regulator_autoset(list_platname[i], &dev, verbose);
+ ret = regulator_autoset_by_name(list_platname[i], &dev);
+ if (ret != -EMEDIUMTYPE && verbose)
+ regulator_show(dev, ret);
if (ret & !error)
error = ret;
if (regulator_name_is_unique(dev, uc_pdata->name))
return 0;
- error("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
+ debug("\"%s\" of dev: \"%s\", has nonunique value: \"%s\"",
property, dev->name, uc_pdata->name);
return -EINVAL;
uc_pdata->boot_on = fdtdec_get_bool(gd->fdt_blob, offset,
"regulator-boot-on");
+ /* Those values are optional (-ENODATA if unset) */
+ if ((uc_pdata->min_uV != -ENODATA) &&
+ (uc_pdata->max_uV != -ENODATA) &&
+ (uc_pdata->min_uV == uc_pdata->max_uV))
+ uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UV;
+
+ /* Those values are optional (-ENODATA if unset) */
+ if ((uc_pdata->min_uA != -ENODATA) &&
+ (uc_pdata->max_uA != -ENODATA) &&
+ (uc_pdata->min_uA == uc_pdata->max_uA))
+ uc_pdata->flags |= REGULATOR_FLAG_AUTOSET_UA;
+
return 0;
}
+int regulators_enable_boot_on(bool verbose)
+{
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_REGULATOR, &uc);
+ if (ret)
+ return ret;
+ for (uclass_first_device(UCLASS_REGULATOR, &dev);
+ dev && !ret;
+ uclass_next_device(&dev)) {
+ ret = regulator_autoset(dev);
+ if (ret == -EMEDIUMTYPE)
+ continue;
+ if (verbose)
+ regulator_show(dev, ret);
+ }
+
+ return ret;
+}
+
UCLASS_DRIVER(regulator) = {
.id = UCLASS_REGULATOR,
.name = "regulator",
--- /dev/null
+config RAM
+ bool "Enable RAM drivers using Driver Model"
+ depends on DM
+ help
+ This allows drivers to be provided for SDRAM and other RAM
+ controllers and their type to be specified in the board's device
+ tree. Generally some parameters are required to set up the RAM and
+ the RAM size can either be statically defined or dynamically
+ detected.
+
+config SPL_RAM_SUPPORT
+ bool "Enable RAM support in SPL"
+ depends on RAM
+ help
+ The RAM subsystem adds a small amount of overhead to the image.
+ If this is acceptable and you have a need to use RAM drivers in
+ SPL, enable this option. It might provide a cleaner interface to
+ setting up RAM (e.g. SDRAM / DDR) within SPL.
--- /dev/null
+#
+# Copyright (c) 2015 Google, Inc
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+obj-$(CONFIG_RAM) += ram-uclass.o
+obj-$(CONFIG_SANDBOX) += sandbox_ram.o
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <ram.h>
+#include <dm.h>
+#include <errno.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+
+int ram_get_info(struct udevice *dev, struct ram_info *info)
+{
+ struct ram_ops *ops = ram_get_ops(dev);
+
+ if (!ops->get_info)
+ return -ENOSYS;
+
+ return ops->get_info(dev, info);
+}
+
+UCLASS_DRIVER(ram) = {
+ .id = UCLASS_RAM,
+ .name = "ram",
+};
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <ram.h>
+#include <asm/test.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_get_info(struct udevice *dev, struct ram_info *info)
+{
+ info->base = 0;
+ info->size = gd->ram_size;
+
+ return 0;
+}
+
+static const struct ram_ops sandbox_ram_ops = {
+ .get_info = sandbox_get_info,
+};
+
+static const struct udevice_id sandbox_ram_ids[] = {
+ { .compatible = "sandbox,ram" },
+ { }
+};
+
+U_BOOT_DRIVER(warm_ram_sandbox) = {
+ .name = "ram_sandbox",
+ .id = UCLASS_RAM,
+ .of_match = sandbox_ram_ids,
+ .ops = &sandbox_ram_ops,
+};
#include <debug_uart.h>
+#define serial_dout(reg, value) \
+ serial_out_shift((char *)com_port + \
+ ((char *)reg - (char *)com_port) * \
+ (1 << CONFIG_DEBUG_UART_SHIFT), \
+ CONFIG_DEBUG_UART_SHIFT, value)
+#define serial_din(reg) \
+ serial_in_shift((char *)com_port + \
+ ((char *)reg - (char *)com_port) * \
+ (1 << CONFIG_DEBUG_UART_SHIFT), \
+ CONFIG_DEBUG_UART_SHIFT)
+
void debug_uart_init(void)
{
struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
*/
baud_divisor = calc_divisor(com_port, CONFIG_DEBUG_UART_CLOCK,
CONFIG_BAUDRATE);
- serial_out_shift(&com_port->ier, CONFIG_DEBUG_UART_SHIFT,
- CONFIG_SYS_NS16550_IER);
- serial_out_shift(&com_port->mcr, CONFIG_DEBUG_UART_SHIFT, UART_MCRVAL);
- serial_out_shift(&com_port->fcr, CONFIG_DEBUG_UART_SHIFT, UART_FCRVAL);
-
- serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT,
- UART_LCR_BKSE | UART_LCRVAL);
- serial_out_shift(&com_port->dll, CONFIG_DEBUG_UART_SHIFT,
- baud_divisor & 0xff);
- serial_out_shift(&com_port->dlm, CONFIG_DEBUG_UART_SHIFT,
- (baud_divisor >> 8) & 0xff);
- serial_out_shift(&com_port->lcr, CONFIG_DEBUG_UART_SHIFT,
- UART_LCRVAL);
+ serial_dout(&com_port->ier, CONFIG_SYS_NS16550_IER);
+ serial_dout(&com_port->mcr, UART_MCRVAL);
+ serial_dout(&com_port->fcr, UART_FCRVAL);
+
+ serial_dout(&com_port->lcr, UART_LCR_BKSE | UART_LCRVAL);
+ serial_dout(&com_port->dll, baud_divisor & 0xff);
+ serial_dout(&com_port->dlm, (baud_divisor >> 8) & 0xff);
+ serial_dout(&com_port->lcr, UART_LCRVAL);
}
static inline void _debug_uart_putc(int ch)
{
struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE;
- while (!(serial_in_shift(&com_port->lsr, 0) & UART_LSR_THRE))
+ while (!(serial_din(&com_port->lsr) & UART_LSR_THRE))
;
- serial_out_shift(&com_port->thr, CONFIG_DEBUG_UART_SHIFT, ch);
+ serial_dout(&com_port->thr, ch);
}
DEBUG_UART_FUNCS
plat->speed_hz = fdtdec_get_int(blob,
node, "spi-max-frequency", FSL_DSPI_DEFAULT_SCK_FREQ);
- debug("DSPI: regs=0x%x, max-frequency=%d, endianess=%s, num-cs=%d\n",
- plat->regs_addr, plat->speed_hz,
+ debug("DSPI: regs=0x%llx, max-frequency=%d, endianess=%s, num-cs=%d\n",
+ (u64)plat->regs_addr, plat->speed_hz,
plat->flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le",
plat->num_chipselect);
return spi_get_ops(bus)->xfer(dev, bitlen, dout, din, flags);
}
-int spi_post_bind(struct udevice *dev)
+static int spi_post_bind(struct udevice *dev)
{
/* Scan the bus for devices */
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
-int spi_child_post_bind(struct udevice *dev)
+static int spi_child_post_bind(struct udevice *dev)
{
struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
return spi_slave_ofdata_to_platdata(gd->fdt_blob, dev->of_offset, plat);
}
-int spi_post_probe(struct udevice *bus)
+static int spi_post_probe(struct udevice *bus)
{
struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
return 0;
}
-int spi_child_pre_probe(struct udevice *dev)
+static int spi_child_pre_probe(struct udevice *dev)
{
struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
struct spi_slave *slave = dev_get_parentdata(dev);
250000000);
plat->speed_hz = plat->frequency / 2;
- debug("zynq_spi_ofdata_to_platdata: regs=%p max-frequency=%d\n",
+ debug("%s: regs=%p max-frequency=%d\n", __func__,
plat->regs, plat->frequency);
return 0;
};
static const struct udevice_id zynq_spi_ids[] = {
- { .compatible = "xlnx,zynq-spi" },
+ { .compatible = "xlnx,zynq-spi-r1p6" },
{ }
};
Much of the code is shared but with this option enabled the USB
uclass takes care of device enumeration. USB devices can be
- declared with the USB_DEVICE() macro and will be automatically
- probed when found on the bus.
+ declared with the U_BOOT_USB_DEVICE() macro and will be
+ automatically probed when found on the bus.
source "drivers/usb/host/Kconfig"
*/
#include <common.h>
+#include <dm.h>
#include <usb.h>
+#include <malloc.h>
#include <linux/mii.h>
#include "usb_ether.h"
-#include <malloc.h>
-
/* ASIX AX8817X based USB 2.0 Ethernet Devices */
#define FLAG_TYPE_AX88772B (1U << 2)
#define FLAG_EEPROM_MAC (1U << 3) /* initial mac address in eeprom */
-/* local vars */
-static int curr_eth_dev; /* index for name of next device detected */
/* driver private */
struct asix_private {
int flags;
+#ifdef CONFIG_DM_ETH
+ struct ueth_data ueth;
+#endif
};
+#ifndef CONFIG_DM_ETH
+/* local vars */
+static int curr_eth_dev; /* index for name of next device detected */
+#endif
+
/*
* Asix infrastructure commands
*/
return ret;
}
-static int asix_write_hwaddr(struct eth_device *eth)
+static int asix_write_hwaddr_common(struct ueth_data *dev, uint8_t *enetaddr)
{
- struct ueth_data *dev = (struct ueth_data *)eth->priv;
int ret;
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
- memcpy(buf, eth->enetaddr, ETH_ALEN);
+ memcpy(buf, enetaddr, ETH_ALEN);
ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, buf);
if (ret < 0)
return r;
}
-static int asix_read_mac(struct eth_device *eth)
+static int asix_read_mac_common(struct ueth_data *dev,
+ struct asix_private *priv, uint8_t *enetaddr)
{
- struct ueth_data *dev = (struct ueth_data *)eth->priv;
- struct asix_private *priv = (struct asix_private *)dev->dev_priv;
- int i;
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buf, ETH_ALEN);
+ int i;
if (priv->flags & FLAG_EEPROM_MAC) {
for (i = 0; i < (ETH_ALEN >> 1); i++) {
debug("Failed to read SROM address 04h.\n");
return -1;
}
- memcpy((eth->enetaddr + i * 2), buf, 2);
+ memcpy(enetaddr + i * 2, buf, 2);
}
} else {
if (asix_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, ETH_ALEN, buf)
debug("Failed to read MAC address.\n");
return -1;
}
- memcpy(eth->enetaddr, buf, ETH_ALEN);
+ memcpy(enetaddr, buf, ETH_ALEN);
}
return 0;
return 0;
}
-/*
- * Asix callbacks
- */
-static int asix_init(struct eth_device *eth, bd_t *bd)
+static int asix_init_common(struct ueth_data *dev)
{
- struct ueth_data *dev = (struct ueth_data *)eth->priv;
int timeout = 0;
#define TIMEOUT_RESOLUTION 50 /* ms */
int link_detected;
return -1;
}
-static int asix_send(struct eth_device *eth, void *packet, int length)
+static int asix_send_common(struct ueth_data *dev, void *packet, int length)
{
- struct ueth_data *dev = (struct ueth_data *)eth->priv;
int err;
u32 packet_len;
int actual_len;
return err;
}
+#ifndef CONFIG_DM_ETH
+/*
+ * Asix callbacks
+ */
+static int asix_init(struct eth_device *eth, bd_t *bd)
+{
+ struct ueth_data *dev = (struct ueth_data *)eth->priv;
+
+ return asix_init_common(dev);
+}
+
+static int asix_send(struct eth_device *eth, void *packet, int length)
+{
+ struct ueth_data *dev = (struct ueth_data *)eth->priv;
+
+ return asix_send_common(dev, packet, length);
+}
+
static int asix_recv(struct eth_device *eth)
{
struct ueth_data *dev = (struct ueth_data *)eth->priv;
debug("** %s()\n", __func__);
}
+static int asix_write_hwaddr(struct eth_device *eth)
+{
+ struct ueth_data *dev = (struct ueth_data *)eth->priv;
+
+ return asix_write_hwaddr_common(dev, eth->enetaddr);
+}
+
/*
* Asix probing functions
*/
return 0;
/* Get the MAC address */
- if (asix_read_mac(eth))
+ if (asix_read_mac_common(ss, priv, eth->enetaddr))
return 0;
debug("MAC %pM\n", eth->enetaddr);
return 1;
}
+#endif
+
+#ifdef CONFIG_DM_ETH
+static int asix_eth_start(struct udevice *dev)
+{
+ struct asix_private *priv = dev_get_priv(dev);
+
+ return asix_init_common(&priv->ueth);
+}
+
+void asix_eth_stop(struct udevice *dev)
+{
+ debug("** %s()\n", __func__);
+}
+
+int asix_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct asix_private *priv = dev_get_priv(dev);
+
+ return asix_send_common(&priv->ueth, packet, length);
+}
+
+int asix_eth_recv(struct udevice *dev, int flags, uchar **packetp)
+{
+ struct asix_private *priv = dev_get_priv(dev);
+ struct ueth_data *ueth = &priv->ueth;
+ uint8_t *ptr;
+ int ret, len;
+ u32 packet_len;
+
+ len = usb_ether_get_rx_bytes(ueth, &ptr);
+ debug("%s: first try, len=%d\n", __func__, len);
+ if (!len) {
+ if (!(flags & ETH_RECV_CHECK_DEVICE))
+ return -EAGAIN;
+ ret = usb_ether_receive(ueth, AX_RX_URB_SIZE);
+ if (ret == -EAGAIN)
+ return ret;
+
+ len = usb_ether_get_rx_bytes(ueth, &ptr);
+ debug("%s: second try, len=%d\n", __func__, len);
+ }
+
+ /*
+ * 1st 4 bytes contain the length of the actual data as two
+ * complementary 16-bit words. Extract the length of the data.
+ */
+ if (len < sizeof(packet_len)) {
+ debug("Rx: incomplete packet length\n");
+ goto err;
+ }
+ memcpy(&packet_len, ptr, sizeof(packet_len));
+ le32_to_cpus(&packet_len);
+ if (((~packet_len >> 16) & 0x7ff) != (packet_len & 0x7ff)) {
+ debug("Rx: malformed packet length: %#x (%#x:%#x)\n",
+ packet_len, (~packet_len >> 16) & 0x7ff,
+ packet_len & 0x7ff);
+ goto err;
+ }
+ packet_len = packet_len & 0x7ff;
+ if (packet_len > len - sizeof(packet_len)) {
+ debug("Rx: too large packet: %d\n", packet_len);
+ goto err;
+ }
+
+ *packetp = ptr + sizeof(packet_len);
+ return packet_len;
+
+err:
+ usb_ether_advance_rxbuf(ueth, -1);
+ return -EINVAL;
+}
+
+static int asix_free_pkt(struct udevice *dev, uchar *packet, int packet_len)
+{
+ struct asix_private *priv = dev_get_priv(dev);
+
+ if (packet_len & 1)
+ packet_len++;
+ usb_ether_advance_rxbuf(&priv->ueth, sizeof(u32) + packet_len);
+
+ return 0;
+}
+
+int asix_write_hwaddr(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct asix_private *priv = dev_get_priv(dev);
+
+ if (priv->flags & FLAG_TYPE_AX88172)
+ return -ENOSYS;
+
+ return asix_write_hwaddr_common(&priv->ueth, pdata->enetaddr);
+}
+
+static int asix_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct asix_private *priv = dev_get_priv(dev);
+ struct ueth_data *ss = &priv->ueth;
+ int ret;
+
+ priv->flags = dev->driver_data;
+ ret = usb_ether_register(dev, ss, AX_RX_URB_SIZE);
+ if (ret)
+ return ret;
+
+ ret = asix_basic_reset(ss);
+ if (ret)
+ goto err;
+
+ /* Get the MAC address */
+ ret = asix_read_mac_common(ss, priv, pdata->enetaddr);
+ if (ret)
+ goto err;
+ debug("MAC %pM\n", pdata->enetaddr);
+
+ return 0;
+
+err:
+ return usb_ether_deregister(ss);
+}
+
+static const struct eth_ops asix_eth_ops = {
+ .start = asix_eth_start,
+ .send = asix_eth_send,
+ .recv = asix_eth_recv,
+ .free_pkt = asix_free_pkt,
+ .stop = asix_eth_stop,
+ .write_hwaddr = asix_write_hwaddr,
+};
+
+U_BOOT_DRIVER(asix_eth) = {
+ .name = "asix_eth",
+ .id = UCLASS_ETH,
+ .probe = asix_eth_probe,
+ .ops = &asix_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct asix_private),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
+
+static const struct usb_device_id asix_eth_id_table[] = {
+ /* Apple USB Ethernet Adapter */
+ { USB_DEVICE(0x05ac, 0x1402), .driver_info = FLAG_TYPE_AX88772 },
+ /* D-Link DUB-E100 H/W Ver B1 */
+ { USB_DEVICE(0x07d1, 0x3c05), .driver_info = FLAG_TYPE_AX88772 },
+ /* D-Link DUB-E100 H/W Ver C1 */
+ { USB_DEVICE(0x2001, 0x1a02), .driver_info = FLAG_TYPE_AX88772 },
+ /* Cables-to-Go USB Ethernet Adapter */
+ { USB_DEVICE(0x0b95, 0x772a), .driver_info = FLAG_TYPE_AX88772 },
+ /* Trendnet TU2-ET100 V3.0R */
+ { USB_DEVICE(0x0b95, 0x7720), .driver_info = FLAG_TYPE_AX88772 },
+ /* SMC */
+ { USB_DEVICE(0x0b95, 0x1720), .driver_info = FLAG_TYPE_AX88172 },
+ /* MSI - ASIX 88772a */
+ { USB_DEVICE(0x0db0, 0xa877), .driver_info = FLAG_TYPE_AX88772 },
+ /* Linksys 200M v2.1 */
+ { USB_DEVICE(0x13b1, 0x0018), .driver_info = FLAG_TYPE_AX88172 },
+ /* 0Q0 cable ethernet */
+ { USB_DEVICE(0x1557, 0x7720), .driver_info = FLAG_TYPE_AX88772 },
+ /* DLink DUB-E100 H/W Ver B1 Alternate */
+ { USB_DEVICE(0x2001, 0x3c05), .driver_info = FLAG_TYPE_AX88772 },
+ /* ASIX 88772B */
+ { USB_DEVICE(0x0b95, 0x772b),
+ .driver_info = FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC },
+ { USB_DEVICE(0x0b95, 0x7e2b), .driver_info = FLAG_TYPE_AX88772B },
+ { } /* Terminating entry */
+};
+
+U_BOOT_USB_DEVICE(asix_eth, asix_eth_id_table);
+#endif
#include <common.h>
#include <dm.h>
+#include <malloc.h>
#include <usb.h>
#include <dm/device-internal.h>
#include "usb_ether.h"
+#ifdef CONFIG_DM_ETH
+
+#define USB_BULK_RECV_TIMEOUT 500
+
+int usb_ether_register(struct udevice *dev, struct ueth_data *ueth, int rxsize)
+{
+ struct usb_device *udev = dev_get_parentdata(dev);
+ struct usb_interface_descriptor *iface_desc;
+ bool ep_in_found = false, ep_out_found = false;
+ struct usb_interface *iface;
+ const int ifnum = 0; /* Always use interface 0 */
+ int ret, i;
+
+ iface = &udev->config.if_desc[ifnum];
+ iface_desc = &udev->config.if_desc[ifnum].desc;
+
+ /* Initialize the ueth_data structure with some useful info */
+ ueth->ifnum = ifnum;
+ ueth->subclass = iface_desc->bInterfaceSubClass;
+ ueth->protocol = iface_desc->bInterfaceProtocol;
+
+ /*
+ * We are expecting a minimum of 3 endpoints - in, out (bulk), and int.
+ * We will ignore any others.
+ */
+ for (i = 0; i < iface_desc->bNumEndpoints; i++) {
+ int ep_addr = iface->ep_desc[i].bEndpointAddress;
+
+ /* is it an BULK endpoint? */
+ if ((iface->ep_desc[i].bmAttributes &
+ USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) {
+ if (ep_addr & USB_DIR_IN && !ep_in_found) {
+ ueth->ep_in = ep_addr &
+ USB_ENDPOINT_NUMBER_MASK;
+ ep_in_found = true;
+ } else if (!(ep_addr & USB_DIR_IN) && !ep_out_found) {
+ ueth->ep_out = ep_addr &
+ USB_ENDPOINT_NUMBER_MASK;
+ ep_out_found = true;
+ }
+ }
+
+ /* is it an interrupt endpoint? */
+ if ((iface->ep_desc[i].bmAttributes &
+ USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) {
+ ueth->ep_int = iface->ep_desc[i].bEndpointAddress &
+ USB_ENDPOINT_NUMBER_MASK;
+ ueth->irqinterval = iface->ep_desc[i].bInterval;
+ }
+ }
+ debug("Endpoints In %d Out %d Int %d\n", ueth->ep_in, ueth->ep_out,
+ ueth->ep_int);
+
+ /* Do some basic sanity checks, and bail if we find a problem */
+ if (!ueth->ep_in || !ueth->ep_out || !ueth->ep_int) {
+ debug("%s: %s: Cannot find endpoints\n", __func__, dev->name);
+ return -ENXIO;
+ }
+
+ ueth->rxsize = rxsize;
+ ueth->rxbuf = memalign(rxsize, ARCH_DMA_MINALIGN);
+ if (!ueth->rxbuf)
+ return -ENOMEM;
+
+ ret = usb_set_interface(udev, iface_desc->bInterfaceNumber, ifnum);
+ if (ret) {
+ debug("%s: %s: Cannot set interface: %d\n", __func__, dev->name,
+ ret);
+ return ret;
+ }
+ ueth->pusb_dev = udev;
+
+ return 0;
+}
+
+int usb_ether_deregister(struct ueth_data *ueth)
+{
+ return 0;
+}
+
+int usb_ether_receive(struct ueth_data *ueth, int rxsize)
+{
+ int actual_len;
+ int ret;
+
+ if (rxsize > ueth->rxsize)
+ return -EINVAL;
+ ret = usb_bulk_msg(ueth->pusb_dev,
+ usb_rcvbulkpipe(ueth->pusb_dev, ueth->ep_in),
+ ueth->rxbuf, rxsize, &actual_len,
+ USB_BULK_RECV_TIMEOUT);
+ debug("Rx: len = %u, actual = %u, err = %d\n", rxsize, actual_len, ret);
+ if (ret) {
+ printf("Rx: failed to receive: %d\n", ret);
+ return ret;
+ }
+ if (actual_len > rxsize) {
+ debug("Rx: received too many bytes %d\n", actual_len);
+ return -ENOSPC;
+ }
+ ueth->rxlen = actual_len;
+ ueth->rxptr = 0;
+
+ return actual_len ? 0 : -EAGAIN;
+}
+
+void usb_ether_advance_rxbuf(struct ueth_data *ueth, int num_bytes)
+{
+ ueth->rxptr += num_bytes;
+ if (num_bytes < 0 || ueth->rxptr >= ueth->rxlen)
+ ueth->rxlen = 0;
+}
+
+int usb_ether_get_rx_bytes(struct ueth_data *ueth, uint8_t **ptrp)
+{
+ if (!ueth->rxlen)
+ return 0;
+
+ *ptrp = &ueth->rxbuf[ueth->rxptr];
+
+ return ueth->rxlen - ueth->rxptr;
+}
+
+#else
+
typedef void (*usb_eth_before_probe)(void);
typedef int (*usb_eth_probe)(struct usb_device *dev, unsigned int ifnum,
struct ueth_data *ss);
usb_max_eth_dev = 0;
#ifdef CONFIG_DM_USB
/*
- * TODO: We should add USB_DEVICE() declarations to each USB ethernet
- * driver and then most of this file can be removed.
+ * TODO: We should add U_BOOT_USB_DEVICE() declarations to each USB
+ * Ethernet driver and then most of this file can be removed.
*/
struct udevice *bus;
struct uclass *uc;
return 0;
return -1;
}
+#endif
# new USB gadget layer dependencies
ifdef CONFIG_USB_GADGET
obj-$(CONFIG_USB_GADGET_ATMEL_USBA) += atmel_usba_udc.o
+obj-$(CONFIG_USB_GADGET_BCM_UDC_OTG_PHY) += bcm_udc_otg_phy.o
obj-$(CONFIG_USB_GADGET_S3C_UDC_OTG) += s3c_udc_otg.o
obj-$(CONFIG_USB_GADGET_S3C_UDC_OTG_PHY) += s3c_udc_otg_phy.o
obj-$(CONFIG_USB_GADGET_FOTG210) += fotg210.o
obj-$(CONFIG_CI_UDC) += ci_udc.o
-obj-$(CONFIG_THOR_FUNCTION) += f_thor.o
-obj-$(CONFIG_USBDOWNLOAD_GADGET) += g_dnl.o
-obj-$(CONFIG_DFU_FUNCTION) += f_dfu.o
-obj-$(CONFIG_USB_GADGET_MASS_STORAGE) += f_mass_storage.o
-obj-$(CONFIG_CMD_FASTBOOT) += f_fastboot.o
+obj-$(CONFIG_USB_GADGET_DOWNLOAD) += g_dnl.o
+obj-$(CONFIG_USB_FUNCTION_THOR) += f_thor.o
+obj-$(CONFIG_USB_FUNCTION_DFU) += f_dfu.o
+obj-$(CONFIG_USB_FUNCTION_MASS_STORAGE) += f_mass_storage.o
+obj-$(CONFIG_USB_FUNCTION_FASTBOOT) += f_fastboot.o
endif
ifdef CONFIG_USB_ETHER
obj-y += ether.o
--- /dev/null
+/*
+ * Copyright 2015 Broadcom Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __BCM_UDC_OTG_H
+#define __BCM_UDC_OTG_H
+
+#include <common.h>
+
+static inline void wfld_set(uintptr_t addr, uint32_t fld_val, uint32_t fld_mask)
+{
+ writel(((readl(addr) & ~(fld_mask)) | (fld_val)), (addr));
+}
+
+static inline void wfld_clear(uintptr_t addr, uint32_t fld_mask)
+{
+ writel((readl(addr) & ~(fld_mask)), (addr));
+}
+
+#endif
--- /dev/null
+/*
+ * Copyright 2015 Broadcom Corporation.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sysmap.h>
+
+#include <usb/s3c_udc.h>
+#include "bcm_udc_otg.h"
+
+void otg_phy_init(struct s3c_udc *dev)
+{
+ /* set Phy to driving mode */
+ wfld_clear(HSOTG_CTRL_BASE_ADDR + HSOTG_CTRL_PHY_P1CTL_OFFSET,
+ HSOTG_CTRL_PHY_P1CTL_NON_DRIVING_MASK);
+
+ udelay(100);
+
+ /* clear Soft Disconnect */
+ wfld_clear(HSOTG_BASE_ADDR + HSOTG_DCTL_OFFSET,
+ HSOTG_DCTL_SFTDISCON_MASK);
+
+ /* invoke Reset (active low) */
+ wfld_clear(HSOTG_CTRL_BASE_ADDR + HSOTG_CTRL_PHY_P1CTL_OFFSET,
+ HSOTG_CTRL_PHY_P1CTL_SOFT_RESET_MASK);
+
+ /* Reset needs to be asserted for 2ms */
+ udelay(2000);
+
+ /* release Reset */
+ wfld_set(HSOTG_CTRL_BASE_ADDR + HSOTG_CTRL_PHY_P1CTL_OFFSET,
+ HSOTG_CTRL_PHY_P1CTL_SOFT_RESET_MASK,
+ HSOTG_CTRL_PHY_P1CTL_SOFT_RESET_MASK);
+}
+
+void otg_phy_off(struct s3c_udc *dev)
+{
+ /* Soft Disconnect */
+ wfld_set(HSOTG_BASE_ADDR + HSOTG_DCTL_OFFSET,
+ HSOTG_DCTL_SFTDISCON_MASK,
+ HSOTG_DCTL_SFTDISCON_MASK);
+
+ /* set Phy to non-driving (reset) mode */
+ wfld_set(HSOTG_CTRL_BASE_ADDR + HSOTG_CTRL_PHY_P1CTL_OFFSET,
+ HSOTG_CTRL_PHY_P1CTL_NON_DRIVING_MASK,
+ HSOTG_CTRL_PHY_P1CTL_NON_DRIVING_MASK);
+}
*/
static void ci_flush_td(struct ept_queue_item *td)
{
- const uint32_t start = (uint32_t)td;
- const uint32_t end = (uint32_t) td + ILIST_ENT_SZ;
+ const unsigned long start = (unsigned long)td;
+ const unsigned long end = (unsigned long)td + ILIST_ENT_SZ;
flush_dcache_range(start, end);
}
*/
static void ci_invalidate_td(struct ept_queue_item *td)
{
- const uint32_t start = (uint32_t)td;
- const uint32_t end = start + ILIST_ENT_SZ;
+ const unsigned long start = (unsigned long)td;
+ const unsigned long end = start + ILIST_ENT_SZ;
invalidate_dcache_range(start, end);
}
ci_ep_alloc_request(struct usb_ep *ep, unsigned int gfp_flags)
{
struct ci_ep *ci_ep = container_of(ep, struct ci_ep, ep);
- int num;
+ int num = -1;
struct ci_req *ci_req;
- num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+ if (ci_ep->desc)
+ num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
+
if (num == 0 && controller.ep0_req)
return &controller.ep0_req->req;
{
struct ci_ep *ci_ep = container_of(ep, struct ci_ep, ep);
struct ci_req *ci_req = container_of(req, struct ci_req, req);
- int num;
+ int num = -1;
+
+ if (ci_ep->desc)
+ num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- num = ci_ep->desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
if (num == 0) {
if (!controller.ep0_req)
return;
if (len) {
qtd = (struct ept_queue_item *)
memalign(ILIST_ALIGN, ILIST_ENT_SZ);
- dtd->next = (uint32_t)qtd;
+ dtd->next = (unsigned long)qtd;
dtd = qtd;
memset(dtd, 0, ILIST_ENT_SZ);
}
ci_flush_qtd(num);
- item = (struct ept_queue_item *)head->next;
+ item = (struct ept_queue_item *)(unsigned long)head->next;
while (item->next != TERMINATE) {
- ci_flush_td((struct ept_queue_item *)item->next);
- item = (struct ept_queue_item *)item->next;
+ ci_flush_td((struct ept_queue_item *)(unsigned long)item->next);
+ item = (struct ept_queue_item *)(unsigned long)item->next;
}
DBG("ept%d %s queue len %x, req %p, buffer %p\n",
printf("EP%d/%s FAIL info=%x pg0=%x\n",
num, in ? "in" : "out", item->info, item->page0);
if (j != ci_req->dtd_count - 1)
- next_td = (struct ept_queue_item *)item->next;
+ next_td = (struct ept_queue_item *)(unsigned long)
+ item->next;
if (j != 0)
free(item);
}
memcpy(in_req->buf, buffer, buffer_size);
in_req->length = buffer_size;
+
+ usb_ep_dequeue(fastboot_func->in_ep, in_req);
+
ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0);
if (ret)
printf("Error %d on queue\n", ret);
!strcmp_l1("max-download-size", cmd)) {
char str_num[12];
- sprintf(str_num, "0x%08x", CONFIG_USB_FASTBOOT_BUF_SIZE);
+ sprintf(str_num, "0x%08x", CONFIG_FASTBOOT_BUF_SIZE);
strncat(response, str_num, chars_left);
} else if (!strcmp_l1("serialno", cmd)) {
s = getenv("serial#");
if (buffer_size < transfer_size)
transfer_size = buffer_size;
- memcpy((void *)CONFIG_USB_FASTBOOT_BUF_ADDR + download_bytes,
+ memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes,
buffer, transfer_size);
pre_dot_num = download_bytes / BYTES_PER_DOT;
if (0 == download_size) {
sprintf(response, "FAILdata invalid size");
- } else if (download_size > CONFIG_USB_FASTBOOT_BUF_SIZE) {
+ } else if (download_size > CONFIG_FASTBOOT_BUF_SIZE) {
download_size = 0;
sprintf(response, "FAILdata too large");
} else {
strcpy(response, "FAILno flash device defined");
#ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
- fb_mmc_flash_write(cmd, (void *)CONFIG_USB_FASTBOOT_BUF_ADDR,
+ fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
download_bytes, response);
#endif
fastboot_tx_write_str(response);
void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;
int i;
+ if (req->status != 0 || req->length == 0)
+ return;
+
for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {
if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {
func_cb = cmd_dispatch_info[i].cb;
}
}
- if (req->status == 0) {
- *cmdbuf = '\0';
- req->actual = 0;
- usb_ep_queue(ep, req, 0);
- }
+ *cmdbuf = '\0';
+ req->actual = 0;
+ usb_ep_queue(ep, req, 0);
}
#include <mmc.h>
#include <part.h>
+#include <usb.h>
#include <g_dnl.h>
#include <usb_mass_storage.h>
return usb_add_config(cdev, config);
}
+__weak
+int board_usb_init(int index, enum usb_init_type init)
+{
+ return 0;
+}
+
+__weak
+int board_usb_cleanup(int index, enum usb_init_type init)
+{
+ return 0;
+}
+
__weak
int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name)
{
# xhci
obj-$(CONFIG_USB_XHCI) += xhci.o xhci-mem.o xhci-ring.o
+obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
obj-$(CONFIG_USB_XHCI_KEYSTONE) += xhci-keystone.o
obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
+obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o
obj-$(CONFIG_USB_XHCI_OMAP) += xhci-omap.o
obj-$(CONFIG_USB_XHCI_PCI) += xhci-pci.o
obj-$(CONFIG_USB_XHCI_UNIPHIER) += xhci-uniphier.o
*
* All rights reserved.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <dm.h>
struct udevice *dev = parent;
if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
- printf("ehci: Error cannot find high speed parent of usb-1 device\n");
+ printf("ehci: Error cannot find high-speed parent of usb-1 device\n");
return;
}
DECLARE_GLOBAL_DATA_PTR;
-#define rdl(off) readl(MVUSB0_BASE + (off))
-#define wrl(off, val) writel((val), MVUSB0_BASE + (off))
-
#define USB_WINDOW_CTRL(i) (0x320 + ((i) << 4))
#define USB_WINDOW_BASE(i) (0x324 + ((i) << 4))
#define USB_TARGET_DRAM 0x0
dram = mvebu_mbus_dram_info();
for (i = 0; i < 4; i++) {
- wrl(USB_WINDOW_CTRL(i), 0);
- wrl(USB_WINDOW_BASE(i), 0);
+ writel(0, MVUSB0_BASE + USB_WINDOW_CTRL(i));
+ writel(0, MVUSB0_BASE + USB_WINDOW_BASE(i));
}
for (i = 0; i < dram->num_cs; i++) {
const struct mbus_dram_window *cs = dram->cs + i;
/* Write size, attributes and target id to control register */
- wrl(USB_WINDOW_CTRL(i),
- ((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
- (dram->mbus_dram_target_id << 4) | 1);
+ writel(((cs->size - 1) & 0xffff0000) | (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+ MVUSB0_BASE + USB_WINDOW_CTRL(i));
/* Write base address to base register */
- wrl(USB_WINDOW_BASE(i), cs->base);
+ writel(cs->base, MVUSB0_BASE + USB_WINDOW_BASE(i));
}
}
#else
size = gd->bd->bi_dram[i].size;
base = gd->bd->bi_dram[i].start;
if ((size) && (attrib))
- wrl(USB_WINDOW_CTRL(i),
- MVCPU_WIN_CTRL_DATA(size, USB_TARGET_DRAM,
- attrib, MVCPU_WIN_ENABLE));
+ writel(MVCPU_WIN_CTRL_DATA(size, USB_TARGET_DRAM,
+ attrib, MVCPU_WIN_ENABLE),
+ MVUSB0_BASE + USB_WINDOW_CTRL(i));
else
- wrl(USB_WINDOW_CTRL(i), MVCPU_WIN_DISABLE);
+ writel(MVCPU_WIN_DISABLE,
+ MVUSB0_BASE + USB_WINDOW_CTRL(i));
- wrl(USB_WINDOW_BASE(i), base);
+ writel(base, MVUSB0_BASE + USB_WINDOW_BASE(i));
}
}
#endif
* Copyright (c) 2007-2008, Juniper Networks, Inc.
* All rights reserved.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <pci.h>
#include <usb.h>
#include "ehci.h"
+/* Information about a USB port */
+struct ehci_pci_priv {
+ struct ehci_ctrl ehci;
+};
+
+static void ehci_pci_common_init(pci_dev_t pdev, struct ehci_hccr **ret_hccr,
+ struct ehci_hcor **ret_hcor)
+{
+ struct ehci_hccr *hccr;
+ struct ehci_hcor *hcor;
+ uint32_t cmd;
+
+ hccr = (struct ehci_hccr *)pci_map_bar(pdev,
+ PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
+ hcor = (struct ehci_hcor *)((uint32_t) hccr +
+ HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
+ (uint32_t)hccr, (uint32_t)hcor,
+ (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+ *ret_hccr = hccr;
+ *ret_hcor = hcor;
+
+ /* enable busmaster */
+ pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
+ cmd |= PCI_COMMAND_MASTER;
+ pci_write_config_dword(pdev, PCI_COMMAND, cmd);
+}
+
+#ifndef CONFIG_DM_USB
+
#ifdef CONFIG_PCI_EHCI_DEVICE
static struct pci_device_id ehci_pci_ids[] = {
/* Please add supported PCI EHCI controller ids here */
{0x12D8, 0x400F}, /* Pericom */
{0, 0}
};
-#else
#endif
/*
struct ehci_hccr **ret_hccr, struct ehci_hcor **ret_hcor)
{
pci_dev_t pdev;
- uint32_t cmd;
- struct ehci_hccr *hccr;
- struct ehci_hcor *hcor;
#ifdef CONFIG_PCI_EHCI_DEVICE
pdev = pci_find_devices(ehci_pci_ids, CONFIG_PCI_EHCI_DEVICE);
printf("EHCI host controller not found\n");
return -1;
}
+ ehci_pci_common_init(pdev, ret_hccr, ret_hcor);
- hccr = (struct ehci_hccr *)pci_map_bar(pdev,
- PCI_BASE_ADDRESS_0, PCI_REGION_MEM);
- hcor = (struct ehci_hcor *)((uint32_t) hccr +
- HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
-
- debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n",
- (uint32_t)hccr, (uint32_t)hcor,
- (uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
-
- *ret_hccr = hccr;
- *ret_hcor = hcor;
-
- /* enable busmaster */
- pci_read_config_dword(pdev, PCI_COMMAND, &cmd);
- cmd |= PCI_COMMAND_MASTER;
- pci_write_config_dword(pdev, PCI_COMMAND, cmd);
return 0;
}
{
return 0;
}
+#endif /* nCONFIG_DM_USB */
+
+#ifdef CONFIG_DM_USB
+static int ehci_pci_probe(struct udevice *dev)
+{
+ struct ehci_hccr *hccr;
+ struct ehci_hcor *hcor;
+
+ ehci_pci_common_init(pci_get_bdf(dev), &hccr, &hcor);
+
+ return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST);
+}
+
+static int ehci_pci_remove(struct udevice *dev)
+{
+ int ret;
+
+ ret = ehci_deregister(dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+U_BOOT_DRIVER(ehci_pci) = {
+ .name = "ehci_pci",
+ .id = UCLASS_USB,
+ .probe = ehci_pci_probe,
+ .remove = ehci_pci_remove,
+ .ops = &ehci_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+ .priv_auto_alloc_size = sizeof(struct ehci_pci_priv),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+
+static struct pci_device_id ehci_pci_supported[] = {
+ { PCI_DEVICE_CLASS(PCI_CLASS_SERIAL_USB_EHCI, ~0) },
+ {},
+};
+
+U_BOOT_PCI_DEVICE(ehci_pci, ehci_pci_supported);
+
+#endif /* CONFIG_DM_USB */
/*
* Copyright (c) 2011 The Chromium OS Authors.
- * Copyright (c) 2009-2013 NVIDIA Corporation
+ * Copyright (c) 2009-2015 NVIDIA Corporation
* Copyright (c) 2013 Lucas Stach
*
* SPDX-License-Identifier: GPL-2.0+
USB_CTLR_T20,
USB_CTLR_T30,
USB_CTLR_T114,
+ USB_CTLR_T210,
USB_CTRL_COUNT,
};
{ 0x3C0, 0x1A, 0x00, 0xC, 2, 0x04, 0x66, 0x09, 0xFE, 0xFDE8, 0xB }
};
+/* NOTE: 13/26MHz settings are N/A for T210, so dupe 12MHz settings for now */
+static const unsigned T210_usb_pll[CLOCK_OSC_FREQ_COUNT][PARAM_COUNT] = {
+ /* DivN, DivM, DivP, KCP, KVCO, Delays Debounce, Bias */
+ { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 30000, 5 },
+ { 0x019, 0x01, 0x01, 0x0, 0, 0x03, 0x4B, 0x0C, 0xBB, 48000, 8 },
+ { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 30000, 5 },
+ { 0x028, 0x01, 0x01, 0x0, 0, 0x02, 0x2F, 0x08, 0x76, 30000, 5 },
+};
+
/* UTMIP Idle Wait Delay */
static const u8 utmip_idle_wait_delay = 17;
.has_hostpc = 1,
.pll_parameter = (const unsigned *)T114_usb_pll,
},
+ {
+ .has_hostpc = 1,
+ .pll_parameter = (const unsigned *)T210_usb_pll,
+ },
};
/*
UTMIP_DEBOUNCE_CFG0_MASK,
timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT);
+ if (timing[PARAM_DEBOUNCE_A_TIME] > 0xFFFF) {
+ clrsetbits_le32(&usbctlr->utmip_debounce_cfg0,
+ UTMIP_DEBOUNCE_CFG0_MASK,
+ (timing[PARAM_DEBOUNCE_A_TIME] >> 1)
+ << UTMIP_DEBOUNCE_CFG0_SHIFT);
+ clrsetbits_le32(&usbctlr->utmip_bias_cfg1,
+ UTMIP_BIAS_DEBOUNCE_TIMESCALE_MASK,
+ 1 << UTMIP_BIAS_DEBOUNCE_TIMESCALE_SHIFT);
+ }
+
setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J);
/* Disable battery charge enabling bit */
static void config_clock(const u32 timing[])
{
+ debug("%s: DIVM = %d, DIVN = %d, DIVP = %d, cpcon/lfcon = %d/%d\n",
+ __func__, timing[PARAM_DIVM], timing[PARAM_DIVN],
+ timing[PARAM_DIVP], timing[PARAM_CPCON], timing[PARAM_LFCON]);
+
clock_start_pll(CLOCK_ID_USB,
timing[PARAM_DIVM], timing[PARAM_DIVN], timing[PARAM_DIVP],
timing[PARAM_CPCON], timing[PARAM_LFCON]);
{ .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
{ .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
{ .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
+ { .compatible = "nvidia,tegra210-ehci", .data = USB_CTLR_T210 },
{ }
};
* Copyright (c) 2008, Michael Trimarchi <trimarchimichael@yahoo.it>
* All rights reserved.
*
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2 of
- * the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
+ * SPDX-License-Identifier: GPL-2.0
*/
#ifndef USB_EHCI_H
*
* Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ * SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
*
* Copyright (C) 2008 Yoshihiro Shimoda <shimoda.yoshihiro@renesas.com>
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ * SPDX-License-Identifier: GPL-2.0
*/
#ifndef __R8A66597_H__
return ops->alloc_device(bus, udev);
}
+int usb_reset_root_port(struct usb_device *udev)
+{
+ struct udevice *bus = udev->controller_dev;
+ struct dm_usb_ops *ops = usb_get_ops(bus);
+
+ if (!ops->reset_root_port)
+ return -ENOSYS;
+
+ return ops->reset_root_port(bus, udev);
+}
+
int usb_stop(void)
{
struct udevice *bus;
ret = device_remove(bus);
if (ret && !err)
err = ret;
+ ret = device_unbind_children(bus);
+ if (ret && !err)
+ err = ret;
}
#ifdef CONFIG_SANDBOX
return usb_started ? 0 : -1;
}
-int usb_reset_root_port(void)
-{
- return -ENOSYS;
-}
-
static struct usb_device *find_child_devnum(struct udevice *parent, int devnum)
{
struct usb_device *udev;
struct usb_device *usb_get_dev_index(struct udevice *bus, int index)
{
- struct udevice *hub;
+ struct udevice *dev;
int devnum = index + 1; /* Addresses are allocated from 1 on USB */
- device_find_first_child(bus, &hub);
- if (device_get_uclass_id(hub) == UCLASS_USB_HUB)
- return find_child_devnum(hub, devnum);
+ device_find_first_child(bus, &dev);
+ if (!dev)
+ return NULL;
- return NULL;
+ return find_child_devnum(dev, devnum);
}
int usb_post_bind(struct udevice *dev)
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
-int usb_port_reset(struct usb_device *parent, int portnr)
-{
- unsigned short portstatus;
- int ret;
-
- debug("%s: start\n", __func__);
-
- if (parent) {
- /* reset the port for the second time */
- assert(portnr > 0);
- debug("%s: reset %d\n", __func__, portnr - 1);
- ret = legacy_hub_port_reset(parent, portnr - 1, &portstatus);
- if (ret < 0) {
- printf("\n Couldn't reset port %i\n", portnr);
- return ret;
- }
- } else {
- debug("%s: reset root\n", __func__);
- usb_reset_root_port();
- }
-
- return 0;
-}
-
-int usb_legacy_port_reset(struct usb_device *parent, int portnr)
-{
- return usb_port_reset(parent, portnr);
-}
-
int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
{
struct usb_platdata *plat;
}
/**
- * usb_find_child() - Find an existing device which matches our needs
- *
- *
+ * usb_find_emul_child() - Find an existing device for emulated devices
*/
-static int usb_find_child(struct udevice *parent,
- struct usb_device_descriptor *desc,
- struct usb_interface_descriptor *iface,
- struct udevice **devp)
+static int usb_find_emul_child(struct udevice *parent,
+ struct usb_device_descriptor *desc,
+ struct usb_interface_descriptor *iface,
+ struct udevice **devp)
{
+#ifdef CONFIG_SANDBOX
struct udevice *dev;
*devp = NULL;
return 0;
}
}
-
+#endif
return -ENOENT;
}
debug("Calling usb_setup_device(), portnr=%d\n", udev->portnr);
parent_udev = device_get_uclass_id(parent) == UCLASS_USB_HUB ?
dev_get_parentdata(parent) : NULL;
- ret = usb_setup_device(udev, priv->desc_before_addr, parent_udev, port);
+ ret = usb_setup_device(udev, priv->desc_before_addr, parent_udev);
debug("read_descriptor for '%s': ret=%d\n", parent->name, ret);
if (ret)
return ret;
- ret = usb_find_child(parent, &udev->descriptor, iface, &dev);
- debug("** usb_find_child returns %d\n", ret);
+ ret = usb_find_emul_child(parent, &udev->descriptor, iface, &dev);
+ debug("** usb_find_emul_child returns %d\n", ret);
if (ret) {
if (ret != -ENOENT)
return ret;
--- /dev/null
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * DWC3 controller driver
+ *
+ * Author: Ramneek Mehresh<ramneek.mehresh@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/usb/dwc3.h>
+
+void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
+{
+ clrsetbits_le32(&dwc3_reg->g_ctl,
+ DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG),
+ DWC3_GCTL_PRTCAPDIR(mode));
+}
+
+void dwc3_phy_reset(struct dwc3 *dwc3_reg)
+{
+ /* Assert USB3 PHY reset */
+ setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
+
+ /* Assert USB2 PHY reset */
+ setbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
+
+ mdelay(100);
+
+ /* Clear USB3 PHY reset */
+ clrbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
+
+ /* Clear USB2 PHY reset */
+ clrbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
+}
+
+void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
+{
+ /* Before Resetting PHY, put Core in Reset */
+ setbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
+
+ /* reset USB3 phy - if required */
+ dwc3_phy_reset(dwc3_reg);
+
+ /* After PHYs are stable we can take Core out of reset state */
+ clrbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
+}
+
+int dwc3_core_init(struct dwc3 *dwc3_reg)
+{
+ u32 reg;
+ u32 revision;
+ unsigned int dwc3_hwparams1;
+
+ revision = readl(&dwc3_reg->g_snpsid);
+ /* This should read as U3 followed by revision number */
+ if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) {
+ puts("this is not a DesignWare USB3 DRD Core\n");
+ return -1;
+ }
+
+ dwc3_core_soft_reset(dwc3_reg);
+
+ dwc3_hwparams1 = readl(&dwc3_reg->g_hwparams1);
+
+ reg = readl(&dwc3_reg->g_ctl);
+ reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
+ reg &= ~DWC3_GCTL_DISSCRAMBLE;
+ switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1)) {
+ case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
+ reg &= ~DWC3_GCTL_DSBLCLKGTNG;
+ break;
+ default:
+ debug("No power optimization available\n");
+ }
+
+ /*
+ * WORKAROUND: DWC3 revisions <1.90a have a bug
+ * where the device can fail to connect at SuperSpeed
+ * and falls back to high-speed mode which causes
+ * the device to enter a Connect/Disconnect loop
+ */
+ if ((revision & DWC3_REVISION_MASK) < 0x190a)
+ reg |= DWC3_GCTL_U2RSTECN;
+
+ writel(reg, &dwc3_reg->g_ctl);
+
+ return 0;
+}
+
+void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val)
+{
+ setbits_le32(&dwc3_reg->g_fladj, GFLADJ_30MHZ_REG_SEL |
+ GFLADJ_30MHZ(val));
+}
set_usbdrd_phy_ctrl(POWER_USB_DRD_PHY_CTRL_DISABLE);
}
-static void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
-{
- clrsetbits_le32(&dwc3_reg->g_ctl,
- DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG),
- DWC3_GCTL_PRTCAPDIR(mode));
-}
-
-static void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
-{
- /* Before Resetting PHY, put Core in Reset */
- setbits_le32(&dwc3_reg->g_ctl,
- DWC3_GCTL_CORESOFTRESET);
-
- /* Assert USB3 PHY reset */
- setbits_le32(&dwc3_reg->g_usb3pipectl[0],
- DWC3_GUSB3PIPECTL_PHYSOFTRST);
-
- /* Assert USB2 PHY reset */
- setbits_le32(&dwc3_reg->g_usb2phycfg,
- DWC3_GUSB2PHYCFG_PHYSOFTRST);
-
- mdelay(100);
-
- /* Clear USB3 PHY reset */
- clrbits_le32(&dwc3_reg->g_usb3pipectl[0],
- DWC3_GUSB3PIPECTL_PHYSOFTRST);
-
- /* Clear USB2 PHY reset */
- clrbits_le32(&dwc3_reg->g_usb2phycfg,
- DWC3_GUSB2PHYCFG_PHYSOFTRST);
-
- /* After PHYs are stable we can take Core out of reset state */
- clrbits_le32(&dwc3_reg->g_ctl,
- DWC3_GCTL_CORESOFTRESET);
-}
-
-static int dwc3_core_init(struct dwc3 *dwc3_reg)
-{
- u32 reg;
- u32 revision;
- unsigned int dwc3_hwparams1;
-
- revision = readl(&dwc3_reg->g_snpsid);
- /* This should read as U3 followed by revision number */
- if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) {
- puts("this is not a DesignWare USB3 DRD Core\n");
- return -EINVAL;
- }
-
- dwc3_core_soft_reset(dwc3_reg);
-
- dwc3_hwparams1 = readl(&dwc3_reg->g_hwparams1);
-
- reg = readl(&dwc3_reg->g_ctl);
- reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
- reg &= ~DWC3_GCTL_DISSCRAMBLE;
- switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1)) {
- case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
- reg &= ~DWC3_GCTL_DSBLCLKGTNG;
- break;
- default:
- debug("No power optimization available\n");
- }
-
- /*
- * WORKAROUND: DWC3 revisions <1.90a have a bug
- * where the device can fail to connect at SuperSpeed
- * and falls back to high-speed mode which causes
- * the device to enter a Connect/Disconnect loop
- */
- if ((revision & DWC3_REVISION_MASK) < 0x190a)
- reg |= DWC3_GCTL_U2RSTECN;
-
- writel(reg, &dwc3_reg->g_ctl);
-
- return 0;
-}
-
static int exynos_xhci_core_init(struct exynos_xhci *exynos)
{
int ret;
--- /dev/null
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * FSL USB HOST xHCI Controller
+ *
+ * Author: Ramneek Mehresh<ramneek.mehresh@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <usb.h>
+#include <asm-generic/errno.h>
+#include <linux/compat.h>
+#include <linux/usb/xhci-fsl.h>
+#include <linux/usb/dwc3.h>
+#include "xhci.h"
+
+/* Declare global data pointer */
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct fsl_xhci fsl_xhci;
+unsigned long ctr_addr[] = FSL_USB_XHCI_ADDR;
+
+__weak int __board_usb_init(int index, enum usb_init_type init)
+{
+ return 0;
+}
+
+void usb_phy_reset(struct dwc3 *dwc3_reg)
+{
+ /* Assert USB3 PHY reset */
+ setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
+
+ /* Assert USB2 PHY reset */
+ setbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
+
+ mdelay(200);
+
+ /* Clear USB3 PHY reset */
+ clrbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
+
+ /* Clear USB2 PHY reset */
+ clrbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
+}
+
+static int fsl_xhci_core_init(struct fsl_xhci *fsl_xhci)
+{
+ int ret = 0;
+
+ ret = dwc3_core_init(fsl_xhci->dwc3_reg);
+ if (ret) {
+ debug("%s:failed to initialize core\n", __func__);
+ return ret;
+ }
+
+ /* We are hard-coding DWC3 core to Host Mode */
+ dwc3_set_mode(fsl_xhci->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
+
+ /* Set GFLADJ_30MHZ as 20h as per XHCI spec default value */
+ dwc3_set_fladj(fsl_xhci->dwc3_reg, GFLADJ_30MHZ_DEFAULT);
+
+ return ret;
+}
+
+static int fsl_xhci_core_exit(struct fsl_xhci *fsl_xhci)
+{
+ /*
+ * Currently fsl socs do not support PHY shutdown from
+ * sw. But this support may be added in future socs.
+ */
+ return 0;
+}
+
+int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
+{
+ struct fsl_xhci *ctx = &fsl_xhci;
+ int ret = 0;
+
+ ctx->hcd = (struct xhci_hccr *)ctr_addr[index];
+ ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
+
+ ret = board_usb_init(index, USB_INIT_HOST);
+ if (ret != 0) {
+ puts("Failed to initialize board for USB\n");
+ return ret;
+ }
+
+ ret = fsl_xhci_core_init(ctx);
+ if (ret < 0) {
+ puts("Failed to initialize xhci\n");
+ return ret;
+ }
+
+ *hccr = (struct xhci_hccr *)ctx->hcd;
+ *hcor = (struct xhci_hcor *)((uintptr_t) *hccr
+ + HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));
+
+ debug("fsl-xhci: init hccr %lx and hcor %lx hc_length %lx\n",
+ (uintptr_t)*hccr, (uintptr_t)*hcor,
+ (uintptr_t)HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));
+
+ return ret;
+}
+
+void xhci_hcd_stop(int index)
+{
+ struct fsl_xhci *ctx = &fsl_xhci;
+
+ fsl_xhci_core_exit(ctx);
+}
writel(val, &phy->phy_clock);
}
-static void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
-{
- clrsetbits_le32(&dwc3_reg->g_ctl,
- DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG),
- DWC3_GCTL_PRTCAPDIR(mode));
-}
-
-static void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
-{
- /* Before Resetting PHY, put Core in Reset */
- setbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
-
- /* Assert USB3 PHY reset */
- setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
-
- /* Assert USB2 PHY reset */
- setbits_le32(&dwc3_reg->g_usb2phycfg[0], DWC3_GUSB2PHYCFG_PHYSOFTRST);
-
- mdelay(100);
-
- /* Clear USB3 PHY reset */
- clrbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
-
- /* Clear USB2 PHY reset */
- clrbits_le32(&dwc3_reg->g_usb2phycfg[0], DWC3_GUSB2PHYCFG_PHYSOFTRST);
-
- /* After PHYs are stable we can take Core out of reset state */
- clrbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
-}
-
-static int dwc3_core_init(struct dwc3 *dwc3_reg)
-{
- u32 revision, val;
- unsigned long t_rst;
- unsigned int dwc3_hwparams1;
-
- revision = readl(&dwc3_reg->g_snpsid);
- /* This should read as U3 followed by revision number */
- if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) {
- puts("this is not a DesignWare USB3 DRD Core\n");
- return -EINVAL;
- }
-
- /* issue device SoftReset too */
- writel(DWC3_DCTL_CSFTRST, &dwc3_reg->d_ctl);
-
- t_rst = get_timer(0);
- do {
- val = readl(&dwc3_reg->d_ctl);
- if (!(val & DWC3_DCTL_CSFTRST))
- break;
- WATCHDOG_RESET();
- } while (get_timer(t_rst) < 500);
-
- if (val & DWC3_DCTL_CSFTRST) {
- debug("Reset timed out\n");
- return -2;
- }
-
- dwc3_core_soft_reset(dwc3_reg);
-
- dwc3_hwparams1 = readl(&dwc3_reg->g_hwparams1);
-
- val = readl(&dwc3_reg->g_ctl);
- val &= ~DWC3_GCTL_SCALEDOWN_MASK;
- val &= ~DWC3_GCTL_DISSCRAMBLE;
- switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1)) {
- case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
- val &= ~DWC3_GCTL_DSBLCLKGTNG;
- break;
- default:
- printf("No power optimization available\n");
- }
-
- /*
- * WORKAROUND: DWC3 revisions <1.90a have a bug
- * where the device can fail to connect at SuperSpeed
- * and falls back to high-speed mode which causes
- * the device to enter a Connect/Disconnect loop
- */
- if ((revision & DWC3_REVISION_MASK) < 0x190a)
- val |= DWC3_GCTL_U2RSTECN;
-
- writel(val, &dwc3_reg->g_ctl);
-
- return 0;
-}
-
static int keystone_xhci_core_init(struct dwc3 *dwc3_reg)
{
int ret;
int board_usb_init(int index, enum usb_init_type init)
__attribute__((weak, alias("__board_usb_init")));
-static void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode)
-{
- clrsetbits_le32(&dwc3_reg->g_ctl,
- DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG),
- DWC3_GCTL_PRTCAPDIR(mode));
-}
-
-static void dwc3_core_soft_reset(struct dwc3 *dwc3_reg)
-{
- /* Before Resetting PHY, put Core in Reset */
- setbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
-
- omap_reset_usb_phy(dwc3_reg);
-
- /* After PHYs are stable we can take Core out of reset state */
- clrbits_le32(&dwc3_reg->g_ctl, DWC3_GCTL_CORESOFTRESET);
-}
-
-static int dwc3_core_init(struct dwc3 *dwc3_reg)
-{
- u32 reg;
- u32 revision;
- unsigned int dwc3_hwparams1;
-
- revision = readl(&dwc3_reg->g_snpsid);
- /* This should read as U3 followed by revision number */
- if ((revision & DWC3_GSNPSID_MASK) != 0x55330000) {
- puts("this is not a DesignWare USB3 DRD Core\n");
- return -1;
- }
-
- dwc3_core_soft_reset(dwc3_reg);
-
- dwc3_hwparams1 = readl(&dwc3_reg->g_hwparams1);
-
- reg = readl(&dwc3_reg->g_ctl);
- reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
- reg &= ~DWC3_GCTL_DISSCRAMBLE;
- switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1)) {
- case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
- reg &= ~DWC3_GCTL_DSBLCLKGTNG;
- break;
- default:
- debug("No power optimization available\n");
- }
-
- /*
- * WORKAROUND: DWC3 revisions <1.90a have a bug
- * where the device can fail to connect at SuperSpeed
- * and falls back to high-speed mode which causes
- * the device to enter a Connect/Disconnect loop
- */
- if ((revision & DWC3_REVISION_MASK) < 0x190a)
- reg |= DWC3_GCTL_U2RSTECN;
-
- writel(reg, &dwc3_reg->g_ctl);
-
- return 0;
-}
-
static int omap_xhci_core_init(struct omap_xhci *omap)
{
int ret = 0;
/*
* am35x_musb_enable - enable interrupts
*/
+#ifndef __UBOOT__
static void am35x_musb_enable(struct musb *musb)
+#else
+static int am35x_musb_enable(struct musb *musb)
+#endif
{
void __iomem *reg_base = musb->ctrl_base;
u32 epmask;
if (is_otg_enabled(musb))
musb_writel(reg_base, CORE_INTR_SRC_SET_REG,
AM35X_INTR_DRVVBUS << AM35X_INTR_USB_SHIFT);
+#ifdef __UBOOT__
+ return 0;
+#endif
}
/*
/*
* Program the HDRC to start (enable interrupts, dma, etc.).
*/
+#ifndef __UBOOT__
void musb_start(struct musb *musb)
+#else
+int musb_start(struct musb *musb)
+#endif
{
void __iomem *regs = musb->mregs;
u8 devctl = musb_readb(regs, MUSB_DEVCTL);
+#ifdef __UBOOT__
+ int ret;
+#endif
dev_dbg(musb->controller, "<== devctl %02x\n", devctl);
if ((devctl & MUSB_DEVCTL_VBUS) == MUSB_DEVCTL_VBUS)
musb->is_active = 1;
}
+
+#ifndef __UBOOT__
musb_platform_enable(musb);
+#else
+ ret = musb_platform_enable(musb);
+ if (ret) {
+ musb->is_active = 0;
+ return ret;
+ }
+#endif
musb_writeb(regs, MUSB_DEVCTL, devctl);
+
+#ifdef __UBOOT__
+ return 0;
+#endif
}
int (*init)(struct musb *musb);
int (*exit)(struct musb *musb);
+#ifndef __UBOOT__
void (*enable)(struct musb *musb);
+#else
+ int (*enable)(struct musb *musb);
+#endif
void (*disable)(struct musb *musb);
int (*set_mode)(struct musb *musb, u8 mode);
extern const char musb_driver_name[];
+#ifndef __UBOOT__
extern void musb_start(struct musb *musb);
+#else
+extern int musb_start(struct musb *musb);
+#endif
extern void musb_stop(struct musb *musb);
extern void musb_write_fifo(struct musb_hw_ep *ep, u16 len, const u8 *src);
musb->ops->set_vbus(musb, is_on);
}
+#ifndef __UBOOT__
static inline void musb_platform_enable(struct musb *musb)
{
if (musb->ops->enable)
musb->ops->enable(musb);
}
+#else
+static inline int musb_platform_enable(struct musb *musb)
+{
+ if (!musb->ops->enable)
+ return 0;
+
+ return musb->ops->enable(musb);
+}
+#endif
static inline void musb_platform_disable(struct musb *musb)
{
/**
* dsps_musb_enable - enable interrupts
*/
+#ifndef __UBOOT__
static void dsps_musb_enable(struct musb *musb)
+#else
+static int dsps_musb_enable(struct musb *musb)
+#endif
{
#ifndef __UBOOT__
struct device *dev = musb->controller;
if (is_otg_enabled(musb))
dsps_writel(reg_base, wrp->coreintr_set,
(1 << wrp->drvvbus) << wrp->usb_shift);
+#else
+ return 0;
#endif
}
#else
#include <common.h>
#include "linux-compat.h"
+#include <asm/processor.h>
#endif
#include "musb_core.h"
/* precompute addressing for external hub/tt ports */
if (musb->is_multipoint) {
+#ifndef __UBOOT__
struct usb_device *parent = urb->dev->parent;
+#else
+ struct usb_device *parent = usb_dev_get_parent(urb->dev);
+#endif
#ifndef __UBOOT__
if (parent != hcd->self.root_hub) {
#include "musb_core.h"
#include "musb_host.h"
#include "musb_gadget.h"
+#include "musb_uboot.h"
#ifdef CONFIG_MUSB_HOST
struct int_queue {
struct urb urb;
};
-static struct musb *host;
-static struct usb_hcd hcd;
-static enum usb_device_speed host_speed;
+#ifndef CONFIG_DM_USB
+struct musb_host_data musb_host;
+#endif
static void musb_host_complete_urb(struct urb *urb)
{
urb->dev->act_len = urb->actual_length;
}
-static struct usb_host_endpoint hep;
-static struct urb urb;
-
static void construct_urb(struct urb *urb, struct usb_host_endpoint *hep,
struct usb_device *dev, int endpoint_type,
unsigned long pipe, void *buffer, int len,
return urb->status;
}
-int submit_control_msg(struct usb_device *dev, unsigned long pipe,
- void *buffer, int len, struct devrequest *setup)
+static int _musb_submit_control_msg(struct musb_host_data *host,
+ struct usb_device *dev, unsigned long pipe,
+ void *buffer, int len, struct devrequest *setup)
{
- construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_CONTROL, pipe,
- buffer, len, setup, 0);
+ construct_urb(&host->urb, &host->hep, dev, USB_ENDPOINT_XFER_CONTROL,
+ pipe, buffer, len, setup, 0);
/* Fix speed for non hub-attached devices */
- if (!dev->parent)
- dev->speed = host_speed;
+ if (!usb_dev_get_parent(dev))
+ dev->speed = host->host_speed;
- return submit_urb(&hcd, &urb);
+ return submit_urb(&host->hcd, &host->urb);
}
-
-int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
- void *buffer, int len)
+static int _musb_submit_bulk_msg(struct musb_host_data *host,
+ struct usb_device *dev, unsigned long pipe, void *buffer, int len)
{
- construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_BULK, pipe,
- buffer, len, NULL, 0);
- return submit_urb(&hcd, &urb);
+ construct_urb(&host->urb, &host->hep, dev, USB_ENDPOINT_XFER_BULK,
+ pipe, buffer, len, NULL, 0);
+ return submit_urb(&host->hcd, &host->urb);
}
-int submit_int_msg(struct usb_device *dev, unsigned long pipe,
- void *buffer, int len, int interval)
+static int _musb_submit_int_msg(struct musb_host_data *host,
+ struct usb_device *dev, unsigned long pipe,
+ void *buffer, int len, int interval)
{
- construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_INT, pipe,
+ construct_urb(&host->urb, &host->hep, dev, USB_ENDPOINT_XFER_INT, pipe,
buffer, len, NULL, interval);
- return submit_urb(&hcd, &urb);
+ return submit_urb(&host->hcd, &host->urb);
}
-struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
- int queuesize, int elementsize, void *buffer, int interval)
+static struct int_queue *_musb_create_int_queue(struct musb_host_data *host,
+ struct usb_device *dev, unsigned long pipe, int queuesize,
+ int elementsize, void *buffer, int interval)
{
struct int_queue *queue;
int ret, index = usb_pipein(pipe) * 16 + usb_pipeendpoint(pipe);
construct_urb(&queue->urb, &queue->hep, dev, USB_ENDPOINT_XFER_INT,
pipe, buffer, elementsize, NULL, interval);
- ret = musb_urb_enqueue(&hcd, &queue->urb, 0);
+ ret = musb_urb_enqueue(&host->hcd, &queue->urb, 0);
if (ret < 0) {
printf("Failed to enqueue URB to controller\n");
free(queue);
return queue;
}
-int destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
+static int _musb_destroy_int_queue(struct musb_host_data *host,
+ struct usb_device *dev, struct int_queue *queue)
{
int index = usb_pipein(queue->urb.pipe) * 16 +
usb_pipeendpoint(queue->urb.pipe);
if (queue->urb.status == -EINPROGRESS)
- musb_urb_dequeue(&hcd, &queue->urb, -ETIME);
+ musb_urb_dequeue(&host->hcd, &queue->urb, -ETIME);
dev->int_pending &= ~(1 << index);
free(queue);
return 0;
}
-void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
+static void *_musb_poll_int_queue(struct musb_host_data *host,
+ struct usb_device *dev, struct int_queue *queue)
{
if (queue->urb.status != -EINPROGRESS)
return NULL; /* URB has already completed in a prev. poll */
- host->isr(0, host);
+ host->host->isr(0, host->host);
if (queue->urb.status != -EINPROGRESS)
return queue->urb.transfer_buffer; /* Done */
return NULL; /* URB still pending */
}
-int usb_reset_root_port(void)
+static int _musb_reset_root_port(struct musb_host_data *host,
+ struct usb_device *dev)
{
- void *mbase = host->mregs;
+ void *mbase = host->host->mregs;
u8 power;
power = musb_readb(mbase, MUSB_POWER);
#ifdef CONFIG_ARCH_SUNXI
sunxi_usb_phy_enable_squelch_detect(0, 1);
#endif
- host->isr(0, host);
- host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
+ host->host->isr(0, host->host);
+ host->host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
USB_SPEED_HIGH :
(musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
USB_SPEED_FULL : USB_SPEED_LOW;
- mdelay((host_speed == USB_SPEED_LOW) ? 200 : 50);
+ mdelay((host->host_speed == USB_SPEED_LOW) ? 200 : 50);
return 0;
}
-int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+int musb_lowlevel_init(struct musb_host_data *host)
{
void *mbase;
/* USB spec says it may take up to 1 second for a device to connect */
unsigned long timeout = get_timer(0) + 1000;
+ int ret;
- if (!host) {
+ if (!host->host) {
printf("MUSB host is not registered\n");
return -ENODEV;
}
- musb_start(host);
- mbase = host->mregs;
+ ret = musb_start(host->host);
+ if (ret)
+ return ret;
+
+ mbase = host->host->mregs;
do {
if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM)
break;
if (get_timer(0) >= timeout)
return -ENODEV;
- usb_reset_root_port();
- host->is_active = 1;
- hcd.hcd_priv = host;
+ _musb_reset_root_port(host, NULL);
+ host->host->is_active = 1;
+ host->hcd.hcd_priv = host->host;
return 0;
}
+#ifndef CONFIG_DM_USB
int usb_lowlevel_stop(int index)
{
- if (!host) {
+ if (!musb_host.host) {
printf("MUSB host is not registered\n");
return -ENODEV;
}
- musb_stop(host);
+ musb_stop(musb_host.host);
return 0;
}
+
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length)
+{
+ return _musb_submit_bulk_msg(&musb_host, dev, pipe, buffer, length);
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length, struct devrequest *setup)
+{
+ return _musb_submit_control_msg(&musb_host, dev, pipe, buffer, length, setup);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length, int interval)
+{
+ return _musb_submit_int_msg(&musb_host, dev, pipe, buffer, length, interval);
+}
+
+struct int_queue *create_int_queue(struct usb_device *dev,
+ unsigned long pipe, int queuesize, int elementsize,
+ void *buffer, int interval)
+{
+ return _musb_create_int_queue(&musb_host, dev, pipe, queuesize, elementsize,
+ buffer, interval);
+}
+
+void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+ return _musb_poll_int_queue(&musb_host, dev, queue);
+}
+
+int destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+ return _musb_destroy_int_queue(&musb_host, dev, queue);
+}
+
+int usb_reset_root_port(struct usb_device *dev)
+{
+ return _musb_reset_root_port(&musb_host, dev);
+}
+
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+{
+ return musb_lowlevel_init(&musb_host);
+}
+#endif /* !CONFIG_DM_USB */
+
+#ifdef CONFIG_DM_USB
+static int musb_submit_control_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ struct devrequest *setup)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ return _musb_submit_control_msg(host, udev, pipe, buffer, length, setup);
+}
+
+static int musb_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ return _musb_submit_bulk_msg(host, udev, pipe, buffer, length);
+}
+
+static int musb_submit_int_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ int interval)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ return _musb_submit_int_msg(host, udev, pipe, buffer, length, interval);
+}
+
+static struct int_queue *musb_create_int_queue(struct udevice *dev,
+ struct usb_device *udev, unsigned long pipe, int queuesize,
+ int elementsize, void *buffer, int interval)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ return _musb_create_int_queue(host, udev, pipe, queuesize, elementsize,
+ buffer, interval);
+}
+
+static void *musb_poll_int_queue(struct udevice *dev, struct usb_device *udev,
+ struct int_queue *queue)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ return _musb_poll_int_queue(host, udev, queue);
+}
+
+static int musb_destroy_int_queue(struct udevice *dev, struct usb_device *udev,
+ struct int_queue *queue)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ return _musb_destroy_int_queue(host, udev, queue);
+}
+
+static int musb_reset_root_port(struct udevice *dev, struct usb_device *udev)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ return _musb_reset_root_port(host, udev);
+}
+
+struct dm_usb_ops musb_usb_ops = {
+ .control = musb_submit_control_msg,
+ .bulk = musb_submit_bulk_msg,
+ .interrupt = musb_submit_int_msg,
+ .create_int_queue = musb_create_int_queue,
+ .poll_int_queue = musb_poll_int_queue,
+ .destroy_int_queue = musb_destroy_int_queue,
+ .reset_root_port = musb_reset_root_port,
+};
+#endif /* CONFIG_DM_USB */
#endif /* CONFIG_MUSB_HOST */
#ifdef CONFIG_MUSB_GADGET
struct musb **musbp;
switch (plat->mode) {
-#ifdef CONFIG_MUSB_HOST
+#if defined(CONFIG_MUSB_HOST) && !defined(CONFIG_DM_USB)
case MUSB_HOST:
- musbp = &host;
+ musbp = &musb_host.host;
break;
#endif
#ifdef CONFIG_MUSB_GADGET
--- /dev/null
+/*
+ * MUSB OTG driver u-boot specific functions
+ *
+ * Copyright © 2015 Hans de Goede <hdegoede@redhat.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef __MUSB_UBOOT_H__
+#define __MUSB_UBOOT_H__
+
+#include <usb.h>
+#include "linux-compat.h"
+#include "usb-compat.h"
+#include "musb_core.h"
+
+struct musb_host_data {
+ struct musb *host;
+ struct usb_hcd hcd;
+ enum usb_device_speed host_speed;
+ struct usb_host_endpoint hep;
+ struct urb urb;
+};
+
+extern struct dm_usb_ops musb_usb_ops;
+
+int musb_lowlevel_init(struct musb_host_data *host);
+
+#endif
return status;
}
+#ifndef __UBOOT__
static void omap2430_musb_enable(struct musb *musb)
+#else
+static int omap2430_musb_enable(struct musb *musb)
+#endif
{
#ifndef __UBOOT__
u8 devctl;
__PRETTY_FUNCTION__);
}
#endif
+ return 0;
#endif
}
#include <asm/arch/gpio.h>
#include <asm/arch/usb_phy.h>
#include <asm-generic/gpio.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <linux/usb/musb.h>
#include "linux-compat.h"
#include "musb_core.h"
-#ifdef CONFIG_AXP152_POWER
-#include <axp152.h>
-#endif
-#ifdef CONFIG_AXP209_POWER
-#include <axp209.h>
-#endif
-#ifdef CONFIG_AXP221_POWER
-#include <axp221.h>
-#endif
+#include "musb_uboot.h"
/******************************************************************************
******************************************************************************
/* musb_core does not call enable / disable in a balanced manner <sigh> */
static bool enabled = false;
-static void sunxi_musb_enable(struct musb *musb)
+static int sunxi_musb_enable(struct musb *musb)
{
+ int ret;
+
pr_debug("%s():\n", __func__);
if (enabled)
- return;
+ return 0;
/* select PIO mode */
musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
- if (is_host_enabled(musb))
+ if (is_host_enabled(musb)) {
+ ret = sunxi_usb_phy_vbus_detect(0);
+ if (ret == 1) {
+ printf("A charger is plugged into the OTG: ");
+ return -ENODEV;
+ }
+ ret = sunxi_usb_phy_id_detect(0);
+ if (ret == 1) {
+ printf("No host cable detected: ");
+ return -ENODEV;
+ }
sunxi_usb_phy_power_on(0); /* port power on */
+ }
USBC_ForceVbusValidToHigh(musb->mregs);
enabled = true;
+ return 0;
}
static void sunxi_musb_disable(struct musb *musb)
static int sunxi_musb_init(struct musb *musb)
{
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
- int err;
pr_debug("%s():\n", __func__);
- if (is_host_enabled(musb)) {
- err = sunxi_usb_phy_vbus_detect(0);
- if (err) {
- eprintf("Error: A charger is plugged into the OTG\n");
- return -EIO;
- }
- }
-
musb->isr = sunxi_musb_interrupt;
setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0);
return 0;
}
-const struct musb_platform_ops sunxi_musb_ops = {
+static const struct musb_platform_ops sunxi_musb_ops = {
.init = sunxi_musb_init,
.enable = sunxi_musb_enable,
.disable = sunxi_musb_disable,
};
+
+static struct musb_hdrc_config musb_config = {
+ .multipoint = 1,
+ .dyn_fifo = 1,
+ .num_eps = 6,
+ .ram_bits = 11,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#if defined(CONFIG_MUSB_HOST)
+ .mode = MUSB_HOST,
+#else
+ .mode = MUSB_PERIPHERAL,
+#endif
+ .config = &musb_config,
+ .power = 250,
+ .platform_ops = &sunxi_musb_ops,
+};
+
+#ifdef CONFIG_MUSB_HOST
+int musb_usb_probe(struct udevice *dev)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+ struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
+ int ret;
+
+ priv->desc_before_addr = true;
+
+ if (!host->host) {
+ host->host = musb_init_controller(&musb_plat, NULL,
+ (void *)SUNXI_USB0_BASE);
+ if (!host->host)
+ return -EIO;
+ }
+
+ ret = musb_lowlevel_init(host);
+ if (ret == 0)
+ printf("MUSB OTG\n");
+
+ return ret;
+}
+
+int musb_usb_remove(struct udevice *dev)
+{
+ struct musb_host_data *host = dev_get_priv(dev);
+
+ musb_stop(host->host);
+
+ return 0;
+}
+
+U_BOOT_DRIVER(usb_musb) = {
+ .name = "sunxi-musb",
+ .id = UCLASS_USB,
+ .probe = musb_usb_probe,
+ .remove = musb_usb_remove,
+ .ops = &musb_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+ .priv_auto_alloc_size = sizeof(struct musb_host_data),
+};
+#endif
+
+void sunxi_musb_board_init(void)
+{
+#ifdef CONFIG_MUSB_HOST
+ struct udevice *dev;
+
+ /*
+ * Bind the driver directly for now as musb linux kernel support is
+ * still pending upstream so our dts files do not have the necessary
+ * nodes yet. TODO: Remove this as soon as the dts nodes are in place
+ * and bind by compatible instead.
+ */
+ device_bind_driver(dm_root(), "sunxi-musb", "sunxi-musb", &dev);
+#else
+ musb_register(&musb_plat, NULL, (void *)SUNXI_USB0_BASE);
+#endif
+}
#ifndef __USB_COMPAT_H__
#define __USB_COMPAT_H__
+#include <dm.h>
#include "usb.h"
struct usb_hcd {
return 0;
}
+#ifdef CONFIG_DM_USB
+static inline u16 find_tt(struct usb_device *udev)
+{
+ struct udevice *parent;
+ struct usb_device *uparent, *ttdev;
+
+ /*
+ * When called from usb-uclass.c: usb_scan_device() udev->dev points
+ * to the parent udevice, not the actual udevice belonging to the
+ * udev as the device is not instantiated yet. So when searching
+ * for the first usb-2 parent start with udev->dev not
+ * udev->dev->parent .
+ */
+ ttdev = udev;
+ parent = udev->dev;
+ uparent = dev_get_parentdata(parent);
+
+ while (uparent->speed != USB_SPEED_HIGH) {
+ struct udevice *dev = parent;
+
+ if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB) {
+ printf("musb: Error cannot find high speed parent of usb-1 device\n");
+ return 0;
+ }
+
+ ttdev = dev_get_parentdata(dev);
+ parent = dev->parent;
+ uparent = dev_get_parentdata(parent);
+ }
+
+ return (uparent->devnum << 8) | (ttdev->portnr - 1);
+}
+
+static inline struct usb_device *usb_dev_get_parent(struct usb_device *udev)
+{
+ struct udevice *parent = udev->dev->parent;
+
+ /*
+ * When called from usb-uclass.c: usb_scan_device() udev->dev points
+ * to the parent udevice, not the actual udevice belonging to the
+ * udev as the device is not instantiated yet.
+ *
+ * If dev is an usb-bus, then we are called from usb_scan_device() for
+ * an usb-device plugged directly into the root port, return NULL.
+ */
+ if (device_get_uclass_id(udev->dev) == UCLASS_USB)
+ return NULL;
+
+ /*
+ * If these 2 are not the same we are being called from
+ * usb_scan_device() and udev itself is the parent.
+ */
+ if (dev_get_parentdata(udev->dev) != udev)
+ return udev;
+
+ /* We are being called normally, use the parent pointer */
+ if (device_get_uclass_id(parent) == UCLASS_USB_HUB)
+ return dev_get_parentdata(parent);
+
+ return NULL;
+}
+#else
static inline u16 find_tt(struct usb_device *dev)
{
u8 chid;
return (hub << 8) | chid;
}
+
+static inline struct usb_device *usb_dev_get_parent(struct usb_device *dev)
+{
+ return dev->parent;
+}
+#endif
+
#endif /* __USB_COMPAT_H__ */
}
#endif /* CONFIG_AM437X_USB2PHY2_HOST */
-void omap_reset_usb_phy(struct dwc3 *dwc3_reg)
-{
- /* Assert USB3 PHY reset */
- setbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
-
- /* Assert USB2 PHY reset */
- setbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
-
- mdelay(100);
-
- /* Clear USB3 PHY reset */
- clrbits_le32(&dwc3_reg->g_usb3pipectl[0], DWC3_GUSB3PIPECTL_PHYSOFTRST);
-
- /* Clear USB2 PHY reset */
- clrbits_le32(&dwc3_reg->g_usb2phycfg, DWC3_GUSB2PHYCFG_PHYSOFTRST);
-
-}
-
void omap_enable_phy(struct omap_xhci *omap)
{
#ifdef CONFIG_OMAP_USB2PHY2_HOST
It can be overridden from the command line:
$ make DEVICE_TREE=<device-tree-name>
+config OF_SPL_REMOVE_PROPS
+ string "List of device tree properties to drop for SPL"
+ depends on OF_CONTROL && SPL
+ default "pinctrl-0 pinctrl-names clocks clock-names interrupt-parent"
+ help
+ Since SPL normally runs in a reduced memory space, the device tree
+ is cut down to only what is needed to load and start U-Boot. Only
+ nodes marked with the property "u-boot,dm-pre-reloc" will be
+ included. In addition, some properties are not used by U-Boot and
+ can be discarded. This option defines the list of properties to
+ discard.
+
endmenu
const char *, char **, unsigned int)
EXPORT_FUNC(ustrtoull, unsigned long long, ustrtoull,
const char *, char **, unsigned int)
+ EXPORT_FUNC(strcpy, char *, strcpy, char *dest, const char *src)
+ EXPORT_FUNC(mdelay, void, mdelay, unsigned long msec)
+#ifdef CONFIG_PHY_AQUANTIA
+ EXPORT_FUNC(mdio_get_current_dev, struct mii_dev *,
+ mdio_get_current_dev, void)
+ EXPORT_FUNC(phy_find_by_mask, struct phy_device *, phy_find_by_mask,
+ struct mii_dev *bus, unsigned phy_mask,
+ phy_interface_t interface)
+ EXPORT_FUNC(mdio_phydev_for_ethname, struct phy_device *,
+ mdio_phydev_for_ethname, const char *ethname)
+ EXPORT_FUNC(miiphy_set_current_dev, int, miiphy_set_current_dev,
+ const char *devname)
+#endif
#define GD_FLG_ENV_READY 0x00080 /* Env. imported into hash table */
#define GD_FLG_SERIAL_READY 0x00100 /* Pre-reloc serial console ready */
#define GD_FLG_FULL_MALLOC_INIT 0x00200 /* Full malloc() is ready */
+#define GD_FLG_SPL_INIT 0x00400 /* spl_init() has been called */
#endif /* __ASM_GENERIC_GBL_DATA_H */
*/
const char *gpio_get_bank_info(struct udevice *dev, int *offset_count);
+/**
+ * dm_gpio_lookup_name() - Look up a named GPIO and return its description
+ *
+ * The name of a GPIO is typically its bank name followed by a number from 0.
+ * For example A0 is the first GPIO in bank A. Each bank is a separate driver
+ * model device.
+ *
+ * @name: Name to look up
+ * @desc: Returns description, on success
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc);
+
/**
* gpio_lookup_name - Look up a GPIO name and return its details
*
struct gpio_desc *desc_list, int max_count,
int flags);
+/**
+ * dm_gpio_request() - manually request a GPIO
+ *
+ * Note: This function should only be used for testing / debugging. Instead.
+ * use gpio_request_by_name() to pull GPIOs from the device tree.
+ *
+ * @desc: GPIO description of GPIO to request (see dm_gpio_lookup_name())
+ * @label: Label to attach to the GPIO while claimed
+ * @return 0 if OK, -ve on error
+ */
+int dm_gpio_request(struct gpio_desc *desc, const char *label);
+
/**
* gpio_get_list_count() - Returns the number of GPIOs in a list
*
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
#ifndef _CLK_H_
#define _CLK_H_
int soc_clk_dump(void);
+struct clk_ops {
+ /**
+ * get_rate() - Get current clock rate
+ *
+ * @dev: Device to check (UCLASS_CLK)
+ * @return clock rate in Hz, or -ve error code
+ */
+ ulong (*get_rate)(struct udevice *dev);
+
+ /**
+ * set_rate() - Set current clock rate
+ *
+ * @dev: Device to adjust
+ * @rate: New clock rate in Hz
+ * @return new rate, or -ve error code
+ */
+ ulong (*set_rate)(struct udevice *dev, ulong rate);
+
+ /**
+ * clk_set_periph_rate() - Set clock rate for a peripheral
+ *
+ * @dev: Device to adjust (UCLASS_CLK)
+ * @rate: New clock rate in Hz
+ * @return new clock rate in Hz, or -ve error code
+ */
+ ulong (*get_periph_rate)(struct udevice *dev, int periph);
+
+ /**
+ * clk_set_periph_rate() - Set current clock rate for a peripheral
+ *
+ * @dev: Device to update (UCLASS_CLK)
+ * @periph: Peripheral ID to cupdate
+ * @return new clock rate in Hz, or -ve error code
+ */
+ ulong (*set_periph_rate)(struct udevice *dev, int periph, ulong rate);
+};
+
+#define clk_get_ops(dev) ((struct clk_ops *)(dev)->driver->ops)
+
+/**
+ * clk_get_rate() - Get current clock rate
+ *
+ * @dev: Device to check (UCLASS_CLK)
+ * @return clock rate in Hz, or -ve error code
+ */
+ulong clk_get_rate(struct udevice *dev);
+
+/**
+ * set_rate() - Set current clock rate
+ *
+ * @dev: Device to adjust
+ * @rate: New clock rate in Hz
+ * @return new rate, or -ve error code
+ */
+ulong clk_set_rate(struct udevice *dev, ulong rate);
+
+/**
+ * clk_get_periph_rate() - Get current clock rate for a peripheral
+ *
+ * @dev: Device to check (UCLASS_CLK)
+ * @return clock rate in Hz, -ve error code
+ */
+ulong clk_get_periph_rate(struct udevice *dev, int periph);
+
+/**
+ * clk_set_periph_rate() - Set current clock rate for a peripheral
+ *
+ * @dev: Device to update (UCLASS_CLK)
+ * @periph: Peripheral ID to cupdate
+ * @return new clock rate in Hz, or -ve error code
+ */
+ulong clk_set_periph_rate(struct udevice *dev, int periph, ulong rate);
+
#endif /* _CLK_H_ */
extern int do_bootz(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern int do_booti(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+
extern int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
char *const argv[]);
#define DEFINE_CACHE_ALIGN_BUFFER(type, name, size) \
DEFINE_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN)
+/*
+ * check_member() - Check the offset of a structure member
+ *
+ * @structure: Name of structure (e.g. global_data)
+ * @member: Name of member (e.g. baudrate)
+ * @offset: Expected offset in bytes
+ */
+#define check_member(structure, member, offset) _Static_assert( \
+ offsetof(struct structure, member) == offset, \
+ "`struct " #structure "` offset for `" #member "` is not " #offset)
+
/* Pull in stuff for the build system */
#ifdef DO_DEPS_ONLY
# include <environment.h>
/* For secure boot flow, default environment used will be used */
#if defined(CONFIG_SYS_RAMBOOT)
+#ifdef CONFIG_BOOTSCRIPT_COPY_RAM
+#define CONFIG_BS_COPY_ENV \
+ "setenv bs_hdr_ram " __stringify(CONFIG_BS_HDR_ADDR_RAM)";" \
+ "setenv bs_hdr_flash " __stringify(CONFIG_BS_HDR_ADDR_FLASH)";" \
+ "setenv bs_hdr_size " __stringify(CONFIG_BS_HDR_SIZE)";" \
+ "setenv bs_ram " __stringify(CONFIG_BS_ADDR_RAM)";" \
+ "setenv bs_flash " __stringify(CONFIG_BS_ADDR_FLASH)";" \
+ "setenv bs_size " __stringify(CONFIG_BS_SIZE)";"
+
+#if defined(CONFIG_RAMBOOT_NAND)
+#define CONFIG_BS_COPY_CMD \
+ "nand read $bs_hdr_ram $bs_hdr_flash $bs_hdr_size ;" \
+ "nand read $bs_ram $bs_flash $bs_size ;"
+#endif /* CONFIG_RAMBOOT_NAND */
+#endif /* CONFIG_BOOTSCRIPT_COPY_RAM */
+
#if defined(CONFIG_RAMBOOT_SPIFLASH)
#undef CONFIG_ENV_IS_IN_SPI_FLASH
#elif defined(CONFIG_RAMBOOT_NAND)
#define CONFIG_ENV_IS_NOWHERE
+#ifndef CONFIG_BS_COPY_ENV
+#define CONFIG_BS_COPY_ENV
+#endif
+
+#ifndef CONFIG_BS_COPY_CMD
+#define CONFIG_BS_COPY_CMD
+#endif
+
+#define CONFIG_SECBOOT_CMD CONFIG_BS_COPY_ENV \
+ CONFIG_BS_COPY_CMD \
+ CONFIG_SECBOOT
/*
* We don't want boot delay for secure boot flow
* before autoboot starts
#undef CONFIG_BOOTDELAY
#define CONFIG_BOOTDELAY 0
#undef CONFIG_BOOTCOMMAND
-#define CONFIG_BOOTCOMMAND CONFIG_SECBOOT
+#define CONFIG_BOOTCOMMAND CONFIG_SECBOOT_CMD
/*
* CONFIG_ZERO_BOOTDELAY_CHECK should not be defined for
#ifndef __T1024RDB_H
#define __T1024RDB_H
-#if defined(CONFIG_T1023RDB)
-#ifdef CONFIG_SPL
-#define CONFIG_SYS_NO_FLASH
-#endif
-#endif
-
/* High Level Configuration Options */
#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_DISPLAY_BOARDINFO
#if defined(CONFIG_T1024RDB)
#define CONFIG_SYS_NOR_CSOR CSOR_NAND_TRHZ_80
#elif defined(CONFIG_T1023RDB)
-#define CONFIG_SYS_NOR_CSOR (CSOR_NOR_ADM_SHIFT(4) | \
+#define CONFIG_SYS_NOR_CSOR (CSOR_NOR_ADM_SHIFT(0) | \
CSOR_NAND_TRHZ_80 | CSOR_NOR_ADM_SHFT_MODE_EN)
#endif
#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x4) | \
| CSOR_NAND_PB(64)) /*Pages Per Block = 64*/
#define CONFIG_SYS_NAND_BLOCK_SIZE (512 * 1024)
#elif defined(CONFIG_T1023RDB)
-#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_RAL_3 /* RAL 3Bytes */ \
+#define CONFIG_SYS_NAND_CSOR (CSOR_NAND_ECC_ENC_EN /* ECC on encode */ \
+ | CSOR_NAND_ECC_DEC_EN /* ECC on decode */ \
+ | CSOR_NAND_ECC_MODE_4 /* 4-bit ECC */ \
| CSOR_NAND_RAL_3 /* RAL 3Bytes */ \
| CSOR_NAND_PGS_2K /* Page Size = 2K */ \
| CSOR_NAND_SPRZ_128 /* Spare size = 128 */ \
#define CONFIG_SYS_FSL_I2C_OFFSET 0x118000
#define CONFIG_SYS_FSL_I2C2_OFFSET 0x118100
-#define I2C_MUX_PCA_ADDR 0x77
-#define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/
-
+#define I2C_PCA6408_BUS_NUM 1
+#define I2C_PCA6408_ADDR 0x20
/* I2C bus multiplexer */
#define I2C_MUX_CH_DEFAULT 0x8
#define CONFIG_SYS_DPAA_FMAN
+#ifdef CONFIG_T1024RDB
#define CONFIG_QE
#define CONFIG_U_QE
+#endif
/* Default address of microcode for the Linux FMan driver */
#if defined(CONFIG_SPIFLASH)
/*
#ifdef CONFIG_T1042RDB
#define CONFIG_SYS_FSL_PBL_RCW $(SRCTREE)/board/freescale/t104xrdb/t1042_rcw.cfg
#endif
+#ifdef CONFIG_T1040D4RDB
+#define CONFIG_SYS_FSL_PBL_RCW \
+$(SRCTREE)/board/freescale/t104xrdb/t1040d4_rcw.cfg
+#endif
+#ifdef CONFIG_T1042D4RDB
+#define CONFIG_SYS_FSL_PBL_RCW \
+$(SRCTREE)/board/freescale/t104xrdb/t1042d4_rcw.cfg
+#endif
#define CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT
#define CONFIG_SPL_ENV_SUPPORT
#define CONFIG_CHIP_SELECTS_PER_CTRL (2 * CONFIG_DIMM_SLOTS_PER_CTLR)
#define CONFIG_DDR_SPD
+#ifndef CONFIG_SYS_FSL_DDR4
#define CONFIG_SYS_FSL_DDR3
+#endif
#define CONFIG_SYS_SPD_BUS_NUM 0
#define SPD_EEPROM_ADDRESS 0x51
#define CPLD_LBMAP_DFLTBANK 0x40 /* BANK OR | BANK0 */
#define CPLD_LBMAP_RESET 0xFF
#define CPLD_LBMAP_SHIFT 0x03
-#ifdef CONFIG_T1042RDB_PI
+
+#if defined(CONFIG_T1042RDB_PI)
#define CPLD_DIU_SEL_DFP 0x80
+#elif defined(CONFIG_T1042D4RDB)
+#define CPLD_DIU_SEL_DFP 0xc0
+#endif
+
+#if defined(CONFIG_T1040D4RDB)
+#define CPLD_INT_MASK_ALL 0xFF
+#define CPLD_INT_MASK_THERM 0x80
+#define CPLD_INT_MASK_DVI_DFP 0x40
+#define CPLD_INT_MASK_QSGMII1 0x20
+#define CPLD_INT_MASK_QSGMII2 0x10
+#define CPLD_INT_MASK_SGMI1 0x08
+#define CPLD_INT_MASK_SGMI2 0x04
+#define CPLD_INT_MASK_TDMR1 0x02
+#define CPLD_INT_MASK_TDMR2 0x01
#endif
#define CONFIG_SYS_CPLD_BASE 0xffdf0000
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
-#ifdef CONFIG_T1042RDB_PI
+#if defined(CONFIG_T1042RDB_PI) || defined(CONFIG_T1042D4RDB)
/* Video */
#define CONFIG_FSL_DIU_FB
/* I2C bus multiplexer */
#define I2C_MUX_PCA_ADDR 0x70
-#if defined(CONFIG_T1040RDB) || defined(CONFIG_T1042RDB)
+#if defined(CONFIG_T104xRDB) || defined(CONFIG_T104XD4RDB)
#define I2C_MUX_CH_DEFAULT 0x8
#endif
-#ifdef CONFIG_T1042RDB_PI
+#if defined(CONFIG_T1042RDB_PI) || defined(CONFIG_T104XD4RDB)
/* LDI/DVI Encoder for display */
#define CONFIG_SYS_I2C_LDI_ADDR 0x38
#define CONFIG_SYS_I2C_DVI_ADDR 0x75
#define CONFIG_SYS_DPAA_FMAN
#define CONFIG_SYS_DPAA_PME
-#if defined(CONFIG_T1040RDB) || defined(CONFIG_T1042RDB)
+#if defined(CONFIG_T104xRDB) || defined(CONFIG_T104XD4RDB)
#define CONFIG_QE
#define CONFIG_U_QE
#endif
#define CONFIG_SYS_FMAN_FW_ADDR 0xEFF00000
#endif
-#if defined(CONFIG_T1040RDB) || defined(CONFIG_T1042RDB)
+#if defined(CONFIG_T104xRDB) || defined(CONFIG_T104XD4RDB)
#if defined(CONFIG_SPIFLASH)
#define CONFIG_SYS_QE_FW_ADDR 0x130000
#elif defined(CONFIG_SDCARD)
#ifdef CONFIG_FMAN_ENET
#if defined(CONFIG_T1040RDB) || defined(CONFIG_T1042RDB)
-#define CONFIG_SYS_SGMII1_PHY_ADDR 0x03
+#define CONFIG_SYS_SGMII1_PHY_ADDR 0x03
+#elif defined(CONFIG_T1040D4RDB) || defined(CONFIG_T1042D4RDB)
+#define CONFIG_SYS_SGMII1_PHY_ADDR 0x02
+#define CONFIG_SYS_SGMII2_PHY_ADDR 0x03
+#define CONFIG_SYS_SGMII3_PHY_ADDR 0x01
+#endif
+
+#ifdef CONFIG_T104XD4RDB
+#define CONFIG_SYS_RGMII1_PHY_ADDR 0x04
+#define CONFIG_SYS_RGMII2_PHY_ADDR 0x05
+#else
+#define CONFIG_SYS_RGMII1_PHY_ADDR 0x01
+#define CONFIG_SYS_RGMII2_PHY_ADDR 0x02
#endif
-#define CONFIG_SYS_RGMII1_PHY_ADDR 0x01
-#define CONFIG_SYS_RGMII2_PHY_ADDR 0x02
/* Enable VSC9953 L2 Switch driver on T1040 SoC */
-#ifdef CONFIG_T1040RDB
+#if defined(CONFIG_T1040RDB) || defined(CONFIG_T1040D4RDB)
#define CONFIG_VSC9953
#define CONFIG_VSC9953_CMD
+#ifdef CONFIG_T1040RDB
#define CONFIG_SYS_FM1_QSGMII11_PHY_ADDR 0x04
#define CONFIG_SYS_FM1_QSGMII21_PHY_ADDR 0x08
+#else
+#define CONFIG_SYS_FM1_QSGMII11_PHY_ADDR 0x08
+#define CONFIG_SYS_FM1_QSGMII21_PHY_ADDR 0x0c
+#endif
#endif
#define CONFIG_MII /* MII PHY management */
#define FDTFILE "t1042rdb_pi/t1042rdb_pi.dtb"
#elif defined(CONFIG_T1042RDB)
#define FDTFILE "t1042rdb/t1042rdb.dtb"
+#elif defined(CONFIG_T1040D4RDB)
+#define FDTFILE "t1042rdb/t1040d4rdb.dtb"
+#elif defined(CONFIG_T1042D4RDB)
+#define FDTFILE "t1042rdb/t1042d4rdb.dtb"
#endif
#ifdef CONFIG_FSL_DIU_FB
#ifndef __CONFIG_H
#define __CONFIG_H
-#include <asm/arch/ag101.h>
+#include <asm/arch-ag101/ag101.h>
/*
* CPU and Board Configuration Options
#ifndef __CONFIG_H
#define __CONFIG_H
-#include <asm/arch/ag101.h>
+#include <asm/arch-ag101/ag101.h>
/*
* CPU and Board Configuration Options
#ifndef __CONFIG_H
#define __CONFIG_H
-#include <asm/arch/ag102.h>
+#include <asm/arch-ag102/ag102.h>
/*
* CPU and Board Configuration Options
#define CONFIG_MUSB_PIO_ONLY
#define CONFIG_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_USB_GADGET
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_USB_GADGET_DUALSPEED
#define CONFIG_USB_GADGET_VBUS_DRAW 2
#define CONFIG_MUSB_HOST
#ifndef CONFIG_SPL_USBETH_SUPPORT
/* Fastboot */
+#define CONFIG_USB_FUNCTION_FASTBOOT
#define CONFIG_CMD_FASTBOOT
#define CONFIG_ANDROID_BOOT_IMAGE
-#define CONFIG_USB_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
-#define CONFIG_USB_FASTBOOT_BUF_SIZE 0x07000000
+#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
+#define CONFIG_FASTBOOT_BUF_SIZE 0x07000000
/* To support eMMC booting */
#define CONFIG_STORAGE_EMMC
/* USB Device Firmware Update support */
#ifndef CONFIG_SPL_BUILD
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_MMC
#define CONFIG_CMD_DFU
#define DFU_ALT_INFO_MMC \
#define CONFIG_MISC_INIT_R
+#define CONFIG_OF_LIBFDT
+
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_INITRD_TAG 1
#endif
/* Now bring in the rest of the common code. */
-#include <configs/ti_armv7_common.h>
+#include <configs/ti_armv7_omap.h>
/* Always 64 KiB env size */
#define CONFIG_ENV_SIZE (64 << 10)
#define CONFIG_CMD_USB
#define CONFIG_USB_HOST
#define CONFIG_USB_XHCI
+#define CONFIG_USB_XHCI_DWC3
#define CONFIG_USB_XHCI_OMAP
#define CONFIG_USB_STORAGE
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
#define CONFIG_USB_DWC3_GADGET
#define CONFIG_USB_GADGET
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_USB_GADGET_VBUS_DRAW 2
#define CONFIG_G_DNL_MANUFACTURER "Texas Instruments"
#define CONFIG_G_DNL_VENDOR_NUM 0x0403
#ifndef CONFIG_SPL_BUILD
/* USB Device Firmware Update support */
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_RAM
#define CONFIG_CMD_DFU
#define CONFIG_MUSB_PIO_ONLY
#define CONFIG_MUSB_DISABLE_BULK_COMBINE_SPLIT
#define CONFIG_USB_GADGET
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_USB_GADGET_DUALSPEED
#define CONFIG_USB_GADGET_VBUS_DRAW 2
#define CONFIG_MUSB_HOST
#ifndef CONFIG_SPL_USBETH_SUPPORT
/* Fastboot */
+#define CONFIG_USB_FUNCTION_FASTBOOT
#define CONFIG_CMD_FASTBOOT
#define CONFIG_ANDROID_BOOT_IMAGE
-#define CONFIG_USB_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
-#define CONFIG_USB_FASTBOOT_BUF_SIZE 0x07000000
+#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
+#define CONFIG_FASTBOOT_BUF_SIZE 0x07000000
/* To support eMMC booting */
#define CONFIG_STORAGE_EMMC
#ifdef CONFIG_MUSB_GADGET
#define CONFIG_CMD_USB_MASS_STORAGE
-#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
/* USB TI's IDs */
#define CONFIG_G_DNL_VENDOR_NUM 0x0451
/* USB Device Firmware Update support */
#ifndef CONFIG_SPL_BUILD
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_MMC
#define CONFIG_CMD_DFU
#define DFU_ALT_INFO_MMC \
* for example.
*/
#define CONFIG_DOS_PARTITION
+#define CONFIG_EFI_PARTITION
/* version string, parser, etc */
#define CONFIG_VERSION_VARIABLE
#define CONFIG_FAT_WRITE
+/* Fastboot and USB OTG */
+#define CONFIG_USB_FUNCTION_FASTBOOT
+#define CONFIG_CMD_FASTBOOT
+#define CONFIG_FASTBOOT_FLASH
+#define CONFIG_FASTBOOT_FLASH_MMC_DEV 0
+#define CONFIG_SYS_CACHELINE_SIZE 64
+#define CONFIG_FASTBOOT_BUF_SIZE (CONFIG_SYS_SDRAM_SIZE - SZ_1M)
+#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_SDRAM_BASE
+#define CONFIG_USB_GADGET
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_VBUS_DRAW 0
+#define CONFIG_USB_GADGET_S3C_UDC_OTG
+#define CONFIG_USB_GADGET_BCM_UDC_OTG_PHY
+#define CONFIG_USB_GADGET_DOWNLOAD
+#define CONFIG_USBID_ADDR 0x34052c46
+#define CONFIG_G_DNL_VENDOR_NUM 0x18d1 /* google */
+#define CONFIG_G_DNL_PRODUCT_NUM 0x0d02 /* nexus one */
+#define CONFIG_G_DNL_MANUFACTURER "Broadcom Corporation"
+
#endif /* __BCM28155_AP_H */
/* USB xHCI HOST */
#define CONFIG_CMD_USB
#define CONFIG_USB_HOST
+#define CONFIG_USB_XHCI_DWC3
#define CONFIG_USB_XHCI
#define CONFIG_USB_XHCI_OMAP
#define CONFIG_USB_STORAGE
#define CONFIG_G_DNL_PRODUCT_NUM CONFIG_TRDX_PID_COLIBRI_VF50
/* USB DFU */
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_CMD_DFU
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_NAND
#define CONFIG_DFU_MMC
#define CONFIG_SYS_DFU_DATA_BUF_SIZE (1024 * 1024)
/* USB Storage */
#define CONFIG_USB_STORAGE
-#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
#define CONFIG_CMD_USB_MASS_STORAGE
/* Enable SPI support */
#include "../board/freescale/common/ics307_clk.h"
#ifdef CONFIG_RAMBOOT_PBL
+#ifdef CONFIG_SECURE_BOOT
+#define CONFIG_RAMBOOT_TEXT_BASE CONFIG_SYS_TEXT_BASE
+#define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc
+#ifdef CONFIG_NAND
+#define CONFIG_RAMBOOT_NAND
+#endif
+#define CONFIG_BOOTSCRIPT_COPY_RAM
+#else
#define CONFIG_RAMBOOT_TEXT_BASE CONFIG_SYS_TEXT_BASE
#define CONFIG_RESET_VECTOR_ADDRESS 0xfffffffc
#define CONFIG_SYS_FSL_PBL_PBI board/freescale/corenet_ds/pbi.cfg
#define CONFIG_SYS_FSL_PBL_RCW board/freescale/corenet_ds/rcw_p5040ds.cfg
#endif
#endif
+#endif
#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE
/* Set 1M boot space */
* High Level Configuration Options (easy to change)
*/
#define CONFIG_ARMADA_XP /* SOC Family Name */
+#define CONFIG_ARMADA_38X
#define CONFIG_DB_88F6820_GP /* Board target name for DDR training */
#define CONFIG_SYS_L2_PL310
"fdt_high=0x10000000\0" \
"initrd_high=0x10000000\0"
+/* SPL */
+/*
+ * Select the boot device here
+ *
+ * Currently supported are:
+ * SPL_BOOT_SPI_NOR_FLASH - Booting via SPI NOR flash
+ * SPL_BOOT_SDIO_MMC_CARD - Booting via SDIO/MMC card (partition 1)
+ */
+#define SPL_BOOT_SPI_NOR_FLASH 1
+#define SPL_BOOT_SDIO_MMC_CARD 2
+#define CONFIG_SPL_BOOT_DEVICE SPL_BOOT_SPI_NOR_FLASH
+
+/* Defines for SPL */
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_SIZE (140 << 10)
+#define CONFIG_SPL_TEXT_BASE 0x40000030
+#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_SIZE - 0x0030)
+
+#define CONFIG_SPL_BSS_START_ADDR (0x40000000 + CONFIG_SPL_SIZE)
+#define CONFIG_SPL_BSS_MAX_SIZE (16 << 10)
+
+#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \
+ CONFIG_SPL_BSS_MAX_SIZE)
+#define CONFIG_SYS_SPL_MALLOC_SIZE (16 << 10)
+
+#define CONFIG_SPL_STACK (0x40000000 + ((192 - 16) << 10))
+#define CONFIG_SPL_BOOTROM_SAVE (CONFIG_SPL_STACK + 4)
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_I2C_SUPPORT
+
+#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SPI_NOR_FLASH
+/* SPL related SPI defines */
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SPL_SPI_LOAD
+#define CONFIG_SPL_SPI_BUS 0
+#define CONFIG_SPL_SPI_CS 0
+#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000
+#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_SPI_U_BOOT_OFFS
+#endif
+
+#if CONFIG_SPL_BOOT_DEVICE == SPL_BOOT_SDIO_MMC_CARD
+/* SPL related MMC defines */
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SPL_LIBDISK_SUPPORT
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 1
+#define CONFIG_SYS_MMC_U_BOOT_OFFS (160 << 10)
+#define CONFIG_SYS_U_BOOT_OFFS CONFIG_SYS_MMC_U_BOOT_OFFS
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR (CONFIG_SYS_U_BOOT_OFFS / 512)
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS ((512 << 10) / 512) /* 512KiB */
+#ifdef CONFIG_SPL_BUILD
+#define CONFIG_FIXED_SDHCI_ALIGNED_BUFFER 0x00180000 /* in SDRAM */
+#endif
+#endif
+
+/* Enable DDR support in SPL (DDR3 training from Marvell bin_hdr) */
+#define CONFIG_SYS_MVEBU_DDR_A38X
+#define CONFIG_DDR3
+
/*
* mv-common.h should be defined after CMD configs since it used them
* to enable certain macros
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_ENV
#define CONFIG_CMD_I2C
+#define CONFIG_CMD_IDE
#define CONFIG_CMD_PING
#define CONFIG_CMD_SF
#define CONFIG_CMD_SPI
#define CONFIG_SYS_CONSOLE_INFO_QUIET /* don't print console @ startup */
#define CONFIG_SYS_ALT_MEMTEST
+/* SATA support */
+#ifdef CONFIG_CMD_IDE
+#define __io
+#define CONFIG_IDE_PREINIT
+#define CONFIG_MVSATA_IDE
+
+/* Needs byte-swapping for ATA data register */
+#define CONFIG_IDE_SWAP_IO
+
+#define CONFIG_SYS_ATA_REG_OFFSET 0x0100 /* Offset for register access */
+#define CONFIG_SYS_ATA_DATA_OFFSET 0x0100 /* Offset for data I/O */
+#define CONFIG_SYS_ATA_ALT_OFFSET 0x0100
+
+/* Each 8-bit ATA register is aligned to a 4-bytes address */
+#define CONFIG_SYS_ATA_STRIDE 4
+
+/* CONFIG_CMD_IDE requires some #defines for ATA registers */
+#define CONFIG_SYS_IDE_MAXBUS 2
+#define CONFIG_SYS_IDE_MAXDEVICE CONFIG_SYS_IDE_MAXBUS
+
+/* ATA registers base is at SATA controller base */
+#define CONFIG_SYS_ATA_BASE_ADDR MVEBU_AXP_SATA_BASE
+#define CONFIG_SYS_ATA_IDE0_OFFSET 0x2000
+#define CONFIG_SYS_ATA_IDE1_OFFSET 0x4000
+
+#define CONFIG_DOS_PARTITION
+#endif /* CONFIG_CMD_IDE */
+
/*
* mv-common.h should be defined after CMD configs since it used them
* to enable certain macros
#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000
/* Enable DDR support in SPL (DDR3 training from Marvell bin_hdr) */
-#define CONFIG_SYS_MVEBU_DDR
+#define CONFIG_SYS_MVEBU_DDR_AXP
#define CONFIG_SPD_EEPROM 0x4e
#endif /* _CONFIG_DB_MV7846MP_GP_H */
DFU_ALT_INFO_RAM
/* Fastboot */
+#define CONFIG_USB_FUNCTION_FASTBOOT
#define CONFIG_CMD_FASTBOOT
#define CONFIG_ANDROID_BOOT_IMAGE
-#define CONFIG_USB_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
-#define CONFIG_USB_FASTBOOT_BUF_SIZE 0x2F000000
+#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
+#define CONFIG_FASTBOOT_BUF_SIZE 0x2F000000
#define CONFIG_FASTBOOT_FLASH
#define CONFIG_FASTBOOT_FLASH_MMC_DEV 1
#endif
#define CONFIG_CMD_USB
#define CONFIG_USB_HOST
#define CONFIG_USB_XHCI
+#define CONFIG_USB_XHCI_DWC3
#define CONFIG_USB_XHCI_OMAP
#define CONFIG_USB_STORAGE
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
#define CONFIG_USB_DWC3_GADGET
#define CONFIG_USB_GADGET
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_USB_GADGET_VBUS_DRAW 2
#define CONFIG_G_DNL_MANUFACTURER "Texas Instruments"
#define CONFIG_G_DNL_VENDOR_NUM 0x0451
#define CONFIG_USB_GADGET_DUALSPEED
/* USB Device Firmware Update support */
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_RAM
#define CONFIG_CMD_DFU
#define CONFIG_CMD_GPT
/* USB Composite download gadget - g_dnl */
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
/* TIZEN THOR downloader support */
#define CONFIG_CMD_THOR_DOWNLOAD
-#define CONFIG_THOR_FUNCTION
+#define CONFIG_USB_FUNCTION_THOR
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_MMC
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M
#define DFU_DEFAULT_POLL_TIMEOUT 300
#define CONFIG_USB_GADGET_VBUS_DRAW 2
#define CONFIG_CMD_USB_MASS_STORAGE
-#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
/* Common environment variables */
#define CONFIG_EXTRA_ENV_ITB \
/* USB */
#define CONFIG_CMD_USB
#define CONFIG_USB_STORAGE
+#define CONFIG_USB_XHCI_DWC3
#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 3
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
/* USB Mass Storage Gadget */
#define CONFIG_USB_GADGET
#define CONFIG_CMD_USB_MASS_STORAGE
-#define CONFIG_USB_GADGET_MASS_STORAGE
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_USB_GADGET_VBUS_DRAW 2
/* Netchip IDs */
#define CONFIG_K2E_EVM
/* U-Boot general configuration */
-#define CONFIG_SYS_PROMPT "K2E EVM # "
-
#define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \
"addr_mon=0x0c140000\0" \
"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \
"root=ubi0:rootfs rootflags=sync rw ubi.mtd=ubifs,2048\0" \
- "name_fdt=uImage-k2e-evm.dtb\0" \
- "name_mon=skern-k2e-evm.bin\0" \
+ "name_fdt=k2e-evm.dtb\0" \
+ "name_mon=skern-k2e.bin\0" \
"name_ubi=k2e-evm-ubifs.ubi\0" \
"name_uboot=u-boot-spi-k2e-evm.gph\0" \
"name_fs=arago-console-image-k2e-evm.cpio.gz\0"
-#include <configs/ks2_evm.h>
+#include <configs/ti_armv7_keystone2.h>
/* SPL SPI Loader Configuration */
#define CONFIG_SPL_TEXT_BASE 0x0c100000
#define CONFIG_K2HK_EVM
/* U-Boot general configuration */
-#define CONFIG_SYS_PROMPT "K2HK EVM # "
-
#define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \
"addr_mon=0x0c5f0000\0" \
"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \
"root=ubi0:rootfs rootflags=sync rw ubi.mtd=ubifs,2048\0" \
- "name_fdt=uImage-k2hk-evm.dtb\0" \
- "name_mon=skern-k2hk-evm.bin\0" \
+ "name_fdt=k2hk-evm.dtb\0" \
+ "name_mon=skern-k2hk.bin\0" \
"name_ubi=k2hk-evm-ubifs.ubi\0" \
"name_uboot=u-boot-spi-k2hk-evm.gph\0" \
"name_fs=arago-console-image-k2hk-evm.cpio.gz\0"
-#include <configs/ks2_evm.h>
+#include <configs/ti_armv7_keystone2.h>
/* SPL SPI Loader Configuration */
#define CONFIG_SPL_TEXT_BASE 0x0c200000
#define CONFIG_K2L_EVM
/* U-Boot general configuration */
-#define CONFIG_SYS_PROMPT "K2L EVM # "
-
#define CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \
"addr_mon=0x0c140000\0" \
"args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \
"root=ubi0:rootfs rootflags=sync rw ubi.mtd=ubifs,4096\0" \
- "name_fdt=uImage-k2l-evm.dtb\0" \
- "name_mon=skern-k2l-evm.bin\0" \
+ "name_fdt=k2l-evm.dtb\0" \
+ "name_mon=skern-k2l.bin\0" \
"name_ubi=k2l-evm-ubifs.ubi\0" \
"name_uboot=u-boot-spi-k2l-evm.gph\0" \
"name_fs=arago-console-image-k2l-evm.cpio.gz\0"
-#include <configs/ks2_evm.h>
+#include <configs/ti_armv7_keystone2.h>
/* SPL SPI Loader Configuration */
#define CONFIG_SPL_TEXT_BASE 0x0c100000
#define CONFIG_LS102XA
+#define CONFIG_ARMV7_PSCI
+
#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_DISPLAY_CPUINFO
/*
* USB
*/
-#define CONFIG_HAS_FSL_DR_USB
+/* EHCI Support - disbaled by default */
+/*#define CONFIG_HAS_FSL_DR_USB*/
#ifdef CONFIG_HAS_FSL_DR_USB
#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_FSL
+#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
+#endif
+
+/*XHCI Support - enabled by default*/
+#define CONFIG_HAS_FSL_XHCI_USB
-#ifdef CONFIG_USB_EHCI
+#ifdef CONFIG_HAS_FSL_XHCI_USB
+#define CONFIG_USB_XHCI_FSL
+#define CONFIG_USB_XHCI_DWC3
+#define CONFIG_USB_XHCI
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
+#endif
+
+#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_XHCI_USB)
#define CONFIG_CMD_USB
#define CONFIG_USB_STORAGE
-#define CONFIG_USB_EHCI_FSL
-#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
#define CONFIG_CMD_EXT2
#endif
-#endif
/*
* Video
#define CONFIG_LS102XA
+#define CONFIG_ARMV7_PSCI
+
#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_SYS_INIT_RAM_ADDR OCRAM_BASE_ADDR
#define CONFIG_SYS_INIT_RAM_SIZE OCRAM_SIZE
+/*
+ * USB
+ */
+
+/*
+ * EHCI Support - disbaled by default as
+ * there is no signal coming out of soc on
+ * this board for this controller. However,
+ * the silicon still has this controller,
+ * and anyone can use this controller by
+ * taking signals out on their board.
+ */
+
+/*#define CONFIG_HAS_FSL_DR_USB*/
+
+#ifdef CONFIG_HAS_FSL_DR_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_FSL
+#define CONFIG_EHCI_HCD_INIT_AFTER_RESET
+#endif
+
+/* XHCI Support - enabled by default */
+#define CONFIG_HAS_FSL_XHCI_USB
+
+#ifdef CONFIG_HAS_FSL_XHCI_USB
+#define CONFIG_USB_XHCI_FSL
+#define CONFIG_USB_XHCI_DWC3
+#define CONFIG_USB_XHCI
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
+#endif
+
+#if defined(CONFIG_HAS_FSL_DR_USB) || defined(CONFIG_HAS_FSL_XHCI_USB)
+#define CONFIG_CMD_USB
+#define CONFIG_USB_STORAGE
+#define CONFIG_CMD_EXT2
+#endif
+
/*
* Generic Timer Definitions
*/
#define CONFIG_ARM_ERRATA_828024
#define CONFIG_ARM_ERRATA_826974
+#include <asm/arch-fsl-lsch3/ls2085a_stream_id.h>
#include <asm/arch-fsl-lsch3/config.h>
#if (defined(CONFIG_SYS_FSL_SRDS_1) || defined(CONFIG_SYS_FSL_SRDS_2))
#define CONFIG_SYS_HAS_SERDES
#define CONFIG_SYS_NAND_BASE_PHYS 0x30000000
/* Debug Server firmware */
-#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
+#define CONFIG_FSL_DEBUG_SERVER
/* 2 sec timeout */
#define CONFIG_SYS_DEBUG_SERVER_TIMEOUT (2 * 1000 * 1000)
/* MC firmware */
#define CONFIG_FSL_MC_ENET
-#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
/* TODO Actual DPL max length needs to be confirmed with the MC FW team */
#define CONFIG_SYS_LS_MC_DPC_MAX_LENGTH 0x20000
#define CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET 0x00F00000
#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH 0x20000
#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0x00F20000
+#define CONFIG_SYS_LS_MC_AIOP_IMG_MAX_LENGTH 0x200000
+#define CONFIG_SYS_LS_MC_DRAM_AIOP_IMG_OFFSET 0x07000000
-/* Carve out a DDR region which will not be used by u-boot/Linux */
+/*
+ * Carve out a DDR region which will not be used by u-boot/Linux
+ *
+ * It will be used by MC and Debug Server. The MC region must be
+ * 512MB aligned, so the min size to hide is 512MB.
+ */
#if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER)
+#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024)
+#define CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE (256UL * 1024 * 1024)
+#define CONFIG_SYS_MEM_TOP_HIDE_MIN (512UL * 1024 * 1024)
#define CONFIG_SYS_MEM_TOP_HIDE get_dram_size_to_hide()
#endif
#define CONFIG_PCIE2 /* PCIE controler 2 */
#define CONFIG_PCIE3 /* PCIE controler 3 */
#define CONFIG_PCIE4 /* PCIE controler 4 */
-#define FSL_PCIE_COMPAT "fsl,20851a-pcie"
+#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */
+#define FSL_PCIE_COMPAT "fsl,ls2085a-pcie"
#define CONFIG_SYS_PCI_64BIT
"initrd_high=0xffffffffffffffff\0" \
"kernel_start=0x581200000\0" \
"kernel_load=0xa0000000\0" \
- "kernel_size=0x1000000\0" \
+ "kernel_size=0x2800000\0" \
"console=ttyAMA0,38400n8\0"
#define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \
"earlycon=uart8250,mmio,0x21c0600,115200 " \
- "default_hugepagesz=2m hugepagesz=2m " \
- "hugepages=16"
+ "ramdisk_size=0x2000000 default_hugepagesz=2m" \
+ " hugepagesz=2m hugepages=16"
#define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \
"$kernel_size && bootm $kernel_load"
#define CONFIG_BOOTDELAY 10
#define CONFIG_SYS_SPL_MALLOC_START 0x80200000
#define CONFIG_SYS_MONITOR_LEN (512 * 1024)
+#define CONFIG_SYS_BOOTM_LEN (64 << 20) /* Increase max gunzip size */
+
+
#endif /* __LS2_COMMON_H */
#include "ls2085a_common.h"
-#define CONFIG_IDENT_STRING " LS2085A-QDS"
-#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-QDS"
-
#define CONFIG_DISPLAY_BOARDINFO
#ifndef __ASSEMBLY__
#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL
#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
+#define CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
+#define CONFIG_SYS_LS_MC_AIOP_IMG_ADDR 0x580900000ULL
/*
* I2C
/* I2C bus multiplexer */
#define I2C_MUX_CH_DEFAULT 0x8
+/* SPI */
+#ifdef CONFIG_FSL_DSPI
+#define CONFIG_CMD_SF
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SPI_FLASH_SST
+#define CONFIG_SPI_FLASH_EON
+#endif
+
/*
* MMC
*/
#define RTC
#define CONFIG_RTC_DS3231 1
#define CONFIG_SYS_I2C_RTC_ADDR 0x68
+#define CONFIG_CMD_DATE
/* EEPROM */
#define CONFIG_ID_EEPROM
"initrd_high=0xffffffffffffffff\0" \
"kernel_start=0x581100000\0" \
"kernel_load=0xa0000000\0" \
- "kernel_size=0x1000000\0"
+ "kernel_size=0x28000000\0"
#ifdef CONFIG_FSL_MC_ENET
#define CONFIG_FSL_MEMAC
#define __LS2_RDB_H
#include "ls2085a_common.h"
-#define CONFIG_IDENT_STRING " LS2085A-RDB"
-#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-RDB"
#undef CONFIG_CONS_INDEX
#define CONFIG_CONS_INDEX 2
#define CONFIG_MEM_INIT_VALUE 0xdeadbeef
#define SPD_EEPROM_ADDRESS1 0x51
#define SPD_EEPROM_ADDRESS2 0x52
-#define SPD_EEPROM_ADDRESS3 0x54
-#define SPD_EEPROM_ADDRESS4 0x53 /* Board error */
+#define SPD_EEPROM_ADDRESS3 0x53
+#define SPD_EEPROM_ADDRESS4 0x54
#define SPD_EEPROM_ADDRESS5 0x55
#define SPD_EEPROM_ADDRESS6 0x56 /* dummy address */
#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1
#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL
#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
+#define CONFIG_SYS_LS_MC_AIOP_IMG_IN_NOR
+#define CONFIG_SYS_LS_MC_AIOP_IMG_ADDR 0x580900000ULL
/*
* I2C
*/
-#define I2C_MUX_PCA_ADDR 0x77
-#define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/
+#define I2C_MUX_PCA_ADDR 0x75
+#define I2C_MUX_PCA_ADDR_PRI 0x75 /* Primary Mux*/
/* I2C bus multiplexer */
#define I2C_MUX_CH_DEFAULT 0x8
+/* SPI */
+#ifdef CONFIG_FSL_DSPI
+#define CONFIG_CMD_SF
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_STMICRO
+#define CONFIG_SPI_FLASH_BAR
+#endif
+
/*
* RTC configuration
*/
#define RTC
#define CONFIG_RTC_DS3231 1
#define CONFIG_SYS_I2C_RTC_ADDR 0x68
+#define CONFIG_CMD_DATE
/* EEPROM */
#define CONFIG_ID_EEPROM
#define CONFIG_DOS_PARTITION
#endif
+#define CONFIG_MISC_INIT_R
+
/* Initial environment variables */
#undef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \
"initrd_high=0xffffffffffffffff\0" \
"kernel_start=0x581100000\0" \
"kernel_load=0xa0000000\0" \
- "kernel_size=0x1000000\0"
+ "kernel_size=0x2800000\0"
+
+/* MAC/PHY configuration */
+#ifdef CONFIG_FSL_MC_ENET
+#define CONFIG_PHYLIB_10G
+#define CONFIG_PHY_CORTINA
+#define CONFIG_PHYLIB
+#define CONFIG_SYS_CORTINA_FW_IN_NOR
+#define CONFIG_CORTINA_FW_ADDR 0x581000000
+#define CONFIG_CORTINA_FW_LENGTH 0x40000
+
+#define CORTINA_PHY_ADDR1 0x10
+#define CORTINA_PHY_ADDR2 0x11
+#define CORTINA_PHY_ADDR3 0x12
+#define CORTINA_PHY_ADDR4 0x13
+#define AQ_PHY_ADDR1 0x00
+#define AQ_PHY_ADDR2 0x01
+#define AQ_PHY_ADDR3 0x02
+#define AQ_PHY_ADDR4 0x03
+
+#define CONFIG_MII
+#define CONFIG_ETHPRIME "DPNI1"
+#define CONFIG_PHY_GIGE
+#define CONFIG_PHY_AQUANTIA
+#endif
#endif /* __LS2_RDB_H */
#define CONFIG_SYS_SPI_U_BOOT_OFFS 0x20000
/* Enable DDR support in SPL (DDR3 training from Marvell bin_hdr) */
-#define CONFIG_SYS_MVEBU_DDR
+#define CONFIG_SYS_MVEBU_DDR_AXP
#define CONFIG_DDR_FIXED_SIZE (1 << 20) /* 1GiB */
#endif /* _CONFIG_DB_MV7846MP_GP_H */
#define CONFIG_FIT_SIGNATURE
#define CONFIG_RSA
-/* Avoid a warning in the Realtek Ethernet driver */
-#define CONFIG_SYS_CACHELINE_SIZE 16
-
#define CONFIG_ENV_SECT_SIZE 0x1000
#define CONFIG_ENV_OFFSET 0x007fe000
#define CONFIG_SYS_MEMTEST_START 0x00800000 /* 8M */
#define CONFIG_SYS_MEMTEST_END 0x00ffffff /*(_16M -1) */
#define CONFIG_SYS_RESET_ADDRESS 0xffff0000 /* Rst Vector Adr */
-#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
+#define CONFIG_SYS_MAXARGS 32 /* max number of command args */
/* ====> Include platform Common Definitions */
#include <asm/arch/config.h>
#define CONFIG_USB_GADGET
#define CONFIG_CMD_USB_MASS_STORAGE
-#define CONFIG_USB_GADGET_MASS_STORAGE
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_USB_GADGET_VBUS_DRAW 2
#define CONFIG_G_DNL_VENDOR_NUM 0x0525
#define CONFIG_USB_GADGET
#define CONFIG_CMD_USB_MASS_STORAGE
-#define CONFIG_USB_GADGET_MASS_STORAGE
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_USB_GADGET_VBUS_DRAW 2
/* Netchip IDs */
#define CONFIG_G_DNL_PRODUCT_NUM 0xa4a5
#define CONFIG_G_DNL_MANUFACTURER "Boundary"
+#define CONFIG_USB_FUNCTION_FASTBOOT
#define CONFIG_CMD_FASTBOOT
#define CONFIG_ANDROID_BOOT_IMAGE
-#define CONFIG_USB_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
-#define CONFIG_USB_FASTBOOT_BUF_SIZE 0x07000000
+#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
+#define CONFIG_FASTBOOT_BUF_SIZE 0x07000000
#endif /* __CONFIG_H */
/* USB */
#define CONFIG_MUSB_UDC
-#define CONFIG_MUSB_HDC
+#define CONFIG_MUSB_HCD
#define CONFIG_USB_OMAP3
#define CONFIG_TWL4030_USB
#define CONFIG_G_DNL_VENDOR_NUM 0x04E8
#define CONFIG_G_DNL_PRODUCT_NUM 0x6601
#define CONFIG_G_DNL_MANUFACTURER "Samsung"
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
/* DFU */
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_MMC
#define CONFIG_CMD_DFU
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M
/* THOR */
#define CONFIG_G_DNL_THOR_VENDOR_NUM CONFIG_G_DNL_VENDOR_NUM
#define CONFIG_G_DNL_THOR_PRODUCT_NUM 0x685D
-#define CONFIG_THOR_FUNCTION
+#define CONFIG_USB_FUNCTION_THOR
#define CONFIG_CMD_THOR_DOWNLOAD
/* UMS */
#define CONFIG_G_DNL_UMS_VENDOR_NUM 0x0525
#define CONFIG_G_DNL_UMS_PRODUCT_NUM 0xA4A5
-#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
#define CONFIG_CMD_USB_MASS_STORAGE
/* FIXME: MUST BE REMOVED AFTER TMU IS TURNED ON */
#define CONFIG_USB_ETHER_RNDIS
#define CONFIG_USB_GADGET
#define CONFIG_USB_GADGET_VBUS_DRAW 0
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_G_DNL_VENDOR_NUM 0x0451
#define CONFIG_G_DNL_PRODUCT_NUM 0xd022
#define CONFIG_G_DNL_MANUFACTURER "TI"
+#define CONFIG_USB_FUNCTION_FASTBOOT
#define CONFIG_CMD_FASTBOOT
#define CONFIG_ANDROID_BOOT_IMAGE
-#define CONFIG_USB_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
-#define CONFIG_USB_FASTBOOT_BUF_SIZE 0x07000000
+#define CONFIG_FASTBOOT_BUF_ADDR CONFIG_SYS_LOAD_ADDR
+#define CONFIG_FASTBOOT_BUF_SIZE 0x07000000
/* USB EHCI */
#define CONFIG_CMD_USB
"defaultdisplay=dvi\0" \
"mmcdev=0\0" \
"mmcroot=/dev/mmcblk0p2 rw\0" \
- "mmcrootfstype=ext3 rootwait\0" \
+ "mmcrootfstype=ext4 rootwait\0" \
"nandroot=ubi0:rootfs ubi.mtd=4\0" \
"nandrootfstype=ubifs\0" \
"mtdparts=" MTDPARTS_DEFAULT "\0" \
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _P2571_H
+#define _P2571_H
+
+#include <linux/sizes.h>
+
+/* enable PMIC */
+#define CONFIG_MAX77620_POWER
+
+#include "tegra210-common.h"
+
+/* High-level configuration options */
+#define V_PROMPT "Tegra210 (P2571) # "
+#define CONFIG_TEGRA_BOARD_STRING "NVIDIA P2571"
+
+/* Board-specific serial config */
+#define CONFIG_SERIAL_MULTI
+#define CONFIG_TEGRA_ENABLE_UARTA
+#define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTA_BASE
+
+/* I2C */
+#define CONFIG_SYS_I2C_TEGRA
+#define CONFIG_CMD_I2C
+
+/* SD/MMC */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_TEGRA_MMC
+#define CONFIG_CMD_MMC
+
+/* Environment in eMMC, at the end of 2nd "boot sector" */
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#define CONFIG_SYS_MMC_ENV_PART 2
+#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE)
+
+/* SPI */
+#define CONFIG_TEGRA114_SPI /* Compatible w/ Tegra114 SPI */
+#define CONFIG_TEGRA114_SPI_CTRLS 6
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
+#define CONFIG_SF_DEFAULT_SPEED 24000000
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_SF
+#define CONFIG_SPI_FLASH_SIZE (4 << 20)
+
+/* USB2.0 Host support */
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_TEGRA
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
+#define CONFIG_USB_STORAGE
+#define CONFIG_CMD_USB
+
+/* USB networking support */
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_ASIX
+
+/* General networking support */
+#define CONFIG_CMD_DHCP
+
+/*
+ * TODO(twarren@nvidia.com) - add tegra-common-usb-gadget.h back
+ * breaks 64-bit build in ci_udc.c
+ */
+#include "tegra-common-post.h"
+
+#define COUNTER_FREQUENCY 38400000
+
+#endif /* _P2571_H */
"optargs=\0" \
"mmcdev=0\0" \
"mmcroot=/dev/mmcblk0p2 rw\0" \
- "mmcrootfstype=ext3 rootwait\0" \
+ "mmcrootfstype=ext4 rootwait\0" \
"mmcargs=setenv bootargs console=${console} " \
"${optargs} " \
"root=${mmcroot} " \
#define CONFIG_CMD_GPT
/* USB Composite download gadget - g_dnl */
-#define CONFIG_USBDOWNLOAD_GADGET
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_GADGET_DOWNLOAD
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_MMC
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_32M
#define DFU_DEFAULT_POLL_TIMEOUT 300
/* TIZEN THOR downloader support */
#define CONFIG_CMD_THOR_DOWNLOAD
-#define CONFIG_THOR_FUNCTION
+#define CONFIG_USB_FUNCTION_THOR
/* USB Samsung's IDs */
#define CONFIG_G_DNL_VENDOR_NUM 0x04E8
#define CONFIG_USB_GADGET_DUALSPEED
#define CONFIG_USB_GADGET_VBUS_DRAW 2
#define CONFIG_CMD_USB_MASS_STORAGE
-#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
#define CONFIG_OF_LIBFDT
#define CONFIG_I2C
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
-#define CONFIG_SYS_OMAP24_I2C_SPEED OMAP_I2C_STANDARD
+#define CONFIG_SYS_OMAP24_I2C_SPEED 100000
#define CONFIG_SYS_OMAP24_I2C_SLAVE 1
#define CONFIG_SYS_I2C_OMAP24XX
#endif /* CONFIG_MUSB_GADGET */
#define CONFIG_USB_GADGET
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
/* USB DRACO ID as default */
#define CONFIG_USBD_HS
#define CONFIG_G_DNL_MANUFACTURER "Siemens AG"
/* USB Device Firmware Update support */
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_NAND
#define CONFIG_CMD_DFU
#define CONFIG_SYS_DFU_DATA_BUF_SIZE (1 << 20)
#define CONFIG_USB_GADGET_VBUS_DRAW 2
/* USB Composite download gadget - g_dnl */
-#define CONFIG_USBDOWNLOAD_GADGET
-#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_GADGET_DOWNLOAD
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_MMC
#define CONFIG_SYS_DFU_DATA_BUF_SIZE (32 * 1024 * 1024)
#define DFU_DEFAULT_POLL_TIMEOUT 300
#define CONFIG_OF_LIBFDT
#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MISC_INIT_R
#define CONFIG_SYS_FLASH_BASE 0x08000000
#define CONFIG_STM32_HSE_HZ 8000000
+#define CONFIG_SYS_CLK_FREQ 180000000 /* 180 MHz */
+
#define CONFIG_SYS_HZ_CLOCK 1000000 /* Timer is clocked at 1MHz */
#define CONFIG_CMDLINE_TAG
#define CONFIG_BAUDRATE 115200
#define CONFIG_BOOTARGS \
- "console=ttystm0,115200 earlyprintk consoleblank=0 ignore_loglevel"
+ "console=ttyS0,115200 earlyprintk consoleblank=0 ignore_loglevel"
#define CONFIG_BOOTCOMMAND \
"run bootcmd_romfs"
#define CONFIG_MUSB_PIO_ONLY
#endif
-#if defined CONFIG_USB_EHCI || defined CONFIG_USB_MUSB_SUNXI
-#define CONFIG_CMD_USB
-#define CONFIG_USB_STORAGE
-#endif
-
#ifdef CONFIG_USB_KEYBOARD
#define CONFIG_CONSOLE_MUX
#define CONFIG_PREBOOT
#define CONFIG_CI_UDC
#define CONFIG_USBD_HS
#define CONFIG_USB_GADGET
-#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
#define CONFIG_USB_GADGET_DUALSPEED
#define CONFIG_USB_GADGET_VBUS_DRAW 0
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_G_DNL_VENDOR_NUM 0x0525
#define CONFIG_G_DNL_PRODUCT_NUM 0xa4a5
#define CONFIG_G_DNL_MANUFACTURER "TBS"
#define CONFIG_CHROMEOS_EXTRA_ENV_SETTINGS
#endif
+#ifdef CONFIG_ARM64
+#define FDT_HIGH "ffffffffffffffff"
+#define INITRD_HIGH "ffffffffffffffff"
+#else
+#define FDT_HIGH "ffffffff"
+#define INITRD_HIGH "ffffffff"
+#endif
+
#define CONFIG_EXTRA_ENV_SETTINGS \
TEGRA_DEVICE_SETTINGS \
MEM_LAYOUT_ENV_SETTINGS \
- "fdt_high=ffffffff\0" \
- "initrd_high=ffffffff\0" \
+ "fdt_high=" FDT_HIGH "\0" \
+ "initrd_high=" INITRD_HIGH "\0" \
BOOTENV \
BOARD_EXTRA_ENV_SETTINGS \
CONFIG_CHROMEOS_EXTRA_ENV_SETTINGS
#define CONFIG_G_DNL_VENDOR_NUM 0x0955
#define CONFIG_G_DNL_PRODUCT_NUM 0x701A
#define CONFIG_G_DNL_MANUFACTURER "NVIDIA"
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_GADGET_DOWNLOAD
/* USB mass storage protocol */
-#define CONFIG_USB_GADGET_MASS_STORAGE
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
#define CONFIG_CMD_USB_MASS_STORAGE
/* DFU protocol */
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_SYS_DFU_DATA_BUF_SIZE (1 * 1024 * 1024)
#define CONFIG_CMD_DFU
#ifdef CONFIG_MMC
#include <asm/arch/tegra.h> /* get chip and board defs */
+/* Use the Tegra US timer on ARMv7, but the architected timer on ARMv8. */
+#ifndef CONFIG_ARM64
#define CONFIG_SYS_TIMER_RATE 1000000
#define CONFIG_SYS_TIMER_COUNTER NV_PA_TMRUS_BASE
+#endif
/*
* Display CPU and Board information
#define CONFIG_SYS_MALLOC_LEN (4 << 20) /* 4MB */
#endif
+#ifndef CONFIG_ARM64
#define CONFIG_SYS_NONCACHED_MEMORY (1 << 20) /* 1 MiB */
+#endif
/*
* NS16550 Configuration
#define CONFIG_SYS_MEMTEST_START (NV_PA_SDRC_CS0 + 0x600000)
#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 0x100000)
+#ifndef CONFIG_ARM64
#ifndef CONFIG_SPL_BUILD
#define CONFIG_USE_ARCH_MEMCPY
#endif
+#endif
/*-----------------------------------------------------------------------
* Physical Memory Map
/*-----------------------------------------------------------------------
* Physical Memory Map
*/
-#define CONFIG_SYS_TEXT_BASE 0x8010E000
+#define CONFIG_SYS_TEXT_BASE 0x80110000
/*
* Memory layout for where various images get loaded by boot scripts:
--- /dev/null
+/*
+ * (C) Copyright 2013-2015
+ * NVIDIA Corporation <www.nvidia.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _TEGRA210_COMMON_H_
+#define _TEGRA210_COMMON_H_
+
+#include "tegra-common.h"
+
+/* Cortex-A57 uses a cache line size of 64 bytes */
+#define CONFIG_SYS_CACHELINE_SIZE 64
+
+/*
+ * NS16550 Configuration
+ */
+#define V_NS16550_CLK 408000000 /* 408MHz (pllp_out0) */
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_STACKBASE 0x82800000 /* 40MB */
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define CONFIG_SYS_TEXT_BASE 0x8010E000
+
+/* Generic Interrupt Controller */
+#define CONFIG_GICV2
+
+/*
+ * Memory layout for where various images get loaded by boot scripts:
+ *
+ * scriptaddr can be pretty much anywhere that doesn't conflict with something
+ * else. Put it above BOOTMAPSZ to eliminate conflicts.
+ *
+ * pxefile_addr_r can be pretty much anywhere that doesn't conflict with
+ * something else. Put it above BOOTMAPSZ to eliminate conflicts.
+ *
+ * kernel_addr_r must be within the first 128M of RAM in order for the
+ * kernel's CONFIG_AUTO_ZRELADDR option to work. Since the kernel will
+ * decompress itself to 0x8000 after the start of RAM, kernel_addr_r
+ * should not overlap that area, or the kernel will have to copy itself
+ * somewhere else before decompression. Similarly, the address of any other
+ * data passed to the kernel shouldn't overlap the start of RAM. Pushing
+ * this up to 16M allows for a sizable kernel to be decompressed below the
+ * compressed load address.
+ *
+ * fdt_addr_r simply shouldn't overlap anything else. Choosing 32M allows for
+ * the compressed kernel to be up to 16M too.
+ *
+ * ramdisk_addr_r simply shouldn't overlap anything else. Choosing 33M allows
+ * for the FDT/DTB to be up to 1M, which is hopefully plenty.
+ */
+#define CONFIG_LOADADDR 0x81000000
+#define MEM_LAYOUT_ENV_SETTINGS \
+ "scriptaddr=0x90000000\0" \
+ "pxefile_addr_r=0x90100000\0" \
+ "kernel_addr_r=" __stringify(CONFIG_LOADADDR) "\0" \
+ "fdt_addr_r=0x82000000\0" \
+ "ramdisk_addr_r=0x82100000\0"
+
+/* Defines for SPL */
+#define CONFIG_SPL_TEXT_BASE 0x80108000
+#define CONFIG_SYS_SPL_MALLOC_START 0x80090000
+#define CONFIG_SPL_STACK 0x800ffffc
+
+/* For USB EHCI controller */
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10
+#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
+
+#endif /* _TEGRA210_COMMON_H_ */
#endif
/* Now bring in the rest of the common code. */
-#include <configs/ti_armv7_common.h>
+#include <configs/ti_armv7_omap.h>
#endif /* __CONFIG_TI_AM335X_COMMON_H__ */
#define __CONFIG_TI_ARMV7_COMMON_H__
/* Common define for many platforms. */
-#define CONFIG_OMAP
-#define CONFIG_OMAP_COMMON
#define CONFIG_SYS_GENERIC_BOARD
/*
#define CONFIG_NR_DRAM_BANKS 1
#endif
#define CONFIG_SYS_SDRAM_BASE 0x80000000
+
+#ifndef CONFIG_SYS_INIT_SP_ADDR
#define CONFIG_SYS_INIT_SP_ADDR (NON_SECURE_SRAM_END - \
GENERATED_GBL_DATA_SIZE)
+#endif
/* Timer information. */
#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
#define CONFIG_I2C
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
-#define CONFIG_SYS_OMAP24_I2C_SPEED 100000
-#define CONFIG_SYS_OMAP24_I2C_SLAVE 1
-#define CONFIG_SYS_I2C_OMAP24XX
/* MMC/SD IP block */
#define CONFIG_MMC
#define CONFIG_GENERIC_MMC
-#define CONFIG_OMAP_HSMMC
#define CONFIG_CMD_MMC
/* McSPI IP block */
#define CONFIG_SPI
-#define CONFIG_OMAP3_SPI
#define CONFIG_CMD_SPI
/* GPIO block */
-#define CONFIG_OMAP_GPIO
#define CONFIG_CMD_GPIO
-/*
- * GPMC NAND block. We support 1 device and the physical address to
- * access CS0 at is 0x8000000.
- */
-#ifdef CONFIG_NAND
-#define CONFIG_NAND_OMAP_GPMC
-#ifndef CONFIG_SYS_NAND_BASE
-#define CONFIG_SYS_NAND_BASE 0x8000000
-#endif
-#define CONFIG_SYS_MAX_NAND_DEVICE 1
-#define CONFIG_CMD_NAND
-#endif
-
/*
* The following are general good-enough settings for U-Boot. We set a
* large malloc pool as we generally have a lot of DDR, and we opt for
* mtdparts, both for ease of use in U-Boot and for passing information
* on to the Linux kernel.
*/
-#if defined(CONFIG_SPI_BOOT) || defined(CONFIG_NOR) || defined(CONFIG_NAND)
+#if defined(CONFIG_SPI_BOOT) || defined(CONFIG_NOR) || defined(CONFIG_NAND) || defined(CONFIG_NAND_DAVINCI)
#define CONFIG_MTD_DEVICE /* Required for mtdparts */
#define CONFIG_CMD_MTDPARTS
#endif
#define CONFIG_SPL_EXT_SUPPORT
#endif
-#ifdef CONFIG_SPL_BUILD
-#define CONFIG_SYS_THUMB_BUILD /* Thumbs mode to save space in SPL */
-#endif
+#define CONFIG_SYS_THUMB_BUILD
/* General parts of the framework, required. */
#define CONFIG_SPL_I2C_SUPPORT
#define CONFIG_SPL_LIBCOMMON_SUPPORT
#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_POWER_SUPPORT
#define CONFIG_SPL_GPIO_SUPPORT
#define CONFIG_SPL_BOARD_INIT
/* U-Boot Build Configuration */
#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is a 2nd stage loader */
-#define CONFIG_SYS_NO_FLASH /* that is, no *NOR* flash */
-#define CONFIG_SYS_CONSOLE_INFO_QUIET
#define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_SYS_THUMB_BUILD
/* SoC Configuration */
#define CONFIG_ARCH_CPU_INIT
/* Memory Configuration */
#define CONFIG_NR_DRAM_BANKS 2
-#define CONFIG_SYS_SDRAM_BASE 0x80000000
#define CONFIG_SYS_LPAE_SDRAM_BASE 0x800000000
#define CONFIG_MAX_RAM_BANK_SIZE (2 << 30) /* 2GB */
#define CONFIG_STACKSIZE (512 << 10) /* 512 KiB */
-#define CONFIG_SYS_MALLOC_LEN (4 << 20) /* 4 MiB */
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE - \
GENERATED_GBL_DATA_SIZE)
#define CONFIG_SPL_STACK (CONFIG_SYS_SPL_MALLOC_START + \
CONFIG_SYS_SPL_MALLOC_SIZE + \
CONFIG_SPL_STACK_SIZE - 4)
-#define CONFIG_SPL_LIBCOMMON_SUPPORT
-#define CONFIG_SPL_LIBGENERIC_SUPPORT
-#define CONFIG_SPL_SERIAL_SUPPORT
#define CONFIG_SPL_SPI_FLASH_SUPPORT
#define CONFIG_SPL_SPI_SUPPORT
-#define CONFIG_SPL_BOARD_INIT
#define CONFIG_SPL_SPI_LOAD
#define CONFIG_SYS_SPI_U_BOOT_OFFS CONFIG_SPL_PAD_TO
-#define CONFIG_SPL_FRAMEWORK
/* UART Configuration */
#define CONFIG_SYS_NS16550
#define CONFIG_SYS_NS16550_COM2 KS2_UART1_BASE
#define CONFIG_SYS_NS16550_CLK clk_get_rate(KS2_CLK1_6)
#define CONFIG_CONS_INDEX 1
-#define CONFIG_BAUDRATE 115200
/* SPI Configuration */
-#define CONFIG_SPI
#define CONFIG_SPI_FLASH_STMICRO
#define CONFIG_DAVINCI_SPI
-#define CONFIG_CMD_SPI
#define CONFIG_SYS_SPI_CLK clk_get_rate(KS2_CLK1_6)
#define CONFIG_SF_DEFAULT_SPEED 30000000
#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
#define CONFIG_AEMIF_CNTRL_BASE KS2_AEMIF_CNTRL_BASE
/* I2C Configuration */
-#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_DAVINCI
#define CONFIG_SYS_DAVINCI_I2C_SPEED 100000
#define CONFIG_SYS_DAVINCI_I2C_SLAVE 0x10 /* SMBus host address */
#define CONFIG_ENV_IS_IN_NAND
#define CONFIG_ENV_OFFSET 0x100000
#define CONFIG_MTD_PARTITIONS
-#define CONFIG_MTD_DEVICE
#define CONFIG_RBTREE
#define CONFIG_LZO
#define MTDIDS_DEFAULT "nand0=davinci_nand.0"
/* USB Configuration */
#define CONFIG_USB_XHCI
+#define CONFIG_USB_XHCI_DWC3
#define CONFIG_USB_XHCI_KEYSTONE
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
-#define CONFIG_USB_STORAGE
-#define CONFIG_DOS_PARTITION
#define CONFIG_EFI_PARTITION
#define CONFIG_FS_FAT
#define CONFIG_SYS_CACHELINE_SIZE 64
#define CONFIG_USB_PHY_CFG_BASE KS2_USB_PHY_CFG_BASE
/* U-Boot command configuration */
-#define CONFIG_CMD_ASKENV
#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_I2C
#define CONFIG_CMD_PING
#define CONFIG_CMD_SAVES
-#define CONFIG_CMD_MTDPARTS
#define CONFIG_CMD_NAND
#define CONFIG_CMD_UBI
#define CONFIG_CMD_UBIFS
#define CONFIG_CMD_SF
#define CONFIG_CMD_EEPROM
#define CONFIG_CMD_USB
-#define CONFIG_CMD_FAT
-#define CONFIG_CMD_FS_GENERIC
/* U-Boot general configuration */
-#define CONFIG_SYS_GENERIC_BOARD
#define CONFIG_MISC_INIT_R
-#define CONFIG_SYS_CBSIZE 1024
-#define CONFIG_SYS_PBSIZE 2048
-#define CONFIG_SYS_MAXARGS 16
-#define CONFIG_SYS_HUSH_PARSER
-#define CONFIG_SYS_LONGHELP
#define CONFIG_CRC32_VERIFY
#define CONFIG_MX_CYCLIC
-#define CONFIG_CMDLINE_EDITING
-#define CONFIG_VERSION_VARIABLE
#define CONFIG_TIMESTAMP
/* EDMA3 */
#define CONFIG_TI_EDMA3
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTFILE "uImage"
#define CONFIG_EXTRA_ENV_SETTINGS \
+ DEFAULT_LINUX_BOOT_ENV \
CONFIG_EXTRA_ENV_KS2_BOARD_SETTINGS \
"boot=ubi\0" \
"tftp_root=/\0" \
"nfs_root=/export\0" \
"mem_lpae=1\0" \
"mem_reserve=512M\0" \
- "addr_fdt=0x87000000\0" \
- "addr_kern=0x88000000\0" \
- "addr_uboot=0x87000000\0" \
- "addr_fs=0x82000000\0" \
"addr_ubi=0x82000000\0" \
"addr_secdb_key=0xc000000\0" \
- "fdt_high=0xffffffff\0" \
- "name_kern=uImage-keystone-evm.bin\0" \
+ "name_kern=zImage\0" \
"run_mon=mon_install ${addr_mon}\0" \
- "run_kern=bootm ${addr_kern} - ${addr_fdt}\0" \
+ "run_kern=bootz ${loadaddr} - ${fdtaddr}\0" \
"init_net=run args_all args_net\0" \
"init_ubi=run args_all args_ubi; " \
"ubi part ubifs; ubifsmount ubi:boot;" \
"ubifsload ${addr_secdb_key} securedb.key.bin;\0" \
- "get_fdt_net=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0" \
- "get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0" \
- "get_kern_net=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0" \
- "get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0" \
+ "get_fdt_net=dhcp ${fdtaddr} ${tftp_root}/${name_fdt}\0" \
+ "get_fdt_ubi=ubifsload ${fdtaddr} ${name_fdt}\0" \
+ "get_kern_net=dhcp ${loadaddr} ${tftp_root}/${name_kern}\0" \
+ "get_kern_ubi=ubifsload ${loadaddr} ${name_kern}\0" \
"get_mon_net=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \
"get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0" \
"get_uboot_net=dhcp ${addr_uboot} ${tftp_root}/${name_uboot}\0" \
"root=/dev/nfs rw nfsroot=${serverip}:${nfs_root}," \
"${nfs_options} ip=dhcp\0" \
"nfs_options=v3,tcp,rsize=4096,wsize=4096\0" \
- "get_fdt_ramfs=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0" \
- "get_kern_ramfs=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0" \
+ "get_fdt_ramfs=dhcp ${fdtaddr} ${tftp_root}/${name_fdt}\0" \
+ "get_kern_ramfs=dhcp ${loadaddr} ${tftp_root}/${name_kern}\0" \
"get_mon_ramfs=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \
- "get_fs_ramfs=dhcp ${addr_fs} ${tftp_root}/${name_fs}\0" \
+ "get_fs_ramfs=dhcp ${rdaddr} ${tftp_root}/${name_fs}\0" \
"get_ubi_net=dhcp ${addr_ubi} ${tftp_root}/${name_ubi}\0" \
"burn_ubi=nand erase.part ubifs; " \
"nand write ${addr_ubi} ubifs ${filesize}\0" \
#define CONFIG_BOOTARGS \
/* Linux interfacing */
-#define CONFIG_CMDLINE_TAG
-#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_OF_LIBFDT 1
#define CONFIG_OF_BOARD_SETUP
-#define CONFIG_SYS_BARGSIZE 1024
-#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x08000000)
-#define CONFIG_LINUX_BOOT_PARAM_ADDR (CONFIG_SYS_SDRAM_BASE + 0x100)
-#define CONFIG_SUPPORT_RAW_INITRD
+/* Now for the remaining common defines */
+#include <configs/ti_armv7_common.h>
+
+/* We wont be loading up OS from SPL for now.. */
+#undef CONFIG_SPL_OS_BOOT
+
+/* We do not have MMC support.. yet.. */
+#undef CONFIG_SPL_LIBDISK_SUPPORT
+#undef CONFIG_SPL_MMC_SUPPORT
+#undef CONFIG_SPL_FAT_SUPPORT
+#undef CONFIG_SPL_EXT_SUPPORT
+#undef CONFIG_MMC
+#undef CONFIG_GENERIC_MMC
+#undef CONFIG_CMD_MMC
+
+/* And no support for GPIO, yet.. */
+#undef CONFIG_SPL_GPIO_SUPPORT
+#undef CONFIG_CMD_GPIO
/* we may include files below only after all above definitions */
#include <asm/arch/hardware.h>
--- /dev/null
+/*
+ * ti_armv7_omap.h
+ *
+ * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * The various ARMv7 SoCs from TI all share a number of IP blocks when
+ * implementing a given feature. This is meant to isolate the features
+ * that are based on OMAP architecture.
+ */
+#ifndef __CONFIG_TI_ARMV7_OMAP_H__
+#define __CONFIG_TI_ARMV7_OMAP_H__
+
+/* Common defines for all OMAP architecture based SoCs */
+#define CONFIG_OMAP
+#define CONFIG_OMAP_COMMON
+
+/* I2C IP block */
+#define CONFIG_SYS_OMAP24_I2C_SPEED 100000
+#define CONFIG_SYS_OMAP24_I2C_SLAVE 1
+#define CONFIG_SYS_I2C_OMAP24XX
+
+/* MMC/SD IP block */
+#define CONFIG_OMAP_HSMMC
+
+/* SPI IP Block */
+#define CONFIG_OMAP3_SPI
+
+/* GPIO block */
+#define CONFIG_OMAP_GPIO
+
+/*
+ * GPMC NAND block. We support 1 device and the physical address to
+ * access CS0 at is 0x8000000.
+ */
+#ifdef CONFIG_NAND
+#define CONFIG_NAND_OMAP_GPMC
+#ifndef CONFIG_SYS_NAND_BASE
+#define CONFIG_SYS_NAND_BASE 0x8000000
+#endif
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_CMD_NAND
+#endif
+
+/* Now for the remaining common defines */
+#include <configs/ti_armv7_common.h>
+
+#endif /* __CONFIG_TI_ARMV7_OMAP_H__ */
#endif
/* Now bring in the rest of the common code. */
-#include <configs/ti_armv7_common.h>
+#include <configs/ti_armv7_omap.h>
#endif /* __CONFIG_TI_OMAP3_COMMON_H__ */
#define CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
#endif
-#include <configs/ti_armv7_common.h>
+#include <configs/ti_armv7_omap.h>
/*
* Hardware drivers
/* No need for i2c in SPL mode as we will use SRI2C for PMIC access on OMAP4 */
#undef CONFIG_SYS_I2C
#undef CONFIG_SYS_I2C_OMAP24XX
+#undef CONFIG_SPL_I2C_SUPPORT
#endif
#endif /* __CONFIG_TI_OMAP4_COMMON_H */
#define CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
#endif
-#ifndef CONFIG_SPL_BUILD
#define CONFIG_PALMAS_POWER
-#endif
#include <asm/arch/cpu.h>
#include <asm/arch/omap.h>
-#include <configs/ti_armv7_common.h>
+#include <configs/ti_armv7_omap.h>
/*
* Hardware drivers
"if test ${dofastboot} -eq 1; then " \
"echo Boot fastboot requested, resetting dofastboot ...;" \
"setenv dofastboot 0; saveenv;" \
- "echo Booting into fastboot ...; fastboot;" \
+ "echo Booting into fastboot ...; fastboot 0;" \
"fi;" \
"run findfdt; " \
"run mmcboot;" \
#ifndef __CONFIG_UNIPHIER_COMMON_H__
#define __CONFIG_UNIPHIER_COMMON_H__
-#if defined(CONFIG_MACH_PH1_PRO4)
+#if defined(CONFIG_MACH_PH1_SLD3)
#define CONFIG_DDR_NUM_CH0 2
-#define CONFIG_DDR_NUM_CH1 2
+#define CONFIG_DDR_NUM_CH1 1
+#define CONFIG_DDR_NUM_CH2 1
/* Physical start address of SDRAM */
#define CONFIG_SDRAM0_BASE 0x80000000
#define CONFIG_SDRAM0_SIZE 0x20000000
-#define CONFIG_SDRAM1_BASE 0xa0000000
+#define CONFIG_SDRAM1_BASE 0xc0000000
#define CONFIG_SDRAM1_SIZE 0x20000000
+#define CONFIG_SDRAM2_BASE 0xc0000000
+#define CONFIG_SDRAM2_SIZE 0x10000000
#endif
#if defined(CONFIG_MACH_PH1_LD4)
#define CONFIG_SDRAM1_SIZE 0x10000000
#endif
+#if defined(CONFIG_MACH_PH1_PRO4)
+#define CONFIG_DDR_NUM_CH0 2
+#define CONFIG_DDR_NUM_CH1 2
+
+/* Physical start address of SDRAM */
+#define CONFIG_SDRAM0_BASE 0x80000000
+#define CONFIG_SDRAM0_SIZE 0x20000000
+#define CONFIG_SDRAM1_BASE 0xa0000000
+#define CONFIG_SDRAM1_SIZE 0x20000000
+#endif
+
#if defined(CONFIG_MACH_PH1_SLD8)
#define CONFIG_DDR_NUM_CH0 1
#define CONFIG_DDR_NUM_CH1 1
#define CONFIG_NAND_DENALI_ECC_SIZE 1024
+#ifdef CONFIG_MACH_PH1_SLD3
+#define CONFIG_SYS_NAND_REGS_BASE 0xf8100000
+#define CONFIG_SYS_NAND_DATA_BASE 0xf8000000
+#else
#define CONFIG_SYS_NAND_REGS_BASE 0x68100000
#define CONFIG_SYS_NAND_DATA_BASE 0x68000000
+#endif
#define CONFIG_SYS_NAND_BASE (CONFIG_SYS_NAND_DATA_BASE + 0x10)
#define CONFIG_LOADADDR 0x84000000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
-#define CONFIG_BOOTFILE "fit.itb"
#define CONFIG_CMDLINE_EDITING /* add command line history */
"ip=$ipaddr:$serverip:$gatewayip:$netmask:$hostname:$netdev:off;" \
"tftpboot; bootm;"
-#define CONFIG_BOOTARGS " user_debug=0x1f init=/sbin/init"
-
-#define CONFIG_EXTRA_ENV_SETTINGS \
- "netdev=eth0\0" \
- "image_offset=0x00080000\0" \
- "image_size=0x00f00000\0" \
- "verify=n\0" \
- "nandupdate=nand erase 0 0x100000 &&" \
- "tftpboot u-boot-spl.bin &&" \
- "nand write $loadaddr 0 0x10000 &&" \
- "tftpboot u-boot-dtb.img &&" \
- "nand write $loadaddr 0x10000 0xf0000\0" \
- "norboot=run add_default_bootargs &&" \
- "bootm $image_offset\0" \
- "nandboot=run add_default_bootargs &&" \
- "nand read $loadaddr $image_offset $image_size &&" \
- "bootm\0" \
- "add_default_bootargs=setenv bootargs $bootargs" \
- " console=ttyS0,$baudrate\0" \
+#define CONFIG_BOOTARGS " earlyprintk loglevel=8"
+
+#ifdef CONFIG_FIT
+#define CONFIG_BOOTFILE "fitImage"
+#define LINUXBOOT_ENV_SETTINGS \
+ "fit_addr=0x00100000\0" \
+ "fit_addr_r=0x84100000\0" \
+ "fit_size=0x00f00000\0" \
+ "norboot=run add_default_bootargs &&" \
+ "bootm $fit_addr\0" \
+ "nandboot=run add_default_bootargs &&" \
+ "nand read $fit_addr_r $fit_addr $fit_size &&" \
+ "bootm $fit_addr_r\0" \
+ "tftpboot=run add_default_bootargs &&" \
+ "tftpboot $fit_addr_r $bootfile &&" \
+ "bootm $fit_addr_r\0"
+#else
+#define CONFIG_BOOTFILE "uImage"
+#define LINUXBOOT_ENV_SETTINGS \
+ "fdt_addr=0x00100000\0" \
+ "fdt_addr_r=0x84100000\0" \
+ "fdt_size=0x00008000\0" \
+ "fdt_file=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \
+ "kernel_addr=0x00200000\0" \
+ "kernel_addr_r=0x84200000\0" \
+ "kernel_size=0x00800000\0" \
+ "ramdisk_addr=0x00a00000\0" \
+ "ramdisk_addr_r=0x84a00000\0" \
+ "ramdisk_size=0x00600000\0" \
+ "ramdisk_file=rootfs.cpio.uboot\0" \
+ "norboot=run add_default_bootargs &&" \
+ "bootm $kernel_addr $ramdisk_addr $fdt_addr\0" \
+ "nandboot=run add_default_bootargs &&" \
+ "nand read $kernel_addr_r $kernel_addr $kernel_size &&" \
+ "nand read $ramdisk_addr_r $ramdisk_addr $ramdisk_size &&" \
+ "nand read $fdt_addr_r $fdt_addr $fdt_size &&" \
+ "bootm $kernel_addr_r $ramdisk_addr_r $fdt_addr_r\0" \
+ "tftpboot=run add_default_bootargs &&" \
+ "tftpboot $kernel_addr_r $bootfile &&" \
+ "tftpboot $ramdisk_addr_r $ramdisk_file &&" \
+ "tftpboot $fdt_addr_r $fdt_file &&" \
+ "bootm $kernel_addr_r $ramdisk_addr_r $fdt_addr_r\0"
+#endif
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "netdev=eth0\0" \
+ "verify=n\0" \
+ "nandupdate=nand erase 0 0x00100000 &&" \
+ "tftpboot u-boot-spl.bin &&" \
+ "nand write $loadaddr 0 0x00010000 &&" \
+ "tftpboot u-boot-dtb.img &&" \
+ "nand write $loadaddr 0x00010000 0x000f0000\0" \
+ "add_default_bootargs=setenv bootargs $bootargs" \
+ " console=ttyS0,$baudrate\0" \
+ LINUXBOOT_ENV_SETTINGS
/* Open Firmware flat tree */
#define CONFIG_OF_LIBFDT
#define CONFIG_SYS_SDRAM_SIZE (CONFIG_SDRAM0_SIZE)
#endif
-#if defined(CONFIG_MACH_PH1_LD4) || defined(CONFIG_MACH_PH1_SLD8)
+#if defined(CONFIG_MACH_PH1_SLD3) || defined(CONFIG_MACH_PH1_LD4) || \
+ defined(CONFIG_MACH_PH1_SLD8)
#define CONFIG_SPL_TEXT_BASE 0x00040000
#endif
#if defined(CONFIG_MACH_PH1_PRO4)
#define CONFIG_USB_GADGET
#define CONFIG_CMD_USB_MASS_STORAGE
-#define CONFIG_USB_GADGET_MASS_STORAGE
-#define CONFIG_USBDOWNLOAD_GADGET
+#define CONFIG_USB_FUNCTION_MASS_STORAGE
+#define CONFIG_USB_GADGET_DOWNLOAD
#define CONFIG_USB_GADGET_VBUS_DRAW 2
#define CONFIG_G_DNL_VENDOR_NUM 0x0525
#define CONFIG_G_DNL_MANUFACTURER "FSL"
#define CONFIG_CMD_DFU
-#define CONFIG_DFU_FUNCTION
+#define CONFIG_USB_FUNCTION_DFU
#define CONFIG_DFU_MMC
#define CONFIG_SYS_DFU_DATA_BUF_SIZE SZ_16M
#define DFU_DEFAULT_POLL_TIMEOUT 300
#define CONFIG_IDENT_STRING " Xilinx ZynqMP"
-#define CONFIG_SYS_TEXT_BASE 0x8000000
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x7fff0)
/* Flat Device Tree Definitions */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 0x400000)
/* Serial setup */
-#define CONFIG_ZYNQ_SERIAL_UART0
-#define CONFIG_ZYNQ_SERIAL
+#if defined(CONFIG_ZYNQMP_DCC)
+# define CONFIG_ARM_DCC
+# define CONFIG_CPU_ARMV8
+#else
+# if defined(CONFIG_ZYNQ_SERIAL_UART0) || defined(CONFIG_ZYNQ_SERIAL_UART1)
+# define CONFIG_ZYNQ_SERIAL
+# endif
+#endif
#define CONFIG_CONS_INDEX 0
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_BAUDRATE_TABLE \
{ 4800, 9600, 19200, 38400, 57600, 115200 }
-#define CONFIG_ZYNQ_SDHCI0
-
/* Command line configuration */
#define CONFIG_CMD_ENV
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_ELF
#define CONFIG_MP
+#define CONFIG_CMD_MII
+
+/* BOOTP options */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_MAY_FAIL
+#define CONFIG_BOOTP_SERVERIP
+
/* SPI */
#ifdef CONFIG_ZYNQ_SPI
# define CONFIG_SPI_FLASH_SST
#define CONFIG_CMDLINE_EDITING
#define CONFIG_SYS_MAXARGS 64
-#define CONFIG_ZYNQ_I2C0
-#define CONFIG_SYS_I2C_ZYNQ
+/* Ethernet driver */
+#if defined(CONFIG_ZYNQ_GEM0) || defined(CONFIG_ZYNQ_GEM1) || \
+ defined(CONFIG_ZYNQ_GEM2) || defined(CONFIG_ZYNQ_GEM3)
+# define CONFIG_NET_MULTI
+# define CONFIG_ZYNQ_GEM
+# define CONFIG_MII
+# define CONFIG_SYS_FAULT_ECHO_LINK_DOWN
+# define CONFIG_PHYLIB
+# define CONFIG_PHY_MARVELL
+#endif
/* I2C */
#if defined(CONFIG_SYS_I2C_ZYNQ)
# define CONFIG_SYS_I2C_ZYNQ_SLAVE 0
#endif
-#define CONFIG_ZYNQMP_EEPROM
-
/* EEPROM */
#ifdef CONFIG_ZYNQMP_EEPROM
# define CONFIG_CMD_EEPROM
# define CONFIG_SYS_EEPROM_SIZE (64 * 1024)
#endif
+#ifdef CONFIG_AHCI
+#define CONFIG_LIBATA
+#define CONFIG_SCSI_AHCI
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1
+#define CONFIG_SYS_SCSI_MAX_LUN 1
+#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
+ CONFIG_SYS_SCSI_MAX_LUN)
+#define CONFIG_CMD_SCSI
+#endif
+
#define CONFIG_FIT
#define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */
--- /dev/null
+/*
+ * Configuration for Xilinx ZynqMP emulation
+ * platforms. See zynqmp-common.h for ZynqMP
+ * common configs
+ *
+ * (C) Copyright 2014 - 2015 Xilinx, Inc.
+ * Michal Simek <michal.simek@xilinx.com>
+ * Siva Durga Prasad Paladugu <sivadur@xilinx.com>
+ *
+ * Based on Configuration for Versatile Express
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_ZYNQMP_EP_H
+#define __CONFIG_ZYNQMP_EP_H
+
+#define CONFIG_ZYNQ_SERIAL_UART0
+#define CONFIG_ZYNQ_SDHCI0
+#define CONFIG_ZYNQ_I2C0
+#define CONFIG_SYS_I2C_ZYNQ
+#define CONFIG_ZYNQ_EEPROM
+#define CONFIG_AHCI
+
+#include <configs/xilinx_zynqmp.h>
+
+#endif /* __CONFIG_ZYNQMP_EP_H */
# define CONFIG_CI_UDC /* ChipIdea CI13xxx UDC */
# define CONFIG_USB_GADGET
# define CONFIG_USB_GADGET_DUALSPEED
-# define CONFIG_USBDOWNLOAD_GADGET
+# define CONFIG_USB_GADGET_DOWNLOAD
# define CONFIG_SYS_DFU_DATA_BUF_SIZE 0x600000
# define DFU_DEFAULT_POLL_TIMEOUT 300
-# define CONFIG_DFU_FUNCTION
+# define CONFIG_USB_FUNCTION_DFU
# define CONFIG_DFU_RAM
# define CONFIG_USB_GADGET_VBUS_DRAW 2
# define CONFIG_G_DNL_VENDOR_NUM 0x03FD
# define CONFIG_USB_CABLE_CHECK
# define CONFIG_CMD_DFU
# define CONFIG_CMD_THOR_DOWNLOAD
-# define CONFIG_THOR_FUNCTION
+# define CONFIG_USB_FUNCTION_THOR
# define DFU_ALT_INFO_RAM \
"dfu_ram_info=" \
"set dfu_alt_info " \
# define CONFIG_ZYNQ_SDHCI0
# define CONFIG_ZYNQ_SPI
+#elif defined(CONFIG_ZC770_XM011)
+# define CONFIG_ZYNQ_SERIAL_UART1
+
#elif defined(CONFIG_ZC770_XM012)
# define CONFIG_ZYNQ_SERIAL_UART1
# undef CONFIG_SYS_NO_FLASH
#ifndef _DEBUG_UART_H
#define _DEBUG_UART_H
-#include <linux/linkage.h>
-
/*
* The debug UART is intended for use very early in U-Boot to debug problems
* when an ICE or other debug mechanism is not available.
*
* @ch: Character to output
*/
-asmlinkage void printch(int ch);
+void printch(int ch);
/**
* printascii() - Output an ASCII string to the debug UART
*
* @str: String to output
*/
-asmlinkage void printascii(const char *str);
+void printascii(const char *str);
/**
* printhex2() - Output a 2-digit hex value
*
* @value: Value to output
*/
-asmlinkage void printhex2(uint value);
+void printhex2(uint value);
/**
* printhex4() - Output a 4-digit hex value
*
* @value: Value to output
*/
-asmlinkage void printhex4(uint value);
+void printhex4(uint value);
/**
* printhex8() - Output a 8-digit hex value
*
* @value: Value to output
*/
-asmlinkage void printhex8(uint value);
+void printhex8(uint value);
/*
* Now define some functions - this should be inserted into the serial driver
*/
#define DEBUG_UART_FUNCS \
- asmlinkage void printch(int ch) \
+ void printch(int ch) \
{ \
_debug_uart_putc(ch); \
} \
\
- asmlinkage void printascii(const char *str) \
+ void printascii(const char *str) \
{ \
while (*str) \
_debug_uart_putc(*str++); \
printhex1(value >> (4 * digits)); \
} \
\
- asmlinkage void printhex2(uint value) \
+ void printhex2(uint value) \
{ \
printhex(value, 2); \
} \
\
- asmlinkage void printhex4(uint value) \
+ void printhex4(uint value) \
{ \
printhex(value, 4); \
} \
\
- asmlinkage void printhex8(uint value) \
+ void printhex8(uint value) \
{ \
printhex(value, 8); \
}
static inline int device_unbind(struct udevice *dev) { return 0; }
#endif
+/**
+ * device_remove_children() - Stop all device's children
+ * @dev: The device whose children are to be removed
+ * @return 0 on success, -ve on error
+ */
+#ifdef CONFIG_DM_DEVICE_REMOVE
+int device_remove_children(struct udevice *dev);
+#else
+static inline int device_remove_children(struct udevice *dev) { return 0; }
+#endif
+
+/**
+ * device_unbind_children() - Unbind all device's children from the device
+ *
+ * On error, the function continues to unbind all children, and reports the
+ * first error.
+ *
+ * @dev: The device that is to be stripped of its children
+ * @return 0 on success, -ve on error
+ */
+#ifdef CONFIG_DM_DEVICE_REMOVE
+int device_unbind_children(struct udevice *dev);
+#else
+static inline int device_unbind_children(struct udevice *dev) { return 0; }
+#endif
+
#ifdef CONFIG_DM_DEVICE_REMOVE
void device_free(struct udevice *dev);
#else
* @devp: Returns pointer to device if found, otherwise this is set to NULL
* @return 0 if OK, -ve on error
*/
-int device_get_child_by_of_offset(struct udevice *parent, int seq,
+int device_get_child_by_of_offset(struct udevice *parent, int of_offset,
struct udevice **devp);
+/**
+ * device_get_global_by_of_offset() - Get a device based on FDT offset
+ *
+ * Locates a device by its device tree offset, searching globally throughout
+ * the all driver model devices.
+ *
+ * The device is probed to activate it ready for use.
+ *
+ * @of_offset: Device tree offset to find
+ * @devp: Returns pointer to device if found, otherwise this is set to NULL
+ * @return 0 if OK, -ve on error
+ */
+int device_get_global_by_of_offset(int of_offset, struct udevice **devp);
+
/**
* device_find_first_child() - Find the first child of a device
*
/**
* struct driver_info - Information required to instantiate a device
*
+ * NOTE: Avoid using this except in extreme circumstances, where device tree
+ * is not feasible (e.g. serial driver in SPL where <8KB of SRAM is
+ * available). U-Boot's driver model uses device tree for configuration.
+ *
* @name: Driver name
* @platdata: Driver-specific platform data
*/
const void *platdata;
};
+/**
+ * NOTE: Avoid using these except in extreme circumstances, where device tree
+ * is not feasible (e.g. serial driver in SPL where <8KB of SRAM is
+ * available). U-Boot's driver model uses device tree for configuration.
+ */
#define U_BOOT_DEVICE(__name) \
ll_entry_declare(struct driver_info, __name, driver_info)
UCLASS_SIMPLE_BUS, /* bus with child devices */
/* U-Boot uclasses start here - in alphabetical order */
+ UCLASS_CLK, /* Clock source, e.g. used by peripherals */
UCLASS_CPU, /* CPU, typically part of an SoC */
UCLASS_CROS_EC, /* Chrome OS EC */
UCLASS_DISPLAY_PORT, /* Display port video */
+ UCLASS_RAM, /* RAM controller */
UCLASS_ETH, /* Ethernet device */
UCLASS_GPIO, /* Bank of general-purpose I/O pins */
UCLASS_I2C, /* I2C bus */
UCLASS_I2C_EEPROM, /* I2C EEPROM device */
UCLASS_I2C_GENERIC, /* Generic I2C device */
+ UCLASS_LED, /* Light-emitting diode (LED) */
UCLASS_LPC, /* x86 'low pin count' interface */
UCLASS_MASS_STORAGE, /* Mass storage device */
+ UCLASS_MMC, /* SD / MMC card or chip */
UCLASS_MOD_EXP, /* RSA Mod Exp device */
UCLASS_PCH, /* x86 platform controller hub */
UCLASS_PCI, /* PCI bus */
UCLASS_PCI_GENERIC, /* Generic PCI bus device */
UCLASS_PMIC, /* PMIC I/O device */
UCLASS_REGULATOR, /* Regulator device */
+ UCLASS_RESET, /* Reset device */
UCLASS_RTC, /* Real time clock device */
UCLASS_SERIAL, /* Serial UART */
UCLASS_SPI, /* SPI bus */
UCLASS_SPI_FLASH, /* SPI flash */
UCLASS_SPI_GENERIC, /* Generic SPI flash target */
+ UCLASS_SYSCON, /* System configuration device */
UCLASS_THERMAL, /* Thermal sensor */
UCLASS_USB, /* USB bus */
UCLASS_USB_DEV_GENERIC, /* USB generic device */
*/
int list_count_items(struct list_head *head);
+/* Dump out a tree of all devices */
+void dm_dump_all(void);
+
+/* Dump out a list of uclasses and their devices */
+void dm_dump_uclass(void);
+
#endif
--- /dev/null
+/*
+ * This header provides Tegra210-specific constants for binding
+ * nvidia,tegra210-car.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_TEGRA210_CAR_H
+#define _DT_BINDINGS_CLOCK_TEGRA210_CAR_H
+
+/* 0 */
+/* 1 */
+/* 2 */
+#define TEGRA210_CLK_ISPB 3
+#define TEGRA210_CLK_RTC 4
+#define TEGRA210_CLK_TIMER 5
+#define TEGRA210_CLK_UARTA 6
+/* 7 (register bit affects uartb and vfir) */
+/* 8 */
+#define TEGRA210_CLK_SDMMC2 9
+/* 10 (register bit affects spdif_in and spdif_out) */
+#define TEGRA210_CLK_I2S1 11
+#define TEGRA210_CLK_I2C1 12
+/* 13 */
+#define TEGRA210_CLK_SDMMC1 14
+#define TEGRA210_CLK_SDMMC4 15
+/* 16 */
+#define TEGRA210_CLK_PWM 17
+#define TEGRA210_CLK_I2S2 18
+/* 20 (register bit affects vi and vi_sensor) */
+/* 21 */
+#define TEGRA210_CLK_USBD 22
+#define TEGRA210_CLK_ISP 23
+/* 26 */
+/* 25 */
+#define TEGRA210_CLK_DISP2 26
+#define TEGRA210_CLK_DISP1 27
+#define TEGRA210_CLK_HOST1X 28
+#define TEGRA210_CLK_VCP 29
+#define TEGRA210_CLK_I2S0 30
+/* 31 */
+
+#define TEGRA210_CLK_MC 32
+/* 33 */
+#define TEGRA210_CLK_APBDMA 34
+/* 35 */
+#define TEGRA210_CLK_KBC 36
+/* 37 */
+/* 38 */
+/* 39 (register bit affects fuse and fuse_burn) */
+#define TEGRA210_CLK_KFUSE 40
+#define TEGRA210_CLK_SBC1 41
+#define TEGRA210_CLK_NOR 42
+/* 43 */
+#define TEGRA210_CLK_SBC2 44
+/* 45 */
+#define TEGRA210_CLK_SBC3 46
+#define TEGRA210_CLK_I2C5 47
+#define TEGRA210_CLK_DSIA 48
+/* 49 */
+#define TEGRA210_CLK_MIPI 50
+#define TEGRA210_CLK_HDMI 51
+#define TEGRA210_CLK_CSI 52
+/* 53 */
+#define TEGRA210_CLK_I2C2 54
+#define TEGRA210_CLK_UARTC 55
+#define TEGRA210_CLK_MIPI_CAL 56
+#define TEGRA210_CLK_EMC 57
+#define TEGRA210_CLK_USB2 58
+#define TEGRA210_CLK_USB3 59
+/* 60 */
+#define TEGRA210_CLK_VDE 61
+#define TEGRA210_CLK_BSEA 62
+#define TEGRA210_CLK_BSEV 63
+
+/* 64 */
+#define TEGRA210_CLK_UARTD 65
+/* 66 */
+#define TEGRA210_CLK_I2C3 67
+#define TEGRA210_CLK_SBC4 68
+#define TEGRA210_CLK_SDMMC3 69
+#define TEGRA210_CLK_PCIE 70
+#define TEGRA210_CLK_OWR 71
+#define TEGRA210_CLK_AFI 72
+#define TEGRA210_CLK_CSITE 73
+/* 74 */
+/* 75 */
+#define TEGRA210_CLK_LA 76
+#define TEGRA210_CLK_TRACE 77
+#define TEGRA210_CLK_SOC_THERM 78
+#define TEGRA210_CLK_DTV 79
+/* 80 */
+#define TEGRA210_CLK_I2CSLOW 81
+#define TEGRA210_CLK_DSIB 82
+#define TEGRA210_CLK_TSEC 83
+/* 84 */
+/* 85 */
+/* 86 */
+/* 87 */
+/* 88 */
+#define TEGRA210_CLK_XUSB_HOST 89
+/* 90 */
+#define TEGRA210_CLK_MSENC 91
+#define TEGRA210_CLK_CSUS 92
+/* 93 */
+/* 94 */
+/* 95 (bit affects xusb_dev and xusb_dev_src) */
+
+/* 96 */
+/* 97 */
+/* 98 */
+#define TEGRA210_CLK_MSELECT 99
+#define TEGRA210_CLK_TSENSOR 100
+#define TEGRA210_CLK_I2S3 101
+#define TEGRA210_CLK_I2S4 102
+#define TEGRA210_CLK_I2C4 103
+#define TEGRA210_CLK_SBC5 104
+#define TEGRA210_CLK_SBC6 105
+#define TEGRA210_CLK_D_AUDIO 106
+#define TEGRA210_CLK_APBIF 107
+#define TEGRA210_CLK_DAM0 108
+#define TEGRA210_CLK_DAM1 109
+#define TEGRA210_CLK_DAM2 110
+#define TEGRA210_CLK_HDA2CODEC_2X 111
+/* 112 */
+#define TEGRA210_CLK_AUDIO0_2X 113
+#define TEGRA210_CLK_AUDIO1_2X 114
+#define TEGRA210_CLK_AUDIO2_2X 115
+#define TEGRA210_CLK_AUDIO3_2X 116
+#define TEGRA210_CLK_AUDIO4_2X 117
+#define TEGRA210_CLK_SPDIF_2X 118
+#define TEGRA210_CLK_ACTMON 119
+#define TEGRA210_CLK_EXTERN1 120
+#define TEGRA210_CLK_EXTERN2 121
+#define TEGRA210_CLK_EXTERN3 122
+#define TEGRA210_CLK_SATA_OOB 123
+#define TEGRA210_CLK_SATA 124
+#define TEGRA210_CLK_HDA 125
+/* 126 */
+#define TEGRA210_CLK_SE 127
+
+#define TEGRA210_CLK_HDA2HDMI 128
+#define TEGRA210_CLK_SATA_COLD 129
+/* 130 */
+/* 131 */
+/* 132 */
+/* 133 */
+/* 134 */
+/* 135 */
+/* 136 */
+/* 137 */
+/* 138 */
+/* 139 */
+/* 140 */
+/* 141 */
+/* 142 */
+/* 143 (bit affects xusb_falcon_src, xusb_fs_src, */
+/* xusb_host_src and xusb_ss_src) */
+#define TEGRA210_CLK_CILAB 144
+#define TEGRA210_CLK_CILCD 145
+#define TEGRA210_CLK_CILE 146
+#define TEGRA210_CLK_DSIALP 147
+#define TEGRA210_CLK_DSIBLP 148
+#define TEGRA210_CLK_ENTROPY 149
+#define TEGRA210_CLK_DDS 150
+/* 151 */
+#define TEGRA210_CLK_DP2 152
+#define TEGRA210_CLK_AMX 153
+#define TEGRA210_CLK_ADX 154
+/* 155 (bit affects dfll_ref and dfll_soc) */
+#define TEGRA210_CLK_XUSB_SS 156
+/* 157 */
+/* 158 */
+/* 159 */
+
+/* 160 */
+/* 161 */
+/* 162 */
+/* 163 */
+/* 164 */
+/* 165 */
+#define TEGRA210_CLK_I2C6 166
+/* 167 */
+/* 168 */
+/* 169 */
+/* 170 */
+#define TEGRA210_CLK_VIM2_CLK 171
+/* 172 */
+/* 173 */
+/* 174 */
+/* 175 */
+#define TEGRA210_CLK_HDMI_AUDIO 176
+#define TEGRA210_CLK_CLK72MHZ 177
+#define TEGRA210_CLK_VIC03 178
+/* 179 */
+#define TEGRA210_CLK_ADX1 180
+#define TEGRA210_CLK_DPAUX 181
+#define TEGRA210_CLK_SOR0 182
+/* 183 */
+#define TEGRA210_CLK_GPU 184
+#define TEGRA210_CLK_AMX1 185
+/* 186 */
+/* 187 */
+/* 188 */
+/* 189 */
+/* 190 */
+/* 191 */
+#define TEGRA210_CLK_UARTB 192
+#define TEGRA210_CLK_VFIR 193
+#define TEGRA210_CLK_SPDIF_IN 194
+#define TEGRA210_CLK_SPDIF_OUT 195
+#define TEGRA210_CLK_VI 196
+#define TEGRA210_CLK_VI_SENSOR 197
+#define TEGRA210_CLK_FUSE 198
+#define TEGRA210_CLK_FUSE_BURN 199
+#define TEGRA210_CLK_CLK_32K 200
+#define TEGRA210_CLK_CLK_M 201
+#define TEGRA210_CLK_CLK_M_DIV2 202
+#define TEGRA210_CLK_CLK_M_DIV4 203
+#define TEGRA210_CLK_PLL_REF 204
+#define TEGRA210_CLK_PLL_C 205
+#define TEGRA210_CLK_PLL_C_OUT1 206
+#define TEGRA210_CLK_PLL_C2 207
+#define TEGRA210_CLK_PLL_C3 208
+#define TEGRA210_CLK_PLL_M 209
+#define TEGRA210_CLK_PLL_M_OUT1 210
+#define TEGRA210_CLK_PLL_P 211
+#define TEGRA210_CLK_PLL_P_OUT1 212
+#define TEGRA210_CLK_PLL_P_OUT2 213
+#define TEGRA210_CLK_PLL_P_OUT3 214
+#define TEGRA210_CLK_PLL_P_OUT4 215
+#define TEGRA210_CLK_PLL_A 216
+#define TEGRA210_CLK_PLL_A_OUT0 217
+#define TEGRA210_CLK_PLL_D 218
+#define TEGRA210_CLK_PLL_D_OUT0 219
+#define TEGRA210_CLK_PLL_D2 220
+#define TEGRA210_CLK_PLL_D2_OUT0 221
+#define TEGRA210_CLK_PLL_U 222
+#define TEGRA210_CLK_PLL_U_480M 223
+
+#define TEGRA210_CLK_PLL_U_60M 224
+#define TEGRA210_CLK_PLL_U_48M 225
+#define TEGRA210_CLK_PLL_U_12M 226
+/* 227 */
+/* 228 */
+#define TEGRA210_CLK_PLL_RE_VCO 229
+#define TEGRA210_CLK_PLL_RE_OUT 230
+#define TEGRA210_CLK_PLL_E 231
+#define TEGRA210_CLK_SPDIF_IN_SYNC 232
+#define TEGRA210_CLK_I2S0_SYNC 233
+#define TEGRA210_CLK_I2S1_SYNC 234
+#define TEGRA210_CLK_I2S2_SYNC 235
+#define TEGRA210_CLK_I2S3_SYNC 236
+#define TEGRA210_CLK_I2S4_SYNC 237
+#define TEGRA210_CLK_VIMCLK_SYNC 238
+#define TEGRA210_CLK_AUDIO0 239
+#define TEGRA210_CLK_AUDIO1 240
+#define TEGRA210_CLK_AUDIO2 241
+#define TEGRA210_CLK_AUDIO3 242
+#define TEGRA210_CLK_AUDIO4 243
+#define TEGRA210_CLK_SPDIF 244
+#define TEGRA210_CLK_CLK_OUT_1 245
+#define TEGRA210_CLK_CLK_OUT_2 246
+#define TEGRA210_CLK_CLK_OUT_3 247
+#define TEGRA210_CLK_BLINK 248
+/* 249 */
+/* 250 */
+/* 251 */
+#define TEGRA210_CLK_XUSB_HOST_SRC 252
+#define TEGRA210_CLK_XUSB_FALCON_SRC 253
+#define TEGRA210_CLK_XUSB_FS_SRC 254
+#define TEGRA210_CLK_XUSB_SS_SRC 255
+
+#define TEGRA210_CLK_XUSB_DEV_SRC 256
+#define TEGRA210_CLK_XUSB_DEV 257
+#define TEGRA210_CLK_XUSB_HS_SRC 258
+#define TEGRA210_CLK_SCLK 259
+#define TEGRA210_CLK_HCLK 260
+#define TEGRA210_CLK_PCLK 261
+/* 262 */
+/* 263 */
+#define TEGRA210_CLK_DFLL_REF 264
+#define TEGRA210_CLK_DFLL_SOC 265
+#define TEGRA210_CLK_VI_SENSOR2 266
+#define TEGRA210_CLK_PLL_P_OUT5 267
+#define TEGRA210_CLK_CML0 268
+#define TEGRA210_CLK_CML1 269
+#define TEGRA210_CLK_PLL_C4 270
+#define TEGRA210_CLK_PLL_DP 271
+#define TEGRA210_CLK_PLL_E_MUX 272
+#define TEGRA210_CLK_PLLD_DSI 273
+/* 274 */
+/* 275 */
+/* 276 */
+/* 277 */
+/* 278 */
+/* 279 */
+/* 280 */
+/* 281 */
+/* 282 */
+/* 283 */
+/* 284 */
+/* 285 */
+/* 286 */
+/* 287 */
+
+/* 288 */
+/* 289 */
+/* 290 */
+/* 291 */
+/* 292 */
+/* 293 */
+/* 294 */
+/* 295 */
+/* 296 */
+/* 297 */
+/* 298 */
+/* 299 */
+#define TEGRA210_CLK_AUDIO0_MUX 300
+#define TEGRA210_CLK_AUDIO1_MUX 301
+#define TEGRA210_CLK_AUDIO2_MUX 302
+#define TEGRA210_CLK_AUDIO3_MUX 303
+#define TEGRA210_CLK_AUDIO4_MUX 304
+#define TEGRA210_CLK_SPDIF_MUX 305
+#define TEGRA210_CLK_CLK_OUT_1_MUX 306
+#define TEGRA210_CLK_CLK_OUT_2_MUX 307
+#define TEGRA210_CLK_CLK_OUT_3_MUX 308
+/* 309 */
+/* 310 */
+#define TEGRA210_CLK_SOR0_LVDS 311
+#define TEGRA210_CLK_XUSB_SS_DIV2 312
+
+#define TEGRA210_CLK_PLL_M_UD 313
+#define TEGRA210_CLK_PLL_C_UD 314
+
+#define TEGRA210_CLK_PLL_X 227
+#define TEGRA210_CLK_PLL_X_OUT0 228
+
+#define TEGRA210_CLK_CCLK_G 262
+#define TEGRA210_CLK_CCLK_LP 263
+
+#define TEGRA210_CLK_CLK_MAX 315
+
+#endif /* _DT_BINDINGS_CLOCK_TEGRA210_CAR_H */
/* quirks */
#define DWMCI_QUIRK_DISABLE_SMU (1 << 0)
+/**
+ * struct dwmci_host - Information about a designware MMC host
+ *
+ * @name: Device name
+ * @ioaddr: Base I/O address of controller
+ * @quirks: Quick flags - see DWMCI_QUIRK_...
+ * @caps: Capabilities - see MMC_MODE_...
+ * @bus_hz: Bus speed in Hz, if @get_mmc_clk() is NULL
+ * @div: Arbitrary clock divider value for use by controller
+ * @dev_index: Arbitrary device index for use by controller
+ * @dev_id: Arbitrary device ID for use by controller
+ * @buswidth: Bus width in bits (8 or 4)
+ * @fifoth_val: Value for FIFOTH register (or 0 to leave unset)
+ * @mmc: Pointer to generic MMC structure for this device
+ * @priv: Private pointer for use by controller
+ */
struct dwmci_host {
- char *name;
+ const char *name;
void *ioaddr;
unsigned int quirks;
unsigned int caps;
#define __EXPORTS_H__
#ifndef __ASSEMBLY__
+#ifdef CONFIG_PHY_AQUANTIA
+#include <miiphy.h>
+#include <phy.h>
+#endif
struct spi_slave;
int i2c_write (uchar, uint, int , uchar* , int);
int i2c_read (uchar, uint, int , uchar* , int);
#endif
+#ifdef CONFIG_PHY_AQUANTIA
+struct mii_dev *mdio_get_current_dev(void);
+struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
+ phy_interface_t interface);
+struct phy_device *mdio_phydev_for_ethname(const char *ethname);
+int miiphy_set_current_dev(const char *devname);
+#endif
void app_startup(char * const *);
};
-#define XF_VERSION 7
+#define XF_VERSION 8
#if defined(CONFIG_X86)
extern gd_t *global_data;
const char *prop, const void *val, int len, int create);
void do_fixup_by_compat_u32(void *fdt, const char *compat,
const char *prop, u32 val, int create);
+/**
+ * Setup the memory node in the DT. Creates one if none was existing before.
+ * Calls fdt_fixup_memory_banks() to populate a single reg pair covering the
+ * whole memory.
+ *
+ * @param blob FDT blob to update
+ * @param start Begin of DRAM mapping in physical memory
+ * @param size Size of the single memory bank
+ * @return 0 if ok, or -1 or -FDT_ERR_... on error
+ */
int fdt_fixup_memory(void *blob, u64 start, u64 size);
+
+/**
+ * Fill the DT memory node with multiple memory banks.
+ * Creates the node if none was existing before.
+ * If banks is 0, it will not touch the existing reg property. This allows
+ * boards to not mess with the existing DT setup, which may have been
+ * filled in properly before.
+ *
+ * @param blob FDT blob to update
+ * @param start Array of size <banks> to hold the start addresses.
+ * @param size Array of size <banks> to hold the size of each region.
+ * @param banks Number of memory banks to create. If 0, the reg
+ * property will be left untouched.
+ * @return 0 if ok, or -1 or -FDT_ERR_... on error
+ */
int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks);
+
void fdt_fixup_ethernet(void *fdt);
int fdt_find_and_setprop(void *fdt, const char *node, const char *prop,
const void *val, int len, int create);
COMPAT_NVIDIA_TEGRA124_SOR, /* Tegra 124 Serial Output Resource */
COMPAT_NVIDIA_TEGRA124_PMC, /* Tegra 124 power mgmt controller */
COMPAT_NVIDIA_TEGRA20_DC, /* Tegra 2 Display controller */
+ COMPAT_NVIDIA_TEGRA210_SDMMC, /* Tegra210 SDMMC controller */
COMPAT_NVIDIA_TEGRA124_SDMMC, /* Tegra124 SDMMC controller */
COMPAT_NVIDIA_TEGRA30_SDMMC, /* Tegra30 SDMMC controller */
COMPAT_NVIDIA_TEGRA20_SDMMC, /* Tegra20 SDMMC controller */
COMPAT_NVIDIA_TEGRA20_PCIE, /* Tegra 20 PCIe controller */
COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL,
/* Tegra124 XUSB pad controller */
+ COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,
+ /* Tegra210 XUSB pad controller */
COMPAT_SMSC_LAN9215, /* SMSC 10/100 Ethernet LAN9215 */
COMPAT_SAMSUNG_EXYNOS5_SROMC, /* Exynos5 SROMC */
COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */
#define _FSL_DPIO_H
/* DPIO Version */
-#define DPIO_VER_MAJOR 2
-#define DPIO_VER_MINOR 1
+#define DPIO_VER_MAJOR 3
+#define DPIO_VER_MINOR 0
/* Command IDs */
#define DPIO_CMDID_CLOSE 0x800
MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_portal_id);\
MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
MC_RSP_OP(cmd, 0, 56, 4, enum dpio_channel_mode, attr->channel_mode);\
- MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_paddr);\
- MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_paddr);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->qbman_portal_ce_offset);\
+ MC_RSP_OP(cmd, 2, 0, 64, uint64_t, attr->qbman_portal_ci_offset);\
MC_RSP_OP(cmd, 3, 0, 16, uint16_t, attr->version.major);\
MC_RSP_OP(cmd, 3, 16, 16, uint16_t, attr->version.minor);\
} while (0)
*/
struct fsl_mc_io;
+
/**
* dpio_open() - Open a control session for the specified object
* @mc_io: Pointer to MC portal's I/O object
int dpio_open(struct fsl_mc_io *mc_io, int dpio_id, uint16_t *token);
/**
- * dpio_open() - Open a control session for the specified object
+ * dpio_close() - Close the control session of the object
* @mc_io: Pointer to MC portal's I/O object
- * @dpio_id: DPIO unique ID
- * @token: Returned token; use in subsequent API calls
- *
- * This function can be used to open a control session for an
- * already created object; an object may have been declared in
- * the DPL or by calling the dpio_create() function.
- * This function returns a unique authentication token,
- * associated with the specific object ID and the specific MC
- * portal; this token must be used in all subsequent commands for
- * this specific object.
+ * @token: Token of DPIO object
*
* Return: '0' on Success; Error code otherwise.
*/
* struct dpio_attr - Structure representing DPIO attributes
* @id: DPIO object ID
* @version: DPIO version
- * @qbman_portal_ce_paddr: Physical address of the software portal
- * cache-enabled area
- * @qbman_portal_ci_paddr: Physical address of the software portal
- * cache-inhibited area
+ * @qbman_portal_ce_offset: offset of the software portal cache-enabled area
+ * @qbman_portal_ci_offset: offset of the software portal cache-inhibited area
* @qbman_portal_id: Software portal ID
* @channel_mode: Notification channel mode
* @num_priorities: Number of priorities for the notification channel (1-8);
uint16_t major;
uint16_t minor;
} version;
- uint64_t qbman_portal_ce_paddr;
- uint64_t qbman_portal_ci_paddr;
+ uint64_t qbman_portal_ce_offset;
+ uint64_t qbman_portal_ci_offset;
uint16_t qbman_portal_id;
enum dpio_channel_mode channel_mode;
uint8_t num_priorities;
/**
* Management Complex firmware version information
*/
-#define MC_VER_MAJOR 6
+#define MC_VER_MAJOR 7
#define MC_VER_MINOR 0
/**
#define _FSL_DPNI_H
/* DPNI Version */
-#define DPNI_VER_MAJOR 4
+#define DPNI_VER_MAJOR 5
#define DPNI_VER_MINOR 0
/* Command IDs */
MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->max_tcs); \
MC_RSP_OP(cmd, 0, 40, 8, uint8_t, attr->max_senders); \
MC_RSP_OP(cmd, 0, 48, 8, enum net_prot, attr->start_hdr); \
- MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->options); \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->options); \
MC_RSP_OP(cmd, 2, 0, 8, uint8_t, attr->max_unicast_filters); \
MC_RSP_OP(cmd, 2, 8, 8, uint8_t, attr->max_multicast_filters);\
MC_RSP_OP(cmd, 2, 16, 8, uint8_t, attr->max_vlan_filters); \
MC_RSP_OP(cmd, 4, 16, 16, uint16_t, \
attr->ipr_cfg.min_frag_size_ipv4); \
MC_RSP_OP(cmd, 4, 32, 16, uint16_t, \
- attr->ipr_cfg.min_frag_size_ipv6); \
+ attr->ipr_cfg.min_frag_size_ipv6);\
+ MC_RSP_OP(cmd, 4, 48, 8, uint8_t, attr->max_policers); \
+ MC_RSP_OP(cmd, 4, 56, 8, uint8_t, attr->max_congestion_ctrl); \
MC_RSP_OP(cmd, 5, 0, 16, uint16_t, \
attr->ipr_cfg.max_open_frames_ipv4); \
MC_RSP_OP(cmd, 5, 16, 16, uint16_t, \
/* cmd, param, offset, width, type, arg_name */
#define DPNI_CMD_SET_LINK_CFG(cmd, cfg) \
do { \
- MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->rate);\
+ MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->rate);\
MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options);\
} while (0)
#define DPNI_RSP_GET_LINK_STATE(cmd, state) \
do { \
MC_RSP_OP(cmd, 0, 32, 1, int, state->up);\
- MC_RSP_OP(cmd, 1, 0, 64, uint64_t, state->rate);\
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, state->rate);\
MC_RSP_OP(cmd, 2, 0, 64, uint64_t, state->options);\
} while (0)
MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx); \
MC_CMD_OP(cmd, 2, 16, 8, uint8_t, tc_id); \
MC_CMD_OP(cmd, 2, 32, 32, uint32_t, cfg->options); \
+ MC_CMD_OP(cmd, 3, 0, 4, enum dpni_flc_type, cfg->flc_cfg.flc_type); \
+ MC_CMD_OP(cmd, 3, 4, 4, enum dpni_stash_size, \
+ cfg->flc_cfg.frame_data_size);\
+ MC_CMD_OP(cmd, 3, 8, 4, enum dpni_stash_size, \
+ cfg->flc_cfg.flow_context_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, uint32_t, cfg->flc_cfg.options);\
+ MC_CMD_OP(cmd, 4, 0, 64, uint64_t, cfg->flc_cfg.flow_context);\
} while (0)
/* cmd, param, offset, width, type, arg_name */
MC_RSP_OP(cmd, 0, 40, 2, enum dpni_dest, attr->dest_cfg.dest_type); \
MC_RSP_OP(cmd, 1, 0, 64, uint64_t, attr->user_ctx); \
MC_RSP_OP(cmd, 2, 32, 32, uint32_t, attr->fqid); \
+ MC_RSP_OP(cmd, 3, 0, 4, enum dpni_flc_type, attr->flc_cfg.flc_type); \
+ MC_RSP_OP(cmd, 3, 4, 4, enum dpni_stash_size, \
+ attr->flc_cfg.frame_data_size);\
+ MC_RSP_OP(cmd, 3, 8, 4, enum dpni_stash_size, \
+ attr->flc_cfg.flow_context_size);\
+ MC_RSP_OP(cmd, 3, 32, 32, uint32_t, attr->flc_cfg.options);\
+ MC_RSP_OP(cmd, 4, 0, 64, uint64_t, attr->flc_cfg.flow_context);\
} while (0)
enum net_prot {
NET_PROT_DUMMY_LAST
};
-/* Data Path Network Interface API
+/**
+ * Data Path Network Interface API
* Contains initialization APIs and runtime control APIs for DPNI
*/
* @max_qos_entries: if 'max_tcs > 1', declares the maximum entries in QoS table
* @max_qos_key_size: Maximum key size for the QoS look-up
* @max_dist_key_size: Maximum key size for the distribution look-up
+ * @max_policers: Maximum number of policers;
+ * @max_congestion_ctrl: Maximum number of congestion control groups (CGs);
* @ipr_cfg: IP reassembly configuration
*/
struct dpni_attr {
uint16_t minor;
} version;
enum net_prot start_hdr;
- uint64_t options;
+ uint32_t options;
uint8_t max_senders;
uint8_t max_tcs;
uint8_t max_dist_per_tc[DPNI_MAX_TC];
uint8_t max_qos_entries;
uint8_t max_qos_key_size;
uint8_t max_dist_key_size;
+ uint8_t max_policers;
+ uint8_t max_congestion_ctrl;
struct dpni_ipr_cfg ipr_cfg;
};
+
/**
* dpni_get_attributes() - Retrieve DPNI attributes.
* @mc_io: Pointer to MC portal's I/O objec
int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io,
uint16_t token,
struct dpni_buffer_layout *layout);
+
/**
* dpni_set_rx_buffer_layout() - Set Rx buffer layout configuration.
* @mc_io: Pointer to MC portal's I/O object
struct dpni_buffer_layout *layout);
/**
- * @brief Set Tx buffer layout configuration.
- *
- * @param[in] mc_io Pointer to MC portal's I/O object
- * @param[in] token Token of DPNI object
- * @param[in] layout Buffer layout configuration
+ * dpni_set_tx_buffer_layout() - Set Tx buffer layout configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Buffer layout configuration
*
- * @returns '0' on Success; Error code otherwise.
+ * Return: '0' on Success; Error code otherwise.
*
* @warning Allowed only when DPNI is disabled
*/
int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io,
uint16_t token,
const struct dpni_buffer_layout *layout);
+
/**
* dpni_get_tx_conf_buffer_layout() - Retrieve Tx confirmation buffer layout
* attributes.
int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
uint16_t token,
struct dpni_buffer_layout *layout);
+
/**
* dpni_set_tx_conf_buffer_layout() - Set Tx confirmation buffer layout
* configuration.
int dpni_set_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
uint16_t token,
const struct dpni_buffer_layout *layout);
+
/**
- * dpni_get_spid() - Get the AIOP storage profile ID associated with the DPNI
+ * dpni_get_qdid() - Get the Queuing Destination ID (QDID) that should be used
+ * for enqueue operations
* @mc_io: Pointer to MC portal's I/O object
* @token: Token of DPNI object
- * @spid: Returned aiop storage-profile ID
+ * @qdid: Returned virtual QDID value that should be used as an argument
+ * in all enqueue operations
*
* Return: '0' on Success; Error code otherwise.
- *
- * @warning Only relevant for DPNI that belongs to AIOP container.
*/
int dpni_get_qdid(struct fsl_mc_io *mc_io, uint16_t token, uint16_t *qdid);
uint16_t token,
enum dpni_counter counter,
uint64_t value);
+
+/* Enable auto-negotiation */
+#define DPNI_LINK_OPT_AUTONEG 0x0000000000000001ULL
+/* Enable half-duplex mode */
+#define DPNI_LINK_OPT_HALF_DUPLEX 0x0000000000000002ULL
+/* Enable pause frames */
+#define DPNI_LINK_OPT_PAUSE 0x0000000000000004ULL
+/* Enable a-symmetric pause frames */
+#define DPNI_LINK_OPT_ASYM_PAUSE 0x0000000000000008ULL
+
/**
* struct - Structure representing DPNI link configuration
* @rate: Rate
* @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
*/
struct dpni_link_cfg {
- uint64_t rate;
+ uint32_t rate;
uint64_t options;
};
*/
int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
uint16_t token,
- struct dpni_link_cfg *cfg);
+ const struct dpni_link_cfg *cfg);
/**
* struct dpni_link_state - Structure representing DPNI link state
* @up: Link state; '0' for down, '1' for up
*/
struct dpni_link_state {
- uint64_t rate;
+ uint32_t rate;
uint64_t options;
int up;
};
int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
uint16_t token,
const uint8_t mac_addr[6]);
+
/**
* dpni_get_primary_mac_addr() - Get the primary MAC address
* @mc_io: Pointer to MC portal's I/O object
int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
uint16_t token,
uint8_t mac_addr[6]);
+
/**
* dpni_add_mac_addr() - Add MAC address filter
* @mc_io: Pointer to MC portal's I/O object
/**
* enum dpni_dest - DPNI destination types
- * DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
+ * @DPNI_DEST_NONE: Unassigned destination; The queue is set in parked mode and
* does not generate FQDAN notifications; user is expected to
* dequeue from the queue based on polling or other user-defined
* method
uint8_t priority;
};
+/**
+ * enum dpni_flc_type - DPNI FLC types
+ * @DPNI_FLC_USER_DEFINED: select the FLC to be used for user defined value
+ * @DPNI_FLC_STASH: select the FLC to be used for stash control
+ */
+enum dpni_flc_type {
+ DPNI_FLC_USER_DEFINED = 0,
+ DPNI_FLC_STASH = 1,
+};
+
+/**
+ * enum dpni_stash_size - DPNI FLC stashing size
+ * @DPNI_STASH_SIZE_0B: no stash
+ * @DPNI_STASH_SIZE_64B: stashes 64 bytes
+ * @DPNI_STASH_SIZE_128B: stashes 128 bytes
+ * @DPNI_STASH_SIZE_192B: stashes 192 bytes
+ */
+enum dpni_stash_size {
+ DPNI_STASH_SIZE_0B = 0,
+ DPNI_STASH_SIZE_64B = 1,
+ DPNI_STASH_SIZE_128B = 2,
+ DPNI_STASH_SIZE_192B = 3,
+};
+
+/* DPNI FLC stash options */
+
+/* stashes the whole annotation area (up to 192 bytes) */
+#define DPNI_FLC_STASH_FRAME_ANNOTATION 0x00000001
+
+/**
+ * struct dpni_flc_cfg - Structure representing DPNI FLC configuration
+ * @flc_type: FLC type
+ * @options: Mask of available options;
+ * use 'DPNI_FLC_STASH_<X>' values
+ * @frame_data_size: Size of frame data to be stashed
+ * @flow_context_size: Size of flow context to be stashed
+ * @flow_context: 1. In case flc_type is 'DPNI_FLC_USER_DEFINED':
+ * this value will be provided in the frame descriptor
+ * (FD[FLC])
+ * 2. In case flc_type is 'DPNI_FLC_STASH':
+ * this value will be I/O virtual address of the
+ * flow-context;
+ * Must be cacheline-aligned and DMA-able memory
+ */
+struct dpni_flc_cfg {
+ enum dpni_flc_type flc_type;
+ uint32_t options;
+ enum dpni_stash_size frame_data_size;
+ enum dpni_stash_size flow_context_size;
+ uint64_t flow_context;
+};
+
/* DPNI queue modification options */
/* Select to modify the user's context associated with the queue */
#define DPNI_QUEUE_OPT_USER_CTX 0x00000001
/* Select to modify the queue's destination */
#define DPNI_QUEUE_OPT_DEST 0x00000002
+/** Select to modify the flow-context parameters;
+ * not applicable for Tx-conf/Err queues as the FD comes from the user
+ */
+#define DPNI_QUEUE_OPT_FLC 0x00000004
+
/**
* struct dpni_queue_cfg - Structure representing queue configuration
* is contained in 'options'
* @dest_cfg: Queue destination parameters;
* valid only if 'DPNI_QUEUE_OPT_DEST' is contained in 'options'
+ * @flc_cfg: Flow context configuration; in case the TC's distribution
+ * is either NONE or HASH the FLC's settings of flow#0 are used.
+ * in the case of FS (flow-steering) the flow's FLC settings
+ * are used.
+ * valid only if 'DPNI_QUEUE_OPT_FLC' is contained in 'options'
*/
struct dpni_queue_cfg {
uint32_t options;
uint64_t user_ctx;
struct dpni_dest_cfg dest_cfg;
+ struct dpni_flc_cfg flc_cfg;
};
/**
* @user_ctx: User context value provided in the frame descriptor of each
* dequeued frame
* @dest_cfg: Queue destination configuration
+ * @flc_cfg: Flow context configuration
* @fqid: Virtual fqid value to be used for dequeue operations
*/
struct dpni_queue_attr {
uint64_t user_ctx;
struct dpni_dest_cfg dest_cfg;
+ struct dpni_flc_cfg flc_cfg;
uint32_t fqid;
};
#define _FSL_DPRC_H
/* DPRC Version */
-#define DPRC_VER_MAJOR 2
+#define DPRC_VER_MAJOR 4
#define DPRC_VER_MINOR 0
/* Command IDs */
MC_RSP_OP(cmd, 4, 40, 8, char, obj_desc->type[13]);\
MC_RSP_OP(cmd, 4, 48, 8, char, obj_desc->type[14]);\
MC_RSP_OP(cmd, 4, 56, 8, char, obj_desc->type[15]);\
+ MC_RSP_OP(cmd, 5, 0, 8, char, obj_desc->label[0]);\
+ MC_RSP_OP(cmd, 5, 8, 8, char, obj_desc->label[1]);\
+ MC_RSP_OP(cmd, 5, 16, 8, char, obj_desc->label[2]);\
+ MC_RSP_OP(cmd, 5, 24, 8, char, obj_desc->label[3]);\
+ MC_RSP_OP(cmd, 5, 32, 8, char, obj_desc->label[4]);\
+ MC_RSP_OP(cmd, 5, 40, 8, char, obj_desc->label[5]);\
+ MC_RSP_OP(cmd, 5, 48, 8, char, obj_desc->label[6]);\
+ MC_RSP_OP(cmd, 5, 56, 8, char, obj_desc->label[7]);\
+ MC_RSP_OP(cmd, 6, 0, 8, char, obj_desc->label[8]);\
+ MC_RSP_OP(cmd, 6, 8, 8, char, obj_desc->label[9]);\
+ MC_RSP_OP(cmd, 6, 16, 8, char, obj_desc->label[10]);\
+ MC_RSP_OP(cmd, 6, 24, 8, char, obj_desc->label[11]);\
+ MC_RSP_OP(cmd, 6, 32, 8, char, obj_desc->label[12]);\
+ MC_RSP_OP(cmd, 6, 40, 8, char, obj_desc->label[13]);\
+ MC_RSP_OP(cmd, 6, 48, 8, char, obj_desc->label[14]);\
+ MC_RSP_OP(cmd, 6, 56, 8, char, obj_desc->label[15]);\
} while (0)
/* cmd, param, offset, width, type, arg_name */
/* param, offset, width, type, arg_name */
#define DPRC_RSP_GET_OBJ_REGION(cmd, region_desc) \
do { \
- MC_RSP_OP(cmd, 1, 0, 64, uint64_t, region_desc->base_paddr);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, region_desc->base_offset);\
MC_RSP_OP(cmd, 2, 0, 32, uint32_t, region_desc->size); \
} while (0)
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_SET_OBJ_LABEL(cmd, obj_index, label) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, obj_index); \
+ MC_CMD_OP(cmd, 1, 0, 8, char, label[0]);\
+ MC_CMD_OP(cmd, 1, 8, 8, char, label[1]);\
+ MC_CMD_OP(cmd, 1, 16, 8, char, label[2]);\
+ MC_CMD_OP(cmd, 1, 24, 8, char, label[3]);\
+ MC_CMD_OP(cmd, 1, 32, 8, char, label[4]);\
+ MC_CMD_OP(cmd, 1, 40, 8, char, label[5]);\
+ MC_CMD_OP(cmd, 1, 48, 8, char, label[6]);\
+ MC_CMD_OP(cmd, 1, 56, 8, char, label[7]);\
+ MC_CMD_OP(cmd, 2, 0, 8, char, label[8]);\
+ MC_CMD_OP(cmd, 2, 8, 8, char, label[9]);\
+ MC_CMD_OP(cmd, 2, 16, 8, char, label[10]);\
+ MC_CMD_OP(cmd, 2, 24, 8, char, label[11]);\
+ MC_CMD_OP(cmd, 2, 32, 8, char, label[12]);\
+ MC_CMD_OP(cmd, 2, 40, 8, char, label[13]);\
+ MC_CMD_OP(cmd, 2, 48, 8, char, label[14]);\
+ MC_CMD_OP(cmd, 2, 56, 8, char, label[15]);\
+} while (0)
+
/* cmd, param, offset, width, type, arg_name */
#define DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2) \
do { \
/* Data Path Resource Container API
* Contains DPRC API for managing and querying DPAA resources
*/
+
struct fsl_mc_io;
/**
/* Object initialization allowed - software context associated with this
* container is allowed to invoke object initialization operations.
*/
-#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004
+#define DPRC_CFG_OPT_OBJ_CREATE_ALLOWED 0x00000004
/* Topology change allowed - software context associated with this
* container is allowed to invoke topology operations, such as attach/detach
* @portal_id: Portal ID; if set to 'DPRC_GET_PORTAL_ID_FROM_POOL', a free
* portal ID is allocated by the DPRC
* @options: Combination of 'DPRC_CFG_OPT_<X>' options
+ * @label: Object's label
*/
struct dprc_cfg {
uint16_t icid;
int portal_id;
uint64_t options;
+ char label[16];
};
/**
* @irq_count: Number of interrupts supported by the object
* @region_count: Number of mappable regions supported by the object
* @state: Object state: combination of DPRC_OBJ_STATE_ states
+ * @label: Object label
*/
struct dprc_obj_desc {
char type[16];
uint8_t irq_count;
uint8_t region_count;
uint32_t state;
+ char label[16];
};
/**
struct dprc_obj_desc *obj_desc);
/**
- * dprc_get_res_count() - Obtains the number of free resources that are assigned
- * to this container, by pool type
+ * dprc_get_res_count() - Obtains the number of free resources that are
+ * assigned to this container, by pool type
* @mc_io: Pointer to MC portal's I/O object
* @token: Token of DPRC object
* @type: pool type
/**
* struct dprc_region_desc - Mappable region descriptor
- * @base_paddr: Region base physical address
+ * @base_offset: Region offset from region's base address.
+ * For DPMCP and DPRC objects, region base is offset from SoC MC portals
+ * base address; For DPIO, region base is offset from SoC QMan portals
+ * base address
* @size: Region size (in bytes)
*/
struct dprc_region_desc {
- uint64_t base_paddr;
+ uint64_t base_offset;
uint32_t size;
};
/**
* dprc_get_connection() - Get connected endpoint and link status if connection
* exists.
-* @mc_io Pointer to MC portal's I/O object
-* @token Token of DPRC object
+* @mc_io Pointer to MC portal's I/O object
+* @token Token of DPRC object
* @endpoint1 Endpoint 1 configuration parameters
* @endpoint2 Returned endpoint 2 configuration parameters
* @state: Returned link state: 1 - link is up, 0 - link is down
#define GCR1_M2_DE_RST BIT(14)
#define GCR1_M_ALL_DE_RST (GCR1_M1_DE_RST | GCR1_M2_DE_RST)
#define GSR_FS_MASK 0x3fffffff
-#define MCFAPR_PL_MASK (0x1 << 18)
-#define MCFAPR_BMT_MASK (0x1 << 17)
-#define MCFAPR_BYPASS_ICID_MASK \
- (MCFAPR_PL_MASK | MCFAPR_BMT_MASK)
#define SOC_MC_PORTALS_BASE_ADDR ((void __iomem *)0x00080C000000)
+#define SOC_QBMAN_PORTALS_BASE_ADDR ((void __iomem *)0x000818000000)
#define SOC_MC_PORTAL_STRIDE 0x10000
#define SOC_MC_PORTAL_ADDR(_portal_id) \
int fsl_ddr_get_dimm_params(dimm_params_t *pdimm,
unsigned int controller_number,
unsigned int dimm_number);
+void update_spd_address(unsigned int ctrl_num,
+ unsigned int slot,
+ unsigned int *addr);
#endif
};
int g_dnl_bind_fixup(struct usb_device_descriptor *, const char *);
+int g_dnl_get_board_bcd_device_number(int gcnum);
int g_dnl_board_usb_cable_connected(void);
int g_dnl_register(const char *s);
void g_dnl_unregister(void);
#define IH_TYPE_LPC32XXIMAGE 21 /* x86 setup.bin Image */
#define IH_TYPE_LOADABLE 22 /* A list of typeless images */
+#define IH_TYPE_COUNT 23 /* Number of image types */
+
/*
* Compression Types
*/
const char *genimg_get_os_name(uint8_t os);
const char *genimg_get_arch_name(uint8_t arch);
const char *genimg_get_type_name(uint8_t type);
+
+/**
+ * genimg_get_type_short_name() - get the short name for an image type
+ *
+ * @param type Image type (IH_TYPE_...)
+ * @return image short name, or "unknown" if unknown
+ */
+const char *genimg_get_type_short_name(uint8_t type);
+
const char *genimg_get_comp_name(uint8_t comp);
int genimg_get_os_id(const char *name);
int genimg_get_arch_id(const char *name);
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LED_H
+#define __LED_H
+
+/**
+ * struct led_uclass_plat - Platform data the uclass stores about each device
+ *
+ * @label: LED label
+ */
+struct led_uclass_plat {
+ const char *label;
+};
+
+struct led_ops {
+ /**
+ * set_on() - set the state of an LED
+ *
+ * @dev: LED device to change
+ * @on: 1 to turn the LED on, 0 to turn it off
+ * @return 0 if OK, -ve on error
+ */
+ int (*set_on)(struct udevice *dev, int on);
+};
+
+#define led_get_ops(dev) ((struct led_ops *)(dev)->driver->ops)
+
+/**
+ * led_get_by_label() - Find an LED device by label
+ *
+ * @label: LED label to look up
+ * @devp: Returns the associated device, if found
+ * @return 0 if found, -ENODEV if not found, other -ve on error
+ */
+int led_get_by_label(const char *label, struct udevice **devp);
+
+/**
+ * led_set_on() - set the state of an LED
+ *
+ * @dev: LED device to change
+ * @on: 1 to turn the LED on, 0 to turn it off
+ * @return 0 if OK, -ve on error
+ */
+int led_set_on(struct udevice *dev, int on);
+
+#endif
/* FDT_ERR_BADNCELLS: Device tree has a #address-cells, #size-cells
* or similar property with a bad format or value */
-#define FDT_ERR_MAX 14
+#define FDT_ERR_TOODEEP 15
+ /* FDT_ERR_TOODEEP: The depth of a node has exceeded the internal
+ * libfdt limit. This can happen if you have more than
+ * FDT_MAX_DEPTH nested nodes. */
+
+#define FDT_ERR_MAX 15
/**********************************************************************/
/* Low-level functions (you probably don't need these) */
int index, const char **output);
/**
- * fdt_get_string() - obtain the string at a given index in a string list
+ * fdt_get_string() - obtain the first string in a string list
* @fdt: pointer to the device tree blob
* @node: offset of the node
* @property: name of the property containing the string list
const char *fdt_strerror(int errval);
+/**
+ * fdt_remove_unused_strings() - Remove any unused strings from an FDT
+ *
+ * This creates a new device tree in @new with unused strings removed. The
+ * called can then use fdt_pack() to minimise the space consumed.
+ *
+ * @old: Old device tree blog
+ * @new: Place to put new device tree blob, which must be as large as
+ * @old
+ * @return
+ * 0, on success
+ * -FDT_ERR_BADOFFSET, corrupt device tree
+ * -FDT_ERR_NOSPACE, out of space, which should not happen unless there
+ * is something very wrong with the device tree input
+ */
+int fdt_remove_unused_strings(const void *old, void *new);
+
struct fdt_region {
int offset;
int size;
};
+/*
+ * Flags for fdt_find_regions()
+ *
+ * Add a region for the string table (always the last region)
+ */
+#define FDT_REG_ADD_STRING_TAB (1 << 0)
+
+/*
+ * Add all supernodes of a matching node/property, useful for creating a
+ * valid subset tree
+ */
+#define FDT_REG_SUPERNODES (1 << 1)
+
+/* Add the FDT_BEGIN_NODE tags of subnodes, including their names */
+#define FDT_REG_DIRECT_SUBNODES (1 << 2)
+
+/* Add all subnodes of a matching node */
+#define FDT_REG_ALL_SUBNODES (1 << 3)
+
+/* Add a region for the mem_rsvmap table (always the first region) */
+#define FDT_REG_ADD_MEM_RSVMAP (1 << 4)
+
+/* Indicates what an fdt part is (node, property, value) */
+#define FDT_IS_NODE (1 << 0)
+#define FDT_IS_PROP (1 << 1)
+#define FDT_IS_VALUE (1 << 2) /* not supported */
+#define FDT_IS_COMPAT (1 << 3) /* used internally */
+#define FDT_NODE_HAS_PROP (1 << 4) /* node contains prop */
+
+#define FDT_ANY_GLOBAL (FDT_IS_NODE | FDT_IS_PROP | FDT_IS_VALUE | \
+ FDT_IS_COMPAT)
+#define FDT_IS_ANY 0x1f /* all the above */
+
+/* We set a reasonable limit on the number of nested nodes */
+#define FDT_MAX_DEPTH 32
+
+/* Decribes what we want to include from the current tag */
+enum want_t {
+ WANT_NOTHING,
+ WANT_NODES_ONLY, /* No properties */
+ WANT_NODES_AND_PROPS, /* Everything for one level */
+ WANT_ALL_NODES_AND_PROPS /* Everything for all levels */
+};
+
+/* Keeps track of the state at parent nodes */
+struct fdt_subnode_stack {
+ int offset; /* Offset of node */
+ enum want_t want; /* The 'want' value here */
+ int included; /* 1 if we included this node, 0 if not */
+};
+
+struct fdt_region_ptrs {
+ int depth; /* Current tree depth */
+ int done; /* What we have completed scanning */
+ enum want_t want; /* What we are currently including */
+ char *end; /* Pointer to end of full node path */
+ int nextoffset; /* Next node offset to check */
+};
+
+/* The state of our finding algortihm */
+struct fdt_region_state {
+ struct fdt_subnode_stack stack[FDT_MAX_DEPTH]; /* node stack */
+ struct fdt_region *region; /* Contains list of regions found */
+ int count; /* Numnber of regions found */
+ const void *fdt; /* FDT blob */
+ int max_regions; /* Maximum regions to find */
+ int can_merge; /* 1 if we can merge with previous region */
+ int start; /* Start position of current region */
+ struct fdt_region_ptrs ptrs; /* Pointers for what we are up to */
+};
+
/**
* fdt_find_regions() - find regions in device tree
*
struct fdt_region region[], int max_regions,
char *path, int path_len, int add_string_tab);
+/**
+ * fdt_first_region() - find regions in device tree
+ *
+ * Given a nodes and properties to include and properties to exclude, find
+ * the regions of the device tree which describe those included parts.
+ *
+ * The use for this function is twofold. Firstly it provides a convenient
+ * way of performing a structure-aware grep of the tree. For example it is
+ * possible to grep for a node and get all the properties associated with
+ * that node. Trees can be subsetted easily, by specifying the nodes that
+ * are required, and then writing out the regions returned by this function.
+ * This is useful for small resource-constrained systems, such as boot
+ * loaders, which want to use an FDT but do not need to know about all of
+ * it.
+ *
+ * Secondly it makes it easy to hash parts of the tree and detect changes.
+ * The intent is to get a list of regions which will be invariant provided
+ * those parts are invariant. For example, if you request a list of regions
+ * for all nodes but exclude the property "data", then you will get the
+ * same region contents regardless of any change to "data" properties.
+ *
+ * This function can be used to produce a byte-stream to send to a hashing
+ * function to verify that critical parts of the FDT have not changed.
+ * Note that semantically null changes in order could still cause false
+ * hash misses. Such reordering might happen if the tree is regenerated
+ * from source, and nodes are reordered (the bytes-stream will be emitted
+ * in a different order and mnay hash functions will detect this). However
+ * if an existing tree is modified using libfdt functions, such as
+ * fdt_add_subnode() and fdt_setprop(), then this problem is avoided.
+ *
+ * The nodes/properties to include/exclude are defined by a function
+ * provided by the caller. This function is called for each node and
+ * property, and must return:
+ *
+ * 0 - to exclude this part
+ * 1 - to include this part
+ * -1 - for FDT_IS_PROP only: no information is available, so include
+ * if its containing node is included
+ *
+ * The last case is only used to deal with properties. Often a property is
+ * included if its containing node is included - this is the case where
+ * -1 is returned.. However if the property is specifically required to be
+ * included/excluded, then 0 or 1 can be returned. Note that including a
+ * property when the FDT_REG_SUPERNODES flag is given will force its
+ * containing node to be included since it is not valid to have a property
+ * that is not in a node.
+ *
+ * Using the information provided, the inclusion of a node can be controlled
+ * either by a node name or its compatible string, or any other property
+ * that the function can determine.
+ *
+ * As an example, including node "/" means to include the root node and all
+ * root properties. A flag provides a way of also including supernodes (of
+ * which there is none for the root node), and another flag includes
+ * immediate subnodes, so in this case we would get the FDT_BEGIN_NODE and
+ * FDT_END_NODE of all subnodes of /.
+ *
+ * The subnode feature helps in a hashing situation since it prevents the
+ * root node from changing at all. Any change to non-excluded properties,
+ * names of subnodes or number of subnodes would be detected.
+ *
+ * When used with FITs this provides the ability to hash and sign parts of
+ * the FIT based on different configurations in the FIT. Then it is
+ * impossible to change anything about that configuration (include images
+ * attached to the configuration), but it may be possible to add new
+ * configurations, new images or new signatures within the existing
+ * framework.
+ *
+ * Adding new properties to a device tree may result in the string table
+ * being extended (if the new property names are different from those
+ * already added). This function can optionally include a region for
+ * the string table so that this can be part of the hash too. This is always
+ * the last region.
+ *
+ * The FDT also has a mem_rsvmap table which can also be included, and is
+ * always the first region if so.
+ *
+ * The device tree header is not included in the region list. Since the
+ * contents of the FDT are changing (shrinking, often), the caller will need
+ * to regenerate the header anyway.
+ *
+ * @fdt: Device tree to check
+ * @h_include: Function to call to determine whether to include a part or
+ * not:
+ *
+ * @priv: Private pointer as passed to fdt_find_regions()
+ * @fdt: Pointer to FDT blob
+ * @offset: Offset of this node / property
+ * @type: Type of this part, FDT_IS_...
+ * @data: Pointer to data (node name, property name, compatible
+ * string, value (not yet supported)
+ * @size: Size of data, or 0 if none
+ * @return 0 to exclude, 1 to include, -1 if no information is
+ * available
+ * @priv: Private pointer passed to h_include
+ * @region: Returns list of regions, sorted by offset
+ * @max_regions: Maximum length of region list
+ * @path: Pointer to a temporary string for the function to use for
+ * building path names
+ * @path_len: Length of path, must be large enough to hold the longest
+ * path in the tree
+ * @flags: Various flags that control the region algortihm, see
+ * FDT_REG_...
+ * @return number of regions in list. If this is >max_regions then the
+ * region array was exhausted. You should increase max_regions and try
+ * the call again. Only the first max_regions elements are available in the
+ * array.
+ *
+ * On error a -ve value is return, which can be:
+ *
+ * -FDT_ERR_BADSTRUCTURE (too deep or more END tags than BEGIN tags
+ * -FDT_ERR_BADLAYOUT
+ * -FDT_ERR_NOSPACE (path area is too small)
+ */
+int fdt_first_region(const void *fdt,
+ int (*h_include)(void *priv, const void *fdt, int offset,
+ int type, const char *data, int size),
+ void *priv, struct fdt_region *region,
+ char *path, int path_len, int flags,
+ struct fdt_region_state *info);
+
+/** fdt_next_region() - find next region
+ *
+ * See fdt_first_region() for full description. This function finds the
+ * next region according to the provided parameters, which must be the same
+ * as passed to fdt_first_region().
+ *
+ * This function can additionally return -FDT_ERR_NOTFOUND when there are no
+ * more regions
+ */
+int fdt_next_region(const void *fdt,
+ int (*h_include)(void *priv, const void *fdt, int offset,
+ int type, const char *data, int size),
+ void *priv, struct fdt_region *region,
+ char *path, int path_len, int flags,
+ struct fdt_region_state *info);
+
+/**
+ * fdt_add_alias_regions() - find aliases that point to existing regions
+ *
+ * Once a device tree grep is complete some of the nodes will be present
+ * and some will have been dropped. This function checks all the alias nodes
+ * to figure out which points point to nodes which are still present. These
+ * aliases need to be kept, along with the nodes they reference.
+ *
+ * Given a list of regions function finds the aliases that still apply and
+ * adds more regions to the list for these. This function is called after
+ * fdt_next_region() has finished returning regions and requires the same
+ * state.
+ *
+ * @fdt: Device tree file to reference
+ * @region: List of regions that will be kept
+ * @count: Number of regions
+ * @max_regions: Number of entries that can fit in @region
+ * @info: Region state as returned from fdt_next_region()
+ * @return new number of regions in @region (i.e. count + the number added)
+ * or -FDT_ERR_NOSPACE if there was not enough space.
+ */
+int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count,
+ int max_regions, struct fdt_region_state *info);
+
#endif /* _LIBFDT_H */
* global list name ("outer"); iterators for only a sub-list should use
* the full sub-list name ("outer_2_inner").
*
- * Here is an example of the sections generated from a global list
+ * Here is an example of the sections generated from a global list
* named "drivers", two sub-lists named "i2c" and "pci", and iterators
* defined for the whole list and each sub-list:
*
*/
/**
- * ll_sym() - Access a linker-generated array entry
+ * llsym() - Access a linker-generated array entry
* @_type: Data type of the entry
* @_name: Name of the entry
* @_list: name of the list. Should contain only characters allowed
* the inner sections are present in the array.
*
* Example:
- * ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub, cmd.sub) = {
+ * ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = {
* .x = 3,
* .y = 4,
* };
* This is like ll_entry_declare() but creates multiple entries. It should
* be assigned to an array.
*
- * ll_entry_declare_list(struct my_sub_cmd, my_sub_cmd, cmd_sub, cmd.sub) = {
+ * ll_entry_declare_list(struct my_sub_cmd, my_sub_cmd, cmd_sub) = {
* { .x = 3, .y = 4 },
* { .x = 8, .y = 2 },
* { .x = 1, .y = 7 }
*/
#define ll_entry_end(_type, _list) \
({ \
- static char end[0] __aligned(4) __attribute__((unused, \
+ static char end[0] __aligned(4) __attribute__((unused, \
section(".u_boot_list_2_"#_list"_3"))); \
(_type *)&end; \
})
* @_name: Name of the entry
* @_list: Name of the list in which this entry is placed
*
- * This function returns a pointer to a particular entry in LG-array
- * identified by the subsection of u_boot_list where the entry resides
+ * This function returns a pointer to a particular entry in linker-generated
+ * array identified by the subsection of u_boot_list where the entry resides
* and it's name.
*
* Example:
({ \
extern _type _u_boot_list_2_##_list##_2_##_name; \
_type *_ll_result = \
- &_u_boot_list_2_##_list##_2_##_name; \
+ &_u_boot_list_2_##_list##_2_##_name; \
_ll_result; \
})
})
/**
- * ll_entry_end() - Point after last entry of last linker-generated array
+ * ll_end() - Point after last entry of last linker-generated array
* @_type: Data type of the entry
*
* This function returns (_type *) pointer after the very last entry of
*/
#define ll_end(_type) \
({ \
- static char end[0] __aligned(4) __attribute__((unused, \
+ static char end[0] __aligned(4) __attribute__((unused, \
section(".u_boot_list_3"))); \
(_type *)&end; \
})
#define KERN_INFO
#define KERN_DEBUG
+#define GFP_ATOMIC ((gfp_t) 0)
+#define GFP_KERNEL ((gfp_t) 0)
+#define GFP_NOFS ((gfp_t) 0)
+#define GFP_USER ((gfp_t) 0)
+#define __GFP_NOWARN ((gfp_t) 0)
+#define __GFP_ZERO ((__force gfp_t)0x8000u) /* Return zeroed page on success */
+
void *kmalloc(size_t size, int flags);
-void *kzalloc(size_t size, int flags);
+
+static inline void *kzalloc(size_t size, gfp_t flags)
+{
+ return kmalloc(size, flags | __GFP_ZERO);
+}
#define vmalloc(size) kmalloc(size, 0)
#define __vmalloc(size, flags, pgsz) kmalloc(size, flags)
+static inline void *vzalloc(unsigned long size)
+{
+ return kzalloc(size, 0);
+}
#define kfree(ptr) free(ptr)
#define vfree(ptr) free(ptr)
/* drivers/char/random.c */
#define get_random_bytes(...)
-/* idr.c */
-#define GFP_ATOMIC ((gfp_t) 0)
-#define GFP_KERNEL ((gfp_t) 0)
-#define GFP_NOFS ((gfp_t) 0)
-#define GFP_USER ((gfp_t) 0)
-#define __GFP_NOWARN ((gfp_t) 0)
-
/* include/linux/leds.h */
struct led_trigger {};
unsigned long copy_from_user(void *dest, const void *src,
unsigned long count);
-void *vzalloc(unsigned long size);
-
typedef unused_t spinlock_t;
typedef int wait_queue_head_t;
typedef unsigned long dmaaddr_t;
-#define cpu_relax() do {} while (0)
-
#define pm_runtime_get_sync(dev) do {} while (0)
#define pm_runtime_put(dev) do {} while (0)
#define pm_runtime_put_sync(dev) do {} while (0)
u32 g_hwparams8;
- u32 reserved4[63];
+ u32 reserved4[11];
+
+ u32 g_fladj;
+
+ u32 reserved5[51];
u32 d_cfg;
u32 d_ctl;
u32 d_gcmdpar;
u32 d_gcmd;
- u32 reserved5[2];
+ u32 reserved6[2];
u32 d_alepena;
- u32 reserved6[55];
+ u32 reserved7[55];
struct d_physical_endpoint d_phy_ep_cmd[32];
- u32 reserved7[128];
+ u32 reserved8[128];
u32 o_cfg;
u32 o_ctl;
u32 o_evten;
u32 o_sts;
- u32 reserved8[3];
+ u32 reserved9[3];
u32 adp_cfg;
u32 adp_ctl;
u32 bc_cfg;
- u32 reserved9;
+ u32 reserved10;
u32 bc_evt;
u32 bc_evten;
#define DWC3_DCTL_CSFTRST (1 << 30)
#define DWC3_DCTL_LSFTRST (1 << 29)
+/* Global Frame Length Adjustment Register */
+#define GFLADJ_30MHZ_REG_SEL (1 << 7)
+#define GFLADJ_30MHZ(n) ((n) & 0x3f)
+#define GFLADJ_30MHZ_DEFAULT 0x20
+
+#ifdef CONFIG_USB_XHCI_DWC3
+void dwc3_set_mode(struct dwc3 *dwc3_reg, u32 mode);
+void dwc3_core_soft_reset(struct dwc3 *dwc3_reg);
+int dwc3_core_init(struct dwc3 *dwc3_reg);
+void usb_phy_reset(struct dwc3 *dwc3_reg);
+void dwc3_set_fladj(struct dwc3 *dwc3_reg, u32 val);
+#endif
#endif /* __DWC3_H_ */
--- /dev/null
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * FSL USB HOST xHCI Controller
+ *
+ * Author: Ramneek Mehresh<ramneek.mehresh@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_ARCH_XHCI_FSL_H_
+#define _ASM_ARCH_XHCI_FSL_H_
+
+/* Default to the FSL XHCI defines */
+#define USB3_PWRCTL_CLK_CMD_MASK 0x3FE000
+#define USB3_PWRCTL_CLK_FREQ_MASK 0xFFC
+#define USB3_PHY_PARTIAL_RX_POWERON BIT(6)
+#define USB3_PHY_RX_POWERON BIT(14)
+#define USB3_PHY_TX_POWERON BIT(15)
+#define USB3_PHY_TX_RX_POWERON (USB3_PHY_RX_POWERON | USB3_PHY_TX_POWERON)
+#define USB3_PWRCTL_CLK_CMD_SHIFT 14
+#define USB3_PWRCTL_CLK_FREQ_SHIFT 22
+
+/* USBOTGSS_WRAPPER definitions */
+#define USBOTGSS_WRAPRESET BIT(17)
+#define USBOTGSS_DMADISABLE BIT(16)
+#define USBOTGSS_STANDBYMODE_NO_STANDBY BIT(4)
+#define USBOTGSS_STANDBYMODE_SMRT BIT(5)
+#define USBOTGSS_STANDBYMODE_SMRT_WKUP (0x3 << 4)
+#define USBOTGSS_IDLEMODE_NOIDLE BIT(2)
+#define USBOTGSS_IDLEMODE_SMRT BIT(3)
+#define USBOTGSS_IDLEMODE_SMRT_WKUP (0x3 << 2)
+
+/* USBOTGSS_IRQENABLE_SET_0 bit */
+#define USBOTGSS_COREIRQ_EN BIT(1)
+
+/* USBOTGSS_IRQENABLE_SET_1 bits */
+#define USBOTGSS_IRQ_SET_1_IDPULLUP_FALL_EN BIT(1)
+#define USBOTGSS_IRQ_SET_1_DISCHRGVBUS_FALL_EN BIT(3)
+#define USBOTGSS_IRQ_SET_1_CHRGVBUS_FALL_EN BIT(4)
+#define USBOTGSS_IRQ_SET_1_DRVVBUS_FALL_EN BIT(5)
+#define USBOTGSS_IRQ_SET_1_IDPULLUP_RISE_EN BIT(8)
+#define USBOTGSS_IRQ_SET_1_DISCHRGVBUS_RISE_EN BIT(11)
+#define USBOTGSS_IRQ_SET_1_CHRGVBUS_RISE_EN BIT(12)
+#define USBOTGSS_IRQ_SET_1_DRVVBUS_RISE_EN BIT(13)
+#define USBOTGSS_IRQ_SET_1_OEVT_EN BIT(16)
+#define USBOTGSS_IRQ_SET_1_DMADISABLECLR_EN BIT(17)
+
+struct fsl_xhci {
+ struct xhci_hccr *hcd;
+ struct dwc3 *dwc3_reg;
+};
+
+#if defined(CONFIG_LS102XA)
+#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_LS102XA_XHCI_USB1_ADDR
+#define CONFIG_SYS_FSL_XHCI_USB2_ADDR 0
+#elif defined(CONFIG_LS2085A)
+#define CONFIG_SYS_FSL_XHCI_USB1_ADDR CONFIG_SYS_LS2085A_XHCI_USB1_ADDR
+#define CONFIG_SYS_FSL_XHCI_USB2_ADDR CONFIG_SYS_LS2085A_XHCI_USB2_ADDR
+#endif
+
+#define FSL_USB_XHCI_ADDR {CONFIG_SYS_FSL_XHCI_USB1_ADDR, \
+ CONFIG_SYS_FSL_XHCI_USB2_ADDR}
+#endif /* _ASM_ARCH_XHCI_FSL_H_ */
#define MMC_NUM_BOOT_PARTITION 2
#define MMC_PART_RPMB 3 /* RPMB partition number */
+/* Driver model support */
+
+/**
+ * struct mmc_uclass_priv - Holds information about a device used by the uclass
+ */
+struct mmc_uclass_priv {
+ struct mmc *mmc;
+};
+
+/**
+ * mmc_get_mmc_dev() - get the MMC struct pointer for a device
+ *
+ * Provided that the device is already probed and ready for use, this value
+ * will be available.
+ *
+ * @dev: Device
+ * @return associated mmc struct pointer if available, else NULL
+ */
+struct mmc *mmc_get_mmc_dev(struct udevice *dev);
+
+/* End of driver model support */
+
struct mmc_cid {
unsigned long psn;
unsigned short oid;
int phy_interface;
};
+enum eth_recv_flags {
+ /*
+ * Check hardware device for new packets (otherwise only return those
+ * which are already in the memory buffer ready to process)
+ */
+ ETH_RECV_CHECK_DEVICE = 1 << 0,
+};
+
/**
* struct eth_ops - functions of Ethernet MAC controllers
*
* mcast: Join or leave a multicast group (for TFTP) - optional
* write_hwaddr: Write a MAC address to the hardware (used to pass it to Linux
* on some platforms like ARM). This function expects the
- * eth_pdata::enetaddr field to be populated - optional
+ * eth_pdata::enetaddr field to be populated. The method can
+ * return -ENOSYS to indicate that this is not implemented for
+ this hardware - optional.
* read_rom_hwaddr: Some devices have a backup of the MAC address stored in a
* ROM on the board. This is how the driver should expose it
* to the network stack. This function should fill in the
struct eth_ops {
int (*start)(struct udevice *dev);
int (*send)(struct udevice *dev, void *packet, int length);
- int (*recv)(struct udevice *dev, uchar **packetp);
+ int (*recv)(struct udevice *dev, int flags, uchar **packetp);
int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
void (*stop)(struct udevice *dev);
#ifdef CONFIG_MCAST_TFTP
#define PCI_ANY_ID (~0)
struct pci_device_id {
- unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
+ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
+ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
+ unsigned long driver_data; /* Data private to the driver */
};
struct pci_controller;
/* Get access to a PCI bus' operations */
#define pci_get_ops(dev) ((struct dm_pci_ops *)(dev)->driver->ops)
+/**
+ * pci_get_bdf() - Get the BDF value for a device
+ *
+ * @dev: Device to check
+ * @return bus/device/function value (see PCI_BDF())
+ */
+pci_dev_t pci_get_bdf(struct udevice *dev);
+
/**
* pci_bind_bus_devices() - scan a PCI bus and bind devices
*
int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
struct udevice **emulp);
-#endif
+#endif /* CONFIG_DM_PCI */
+
+/**
+ * PCI_DEVICE - macro used to describe a specific pci device
+ * @vend: the 16 bit PCI Vendor ID
+ * @dev: the 16 bit PCI Device ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific device. The subvendor and subdevice fields will be set to
+ * PCI_ANY_ID.
+ */
+#define PCI_DEVICE(vend, dev) \
+ .vendor = (vend), .device = (dev), \
+ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
+
+/**
+ * PCI_DEVICE_SUB - macro used to describe a specific pci device with subsystem
+ * @vend: the 16 bit PCI Vendor ID
+ * @dev: the 16 bit PCI Device ID
+ * @subvend: the 16 bit PCI Subvendor ID
+ * @subdev: the 16 bit PCI Subdevice ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific device with subsystem information.
+ */
+#define PCI_DEVICE_SUB(vend, dev, subvend, subdev) \
+ .vendor = (vend), .device = (dev), \
+ .subvendor = (subvend), .subdevice = (subdev)
+
+/**
+ * PCI_DEVICE_CLASS - macro used to describe a specific pci device class
+ * @dev_class: the class, subclass, prog-if triple for this device
+ * @dev_class_mask: the class mask for this device
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific PCI class. The vendor, device, subvendor, and subdevice
+ * fields will be set to PCI_ANY_ID.
+ */
+#define PCI_DEVICE_CLASS(dev_class, dev_class_mask) \
+ .class = (dev_class), .class_mask = (dev_class_mask), \
+ .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \
+ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
+
+/**
+ * PCI_VDEVICE - macro used to describe a specific pci device in short form
+ * @vend: the vendor name
+ * @dev: the 16 bit PCI Device ID
+ *
+ * This macro is used to create a struct pci_device_id that matches a
+ * specific PCI device. The subvendor, and subdevice fields will be set
+ * to PCI_ANY_ID. The macro allows the next field to follow as the device
+ * private data.
+ */
+
+#define PCI_VDEVICE(vend, dev) \
+ .vendor = PCI_VENDOR_ID_##vend, .device = (dev), \
+ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0
+
+/**
+ * struct pci_driver_entry - Matches a driver to its pci_device_id list
+ * @driver: Driver to use
+ * @match: List of match records for this driver, terminated by {}
+ */
+struct pci_driver_entry {
+ struct driver *driver;
+ const struct pci_device_id *match;
+};
+
+#define U_BOOT_PCI_DEVICE(__name, __match) \
+ ll_entry_declare(struct pci_driver_entry, __name, pci_driver_entry) = {\
+ .driver = llsym(struct driver, __name, driver), \
+ .match = __match, \
+ }
#endif /* __ASSEMBLY__ */
#endif /* _PCI_H */
*/
int pmic_read(struct udevice *dev, uint reg, uint8_t *buffer, int len);
int pmic_write(struct udevice *dev, uint reg, const uint8_t *buffer, int len);
+
+/**
+ * pmic_reg_read() - read a PMIC register value
+ *
+ * @dev: PMIC device to read
+ * @reg: Register to read
+ * @return value read on success or negative value of errno.
+ */
+int pmic_reg_read(struct udevice *dev, uint reg);
+
+/**
+ * pmic_reg_write() - write a PMIC register value
+ *
+ * @dev: PMIC device to write
+ * @reg: Register to write
+ * @value: Value to write
+ * @return 0 on success or negative value of errno.
+ */
+int pmic_reg_write(struct udevice *dev, uint reg, uint value);
+
+/**
+ * pmic_clrsetbits() - clear and set bits in a PMIC register
+ *
+ * This reads a register, optionally clears some bits, optionally sets some
+ * bits, then writes the register.
+ *
+ * @dev: PMIC device to update
+ * @reg: Register to update
+ * @clr: Bit mask to clear (set those bits that you want cleared)
+ * @set: Bit mask to set (set those bits that you want set)
+ * @return 0 on success or negative value of errno.
+ */
+int pmic_clrsetbits(struct udevice *dev, uint reg, uint clr, uint set);
+
#endif /* CONFIG_DM_PMIC */
#ifdef CONFIG_POWER
const char *name;
};
+enum regulator_flag {
+ REGULATOR_FLAG_AUTOSET_UV = 1 << 0,
+ REGULATOR_FLAG_AUTOSET_UA = 1 << 1,
+};
+
/**
* struct dm_regulator_uclass_platdata - pointed by dev->uclass_platdata, and
* allocated on each regulator bind. This structure holds an information
* @max_uA* - maximum amperage (micro Amps)
* @always_on* - bool type, true or false
* @boot_on* - bool type, true or false
+ * TODO(sjg@chromium.org): Consider putting the above two into @flags
+ * @flags: - flags value (see REGULATOR_FLAG_...)
* @name** - fdt regulator name - should be taken from the device tree
*
* Note:
bool always_on;
bool boot_on;
const char *name;
+ int flags;
};
/* Regulator device operations */
int regulator_set_mode(struct udevice *dev, int mode_id);
/**
- * regulator_autoset: setup the regulator given by its uclass's platform data
- * name field. The setup depends on constraints found in device's uclass's
- * platform data (struct dm_regulator_uclass_platdata):
+ * regulators_enable_boot_on() - enable regulators needed for boot
+ *
+ * This enables all regulators which are marked to be on at boot time. This
+ * only works for regulators which don't have a range for voltage/current,
+ * since in that case it is not possible to know which value to use.
+ *
+ * This effectively calls regulator_autoset() for every regulator.
+ */
+int regulators_enable_boot_on(bool verbose);
+
+/**
+ * regulator_autoset: setup the voltage/current on a regulator
+ *
+ * The setup depends on constraints found in device's uclass's platform data
+ * (struct dm_regulator_uclass_platdata):
+ *
+ * - Enable - will set - if any of: 'always_on' or 'boot_on' is set to true,
+ * or if both are unset, then the function returns
+ * - Voltage value - will set - if '.min_uV' and '.max_uV' values are equal
+ * - Current limit - will set - if '.min_uA' and '.max_uA' values are equal
+ *
+ * The function returns on the first-encountered error.
+ *
+ * @platname - expected string for dm_regulator_uclass_platdata .name field
+ * @devp - returned pointer to the regulator device - if non-NULL passed
+ * @return: 0 on success or negative value of errno.
+ */
+int regulator_autoset(struct udevice *dev);
+
+/**
+ * regulator_autoset_by_name: setup the regulator given by its uclass's
+ * platform data name field. The setup depends on constraints found in device's
+ * uclass's platform data (struct dm_regulator_uclass_platdata):
* - Enable - will set - if any of: 'always_on' or 'boot_on' is set to true,
* or if both are unset, then the function returns
* - Voltage value - will set - if '.min_uV' and '.max_uV' values are equal
*
* @platname - expected string for dm_regulator_uclass_platdata .name field
* @devp - returned pointer to the regulator device - if non-NULL passed
- * @verbose - (true/false) print regulator setup info, or be quiet
* @return: 0 on success or negative value of errno.
*
* The returned 'regulator' device can be used with:
* - regulator_get/set_*
*/
-int regulator_autoset(const char *platname,
- struct udevice **devp,
- bool verbose);
+int regulator_autoset_by_name(const char *platname, struct udevice **devp);
/**
* regulator_list_autoset: setup the regulators given by list of their uclass's
* platform data name field. The setup depends on constraints found in device's
* uclass's platform data. The function loops with calls to:
- * regulator_autoset() for each name from the list.
+ * regulator_autoset_by_name() for each name from the list.
*
* @list_platname - an array of expected strings for .name field of each
* regulator's uclass platdata
* Search by name, found in regulator uclass platdata.
*
* @platname - expected string for uc_pdata->name of regulator uclass platdata
- * @devp - returned pointer to the regulator device
+ * @devp - returns pointer to the regulator device or NULL on error
* @return 0 on success or negative value of errno.
*
* The returned 'regulator' device is probed and can be used with:
/*
* Expected regulators setup after call of:
- * - regulator_autoset()
+ * - regulator_autoset_by_name()
* - regulator_list_autoset()
*/
-/* BUCK1: for testing regulator_autoset() */
+/* BUCK1: for testing regulator_autoset_by_name() */
#define SANDBOX_BUCK1_AUTOSET_EXPECTED_UV 1200000
#define SANDBOX_BUCK1_AUTOSET_EXPECTED_UA 200000
#define SANDBOX_BUCK1_AUTOSET_EXPECTED_ENABLE true
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __RAM_H
+#define __RAM_H
+
+struct ram_info {
+ phys_addr_t base;
+ size_t size;
+};
+
+struct ram_ops {
+ /**
+ * get_info() - Get basic memory info
+ *
+ * @dev: Device to check (UCLASS_RAM)
+ * @info: Place to put info
+ * @return 0 if OK, -ve on error
+ */
+ int (*get_info)(struct udevice *dev, struct ram_info *info);
+};
+
+#define ram_get_ops(dev) ((struct ram_ops *)(dev)->driver->ops)
+
+/**
+ * ram_get_info() - Get information about a RAM device
+ *
+ * @dev: Device to check (UCLASS_RAM)
+ * @info: Returns RAM info
+ * @return 0 if OK, -ve on error
+ */
+int ram_get_info(struct udevice *dev, struct ram_info *info);
+
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2014 Rockchip Electronics
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __RC4_H
+#define __RC4_H
+
+/**
+ * rc4_encode() - encode a buf with the RC4 cipher
+ *
+ * @buf: Buffer to encode (it is overwrite in the process
+ * @len: Length of buffer in bytes
+ * @key: 16-byte key to use
+ */
+void rc4_encode(unsigned char *buf, unsigned int len, unsigned char key[16]);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __REGMAP_H
+#define __REGMAP_H
+
+/**
+ * struct regmap_range - a register map range
+ *
+ * @start: Start address
+ * @size: Size in bytes
+ */
+struct regmap_range {
+ ulong start;
+ ulong size;
+};
+
+/**
+ * struct regmap - a way of accessing hardware/bus registers
+ *
+ * @base: Base address of register map
+ * @range_count: Number of ranges available within the map
+ * @range: Pointer to the list of ranges, allocated if @range_count > 1
+ * @base_range: If @range_count is <= 1, @range points here
+ */
+struct regmap {
+ phys_addr_t base;
+ int range_count;
+ struct regmap_range *range, base_range;
+};
+
+/*
+ * Interface to provide access to registers either through a direct memory
+ * bus or through a peripheral bus like I2C, SPI.
+ */
+int regmap_write(struct regmap *map, uint offset, uint val);
+int regmap_read(struct regmap *map, uint offset, uint *valp);
+
+#define regmap_write32(map, ptr, member, val) \
+ regmap_write(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), val)
+
+#define regmap_read32(map, ptr, member, valp) \
+ regmap_read(map, (uint32_t *)(ptr)->member - (uint32_t *)(ptr), valp)
+
+/**
+ * regmap_init_mem() - Set up a new register map that uses memory access
+ *
+ * Use regmap_uninit() to free it.
+ *
+ * @dev: Device that uses this map
+ * @mapp: Returns allocated map
+ */
+int regmap_init_mem(struct udevice *dev, struct regmap **mapp);
+
+/**
+ * regmap_get_range() - Obtain the base memory address of a regmap range
+ *
+ * @map: Regmap to query
+ * @range_num: Range to look up
+ */
+void *regmap_get_range(struct regmap *map, unsigned int range_num);
+
+/**
+ * regmap_uninit() - free a previously inited regmap
+ */
+int regmap_uninit(struct regmap *map);
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __RESET_H
+#define __RESET_H
+
+enum reset_t {
+ RESET_WARM, /* Reset CPU, keep GPIOs active */
+ RESET_COLD, /* Reset CPU and GPIOs */
+ RESET_POWER, /* Reset PMIC (remove and restore power) */
+
+ RESET_COUNT,
+};
+
+struct reset_ops {
+ /**
+ * request() - request a reset of the given type
+ *
+ * Note that this function may return before the reset takes effect.
+ *
+ * @type: Reset type to request
+ * @return -EINPROGRESS if the reset has been started and
+ * will complete soon, -EPROTONOSUPPORT if not supported
+ * by this device, 0 if the reset has already happened
+ * (in which case this method will not actually return)
+ */
+ int (*request)(struct udevice *dev, enum reset_t type);
+};
+
+#define reset_get_ops(dev) ((struct reset_ops *)(dev)->driver->ops)
+
+/**
+ * reset_request() - request a reset
+ *
+ * @type: Reset type to request
+ * @return 0 if OK, -EPROTONOSUPPORT if not supported by this device
+ */
+int reset_request(struct udevice *dev, enum reset_t type);
+
+/**
+ * reset_walk() - cause a reset
+ *
+ * This works through the available reset devices until it finds one that can
+ * perform a reset. If the provided reset type is not available, the next one
+ * will be tried.
+ *
+ * If this function fails to reset, it will display a message and halt
+ *
+ * @type: Reset type to request
+ * @return -EINPROGRESS if a reset is in progress, -ENOSYS if not available
+ */
+int reset_walk(enum reset_t type);
+
+/**
+ * reset_walk_halt() - try to reset, otherwise halt
+ *
+ * This calls reset_walk(). If it returns, indicating that reset is not
+ * supported, it prints a message and halts.
+ */
+void reset_walk_halt(enum reset_t type);
+
+/**
+ * reset_cpu() - calls reset_walk(RESET_WARM)
+ */
+void reset_cpu(ulong addr);
+
+#endif
int spl_load_image_ext(block_dev_desc_t *block_dev, int partition, const char *filename);
int spl_load_image_ext_os(block_dev_desc_t *block_dev, int partition);
+/**
+ * spl_init() - Set up device tree and driver model in SPL if enabled
+ *
+ * Call this function in board_init_f() if you want to use device tree and
+ * driver model early, before board_init_r() is called. This function will
+ * be called from board_init_r() if not called earlier.
+ *
+ * If this is not called, then driver model will be inactive in SPL's
+ * board_init_f(), and no device tree will be available.
+ */
+int spl_init(void);
+
#ifdef CONFIG_SPL_BOARD_INIT
void spl_board_init(void);
#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __SYSCON_H
+#define __SYSCON_H
+
+/**
+ * struct syscon_uc_info - Information stored by the syscon UCLASS_UCLASS
+ *
+ * @regmap: Register map for this controller
+ */
+struct syscon_uc_info {
+ struct regmap *regmap;
+};
+
+/* So far there are no ops so this is a placeholder */
+struct syscon_ops {
+};
+
+#define syscon_get_ops(dev) ((struct syscon_ops *)(dev)->driver->ops)
+
+/**
+ * syscon_get_regmap() - Get access to a register map
+ *
+ * @dev: Device to check (UCLASS_SCON)
+ * @info: Returns regmap for the device
+ * @return 0 if OK, -ve on error
+ */
+struct regmap *syscon_get_regmap(struct udevice *dev);
+
+/**
+ * syscon_get_regmap_by_driver_data() - Look up a controller by its ID
+ *
+ * Each system controller can be accessed by its driver data, which is
+ * assumed to be unique through the scope of all system controllers that
+ * are in use. This function looks up the regmap given this driver data.
+ *
+ * @driver_data: Driver data value to look up
+ * @return register map correponding to @driver_data, or -ve error code
+ */
+struct regmap *syscon_get_regmap_by_driver_data(ulong driver_data);
+
+/**
+ * syscon_get_first_range() - get the first memory range from a syscon regmap
+ *
+ * @driver_data: Driver data value to look up
+ * @return first region of register map correponding to @driver_data, or
+ * -ve error code
+ */
+void *syscon_get_first_range(ulong driver_data);
+
+#endif
#ifndef __TEST_UT_H
#define __TEST_UT_H
+#include <linux/err.h>
+
struct unit_test_state;
/**
} \
}
+/* Assert that a pointer is not an error pointer */
+#define ut_assertok_ptr(expr) { \
+ const void *val = (expr); \
+ \
+ if (IS_ERR(val)) { \
+ ut_failf(uts, __FILE__, __LINE__, __func__, \
+ #expr " = NULL", \
+ "Expected pointer, got error %ld", \
+ PTR_ERR(val)); \
+ return CMD_RET_FAILURE; \
+ } \
+}
+
/* Assert that an operation succeeds (returns 0) */
#define ut_assertok(cond) ut_asserteq(0, cond)
int usb_lowlevel_stop(int index);
#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_DM_USB)
-int usb_reset_root_port(void);
+int usb_reset_root_port(struct usb_device *dev);
#else
-#define usb_reset_root_port()
+#define usb_reset_root_port(dev)
#endif
int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
/**
* struct usb_driver_entry - Matches a driver to its usb_device_ids
- * @compatible: Compatible string
- * @data: Data for this compatible string
+ * @driver: Driver to use
+ * @match: List of match records for this driver, terminated by {}
*/
struct usb_driver_entry {
struct driver *driver;
const struct usb_device_id *match;
};
-#define USB_DEVICE(__name, __match) \
+#define USB_DEVICE_ID_MATCH_DEVICE \
+ (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
+
+/**
+ * USB_DEVICE - macro used to describe a specific usb device
+ * @vend: the 16 bit USB Vendor ID
+ * @prod: the 16 bit USB Product ID
+ *
+ * This macro is used to create a struct usb_device_id that matches a
+ * specific device.
+ */
+#define USB_DEVICE(vend, prod) \
+ .match_flags = USB_DEVICE_ID_MATCH_DEVICE, \
+ .idVendor = (vend), \
+ .idProduct = (prod)
+
+#define U_BOOT_USB_DEVICE(__name, __match) \
ll_entry_declare(struct usb_driver_entry, __name, usb_driver_entry) = {\
.driver = llsym(struct driver, __name, driver), \
.match = __match, \
* is read). This should be NULL for EHCI, which does not need this.
*/
int (*alloc_device)(struct udevice *bus, struct usb_device *udev);
+
+ /**
+ * reset_root_port() - Reset usb root port
+ */
+ int (*reset_root_port)(struct udevice *bus, struct usb_device *udev);
};
#define usb_get_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops)
#define usb_get_emul_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops)
-#ifdef CONFIG_MUSB_HOST
-int usb_reset_root_port(void);
-#endif
-
/**
* usb_get_dev_index() - look up a device index number
*
*/
struct usb_device *usb_get_dev_index(struct udevice *bus, int index);
-/**
- * usb_legacy_port_reset() - Legacy function to reset a hub port
- *
- * @hub: Hub device
- * @portnr: Port number (1=first)
- */
-int usb_legacy_port_reset(struct usb_device *hub, int portnr);
-
/**
* usb_setup_device() - set up a device ready for use
*
* @dev: USB device pointer. This need not be a real device - it is
* common for it to just be a local variable with its ->dev
- * member (i.e. @dev->dev) set to the parent device
+ * member (i.e. @dev->dev) set to the parent device and
+ * dev->portnr set to the port number on the hub (1=first)
* @do_read: true to read the device descriptor before an address is set
* (should be false for XHCI buses, true otherwise)
* @parent: Parent device (either UCLASS_USB or UCLASS_USB_HUB)
- * @portnr: Port number on hub (1=first) or 0 for none
* @return 0 if OK, -ve on error */
int usb_setup_device(struct usb_device *dev, bool do_read,
- struct usb_device *parent, int portnr);
+ struct usb_device *parent);
/**
* usb_hub_scan() - Scan a hub and find its devices
#define ETH_DATA_LEN 1500 /* Max. octets in payload */
#define ETH_FRAME_LEN PKTSIZE_ALIGN /* Max. octets in frame sans FCS */
+/* TODO(sjg@chromium.org): Remove @pusb_dev when all boards use CONFIG_DM_ETH */
struct ueth_data {
/* eth info */
- struct eth_device eth_dev; /* used with eth_register */
- int phy_id; /* mii phy id */
+#ifdef CONFIG_DM_ETH
+ uint8_t *rxbuf;
+ int rxsize;
+ int rxlen; /* Total bytes available in rxbuf */
+ int rxptr; /* Current position in rxbuf */
+#else
+ struct eth_device eth_dev; /* used with eth_register */
+ /* driver private */
+ void *dev_priv;
+#endif
+ int phy_id; /* mii phy id */
/* usb info */
struct usb_device *pusb_dev; /* this usb_device */
- unsigned char ifnum; /* interface number */
- unsigned char ep_in; /* in endpoint */
- unsigned char ep_out; /* out ....... */
- unsigned char ep_int; /* interrupt . */
- unsigned char subclass; /* as in overview */
- unsigned char protocol; /* .............. */
+ unsigned char ifnum; /* interface number */
+ unsigned char ep_in; /* in endpoint */
+ unsigned char ep_out; /* out ....... */
+ unsigned char ep_int; /* interrupt . */
+ unsigned char subclass; /* as in overview */
+ unsigned char protocol; /* .............. */
unsigned char irqinterval; /* Intervall for IRQ Pipe */
-
- /* driver private */
- void *dev_priv;
};
+#ifdef CONFIG_DM_ETH
+/**
+ * usb_ether_register() - register a new USB ethernet device
+ *
+ * This selects the correct USB interface and figures out the endpoints to use.
+ *
+ * @dev: USB device
+ * @ss: Place to put USB ethernet data
+ * @rxsize: Maximum size to allocate for the receive buffer
+ * @return 0 if OK, -ve on error
+ */
+int usb_ether_register(struct udevice *dev, struct ueth_data *ueth, int rxsize);
+
+/**
+ * usb_ether_deregister() - deregister a USB ethernet device
+ *
+ * @ueth: USB Ethernet device
+ * @return 0
+ */
+int usb_ether_deregister(struct ueth_data *ueth);
+
+/**
+ * usb_ether_receive() - recieve a packet from the bulk in endpoint
+ *
+ * The packet is stored in the internal buffer ready for processing.
+ *
+ * @ueth: USB Ethernet device
+ * @rxsize: Maximum size to receive
+ * @return 0 if a packet was received, -EAGAIN if not, -ENOSPC if @rxsize is
+ * larger than the size passed ot usb_ether_register(), other -ve on error
+ */
+int usb_ether_receive(struct ueth_data *ueth, int rxsize);
+
+/**
+ * usb_ether_get_rx_bytes() - obtain bytes from the internal packet buffer
+ *
+ * This should be called repeatedly to obtain packet data until it returns 0.
+ * After each packet is processed, call usb_ether_advance_rxbuf() to move to
+ * the next one.
+ *
+ * @ueth: USB Ethernet device
+ * @ptrp: Returns a pointer to the start of the next packet if there is
+ * one available
+ * @return number of bytes available, or 0 if none
+ */
+int usb_ether_get_rx_bytes(struct ueth_data *ueth, uint8_t **ptrp);
+
+/**
+ * usb_ether_advance_rxbuf() - Advance to the next packet in the internal buffer
+ *
+ * After processing the data returned by usb_ether_get_rx_bytes(), call this
+ * function to move to the next packet. You must specify the number of bytes
+ * you have processed in @num_bytes.
+ *
+ * @ueth: USB Ethernet device
+ * @num_bytes: Number of bytes to skip, or -1 to skip all bytes
+ */
+void usb_ether_advance_rxbuf(struct ueth_data *ueth, int num_bytes);
+#else
/*
* Function definitions for each USB ethernet driver go here
* (declaration is unconditional, compilation is conditional)
struct ueth_data *ss);
int smsc95xx_eth_get_info(struct usb_device *dev, struct ueth_data *ss,
struct eth_device *eth);
+#endif
#endif /* __USB_ETHER_H__ */
unsigned int base);
long simple_strtol(const char *cp, char **endp, unsigned int base);
+/**
+ * trailing_strtol() - extract a trailing integer from a string
+ *
+ * Given a string this finds a trailing number on the string and returns it.
+ * For example, "abc123" would return 123.
+ *
+ * @str: String to exxamine
+ * @return training number if found, else -1
+ */
+long trailing_strtol(const char *str);
+
+/**
+ * trailing_strtoln() - extract a trailing integer from a fixed-length string
+ *
+ * Given a fixed-length string this finds a trailing number on the string
+ * and returns it. For example, "abc123" would return 123. Only the
+ * characters between @str and @end - 1 are examined. If @end is NULL, it is
+ * set to str + strlen(str).
+ *
+ * @str: String to exxamine
+ * @end: Pointer to end of string to examine, or NULL to use the
+ * whole string
+ * @return training number if found, else -1
+ */
+long trailing_strtoln(const char *str, const char *end);
+
/**
* panic() - Print a message and reset/hang
*
help
This library provides pseudo-random number generator functions.
+source lib/dhry/Kconfig
+
source lib/rsa/Kconfig
menu "Hashing Support"
obj-$(CONFIG_TIZEN) += tizen/
obj-$(CONFIG_OF_LIBFDT) += libfdt/
obj-$(CONFIG_FIT) += libfdt/
+obj-$(CONFIG_FIT) += libfdt/
+obj-$(CONFIG_CMD_DHRYSTONE) += dhry/
obj-$(CONFIG_AES) += aes.o
obj-$(CONFIG_USB_TTY) += circbuf.o
obj-y += crc7.o
obj-y += crc8.o
obj-y += crc16.o
+obj-$(CONFIG_ERRNO_STR) += errno_str.o
obj-$(CONFIG_FIT) += fdtdec_common.o
obj-$(CONFIG_OF_CONTROL) += fdtdec_common.o
obj-$(CONFIG_OF_CONTROL) += fdtdec.o
obj-y += net_utils.o
obj-$(CONFIG_PHYSMEM) += physmem.o
obj-y += qsort.o
+obj-y += rc4.o
obj-$(CONFIG_SHA1) += sha1.o
obj-$(CONFIG_SUPPORT_EMMC_RPMB) += sha256.o
obj-$(CONFIG_SHA256) += sha256.o
obj-$(CONFIG_ADDR_MAP) += addr_map.o
obj-y += hashtable.o
obj-y += errno.o
-obj-$(CONFIG_ERRNO_STR) += errno_str.o
obj-y += display_options.o
obj-$(CONFIG_BCH) += bch.o
obj-y += crc32.o
--- /dev/null
+config CMD_DHRYSTONE
+ bool "Support the 'dhry' command to run the dhrystone benchmark"
+ help
+ Dhrystone is an old benchmark in the public domain that gives a
+ rough idea of CPU performance. This enables a 'dhry' command
+ which runs this benchmark within U-Boot and reports the performance.
+ The number of 'Dhrystone MIPS' is also reported.
--- /dev/null
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += cmd_dhry.o dhry_1.o dhry_2.o
--- /dev/null
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include "dhry.h"
+
+static int do_dhry(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ ulong start, duration, dhry_per_sec, vax_mips;
+ int iterations = 1000000;
+
+ if (argc > 1)
+ iterations = simple_strtoul(argv[1], NULL, 10);
+
+ start = get_timer(0);
+ dhry(iterations);
+ duration = get_timer(start);
+ dhry_per_sec = iterations * 1000 / duration;
+ vax_mips = dhry_per_sec / 1757;
+ printf("%d iterations in %lu ms: %lu/s, %lu DMIPS\n", iterations,
+ duration, dhry_per_sec, vax_mips);
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ dhry, 2, 1, do_dhry,
+ "[iterations] - run dhrystone benchmark",
+ "\n - run the Dhrystone 2.1 benchmark, a rough measure of CPU speed\n"
+);
--- /dev/null
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Dhrystone is widely available in the public domain. A GPL license is
+ * chosen for U-Boot.
+ */
+
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry.h SID: 3.4 5/15/91 19:30:21
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ * Modification Log:
+ * addapted from:
+ *
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry.h (part 1 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ * Siemens AG, AUT E 51
+ * Postfach 3220
+ * 8520 Erlangen
+ * Germany (West)
+ * Phone: [+49]-9131-7-20330
+ * (8-17 Central European Time)
+ * Usenet: ..!mcvax!unido!estevax!weicker
+ *
+ * Original Version (in Ada) published in
+ * "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
+ * pp. 1013 - 1030, together with the statistics
+ * on which the distribution of statements etc. is based.
+ *
+ * In this C version, the following C library functions are used:
+ * - strcpy, strcmp (inside the measurement loop)
+ * - printf, scanf (outside the measurement loop)
+ * In addition, Berkeley UNIX system calls "times ()" or "time ()"
+ * are used for execution time measurement. For measurements
+ * on other systems, these calls have to be changed.
+ *
+ * Collection of Results:
+ * Reinhold Weicker (address see above) and
+ *
+ * Rick Richardson
+ * PC Research. Inc.
+ * 94 Apple Orchard Drive
+ * Tinton Falls, NJ 07724
+ * Phone: (201) 834-1378 (9-17 EST)
+ * Usenet: ...!seismo!uunet!pcrat!rick
+ *
+ * Please send results to Rick Richardson and/or Reinhold Weicker.
+ * Complete information should be given on hardware and software used.
+ * Hardware information includes: Machine type, CPU, type and size
+ * of caches; for microprocessors: clock frequency, memory speed
+ * (number of wait states).
+ * Software information includes: Compiler (and runtime library)
+ * manufacturer and version, compilation switches, OS version.
+ * The Operating System version may give an indication about the
+ * compiler; Dhrystone itself performs no OS calls in the measurement loop.
+ *
+ * The complete output generated by the program should be mailed
+ * such that at least some checks for correctness can be made.
+ *
+ ***************************************************************************
+ *
+ * History: This version C/2.1 has been made for two reasons:
+ *
+ * 1) There is an obvious need for a common C version of
+ * Dhrystone, since C is at present the most popular system
+ * programming language for the class of processors
+ * (microcomputers, minicomputers) where Dhrystone is used most.
+ * There should be, as far as possible, only one C version of
+ * Dhrystone such that results can be compared without
+ * restrictions. In the past, the C versions distributed
+ * by Rick Richardson (Version 1.1) and by Reinhold Weicker
+ * had small (though not significant) differences.
+ *
+ * 2) As far as it is possible without changes to the Dhrystone
+ * statistics, optimizing compilers should be prevented from
+ * removing significant statements.
+ *
+ * This C version has been developed in cooperation with
+ * Rick Richardson (Tinton Falls, NJ), it incorporates many
+ * ideas from the "Version 1.1" distributed previously by
+ * him over the UNIX network Usenet.
+ * I also thank Chaim Benedelac (National Semiconductor),
+ * David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
+ * Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
+ * for their help with comments on earlier versions of the
+ * benchmark.
+ *
+ * Changes: In the initialization part, this version follows mostly
+ * Rick Richardson's version distributed via Usenet, not the
+ * version distributed earlier via floppy disk by Reinhold Weicker.
+ * As a concession to older compilers, names have been made
+ * unique within the first 8 characters.
+ * Inside the measurement loop, this version follows the
+ * version previously distributed by Reinhold Weicker.
+ *
+ * At several places in the benchmark, code has been added,
+ * but within the measurement loop only in branches that
+ * are not executed. The intention is that optimizing compilers
+ * should be prevented from moving code out of the measurement
+ * loop, or from removing code altogether. Since the statements
+ * that are executed within the measurement loop have NOT been
+ * changed, the numbers defining the "Dhrystone distribution"
+ * (distribution of statements, operand types and locality)
+ * still hold. Except for sophisticated optimizing compilers,
+ * execution times for this version should be the same as
+ * for previous versions.
+ *
+ * Since it has proven difficult to subtract the time for the
+ * measurement loop overhead in a correct way, the loop check
+ * has been made a part of the benchmark. This does have
+ * an impact - though a very minor one - on the distribution
+ * statistics which have been updated for this version.
+ *
+ * All changes within the measurement loop are described
+ * and discussed in the companion paper "Rationale for
+ * Dhrystone version 2".
+ *
+ * Because of the self-imposed limitation that the order and
+ * distribution of the executed statements should not be
+ * changed, there are still cases where optimizing compilers
+ * may not generate code for some statements. To a certain
+ * degree, this is unavoidable for small synthetic benchmarks.
+ * Users of the benchmark are advised to check code listings
+ * whether code is generated for all statements of Dhrystone.
+ *
+ * Version 2.1 is identical to version 2.0 distributed via
+ * the UNIX network Usenet in March 1988 except that it corrects
+ * some minor deficiencies that were found by users of version 2.0.
+ * The only change within the measurement loop is that a
+ * non-executed "else" part was added to the "if" statement in
+ * Func_3, and a non-executed "else" part removed from Proc_3.
+ *
+ ***************************************************************************
+ *
+ * Defines: The following "Defines" are possible:
+ * -DREG=register (default: Not defined)
+ * As an approximation to what an average C programmer
+ * might do, the "register" storage class is applied
+ * (if enabled by -DREG=register)
+ * - for local variables, if they are used (dynamically)
+ * five or more times
+ * - for parameters if they are used (dynamically)
+ * six or more times
+ * Note that an optimal "register" strategy is
+ * compiler-dependent, and that "register" declarations
+ * do not necessarily lead to faster execution.
+ * -DNOSTRUCTASSIGN (default: Not defined)
+ * Define if the C compiler does not support
+ * assignment of structures.
+ * -DNOENUMS (default: Not defined)
+ * Define if the C compiler does not support
+ * enumeration types.
+ * -DTIMES (default)
+ * -DTIME
+ * The "times" function of UNIX (returning process times)
+ * or the "time" function (returning wallclock time)
+ * is used for measurement.
+ * For single user machines, "time ()" is adequate. For
+ * multi-user machines where you cannot get single-user
+ * access, use the "times ()" function. If you have
+ * neither, use a stopwatch in the dead of night.
+ * "printf"s are provided marking the points "Start Timer"
+ * and "Stop Timer". DO NOT use the UNIX "time(1)"
+ * command, as this will measure the total time to
+ * run this program, which will (erroneously) include
+ * the time to allocate storage (malloc) and to perform
+ * the initialization.
+ * -DHZ=nnn
+ * In Berkeley UNIX, the function "times" returns process
+ * time in 1/HZ seconds, with HZ = 60 for most systems.
+ * CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
+ * A VALUE.
+ *
+ ***************************************************************************
+ *
+ * Compilation model and measurement (IMPORTANT):
+ *
+ * This C version of Dhrystone consists of three files:
+ * - dhry.h (this file, containing global definitions and comments)
+ * - dhry_1.c (containing the code corresponding to Ada package Pack_1)
+ * - dhry_2.c (containing the code corresponding to Ada package Pack_2)
+ *
+ * The following "ground rules" apply for measurements:
+ * - Separate compilation
+ * - No procedure merging
+ * - Otherwise, compiler optimizations are allowed but should be indicated
+ * - Default results are those without register declarations
+ * See the companion paper "Rationale for Dhrystone Version 2" for a more
+ * detailed discussion of these ground rules.
+ *
+ * For 16-Bit processors (e.g. 80186, 80286), times for all compilation
+ * models ("small", "medium", "large" etc.) should be given if possible,
+ * together with a definition of these models for the compiler system used.
+ *
+ **************************************************************************
+ *
+ * Dhrystone (C version) statistics:
+ *
+ * [Comment from the first distribution, updated for version 2.
+ * Note that because of language differences, the numbers are slightly
+ * different from the Ada version.]
+ *
+ * The following program contains statements of a high level programming
+ * language (here: C) in a distribution considered representative:
+ *
+ * assignments 52 (51.0 %)
+ * control statements 33 (32.4 %)
+ * procedure, function calls 17 (16.7 %)
+ *
+ * 103 statements are dynamically executed. The program is balanced with
+ * respect to the three aspects:
+ *
+ * - statement type
+ * - operand type
+ * - operand locality
+ * operand global, local, parameter, or constant.
+ *
+ * The combination of these three aspects is balanced only approximately.
+ *
+ * 1. Statement Type:
+ * ----------------- number
+ *
+ * V1 = V2 9
+ * (incl. V1 = F(..)
+ * V = Constant 12
+ * Assignment, 7
+ * with array element
+ * Assignment, 6
+ * with record component
+ * --
+ * 34 34
+ *
+ * X = Y +|-|"&&"|"|" Z 5
+ * X = Y +|-|"==" Constant 6
+ * X = X +|- 1 3
+ * X = Y *|/ Z 2
+ * X = Expression, 1
+ * two operators
+ * X = Expression, 1
+ * three operators
+ * --
+ * 18 18
+ *
+ * if .... 14
+ * with "else" 7
+ * without "else" 7
+ * executed 3
+ * not executed 4
+ * for ... 7 | counted every time
+ * while ... 4 | the loop condition
+ * do ... while 1 | is evaluated
+ * switch ... 1
+ * break 1
+ * declaration with 1
+ * initialization
+ * --
+ * 34 34
+ *
+ * P (...) procedure call 11
+ * user procedure 10
+ * library procedure 1
+ * X = F (...)
+ * function call 6
+ * user function 5
+ * library function 1
+ * --
+ * 17 17
+ * ---
+ * 103
+ *
+ * The average number of parameters in procedure or function calls
+ * is 1.82 (not counting the function values as implicit parameters).
+ *
+ *
+ * 2. Operators
+ * ------------
+ * number approximate
+ * percentage
+ *
+ * Arithmetic 32 50.8
+ *
+ * + 21 33.3
+ * - 7 11.1
+ * * 3 4.8
+ * / (int div) 1 1.6
+ *
+ * Comparison 27 42.8
+ *
+ * == 9 14.3
+ * /= 4 6.3
+ * > 1 1.6
+ * < 3 4.8
+ * >= 1 1.6
+ * <= 9 14.3
+ *
+ * Logic 4 6.3
+ *
+ * && (AND-THEN) 1 1.6
+ * | (OR) 1 1.6
+ * ! (NOT) 2 3.2
+ *
+ * -- -----
+ * 63 100.1
+ *
+ *
+ * 3. Operand Type (counted once per operand reference):
+ * ---------------
+ * number approximate
+ * percentage
+ *
+ * Integer 175 72.3 %
+ * Character 45 18.6 %
+ * Pointer 12 5.0 %
+ * String30 6 2.5 %
+ * Array 2 0.8 %
+ * Record 2 0.8 %
+ * --- -------
+ * 242 100.0 %
+ *
+ * When there is an access path leading to the final operand (e.g. a record
+ * component), only the final data type on the access path is counted.
+ *
+ *
+ * 4. Operand Locality:
+ * -------------------
+ * number approximate
+ * percentage
+ *
+ * local variable 114 47.1 %
+ * global variable 22 9.1 %
+ * parameter 45 18.6 %
+ * value 23 9.5 %
+ * reference 22 9.1 %
+ * function result 6 2.5 %
+ * constant 55 22.7 %
+ * --- -------
+ * 242 100.0 %
+ *
+ *
+ * The program does not compute anything meaningful, but it is syntactically
+ * and semantically correct. All variables have a value assigned to them
+ * before they are used as a source operand.
+ *
+ * There has been no explicit effort to account for the effects of a
+ * cache, or to balance the use of long or short displacements for code or
+ * data.
+ *
+ ***************************************************************************
+ */
+
+
+/* Compiler and system dependent definitions: */
+
+#ifndef TIME
+#define TIMES
+#endif
+ /* Use times(2) time function unless */
+ /* explicitly defined otherwise */
+
+#define Mic_secs_Per_Second 1000000.0
+ /* Berkeley UNIX C returns process times in seconds/HZ */
+
+#ifdef NOSTRUCTASSIGN
+#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
+#else
+#define structassign(d, s) d = s
+#endif
+
+#ifdef NOENUM
+#define Ident_1 0
+#define Ident_2 1
+#define Ident_3 2
+#define Ident_4 3
+#define Ident_5 4
+ typedef int Enumeration;
+#else
+ typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
+ Enumeration;
+#endif
+ /* for boolean and enumeration types in Ada, Pascal */
+
+/* General definitions: */
+
+#define Null 0
+ /* Value of a Null pointer */
+#define true 1
+#define false 0
+
+typedef int One_Thirty;
+typedef int One_Fifty;
+typedef char Capital_Letter;
+typedef int Boolean;
+typedef char Str_30 [31];
+typedef int Arr_1_Dim [50];
+typedef int Arr_2_Dim [50] [50];
+
+typedef struct record
+ {
+ struct record *Ptr_Comp;
+ Enumeration Discr;
+ union {
+ struct {
+ Enumeration Enum_Comp;
+ int Int_Comp;
+ char Str_Comp [31];
+ } var_1;
+ struct {
+ Enumeration E_Comp_2;
+ char Str_2_Comp [31];
+ } var_2;
+ struct {
+ char Ch_1_Comp;
+ char Ch_2_Comp;
+ } var_3;
+ } variant;
+ } Rec_Type, *Rec_Pointer;
+
+
+/*
+ * dhry() - run dhrystone for a given number of iterations
+ *
+ * @iterations: Number of iterations to run
+ */
+void dhry(int iterations);
--- /dev/null
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Dhrystone is widely available in the public domain. A GPL license is
+ * chosen for U-Boot.
+ */
+
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry_1.c SID: 3.4 5/15/91 19:30:21
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ *
+ * *** WARNING **** With BYTE's modifications applied, results obtained with
+ * ******* this version of the Dhrystone program may not be applicable
+ * to other versions.
+ *
+ * Modification Log:
+ * 10/22/97 - code cleanup to remove ANSI C compiler warnings
+ * Andy Kahn <kahn@zk3.dec.com>
+ *
+ * Adapted from:
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_1.c (part 2 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ***************************************************************************/
+char SCCSid[] = "@(#) @(#)dhry_1.c:3.4 -- 5/15/91 19:30:21";
+
+#include <common.h>
+#include <malloc.h>
+
+#include "dhry.h"
+
+unsigned long Run_Index;
+
+void report(void)
+{
+ printf("%ld loops\n", Run_Index);
+}
+
+/* Global Variables: */
+
+Rec_Pointer Ptr_Glob,
+ Next_Ptr_Glob;
+int Int_Glob;
+Boolean Bool_Glob;
+char Ch_1_Glob,
+ Ch_2_Glob;
+int Arr_1_Glob [50];
+int Arr_2_Glob [50] [50];
+
+Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val);
+ /* forward declaration necessary since Enumeration may not simply be int */
+
+#ifndef REG
+ Boolean Reg = false;
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#else
+ Boolean Reg = true;
+#endif
+
+/* variables for time measurement: */
+
+#ifdef TIMES
+#define Too_Small_Time 120
+ /* Measurements should last at least about 2 seconds */
+#endif
+#ifdef TIME
+extern long time();
+ /* see library function "time" */
+#define Too_Small_Time 2
+ /* Measurements should last at least 2 seconds */
+#endif
+
+long Begin_Time,
+ End_Time,
+ User_Time;
+
+/* end of variables for time measurement */
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par);
+void Proc_2 (One_Fifty *Int_Par_Ref);
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par);
+void Proc_4 (void);
+void Proc_5 (void);
+
+
+extern Boolean Func_2(Str_30, Str_30);
+extern void Proc_6(Enumeration, Enumeration *);
+extern void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+extern void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+
+void dhry(int Number_Of_Runs)
+ /* main program, corresponds to procedures */
+ /* Main and Proc_0 in the Ada version */
+{
+ One_Fifty Int_1_Loc;
+ REG One_Fifty Int_2_Loc;
+ One_Fifty Int_3_Loc;
+ REG char Ch_Index;
+ Enumeration Enum_Loc;
+ Str_30 Str_1_Loc;
+ Str_30 Str_2_Loc;
+
+ /* Initializations */
+
+ Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+ Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
+
+ Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
+ Ptr_Glob->Discr = Ident_1;
+ Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
+ Ptr_Glob->variant.var_1.Int_Comp = 40;
+ strcpy (Ptr_Glob->variant.var_1.Str_Comp,
+ "DHRYSTONE PROGRAM, SOME STRING");
+ strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
+
+ Arr_2_Glob [8][7] = 10;
+ /* Was missing in published program. Without this statement, */
+ /* Arr_2_Glob [8][7] would have an undefined value. */
+ /* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
+ /* overflow may occur for this array element. */
+
+#ifdef PRATTLE
+ printf ("\n");
+ printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\n");
+ printf ("\n");
+ if (Reg)
+ {
+ printf ("Program compiled with 'register' attribute\n");
+ printf ("\n");
+ }
+ else
+ {
+ printf ("Program compiled without 'register' attribute\n");
+ printf ("\n");
+ }
+ printf ("Please give the number of runs through the benchmark: ");
+ {
+ int n;
+ scanf ("%d", &n);
+ Number_Of_Runs = n;
+ }
+ printf ("\n");
+
+ printf ("Execution starts, %d runs through Dhrystone\n", Number_Of_Runs);
+#endif /* PRATTLE */
+
+ Run_Index = 0;
+
+ /***************/
+ /* Start timer */
+ /***************/
+
+#ifdef SELF_TIMED
+#ifdef TIMES
+ times (&time_info);
+ Begin_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+ Begin_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+ for (Run_Index = 1; Run_Index < Number_Of_Runs; ++Run_Index)
+ {
+
+ Proc_5();
+ Proc_4();
+ /* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
+ Int_1_Loc = 2;
+ Int_2_Loc = 3;
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
+ Enum_Loc = Ident_2;
+ Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
+ /* Bool_Glob == 1 */
+ while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
+ {
+ Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
+ /* Int_3_Loc == 7 */
+ Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
+ /* Int_3_Loc == 7 */
+ Int_1_Loc += 1;
+ } /* while */
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
+ /* Int_Glob == 5 */
+ Proc_1 (Ptr_Glob);
+ for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
+ /* loop body executed twice */
+ {
+ if (Enum_Loc == Func_1 (Ch_Index, 'C'))
+ /* then, not executed */
+ {
+ Proc_6 (Ident_1, &Enum_Loc);
+ strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
+ Int_2_Loc = Run_Index;
+ Int_Glob = Run_Index;
+ }
+ }
+ /* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
+ Int_2_Loc = Int_2_Loc * Int_1_Loc;
+ Int_1_Loc = Int_2_Loc / Int_3_Loc;
+ Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
+ /* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
+ Proc_2 (&Int_1_Loc);
+ /* Int_1_Loc == 5 */
+
+ } /* loop "for Run_Index" */
+
+ /**************/
+ /* Stop timer */
+ /**************/
+#ifdef SELF_TIMED
+#ifdef TIMES
+ times (&time_info);
+ End_Time = (long) time_info.tms_utime;
+#endif
+#ifdef TIME
+ End_Time = time ( (long *) 0);
+#endif
+#endif /* SELF_TIMED */
+
+ /* BYTE version never executes this stuff */
+#ifdef SELF_TIMED
+ printf ("Execution ends\n");
+ printf ("\n");
+ printf ("Final values of the variables used in the benchmark:\n");
+ printf ("\n");
+ printf ("Int_Glob: %d\n", Int_Glob);
+ printf (" should be: %d\n", 5);
+ printf ("Bool_Glob: %d\n", Bool_Glob);
+ printf (" should be: %d\n", 1);
+ printf ("Ch_1_Glob: %c\n", Ch_1_Glob);
+ printf (" should be: %c\n", 'A');
+ printf ("Ch_2_Glob: %c\n", Ch_2_Glob);
+ printf (" should be: %c\n", 'B');
+ printf ("Arr_1_Glob[8]: %d\n", Arr_1_Glob[8]);
+ printf (" should be: %d\n", 7);
+ printf ("Arr_2_Glob[8][7]: %d\n", Arr_2_Glob[8][7]);
+ printf (" should be: Number_Of_Runs + 10\n");
+ printf ("Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent)\n");
+ printf (" Discr: %d\n", Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 2);
+ printf (" Int_Comp: %d\n", Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 17);
+ printf (" Str_Comp: %s\n", Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Next_Ptr_Glob->\n");
+ printf (" Ptr_Comp: %d\n", (int) Next_Ptr_Glob->Ptr_Comp);
+ printf (" should be: (implementation-dependent), same as above\n");
+ printf (" Discr: %d\n", Next_Ptr_Glob->Discr);
+ printf (" should be: %d\n", 0);
+ printf (" Enum_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
+ printf (" should be: %d\n", 1);
+ printf (" Int_Comp: %d\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
+ printf (" should be: %d\n", 18);
+ printf (" Str_Comp: %s\n",
+ Next_Ptr_Glob->variant.var_1.Str_Comp);
+ printf (" should be: DHRYSTONE PROGRAM, SOME STRING\n");
+ printf ("Int_1_Loc: %d\n", Int_1_Loc);
+ printf (" should be: %d\n", 5);
+ printf ("Int_2_Loc: %d\n", Int_2_Loc);
+ printf (" should be: %d\n", 13);
+ printf ("Int_3_Loc: %d\n", Int_3_Loc);
+ printf (" should be: %d\n", 7);
+ printf ("Enum_Loc: %d\n", Enum_Loc);
+ printf (" should be: %d\n", 1);
+ printf ("Str_1_Loc: %s\n", Str_1_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\n");
+ printf ("Str_2_Loc: %s\n", Str_2_Loc);
+ printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\n");
+ printf ("\n");
+
+ User_Time = End_Time - Begin_Time;
+
+ if (User_Time < Too_Small_Time)
+ {
+ printf ("Measured time too small to obtain meaningful results\n");
+ printf ("Please increase number of runs\n");
+ printf ("\n");
+ }
+ else
+ {
+#ifdef TIME
+ Microseconds = (float) User_Time * Mic_secs_Per_Second
+ / (float) Number_Of_Runs;
+ Dhrystones_Per_Second = (float) Number_Of_Runs / (float) User_Time;
+#else
+ Microseconds = (float) User_Time * Mic_secs_Per_Second
+ / ((float) HZ * ((float) Number_Of_Runs));
+ Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
+ / (float) User_Time;
+#endif
+ printf ("Microseconds for one run through Dhrystone: ");
+ printf ("%6.1f \n", Microseconds);
+ printf ("Dhrystones per Second: ");
+ printf ("%6.1f \n", Dhrystones_Per_Second);
+ printf ("\n");
+ }
+#endif /* SELF_TIMED */
+}
+
+
+void Proc_1 (REG Rec_Pointer Ptr_Val_Par)
+ /* executed once */
+{
+ REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
+ /* == Ptr_Glob_Next */
+ /* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
+ /* corresponds to "rename" in Ada, "with" in Pascal */
+
+ structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
+ Ptr_Val_Par->variant.var_1.Int_Comp = 5;
+ Next_Record->variant.var_1.Int_Comp
+ = Ptr_Val_Par->variant.var_1.Int_Comp;
+ Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
+ Proc_3 (&Next_Record->Ptr_Comp);
+ /* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
+ == Ptr_Glob->Ptr_Comp */
+ if (Next_Record->Discr == Ident_1)
+ /* then, executed */
+ {
+ Next_Record->variant.var_1.Int_Comp = 6;
+ Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
+ &Next_Record->variant.var_1.Enum_Comp);
+ Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
+ Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
+ &Next_Record->variant.var_1.Int_Comp);
+ }
+ else /* not executed */
+ structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
+} /* Proc_1 */
+
+
+void Proc_2 (One_Fifty *Int_Par_Ref)
+ /* executed once */
+ /* *Int_Par_Ref == 1, becomes 4 */
+{
+ One_Fifty Int_Loc;
+ Enumeration Enum_Loc;
+
+ Enum_Loc = 0;
+
+ Int_Loc = *Int_Par_Ref + 10;
+ do /* executed once */
+ if (Ch_1_Glob == 'A')
+ /* then, executed */
+ {
+ Int_Loc -= 1;
+ *Int_Par_Ref = Int_Loc - Int_Glob;
+ Enum_Loc = Ident_1;
+ } /* if */
+ while (Enum_Loc != Ident_1); /* true */
+} /* Proc_2 */
+
+
+void Proc_3 (Rec_Pointer *Ptr_Ref_Par)
+ /* executed once */
+ /* Ptr_Ref_Par becomes Ptr_Glob */
+{
+ if (Ptr_Glob != Null)
+ /* then, executed */
+ *Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
+ Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
+} /* Proc_3 */
+
+
+void Proc_4 (void) /* without parameters */
+ /* executed once */
+{
+ Boolean Bool_Loc;
+
+ Bool_Loc = Ch_1_Glob == 'A';
+ Bool_Glob = Bool_Loc | Bool_Glob;
+ Ch_2_Glob = 'B';
+} /* Proc_4 */
+
+void Proc_5 (void) /* without parameters */
+/*******/
+ /* executed once */
+{
+ Ch_1_Glob = 'A';
+ Bool_Glob = false;
+} /* Proc_5 */
+
+
+ /* Procedure for the assignment of structures, */
+ /* if the C compiler doesn't support this feature */
+#ifdef NOSTRUCTASSIGN
+memcpy (d, s, l)
+register char *d;
+register char *s;
+register int l;
+{
+ while (l--) *d++ = *s++;
+}
+#endif
--- /dev/null
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Dhrystone is widely available in the public domain. A GPL license is
+ * chosen for U-Boot.
+ */
+
+/*****************************************************************************
+ * The BYTE UNIX Benchmarks - Release 3
+ * Module: dhry_2.c SID: 3.4 5/15/91 19:30:22
+ *
+ *****************************************************************************
+ * Bug reports, patches, comments, suggestions should be sent to:
+ *
+ * Ben Smith, Rick Grehan or Tom Yager
+ * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com
+ *
+ *****************************************************************************
+ * Modification Log:
+ * 10/22/97 - code cleanup to remove ANSI C compiler warnings
+ * Andy Kahn <kahn@zk3.dec.com>
+ *
+ * Adapted from:
+ *
+ * "DHRYSTONE" Benchmark Program
+ * -----------------------------
+ *
+ * **** WARNING **** See warning in n.dhry_1.c
+ *
+ * Version: C, Version 2.1
+ *
+ * File: dhry_2.c (part 3 of 3)
+ *
+ * Date: May 25, 1988
+ *
+ * Author: Reinhold P. Weicker
+ *
+ ****************************************************************************/
+/* SCCSid is defined in dhry_1.c */
+
+#include <common.h>
+#include "dhry.h"
+
+#ifndef REG
+#define REG
+ /* REG becomes defined as empty */
+ /* i.e. no register variables */
+#endif
+
+extern int Int_Glob;
+extern char Ch_1_Glob;
+
+void Proc_6(Enumeration, Enumeration *);
+void Proc_7(One_Fifty, One_Fifty, One_Fifty *);
+void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int);
+Enumeration Func_1(Capital_Letter, Capital_Letter);
+Boolean Func_2(Str_30, Str_30);
+Boolean Func_3(Enumeration);
+
+void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par)
+ /* executed once */
+ /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
+{
+ *Enum_Ref_Par = Enum_Val_Par;
+ if (! Func_3 (Enum_Val_Par))
+ /* then, not executed */
+ *Enum_Ref_Par = Ident_4;
+ switch (Enum_Val_Par)
+ {
+ case Ident_1:
+ *Enum_Ref_Par = Ident_1;
+ break;
+ case Ident_2:
+ if (Int_Glob > 100)
+ /* then */
+ *Enum_Ref_Par = Ident_1;
+ else *Enum_Ref_Par = Ident_4;
+ break;
+ case Ident_3: /* executed */
+ *Enum_Ref_Par = Ident_2;
+ break;
+ case Ident_4: break;
+ case Ident_5:
+ *Enum_Ref_Par = Ident_3;
+ break;
+ } /* switch */
+} /* Proc_6 */
+
+void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
+One_Fifty Int_1_Par_Val;
+One_Fifty Int_2_Par_Val;
+One_Fifty *Int_Par_Ref;
+/**********************************************/
+ /* executed three times */
+ /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
+ /* Int_Par_Ref becomes 7 */
+ /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
+ /* Int_Par_Ref becomes 17 */
+ /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
+ /* Int_Par_Ref becomes 18 */
+{
+ One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 2;
+ *Int_Par_Ref = Int_2_Par_Val + Int_Loc;
+} /* Proc_7 */
+
+
+void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
+/*********************************************************************/
+ /* executed once */
+ /* Int_Par_Val_1 == 3 */
+ /* Int_Par_Val_2 == 7 */
+Arr_1_Dim Arr_1_Par_Ref;
+Arr_2_Dim Arr_2_Par_Ref;
+int Int_1_Par_Val;
+int Int_2_Par_Val;
+{
+ REG One_Fifty Int_Index;
+ REG One_Fifty Int_Loc;
+
+ Int_Loc = Int_1_Par_Val + 5;
+ Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
+ Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
+ Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
+ for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
+ Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
+ Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
+ Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
+ Int_Glob = 5;
+} /* Proc_8 */
+
+
+Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val)
+/*************************************************/
+ /* executed three times */
+ /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
+ /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
+ /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
+{
+ Capital_Letter Ch_1_Loc;
+ Capital_Letter Ch_2_Loc;
+
+ Ch_1_Loc = Ch_1_Par_Val;
+ Ch_2_Loc = Ch_1_Loc;
+ if (Ch_2_Loc != Ch_2_Par_Val)
+ /* then, executed */
+ return (Ident_1);
+ else /* not executed */
+ {
+ Ch_1_Glob = Ch_1_Loc;
+ return (Ident_2);
+ }
+} /* Func_1 */
+
+
+
+Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
+/*************************************************/
+ /* executed once */
+ /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
+ /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
+
+Str_30 Str_1_Par_Ref;
+Str_30 Str_2_Par_Ref;
+{
+ REG One_Thirty Int_Loc;
+ Capital_Letter Ch_Loc;
+
+ Ch_Loc = 'A';
+ Int_Loc = 2;
+ while (Int_Loc <= 2) /* loop body executed once */
+ if (Func_1 (Str_1_Par_Ref[Int_Loc],
+ Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
+ /* then, executed */
+ {
+ Ch_Loc = 'A';
+ Int_Loc += 1;
+ } /* if, while */
+ if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
+ /* then, not executed */
+ Int_Loc = 7;
+ if (Ch_Loc == 'R')
+ /* then, not executed */
+ return (true);
+ else /* executed */
+ {
+ if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
+ /* then, not executed */
+ {
+ Int_Loc += 7;
+ Int_Glob = Int_Loc;
+ return (true);
+ }
+ else /* executed */
+ return (false);
+ } /* if Ch_Loc */
+} /* Func_2 */
+
+
+Boolean Func_3 (Enum_Par_Val)
+/***************************/
+ /* executed once */
+ /* Enum_Par_Val == Ident_3 */
+Enumeration Enum_Par_Val;
+{
+ Enumeration Enum_Loc;
+
+ Enum_Loc = Enum_Par_Val;
+ if (Enum_Loc == Ident_3)
+ /* then, executed */
+ return (true);
+ else /* not executed */
+ return (false);
+} /* Func_3 */
COMPAT(NVIDIA_TEGRA124_SOR, "nvidia,tegra124-sor"),
COMPAT(NVIDIA_TEGRA124_PMC, "nvidia,tegra124-pmc"),
COMPAT(NVIDIA_TEGRA20_DC, "nvidia,tegra20-dc"),
+ COMPAT(NVIDIA_TEGRA210_SDMMC, "nvidia,tegra210-sdhci"),
COMPAT(NVIDIA_TEGRA124_SDMMC, "nvidia,tegra124-sdhci"),
COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"),
COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
COMPAT(NVIDIA_TEGRA30_PCIE, "nvidia,tegra30-pcie"),
COMPAT(NVIDIA_TEGRA20_PCIE, "nvidia,tegra20-pcie"),
COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"),
+ COMPAT(NVIDIA_TEGRA210_XUSB_PADCTL, "nvidia,tegra210-xusb-padctl"),
COMPAT(SMSC_LAN9215, "smsc,lan9215"),
COMPAT(SAMSUNG_EXYNOS5_SROMC, "samsung,exynos-sromc"),
COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
const char *prop_name, fdt_size_t *sizep)
{
- const fdt_addr_t *cell;
- int len;
+ const fdt32_t *ptr, *end;
+ int parent, na, ns, len;
+ fdt_addr_t addr;
debug("%s: %s: ", __func__, prop_name);
- cell = fdt_getprop(blob, node, prop_name, &len);
- if (cell && ((!sizep && len == sizeof(fdt_addr_t)) ||
- len == sizeof(fdt_addr_t) * 2)) {
- fdt_addr_t addr = fdt_addr_to_cpu(*cell);
- if (sizep) {
- const fdt_size_t *size;
-
- size = (fdt_size_t *)((char *)cell +
- sizeof(fdt_addr_t));
- *sizep = fdt_size_to_cpu(*size);
- debug("addr=%08lx, size=%08x\n",
- (ulong)addr, *sizep);
- } else {
- debug("%08lx\n", (ulong)addr);
- }
- return addr;
+
+ parent = fdt_parent_offset(blob, node);
+ if (parent < 0) {
+ debug("(no parent found)\n");
+ return FDT_ADDR_T_NONE;
}
- debug("(not found)\n");
- return FDT_ADDR_T_NONE;
+
+ na = fdt_address_cells(blob, parent);
+ ns = fdt_size_cells(blob, parent);
+
+ ptr = fdt_getprop(blob, node, prop_name, &len);
+ if (!ptr) {
+ debug("(not found)\n");
+ return FDT_ADDR_T_NONE;
+ }
+
+ end = ptr + len / sizeof(*ptr);
+
+ if (ptr + na + ns > end) {
+ debug("(not enough data: expected %d bytes, got %d bytes)\n",
+ (na + ns) * 4, len);
+ return FDT_ADDR_T_NONE;
+ }
+
+ addr = fdtdec_get_number(ptr, na);
+
+ if (sizep) {
+ *sizep = fdtdec_get_number(ptr + na, ns);
+ debug("addr=%pa, size=%pa\n", &addr, sizep);
+ } else {
+ debug("%pa\n", &addr);
+ }
+
+ return addr;
}
fdt_addr_t fdtdec_get_addr(const void *blob, int node,
const char *prop;
const char *name;
const char *slash;
- const char *p;
- int len;
+ int len, val;
prop = fdt_getprop_by_offset(blob, prop_offset, &name, &len);
debug(" - %s, %s\n", name, prop);
slash = strrchr(prop, '/');
if (strcmp(slash + 1, find_name))
continue;
- for (p = name + strlen(name) - 1; p > name; p--) {
- if (!isdigit(*p)) {
- *seqp = simple_strtoul(p + 1, NULL, 10);
- debug("Found seq %d\n", *seqp);
- return 0;
- }
+ val = trailing_strtol(name);
+ if (val != -1) {
+ *seqp = val;
+ debug("Found seq %d\n", *seqp);
+ return 0;
}
}
puts("Missing DTB\n");
#else
puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
+# ifdef DEBUG
+ if (gd->fdt_blob) {
+ printf("fdt_blob=%p\n", gd->fdt_blob);
+ print_buffer((ulong)gd->fdt_blob, gd->fdt_blob, 4,
+ 32, 0);
+ }
+# endif
#endif
return -1;
}
#
obj-y += fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_sw.o fdt_wip.o \
- fdt_empty_tree.o fdt_addresses.o
+ fdt_empty_tree.o fdt_addresses.o fdt_region.o
--- /dev/null
+/*
+ * libfdt - Flat Device Tree manipulation
+ * Copyright (C) 2013 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ * SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
+ */
+
+#include "libfdt_env.h"
+
+#ifndef USE_HOSTCC
+#include <fdt.h>
+#include <libfdt.h>
+#else
+#include "fdt_host.h"
+#endif
+
+#include "libfdt_internal.h"
+
+/**
+ * fdt_add_region() - Add a new region to our list
+ *
+ * The region is added if there is space, but in any case we increment the
+ * count. If permitted, and the new region overlaps the last one, we merge
+ * them.
+ *
+ * @info: State information
+ * @offset: Start offset of region
+ * @size: Size of region
+ */
+static int fdt_add_region(struct fdt_region_state *info, int offset, int size)
+{
+ struct fdt_region *reg;
+
+ reg = info->region ? &info->region[info->count - 1] : NULL;
+ if (info->can_merge && info->count &&
+ info->count <= info->max_regions &&
+ reg && offset <= reg->offset + reg->size) {
+ reg->size = offset + size - reg->offset;
+ } else if (info->count++ < info->max_regions) {
+ if (reg) {
+ reg++;
+ reg->offset = offset;
+ reg->size = size;
+ }
+ } else {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int region_list_contains_offset(struct fdt_region_state *info,
+ const void *fdt, int target)
+{
+ struct fdt_region *reg;
+ int num;
+
+ target += fdt_off_dt_struct(fdt);
+ for (reg = info->region, num = 0; num < info->count; reg++, num++) {
+ if (target >= reg->offset && target < reg->offset + reg->size)
+ return 1;
+ }
+
+ return 0;
+}
+
+int fdt_add_alias_regions(const void *fdt, struct fdt_region *region, int count,
+ int max_regions, struct fdt_region_state *info)
+{
+ int base = fdt_off_dt_struct(fdt);
+ int node, node_end, offset;
+ int did_alias_header;
+
+ node = fdt_subnode_offset(fdt, 0, "aliases");
+ if (node < 0)
+ return -FDT_ERR_NOTFOUND;
+
+ /* The aliases node must come before the others */
+ node_end = fdt_next_subnode(fdt, node);
+ if (node_end <= 0)
+ return -FDT_ERR_BADLAYOUT;
+ node_end -= sizeof(fdt32_t);
+
+ did_alias_header = 0;
+ info->region = region;
+ info->count = count;
+ info->can_merge = 0;
+ info->max_regions = max_regions;
+
+ for (offset = fdt_first_property_offset(fdt, node);
+ offset >= 0;
+ offset = fdt_next_property_offset(fdt, offset)) {
+ const struct fdt_property *prop;
+ const char *name;
+ int target, next;
+
+ prop = fdt_get_property_by_offset(fdt, offset, NULL);
+ name = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ target = fdt_path_offset(fdt, name);
+ if (!region_list_contains_offset(info, fdt, target))
+ continue;
+ next = fdt_next_property_offset(fdt, offset);
+ if (next < 0)
+ next = node_end - sizeof(fdt32_t);
+
+ if (!did_alias_header) {
+ fdt_add_region(info, base + node, 12);
+ did_alias_header = 1;
+ }
+ fdt_add_region(info, base + offset, next - offset);
+ }
+
+ /* Add the 'end' tag */
+ if (did_alias_header)
+ fdt_add_region(info, base + node_end, sizeof(fdt32_t));
+
+ return info->count < max_regions ? info->count : -FDT_ERR_NOSPACE;
+}
+
+/**
+ * fdt_include_supernodes() - Include supernodes required by this node
+ *
+ * When we decided to include a node or property which is not at the top
+ * level, this function forces the inclusion of higher level nodes. For
+ * example, given this tree:
+ *
+ * / {
+ * testing {
+ * }
+ * }
+ *
+ * If we decide to include testing then we need the root node to have a valid
+ * tree. This function adds those regions.
+ *
+ * @info: State information
+ * @depth: Current stack depth
+ */
+static int fdt_include_supernodes(struct fdt_region_state *info, int depth)
+{
+ int base = fdt_off_dt_struct(info->fdt);
+ int start, stop_at;
+ int i;
+
+ /*
+ * Work down the stack looking for supernodes that we didn't include.
+ * The algortihm here is actually pretty simple, since we know that
+ * no previous subnode had to include these nodes, or if it did, we
+ * marked them as included (on the stack) already.
+ */
+ for (i = 0; i <= depth; i++) {
+ if (!info->stack[i].included) {
+ start = info->stack[i].offset;
+
+ /* Add the FDT_BEGIN_NODE tag of this supernode */
+ fdt_next_tag(info->fdt, start, &stop_at);
+ if (fdt_add_region(info, base + start, stop_at - start))
+ return -1;
+
+ /* Remember that this supernode is now included */
+ info->stack[i].included = 1;
+ info->can_merge = 1;
+ }
+
+ /* Force (later) generation of the FDT_END_NODE tag */
+ if (!info->stack[i].want)
+ info->stack[i].want = WANT_NODES_ONLY;
+ }
+
+ return 0;
+}
+
+enum {
+ FDT_DONE_NOTHING,
+ FDT_DONE_MEM_RSVMAP,
+ FDT_DONE_STRUCT,
+ FDT_DONE_END,
+ FDT_DONE_STRINGS,
+ FDT_DONE_ALL,
+};
+
+int fdt_first_region(const void *fdt,
+ int (*h_include)(void *priv, const void *fdt, int offset,
+ int type, const char *data, int size),
+ void *priv, struct fdt_region *region,
+ char *path, int path_len, int flags,
+ struct fdt_region_state *info)
+{
+ struct fdt_region_ptrs *p = &info->ptrs;
+
+ /* Set up our state */
+ info->fdt = fdt;
+ info->can_merge = 1;
+ info->max_regions = 1;
+ info->start = -1;
+ p->want = WANT_NOTHING;
+ p->end = path;
+ *p->end = '\0';
+ p->nextoffset = 0;
+ p->depth = -1;
+ p->done = FDT_DONE_NOTHING;
+
+ return fdt_next_region(fdt, h_include, priv, region,
+ path, path_len, flags, info);
+}
+
+/*
+ * Theory of operation
+ *
+ *
+ *
+
+Note: in this description 'included' means that a node (or other part of
+the tree) should be included in the region list, i.e. it will have a region
+which covers its part of the tree.
+
+This function maintains some state from the last time it is called. It
+checks the next part of the tree that it is supposed to look at
+(p.nextoffset) to see if that should be included or not. When it finds
+something to include, it sets info->start to its offset. This marks the
+start of the region we want to include.
+
+Once info->start is set to the start (i.e. not -1), we continue scanning
+until we find something that we don't want included. This will be the end
+of a region. At this point we can close off the region and add it to the
+list. So we do so, and reset info->start to -1.
+
+One complication here is that we want to merge regions. So when we come to
+add another region later, we may in fact merge it with the previous one if
+one ends where the other starts.
+
+The function fdt_add_region() will return -1 if it fails to add the region,
+because we already have a region ready to be returned, and the new one
+cannot be merged in with it. In this case, we must return the region we
+found, and wait for another call to this function. When it comes, we will
+repeat the processing of the tag and again try to add a region. This time it
+will succeed.
+
+The current state of the pointers (stack, offset, etc.) is maintained in
+a ptrs member. At the start of every loop iteration we make a copy of it.
+The copy is then updated as the tag is processed. Only if we get to the end
+of the loop iteration (and successfully call fdt_add_region() if we need
+to) can we commit the changes we have made to these pointers. For example,
+if we see an FDT_END_NODE tag we will decrement the depth value. But if we
+need to add a region for this tag (let's say because the previous tag is
+included and this FDT_END_NODE tag is not included) then we will only commit
+the result if we were able to add the region. That allows us to retry again
+next time.
+
+We keep track of a variable called 'want' which tells us what we want to
+include when there is no specific information provided by the h_include
+function for a particular property. This basically handles the inclusion of
+properties which are pulled in by virtue of the node they are in. So if you
+include a node, its properties are also included. In this case 'want' will
+be WANT_NODES_AND_PROPS. The FDT_REG_DIRECT_SUBNODES feature also makes use
+of 'want'. While we are inside the subnode, 'want' will be set to
+WANT_NODES_ONLY, so that only the subnode's FDT_BEGIN_NODE and FDT_END_NODE
+tags will be included, and properties will be skipped. If WANT_NOTHING is
+selected, then we will just rely on what the h_include() function tells us.
+
+Using 'want' we work out 'include', which tells us whether this current tag
+should be included or not. As you can imagine, if the value of 'include'
+changes, that means we are on a boundary between nodes to include and nodes
+to exclude. At this point we either close off a previous region and add it
+to the list, or mark the start of a new region.
+
+Apart from the nodes, we have mem_rsvmap, the FDT_END tag and the string
+list. Each of these dealt with as a whole (i.e. we create a region for each
+if it is to be included). For mem_rsvmap we don't allow it to merge with
+the first struct region. For the stringlist we don't allow it to merge with
+the last struct region (which contains at minimum the FDT_END tag).
+*/
+int fdt_next_region(const void *fdt,
+ int (*h_include)(void *priv, const void *fdt, int offset,
+ int type, const char *data, int size),
+ void *priv, struct fdt_region *region,
+ char *path, int path_len, int flags,
+ struct fdt_region_state *info)
+{
+ int base = fdt_off_dt_struct(fdt);
+ int last_node = 0;
+ const char *str;
+
+ info->region = region;
+ info->count = 0;
+ if (info->ptrs.done < FDT_DONE_MEM_RSVMAP &&
+ (flags & FDT_REG_ADD_MEM_RSVMAP)) {
+ /* Add the memory reserve map into its own region */
+ if (fdt_add_region(info, fdt_off_mem_rsvmap(fdt),
+ fdt_off_dt_struct(fdt) -
+ fdt_off_mem_rsvmap(fdt)))
+ return 0;
+ info->can_merge = 0; /* Don't allow merging with this */
+ info->ptrs.done = FDT_DONE_MEM_RSVMAP;
+ }
+
+ /*
+ * Work through the tags one by one, deciding whether each needs to
+ * be included or not. We set the variable 'include' to indicate our
+ * decision. 'want' is used to track what we want to include - it
+ * allows us to pick up all the properties (and/or subnode tags) of
+ * a node.
+ */
+ while (info->ptrs.done < FDT_DONE_STRUCT) {
+ const struct fdt_property *prop;
+ struct fdt_region_ptrs p;
+ const char *name;
+ int include = 0;
+ int stop_at = 0;
+ uint32_t tag;
+ int offset;
+ int val;
+ int len;
+
+ /*
+ * Make a copy of our pointers. If we make it to the end of
+ * this block then we will commit them back to info->ptrs.
+ * Otherwise we can try again from the same starting state
+ * next time we are called.
+ */
+ p = info->ptrs;
+
+ /*
+ * Find the tag, and the offset of the next one. If we need to
+ * stop including tags, then by default we stop *after*
+ * including the current tag
+ */
+ offset = p.nextoffset;
+ tag = fdt_next_tag(fdt, offset, &p.nextoffset);
+ stop_at = p.nextoffset;
+
+ switch (tag) {
+ case FDT_PROP:
+ stop_at = offset;
+ prop = fdt_get_property_by_offset(fdt, offset, NULL);
+ str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ val = h_include(priv, fdt, last_node, FDT_IS_PROP, str,
+ strlen(str) + 1);
+ if (val == -1) {
+ include = p.want >= WANT_NODES_AND_PROPS;
+ } else {
+ include = val;
+ /*
+ * Make sure we include the } for this block.
+ * It might be more correct to have this done
+ * by the call to fdt_include_supernodes() in
+ * the case where it adds the node we are
+ * currently in, but this is equivalent.
+ */
+ if ((flags & FDT_REG_SUPERNODES) && val &&
+ !p.want)
+ p.want = WANT_NODES_ONLY;
+ }
+
+ /* Value grepping is not yet supported */
+ break;
+
+ case FDT_NOP:
+ include = p.want >= WANT_NODES_AND_PROPS;
+ stop_at = offset;
+ break;
+
+ case FDT_BEGIN_NODE:
+ last_node = offset;
+ p.depth++;
+ if (p.depth == FDT_MAX_DEPTH)
+ return -FDT_ERR_TOODEEP;
+ name = fdt_get_name(fdt, offset, &len);
+ if (p.end - path + 2 + len >= path_len)
+ return -FDT_ERR_NOSPACE;
+
+ /* Build the full path of this node */
+ if (p.end != path + 1)
+ *p.end++ = '/';
+ strcpy(p.end, name);
+ p.end += len;
+ info->stack[p.depth].want = p.want;
+ info->stack[p.depth].offset = offset;
+
+ /*
+ * If we are not intending to include this node unless
+ * it matches, make sure we stop *before* its tag.
+ */
+ if (p.want == WANT_NODES_ONLY ||
+ !(flags & (FDT_REG_DIRECT_SUBNODES |
+ FDT_REG_ALL_SUBNODES))) {
+ stop_at = offset;
+ p.want = WANT_NOTHING;
+ }
+ val = h_include(priv, fdt, offset, FDT_IS_NODE, path,
+ p.end - path + 1);
+
+ /* Include this if requested */
+ if (val) {
+ p.want = (flags & FDT_REG_ALL_SUBNODES) ?
+ WANT_ALL_NODES_AND_PROPS :
+ WANT_NODES_AND_PROPS;
+ }
+
+ /* If not requested, decay our 'p.want' value */
+ else if (p.want) {
+ if (p.want != WANT_ALL_NODES_AND_PROPS)
+ p.want--;
+
+ /* Not including this tag, so stop now */
+ } else {
+ stop_at = offset;
+ }
+
+ /*
+ * Decide whether to include this tag, and update our
+ * stack with the state for this node
+ */
+ include = p.want;
+ info->stack[p.depth].included = include;
+ break;
+
+ case FDT_END_NODE:
+ include = p.want;
+ if (p.depth < 0)
+ return -FDT_ERR_BADSTRUCTURE;
+
+ /*
+ * If we don't want this node, stop right away, unless
+ * we are including subnodes
+ */
+ if (!p.want && !(flags & FDT_REG_DIRECT_SUBNODES))
+ stop_at = offset;
+ p.want = info->stack[p.depth].want;
+ p.depth--;
+ while (p.end > path && *--p.end != '/')
+ ;
+ *p.end = '\0';
+ break;
+
+ case FDT_END:
+ /* We always include the end tag */
+ include = 1;
+ p.done = FDT_DONE_STRUCT;
+ break;
+ }
+
+ /* If this tag is to be included, mark it as region start */
+ if (include && info->start == -1) {
+ /* Include any supernodes required by this one */
+ if (flags & FDT_REG_SUPERNODES) {
+ if (fdt_include_supernodes(info, p.depth))
+ return 0;
+ }
+ info->start = offset;
+ }
+
+ /*
+ * If this tag is not to be included, finish up the current
+ * region.
+ */
+ if (!include && info->start != -1) {
+ if (fdt_add_region(info, base + info->start,
+ stop_at - info->start))
+ return 0;
+ info->start = -1;
+ info->can_merge = 1;
+ }
+
+ /* If we have made it this far, we can commit our pointers */
+ info->ptrs = p;
+ }
+
+ /* Add a region for the END tag and a separate one for string table */
+ if (info->ptrs.done < FDT_DONE_END) {
+ if (info->ptrs.nextoffset != fdt_size_dt_struct(fdt))
+ return -FDT_ERR_BADSTRUCTURE;
+
+ if (fdt_add_region(info, base + info->start,
+ info->ptrs.nextoffset - info->start))
+ return 0;
+ info->ptrs.done++;
+ }
+ if (info->ptrs.done < FDT_DONE_STRINGS) {
+ if (flags & FDT_REG_ADD_STRING_TAB) {
+ info->can_merge = 0;
+ if (fdt_off_dt_strings(fdt) <
+ base + info->ptrs.nextoffset)
+ return -FDT_ERR_BADLAYOUT;
+ if (fdt_add_region(info, fdt_off_dt_strings(fdt),
+ fdt_size_dt_strings(fdt)))
+ return 0;
+ }
+ info->ptrs.done++;
+ }
+
+ return info->count > 0 ? 0 : -FDT_ERR_NOTFOUND;
+}
list = fdt_getprop(fdt, node, property, &length);
if (!list)
- return -length;
+ return length;
for (i = 0; i < length; i++) {
int len = strlen(list);
index--;
}
- return FDT_ERR_NOTFOUND;
+ return -FDT_ERR_NOTFOUND;
}
int fdt_get_string(const void *fdt, int node, const char *property,
return 0;
}
+
+int fdt_remove_unused_strings(const void *old, void *new)
+{
+ const struct fdt_property *old_prop;
+ struct fdt_property *new_prop;
+ int size = fdt_totalsize(old);
+ int next_offset, offset;
+ const char *str;
+ int ret;
+ int tag = FDT_PROP;
+
+ /* Make a copy and remove the strings */
+ memcpy(new, old, size);
+ fdt_set_size_dt_strings(new, 0);
+
+ /* Add every property name back into the new string table */
+ for (offset = 0; tag != FDT_END; offset = next_offset) {
+ tag = fdt_next_tag(old, offset, &next_offset);
+ if (tag != FDT_PROP)
+ continue;
+ old_prop = fdt_get_property_by_offset(old, offset, NULL);
+ new_prop = (struct fdt_property *)(unsigned long)
+ fdt_get_property_by_offset(new, offset, NULL);
+ str = fdt_string(old, fdt32_to_cpu(old_prop->nameoff));
+ ret = _fdt_find_add_string(new, str);
+ if (ret < 0)
+ return ret;
+ new_prop->nameoff = cpu_to_fdt32(ret);
+ }
+
+ return 0;
+}
void *kmalloc(size_t size, int flags)
{
- return memalign(ARCH_DMA_MINALIGN, size);
-}
+ void *p;
-void *kzalloc(size_t size, int flags)
-{
- void *ptr = kmalloc(size, flags);
- memset(ptr, 0, size);
- return ptr;
-}
+ p = memalign(ARCH_DMA_MINALIGN, size);
+ if (flags & __GFP_ZERO)
+ memset(p, 0, size);
-void *vzalloc(unsigned long size)
-{
- return kzalloc(size, 0);
+ return p;
}
struct kmem_cache *get_mem(int element_sz)
--- /dev/null
+/*
+ * (C) Copyright 2015 Google, Inc
+ *
+ * (C) Copyright 2008-2014 Rockchip Electronics
+ *
+ * Rivest Cipher 4 (RC4) implementation
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef USE_HOSTCC
+#include <common.h>
+#endif
+#include <rc4.h>
+
+void rc4_encode(unsigned char *buf, unsigned int len, unsigned char key[16])
+{
+ unsigned char s[256], k[256], temp;
+ unsigned short i, j, t;
+ int ptr;
+
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ s[i] = (unsigned char)i;
+ j &= 0x0f;
+ k[i] = key[j];
+ j++;
+ }
+
+ j = 0;
+ for (i = 0; i < 256; i++) {
+ j = (j + s[i] + k[i]) % 256;
+ temp = s[i];
+ s[i] = s[j];
+ s[j] = temp;
+ }
+
+ i = 0;
+ j = 0;
+ for (ptr = 0; ptr < len; ptr++) {
+ i = (i + 1) % 256;
+ j = (j + s[i]) % 256;
+ temp = s[i];
+ s[i] = s[j];
+ s[j] = temp;
+ t = (s[i] + (s[j] % 256)) % 256;
+ buf[ptr] = buf[ptr] ^ s[t];
+ }
+}
return result;
}
+long trailing_strtoln(const char *str, const char *end)
+{
+ const char *p;
+
+ if (!end)
+ end = str + strlen(str);
+ for (p = end - 1; p > str; p--) {
+ if (!isdigit(*p))
+ return simple_strtoul(p + 1, NULL, 10);
+ }
+
+ return -1;
+}
+
+long trailing_strtol(const char *str)
+{
+ return trailing_strtoln(str, NULL);
+}
+
/* we use this so that we can do without the ctype library */
#define is_digit(c) ((c) >= '0' && (c) <= '9')
return -EINVAL;
}
+ /*
+ * Drivers are allowed to decide not to implement this at
+ * run-time. E.g. Some devices may use it and some may not.
+ */
ret = eth_get_ops(dev)->write_hwaddr(dev);
+ if (ret == -ENOSYS)
+ ret = 0;
if (ret)
printf("\nWarning: %s failed to set MAC address\n",
dev->name);
{
struct udevice *current;
uchar *packet;
+ int flags;
int ret;
int i;
return -EINVAL;
/* Process up to 32 packets at one time */
+ flags = ETH_RECV_CHECK_DEVICE;
for (i = 0; i < 32; i++) {
- ret = eth_get_ops(current)->recv(current, &packet);
+ ret = eth_get_ops(current)->recv(current, flags, &packet);
+ flags = 0;
if (ret > 0)
net_process_received_packet(packet, ret);
if (ret >= 0 && eth_get_ops(current)->free_pkt)
$(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1)))
# cc-version
-# Usage gcc-ver := $(call cc-version)
cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC))
# cc-fullversion
-# Usage gcc-ver := $(call cc-fullversion)
cc-fullversion = $(shell $(CONFIG_SHELL) \
$(srctree)/scripts/gcc-version.sh -p $(CC))
# cc-ifversion
# Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1)
-cc-ifversion = $(shell [ $(call cc-version, $(CC)) $(1) $(2) ] && echo $(3))
+cc-ifversion = $(shell [ $(cc-version) $(1) $(2) ] && echo $(3) || echo $(4))
# added for U-Boot
binutils-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/binutils-version.sh $(AS))
ar-option = $(call try-run, $(AR) rc$(1) "$$TMP",$(1),$(2))
# ld-version
-# Usage: $(call ld-version)
# Note this is mainly for HJ Lu's 3 number binutil versions
ld-version = $(shell $(LD) --version | $(srctree)/scripts/ld-version.sh)
# ld-ifversion
# Usage: $(call ld-ifversion, -ge, 22252, y)
-ld-ifversion = $(shell [ $(call ld-version) $(1) $(2) ] && echo $(3))
+ld-ifversion = $(shell [ $(ld-version) $(1) $(2) ] && echo $(3) || echo $(4))
######
# $(Q)$(MAKE) $(modbuiltin)=dir
modbuiltin := -f $(srctree)/scripts/Makefile.modbuiltin obj
+###
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj=
+# Usage:
+# $(Q)$(MAKE) $(dtbinst)=dir
+dtbinst := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.dtbinst obj
+
+###
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=
+# Usage:
+# $(Q)$(MAKE) $(clean)=dir
+clean := -f $(srctree)/scripts/Makefile.clean obj
+
+###
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.headersinst obj=
+# Usage:
+# $(Q)$(MAKE) $(hdr-inst)=dir
+hdr-inst := -f $(srctree)/scripts/Makefile.headersinst obj
+
# Prefix -I with $(srctree) if it is not an absolute path.
# skip if -I has no parameter
addtree = $(if $(patsubst -I%,%,$(1)), \
# Otherwise, create a symbolic link to arch/$(ARCH)/include/asm/arch-$(SOC).
PHONY += create_symlink
create_symlink:
+ifdef CONFIG_CREATE_ARCH_SYMLINK
ifneq ($(KBUILD_SRC),)
$(Q)mkdir -p include/asm
$(Q)if [ -d $(KBUILD_SRC)/arch/$(ARCH)/mach-$(SOC)/include/mach ]; then \
fi; \
ln -fsn $$dest arch/$(ARCH)/include/asm/arch
endif
+endif
PHONY += FORCE
FORCE:
"$(if $(part-of-module),1,0)" "$(@)";
recordmcount_source := $(srctree)/scripts/recordmcount.pl
endif
-cmd_record_mcount = \
- if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \
+cmd_record_mcount = \
+ if [ "$(findstring $(CC_FLAGS_FTRACE),$(_c_flags))" = \
+ "$(CC_FLAGS_FTRACE)" ]; then \
$(sub_cmd_record_mcount) \
fi;
endif
PHONY := __clean
__clean:
-# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
-# Usage:
-# $(Q)$(MAKE) $(clean)=dir
-clean := -f $(srctree)/scripts/Makefile.clean obj
+include scripts/Kbuild.include
# The filename Kbuild has precedence over Makefile
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
__clean-files := $(filter-out $(no-clean-files), $(__clean-files))
-# as clean-files is given relative to the current directory, this adds
-# a $(obj) prefix, except for absolute paths
+# clean-files is given relative to the current directory, unless it
+# starts with $(objtree)/ (which means "./", so do not add "./" unless
+# you want to delete a file from the toplevel object directory).
__clean-files := $(wildcard \
- $(addprefix $(obj)/, $(filter-out /%, $(__clean-files))) \
- $(filter /%, $(__clean-files)))
+ $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \
+ $(filter $(objtree)/%, $(__clean-files)))
-# as clean-dirs is given relative to the current directory, this adds
-# a $(obj) prefix, except for absolute paths
+# same as clean-files
__clean-dirs := $(wildcard \
- $(addprefix $(obj)/, $(filter-out /%, $(clean-dirs))) \
- $(filter /%, $(clean-dirs)))
+ $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(clean-dirs))) \
+ $(filter $(objtree)/%, $(clean-dirs)))
# ==========================================================================
endif
ifneq ($(strip $(__clean-dirs)),)
+$(call cmd,cleandir)
-endif
-ifneq ($(strip $(clean-rule)),)
- +$(clean-rule)
endif
@:
$(subdir-ymn):
$(Q)$(MAKE) $(clean)=$@
-# If quiet is set, only print short version of command
-
-cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1))
-
-
# Declare the contents of the .PHONY variable as phony. We keep that
# information in a variable se we can use it in if_changed and friends.
$(CFLAGS_GCOV))
endif
+#
+# Enable address sanitizer flags for kernel except some files or directories
+# we don't want to check (depends on variables KASAN_SANITIZE_obj.o, KASAN_SANITIZE)
+#
+ifeq ($(CONFIG_KASAN),y)
+_c_flags += $(if $(patsubst n%,, \
+ $(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \
+ $(CFLAGS_KASAN))
+endif
+
# If building the kernel in a separate objtree expand all occurrences
# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
quiet_cmd_dtc = DTC $@
# Modified for U-Boot
-cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
+cmd_dtc = mkdir -p $(dir ${dtc-tmp}) ; \
+ $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
$(DTC) -O dtb -o $@ -b 0 \
-i $(dir $<) $(DTC_FLAGS) \
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
-# Helper targets for Installing DTBs into the boot directory
-quiet_cmd_dtb_install = INSTALL $<
- cmd_dtb_install = cp $< $(2)
-
-_dtbinst_pre_:
- $(Q)if [ -d $(INSTALL_DTBS_PATH).old ]; then rm -rf $(INSTALL_DTBS_PATH).old; fi
- $(Q)if [ -d $(INSTALL_DTBS_PATH) ]; then mv $(INSTALL_DTBS_PATH) $(INSTALL_DTBS_PATH).old; fi
- $(Q)mkdir -p $(INSTALL_DTBS_PATH)
-
-%.dtb_dtbinst_: $(obj)/%.dtb _dtbinst_pre_
- $(call cmd,dtb_install,$(INSTALL_DTBS_PATH))
-
# Bzip2
# ---------------------------------------------------------------------------
libs-$(CONFIG_SPL_FRAMEWORK) += common/spl/
libs-$(CONFIG_SPL_LIBCOMMON_SUPPORT) += common/
libs-$(CONFIG_SPL_LIBDISK_SUPPORT) += disk/
+libs-$(CONFIG_SPL_CLK_SUPPORT) += drivers/clk/
libs-$(CONFIG_SPL_DM) += drivers/core/
libs-$(CONFIG_SPL_I2C_SUPPORT) += drivers/i2c/
libs-$(CONFIG_SPL_GPIO_SUPPORT) += drivers/gpio/
libs-$(CONFIG_SPL_MMC_SUPPORT) += drivers/mmc/
libs-$(CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT) += drivers/ddr/fsl/
-libs-$(CONFIG_SYS_MVEBU_DDR) += drivers/ddr/mvebu/
+libs-$(CONFIG_SYS_MVEBU_DDR_A38X) += drivers/ddr/marvell/a38x/
+libs-$(CONFIG_SYS_MVEBU_DDR_AXP) += drivers/ddr/marvell/axp/
libs-$(CONFIG_SPL_SERIAL_SUPPORT) += drivers/serial/
libs-$(CONFIG_SPL_SPI_FLASH_SUPPORT) += drivers/mtd/spi/
libs-$(CONFIG_SPL_SPI_SUPPORT) += drivers/spi/
libs-y += fs/
+libs-$(CONFIG_SPL_LED_SUPPORT) += drivers/led/
libs-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/
libs-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/ drivers/power/pmic/
+libs-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/regulator/
libs-$(CONFIG_SPL_MTD_SUPPORT) += drivers/mtd/
libs-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/
libs-$(CONFIG_SPL_DRIVERS_MISC_SUPPORT) += drivers/misc/
libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/
libs-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/
libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/net/phy/
+libs-$(CONFIG_SPL_RAM_SUPPORT) += drivers/ram/
libs-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/
libs-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/
libs-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/
ALL-y += $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN).cfg
+ALL-$(CONFIG_OF_SEPARATE) += $(obj)/$(SPL_BIN)-pad.bin $(obj)/$(SPL_BIN)-dtb.bin
+
ifdef CONFIG_SAMSUNG
ALL-y += $(obj)/$(BOARD)-spl.bin
endif
all: $(ALL-y)
+quiet_cmd_cat = CAT $@
+cmd_cat = cat $(filter-out $(PHONY), $^) > $@
+
+$(obj)/$(SPL_BIN)-dtb.bin: $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN)-pad.bin \
+ $(obj)/$(SPL_BIN).dtb FORCE
+ $(call if_changed,cat)
+
+# Create a file that pads from the end of u-boot-spl.bin to bss_end
+$(obj)/$(SPL_BIN)-pad.bin: $(obj)/$(SPL_BIN)
+ @bss_size_str=$(shell $(NM) $< | awk 'BEGIN {size = 0} /__bss_size/ {size = $$1} END {print "ibase=16; " toupper(size)}' | bc); \
+ dd if=/dev/zero of=$@ bs=1 count=$${bss_size_str} 2>/dev/null;
+
+# Pass the original device tree file through fdtgrep twice. The first pass
+# removes any unwanted nodes (i.e. those which don't have the
+# 'u-boot,dm-pre-reloc' property and thus are not needed by SPL. The second
+# pass removes various unused properties from the remaining nodes.
+# The output is typically a much smaller device tree file.
+quiet_cmd_fdtgrep = FDTGREP $@
+ cmd_fdtgrep = $(objtree)/tools/fdtgrep -b u-boot,dm-pre-reloc -RT $< \
+ -n /chosen -O dtb | \
+ $(objtree)/tools/fdtgrep -r -O dtb - -o $@ \
+ $(addprefix -P ,$(subst $\",,$(CONFIG_OF_SPL_REMOVE_PROPS)))
+
+$(obj)/$(SPL_BIN).dtb: dts/dt.dtb
+ $(call cmd,fdtgrep)
+
quiet_cmd_cpp_cfg = CFG $@
cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
-DDO_DEPS_ONLY -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $<
# Kernel configuration targets
# These targets are used from top-level makefile
-PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config \
+PHONY += xconfig gconfig menuconfig config silentoldconfig update-po-config \
localmodconfig localyesconfig
# Added for U-Boot
Kconfig := Kconfig
endif
+ifeq ($(quiet),silent_)
+silent := -s
+endif
+
# We need this, in case the user has it in its environment
unexport CONFIG_
xconfig: $(obj)/qconf
- $< $(Kconfig)
+ $< $(silent) $(Kconfig)
gconfig: $(obj)/gconf
- $< $(Kconfig)
+ $< $(silent) $(Kconfig)
menuconfig: $(obj)/mconf
- $< $(Kconfig)
+ $< $(silent) $(Kconfig)
config: $(obj)/conf
- $< --oldaskconfig $(Kconfig)
+ $< $(silent) --oldaskconfig $(Kconfig)
nconfig: $(obj)/nconf
- $< $(Kconfig)
-
-oldconfig: $(obj)/conf
- $< --$@ $(Kconfig)
+ $< $(silent) $(Kconfig)
silentoldconfig: $(obj)/conf
$(Q)mkdir -p include/config include/generated
- $< --$@ $(Kconfig)
+ $< $(silent) --$@ $(Kconfig)
localyesconfig localmodconfig: $(obj)/streamline_config.pl $(obj)/conf
$(Q)mkdir -p include/config include/generated
cmp -s .tmp.config .config || \
(mv -f .config .config.old.1; \
mv -f .tmp.config .config; \
- $(obj)/conf --silentoldconfig $(Kconfig); \
+ $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \
mv -f .config.old.1 .config.old) \
else \
mv -f .tmp.config .config; \
- $(obj)/conf --silentoldconfig $(Kconfig); \
+ $(obj)/conf $(silent) --silentoldconfig $(Kconfig); \
fi
$(Q)rm -f .tmp.config
# Create new linux.pot file
# Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
update-po-config: $(obj)/kxgettext $(obj)/gconf.glade.h
- $(Q)echo " GEN config.pot"
+ $(Q)$(kecho) " GEN config.pot"
$(Q)xgettext --default-domain=linux \
--add-comments --keyword=_ --keyword=N_ \
--from-code=UTF-8 \
$(Q)(for i in `ls $(srctree)/arch/*/Kconfig \
$(srctree)/arch/*/um/Kconfig`; \
do \
- echo " GEN $$i"; \
+ $(kecho) " GEN $$i"; \
$(obj)/kxgettext $$i \
>> $(obj)/config.pot; \
done )
- $(Q)echo " GEN linux.pot"
+ $(Q)$(kecho) " GEN linux.pot"
$(Q)msguniq --sort-by-file --to-code=UTF-8 $(obj)/config.pot \
--output $(obj)/linux.pot
$(Q)rm -f $(obj)/config.pot
-PHONY += allnoconfig allyesconfig allmodconfig alldefconfig randconfig
+# These targets map 1:1 to the commandline options of 'conf'
+simple-targets := oldconfig allnoconfig allyesconfig allmodconfig \
+ alldefconfig randconfig listnewconfig olddefconfig
+PHONY += $(simple-targets)
-allnoconfig allyesconfig allmodconfig alldefconfig randconfig: $(obj)/conf
- $< --$@ $(Kconfig)
+$(simple-targets): $(obj)/conf
+ $< $(silent) --$@ $(Kconfig)
-PHONY += listnewconfig olddefconfig oldnoconfig savedefconfig defconfig
-
-listnewconfig olddefconfig: $(obj)/conf
- $< --$@ $(Kconfig)
+PHONY += oldnoconfig savedefconfig defconfig
# oldnoconfig is an alias of olddefconfig, because people already are dependent
# on its behavior(sets new symbols to their default value but not 'n') with the
# counter-intuitive name.
-oldnoconfig: $(obj)/conf
- $< --olddefconfig $(Kconfig)
+oldnoconfig: olddefconfig
savedefconfig: $(obj)/conf
- $< --$@=defconfig $(Kconfig)
+ $< $(silent) --$@=defconfig $(Kconfig)
defconfig: $(obj)/conf
ifeq ($(KBUILD_DEFCONFIG),)
- $< --defconfig $(Kconfig)
+ $< $(silent) --defconfig $(Kconfig)
else
- @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
- $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
+ @$(kecho) "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
+ $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
endif
%_defconfig: $(obj)/conf
- $(Q)$< --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
+ $(Q)$< $(silent) --defconfig=arch/$(SRCARCH)/configs/$@ $(Kconfig)
# Added for U-Boot (backward compatibility)
%_config: %_defconfig
@:
-configfiles=$(wildcard $(srctree)/kernel/configs/$(1).config $(srctree)/arch/$(SRCARCH)/configs/$(1).config)
+configfiles=$(wildcard $(srctree)/kernel/configs/$@ $(srctree)/arch/$(SRCARCH)/configs/$@)
-define mergeconfig
-$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target))
-$(if $(call configfiles,$(1)),, $(error No configuration exists for this target on this architecture))
-$(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(call configfiles,$(1))
-$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
-endef
+%.config: $(obj)/conf
+ $(if $(call configfiles),, $(error No configuration exists for this target on this architecture))
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m .config $(configfiles)
+ +$(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
PHONY += kvmconfig
-kvmconfig:
- $(call mergeconfig,kvm_guest)
+kvmconfig: kvm_guest.config
+ @:
PHONY += tinyconfig
-tinyconfig: allnoconfig
- $(call mergeconfig,tiny)
+tinyconfig:
+ $(Q)$(MAKE) -f $(srctree)/Makefile allnoconfig tiny.config
# Help text used by make help
help:
# QT needs some extra effort...
$(obj)/.tmp_qtcheck:
- @set -e; echo " CHECK qt"; dir=""; pkg=""; \
+ @set -e; $(kecho) " CHECK qt"; dir=""; pkg=""; \
if ! pkg-config --exists QtCore 2> /dev/null; then \
echo "* Unable to find the QT4 tool qmake. Trying to use QT3"; \
pkg-config --exists qt 2> /dev/null && pkg=qt; \
static void conf_usage(const char *progname)
{
- printf("Usage: %s [option] <kconfig-file>\n", progname);
+ printf("Usage: %s [-s] [option] <kconfig-file>\n", progname);
printf("[option] is _one_ of the following:\n");
printf(" --listnewconfig List new options\n");
printf(" --oldaskconfig Start a new configuration using a line-oriented program\n");
tty_stdio = isatty(0) && isatty(1) && isatty(2);
- while ((opt = getopt_long(ac, av, "", long_opts, NULL)) != -1) {
+ while ((opt = getopt_long(ac, av, "s", long_opts, NULL)) != -1) {
+ if (opt == 's') {
+ conf_set_message_callback(NULL);
+ continue;
+ }
input_mode = (enum input_mode)opt;
switch (opt) {
case silentoldconfig:
#include "lkc.h"
+struct conf_printer {
+ void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
+ void (*print_comment)(FILE *, const char *, void *);
+};
+
static void conf_warning(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
va_start(ap, fmt);
if (conf_message_callback)
conf_message_callback(fmt, ap);
+ va_end(ap);
}
const char *conf_get_configname(void)
#define DEBUG_EXPR 0
+static int expr_eq(struct expr *e1, struct expr *e2);
+static struct expr *expr_eliminate_yn(struct expr *e);
+static struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
+static struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
+static void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
+
struct expr *expr_alloc_symbol(struct symbol *sym)
{
struct expr *e = xcalloc(1, sizeof(*e));
#undef e1
#undef e2
-int expr_eq(struct expr *e1, struct expr *e2)
+static int expr_eq(struct expr *e1, struct expr *e2)
{
int res, old_count;
return 0;
}
-struct expr *expr_eliminate_yn(struct expr *e)
+static struct expr *expr_eliminate_yn(struct expr *e)
{
struct expr *tmp;
return false;
}
-struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
+static struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2)
{
struct expr *tmp = NULL;
expr_extract_eq(E_AND, &tmp, ep1, ep2);
return tmp;
}
-struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
+static struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2)
{
struct expr *tmp = NULL;
expr_extract_eq(E_OR, &tmp, ep1, ep2);
return tmp;
}
-void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
+static void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2)
{
#define e1 (*ep1)
#define e2 (*ep2)
}
}
-int expr_compare_type(enum expr_type t1, enum expr_type t2)
+static int expr_compare_type(enum expr_type t1, enum expr_type t2)
{
-#if 0
- return 1;
-#else
if (t1 == t2)
return 0;
switch (t1) {
}
printf("[%dgt%d?]", t1, t2);
return 0;
-#endif
}
static inline struct expr *
struct expr *expr_alloc_or(struct expr *e1, struct expr *e2);
struct expr *expr_copy(const struct expr *org);
void expr_free(struct expr *e);
-int expr_eq(struct expr *e1, struct expr *e2);
void expr_eliminate_eq(struct expr **ep1, struct expr **ep2);
tristate expr_calc_value(struct expr *e);
-struct expr *expr_eliminate_yn(struct expr *e);
struct expr *expr_trans_bool(struct expr *e);
struct expr *expr_eliminate_dups(struct expr *e);
struct expr *expr_transform(struct expr *e);
int expr_contains_symbol(struct expr *dep, struct symbol *sym);
bool expr_depends_symbol(struct expr *dep, struct symbol *sym);
-struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2);
-struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2);
-void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2);
struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2);
style = gtk_widget_get_style(main_wnd);
widget = glade_xml_get_widget(xml, "toolbar1");
-#if 0 /* Use stock Gtk icons instead */
- replace_button_icon(xml, main_wnd->window, style,
- "button1", (gchar **) xpm_back);
- replace_button_icon(xml, main_wnd->window, style,
- "button2", (gchar **) xpm_load);
- replace_button_icon(xml, main_wnd->window, style,
- "button3", (gchar **) xpm_save);
-#endif
replace_button_icon(xml, main_wnd->window, style,
"button4", (gchar **) xpm_single_view);
replace_button_icon(xml, main_wnd->window, style,
replace_button_icon(xml, main_wnd->window, style,
"button6", (gchar **) xpm_tree_view);
-#if 0
- switch (view_mode) {
- case SINGLE_VIEW:
- widget = glade_xml_get_widget(xml, "button4");
- g_signal_emit_by_name(widget, "clicked");
- break;
- case SPLIT_VIEW:
- widget = glade_xml_get_widget(xml, "button5");
- g_signal_emit_by_name(widget, "clicked");
- break;
- case FULL_VIEW:
- widget = glade_xml_get_widget(xml, "button6");
- g_signal_emit_by_name(widget, "clicked");
- break;
- }
-#endif
txtbuf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_w));
tag1 = gtk_text_buffer_create_tag(txtbuf, "mytag1",
"foreground", "red",
case 'a':
//showAll = 1;
break;
+ case 's':
+ conf_set_message_callback(NULL);
+ break;
case 'h':
case '?':
- printf("%s <config>\n", av[0]);
+ printf("%s [-s] <config>\n", av[0]);
exit(0);
}
name = av[2];
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
+ * @member: the name of the list_head within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
- * @member: the name of the list_struct within the struct.
+ * @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
- * @member: the name of the list_struct within the struct.
+ * @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
extern "C" {
#endif
-#define P(name,type,arg) extern type name arg
#include "lkc_proto.h"
-#undef P
#define SRCTREE "srctree"
enum symbol_type stype;
};
-extern int zconfdebug;
-
-int zconfparse(void);
void zconfdump(FILE *out);
void zconf_starthelp(void);
FILE *zconf_fopen(const char *name);
bool conf_set_all_new_symbols(enum conf_def_mode mode);
void set_all_choice_values(struct symbol *csym);
-struct conf_printer {
- void (*print_symbol)(FILE *, struct symbol *, const char *, void *);
- void (*print_comment)(FILE *, const char *, void *);
-};
-
/* confdata.c and expr.c */
static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
{
void menu_end_entry(void);
void menu_add_dep(struct expr *dep);
void menu_add_visibility(struct expr *dep);
-struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep);
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
int max_width;
};
struct gstr str_new(void);
-struct gstr str_assign(const char *s);
void str_free(struct gstr *gs);
void str_append(struct gstr *gs, const char *s);
void str_printf(struct gstr *gs, const char *fmt, ...);
void sym_init(void);
void sym_clear_all_valid(void);
-void sym_set_all_changed(void);
-void sym_set_changed(struct symbol *sym);
struct symbol *sym_choice_default(struct symbol *sym);
const char *sym_get_string_default(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym);
#include <stdarg.h>
/* confdata.c */
-P(conf_parse,void,(const char *name));
-P(conf_read,int,(const char *name));
-P(conf_read_simple,int,(const char *name, int));
-P(conf_write_defconfig,int,(const char *name));
-P(conf_write,int,(const char *name));
-P(conf_write_autoconf,int,(void));
-P(conf_get_changed,bool,(void));
-P(conf_set_changed_callback, void,(void (*fn)(void)));
-P(conf_set_message_callback, void,(void (*fn)(const char *fmt, va_list ap)));
+void conf_parse(const char *name);
+int conf_read(const char *name);
+int conf_read_simple(const char *name, int);
+int conf_write_defconfig(const char *name);
+int conf_write(const char *name);
+int conf_write_autoconf(void);
+bool conf_get_changed(void);
+void conf_set_changed_callback(void (*fn)(void));
+void conf_set_message_callback(void (*fn)(const char *fmt, va_list ap));
/* menu.c */
-P(rootmenu,struct menu,);
+extern struct menu rootmenu;
-P(menu_is_empty, bool, (struct menu *menu));
-P(menu_is_visible, bool, (struct menu *menu));
-P(menu_has_prompt, bool, (struct menu *menu));
-P(menu_get_prompt,const char *,(struct menu *menu));
-P(menu_get_root_menu,struct menu *,(struct menu *menu));
-P(menu_get_parent_menu,struct menu *,(struct menu *menu));
-P(menu_has_help,bool,(struct menu *menu));
-P(menu_get_help,const char *,(struct menu *menu));
-P(get_symbol_str, void, (struct gstr *r, struct symbol *sym, struct list_head
- *head));
-P(get_relations_str, struct gstr, (struct symbol **sym_arr, struct list_head
- *head));
-P(menu_get_ext_help,void,(struct menu *menu, struct gstr *help));
+bool menu_is_empty(struct menu *menu);
+bool menu_is_visible(struct menu *menu);
+bool menu_has_prompt(struct menu *menu);
+const char * menu_get_prompt(struct menu *menu);
+struct menu * menu_get_root_menu(struct menu *menu);
+struct menu * menu_get_parent_menu(struct menu *menu);
+bool menu_has_help(struct menu *menu);
+const char * menu_get_help(struct menu *menu);
+struct gstr get_relations_str(struct symbol **sym_arr, struct list_head *head);
+void menu_get_ext_help(struct menu *menu, struct gstr *help);
/* symbol.c */
-P(symbol_hash,struct symbol *,[SYMBOL_HASHSIZE]);
+extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
-P(sym_lookup,struct symbol *,(const char *name, int flags));
-P(sym_find,struct symbol *,(const char *name));
-P(sym_expand_string_value,const char *,(const char *in));
-P(sym_escape_string_value, const char *,(const char *in));
-P(sym_re_search,struct symbol **,(const char *pattern));
-P(sym_type_name,const char *,(enum symbol_type type));
-P(sym_calc_value,void,(struct symbol *sym));
-P(sym_get_type,enum symbol_type,(struct symbol *sym));
-P(sym_tristate_within_range,bool,(struct symbol *sym,tristate tri));
-P(sym_set_tristate_value,bool,(struct symbol *sym,tristate tri));
-P(sym_toggle_tristate_value,tristate,(struct symbol *sym));
-P(sym_string_valid,bool,(struct symbol *sym, const char *newval));
-P(sym_string_within_range,bool,(struct symbol *sym, const char *str));
-P(sym_set_string_value,bool,(struct symbol *sym, const char *newval));
-P(sym_is_changable,bool,(struct symbol *sym));
-P(sym_get_choice_prop,struct property *,(struct symbol *sym));
-P(sym_get_default_prop,struct property *,(struct symbol *sym));
-P(sym_get_string_value,const char *,(struct symbol *sym));
+struct symbol * sym_lookup(const char *name, int flags);
+struct symbol * sym_find(const char *name);
+const char * sym_expand_string_value(const char *in);
+const char * sym_escape_string_value(const char *in);
+struct symbol ** sym_re_search(const char *pattern);
+const char * sym_type_name(enum symbol_type type);
+void sym_calc_value(struct symbol *sym);
+enum symbol_type sym_get_type(struct symbol *sym);
+bool sym_tristate_within_range(struct symbol *sym,tristate tri);
+bool sym_set_tristate_value(struct symbol *sym,tristate tri);
+tristate sym_toggle_tristate_value(struct symbol *sym);
+bool sym_string_valid(struct symbol *sym, const char *newval);
+bool sym_string_within_range(struct symbol *sym, const char *str);
+bool sym_set_string_value(struct symbol *sym, const char *newval);
+bool sym_is_changable(struct symbol *sym);
+struct property * sym_get_choice_prop(struct symbol *sym);
+const char * sym_get_string_value(struct symbol *sym);
-P(prop_get_type_name,const char *,(enum prop_type type));
+const char * prop_get_type_name(enum prop_type type);
/* expr.c */
-P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
-P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken));
+void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
# Where is ncurses.h?
ccflags()
{
- if [ -f /usr/include/ncursesw/curses.h ]; then
+ if pkg-config --cflags ncursesw 2>/dev/null; then
+ echo '-DCURSES_LOC="<ncurses.h>" -DNCURSES_WIDECHAR=1'
+ elif pkg-config --cflags ncurses 2>/dev/null; then
+ echo '-DCURSES_LOC="<ncurses.h>"'
+ elif [ -f /usr/include/ncursesw/curses.h ]; then
echo '-I/usr/include/ncursesw -DCURSES_LOC="<curses.h>"'
echo ' -DNCURSES_WIDECHAR=1'
elif [ -f /usr/include/ncurses/ncurses.h ]; then
static int single_menu_mode;
static int show_all_options;
static int save_and_exit;
+static int silent;
static void conf(struct menu *menu, struct menu *active_menu);
static void conf_choice(struct menu *menu);
list_for_each_entry(sp, &trail, entries) {
if (sp->text) {
if (pos) {
- pos->next = xcalloc(sizeof(*pos), 1);
+ pos->next = xcalloc(1, sizeof(*pos));
pos = pos->next;
} else {
- subtitles = pos = xcalloc(sizeof(*pos), 1);
+ subtitles = pos = xcalloc(1, sizeof(*pos));
}
pos->text = sp->text;
}
char buf[PATH_MAX+1];
vsnprintf(buf, sizeof(buf), fmt, ap);
- if (save_and_exit)
- printf("%s", buf);
- else
+ if (save_and_exit) {
+ if (!silent)
+ printf("%s", buf);
+ } else {
show_textbox(NULL, buf, 6, 60);
+ }
}
static void show_help(struct menu *menu)
}
/* fall through */
case -1:
- printf(_("\n\n"
- "*** End of the configuration.\n"
- "*** Execute 'make' to start the build or try 'make help'."
- "\n\n"));
+ if (!silent)
+ printf(_("\n\n"
+ "*** End of the configuration.\n"
+ "*** Execute 'make' to start the build or try 'make help'."
+ "\n\n"));
res = 0;
break;
default:
- fprintf(stderr, _("\n\n"
- "Your configuration changes were NOT saved."
- "\n\n"));
+ if (!silent)
+ fprintf(stderr, _("\n\n"
+ "Your configuration changes were NOT saved."
+ "\n\n"));
if (res != KEY_ESC)
res = 0;
}
signal(SIGINT, sig_handler);
+ if (ac > 1 && strcmp(av[1], "-s") == 0) {
+ silent = 1;
+ /* Silence conf_read() until the real callback is set up */
+ conf_set_message_callback(NULL);
+ av++;
+ }
conf_parse(av[1]);
conf_read(NULL);
sym_type_name(sym->type), sym_type_name(type));
}
-struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
+static struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *expr, struct expr *dep)
{
struct property *prop = prop_alloc(type, current_entry->sym);
/*
* head is optional and may be NULL
*/
-void get_symbol_str(struct gstr *r, struct symbol *sym,
+static void get_symbol_str(struct gstr *r, struct symbol *sym,
struct list_head *head)
{
bool hit;
echo " -O dir to put generated output files"
}
-MAKE=true
+RUNMAKE=true
ALLTARGET=alldefconfig
WARNREDUN=false
OUTPUT=.
continue
;;
"-m")
- MAKE=false
+ RUNMAKE=false
shift
continue
;;
esac
done
+if [ "$#" -lt 2 ] ; then
+ usage
+ exit
+fi
+
INITFILE=$1
shift;
+if [ ! -r "$INITFILE" ]; then
+ echo "The base file '$INITFILE' does not exist. Exit." >&2
+ exit 1
+fi
+
MERGE_LIST=$*
SED_CONFIG_EXP="s/^\(# \)\{0,1\}\(CONFIG_[a-zA-Z0-9_]*\)[= ].*/\2/p"
TMP_FILE=$(mktemp ./.tmp.config.XXXXXXXXXX)
CFG_LIST=$(sed -n "$SED_CONFIG_EXP" $MERGE_FILE)
for CFG in $CFG_LIST ; do
- grep -q -w $CFG $TMP_FILE
- if [ $? -eq 0 ] ; then
- PREV_VAL=$(grep -w $CFG $TMP_FILE)
- NEW_VAL=$(grep -w $CFG $MERGE_FILE)
- if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then
+ grep -q -w $CFG $TMP_FILE || continue
+ PREV_VAL=$(grep -w $CFG $TMP_FILE)
+ NEW_VAL=$(grep -w $CFG $MERGE_FILE)
+ if [ "x$PREV_VAL" != "x$NEW_VAL" ] ; then
echo Value of $CFG is redefined by fragment $MERGE_FILE:
echo Previous value: $PREV_VAL
echo New value: $NEW_VAL
echo
- elif [ "$WARNREDUN" = "true" ]; then
+ elif [ "$WARNREDUN" = "true" ]; then
echo Value of $CFG is redundant by fragment $MERGE_FILE:
- fi
- sed -i "/$CFG[ =]/d" $TMP_FILE
fi
+ sed -i "/$CFG[ =]/d" $TMP_FILE
done
cat $MERGE_FILE >> $TMP_FILE
done
-if [ "$MAKE" = "false" ]; then
+if [ "$RUNMAKE" = "false" ]; then
cp $TMP_FILE $OUTPUT/.config
echo "#"
echo "# merged configuration written to $OUTPUT/.config (needs make)"
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
+ if (ac > 1 && strcmp(av[1], "-s") == 0) {
+ /* Silence conf_read() until the real callback is set up */
+ conf_set_message_callback(NULL);
+ av++;
+ }
conf_parse(av[1]);
conf_read(NULL);
static void usage(void)
{
- printf(_("%s <config>\n"), progname);
+ printf(_("%s [-s] <config>\n"), progname);
exit(0);
}
configApp = new QApplication(ac, av);
if (ac > 1 && av[1][0] == '-') {
switch (av[1][1]) {
+ case 's':
+ conf_set_message_callback(NULL);
+ break;
case 'h':
case '?':
usage();
return NULL;
}
-struct property *sym_get_default_prop(struct symbol *sym)
+static struct property *sym_get_default_prop(struct symbol *sym)
{
struct property *prop;
sym->curr.val = strdup(str);
}
+static void sym_set_changed(struct symbol *sym)
+{
+ struct property *prop;
+
+ sym->flags |= SYMBOL_CHANGED;
+ for (prop = sym->prop; prop; prop = prop->next) {
+ if (prop->menu)
+ prop->menu->flags |= MENU_CHANGED;
+ }
+}
+
+static void sym_set_all_changed(void)
+{
+ struct symbol *sym;
+ int i;
+
+ for_all_symbols(i, sym)
+ sym_set_changed(sym);
+}
+
static void sym_calc_visibility(struct symbol *sym)
{
struct property *prop;
sym_calc_value(modules_sym);
}
-void sym_set_changed(struct symbol *sym)
-{
- struct property *prop;
-
- sym->flags |= SYMBOL_CHANGED;
- for (prop = sym->prop; prop; prop = prop->next) {
- if (prop->menu)
- prop->menu->flags |= MENU_CHANGED;
- }
-}
-
-void sym_set_all_changed(void)
-{
- struct symbol *sym;
- int i;
-
- for_all_symbols(i, sym)
- sym_set_changed(sym);
-}
-
bool sym_tristate_within_range(struct symbol *sym, tristate val)
{
int type = sym_get_type(sym);
return gs;
}
-/* Allocate and assign growable string */
-struct gstr str_assign(const char *s)
-{
- struct gstr gs;
- gs.s = strdup(s);
- gs.len = strlen(s) + 1;
- gs.max_width = 0;
- return gs;
-}
-
/* Free storage for growable string */
void str_free(struct gstr *gs)
{
# subsystem you must add sandbox tests here.
obj-$(CONFIG_UT_DM) += core.o
ifneq ($(CONFIG_SANDBOX),)
+obj-$(CONFIG_CLK) += clk.o
obj-$(CONFIG_DM_ETH) += eth.o
obj-$(CONFIG_DM_GPIO) += gpio.o
obj-$(CONFIG_DM_I2C) += i2c.o
+obj-$(CONFIG_LED) += led.o
+obj-$(CONFIG_DM_MMC) += mmc.o
obj-$(CONFIG_DM_PCI) += pci.o
+obj-$(CONFIG_RAM) += ram.o
+obj-y += regmap.o
+obj-$(CONFIG_RESET) += reset.o
obj-$(CONFIG_DM_RTC) += rtc.o
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
obj-$(CONFIG_DM_SPI) += spi.o
+obj-y += syscon.o
obj-$(CONFIG_DM_USB) += usb.o
obj-$(CONFIG_DM_PMIC) += pmic.o
obj-$(CONFIG_DM_REGULATOR) += regulator.o
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <linux/err.h>
+#include <test/ut.h>
+
+/* Test that we can find and adjust clocks */
+static int dm_test_clk_base(struct unit_test_state *uts)
+{
+ struct udevice *clk;
+ ulong rate;
+
+ ut_assertok(uclass_get_device(UCLASS_CLK, 0, &clk));
+ rate = clk_get_rate(clk);
+ ut_asserteq(SANDBOX_CLK_RATE, rate);
+ ut_asserteq(-EINVAL, clk_set_rate(clk, 0));
+ ut_assertok(clk_set_rate(clk, rate * 2));
+ ut_asserteq(SANDBOX_CLK_RATE * 2, clk_get_rate(clk));
+
+ return 0;
+}
+DM_TEST(dm_test_clk_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that peripheral clocks work as expected */
+static int dm_test_clk_periph(struct unit_test_state *uts)
+{
+ struct udevice *clk;
+ ulong rate;
+
+ ut_assertok(uclass_get_device(UCLASS_CLK, 0, &clk));
+ rate = clk_set_periph_rate(clk, PERIPH_ID_COUNT, 123);
+ ut_asserteq(-EINVAL, rate);
+ ut_asserteq(1, IS_ERR_VALUE(rate));
+
+ rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 123);
+ ut_asserteq(0, rate);
+ ut_asserteq(123, clk_get_periph_rate(clk, PERIPH_ID_SPI));
+
+ rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 1234);
+ ut_asserteq(123, rate);
+
+ rate = clk_set_periph_rate(clk, PERIPH_ID_I2C, 567);
+
+ rate = clk_set_periph_rate(clk, PERIPH_ID_SPI, 1234);
+ ut_asserteq(1234, rate);
+
+ ut_asserteq(567, clk_get_periph_rate(clk, PERIPH_ID_I2C));
+
+ return 0;
+}
+DM_TEST(dm_test_clk_periph, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
#include <errno.h>
#include <asm/io.h>
#include <dm/root.h>
-#include <dm/uclass-internal.h>
-
-static void show_devices(struct udevice *dev, int depth, int last_flag)
-{
- int i, is_last;
- struct udevice *child;
- char class_name[12];
-
- /* print the first 11 characters to not break the tree-format. */
- strlcpy(class_name, dev->uclass->uc_drv->name, sizeof(class_name));
- printf(" %-11s [ %c ] ", class_name,
- dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ');
-
- for (i = depth; i >= 0; i--) {
- is_last = (last_flag >> i) & 1;
- if (i) {
- if (is_last)
- printf(" ");
- else
- printf("| ");
- } else {
- if (is_last)
- printf("`-- ");
- else
- printf("|-- ");
- }
- }
-
- printf("%s\n", dev->name);
-
- list_for_each_entry(child, &dev->child_head, sibling_node) {
- is_last = list_is_last(&child->sibling_node, &dev->child_head);
- show_devices(child, depth + 1, (last_flag << 1) | is_last);
- }
-}
+#include <dm/util.h>
static int do_dm_dump_all(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
- struct udevice *root;
-
- root = dm_root();
- if (root) {
- printf(" Class Probed Name\n");
- printf("----------------------------------------\n");
- show_devices(root, -1, 0);
- }
+ dm_dump_all();
return 0;
}
-/**
- * dm_display_line() - Display information about a single device
- *
- * Displays a single line of information with an option prefix
- *
- * @dev: Device to display
- */
-static void dm_display_line(struct udevice *dev)
-{
- printf("- %c %s @ %08lx",
- dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
- dev->name, (ulong)map_to_sysmem(dev));
- if (dev->seq != -1 || dev->req_seq != -1)
- printf(", seq %d, (req %d)", dev->seq, dev->req_seq);
- puts("\n");
-}
-
static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
- struct uclass *uc;
- int ret;
- int id;
-
- for (id = 0; id < UCLASS_COUNT; id++) {
- struct udevice *dev;
-
- ret = uclass_get(id, &uc);
- if (ret)
- continue;
-
- printf("uclass %d: %s\n", id, uc->uc_drv->name);
- if (list_empty(&uc->dev_head))
- continue;
- list_for_each_entry(dev, &uc->dev_head, uclass_node) {
- dm_display_line(dev);
- }
- puts("\n");
- }
+ dm_dump_uclass();
return 0;
}
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <led.h>
+#include <asm/gpio.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Base test of the led uclass */
+static int dm_test_led_base(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+
+ /* Get the top-level device */
+ ut_assertok(uclass_get_device(UCLASS_LED, 0, &dev));
+ ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
+ ut_assertok(uclass_get_device(UCLASS_LED, 2, &dev));
+ ut_asserteq(-ENODEV, uclass_get_device(UCLASS_LED, 3, &dev));
+
+ return 0;
+}
+DM_TEST(dm_test_led_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test of the led uclass using the led_gpio driver */
+static int dm_test_led_gpio(struct unit_test_state *uts)
+{
+ const int offset = 1;
+ struct udevice *dev, *gpio;
+
+ /*
+ * Check that we can manipulate an LED. LED 1 is connected to GPIO
+ * bank gpio_a, offset 1.
+ */
+ ut_assertok(uclass_get_device(UCLASS_LED, 1, &dev));
+ ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio));
+ ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+ led_set_on(dev, 1);
+ ut_asserteq(1, sandbox_gpio_get_value(gpio, offset));
+ led_set_on(dev, 0);
+ ut_asserteq(0, sandbox_gpio_get_value(gpio, offset));
+
+ return 0;
+}
+DM_TEST(dm_test_led_gpio, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test obtaining an LED by label */
+static int dm_test_led_label(struct unit_test_state *uts)
+{
+ struct udevice *dev, *cmp;
+
+ ut_assertok(led_get_by_label("sandbox:red", &dev));
+ ut_asserteq(1, device_active(dev));
+ ut_assertok(uclass_get_device(UCLASS_LED, 1, &cmp));
+ ut_asserteq_ptr(dev, cmp);
+
+ ut_assertok(led_get_by_label("sandbox:green", &dev));
+ ut_asserteq(1, device_active(dev));
+ ut_assertok(uclass_get_device(UCLASS_LED, 2, &cmp));
+ ut_asserteq_ptr(dev, cmp);
+
+ ut_asserteq(-ENODEV, led_get_by_label("sandbox:blue", &dev));
+
+ return 0;
+}
+DM_TEST(dm_test_led_label, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mmc.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Basic test of the mmc uclass. We could expand this by implementing an MMC
+ * stack for sandbox, or at least implementing the basic operation.
+ */
+static int dm_test_mmc_base(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+
+ ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
+
+ return 0;
+}
+DM_TEST(dm_test_mmc_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ram.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Basic test of the ram uclass */
+static int dm_test_ram_base(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct ram_info info;
+
+ ut_assertok(uclass_get_device(UCLASS_RAM, 0, &dev));
+ ut_assertok(ram_get_info(dev, &info));
+ ut_asserteq(0, info.base);
+ ut_asserteq(gd->ram_size, info.size);
+
+ return 0;
+}
+DM_TEST(dm_test_ram_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+2 *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <mapmem.h>
+#include <regmap.h>
+#include <syscon.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Base test of register maps */
+static int dm_test_regmap_base(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+ struct regmap *map;
+ int i;
+
+ ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
+ map = syscon_get_regmap(dev);
+ ut_assertok_ptr(map);
+ ut_asserteq(1, map->range_count);
+ ut_asserteq(0x10, map->base);
+ ut_asserteq(0x10, map->range->start);
+ ut_asserteq(4, map->range->size);
+ ut_asserteq_ptr(&map->base_range, map->range);
+ ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0)));
+
+ ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev));
+ map = syscon_get_regmap(dev);
+ ut_assertok_ptr(map);
+ ut_asserteq(4, map->range_count);
+ ut_asserteq(0x20, map->base);
+ ut_assert(&map->base_range != map->range);
+ for (i = 0; i < 4; i++) {
+ const unsigned long addr = 0x20 + 8 * i;
+
+ ut_asserteq(addr, map->range[i].start);
+ ut_asserteq(5 + i, map->range[i].size);
+ ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i)));
+ }
+
+ /* Check that we can't pretend a different device is a syscon */
+ ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
+ map = syscon_get_regmap(dev);
+ ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map);
+
+ return 0;
+}
+DM_TEST(dm_test_regmap_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test we can access a regmap through syscon */
+static int dm_test_regmap_syscon(struct unit_test_state *uts)
+{
+ struct regmap *map;
+
+ map = syscon_get_regmap_by_driver_data(SYSCON0);
+ ut_assertok_ptr(map);
+ ut_asserteq(1, map->range_count);
+
+ map = syscon_get_regmap_by_driver_data(SYSCON1);
+ ut_assertok_ptr(map);
+ ut_asserteq(4, map->range_count);
+
+ map = syscon_get_regmap_by_driver_data(SYSCON_COUNT);
+ ut_asserteq_ptr(ERR_PTR(-ENODEV), map);
+
+ ut_asserteq(0x10, map_to_sysmem(syscon_get_first_range(SYSCON0)));
+ ut_asserteq(0x20, map_to_sysmem(syscon_get_first_range(SYSCON1)));
+ ut_asserteq_ptr(ERR_PTR(-ENODEV),
+ syscon_get_first_range(SYSCON_COUNT));
+
+ return 0;
+}
+
+DM_TEST(dm_test_regmap_syscon, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
* Expected output state: uV=1200000; uA=200000; output enabled
*/
platname = regulator_names[BUCK1][PLATNAME];
- ut_assertok(regulator_autoset(platname, &dev_autoset, false));
+ ut_assertok(regulator_autoset_by_name(platname, &dev_autoset));
/* Check, that the returned device is proper */
ut_assertok(regulator_get_by_platname(platname, &dev));
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <reset.h>
+#include <asm/state.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+/* Test that we can use particular reset devices */
+static int dm_test_reset_base(struct unit_test_state *uts)
+{
+ struct sandbox_state *state = state_get_current();
+ struct udevice *dev;
+
+ /* Device 0 is the platform data device - it should never respond */
+ ut_assertok(uclass_get_device(UCLASS_RESET, 0, &dev));
+ ut_asserteq(-ENODEV, reset_request(dev, RESET_WARM));
+ ut_asserteq(-ENODEV, reset_request(dev, RESET_COLD));
+ ut_asserteq(-ENODEV, reset_request(dev, RESET_POWER));
+
+ /* Device 1 is the warm reset device */
+ ut_assertok(uclass_get_device(UCLASS_RESET, 1, &dev));
+ ut_asserteq(-EACCES, reset_request(dev, RESET_WARM));
+ ut_asserteq(-ENOSYS, reset_request(dev, RESET_COLD));
+ ut_asserteq(-ENOSYS, reset_request(dev, RESET_POWER));
+
+ state->reset_allowed[RESET_WARM] = true;
+ ut_asserteq(-EINPROGRESS, reset_request(dev, RESET_WARM));
+ state->reset_allowed[RESET_WARM] = false;
+
+ /* Device 2 is the cold reset device */
+ ut_assertok(uclass_get_device(UCLASS_RESET, 2, &dev));
+ ut_asserteq(-ENOSYS, reset_request(dev, RESET_WARM));
+ ut_asserteq(-EACCES, reset_request(dev, RESET_COLD));
+ state->reset_allowed[RESET_POWER] = false;
+ ut_asserteq(-EACCES, reset_request(dev, RESET_POWER));
+ state->reset_allowed[RESET_POWER] = true;
+
+ return 0;
+}
+DM_TEST(dm_test_reset_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we can walk through the reset devices */
+static int dm_test_reset_walk(struct unit_test_state *uts)
+{
+ struct sandbox_state *state = state_get_current();
+
+ /* If we generate a power reset, we will exit sandbox! */
+ state->reset_allowed[RESET_POWER] = false;
+ ut_asserteq(-EACCES, reset_walk(RESET_WARM));
+ ut_asserteq(-EACCES, reset_walk(RESET_COLD));
+ ut_asserteq(-EACCES, reset_walk(RESET_POWER));
+
+ /*
+ * Enable cold reset - this should make cold reset work, plus a warm
+ * reset should be promoted to cold, since this is the next step
+ * along.
+ */
+ state->reset_allowed[RESET_COLD] = true;
+ ut_asserteq(-EINPROGRESS, reset_walk(RESET_WARM));
+ ut_asserteq(-EINPROGRESS, reset_walk(RESET_COLD));
+ ut_asserteq(-EACCES, reset_walk(RESET_POWER));
+ state->reset_allowed[RESET_COLD] = false;
+ state->reset_allowed[RESET_POWER] = true;
+
+ return 0;
+}
+DM_TEST(dm_test_reset_walk, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
--- /dev/null
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <syscon.h>
+#include <asm/test.h>
+#include <dm/test.h>
+#include <test/ut.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Base test of system controllers */
+static int dm_test_syscon_base(struct unit_test_state *uts)
+{
+ struct udevice *dev;
+
+ ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
+ ut_asserteq(SYSCON0, dev->driver_data);
+
+ ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev));
+ ut_asserteq(SYSCON1, dev->driver_data);
+
+ ut_asserteq(-ENODEV, uclass_get_device(UCLASS_SYSCON, 2, &dev));
+
+ return 0;
+}
+DM_TEST(dm_test_syscon_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
struct unit_test_state *uts = &global_dm_test_state;
uts->priv = &_global_priv_dm_test_state;
struct unit_test *test;
+ int run_count;
/*
* If we have no device tree, or it only has a root node, then these
if (!test_name)
printf("Running %d driver model tests\n", n_ents);
+ run_count = 0;
for (test = tests; test < tests + n_ents; test++) {
- if (test_name && strcmp(test_name, test->name))
+ const char *name = test->name;
+
+ /* All tests have this prefix */
+ if (!strncmp(name, "dm_test_", 8))
+ name += 8;
+ if (test_name && strcmp(test_name, name))
continue;
printf("Test: %s\n", test->name);
+ run_count++;
ut_assertok(dm_test_init(uts));
uts->start = mallinfo();
ut_assertok(dm_test_destroy(uts));
}
- printf("Failures: %d\n", uts->fail_count);
+ if (test_name && !run_count)
+ printf("Test '%s' not found\n", test_name);
+ else
+ printf("Failures: %d\n", uts->fail_count);
gd->dm_root = NULL;
ut_assertok(dm_init());
/mkenvimage
/mkimage
/mkexynosspl
-/mpc86x_clk
/mxsboot
/mksunxiboot
/ncb
FIT_SIG_OBJS-$(CONFIG_FIT_SIGNATURE) := common/image-sig.o
# Flattened device tree objects
LIBFDT_OBJS := $(addprefix lib/libfdt/, \
- fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o)
+ fdt.o fdt_ro.o fdt_rw.o fdt_strerror.o fdt_wip.o \
+ fdt_region.o)
RSA_OBJS-$(CONFIG_FIT_SIGNATURE) := $(addprefix lib/rsa/, \
rsa-sign.o rsa-verify.o rsa-checksum.o \
rsa-mod-exp.o)
HOST_EXTRACFLAGS += -DCONFIG_FIT_SIGNATURE
endif
-ifdef CONFIG_SYS_SPI_U_BOOT_OFFS
-HOSTCFLAGS_kwbimage.o += -DCONFIG_SYS_SPI_U_BOOT_OFFS=$(CONFIG_SYS_SPI_U_BOOT_OFFS)
+ifdef CONFIG_SYS_U_BOOT_OFFS
+HOSTCFLAGS_kwbimage.o += -DCONFIG_SYS_U_BOOT_OFFS=$(CONFIG_SYS_U_BOOT_OFFS)
endif
# MXSImage needs LibSSL
hostprogs-y += proftool
hostprogs-$(CONFIG_STATIC_RELA) += relocate-rela
+hostprogs-y += fdtgrep
+fdtgrep-objs += $(LIBFDT_OBJS) fdtgrep.o
+
# We build some files with extra pedantic flags to try to minimize things
# that won't build on some weird host compiler -- though there are lots of
# exceptions for files that aren't complaint.
HOSTCFLAGS_sha1.o := -pedantic
HOSTCFLAGS_sha256.o := -pedantic
-# Don't build by default
-#hostprogs-$(CONFIG_PPC) += mpc86x_clk
-#HOSTCFLAGS_mpc86x_clk.o := -pedantic
-
quiet_cmd_wrap = WRAP $@
cmd_wrap = echo "\#include <../$(patsubst $(obj)/%,%,$@)>" >$@
To make this easier, buildman can automatically download and install
toolchains from kernel.org. First list the available architectures:
-$ ./tools/buildman/buildman sandbox --fetch-arch list
+$ ./tools/buildman/buildman --fetch-arch list
Checking: https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.6.3/
Checking: https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.6.2/
Checking: https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.5.1/
Then pick one and download it:
-$ ./tools/buildman/buildman sandbox --fetch-arch or32
+$ ./tools/buildman/buildman --fetch-arch or32
Checking: https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.6.3/
Checking: https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.6.2/
Checking: https://www.kernel.org/pub/tools/crosstool/files/bin/x86_64/4.5.1/
struct image_tool_params *params)
{
uint32_t checksum;
+ char *source_date_epoch;
+ struct tm *time_universal;
+ time_t time;
image_header_t * hdr = (image_header_t *)ptr;
sizeof(image_header_t)),
sbuf->st_size - sizeof(image_header_t));
+ source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+ if (source_date_epoch != NULL) {
+ time = (time_t) strtol(source_date_epoch, NULL, 10);
+
+ time_universal = gmtime(&time);
+ if (time_universal == NULL) {
+ fprintf(stderr, "%s: SOURCE_DATE_EPOCH is not valid\n",
+ __func__);
+ time = 0;
+ } else {
+ time = mktime(time_universal);
+ }
+ } else {
+ time = sbuf->st_mtime;
+ }
+
/* Build new header */
image_set_magic(hdr, IH_MAGIC);
- image_set_time(hdr, sbuf->st_mtime);
+ image_set_time(hdr, time);
image_set_size(hdr, sbuf->st_size - sizeof(image_header_t));
image_set_load(hdr, params->addr);
image_set_ep(hdr, params->ep);
--- /dev/null
+/*
+ * Copyright (c) 2013, Google Inc.
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Perform a grep of an FDT either displaying the source subset or producing
+ * a new .dtb subset which can be used as required.
+ */
+
+#include <assert.h>
+#include <ctype.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <../include/libfdt.h>
+#include <libfdt_internal.h>
+
+/* Define DEBUG to get some debugging output on stderr */
+#ifdef DEBUG
+#define debug(a, b...) fprintf(stderr, a, ## b)
+#else
+#define debug(a, b...)
+#endif
+
+/* A linked list of values we are grepping for */
+struct value_node {
+ int type; /* Types this value matches (FDT_IS... mask) */
+ int include; /* 1 to include matches, 0 to exclude */
+ const char *string; /* String to match */
+ struct value_node *next; /* Pointer to next node, or NULL */
+};
+
+/* Output formats we support */
+enum output_t {
+ OUT_DTS, /* Device tree source */
+ OUT_DTB, /* Valid device tree binary */
+ OUT_BIN, /* Fragment of .dtb, for hashing */
+};
+
+/* Holds information which controls our output and options */
+struct display_info {
+ enum output_t output; /* Output format */
+ int add_aliases; /* Add aliases node to output */
+ int all; /* Display all properties/nodes */
+ int colour; /* Display output in ANSI colour */
+ int region_list; /* Output a region list */
+ int flags; /* Flags (FDT_REG_...) */
+ int list_strings; /* List strings in string table */
+ int show_offset; /* Show offset */
+ int show_addr; /* Show address */
+ int header; /* Output an FDT header */
+ int diff; /* Show +/- diff markers */
+ int include_root; /* Include the root node and all properties */
+ int remove_strings; /* Remove unused strings */
+ int show_dts_version; /* Put '/dts-v1/;' on the first line */
+ int types_inc; /* Mask of types that we include (FDT_IS...) */
+ int types_exc; /* Mask of types that we exclude (FDT_IS...) */
+ int invert; /* Invert polarity of match */
+ struct value_node *value_head; /* List of values to match */
+ const char *output_fname; /* Output filename */
+ FILE *fout; /* File to write dts/dtb output */
+};
+
+static void report_error(const char *where, int err)
+{
+ fprintf(stderr, "Error at '%s': %s\n", where, fdt_strerror(err));
+}
+
+/* Supported ANSI colours */
+enum {
+ COL_BLACK,
+ COL_RED,
+ COL_GREEN,
+ COL_YELLOW,
+ COL_BLUE,
+ COL_MAGENTA,
+ COL_CYAN,
+ COL_WHITE,
+
+ COL_NONE = -1,
+};
+
+/**
+ * print_ansi_colour() - Print out the ANSI sequence for a colour
+ *
+ * @fout: Output file
+ * @col: Colour to output (COL_...), or COL_NONE to reset colour
+ */
+static void print_ansi_colour(FILE *fout, int col)
+{
+ if (col == COL_NONE)
+ fprintf(fout, "\033[0m");
+ else
+ fprintf(fout, "\033[1;%dm", col + 30);
+}
+
+
+/**
+ * value_add() - Add a new value to our list of things to grep for
+ *
+ * @disp: Display structure, holding info about our options
+ * @headp: Pointer to header pointer of list
+ * @type: Type of this value (FDT_IS_...)
+ * @include: 1 if we want to include matches, 0 to exclude
+ * @str: String value to match
+ */
+static int value_add(struct display_info *disp, struct value_node **headp,
+ int type, int include, const char *str)
+{
+ struct value_node *node;
+
+ /*
+ * Keep track of which types we are excluding/including. We don't
+ * allow both including and excluding things, because it doesn't make
+ * sense. 'Including' means that everything not mentioned is
+ * excluded. 'Excluding' means that everything not mentioned is
+ * included. So using the two together would be meaningless.
+ */
+ if (include)
+ disp->types_inc |= type;
+ else
+ disp->types_exc |= type;
+ if (disp->types_inc & disp->types_exc & type) {
+ fprintf(stderr,
+ "Cannot use both include and exclude for '%s'\n", str);
+ return -1;
+ }
+
+ str = strdup(str);
+ node = malloc(sizeof(*node));
+ if (!str || !node) {
+ fprintf(stderr, "Out of memory\n");
+ return -1;
+ }
+ node->next = *headp;
+ node->type = type;
+ node->include = include;
+ node->string = str;
+ *headp = node;
+
+ return 0;
+}
+
+static bool util_is_printable_string(const void *data, int len)
+{
+ const char *s = data;
+ const char *ss, *se;
+
+ /* zero length is not */
+ if (len == 0)
+ return 0;
+
+ /* must terminate with zero */
+ if (s[len - 1] != '\0')
+ return 0;
+
+ se = s + len;
+
+ while (s < se) {
+ ss = s;
+ while (s < se && *s && isprint((unsigned char)*s))
+ s++;
+
+ /* not zero, or not done yet */
+ if (*s != '\0' || s == ss)
+ return 0;
+
+ s++;
+ }
+
+ return 1;
+}
+
+static void utilfdt_print_data(const char *data, int len)
+{
+ int i;
+ const char *p = data;
+ const char *s;
+
+ /* no data, don't print */
+ if (len == 0)
+ return;
+
+ if (util_is_printable_string(data, len)) {
+ printf(" = ");
+
+ s = data;
+ do {
+ printf("\"%s\"", s);
+ s += strlen(s) + 1;
+ if (s < data + len)
+ printf(", ");
+ } while (s < data + len);
+
+ } else if ((len % 4) == 0) {
+ const uint32_t *cell = (const uint32_t *)data;
+
+ printf(" = <");
+ for (i = 0, len /= 4; i < len; i++)
+ printf("0x%08x%s", fdt32_to_cpu(cell[i]),
+ i < (len - 1) ? " " : "");
+ printf(">");
+ } else {
+ printf(" = [");
+ for (i = 0; i < len; i++)
+ printf("%02x%s", *p++, i < len - 1 ? " " : "");
+ printf("]");
+ }
+}
+
+/**
+ * display_fdt_by_regions() - Display regions of an FDT source
+ *
+ * This dumps an FDT as source, but only certain regions of it. This is the
+ * final stage of the grep - we have a list of regions we want to display,
+ * and this function displays them.
+ *
+ * @disp: Display structure, holding info about our options
+ * @blob: FDT blob to display
+ * @region: List of regions to display
+ * @count: Number of regions
+ */
+static int display_fdt_by_regions(struct display_info *disp, const void *blob,
+ struct fdt_region region[], int count)
+{
+ struct fdt_region *reg = region, *reg_end = region + count;
+ uint32_t off_mem_rsvmap = fdt_off_mem_rsvmap(blob);
+ int base = fdt_off_dt_struct(blob);
+ int version = fdt_version(blob);
+ int offset, nextoffset;
+ int tag, depth, shift;
+ FILE *f = disp->fout;
+ uint64_t addr, size;
+ int in_region;
+ int file_ofs;
+ int i;
+
+ if (disp->show_dts_version)
+ fprintf(f, "/dts-v1/;\n");
+
+ if (disp->header) {
+ fprintf(f, "// magic:\t\t0x%x\n", fdt_magic(blob));
+ fprintf(f, "// totalsize:\t\t0x%x (%d)\n", fdt_totalsize(blob),
+ fdt_totalsize(blob));
+ fprintf(f, "// off_dt_struct:\t0x%x\n",
+ fdt_off_dt_struct(blob));
+ fprintf(f, "// off_dt_strings:\t0x%x\n",
+ fdt_off_dt_strings(blob));
+ fprintf(f, "// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
+ fprintf(f, "// version:\t\t%d\n", version);
+ fprintf(f, "// last_comp_version:\t%d\n",
+ fdt_last_comp_version(blob));
+ if (version >= 2) {
+ fprintf(f, "// boot_cpuid_phys:\t0x%x\n",
+ fdt_boot_cpuid_phys(blob));
+ }
+ if (version >= 3) {
+ fprintf(f, "// size_dt_strings:\t0x%x\n",
+ fdt_size_dt_strings(blob));
+ }
+ if (version >= 17) {
+ fprintf(f, "// size_dt_struct:\t0x%x\n",
+ fdt_size_dt_struct(blob));
+ }
+ fprintf(f, "\n");
+ }
+
+ if (disp->flags & FDT_REG_ADD_MEM_RSVMAP) {
+ const struct fdt_reserve_entry *p_rsvmap;
+
+ p_rsvmap = (const struct fdt_reserve_entry *)
+ ((const char *)blob + off_mem_rsvmap);
+ for (i = 0; ; i++) {
+ addr = fdt64_to_cpu(p_rsvmap[i].address);
+ size = fdt64_to_cpu(p_rsvmap[i].size);
+ if (addr == 0 && size == 0)
+ break;
+
+ fprintf(f, "/memreserve/ %llx %llx;\n",
+ (unsigned long long)addr,
+ (unsigned long long)size);
+ }
+ }
+
+ depth = 0;
+ nextoffset = 0;
+ shift = 4; /* 4 spaces per indent */
+ do {
+ const struct fdt_property *prop;
+ const char *name;
+ int show;
+ int len;
+
+ offset = nextoffset;
+
+ /*
+ * Work out the file offset of this offset, and decide
+ * whether it is in the region list or not
+ */
+ file_ofs = base + offset;
+ if (reg < reg_end && file_ofs >= reg->offset + reg->size)
+ reg++;
+ in_region = reg < reg_end && file_ofs >= reg->offset &&
+ file_ofs < reg->offset + reg->size;
+ tag = fdt_next_tag(blob, offset, &nextoffset);
+
+ if (tag == FDT_END)
+ break;
+ show = in_region || disp->all;
+ if (show && disp->diff)
+ fprintf(f, "%c", in_region ? '+' : '-');
+
+ if (!show) {
+ /* Do this here to avoid 'if (show)' in every 'case' */
+ if (tag == FDT_BEGIN_NODE)
+ depth++;
+ else if (tag == FDT_END_NODE)
+ depth--;
+ continue;
+ }
+ if (tag != FDT_END) {
+ if (disp->show_addr)
+ fprintf(f, "%4x: ", file_ofs);
+ if (disp->show_offset)
+ fprintf(f, "%4x: ", file_ofs - base);
+ }
+
+ /* Green means included, red means excluded */
+ if (disp->colour)
+ print_ansi_colour(f, in_region ? COL_GREEN : COL_RED);
+
+ switch (tag) {
+ case FDT_PROP:
+ prop = fdt_get_property_by_offset(blob, offset, NULL);
+ name = fdt_string(blob, fdt32_to_cpu(prop->nameoff));
+ fprintf(f, "%*s%s", depth * shift, "", name);
+ utilfdt_print_data(prop->data,
+ fdt32_to_cpu(prop->len));
+ fprintf(f, ";");
+ break;
+
+ case FDT_NOP:
+ fprintf(f, "%*s// [NOP]", depth * shift, "");
+ break;
+
+ case FDT_BEGIN_NODE:
+ name = fdt_get_name(blob, offset, &len);
+ fprintf(f, "%*s%s {", depth++ * shift, "",
+ *name ? name : "/");
+ break;
+
+ case FDT_END_NODE:
+ fprintf(f, "%*s};", --depth * shift, "");
+ break;
+ }
+
+ /* Reset colour back to normal before end of line */
+ if (disp->colour)
+ print_ansi_colour(f, COL_NONE);
+ fprintf(f, "\n");
+ } while (1);
+
+ /* Print a list of strings if requested */
+ if (disp->list_strings) {
+ const char *str;
+ int str_base = fdt_off_dt_strings(blob);
+
+ for (offset = 0; offset < fdt_size_dt_strings(blob);
+ offset += strlen(str) + 1) {
+ str = fdt_string(blob, offset);
+ int len = strlen(str) + 1;
+ int show;
+
+ /* Only print strings that are in the region */
+ file_ofs = str_base + offset;
+ in_region = reg < reg_end &&
+ file_ofs >= reg->offset &&
+ file_ofs + len < reg->offset +
+ reg->size;
+ show = in_region || disp->all;
+ if (show && disp->diff)
+ printf("%c", in_region ? '+' : '-');
+ if (disp->show_addr)
+ printf("%4x: ", file_ofs);
+ if (disp->show_offset)
+ printf("%4x: ", offset);
+ printf("%s\n", str);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * dump_fdt_regions() - Dump regions of an FDT as binary data
+ *
+ * This dumps an FDT as binary, but only certain regions of it. This is the
+ * final stage of the grep - we have a list of regions we want to dump,
+ * and this function dumps them.
+ *
+ * The output of this function may or may not be a valid FDT. To ensure it
+ * is, these disp->flags must be set:
+ *
+ * FDT_REG_SUPERNODES: ensures that subnodes are preceeded by their
+ * parents. Without this option, fragments of subnode data may be
+ * output without the supernodes above them. This is useful for
+ * hashing but cannot produce a valid FDT.
+ * FDT_REG_ADD_STRING_TAB: Adds a string table to the end of the FDT.
+ * Without this none of the properties will have names
+ * FDT_REG_ADD_MEM_RSVMAP: Adds a mem_rsvmap table - an FDT is invalid
+ * without this.
+ *
+ * @disp: Display structure, holding info about our options
+ * @blob: FDT blob to display
+ * @region: List of regions to display
+ * @count: Number of regions
+ * @out: Output destination
+ */
+static int dump_fdt_regions(struct display_info *disp, const void *blob,
+ struct fdt_region region[], int count, char *out)
+{
+ struct fdt_header *fdt;
+ int size, struct_start;
+ int ptr;
+ int i;
+
+ /* Set up a basic header (even if we don't actually write it) */
+ fdt = (struct fdt_header *)out;
+ memset(fdt, '\0', sizeof(*fdt));
+ fdt_set_magic(fdt, FDT_MAGIC);
+ struct_start = FDT_ALIGN(sizeof(struct fdt_header),
+ sizeof(struct fdt_reserve_entry));
+ fdt_set_off_mem_rsvmap(fdt, struct_start);
+ fdt_set_version(fdt, FDT_LAST_SUPPORTED_VERSION);
+ fdt_set_last_comp_version(fdt, FDT_FIRST_SUPPORTED_VERSION);
+
+ /*
+ * Calculate the total size of the regions we are writing out. The
+ * first will be the mem_rsvmap if the FDT_REG_ADD_MEM_RSVMAP flag
+ * is set. The last will be the string table if FDT_REG_ADD_STRING_TAB
+ * is set.
+ */
+ for (i = size = 0; i < count; i++)
+ size += region[i].size;
+
+ /* Bring in the mem_rsvmap section from the old file if requested */
+ if (count > 0 && (disp->flags & FDT_REG_ADD_MEM_RSVMAP)) {
+ struct_start += region[0].size;
+ size -= region[0].size;
+ }
+ fdt_set_off_dt_struct(fdt, struct_start);
+
+ /* Update the header to have the correct offsets/sizes */
+ if (count >= 2 && (disp->flags & FDT_REG_ADD_STRING_TAB)) {
+ int str_size;
+
+ str_size = region[count - 1].size;
+ fdt_set_size_dt_struct(fdt, size - str_size);
+ fdt_set_off_dt_strings(fdt, struct_start + size - str_size);
+ fdt_set_size_dt_strings(fdt, str_size);
+ fdt_set_totalsize(fdt, struct_start + size);
+ }
+
+ /* Write the header if required */
+ ptr = 0;
+ if (disp->header) {
+ ptr = sizeof(*fdt);
+ while (ptr < fdt_off_mem_rsvmap(fdt))
+ out[ptr++] = '\0';
+ }
+
+ /* Output all the nodes including any mem_rsvmap/string table */
+ for (i = 0; i < count; i++) {
+ struct fdt_region *reg = ®ion[i];
+
+ memcpy(out + ptr, (const char *)blob + reg->offset, reg->size);
+ ptr += reg->size;
+ }
+
+ return ptr;
+}
+
+/**
+ * show_region_list() - Print out a list of regions
+ *
+ * The list includes the region offset (absolute offset from start of FDT
+ * blob in bytes) and size
+ *
+ * @reg: List of regions to print
+ * @count: Number of regions
+ */
+static void show_region_list(struct fdt_region *reg, int count)
+{
+ int i;
+
+ printf("Regions: %d\n", count);
+ for (i = 0; i < count; i++, reg++) {
+ printf("%d: %-10x %-10x\n", i, reg->offset,
+ reg->offset + reg->size);
+ }
+}
+
+static int check_type_include(void *priv, int type, const char *data, int size)
+{
+ struct display_info *disp = priv;
+ struct value_node *val;
+ int match, none_match = FDT_IS_ANY;
+
+ /* If none of our conditions mention this type, we know nothing */
+ debug("type=%x, data=%s\n", type, data ? data : "(null)");
+ if (!((disp->types_inc | disp->types_exc) & type)) {
+ debug(" - not in any condition\n");
+ return -1;
+ }
+
+ /*
+ * Go through the list of conditions. For inclusive conditions, we
+ * return 1 at the first match. For exclusive conditions, we must
+ * check that there are no matches.
+ */
+ for (val = disp->value_head; val; val = val->next) {
+ if (!(type & val->type))
+ continue;
+ match = fdt_stringlist_contains(data, size, val->string);
+ debug(" - val->type=%x, str='%s', match=%d\n",
+ val->type, val->string, match);
+ if (match && val->include) {
+ debug(" - match inc %s\n", val->string);
+ return 1;
+ }
+ if (match)
+ none_match &= ~val->type;
+ }
+
+ /*
+ * If this is an exclusive condition, and nothing matches, then we
+ * should return 1.
+ */
+ if ((type & disp->types_exc) && (none_match & type)) {
+ debug(" - match exc\n");
+ /*
+ * Allow FDT_IS_COMPAT to make the final decision in the
+ * case where there is no specific type
+ */
+ if (type == FDT_IS_NODE && disp->types_exc == FDT_ANY_GLOBAL) {
+ debug(" - supressed exc node\n");
+ return -1;
+ }
+ return 1;
+ }
+
+ /*
+ * Allow FDT_IS_COMPAT to make the final decision in the
+ * case where there is no specific type (inclusive)
+ */
+ if (type == FDT_IS_NODE && disp->types_inc == FDT_ANY_GLOBAL)
+ return -1;
+
+ debug(" - no match, types_inc=%x, types_exc=%x, none_match=%x\n",
+ disp->types_inc, disp->types_exc, none_match);
+
+ return 0;
+}
+
+/**
+ * h_include() - Include handler function for fdt_find_regions()
+ *
+ * This function decides whether to include or exclude a node, property or
+ * compatible string. The function is defined by fdt_find_regions().
+ *
+ * The algorithm is documented in the code - disp->invert is 0 for normal
+ * operation, and 1 to invert the sense of all matches.
+ *
+ * See
+ */
+static int h_include(void *priv, const void *fdt, int offset, int type,
+ const char *data, int size)
+{
+ struct display_info *disp = priv;
+ int inc, len;
+
+ inc = check_type_include(priv, type, data, size);
+ if (disp->include_root && type == FDT_IS_PROP && offset == 0 && inc)
+ return 1;
+
+ /*
+ * If the node name does not tell us anything, check the
+ * compatible string
+ */
+ if (inc == -1 && type == FDT_IS_NODE) {
+ debug(" - checking compatible2\n");
+ data = fdt_getprop(fdt, offset, "compatible", &len);
+ inc = check_type_include(priv, FDT_IS_COMPAT, data, len);
+ }
+
+ /* If we still have no idea, check for properties in the node */
+ if (inc != 1 && type == FDT_IS_NODE &&
+ (disp->types_inc & FDT_NODE_HAS_PROP)) {
+ debug(" - checking node '%s'\n",
+ fdt_get_name(fdt, offset, NULL));
+ for (offset = fdt_first_property_offset(fdt, offset);
+ offset > 0 && inc != 1;
+ offset = fdt_next_property_offset(fdt, offset)) {
+ const struct fdt_property *prop;
+ const char *str;
+
+ prop = fdt_get_property_by_offset(fdt, offset, NULL);
+ if (!prop)
+ continue;
+ str = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));
+ inc = check_type_include(priv, FDT_NODE_HAS_PROP, str,
+ strlen(str));
+ }
+ if (inc == -1)
+ inc = 0;
+ }
+
+ switch (inc) {
+ case 1:
+ inc = !disp->invert;
+ break;
+ case 0:
+ inc = disp->invert;
+ break;
+ }
+ debug(" - returning %d\n", inc);
+
+ return inc;
+}
+
+static int h_cmp_region(const void *v1, const void *v2)
+{
+ const struct fdt_region *region1 = v1, *region2 = v2;
+
+ return region1->offset - region2->offset;
+}
+
+static int fdtgrep_find_regions(const void *fdt,
+ int (*include_func)(void *priv, const void *fdt, int offset,
+ int type, const char *data, int size),
+ struct display_info *disp, struct fdt_region *region,
+ int max_regions, char *path, int path_len, int flags)
+{
+ struct fdt_region_state state;
+ int count;
+ int ret;
+
+ count = 0;
+ ret = fdt_first_region(fdt, include_func, disp,
+ ®ion[count++], path, path_len,
+ disp->flags, &state);
+ while (ret == 0) {
+ ret = fdt_next_region(fdt, include_func, disp,
+ count < max_regions ? ®ion[count] : NULL,
+ path, path_len, disp->flags, &state);
+ if (!ret)
+ count++;
+ }
+
+ /* Find all the aliases and add those regions back in */
+ if (disp->add_aliases && count < max_regions) {
+ int new_count;
+
+ new_count = fdt_add_alias_regions(fdt, region, count,
+ max_regions, &state);
+ if (new_count > max_regions) {
+ region = malloc(new_count * sizeof(struct fdt_region));
+ if (!region) {
+ fprintf(stderr,
+ "Out of memory for %d regions\n",
+ count);
+ return -1;
+ }
+ memcpy(region, state.region,
+ count * sizeof(struct fdt_region));
+ free(state.region);
+ new_count = fdt_add_alias_regions(fdt, region, count,
+ max_regions, &state);
+ }
+
+ /*
+ * The alias regions will now be at the end of the list. Sort
+ * the regions by offset to get things into the right order
+ */
+ qsort(region, new_count, sizeof(struct fdt_region),
+ h_cmp_region);
+ count = new_count;
+ }
+
+ if (ret != -FDT_ERR_NOTFOUND)
+ return ret;
+
+ return count;
+}
+
+int utilfdt_read_err_len(const char *filename, char **buffp, off_t *len)
+{
+ int fd = 0; /* assume stdin */
+ char *buf = NULL;
+ off_t bufsize = 1024, offset = 0;
+ int ret = 0;
+
+ *buffp = NULL;
+ if (strcmp(filename, "-") != 0) {
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ return errno;
+ }
+
+ /* Loop until we have read everything */
+ buf = malloc(bufsize);
+ if (!buf)
+ return -ENOMEM;
+ do {
+ /* Expand the buffer to hold the next chunk */
+ if (offset == bufsize) {
+ bufsize *= 2;
+ buf = realloc(buf, bufsize);
+ if (!buf)
+ return -ENOMEM;
+ }
+
+ ret = read(fd, &buf[offset], bufsize - offset);
+ if (ret < 0) {
+ ret = errno;
+ break;
+ }
+ offset += ret;
+ } while (ret != 0);
+
+ /* Clean up, including closing stdin; return errno on error */
+ close(fd);
+ if (ret)
+ free(buf);
+ else
+ *buffp = buf;
+ *len = bufsize;
+ return ret;
+}
+
+int utilfdt_read_err(const char *filename, char **buffp)
+{
+ off_t len;
+ return utilfdt_read_err_len(filename, buffp, &len);
+}
+
+char *utilfdt_read_len(const char *filename, off_t *len)
+{
+ char *buff;
+ int ret = utilfdt_read_err_len(filename, &buff, len);
+
+ if (ret) {
+ fprintf(stderr, "Couldn't open blob from '%s': %s\n", filename,
+ strerror(ret));
+ return NULL;
+ }
+ /* Successful read */
+ return buff;
+}
+
+char *utilfdt_read(const char *filename)
+{
+ off_t len;
+ return utilfdt_read_len(filename, &len);
+}
+
+/**
+ * Run the main fdtgrep operation, given a filename and valid arguments
+ *
+ * @param disp Display information / options
+ * @param filename Filename of blob file
+ * @param return 0 if ok, -ve on error
+ */
+static int do_fdtgrep(struct display_info *disp, const char *filename)
+{
+ struct fdt_region *region;
+ int max_regions;
+ int count = 100;
+ char path[1024];
+ char *blob;
+ int i, ret;
+
+ blob = utilfdt_read(filename);
+ if (!blob)
+ return -1;
+ ret = fdt_check_header(blob);
+ if (ret) {
+ fprintf(stderr, "Error: %s\n", fdt_strerror(ret));
+ return ret;
+ }
+
+ /* Allow old files, but they are untested */
+ if (fdt_version(blob) < 17 && disp->value_head) {
+ fprintf(stderr,
+ "Warning: fdtgrep does not fully support version %d files\n",
+ fdt_version(blob));
+ }
+
+ /*
+ * We do two passes, since we don't know how many regions we need.
+ * The first pass will count the regions, but if it is too many,
+ * we do another pass to actually record them.
+ */
+ for (i = 0; i < 2; i++) {
+ region = malloc(count * sizeof(struct fdt_region));
+ if (!region) {
+ fprintf(stderr, "Out of memory for %d regions\n",
+ count);
+ return -1;
+ }
+ max_regions = count;
+ count = fdtgrep_find_regions(blob,
+ h_include, disp,
+ region, max_regions, path, sizeof(path),
+ disp->flags);
+ if (count < 0) {
+ report_error("fdt_find_regions", count);
+ return -1;
+ }
+ if (count <= max_regions)
+ break;
+ free(region);
+ }
+
+ /* Optionally print a list of regions */
+ if (disp->region_list)
+ show_region_list(region, count);
+
+ /* Output either source .dts or binary .dtb */
+ if (disp->output == OUT_DTS) {
+ ret = display_fdt_by_regions(disp, blob, region, count);
+ } else {
+ void *fdt;
+ /* Allow reserved memory section to expand slightly */
+ int size = fdt_totalsize(blob) + 16;
+
+ fdt = malloc(size);
+ if (!fdt) {
+ fprintf(stderr, "Out_of_memory\n");
+ ret = -1;
+ goto err;
+ }
+ size = dump_fdt_regions(disp, blob, region, count, fdt);
+ if (disp->remove_strings) {
+ void *out;
+
+ out = malloc(size);
+ if (!out) {
+ fprintf(stderr, "Out_of_memory\n");
+ ret = -1;
+ goto err;
+ }
+ ret = fdt_remove_unused_strings(fdt, out);
+ if (ret < 0) {
+ fprintf(stderr,
+ "Failed to remove unused strings: err=%d\n",
+ ret);
+ goto err;
+ }
+ free(fdt);
+ fdt = out;
+ ret = fdt_pack(fdt);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to pack: err=%d\n",
+ ret);
+ goto err;
+ }
+ size = fdt_totalsize(fdt);
+ }
+
+ if (size != fwrite(fdt, 1, size, disp->fout)) {
+ fprintf(stderr, "Write failure, %d bytes\n", size);
+ free(fdt);
+ ret = 1;
+ goto err;
+ }
+ free(fdt);
+ }
+err:
+ free(blob);
+ free(region);
+
+ return ret;
+}
+
+static const char usage_synopsis[] =
+ "fdtgrep - extract portions from device tree\n"
+ "\n"
+ "Usage:\n"
+ " fdtgrep <options> <dt file>|-\n\n"
+ "Output formats are:\n"
+ "\tdts - device tree soure text\n"
+ "\tdtb - device tree blob (sets -Hmt automatically)\n"
+ "\tbin - device tree fragment (may not be a valid .dtb)";
+
+/* Helper for usage_short_opts string constant */
+#define USAGE_COMMON_SHORT_OPTS "hV"
+
+/* Helper for aligning long_opts array */
+#define a_argument required_argument
+
+/* Helper for usage_long_opts option array */
+#define USAGE_COMMON_LONG_OPTS \
+ {"help", no_argument, NULL, 'h'}, \
+ {"version", no_argument, NULL, 'V'}, \
+ {NULL, no_argument, NULL, 0x0}
+
+/* Helper for usage_opts_help array */
+#define USAGE_COMMON_OPTS_HELP \
+ "Print this help and exit", \
+ "Print version and exit", \
+ NULL
+
+/* Helper for getopt case statements */
+#define case_USAGE_COMMON_FLAGS \
+ case 'h': usage(NULL); \
+ case 'V': util_version(); \
+ case '?': usage("unknown option");
+
+static const char usage_short_opts[] =
+ "haAc:b:C:defg:G:HIlLmn:N:o:O:p:P:rRsStTv"
+ USAGE_COMMON_SHORT_OPTS;
+static struct option const usage_long_opts[] = {
+ {"show-address", no_argument, NULL, 'a'},
+ {"colour", no_argument, NULL, 'A'},
+ {"include-node-with-prop", a_argument, NULL, 'b'},
+ {"include-compat", a_argument, NULL, 'c'},
+ {"exclude-compat", a_argument, NULL, 'C'},
+ {"diff", no_argument, NULL, 'd'},
+ {"enter-node", no_argument, NULL, 'e'},
+ {"show-offset", no_argument, NULL, 'f'},
+ {"include-match", a_argument, NULL, 'g'},
+ {"exclude-match", a_argument, NULL, 'G'},
+ {"show-header", no_argument, NULL, 'H'},
+ {"show-version", no_argument, NULL, 'I'},
+ {"list-regions", no_argument, NULL, 'l'},
+ {"list-strings", no_argument, NULL, 'L'},
+ {"include-mem", no_argument, NULL, 'm'},
+ {"include-node", a_argument, NULL, 'n'},
+ {"exclude-node", a_argument, NULL, 'N'},
+ {"include-prop", a_argument, NULL, 'p'},
+ {"exclude-prop", a_argument, NULL, 'P'},
+ {"remove-strings", no_argument, NULL, 'r'},
+ {"include-root", no_argument, NULL, 'R'},
+ {"show-subnodes", no_argument, NULL, 's'},
+ {"skip-supernodes", no_argument, NULL, 'S'},
+ {"show-stringtab", no_argument, NULL, 't'},
+ {"show-aliases", no_argument, NULL, 'T'},
+ {"out", a_argument, NULL, 'o'},
+ {"out-format", a_argument, NULL, 'O'},
+ {"invert-match", no_argument, NULL, 'v'},
+ USAGE_COMMON_LONG_OPTS,
+};
+static const char * const usage_opts_help[] = {
+ "Display address",
+ "Show all nodes/tags, colour those that match",
+ "Include contains containing property",
+ "Compatible nodes to include in grep",
+ "Compatible nodes to exclude in grep",
+ "Diff: Mark matching nodes with +, others with -",
+ "Enter direct subnode names of matching nodes",
+ "Display offset",
+ "Node/property/compatible string to include in grep",
+ "Node/property/compatible string to exclude in grep",
+ "Output a header",
+ "Put \"/dts-v1/;\" on first line of dts output",
+ "Output a region list",
+ "List strings in string table",
+ "Include mem_rsvmap section in binary output",
+ "Node to include in grep",
+ "Node to exclude in grep",
+ "Property to include in grep",
+ "Property to exclude in grep",
+ "Remove unused strings from string table",
+ "Include root node and all properties",
+ "Show all subnodes matching nodes",
+ "Don't include supernodes of matching nodes",
+ "Include string table in binary output",
+ "Include matching aliases in output",
+ "-o <output file>",
+ "-O <output format>",
+ "Invert the sense of matching (select non-matching lines)",
+ USAGE_COMMON_OPTS_HELP
+};
+
+/**
+ * Call getopt_long() with standard options
+ *
+ * Since all util code runs getopt in the same way, provide a helper.
+ */
+#define util_getopt_long() getopt_long(argc, argv, usage_short_opts, \
+ usage_long_opts, NULL)
+
+void util_usage(const char *errmsg, const char *synopsis,
+ const char *short_opts, struct option const long_opts[],
+ const char * const opts_help[])
+{
+ FILE *fp = errmsg ? stderr : stdout;
+ const char a_arg[] = "<arg>";
+ size_t a_arg_len = strlen(a_arg) + 1;
+ size_t i;
+ int optlen;
+
+ fprintf(fp,
+ "Usage: %s\n"
+ "\n"
+ "Options: -[%s]\n", synopsis, short_opts);
+
+ /* prescan the --long opt length to auto-align */
+ optlen = 0;
+ for (i = 0; long_opts[i].name; ++i) {
+ /* +1 is for space between --opt and help text */
+ int l = strlen(long_opts[i].name) + 1;
+ if (long_opts[i].has_arg == a_argument)
+ l += a_arg_len;
+ if (optlen < l)
+ optlen = l;
+ }
+
+ for (i = 0; long_opts[i].name; ++i) {
+ /* helps when adding new applets or options */
+ assert(opts_help[i] != NULL);
+
+ /* first output the short flag if it has one */
+ if (long_opts[i].val > '~')
+ fprintf(fp, " ");
+ else
+ fprintf(fp, " -%c, ", long_opts[i].val);
+
+ /* then the long flag */
+ if (long_opts[i].has_arg == no_argument) {
+ fprintf(fp, "--%-*s", optlen, long_opts[i].name);
+ } else {
+ fprintf(fp, "--%s %s%*s", long_opts[i].name, a_arg,
+ (int)(optlen - strlen(long_opts[i].name) -
+ a_arg_len), "");
+ }
+
+ /* finally the help text */
+ fprintf(fp, "%s\n", opts_help[i]);
+ }
+
+ if (errmsg) {
+ fprintf(fp, "\nError: %s\n", errmsg);
+ exit(EXIT_FAILURE);
+ } else {
+ exit(EXIT_SUCCESS);
+ }
+}
+
+/**
+ * Show usage and exit
+ *
+ * If you name all your usage variables with usage_xxx, then you can call this
+ * help macro rather than expanding all arguments yourself.
+ *
+ * @param errmsg If non-NULL, an error message to display
+ */
+#define usage(errmsg) \
+ util_usage(errmsg, usage_synopsis, usage_short_opts, \
+ usage_long_opts, usage_opts_help)
+
+void util_version(void)
+{
+ printf("Version: %s\n", "(U-Boot)");
+ exit(0);
+}
+
+static void scan_args(struct display_info *disp, int argc, char *argv[])
+{
+ int opt;
+
+ while ((opt = util_getopt_long()) != EOF) {
+ int type = 0;
+ int inc = 1;
+
+ switch (opt) {
+ case_USAGE_COMMON_FLAGS
+ case 'a':
+ disp->show_addr = 1;
+ break;
+ case 'A':
+ disp->all = 1;
+ break;
+ case 'b':
+ type = FDT_NODE_HAS_PROP;
+ break;
+ case 'C':
+ inc = 0;
+ /* no break */
+ case 'c':
+ type = FDT_IS_COMPAT;
+ break;
+ case 'd':
+ disp->diff = 1;
+ break;
+ case 'e':
+ disp->flags |= FDT_REG_DIRECT_SUBNODES;
+ break;
+ case 'f':
+ disp->show_offset = 1;
+ break;
+ case 'G':
+ inc = 0;
+ /* no break */
+ case 'g':
+ type = FDT_ANY_GLOBAL;
+ break;
+ case 'H':
+ disp->header = 1;
+ break;
+ case 'l':
+ disp->region_list = 1;
+ break;
+ case 'L':
+ disp->list_strings = 1;
+ break;
+ case 'm':
+ disp->flags |= FDT_REG_ADD_MEM_RSVMAP;
+ break;
+ case 'N':
+ inc = 0;
+ /* no break */
+ case 'n':
+ type = FDT_IS_NODE;
+ break;
+ case 'o':
+ disp->output_fname = optarg;
+ break;
+ case 'O':
+ if (!strcmp(optarg, "dtb"))
+ disp->output = OUT_DTB;
+ else if (!strcmp(optarg, "dts"))
+ disp->output = OUT_DTS;
+ else if (!strcmp(optarg, "bin"))
+ disp->output = OUT_BIN;
+ else
+ usage("Unknown output format");
+ break;
+ case 'P':
+ inc = 0;
+ /* no break */
+ case 'p':
+ type = FDT_IS_PROP;
+ break;
+ case 'r':
+ disp->remove_strings = 1;
+ break;
+ case 'R':
+ disp->include_root = 1;
+ break;
+ case 's':
+ disp->flags |= FDT_REG_ALL_SUBNODES;
+ break;
+ case 'S':
+ disp->flags &= ~FDT_REG_SUPERNODES;
+ break;
+ case 't':
+ disp->flags |= FDT_REG_ADD_STRING_TAB;
+ break;
+ case 'T':
+ disp->add_aliases = 1;
+ break;
+ case 'v':
+ disp->invert = 1;
+ break;
+ case 'I':
+ disp->show_dts_version = 1;
+ break;
+ }
+
+ if (type && value_add(disp, &disp->value_head, type, inc,
+ optarg))
+ usage("Cannot add value");
+ }
+
+ if (disp->invert && disp->types_exc)
+ usage("-v has no meaning when used with 'exclude' conditions");
+}
+
+int main(int argc, char *argv[])
+{
+ char *filename = NULL;
+ struct display_info disp;
+ int ret;
+
+ /* set defaults */
+ memset(&disp, '\0', sizeof(disp));
+ disp.flags = FDT_REG_SUPERNODES; /* Default flags */
+
+ scan_args(&disp, argc, argv);
+
+ /* Show matched lines in colour if we can */
+ disp.colour = disp.all && isatty(0);
+
+ /* Any additional arguments can match anything, just like -g */
+ while (optind < argc - 1) {
+ if (value_add(&disp, &disp.value_head, FDT_IS_ANY, 1,
+ argv[optind++]))
+ usage("Cannot add value");
+ }
+
+ if (optind < argc)
+ filename = argv[optind++];
+ if (!filename)
+ usage("Missing filename");
+
+ /* If a valid .dtb is required, set flags to ensure we get one */
+ if (disp.output == OUT_DTB) {
+ disp.header = 1;
+ disp.flags |= FDT_REG_ADD_MEM_RSVMAP | FDT_REG_ADD_STRING_TAB;
+ }
+
+ if (disp.output_fname) {
+ disp.fout = fopen(disp.output_fname, "w");
+ if (!disp.fout)
+ usage("Cannot open output file");
+ } else {
+ disp.fout = stdout;
+ }
+
+ /* Run the grep and output the results */
+ ret = do_fdtgrep(&disp, filename);
+ if (disp.output_fname)
+ fclose(disp.fout);
+ if (ret)
+ return 1;
+
+ return 0;
+}
const char *keydest; /* Destination .dtb for public key */
const char *comment; /* Comment to add to signature node */
int require_keys; /* 1 to mark signing keys as 'required' */
+ int file_size; /* Total size of output file */
};
/*
{ 0x78, "sata" },
{ 0x9C, "pex" },
{ 0x69, "uart" },
+ { 0xAE, "sdio" },
{},
};
*hasext = 1;
}
-#if defined(CONFIG_SYS_SPI_U_BOOT_OFFS)
- if (headersz > CONFIG_SYS_SPI_U_BOOT_OFFS) {
+#if defined(CONFIG_SYS_U_BOOT_OFFS)
+ if (headersz > CONFIG_SYS_U_BOOT_OFFS) {
fprintf(stderr, "Error: Image header (incl. SPL image) too big!\n");
- fprintf(stderr, "header=0x%x CONFIG_SYS_SPI_U_BOOT_OFFS=0x%x!\n",
- (int)headersz, CONFIG_SYS_SPI_U_BOOT_OFFS);
- fprintf(stderr, "Increase CONFIG_SYS_SPI_U_BOOT_OFFS!\n");
+ fprintf(stderr, "header=0x%x CONFIG_SYS_U_BOOT_OFFS=0x%x!\n",
+ (int)headersz, CONFIG_SYS_U_BOOT_OFFS);
+ fprintf(stderr, "Increase CONFIG_SYS_U_BOOT_OFFS!\n");
return 0;
} else {
- headersz = CONFIG_SYS_SPI_U_BOOT_OFFS;
+ headersz = CONFIG_SYS_U_BOOT_OFFS;
}
#endif
.imagename2 = "",
};
-int
-main (int argc, char **argv)
+static int h_compare_image_name(const void *vtype1, const void *vtype2)
+{
+ const int *type1 = vtype1;
+ const int *type2 = vtype2;
+ const char *name1 = genimg_get_type_short_name(*type1);
+ const char *name2 = genimg_get_type_short_name(*type2);
+
+ return strcmp(name1, name2);
+}
+
+/* Show all image types supported by mkimage */
+static void show_image_types(void)
+{
+ struct image_type_params *tparams;
+ int order[IH_TYPE_COUNT];
+ int count;
+ int type;
+ int i;
+
+ /* Sort the names in order of short name for easier reading */
+ memset(order, '\0', sizeof(order));
+ for (count = 0, type = 0; type < IH_TYPE_COUNT; type++) {
+ tparams = imagetool_get_type(type);
+ if (tparams)
+ order[count++] = type;
+ }
+ qsort(order, count, sizeof(int), h_compare_image_name);
+
+ fprintf(stderr, "\nInvalid image type. Supported image types:\n");
+ for (i = 0; i < count; i++) {
+ type = order[i];
+ tparams = imagetool_get_type(type);
+ if (tparams) {
+ fprintf(stderr, "\t%-15s %s\n",
+ genimg_get_type_short_name(type),
+ genimg_get_type_name(type));
+ }
+ }
+ fprintf(stderr, "\n");
+}
+
+int main(int argc, char **argv)
{
int ifd = -1;
struct stat sbuf;
int retval = 0;
struct image_type_params *tparams = NULL;
int pad_len = 0;
+ int dfd;
params.cmdname = *argv;
params.addr = params.ep = 0;
usage ();
goto NXTARG;
case 'T':
- if ((--argc <= 0) ||
- (params.type =
- genimg_get_type_id (*++argv)) < 0)
- usage ();
+ params.type = -1;
+ if (--argc >= 0 && argv[1]) {
+ params.type =
+ genimg_get_type_id(*++argv);
+ }
+ if (params.type < 0) {
+ show_image_types();
+ usage();
+ }
goto NXTARG;
-
case 'a':
if (--argc <= 0)
usage ();
exit (retval);
}
+ dfd = open(params.datafile, O_RDONLY | O_BINARY);
+ if (dfd < 0) {
+ fprintf(stderr, "%s: Can't open %s: %s\n",
+ params.cmdname, params.datafile, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ if (fstat(dfd, &sbuf) < 0) {
+ fprintf(stderr, "%s: Can't stat %s: %s\n",
+ params.cmdname, params.datafile, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ params.file_size = sbuf.st_size + tparams->header_size;
+ close(dfd);
+
/*
* In case there an header with a variable
* length will be added, the corresponding
params.cmdname, params.imagefile, strerror(errno));
exit (EXIT_FAILURE);
}
+ params.file_size = sbuf.st_size;
ptr = mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0);
if (ptr == MAP_FAILED) {
#endif
fprintf (stderr, " %s -V ==> print version information and exit\n",
params.cmdname);
+ fprintf(stderr, "Use -T to see a list of available image types\n");
exit (EXIT_FAILURE);
}
+++ /dev/null
-/*
- * (C) Copyright 2003 Intracom S.A.
- * Pantelis Antoniou <panto@intracom.gr>
- *
- * This little program makes an exhaustive search for the
- * correct terms of pdf, mfi, mfn, mfd, s, dbrmo, in PLPRCR.
- * The goal is to produce a gclk2 from a xin input, while respecting
- * all the restrictions on their combination.
- *
- * Generaly you select the first row of the produced table.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#define DPREF_MIN 10000000
-#define DPREF_MAX 32000000
-
-#define DPGDCK_MAX 320000000
-#define DPGDCK_MIN 160000000
-
-#define S_MIN 0
-#define S_MAX 2
-
-#define MFI_MIN 5
-#define MFI_MAX 15
-
-#define MFN_MIN 0
-#define MFN_MAX 15
-
-#define MFD_MIN 0
-#define MFD_MAX 31
-
-#define MF_MIN 5
-#define MF_MAX 15
-
-#define PDF_MIN 0
-#define PDF_MAX 15
-
-#define GCLK2_MAX 150000000
-
-static int calculate (int xin, int target_clock,
- int ppm, int pdf, int mfi, int mfn, int mfd, int s,
- int *dprefp, int *dpgdckp, int *jdbckp,
- int *gclk2p, int *dbrmop)
-{
- unsigned int dpref, dpgdck, jdbck, gclk2, t1, t2, dbrmo;
-
- /* valid MFI? */
- if (mfi < MFI_MIN)
- return -1;
-
- /* valid num, denum? */
- if (mfn > 0 && mfn >= mfd)
- return -1;
-
- dpref = xin / (pdf + 1);
-
- /* valid dpef? */
- if (dpref < DPREF_MIN || dpref > DPREF_MAX)
- return -1;
-
- if (mfn == 0) {
- dpgdck = (2 * mfi * xin) / (pdf + 1) ;
- dbrmo = 0;
- } else {
- /* 5 <= mfi + (mfn / mfd + 1) <= 15 */
- t1 = mfd + 1;
- t2 = mfi * t1 + mfn;
- if ( MF_MIN * t1 > t2 || MF_MAX * t1 < t2)
- return -1;
-
- dpgdck = (unsigned int)(2 * (mfi * mfd + mfi + mfn) *
- (unsigned int)xin) /
- ((mfd + 1) * (pdf + 1));
-
- dbrmo = 10 * mfn < (mfd + 1);
- }
-
- /* valid dpgclk? */
- if (dpgdck < DPGDCK_MIN || dpgdck > DPGDCK_MAX)
- return -1;
-
- jdbck = dpgdck >> s;
- gclk2 = jdbck / 2;
-
- /* valid gclk2 */
- if (gclk2 > GCLK2_MAX)
- return -1;
-
- t1 = abs(gclk2 - target_clock);
-
- /* XXX max 1MHz dev. in clock */
- if (t1 > 1000000)
- return -1;
-
- /* dev within range (XXX gclk2 scaled to avoid overflow) */
- if (t1 * 1000 > (unsigned int)ppm * (gclk2 / 1000))
- return -1;
-
- *dprefp = dpref;
- *dpgdckp = dpgdck;
- *jdbckp = jdbck;
- *gclk2p = gclk2;
- *dbrmop = dbrmo;
-
- return gclk2;
-}
-
-int conf_clock(int xin, int target_clock, int ppm)
-{
- int pdf, s, mfn, mfd, mfi;
- int dpref, dpgdck, jdbck, gclk2, xout, dbrmo;
- int found = 0;
-
- /* integer multipliers */
- for (pdf = PDF_MIN; pdf <= PDF_MAX; pdf++) {
- for (mfi = MFI_MIN; mfi <= MFI_MAX; mfi++) {
- for (s = 0; s <= S_MAX; s++) {
- xout = calculate(xin, target_clock,
- ppm, pdf, mfi, 0, 0, s,
- &dpref, &dpgdck, &jdbck,
- &gclk2, &dbrmo);
- if (xout < 0)
- continue;
-
- if (found == 0) {
- printf("pdf mfi mfn mfd s dbrmo dpref dpgdck jdbck gclk2 exact?\n");
- printf("--- --- --- --- - ----- ----- ------ ----- ----- ------\n");
- }
-
- printf("%3d %3d --- --- %1d %5d %9d %9d %9d %9d%s\n",
- pdf, mfi, s, dbrmo,
- dpref, dpgdck, jdbck, gclk2,
- gclk2 == target_clock ? " YES" : "");
-
- found++;
- }
- }
- }
-
- /* fractional multipliers */
- for (pdf = PDF_MIN; pdf <= PDF_MAX; pdf++) {
- for (mfi = MFI_MIN; mfi <= MFI_MAX; mfi++) {
- for (mfn = 1; mfn <= MFN_MAX; mfn++) {
- for (mfd = 1; mfd <= MFD_MAX; mfd++) {
- for (s = 0; s <= S_MAX; s++) {
- xout = calculate(xin, target_clock,
- ppm, pdf, mfi, mfn, mfd, s,
- &dpref, &dpgdck, &jdbck,
- &gclk2, &dbrmo);
- if (xout < 0)
- continue;
-
- if (found == 0) {
- printf("pdf mfi mfn mfd s dbrmo dpref dpgdck jdbck gclk2 exact?\n");
- printf("--- --- --- --- - ----- ----- ------ ----- ----- ------\n");
- }
-
- printf("%3d %3d %3d %3d %1d %5d %9d %9d %9d %9d%s\n",
- pdf, mfi, mfn, mfd, s,
- dbrmo, dpref, dpgdck, jdbck, gclk2,
- gclk2 == target_clock ? " YES" : "");
-
- found++;
- }
- }
- }
-
- }
- }
-
- return found;
-}
-
-int main(int argc, char *argv[])
-{
- int xin, want_gclk2, found, ppm = 100;
-
- if (argc < 3) {
- fprintf(stderr, "usage: mpc86x_clk <xin> <want_gclk2> [ppm]\n");
- fprintf(stderr, " default ppm is 100\n");
- return 10;
- }
-
- xin = atoi(argv[1]);
- want_gclk2 = atoi(argv[2]);
- if (argc >= 4)
- ppm = atoi(argv[3]);
-
- found = conf_clock(xin, want_gclk2, ppm);
- if (found <= 0) {
- fprintf(stderr, "cannot produce gclk2 %d from xin %d\n",
- want_gclk2, xin);
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
is useful if your top commit is for setting up testing.
+How to install it
+=================
+
+The most up to date version of patman can be found in the U-boot sources.
+However to use it on other projects it may be more convenient to install it as
+a standalone application. A distutils installer is included, this can be used
+to install patman:
+
+$ cd tools/patman && python setup.py install
+
+
How to add tags
===============
--- /dev/null
+__all__ = ['checkpatch', 'command', 'commit', 'cros_subprocess',
+ 'get_maintainer', 'gitutil', 'patchstream', 'project',
+ 'series', 'settings', 'terminal', 'test']
import unittest
# Our modules
-import checkpatch
-import command
-import gitutil
-import patchstream
-import project
-import settings
-import terminal
-import test
+try:
+ from patman import checkpatch, command, gitutil, patchstream, \
+ project, settings, terminal, test
+except ImportError:
+ import checkpatch
+ import command
+ import gitutil
+ import patchstream
+ import project
+ import settings
+ import terminal
+ import test
parser = OptionParser()
settings.Setup(parser, options.project, '')
(options, args) = parser.parse_args()
+if __name__ != "__main__":
+ pass
+
# Run our meagre tests
-if options.test:
+elif options.test:
import doctest
sys.argv = [sys.argv[0]]
--- /dev/null
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+from distutils.core import setup
+setup(name='patman',
+ version='1.0',
+ license='GPL-2.0+',
+ scripts=['patman'],
+ packages=['patman'],
+ package_dir={'patman': ''},
+ package_data={'patman': ['README']},
+ classifiers=['Environment :: Console',
+ 'Topic :: Software Development'])