summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2015-04-24 13:43:24 -0400
committerTom Rini <trini@konsulko.com>2015-04-24 13:43:24 -0400
commit3f6dcdb9cd4dbda226a1474f1e9398413e906b41 (patch)
treefb3a7d7873e9c14a3733197e4cc028ce90827970
parentd8c1d5d5fb6eafbc532982125f006e49f2c40e71 (diff)
parentab10d73d2fc13bd5baf5024e54ad92641d238bdb (diff)
downloadu-boot-imx-3f6dcdb9cd4dbda226a1474f1e9398413e906b41.zip
u-boot-imx-3f6dcdb9cd4dbda226a1474f1e9398413e906b41.tar.gz
u-boot-imx-3f6dcdb9cd4dbda226a1474f1e9398413e906b41.tar.bz2
Merge branch 'master' of git://git.denx.de/u-boot-fsl-qoriq
-rw-r--r--README13
-rw-r--r--arch/arm/Kconfig24
-rw-r--r--arch/arm/cpu/armv7/ls102xa/clock.c4
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/Makefile2
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/README138
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/cpu.c123
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/fdt.c9
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c115
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S15
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c117
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/mp.c7
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/mp.h1
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/soc.c107
-rw-r--r--arch/arm/cpu/armv8/fsl-lsch3/speed.c11
-rw-r--r--arch/arm/cpu/armv8/generic_timer.c11
-rw-r--r--arch/arm/cpu/armv8/u-boot-spl.lds77
-rw-r--r--arch/arm/include/asm/arch-fsl-lsch3/config.h60
-rw-r--r--arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h67
-rw-r--r--arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h29
-rw-r--r--arch/arm/include/asm/arch-fsl-lsch3/soc.h8
-rw-r--r--arch/arm/include/asm/arch-ls102xa/config.h4
-rw-r--r--arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h3
-rw-r--r--arch/arm/include/asm/fsl_secure_boot.h25
-rw-r--r--arch/arm/include/asm/pcie_layerscape.h13
-rw-r--r--arch/arm/lib/crt0_64.S7
-rw-r--r--arch/powerpc/cpu/mpc85xx/cpu_init_early.c8
-rw-r--r--arch/powerpc/cpu/mpc85xx/speed.c4
-rw-r--r--arch/powerpc/include/asm/fsl_secure_boot.h19
-rw-r--r--board/freescale/bsc9132qds/bsc9132qds.c4
-rw-r--r--board/freescale/c29xpcie/c29xpcie.c4
-rw-r--r--board/freescale/common/arm_sleep.c6
-rw-r--r--board/freescale/common/cmd_esbc_validate.c16
-rw-r--r--board/freescale/common/mpc85xx_sleep.c8
-rw-r--r--board/freescale/common/qixis.c31
-rw-r--r--board/freescale/ls1021aqds/MAINTAINERS1
-rw-r--r--board/freescale/ls1021aqds/ls1021aqds.c73
-rw-r--r--board/freescale/ls1021atwr/ls1021atwr.c110
-rw-r--r--board/freescale/ls2085a/ls2085a.c43
-rw-r--r--board/freescale/ls2085aqds/Kconfig16
-rw-r--r--board/freescale/ls2085aqds/MAINTAINERS8
-rw-r--r--board/freescale/ls2085aqds/Makefile9
-rw-r--r--board/freescale/ls2085aqds/README129
-rw-r--r--board/freescale/ls2085aqds/ddr.c196
-rw-r--r--board/freescale/ls2085aqds/ddr.h92
-rw-r--r--board/freescale/ls2085aqds/eth.c380
-rw-r--r--board/freescale/ls2085aqds/ls2085aqds.c274
-rw-r--r--board/freescale/ls2085aqds/ls2085aqds_qixis.h30
-rw-r--r--board/freescale/ls2085ardb/Kconfig16
-rw-r--r--board/freescale/ls2085ardb/MAINTAINERS8
-rw-r--r--board/freescale/ls2085ardb/Makefile8
-rw-r--r--board/freescale/ls2085ardb/README109
-rw-r--r--board/freescale/ls2085ardb/ddr.c196
-rw-r--r--board/freescale/ls2085ardb/ddr.h92
-rw-r--r--board/freescale/ls2085ardb/ls2085ardb.c249
-rw-r--r--board/freescale/ls2085ardb/ls2085ardb_qixis.h20
-rw-r--r--board/freescale/p1010rdb/p1010rdb.c5
-rw-r--r--board/freescale/p1010rdb/spl.c4
-rw-r--r--common/board_r.c6
-rw-r--r--common/cmd_mem.c6
-rw-r--r--common/spl/spl.c2
-rw-r--r--common/spl/spl_nand.c2
-rw-r--r--configs/ls1021aqds_ddr4_nor_lpuart_defconfig3
-rw-r--r--configs/ls2085aqds_defconfig3
-rw-r--r--configs/ls2085aqds_nand_defconfig4
-rw-r--r--configs/ls2085ardb_defconfig3
-rw-r--r--configs/ls2085ardb_nand_defconfig4
-rw-r--r--drivers/ddr/fsl/ctrl_regs.c77
-rw-r--r--drivers/ddr/fsl/ddr4_dimm_params.c3
-rw-r--r--drivers/ddr/fsl/fsl_ddr_gen4.c169
-rw-r--r--drivers/ddr/fsl/interactive.c56
-rw-r--r--drivers/ddr/fsl/lc_common_dimm_params.c5
-rw-r--r--drivers/ddr/fsl/main.c2
-rw-r--r--drivers/ddr/fsl/options.c7
-rw-r--r--drivers/ddr/fsl/util.c28
-rw-r--r--drivers/i2c/mxc_i2c.c17
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/fsl_debug_server.c246
-rw-r--r--drivers/misc/fsl_ifc.c21
-rw-r--r--drivers/mmc/fsl_esdhc.c36
-rw-r--r--drivers/mtd/nand/fsl_ifc_nand.c64
-rw-r--r--drivers/mtd/nand/fsl_ifc_spl.c25
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/e1000.c8
-rw-r--r--drivers/net/fm/eth.c2
-rw-r--r--drivers/net/fm/memac.c2
-rw-r--r--drivers/net/fm/memac_phy.c62
-rw-r--r--drivers/net/fsl-mc/Makefile6
-rw-r--r--drivers/net/fsl-mc/dpbp.c102
-rw-r--r--drivers/net/fsl-mc/dpio/Makefile9
-rw-r--r--drivers/net/fsl-mc/dpio/dpio.c102
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_portal.c593
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_portal.h157
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_private.h169
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_sys.h290
-rw-r--r--drivers/net/fsl-mc/dpmng.c65
-rw-r--r--drivers/net/fsl-mc/dpni.c506
-rw-r--r--drivers/net/fsl-mc/dprc.c283
-rw-r--r--drivers/net/fsl-mc/fsl_dpmng_cmd.h32
-rw-r--r--drivers/net/fsl-mc/mc.c702
-rw-r--r--drivers/net/fsl-mc/mc_sys.c6
-rw-r--r--drivers/net/ldpaa_eth/Makefile9
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.c710
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.h149
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_wriop.c146
-rw-r--r--drivers/net/ldpaa_eth/ls2085a.c83
-rw-r--r--drivers/net/phy/cortina.c4
-rw-r--r--drivers/net/vsc9953.c2
-rw-r--r--drivers/pci/pcie_layerscape.c52
-rw-r--r--drivers/qe/qe.c82
-rw-r--r--drivers/qe/qe.h6
-rw-r--r--drivers/usb/host/ehci-fsl.c16
-rw-r--r--include/config_fsl_secboot.h89
-rw-r--r--include/configs/aristainetos.h1
-rw-r--r--include/configs/cm_fx6.h1
-rw-r--r--include/configs/embestmx6boards.h1
-rw-r--r--include/configs/flea3.h1
-rw-r--r--include/configs/gw_ventana.h1
-rw-r--r--include/configs/imx31_phycore.h1
-rw-r--r--include/configs/ls1021aqds.h2
-rw-r--r--include/configs/ls1021atwr.h1
-rw-r--r--include/configs/ls2085a_common.h242
-rw-r--r--include/configs/ls2085a_emu.h65
-rw-r--r--include/configs/ls2085a_simu.h122
-rw-r--r--include/configs/ls2085aqds.h359
-rw-r--r--include/configs/ls2085ardb.h305
-rw-r--r--include/configs/m53evk.h1
-rw-r--r--include/configs/mx35pdk.h1
-rw-r--r--include/configs/mx53ard.h1
-rw-r--r--include/configs/mx53evk.h1
-rw-r--r--include/configs/mx53loco.h1
-rw-r--r--include/configs/mx53smd.h1
-rw-r--r--include/configs/mx6qsabreauto.h1
-rw-r--r--include/configs/mx6sabresd.h1
-rw-r--r--include/configs/mx6slevk.h1
-rw-r--r--include/configs/mx6sxsabresd.h1
-rw-r--r--include/configs/nitrogen6x.h1
-rw-r--r--include/configs/novena.h1
-rw-r--r--include/configs/ot1200.h1
-rw-r--r--include/configs/platinum.h1
-rw-r--r--include/configs/tbs2910.h1
-rw-r--r--include/configs/titanium.h1
-rw-r--r--include/configs/tqma6.h1
-rw-r--r--include/configs/wandboard.h1
-rw-r--r--include/configs/woodburn_common.h1
-rw-r--r--include/fsl-mc/fsl_dpaa_fd.h121
-rw-r--r--include/fsl-mc/fsl_dpbp.h143
-rw-r--r--include/fsl-mc/fsl_dpio.h163
-rw-r--r--include/fsl-mc/fsl_dpmng.h113
-rw-r--r--include/fsl-mc/fsl_dpni.h1093
-rw-r--r--include/fsl-mc/fsl_dprc.h659
-rw-r--r--include/fsl-mc/fsl_mc.h5
-rw-r--r--include/fsl-mc/fsl_mc_cmd.h17
-rw-r--r--include/fsl-mc/fsl_mc_private.h50
-rw-r--r--include/fsl-mc/fsl_qbman_base.h87
-rw-r--r--include/fsl-mc/fsl_qbman_portal.h175
-rw-r--r--include/fsl-mc/ldpaa_wriop.h70
-rw-r--r--include/fsl_ddr.h4
-rw-r--r--include/fsl_ddr_sdram.h3
-rw-r--r--include/fsl_debug_server.h32
-rw-r--r--include/fsl_esdhc.h4
-rw-r--r--include/fsl_ifc.h84
-rw-r--r--include/fsl_memac.h (renamed from arch/powerpc/include/asm/fsl_memac.h)0
-rw-r--r--include/fsl_usb.h57
-rw-r--r--include/linux/immap_qe.h12
164 files changed, 11694 insertions, 713 deletions
diff --git a/README b/README
index fc1fd52..a70af98 100644
--- a/README
+++ b/README
@@ -690,6 +690,14 @@ The following options need to be configured:
exists, unlike the similar options in the Linux kernel. Do not
set these options unless they apply!
+ COUNTER_FREQUENCY
+ Generic timer clock source frequency.
+
+ COUNTER_FREQUENCY_REAL
+ Generic timer clock source frequency if the real clock is
+ different from COUNTER_FREQUENCY, and can only be determined
+ at run time.
+
NOTE: The following can be machine specific errata. These
do have ability to provide rudimentary version and machine
specific checks, but expect no product checks.
@@ -2395,6 +2403,8 @@ CBFS (Coreboot Filesystem) support
- define slave for bus 3 with CONFIG_SYS_MXC_I2C3_SLAVE
If those defines are not set, default value is 100000
for speed, and 0 for slave.
+ - enable bus 3 with CONFIG_SYS_I2C_MXC_I2C3
+ - enable bus 4 with CONFIG_SYS_I2C_MXC_I2C4
- drivers/i2c/rcar_i2c.c:
- activate this driver with CONFIG_SYS_I2C_RCAR
@@ -4882,6 +4892,9 @@ Low Level (hardware related) configuration options:
- CONFIG_FSL_DDR_SYNC_REFRESH
Enable sync of refresh for multiple controllers.
+- CONFIG_FSL_DDR_BIST
+ Enable built-in memory test for Freescale DDR controllers.
+
- CONFIG_SYS_83XX_DDR_USES_CS0
Only for 83xx systems. If specified, then DDR should
be configured using CS0 and CS1 instead of CS2 and CS3.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b39bb4f..5f21b59 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -690,6 +690,28 @@ config TARGET_LS2085A_SIMU
select ARM64
select ARMV8_MULTIENTRY
+config TARGET_LS2085AQDS
+ bool "Support ls2085aqds"
+ select ARM64
+ select ARMV8_MULTIENTRY
+ select SUPPORT_SPL
+ help
+ Support for Freescale LS2085AQDS platform
+ The LS2085A Development System (QDS) is a high-performance
+ development platform that supports the QorIQ LS2085A
+ Layerscape Architecture processor.
+
+config TARGET_LS2085ARDB
+ bool "Support ls2085ardb"
+ select ARM64
+ select ARMV8_MULTIENTRY
+ select SUPPORT_SPL
+ help
+ Support for Freescale LS2085ARDB platform.
+ The LS2085A Reference design board (RDB) is a high-performance
+ development platform that supports the QorIQ LS2085A
+ Layerscape Architecture processor.
+
config TARGET_LS1021AQDS
bool "Support ls1021aqds"
select CPU_V7
@@ -849,6 +871,8 @@ source "board/denx/m53evk/Kconfig"
source "board/embest/mx6boards/Kconfig"
source "board/esg/ima3-mx53/Kconfig"
source "board/freescale/ls2085a/Kconfig"
+source "board/freescale/ls2085aqds/Kconfig"
+source "board/freescale/ls2085ardb/Kconfig"
source "board/freescale/ls1021aqds/Kconfig"
source "board/freescale/ls1021atwr/Kconfig"
source "board/freescale/mx23evk/Kconfig"
diff --git a/arch/arm/cpu/armv7/ls102xa/clock.c b/arch/arm/cpu/armv7/ls102xa/clock.c
index 8f80c61..7a337e1 100644
--- a/arch/arm/cpu/armv7/ls102xa/clock.c
+++ b/arch/arm/cpu/armv7/ls102xa/clock.c
@@ -20,7 +20,7 @@ void get_sys_info(struct sys_info *sys_info)
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
#ifdef CONFIG_FSL_IFC
- struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
+ struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
u32 ccr;
#endif
struct ccsr_clk *clk = (void *)(CONFIG_SYS_FSL_LS1_CLK_ADDR);
@@ -74,7 +74,7 @@ void get_sys_info(struct sys_info *sys_info)
}
#if defined(CONFIG_FSL_IFC)
- ccr = in_be32(&ifc_regs->ifc_ccr);
+ ccr = in_be32(&ifc_regs.gregs->ifc_ccr);
ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
sys_info->freq_localbus = sys_info->freq_systembus / ccr;
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/Makefile b/arch/arm/cpu/armv8/fsl-lsch3/Makefile
index f920eeb..9f7815b 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/Makefile
+++ b/arch/arm/cpu/armv8/fsl-lsch3/Makefile
@@ -6,6 +6,8 @@
obj-y += cpu.o
obj-y += lowlevel.o
+obj-y += soc.o
obj-y += speed.o
+obj-$(CONFIG_SYS_HAS_SERDES) += fsl_lsch3_serdes.o ls2085a_serdes.o
obj-$(CONFIG_MP) += mp.o
obj-$(CONFIG_OF_LIBFDT) += fdt.o
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/README b/arch/arm/cpu/armv8/fsl-lsch3/README
index cc47466..37f07fb 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/README
+++ b/arch/arm/cpu/armv8/fsl-lsch3/README
@@ -8,3 +8,141 @@ Freescale LayerScape with Chassis Generation 3
This architecture supports Freescale ARMv8 SoCs with Chassis generation 3,
for example LS2085A.
+
+Flash Layout
+============
+
+(1) A typical layout of various images (including Linux and other firmware images)
+ is shown below considering a 32MB NOR flash device present on most
+ pre-silicon platforms (simulator and emulator):
+
+ -------------------------
+ | FIT Image |
+ | (linux + DTB + RFS) |
+ ------------------------- ----> 0x0120_0000
+ | Debug Server FW |
+ ------------------------- ----> 0x00C0_0000
+ | AIOP FW |
+ ------------------------- ----> 0x0070_0000
+ | MC FW |
+ ------------------------- ----> 0x006C_0000
+ | MC DPL Blob |
+ ------------------------- ----> 0x0020_0000
+ | BootLoader + Env|
+ ------------------------- ----> 0x0000_1000
+ | PBI |
+ ------------------------- ----> 0x0000_0080
+ | RCW |
+ ------------------------- ----> 0x0000_0000
+
+ 32-MB NOR flash layout for pre-silicon platforms (simulator and emulator)
+
+(2) A typical layout of various images (including Linux and other firmware images)
+ is shown below considering a 128MB NOR flash device present on QDS and RDB
+ boards:
+ ----------------------------------------- ----> 0x5_8800_0000 ---
+ | .. Unused .. (7M) | |
+ ----------------------------------------- ----> 0x5_8790_0000 |
+ | FIT Image (linux + DTB + RFS) (40M) | |
+ ----------------------------------------- ----> 0x5_8510_0000 |
+ | PHY firmware (2M) | |
+ ----------------------------------------- ----> 0x5_84F0_0000 | 64K
+ | Debug Server FW (2M) | | Alt
+ ----------------------------------------- ----> 0x5_84D0_0000 | Bank
+ | AIOP FW (4M) | |
+ ----------------------------------------- ----> 0x5_8490_0000 (vbank4)
+ | MC DPC Blob (1M) | |
+ ----------------------------------------- ----> 0x5_8480_0000 |
+ | MC DPL Blob (1M) | |
+ ----------------------------------------- ----> 0x5_8470_0000 |
+ | MC FW (4M) | |
+ ----------------------------------------- ----> 0x5_8430_0000 |
+ | BootLoader Environment (1M) | |
+ ----------------------------------------- ----> 0x5_8420_0000 |
+ | BootLoader (1M) | |
+ ----------------------------------------- ----> 0x5_8410_0000 |
+ | RCW and PBI (1M) | |
+ ----------------------------------------- ----> 0x5_8400_0000 ---
+ | .. Unused .. (7M) | |
+ ----------------------------------------- ----> 0x5_8390_0000 |
+ | FIT Image (linux + DTB + RFS) (40M) | |
+ ----------------------------------------- ----> 0x5_8110_0000 |
+ | PHY firmware (2M) | |
+ ----------------------------------------- ----> 0x5_80F0_0000 | 64K
+ | Debug Server FW (2M) | | Bank
+ ----------------------------------------- ----> 0x5_80D0_0000 |
+ | AIOP FW (4M) | |
+ ----------------------------------------- ----> 0x5_8090_0000 (vbank0)
+ | MC DPC Blob (1M) | |
+ ----------------------------------------- ----> 0x5_8080_0000 |
+ | MC DPL Blob (1M) | |
+ ----------------------------------------- ----> 0x5_8070_0000 |
+ | MC FW (4M) | |
+ ----------------------------------------- ----> 0x5_8030_0000 |
+ | BootLoader Environment (1M) | |
+ ----------------------------------------- ----> 0x5_8020_0000 |
+ | BootLoader (1M) | |
+ ----------------------------------------- ----> 0x5_8010_0000 |
+ | RCW and PBI (1M) | |
+ ----------------------------------------- ----> 0x5_8000_0000 ---
+
+ 128-MB NOR flash layout for QDS and RDB boards
+
+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 from NAND
+-------------------
+Booting from NAND requires two images, RCW and u-boot-with-spl.bin.
+The difference between NAND boot RCW image and NOR boot image is the PBI
+command sequence. Below is one example for PBI commands for QDS which uses
+NAND device with 2KB/page, block size 128KB.
+
+1) CCSR 4-byte write to 0x00e00404, data=0x00000000
+2) CCSR 4-byte write to 0x00e00400, data=0x1800a000
+The above two commands set bootloc register to 0x00000000_1800a000 where
+the u-boot code will be running in OCRAM.
+
+3) Block Copy: SRC=0x0107, SRC_ADDR=0x00020000, DEST_ADDR=0x1800a000,
+BLOCK_SIZE=0x00014000
+This command copies u-boot image from NAND device into OCRAM. The values need
+to adjust accordingly.
+
+SRC should match the cfg_rcw_src, the reset config pins. It depends
+ on the NAND device. See reference manual for cfg_rcw_src.
+SRC_ADDR is the offset of u-boot-with-spl.bin image in NAND device. In
+ the example above, 128KB. For easy maintenance, we put it at
+ the beginning of next block from RCW.
+DEST_ADDR is fixed at 0x1800a000, matching bootloc set above.
+BLOCK_SIZE is the size to be copied by PBI.
+
+RCW image should be written to the beginning of NAND device. Example of using
+u-boot command
+
+nand write <rcw image in memory> 0 <size of rcw image>
+
+To form the NAND image, build u-boot with NAND config, for example,
+ls2085aqds_nand_defconfig. The image needed is u-boot-with-spl.bin.
+The u-boot image should be written to match SRC_ADDR, in above example 0x20000.
+
+nand write <u-boot image in memory> 200000 <size of u-boot image>
+
+With these two images in NAND device, the board can boot from NAND.
+
+Another example for RDB boards,
+
+1) CCSR 4-byte write to 0x00e00404, data=0x00000000
+2) CCSR 4-byte write to 0x00e00400, data=0x1800a000
+3) Block Copy: SRC=0x0119, SRC_ADDR=0x00080000, DEST_ADDR=0x1800a000,
+BLOCK_SIZE=0x00014000
+
+nand write <rcw image in memory> 0 <size of rcw image>
+nand write <u-boot image in memory> 80000 <size of u-boot image>
+
+Notice the difference from QDS is SRC, SRC_ADDR and the offset of u-boot image
+to match board NAND device with 4KB/page, block size 512KB.
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
index 4997487..6714577 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
+++ b/arch/arm/cpu/armv8/fsl-lsch3/cpu.c
@@ -10,7 +10,12 @@
#include <asm/armv8/mmu.h>
#include <asm/io.h>
#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+#include <fsl_debug_server.h>
#include <fsl-mc/fsl_mc.h>
+#include <asm/arch/fsl_serdes.h>
+#ifdef CONFIG_FSL_ESDHC
+#include <fsl_esdhc.h>
+#endif
#include "cpu.h"
#include "mp.h"
#include "speed.h"
@@ -24,8 +29,9 @@ DECLARE_GLOBAL_DATA_PTR;
* levels of translation tables here to cover 40-bit address space.
* We use 4KB granule size, with 40 bits physical address, T0SZ=24
* Level 0 IA[39], table address @0
- * Level 1 IA[31:30], table address @01000, 0x2000
- * Level 2 IA[29:21], table address @0x3000
+ * Level 1 IA[31:30], table address @0x1000, 0x2000
+ * Level 2 IA[29:21], table address @0x3000, 0x4000
+ * Address above 0x5000 is free for other purpose.
*/
#define SECTION_SHIFT_L0 39UL
@@ -60,12 +66,12 @@ static inline void early_mmu_setup(void)
{
int el;
u64 i;
- u64 section_l1t0, section_l1t1, section_l2;
+ u64 section_l1t0, section_l1t1, section_l2t0, section_l2t1;
u64 *level0_table = (u64 *)CONFIG_SYS_FSL_OCRAM_BASE;
u64 *level1_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x1000);
u64 *level1_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x2000);
- u64 *level2_table = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
-
+ u64 *level2_table_0 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x3000);
+ u64 *level2_table_1 = (u64 *)(CONFIG_SYS_FSL_OCRAM_BASE + 0x4000);
level0_table[0] =
(u64)level1_table_0 | PMD_TYPE_TABLE;
@@ -79,21 +85,25 @@ static inline void early_mmu_setup(void)
*/
section_l1t0 = 0;
section_l1t1 = BLOCK_SIZE_L0;
- section_l2 = 0;
+ section_l2t0 = 0;
+ section_l2t1 = CONFIG_SYS_FLASH_BASE;
for (i = 0; i < 512; i++) {
set_pgtable_section(level1_table_0, i, section_l1t0,
MT_DEVICE_NGNRNE);
set_pgtable_section(level1_table_1, i, section_l1t1,
MT_NORMAL);
- set_pgtable_section(level2_table, i, section_l2,
+ set_pgtable_section(level2_table_0, i, section_l2t0,
+ MT_DEVICE_NGNRNE);
+ set_pgtable_section(level2_table_1, i, section_l2t1,
MT_DEVICE_NGNRNE);
section_l1t0 += BLOCK_SIZE_L1;
section_l1t1 += BLOCK_SIZE_L1;
- section_l2 += BLOCK_SIZE_L2;
+ section_l2t0 += BLOCK_SIZE_L2;
+ section_l2t1 += BLOCK_SIZE_L2;
}
level1_table_0[0] =
- (u64)level2_table | PMD_TYPE_TABLE;
+ (u64)level2_table_0 | PMD_TYPE_TABLE;
level1_table_0[1] =
0x40000000 | PMD_SECT_AF | PMD_TYPE_SECT |
PMD_ATTRINDX(MT_DEVICE_NGNRNE);
@@ -104,17 +114,34 @@ static inline void early_mmu_setup(void)
0xc0000000 | PMD_SECT_AF | PMD_TYPE_SECT |
PMD_ATTRINDX(MT_NORMAL);
- /* Rewrite table to enable cache */
- set_pgtable_section(level2_table,
+ /* Rewerite table to enable cache for OCRAM */
+ set_pgtable_section(level2_table_0,
CONFIG_SYS_FSL_OCRAM_BASE >> SECTION_SHIFT_L2,
CONFIG_SYS_FSL_OCRAM_BASE,
MT_NORMAL);
- for (i = CONFIG_SYS_IFC_BASE >> SECTION_SHIFT_L2;
- i < (CONFIG_SYS_IFC_BASE + CONFIG_SYS_IFC_SIZE)
- >> SECTION_SHIFT_L2; i++) {
- section_l2 = i << SECTION_SHIFT_L2;
- set_pgtable_section(level2_table, i,
- section_l2, MT_NORMAL);
+
+#if defined(CONFIG_SYS_NOR0_CSPR_EARLY) && defined(CONFIG_SYS_NOR_AMASK_EARLY)
+ /* Rewrite table to enable cache for two entries (4MB) */
+ section_l2t1 = CONFIG_SYS_IFC_BASE;
+ set_pgtable_section(level2_table_0,
+ section_l2t1 >> SECTION_SHIFT_L2,
+ section_l2t1,
+ MT_NORMAL);
+ section_l2t1 += BLOCK_SIZE_L2;
+ set_pgtable_section(level2_table_0,
+ section_l2t1 >> SECTION_SHIFT_L2,
+ section_l2t1,
+ MT_NORMAL);
+#endif
+
+ /* Create a mapping for 256MB IFC region to final flash location */
+ level1_table_0[CONFIG_SYS_FLASH_BASE >> SECTION_SHIFT_L1] =
+ (u64)level2_table_1 | PMD_TYPE_TABLE;
+ section_l2t1 = CONFIG_SYS_IFC_BASE;
+ for (i = 0; i < 0x10000000 >> SECTION_SHIFT_L2; i++) {
+ set_pgtable_section(level2_table_1, i,
+ section_l2t1, MT_DEVICE_NGNRNE);
+ section_l2t1 += BLOCK_SIZE_L2;
}
el = current_el();
@@ -347,6 +374,7 @@ u32 fsl_qoriq_core_to_type(unsigned int core)
#ifdef CONFIG_DISPLAY_CPUINFO
int print_cpuinfo(void)
{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
struct sys_info sysinfo;
char buf[32];
unsigned int i, core;
@@ -370,21 +398,40 @@ int print_cpuinfo(void)
printf(" DP-DDR: %-4s MHz", strmhz(buf, sysinfo.freq_ddrbus2));
puts("\n");
+ /* Display the RCW, so that no one gets confused as to what RCW
+ * we're actually using for this boot.
+ */
+ puts("Reset Configuration Word (RCW):");
+ for (i = 0; i < ARRAY_SIZE(gur->rcwsr); i++) {
+ u32 rcw = in_le32(&gur->rcwsr[i]);
+
+ if ((i % 4) == 0)
+ printf("\n %02x:", i * 4);
+ printf(" %08x", rcw);
+ }
+ puts("\n");
+
return 0;
}
#endif
+#ifdef CONFIG_FSL_ESDHC
+int cpu_mmc_init(bd_t *bis)
+{
+ return fsl_esdhc_mmc_init(bis);
+}
+#endif
+
int cpu_eth_init(bd_t *bis)
{
int error = 0;
#ifdef CONFIG_FSL_MC_ENET
- error = mc_init(bis);
+ error = fsl_mc_ldpaa_init(bis);
#endif
return error;
}
-
int arch_early_init_r(void)
{
int rv;
@@ -393,5 +440,43 @@ int arch_early_init_r(void)
if (rv)
printf("Did not wake secondary cores\n");
+#ifdef CONFIG_SYS_HAS_SERDES
+ fsl_serdes_init();
+#endif
+ return 0;
+}
+
+int timer_init(void)
+{
+ u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
+ u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
+#ifdef COUNTER_FREQUENCY_REAL
+ unsigned long cntfrq = COUNTER_FREQUENCY_REAL;
+
+ /* Update with accurate clock frequency */
+ asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
+#endif
+
+ /* Enable timebase for all clusters.
+ * It is safe to do so even some clusters are not enabled.
+ */
+ out_le32(cltbenr, 0xf);
+
+ /* Enable clock for timer
+ * This is a global setting.
+ */
+ out_le32(cntcr, 0x1);
+
return 0;
}
+
+void reset_cpu(ulong addr)
+{
+ u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
+ u32 val;
+
+ /* Raise RESET_REQ_B */
+ val = in_le32(rstcr);
+ val |= 0x02;
+ out_le32(rstcr, val);
+}
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c
index 7eb9b6a..d370023 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/fdt.c
+++ b/arch/arm/cpu/armv8/fsl-lsch3/fdt.c
@@ -7,6 +7,9 @@
#include <common.h>
#include <libfdt.h>
#include <fdt_support.h>
+#ifdef CONFIG_FSL_ESDHC
+#include <fsl_esdhc.h>
+#endif
#include "mp.h"
#ifdef CONFIG_MP
@@ -62,7 +65,11 @@ void ft_cpu_setup(void *blob, bd_t *bd)
#endif
#ifdef CONFIG_SYS_NS16550
- do_fixup_by_compat_u32(blob, "ns16550",
+ do_fixup_by_compat_u32(blob, "fsl,ns16550",
"clock-frequency", CONFIG_SYS_NS16550_CLK, 1);
#endif
+
+#if defined(CONFIG_FSL_ESDHC)
+ fdt_fixup_esdhc(blob, bd);
+#endif
}
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c b/arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c
new file mode 100644
index 0000000..02ca126
--- /dev/null
+++ b/arch/arm/cpu/armv8/fsl-lsch3/fsl_lsch3_serdes.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+#include <fsl-mc/ldpaa_wriop.h>
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+static u8 serdes1_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+static u8 serdes2_prtcl_map[SERDES_PRCTL_COUNT];
+#endif
+
+int is_serdes_configured(enum srds_prtcl device)
+{
+ int ret = 0;
+
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ ret |= serdes1_prtcl_map[device];
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ ret |= serdes2_prtcl_map[device];
+#endif
+
+ return !!ret;
+}
+
+int serdes_get_first_lane(u32 sd, enum srds_prtcl device)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 cfg = in_le32(&gur->rcwsr[28]);
+ int i;
+
+ switch (sd) {
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ case FSL_SRDS_1:
+ cfg &= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
+ break;
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ case FSL_SRDS_2:
+ cfg &= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK;
+ cfg >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
+ break;
+#endif
+ default:
+ printf("invalid SerDes%d\n", sd);
+ break;
+ }
+ /* Is serdes enabled at all? */
+ if (cfg == 0)
+ return -ENODEV;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (serdes_get_prtcl(sd, cfg, i) == device)
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+void serdes_init(u32 sd, u32 sd_addr, u32 sd_prctl_mask, u32 sd_prctl_shift,
+ u8 serdes_prtcl_map[SERDES_PRCTL_COUNT])
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ u32 cfg;
+ int lane;
+
+ memset(serdes_prtcl_map, 0, sizeof(serdes_prtcl_map));
+
+ cfg = in_le32(&gur->rcwsr[28]) & sd_prctl_mask;
+ cfg >>= sd_prctl_shift;
+ printf("Using SERDES%d Protocol: %d (0x%x)\n", sd + 1, cfg, cfg);
+
+ if (!is_serdes_prtcl_valid(sd, cfg))
+ printf("SERDES%d[PRTCL] = 0x%x is not valid\n", sd + 1, cfg);
+
+ for (lane = 0; lane < SRDS_MAX_LANES; lane++) {
+ enum srds_prtcl lane_prtcl = serdes_get_prtcl(sd, cfg, lane);
+ if (unlikely(lane_prtcl >= SERDES_PRCTL_COUNT))
+ debug("Unknown SerDes lane protocol %d\n", lane_prtcl);
+ else {
+ serdes_prtcl_map[lane_prtcl] = 1;
+#ifdef CONFIG_FSL_MC_ENET
+ wriop_init_dpmac(sd, lane + 1, (int)lane_prtcl);
+#endif
+ }
+ }
+}
+
+void fsl_serdes_init(void)
+{
+#ifdef CONFIG_SYS_FSL_SRDS_1
+ serdes_init(FSL_SRDS_1,
+ CONFIG_SYS_FSL_LSCH3_SERDES_ADDR,
+ FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK,
+ FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT,
+ serdes1_prtcl_map);
+#endif
+#ifdef CONFIG_SYS_FSL_SRDS_2
+ serdes_init(FSL_SRDS_2,
+ CONFIG_SYS_FSL_LSCH3_SERDES_ADDR + FSL_SRDS_2 * 0x10000,
+ FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK,
+ FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT,
+ serdes2_prtcl_map);
+#endif
+}
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
index 886576e..018c617 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
+++ b/arch/arm/cpu/armv8/fsl-lsch3/lowlevel.S
@@ -15,6 +15,15 @@
ENTRY(lowlevel_init)
mov x29, lr /* Save LR */
+ /* Add fully-coherent masters to DVM domain */
+ ldr x1, =CCI_MN_BASE
+ ldr x2, [x1, #CCI_MN_RNF_NODEID_LIST]
+ str x2, [x1, #CCI_MN_DVM_DOMAIN_CTL_SET]
+1: ldr x3, [x1, #CCI_MN_DVM_DOMAIN_CTL_SET]
+ mvn x0, x3
+ tst x0, x3 /* Wait for domain addition to complete */
+ b.ne 1b
+
/* Set the SMMU page size in the sACR register */
ldr x1, =SMMU_BASE
ldr w0, [x1, #0x10]
@@ -224,6 +233,9 @@ ENTRY(secondary_boot_func)
/* physical address of this cpus spin table element */
add x11, x1, x0
+ ldr x0, =__real_cntfrq
+ ldr x0, [x0]
+ msr cntfrq_el0, x0 /* set with real frequency */
str x9, [x11, #16] /* LPID */
mov x4, #1
str x4, [x11, #8] /* STATUS */
@@ -275,6 +287,9 @@ ENDPROC(secondary_switch_to_el1)
/* 64 bit alignment for elements accessed as data */
.align 4
+ .global __real_cntfrq
+__real_cntfrq:
+ .quad COUNTER_FREQUENCY
.globl __secondary_boot_code_size
.type __secondary_boot_code_size, %object
/* Secondary Boot Code ends here */
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c b/arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c
new file mode 100644
index 0000000..098745b
--- /dev/null
+++ b/arch/arm/cpu/armv8/fsl-lsch3/ls2085a_serdes.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+
+struct serdes_config {
+ u8 protocol;
+ u8 lanes[SRDS_MAX_LANES];
+};
+
+static struct serdes_config serdes1_cfg_tbl[] = {
+ /* SerDes 1 */
+ {0x03, {PCIE1, PCIE1, PCIE1, PCIE1, PCIE2, PCIE2, PCIE2, PCIE2 } },
+ {0x05, {PCIE2, PCIE2, PCIE2, PCIE2, SGMII4, SGMII3, SGMII2, SGMII1 } },
+ {0x07, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x09, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x0A, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x0C, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x0E, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, SGMII2,
+ SGMII1 } },
+ {0x26, {SGMII8, SGMII7, SGMII6, SGMII5, SGMII4, SGMII3, XFI2, XFI1 } },
+ {0x28, {SGMII8, SGMII7, SGMII6, SGMII5, XFI4, XFI3, XFI2, XFI1 } },
+ {0x2A, {XFI8, XFI7, XFI6, XFI5, XFI4, XFI3, XFI2, XFI1 } },
+ {0x2B, {SGMII8, SGMII7, SGMII6, SGMII5, XAUI1, XAUI1, XAUI1, XAUI1 } },
+ {0x32, {XAUI2, XAUI2, XAUI2, XAUI2, XAUI1, XAUI1, XAUI1, XAUI1 } },
+ {0x33, {PCIE2, PCIE2, PCIE2, PCIE2, QSGMII_D, QSGMII_C, QSGMII_B,
+ QSGMII_A} },
+ {0x35, {QSGMII_D, QSGMII_C, QSGMII_B, PCIE2, XFI4, XFI3, XFI2, XFI1 } },
+ {}
+};
+static struct serdes_config serdes2_cfg_tbl[] = {
+ /* SerDes 2 */
+ {0x07, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x09, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x0A, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x0C, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x0E, {SGMII9, SGMII10, SGMII11, SGMII12, SGMII13, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x3D, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
+ {0x3E, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3, PCIE3 } },
+ {0x3F, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
+ {0x40, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, PCIE4, PCIE4 } },
+ {0x41, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
+ {0x42, {PCIE3, PCIE3, PCIE3, PCIE3, PCIE4, PCIE4, SATA1, SATA2 } },
+ {0x43, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } },
+ {0x44, {PCIE3, PCIE3, PCIE3, PCIE3, NONE, NONE, SATA1, SATA2 } },
+ {0x45, {PCIE3, SGMII10, SGMII11, SGMII12, PCIE4, SGMII14, SGMII15,
+ SGMII16 } },
+ {0x47, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, PCIE4,
+ PCIE4 } },
+ {0x49, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1,
+ SATA2 } },
+ {0x4A, {SGMII9, SGMII10, SGMII11, SGMII12, PCIE4, PCIE4, SATA1,
+ SATA2 } },
+ {}
+};
+
+static struct serdes_config *serdes_cfg_tbl[] = {
+ serdes1_cfg_tbl,
+ serdes2_cfg_tbl,
+};
+
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane)
+{
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == cfg)
+ return ptr->lanes[lane];
+ ptr++;
+ }
+
+ return 0;
+}
+
+int is_serdes_prtcl_valid(int serdes, u32 prtcl)
+{
+ int i;
+ struct serdes_config *ptr;
+
+ if (serdes >= ARRAY_SIZE(serdes_cfg_tbl))
+ return 0;
+
+ ptr = serdes_cfg_tbl[serdes];
+ while (ptr->protocol) {
+ if (ptr->protocol == prtcl)
+ break;
+ ptr++;
+ }
+
+ if (!ptr->protocol)
+ return 0;
+
+ for (i = 0; i < SRDS_MAX_LANES; i++) {
+ if (ptr->lanes[i] != NONE)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/mp.c b/arch/arm/cpu/armv8/fsl-lsch3/mp.c
index ce9c0c1..da7853a 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/mp.c
+++ b/arch/arm/cpu/armv8/fsl-lsch3/mp.c
@@ -31,6 +31,13 @@ int fsl_lsch3_wake_seconday_cores(void)
int i, timeout = 10;
u64 *table = get_spin_tbl_addr();
+#ifdef COUNTER_FREQUENCY_REAL
+ /* update for secondary cores */
+ __real_cntfrq = COUNTER_FREQUENCY_REAL;
+ flush_dcache_range((unsigned long)&__real_cntfrq,
+ (unsigned long)&__real_cntfrq + 8);
+#endif
+
cores = cpu_mask();
/* Clear spin table so that secondary processors
* observe the correct value after waking up from wfe.
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/mp.h b/arch/arm/cpu/armv8/fsl-lsch3/mp.h
index 66144d6..c985d6a 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/mp.h
+++ b/arch/arm/cpu/armv8/fsl-lsch3/mp.h
@@ -26,6 +26,7 @@
#define id_to_core(x) ((x & 3) | (x >> 6))
#ifndef __ASSEMBLY__
extern u64 __spin_table[];
+extern u64 __real_cntfrq;
extern u64 *secondary_boot_code;
extern size_t __secondary_boot_code_size;
int fsl_lsch3_wake_seconday_cores(void);
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/soc.c b/arch/arm/cpu/armv8/fsl-lsch3/soc.c
new file mode 100644
index 0000000..2538001
--- /dev/null
+++ b/arch/arm/cpu/armv8/fsl-lsch3/soc.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fsl_ifc.h>
+#include <nand.h>
+#include <spl.h>
+#include <asm/arch-fsl-lsch3/soc.h>
+#include <asm/io.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void erratum_a008751(void)
+{
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008751
+ u32 __iomem *scfg = (u32 __iomem *)SCFG_BASE;
+
+ writel(0x27672b2a, scfg + SCFG_USB3PRM1CR / 4);
+#endif
+}
+
+static void erratum_rcw_src(void)
+{
+#if defined(CONFIG_SPL)
+ u32 __iomem *dcfg_ccsr = (u32 __iomem *)DCFG_BASE;
+ u32 __iomem *dcfg_dcsr = (u32 __iomem *)DCFG_DCSR_BASE;
+ u32 val;
+
+ val = in_le32(dcfg_ccsr + DCFG_PORSR1 / 4);
+ val &= ~DCFG_PORSR1_RCW_SRC;
+ val |= DCFG_PORSR1_RCW_SRC_NOR;
+ out_le32(dcfg_dcsr + DCFG_DCSR_PORCR1 / 4, val);
+#endif
+}
+
+#define I2C_DEBUG_REG 0x6
+#define I2C_GLITCH_EN 0x8
+/*
+ * This erratum requires setting glitch_en bit to enable
+ * digital glitch filter to improve clock stability.
+ */
+static void erratum_a009203(void)
+{
+ u8 __iomem *ptr;
+#ifdef CONFIG_SYS_I2C
+#ifdef I2C1_BASE_ADDR
+ ptr = (u8 __iomem *)(I2C1_BASE_ADDR + I2C_DEBUG_REG);
+
+ writeb(I2C_GLITCH_EN, ptr);
+#endif
+#ifdef I2C2_BASE_ADDR
+ ptr = (u8 __iomem *)(I2C2_BASE_ADDR + I2C_DEBUG_REG);
+
+ writeb(I2C_GLITCH_EN, ptr);
+#endif
+#ifdef I2C3_BASE_ADDR
+ ptr = (u8 __iomem *)(I2C3_BASE_ADDR + I2C_DEBUG_REG);
+
+ writeb(I2C_GLITCH_EN, ptr);
+#endif
+#ifdef I2C4_BASE_ADDR
+ ptr = (u8 __iomem *)(I2C4_BASE_ADDR + I2C_DEBUG_REG);
+
+ writeb(I2C_GLITCH_EN, ptr);
+#endif
+#endif
+}
+
+void fsl_lsch3_early_init_f(void)
+{
+ erratum_a008751();
+ erratum_rcw_src();
+ init_early_memctl_regs(); /* tighten IFC timing */
+ erratum_a009203();
+}
+
+#ifdef CONFIG_SPL_BUILD
+void board_init_f(ulong dummy)
+{
+ /* Clear global data */
+ memset((void *)gd, 0, sizeof(gd_t));
+
+ arch_cpu_init();
+ board_early_init_f();
+ timer_init();
+ env_init();
+ gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE);
+
+ serial_init();
+ console_init_f();
+ dram_init();
+
+ /* Clear the BSS. */
+ memset(__bss_start, 0, __bss_end - __bss_start);
+
+ board_init_r(NULL, 0);
+}
+
+u32 spl_boot_device(void)
+{
+ return BOOT_DEVICE_NAND;
+}
+#endif
diff --git a/arch/arm/cpu/armv8/fsl-lsch3/speed.c b/arch/arm/cpu/armv8/fsl-lsch3/speed.c
index 72cd999..cac4f92 100644
--- a/arch/arm/cpu/armv8/fsl-lsch3/speed.c
+++ b/arch/arm/cpu/armv8/fsl-lsch3/speed.c
@@ -26,7 +26,7 @@ void get_sys_info(struct sys_info *sys_info)
{
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
#ifdef CONFIG_FSL_IFC
- struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
+ struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
u32 ccr;
#endif
struct ccsr_clk_cluster_group __iomem *clk_grp[2] = {
@@ -86,6 +86,8 @@ void get_sys_info(struct sys_info *sys_info)
sys_info->freq_systembus *= (in_le32(&gur->rcwsr[0]) >>
FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_SHIFT) &
FSL_CHASSIS3_RCWSR0_SYS_PLL_RAT_MASK;
+ /* Platform clock is half of platform PLL */
+ sys_info->freq_systembus /= 2;
sys_info->freq_ddrbus *= (in_le32(&gur->rcwsr[0]) >>
FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_SHIFT) &
FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK;
@@ -102,10 +104,7 @@ void get_sys_info(struct sys_info *sys_info)
offsetof(struct ccsr_clk_cluster_group,
pllngsr[i%3].gsr));
ratio[i] = (in_le32(offset) >> 1) & 0x3f;
- if (ratio[i] > 4)
- freq_c_pll[i] = sysclk * ratio[i];
- else
- freq_c_pll[i] = sys_info->freq_systembus * ratio[i];
+ freq_c_pll[i] = sysclk * ratio[i];
}
for_each_cpu(i, cpu, cpu_numcores(), cpu_mask()) {
@@ -119,7 +118,7 @@ void get_sys_info(struct sys_info *sys_info)
}
#if defined(CONFIG_FSL_IFC)
- ccr = in_le32(&ifc_regs->ifc_ccr);
+ ccr = in_le32(&ifc_regs.gregs->ifc_ccr);
ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
sys_info->freq_localbus = sys_info->freq_systembus / ccr;
diff --git a/arch/arm/cpu/armv8/generic_timer.c b/arch/arm/cpu/armv8/generic_timer.c
index 223b95e..8e60bae 100644
--- a/arch/arm/cpu/armv8/generic_timer.c
+++ b/arch/arm/cpu/armv8/generic_timer.c
@@ -25,7 +25,18 @@ unsigned long get_tbclk(void)
unsigned long timer_read_counter(void)
{
unsigned long cntpct;
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008585
+ /* This erratum number needs to be confirmed to match ARM document */
+ unsigned long temp;
+#endif
isb();
asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008585
+ asm volatile("mrs %0, cntpct_el0" : "=r" (temp));
+ while (temp != cntpct) {
+ asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct));
+ asm volatile("mrs %0, cntpct_el0" : "=r" (temp));
+ }
+#endif
return cntpct;
}
diff --git a/arch/arm/cpu/armv8/u-boot-spl.lds b/arch/arm/cpu/armv8/u-boot-spl.lds
new file mode 100644
index 0000000..4df339c
--- /dev/null
+++ b/arch/arm/cpu/armv8/u-boot-spl.lds
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ * Aneesh V <aneesh@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,
+ LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR,
+ LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(_start)
+SECTIONS
+{
+ .text : {
+ . = ALIGN(8);
+ *(.__image_copy_start)
+ CPUDIR/start.o (.text*)
+ *(.text*)
+ } >.sram
+
+ .rodata : {
+ . = ALIGN(8);
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ } >.sram
+
+ .data : {
+ . = ALIGN(8);
+ *(.data*)
+ } >.sram
+
+ .u_boot_list : {
+ . = ALIGN(8);
+ KEEP(*(SORT(.u_boot_list*)));
+ } >.sram
+
+ .image_copy_end : {
+ . = ALIGN(8);
+ *(.__image_copy_end)
+ } >.sram
+
+ .end : {
+ . = ALIGN(8);
+ *(.__end)
+ } >.sram
+
+ .bss_start : {
+ . = ALIGN(8);
+ KEEP(*(.__bss_start));
+ } >.sdram
+
+ .bss : {
+ *(.bss*)
+ . = ALIGN(8);
+ } >.sdram
+
+ .bss_end : {
+ KEEP(*(.__bss_end));
+ } >.sdram
+
+ /DISCARD/ : { *(.dynsym) }
+ /DISCARD/ : { *(.dynstr*) }
+ /DISCARD/ : { *(.dynamic*) }
+ /DISCARD/ : { *(.plt*) }
+ /DISCARD/ : { *(.interp*) }
+ /DISCARD/ : { *(.gnu*) }
+}
diff --git a/arch/arm/include/asm/arch-fsl-lsch3/config.h b/arch/arm/include/asm/arch-fsl-lsch3/config.h
index b140c1f..ca8d38c 100644
--- a/arch/arm/include/asm/arch-fsl-lsch3/config.h
+++ b/arch/arm/include/asm/arch-fsl-lsch3/config.h
@@ -8,6 +8,14 @@
#define _ASM_ARMV8_FSL_LSCH3_CONFIG_
#include <fsl_ddrc_version.h>
+
+#define CONFIG_SYS_PAGE_SIZE 0x10000
+
+#ifndef L1_CACHE_BYTES
+#define L1_CACHE_SHIFT 6
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+#endif
+
#define CONFIG_MP
#define CONFIG_SYS_FSL_OCRAM_BASE 0x18000000 /* initial RAM */
/* Link Definitions */
@@ -23,6 +31,7 @@
#define CONFIG_SYS_FSL_CH3_CLK_GRPA_ADDR (CONFIG_SYS_IMMR + 0x00300000)
#define CONFIG_SYS_FSL_CH3_CLK_GRPB_ADDR (CONFIG_SYS_IMMR + 0x00310000)
#define CONFIG_SYS_FSL_CH3_CLK_CTRL_ADDR (CONFIG_SYS_IMMR + 0x00370000)
+#define CONFIG_SYS_FSL_ESDHC_ADDR (CONFIG_SYS_IMMR + 0x01140000)
#define CONFIG_SYS_IFC_ADDR (CONFIG_SYS_IMMR + 0x01240000)
#define CONFIG_SYS_NS16550_COM1 (CONFIG_SYS_IMMR + 0x011C0500)
#define CONFIG_SYS_NS16550_COM2 (CONFIG_SYS_IMMR + 0x011C0600)
@@ -30,6 +39,20 @@
#define CONFIG_SYS_FSL_PMU_CLTBENR (CONFIG_SYS_FSL_PMU_ADDR + \
0x18A0)
+#define CONFIG_SYS_FSL_WRIOP1_ADDR (CONFIG_SYS_IMMR + 0x7B80000)
+#define CONFIG_SYS_FSL_WRIOP1_MDIO1 (CONFIG_SYS_FSL_WRIOP1_ADDR + 0x16000)
+#define CONFIG_SYS_FSL_WRIOP1_MDIO2 (CONFIG_SYS_FSL_WRIOP1_ADDR + 0x17000)
+#define CONFIG_SYS_FSL_LSCH3_SERDES_ADDR (CONFIG_SYS_IMMR + 0xEA0000)
+
+/* SP (Cortex-A5) related */
+#define CONFIG_SYS_FSL_SP_ADDR (CONFIG_SYS_IMMR + 0x00F00000)
+#define CONFIG_SYS_FSL_SP_VSG_GIC_ADDR (CONFIG_SYS_FSL_SP_ADDR)
+#define CONFIG_SYS_FSL_SP_VSG_GIC_VIGR1 (CONFIG_SYS_FSL_SP_ADDR)
+#define CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2 \
+ (CONFIG_SYS_FSL_SP_ADDR + 0x0008)
+#define CONFIG_SYS_FSL_SP_LOOPBACK_DUART \
+ (CONFIG_SYS_FSL_SP_ADDR + 0x1000)
+
#define CONFIG_SYS_FSL_DCSR_DDR_ADDR 0x70012c000ULL
#define CONFIG_SYS_FSL_DCSR_DDR2_ADDR 0x70012d000ULL
#define CONFIG_SYS_FSL_DCSR_DDR3_ADDR 0x700132000ULL
@@ -88,22 +111,57 @@
#define CONFIG_MAX_MEM_MAPPED CONFIG_SYS_LS2_DDR_BLOCK1_SIZE
#define CONFIG_SYS_FSL_DDR_VER FSL_DDR_VER_5_0
-
+#define CONFIG_SYS_FSL_ESDHC_LE
/* IFC */
#define CONFIG_SYS_FSL_IFC_LE
+#define CONFIG_SYS_MEMAC_LITTLE_ENDIAN
+
+/* PCIe */
+#define CONFIG_SYS_PCIE1_ADDR (CONFIG_SYS_IMMR + 0x2400000)
+#define CONFIG_SYS_PCIE2_ADDR (CONFIG_SYS_IMMR + 0x2500000)
+#define CONFIG_SYS_PCIE3_ADDR (CONFIG_SYS_IMMR + 0x2600000)
+#define CONFIG_SYS_PCIE4_ADDR (CONFIG_SYS_IMMR + 0x2700000)
+#define CONFIG_SYS_PCIE1_PHYS_ADDR 0x1000000000ULL
+#define CONFIG_SYS_PCIE2_PHYS_ADDR 0x1200000000ULL
+#define CONFIG_SYS_PCIE3_PHYS_ADDR 0x1400000000ULL
+#define CONFIG_SYS_PCIE4_PHYS_ADDR 0x1600000000ULL
+
+/* Cache Coherent Interconnect */
+#define CCI_MN_BASE 0x04000000
+#define CCI_MN_RNF_NODEID_LIST 0x180
+#define CCI_MN_DVM_DOMAIN_CTL 0x200
+#define CCI_MN_DVM_DOMAIN_CTL_SET 0x210
+
+/* Device Configuration */
+#define DCFG_BASE 0x01e00000
+#define DCFG_PORSR1 0x000
+#define DCFG_PORSR1_RCW_SRC 0xff800000
+#define DCFG_PORSR1_RCW_SRC_NOR 0x12f00000
+
+#define DCFG_DCSR_BASE 0X700100000ULL
+#define DCFG_DCSR_PORCR1 0x000
+
+/* Supplemental Configuration */
+#define SCFG_BASE 0x01fc0000
+#define SCFG_USB3PRM1CR 0x000
#ifdef CONFIG_LS2085A
#define CONFIG_MAX_CPUS 16
#define CONFIG_SYS_FSL_IFC_BANK_COUNT 8
#define CONFIG_NUM_DDR_CONTROLLERS 3
#define CONFIG_SYS_FSL_CLUSTER_CLOCKS { 1, 1, 4, 4 }
+#define CONFIG_SYS_FSL_SRDS_1
+#define CONFIG_SYS_FSL_SRDS_2
#else
#error SoC not defined
#endif
#ifdef CONFIG_LS2085A
#define CONFIG_SYS_FSL_ERRATUM_A008336
+#define CONFIG_SYS_FSL_ERRATUM_A008511
#define CONFIG_SYS_FSL_ERRATUM_A008514
+#define CONFIG_SYS_FSL_ERRATUM_A008585
+#define CONFIG_SYS_FSL_ERRATUM_A008751
#endif
#endif /* _ASM_ARMV8_FSL_LSCH3_CONFIG_ */
diff --git a/arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h b/arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h
new file mode 100644
index 0000000..2810f3f
--- /dev/null
+++ b/arch/arm/include/asm/arch-fsl-lsch3/fsl_serdes.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __FSL_SERDES_H
+#define __FSL_SERDES_H
+
+#include <config.h>
+
+#define SRDS_MAX_LANES 8
+
+enum srds_prtcl {
+ NONE = 0,
+ PCIE1,
+ PCIE2,
+ PCIE3,
+ PCIE4,
+ SATA1,
+ SATA2,
+ XAUI1,
+ XAUI2,
+ XFI1,
+ XFI2,
+ XFI3,
+ XFI4,
+ XFI5,
+ XFI6,
+ XFI7,
+ XFI8,
+ SGMII1,
+ SGMII2,
+ SGMII3,
+ SGMII4,
+ SGMII5,
+ SGMII6,
+ SGMII7,
+ SGMII8,
+ SGMII9,
+ SGMII10,
+ SGMII11,
+ SGMII12,
+ SGMII13,
+ SGMII14,
+ SGMII15,
+ SGMII16,
+ QSGMII_A, /* A indicates MACs 1-4 */
+ QSGMII_B, /* B indicates MACs 5-8 */
+ QSGMII_C, /* C indicates MACs 9-12 */
+ QSGMII_D, /* D indicates MACs 12-16 */
+ SERDES_PRCTL_COUNT
+};
+
+enum srds {
+ FSL_SRDS_1 = 0,
+ FSL_SRDS_2 = 1,
+};
+
+int is_serdes_configured(enum srds_prtcl device);
+void fsl_serdes_init(void);
+
+int serdes_get_first_lane(u32 sd, enum srds_prtcl device);
+enum srds_prtcl serdes_get_prtcl(int serdes, int cfg, int lane);
+int is_serdes_prtcl_valid(int serdes, u32 prtcl);
+
+#endif /* __FSL_SERDES_H */
diff --git a/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h b/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h
index dd11ef7..d6bee60 100644
--- a/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h
+++ b/arch/arm/include/asm/arch-fsl-lsch3/immap_lsch3.h
@@ -47,6 +47,30 @@ struct ccsr_gur {
u32 devdisr5; /* Device disable control 5 */
u32 devdisr6; /* Device disable control 6 */
u32 devdisr7; /* Device disable control 7 */
+#define FSL_CHASSIS3_DEVDISR2_DPMAC1 0x00000001
+#define FSL_CHASSIS3_DEVDISR2_DPMAC2 0x00000002
+#define FSL_CHASSIS3_DEVDISR2_DPMAC3 0x00000004
+#define FSL_CHASSIS3_DEVDISR2_DPMAC4 0x00000008
+#define FSL_CHASSIS3_DEVDISR2_DPMAC5 0x00000010
+#define FSL_CHASSIS3_DEVDISR2_DPMAC6 0x00000020
+#define FSL_CHASSIS3_DEVDISR2_DPMAC7 0x00000040
+#define FSL_CHASSIS3_DEVDISR2_DPMAC8 0x00000080
+#define FSL_CHASSIS3_DEVDISR2_DPMAC9 0x00000100
+#define FSL_CHASSIS3_DEVDISR2_DPMAC10 0x00000200
+#define FSL_CHASSIS3_DEVDISR2_DPMAC11 0x00000400
+#define FSL_CHASSIS3_DEVDISR2_DPMAC12 0x00000800
+#define FSL_CHASSIS3_DEVDISR2_DPMAC13 0x00001000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC14 0x00002000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC15 0x00004000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC16 0x00008000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC17 0x00010000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC18 0x00020000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC19 0x00040000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC20 0x00080000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC21 0x00100000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC22 0x00200000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC23 0x00400000
+#define FSL_CHASSIS3_DEVDISR2_DPMAC24 0x00800000
u8 res_08c[0x90-0x8c];
u32 coredisru; /* uppper portion for support of 64 cores */
u32 coredisrl; /* lower portion for support of 64 cores */
@@ -63,6 +87,11 @@ struct ccsr_gur {
#define FSL_CHASSIS3_RCWSR0_MEM_PLL_RAT_MASK 0x3f
#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_SHIFT 18
#define FSL_CHASSIS3_RCWSR0_MEM2_PLL_RAT_MASK 0x3f
+#define FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK 0x00FF0000
+#define FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT 16
+#define FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK 0xFF000000
+#define FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT 24
+
u8 res_180[0x200-0x180];
u32 scratchrw[32]; /* Scratch Read/Write */
u8 res_280[0x300-0x280];
diff --git a/arch/arm/include/asm/arch-fsl-lsch3/soc.h b/arch/arm/include/asm/arch-fsl-lsch3/soc.h
new file mode 100644
index 0000000..16b723d
--- /dev/null
+++ b/arch/arm/include/asm/arch-fsl-lsch3/soc.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+void fsl_lsch3_early_init_f(void);
+
diff --git a/arch/arm/include/asm/arch-ls102xa/config.h b/arch/arm/include/asm/arch-ls102xa/config.h
index 6561ce6..4dc528b 100644
--- a/arch/arm/include/asm/arch-ls102xa/config.h
+++ b/arch/arm/include/asm/arch-ls102xa/config.h
@@ -119,10 +119,6 @@
#define DCU_LAYER_MAX_NUM 16
-#define QE_MURAM_SIZE 0x6000UL
-#define MAX_QE_RISC 1
-#define QE_NUM_OF_SNUM 28
-
#define CONFIG_SYS_FSL_SRDS_1
#ifdef CONFIG_LS102XA
diff --git a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h
index 3a64afc..a8122c1 100644
--- a/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h
+++ b/arch/arm/include/asm/arch-ls102xa/immap_ls102xa.h
@@ -17,6 +17,9 @@
#define SOC_VER_LS1021 0x11
#define SOC_VER_LS1022 0x12
+#define SOC_MAJOR_VER_1_0 0x1
+#define SOC_MAJOR_VER_2_0 0x2
+
#define CCSR_BRR_OFFSET 0xe4
#define CCSR_SCRATCHRW1_OFFSET 0x200
diff --git a/arch/arm/include/asm/fsl_secure_boot.h b/arch/arm/include/asm/fsl_secure_boot.h
new file mode 100644
index 0000000..f097c81
--- /dev/null
+++ b/arch/arm/include/asm/fsl_secure_boot.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __FSL_SECURE_BOOT_H
+#define __FSL_SECURE_BOOT_H
+
+#ifdef CONFIG_SECURE_BOOT
+#ifndef CONFIG_FIT_SIGNATURE
+
+#define CONFIG_EXTRA_ENV \
+ "setenv fdt_high 0xcfffffff;" \
+ "setenv initrd_high 0xcfffffff;" \
+ "setenv hwconfig \'fsl_ddr:ctlr_intlv=null,bank_intlv=null\';"
+
+/* The address needs to be modified according to NOR memory map */
+#define CONFIG_BOOTSCRIPT_HDR_ADDR 0x600a0000
+
+#include <config_fsl_secboot.h>
+#endif
+#endif
+
+#endif
diff --git a/arch/arm/include/asm/pcie_layerscape.h b/arch/arm/include/asm/pcie_layerscape.h
deleted file mode 100644
index fb08578..0000000
--- a/arch/arm/include/asm/pcie_layerscape.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright 2014 Freescale Semiconductor, Inc.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef __PCIE_LAYERSCAPE_H_
-#define __PCIE_LAYERSCAPE_H_
-
-void pci_init_board(void);
-void ft_pcie_setup(void *blob, bd_t *bd);
-
-#endif
diff --git a/arch/arm/lib/crt0_64.S b/arch/arm/lib/crt0_64.S
index 1654011..bc9c53c 100644
--- a/arch/arm/lib/crt0_64.S
+++ b/arch/arm/lib/crt0_64.S
@@ -61,7 +61,11 @@ ENTRY(_main)
/*
* Set up initial C runtime environment and call board_init_f(0).
*/
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_STACK)
+ ldr x0, =(CONFIG_SPL_STACK)
+#else
ldr x0, =(CONFIG_SYS_INIT_SP_ADDR)
+#endif
sub x18, x0, #GD_SIZE /* allocate one GD above SP */
bic x18, x18, #0x7 /* 8-byte alignment for GD */
zero_gd:
@@ -77,6 +81,7 @@ zero_gd:
mov x0, #0
bl board_init_f
+#if !defined(CONFIG_SPL_BUILD)
/*
* Set up intermediate environment (new sp and gd) and call
* relocate_code(addr_moni). Trick here is that we'll return
@@ -119,4 +124,6 @@ clear_loop:
/* NOTREACHED - board_init_r() does not return */
+#endif /* !CONFIG_SPL_BUILD */
+
ENDPROC(_main)
diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
index 5ca9bf5..235a635 100644
--- a/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
+++ b/arch/powerpc/cpu/mpc85xx/cpu_init_early.c
@@ -15,7 +15,7 @@ DECLARE_GLOBAL_DATA_PTR;
#ifdef CONFIG_A003399_NOR_WORKAROUND
void setup_ifc(void)
{
- struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
+ struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
u32 _mas0, _mas1, _mas2, _mas3, _mas7;
phys_addr_t flash_phys = CONFIG_SYS_FLASH_BASE_PHYS;
@@ -70,9 +70,9 @@ void setup_ifc(void)
#endif
/* Change flash's physical address */
- ifc_out32(&(ifc_regs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0);
- ifc_out32(&(ifc_regs->csor_cs[0].csor), CONFIG_SYS_CSOR0);
- ifc_out32(&(ifc_regs->amask_cs[0].amask), CONFIG_SYS_AMASK0);
+ ifc_out32(&(ifc_regs.gregs->cspr_cs[0].cspr), CONFIG_SYS_CSPR0);
+ ifc_out32(&(ifc_regs.gregs->csor_cs[0].csor), CONFIG_SYS_CSOR0);
+ ifc_out32(&(ifc_regs.gregs->amask_cs[0].amask), CONFIG_SYS_AMASK0);
return ;
}
diff --git a/arch/powerpc/cpu/mpc85xx/speed.c b/arch/powerpc/cpu/mpc85xx/speed.c
index e24b857..321ade2 100644
--- a/arch/powerpc/cpu/mpc85xx/speed.c
+++ b/arch/powerpc/cpu/mpc85xx/speed.c
@@ -28,7 +28,7 @@ void get_sys_info(sys_info_t *sys_info)
{
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
#ifdef CONFIG_FSL_IFC
- struct fsl_ifc *ifc_regs = (void *)CONFIG_SYS_IFC_ADDR;
+ struct fsl_ifc ifc_regs = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
u32 ccr;
#endif
#ifdef CONFIG_FSL_CORENET
@@ -597,7 +597,7 @@ void get_sys_info(sys_info_t *sys_info)
#endif
#if defined(CONFIG_FSL_IFC)
- ccr = ifc_in32(&ifc_regs->ifc_ccr);
+ ccr = ifc_in32(&ifc_regs.gregs->ifc_ccr);
ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT) + 1;
sys_info->freq_localbus = sys_info->freq_systembus / ccr;
diff --git a/arch/powerpc/include/asm/fsl_secure_boot.h b/arch/powerpc/include/asm/fsl_secure_boot.h
index 49f6814..8f794ef 100644
--- a/arch/powerpc/include/asm/fsl_secure_boot.h
+++ b/arch/powerpc/include/asm/fsl_secure_boot.h
@@ -67,5 +67,24 @@
#define CONFIG_FSL_ISBC_KEY_EXT
#endif
+#ifndef CONFIG_FIT_SIGNATURE
+/* The bootscript header address is different for B4860 because the NOR
+ * mapping is different on B4 due to reduced NOR size.
+ */
+#if defined(CONFIG_B4860QDS)
+#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xecc00000
+#elif defined(CONFIG_FSL_CORENET)
+#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xe8e00000
+#elif defined(CONFIG_BSC9132QDS)
+#define CONFIG_BOOTSCRIPT_HDR_ADDR 0x88020000
+#elif defined(CONFIG_C29XPCIE)
+#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xec020000
+#else
+#define CONFIG_BOOTSCRIPT_HDR_ADDR 0xee020000
+#endif
+
+#include <config_fsl_secboot.h>
+#endif
+
#endif
#endif
diff --git a/board/freescale/bsc9132qds/bsc9132qds.c b/board/freescale/bsc9132qds/bsc9132qds.c
index 36a68db..586dacc 100644
--- a/board/freescale/bsc9132qds/bsc9132qds.c
+++ b/board/freescale/bsc9132qds/bsc9132qds.c
@@ -36,9 +36,9 @@ DECLARE_GLOBAL_DATA_PTR;
int board_early_init_f(void)
{
- struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
+ struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
- setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
+ setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
return 0;
}
diff --git a/board/freescale/c29xpcie/c29xpcie.c b/board/freescale/c29xpcie/c29xpcie.c
index d7577096..f42d373 100644
--- a/board/freescale/c29xpcie/c29xpcie.c
+++ b/board/freescale/c29xpcie/c29xpcie.c
@@ -38,10 +38,10 @@ int checkboard(void)
int board_early_init_f(void)
{
- struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
+ struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
/* Clock configuration to access CPLD using IFC(GPCM) */
- setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
+ setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
return 0;
}
diff --git a/board/freescale/common/arm_sleep.c b/board/freescale/common/arm_sleep.c
index 8edf878..c06b862 100644
--- a/board/freescale/common/arm_sleep.c
+++ b/board/freescale/common/arm_sleep.c
@@ -19,6 +19,9 @@
#endif
#include "sleep.h"
+#ifdef CONFIG_U_QE
+#include "../../../drivers/qe/qe.h"
+#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -72,6 +75,9 @@ static void dp_resume_prepare(void)
board_sleep_prepare();
armv7_init_nonsec();
cleanup_before_linux();
+#ifdef CONFIG_U_QE
+ u_qe_resume();
+#endif
}
int fsl_dp_resume(void)
diff --git a/board/freescale/common/cmd_esbc_validate.c b/board/freescale/common/cmd_esbc_validate.c
index 8500ba5..8bbe85b 100644
--- a/board/freescale/common/cmd_esbc_validate.c
+++ b/board/freescale/common/cmd_esbc_validate.c
@@ -8,6 +8,16 @@
#include <command.h>
#include <fsl_validate.h>
+static int do_esbc_halt(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ printf("Core is entering spin loop.\n");
+loop:
+ goto loop;
+
+ return 0;
+}
+
static int do_esbc_validate(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
@@ -32,3 +42,9 @@ U_BOOT_CMD(
"Validates signature on a given image using RSA verification",
esbc_validate_help_text
);
+
+U_BOOT_CMD(
+ esbc_halt, 1, 0, do_esbc_halt,
+ "Put the core in spin loop ",
+ ""
+);
diff --git a/board/freescale/common/mpc85xx_sleep.c b/board/freescale/common/mpc85xx_sleep.c
index f924e7f..9e4132c 100644
--- a/board/freescale/common/mpc85xx_sleep.c
+++ b/board/freescale/common/mpc85xx_sleep.c
@@ -7,6 +7,9 @@
#include <common.h>
#include <asm/immap_85xx.h>
#include "sleep.h"
+#ifdef CONFIG_U_QE
+#include "../../../drivers/qe/qe.h"
+#endif
DECLARE_GLOBAL_DATA_PTR;
@@ -65,6 +68,11 @@ static void dp_resume_prepare(void)
disable_cpc_sram();
#endif
enable_cpc();
+
+#ifdef CONFIG_U_QE
+ u_qe_resume();
+#endif
+
}
int fsl_dp_resume(void)
diff --git a/board/freescale/common/qixis.c b/board/freescale/common/qixis.c
index a49e300..9f6b0e7 100644
--- a/board/freescale/common/qixis.c
+++ b/board/freescale/common/qixis.c
@@ -138,24 +138,23 @@ void qixis_bank_reset(void)
QIXIS_WRITE(rcfg_ctl, QIXIS_RCFG_CTL_RECONFIG_START);
}
-/* Set the boot bank to the power-on default bank */
-void clear_altbank(void)
+static void __maybe_unused set_lbmap(int lbmap)
{
u8 reg;
reg = QIXIS_READ(brdcfg[0]);
- reg = (reg & ~QIXIS_LBMAP_MASK) | QIXIS_LBMAP_DFLTBANK;
+ reg = (reg & ~QIXIS_LBMAP_MASK) | lbmap;
QIXIS_WRITE(brdcfg[0], reg);
}
-/* Set the boot bank to the alternate bank */
-void set_altbank(void)
+static void __maybe_unused set_rcw_src(int rcw_src)
{
u8 reg;
- reg = QIXIS_READ(brdcfg[0]);
- reg = (reg & ~QIXIS_LBMAP_MASK) | QIXIS_LBMAP_ALTBANK;
- QIXIS_WRITE(brdcfg[0], reg);
+ reg = QIXIS_READ(dutcfg[1]);
+ reg = (reg & ~1) | (rcw_src & 1);
+ QIXIS_WRITE(dutcfg[1], reg);
+ QIXIS_WRITE(dutcfg[0], (rcw_src >> 1) & 0xff);
}
static void qixis_dump_regs(void)
@@ -201,11 +200,22 @@ int qixis_reset_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
int i;
if (argc <= 1) {
- clear_altbank();
+ set_lbmap(QIXIS_LBMAP_DFLTBANK);
qixis_reset();
} else if (strcmp(argv[1], "altbank") == 0) {
- set_altbank();
+ set_lbmap(QIXIS_LBMAP_ALTBANK);
qixis_bank_reset();
+ } else if (strcmp(argv[1], "nand") == 0) {
+#ifdef QIXIS_LBMAP_NAND
+ QIXIS_WRITE(rst_ctl, 0x30);
+ QIXIS_WRITE(rcfg_ctl, 0);
+ set_lbmap(QIXIS_LBMAP_NAND);
+ set_rcw_src(QIXIS_RCW_SRC_NAND);
+ QIXIS_WRITE(rcfg_ctl, 0x20);
+ QIXIS_WRITE(rcfg_ctl, 0x21);
+#else
+ printf("Not implemented\n");
+#endif
} else if (strcmp(argv[1], "watchdog") == 0) {
static char *period[9] = {"2s", "4s", "8s", "16s", "32s",
"1min", "2min", "4min", "8min"};
@@ -244,6 +254,7 @@ U_BOOT_CMD(
"Reset the board using the FPGA sequencer",
"- hard reset to default bank\n"
"qixis_reset altbank - reset to alternate bank\n"
+ "qixis_reset nand - reset to nand\n"
"qixis watchdog <watchdog_period> - set the watchdog period\n"
" period: 1s 2s 4s 8s 16s 32s 1min 2min 4min 8min\n"
"qixis_reset dump - display the QIXIS registers\n"
diff --git a/board/freescale/ls1021aqds/MAINTAINERS b/board/freescale/ls1021aqds/MAINTAINERS
index 661526b..820d322 100644
--- a/board/freescale/ls1021aqds/MAINTAINERS
+++ b/board/freescale/ls1021aqds/MAINTAINERS
@@ -5,6 +5,7 @@ F: board/freescale/ls1021aqds/
F: include/configs/ls1021aqds.h
F: configs/ls1021aqds_nor_defconfig
F: configs/ls1021aqds_ddr4_nor_defconfig
+F: configs/ls1021aqds_ddr4_nor_lpuart_defconfig
F: configs/ls1021aqds_nor_SECURE_BOOT_defconfig
F: configs/ls1021aqds_nor_lpuart_defconfig
F: configs/ls1021aqds_sdcard_defconfig
diff --git a/board/freescale/ls1021aqds/ls1021aqds.c b/board/freescale/ls1021aqds/ls1021aqds.c
index 722b88f..92f613a 100644
--- a/board/freescale/ls1021aqds/ls1021aqds.c
+++ b/board/freescale/ls1021aqds/ls1021aqds.c
@@ -12,7 +12,6 @@
#include <asm/arch/clock.h>
#include <asm/arch/fsl_serdes.h>
#include <asm/arch/ls102xa_stream_id.h>
-#include <asm/pcie_layerscape.h>
#include <hwconfig.h>
#include <mmc.h>
#include <fsl_esdhc.h>
@@ -138,6 +137,17 @@ unsigned long get_board_ddr_clk(void)
return 66666666;
}
+unsigned int get_soc_major_rev(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int svr, major;
+
+ svr = in_be32(&gur->svr);
+ major = SVR_MAJ(svr);
+
+ return major;
+}
+
int select_i2c_ch_pca9547(u8 ch)
{
int ret;
@@ -181,6 +191,7 @@ int board_early_init_f(void)
{
struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
+ unsigned int major;
#ifdef CONFIG_TSEC_ENET
out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR);
@@ -205,19 +216,22 @@ int board_early_init_f(void)
out_le32(&cci->slave[4].snoop_ctrl,
CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
- /*
- * Set CCI-400 Slave interface S1, S2 Shareable Override Register
- * All transactions are treated as non-shareable
- */
- out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
- out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
-
- /* Workaround for the issue that DDR could not respond to
- * barrier transaction which is generated by executing DSB/ISB
- * instruction. Set CCI-400 control override register to
- * terminate the barrier transaction. After DDR is initialized,
- * allow barrier transaction to DDR again */
- out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
+ major = get_soc_major_rev();
+ if (major == SOC_MAJOR_VER_1_0) {
+ /*
+ * Set CCI-400 Slave interface S1, S2 Shareable Override
+ * Register All transactions are treated as non-shareable
+ */
+ out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
+ out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
+
+ /* Workaround for the issue that DDR could not respond to
+ * barrier transaction which is generated by executing DSB/ISB
+ * instruction. Set CCI-400 control override register to
+ * terminate the barrier transaction. After DDR is initialized,
+ * allow barrier transaction to DDR again */
+ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
+ }
#if defined(CONFIG_DEEP_SLEEP)
if (is_warm_boot())
@@ -231,6 +245,7 @@ int board_early_init_f(void)
void board_init_f(ulong dummy)
{
struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
+ unsigned int major;
#ifdef CONFIG_NAND_BOOT
struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
@@ -267,7 +282,10 @@ void board_init_f(ulong dummy)
#ifdef CONFIG_SPL_I2C_SUPPORT
i2c_init_all();
#endif
- out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
+
+ major = get_soc_major_rev();
+ if (major == SOC_MAJOR_VER_1_0)
+ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_TERM_BARRIER);
dram_init();
@@ -548,10 +566,14 @@ struct smmu_stream_id dev_stream_id[] = {
int board_init(void)
{
struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
+ unsigned int major;
- /* Set CCI-400 control override register to
- * enable barrier transaction */
- out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
+ major = get_soc_major_rev();
+ if (major == SOC_MAJOR_VER_1_0) {
+ /* Set CCI-400 control override register to
+ * enable barrier transaction */
+ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
+ }
select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
@@ -580,10 +602,15 @@ int board_init(void)
void board_sleep_prepare(void)
{
struct ccsr_cci400 __iomem *cci = (void *)CONFIG_SYS_CCI400_ADDR;
+ unsigned int major;
+
+ major = get_soc_major_rev();
+ if (major == SOC_MAJOR_VER_1_0) {
+ /* Set CCI-400 control override register to
+ * enable barrier transaction */
+ out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
+ }
- /* Set CCI-400 control override register to
- * enable barrier transaction */
- out_le32(&cci->ctrl_ord, CCI400_CTRLORD_EN_BARRIER);
#ifdef CONFIG_LS102XA_NS_ACCESS
enable_devices_ns_access(ns_dev, ARRAY_SIZE(ns_dev));
@@ -595,8 +622,8 @@ int ft_board_setup(void *blob, bd_t *bd)
{
ft_cpu_setup(blob, bd);
-#ifdef CONFIG_PCIE_LAYERSCAPE
- ft_pcie_setup(blob, bd);
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
#endif
return 0;
diff --git a/board/freescale/ls1021atwr/ls1021atwr.c b/board/freescale/ls1021atwr/ls1021atwr.c
index fb8525f..ed5bd27 100644
--- a/board/freescale/ls1021atwr/ls1021atwr.c
+++ b/board/freescale/ls1021atwr/ls1021atwr.c
@@ -12,7 +12,7 @@
#include <asm/arch/clock.h>
#include <asm/arch/fsl_serdes.h>
#include <asm/arch/ls102xa_stream_id.h>
-#include <asm/pcie_layerscape.h>
+#include <hwconfig.h>
#include <mmc.h>
#include <fsl_esdhc.h>
#include <fsl_ifc.h>
@@ -54,6 +54,17 @@ DECLARE_GLOBAL_DATA_PTR;
#define KEEP_STATUS 0x0
#define NEED_RESET 0x1
+#define SOFT_MUX_ON_I2C3_IFC 0x2
+#define SOFT_MUX_ON_CAN3_USB2 0x8
+#define SOFT_MUX_ON_QE_LCD 0x10
+
+#define PIN_I2C3_IFC_MUX_I2C3 0x0
+#define PIN_I2C3_IFC_MUX_IFC 0x1
+#define PIN_CAN3_USB2_MUX_USB2 0x0
+#define PIN_CAN3_USB2_MUX_CAN3 0x1
+#define PIN_QE_LCD_MUX_LCD 0x0
+#define PIN_QE_LCD_MUX_QE 0x1
+
struct cpld_data {
u8 cpld_ver; /* cpld revision */
u8 cpld_ver_sub; /* cpld sub revision */
@@ -122,6 +133,17 @@ int checkboard(void)
return 0;
}
+unsigned int get_soc_major_rev(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ unsigned int svr, major;
+
+ svr = in_be32(&gur->svr);
+ major = SVR_MAJ(svr);
+
+ return major;
+}
+
void ddrmc_init(void)
{
struct ccsr_ddr *ddr = (struct ccsr_ddr *)CONFIG_SYS_FSL_DDR_ADDR;
@@ -260,10 +282,73 @@ int config_serdes_mux(void)
}
#endif
+#ifndef CONFIG_QSPI_BOOT
+int config_board_mux(void)
+{
+ struct cpld_data *cpld_data = (void *)(CONFIG_SYS_CPLD_BASE);
+ int conflict_flag;
+
+ conflict_flag = 0;
+ if (hwconfig("i2c3")) {
+ conflict_flag++;
+ cpld_data->soft_mux_on |= SOFT_MUX_ON_I2C3_IFC;
+ cpld_data->i2c3_ifc_mux = PIN_I2C3_IFC_MUX_I2C3;
+ }
+
+ if (hwconfig("ifc")) {
+ conflict_flag++;
+ /* some signals can not enable simultaneous*/
+ if (conflict_flag > 1)
+ goto conflict;
+ cpld_data->soft_mux_on |= SOFT_MUX_ON_I2C3_IFC;
+ cpld_data->i2c3_ifc_mux = PIN_I2C3_IFC_MUX_IFC;
+ }
+
+ conflict_flag = 0;
+ if (hwconfig("usb2")) {
+ conflict_flag++;
+ cpld_data->soft_mux_on |= SOFT_MUX_ON_CAN3_USB2;
+ cpld_data->can3_usb2_mux = PIN_CAN3_USB2_MUX_USB2;
+ }
+
+ if (hwconfig("can3")) {
+ conflict_flag++;
+ /* some signals can not enable simultaneous*/
+ if (conflict_flag > 1)
+ goto conflict;
+ cpld_data->soft_mux_on |= SOFT_MUX_ON_CAN3_USB2;
+ cpld_data->can3_usb2_mux = PIN_CAN3_USB2_MUX_CAN3;
+ }
+
+ conflict_flag = 0;
+ if (hwconfig("lcd")) {
+ conflict_flag++;
+ cpld_data->soft_mux_on |= SOFT_MUX_ON_QE_LCD;
+ cpld_data->qe_lcd_mux = PIN_QE_LCD_MUX_LCD;
+ }
+
+ if (hwconfig("qe")) {
+ conflict_flag++;
+ /* some signals can not enable simultaneous*/
+ if (conflict_flag > 1)
+ goto conflict;
+ cpld_data->soft_mux_on |= SOFT_MUX_ON_QE_LCD;
+ cpld_data->qe_lcd_mux = PIN_QE_LCD_MUX_QE;
+ }
+
+ return 0;
+
+conflict:
+ printf("WARNING: pin conflict! MUX setting may failed!\n");
+ return 0;
+}
+#endif
+
int board_early_init_f(void)
{
struct ccsr_scfg *scfg = (struct ccsr_scfg *)CONFIG_SYS_FSL_SCFG_ADDR;
struct ccsr_cci400 *cci = (struct ccsr_cci400 *)CONFIG_SYS_CCI400_ADDR;
+ unsigned int major;
#ifdef CONFIG_TSEC_ENET
out_be32(&scfg->etsecdmamcr, SCFG_ETSECDMAMCR_LE_BD_FR);
@@ -289,12 +374,15 @@ int board_early_init_f(void)
out_le32(&cci->slave[4].snoop_ctrl,
CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN);
- /*
- * Set CCI-400 Slave interface S1, S2 Shareable Override Register
- * All transactions are treated as non-shareable
- */
- out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
- out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
+ major = get_soc_major_rev();
+ if (major == SOC_MAJOR_VER_1_0) {
+ /*
+ * Set CCI-400 Slave interface S1, S2 Shareable Override
+ * Register All transactions are treated as non-shareable
+ */
+ out_le32(&cci->slave[1].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
+ out_le32(&cci->slave[2].sha_ord, CCI400_SHAORD_NON_SHAREABLE);
+ }
return 0;
}
@@ -465,6 +553,10 @@ int board_init(void)
#if defined(CONFIG_MISC_INIT_R)
int misc_init_r(void)
{
+#ifndef CONFIG_QSPI_BOOT
+ config_board_mux();
+#endif
+
#ifdef CONFIG_FSL_CAAM
return sec_init();
#endif
@@ -475,8 +567,8 @@ int ft_board_setup(void *blob, bd_t *bd)
{
ft_cpu_setup(blob, bd);
-#ifdef CONFIG_PCIE_LAYERSCAPE
- ft_pcie_setup(blob, bd);
+#ifdef CONFIG_PCI
+ ft_pci_setup(blob, bd);
#endif
return 0;
diff --git a/board/freescale/ls2085a/ls2085a.c b/board/freescale/ls2085a/ls2085a.c
index 519d61c..dd0acf2 100644
--- a/board/freescale/ls2085a/ls2085a.c
+++ b/board/freescale/ls2085a/ls2085a.c
@@ -12,8 +12,10 @@
#include <asm/io.h>
#include <fdt_support.h>
#include <libfdt.h>
+#include <fsl_debug_server.h>
#include <fsl-mc/fsl_mc.h>
#include <environment.h>
+#include <asm/arch-fsl-lsch3/soc.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -30,8 +32,7 @@ int board_init(void)
int board_early_init_f(void)
{
- init_early_memctl_regs(); /* tighten IFC timing */
-
+ fsl_lsch3_early_init_f();
return 0;
}
@@ -54,29 +55,32 @@ int dram_init(void)
return 0;
}
-int timer_init(void)
+#if defined(CONFIG_ARCH_MISC_INIT)
+int arch_misc_init(void)
{
- u32 __iomem *cntcr = (u32 *)CONFIG_SYS_FSL_TIMER_ADDR;
- u32 __iomem *cltbenr = (u32 *)CONFIG_SYS_FSL_PMU_CLTBENR;
-
- /* Enable timebase for all clusters.
- * It is safe to do so even some clusters are not enabled.
- */
- out_le32(cltbenr, 0xf);
-
- /* Enable clock for timer
- * This is a global setting.
- */
- out_le32(cntcr, 0x1);
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ debug_server_init();
+#endif
return 0;
}
+#endif
-/*
- * Board specific reset that is system reset.
- */
-void reset_cpu(ulong addr)
+unsigned long get_dram_size_to_hide(void)
{
+ unsigned long dram_to_hide = 0;
+
+/* Carve the Debug Server private DRAM block from the end of DRAM */
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ dram_to_hide += debug_server_get_dram_block_size();
+#endif
+
+/* Carve the MC private DRAM block from the end of DRAM */
+#ifdef CONFIG_FSL_MC_ENET
+ dram_to_hide += mc_get_dram_block_size();
+#endif
+
+ return dram_to_hide;
}
int board_eth_init(bd_t *bis)
@@ -135,6 +139,7 @@ int ft_board_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
+ fsl_mc_ldpaa_exit(bd);
#endif
return 0;
diff --git a/board/freescale/ls2085aqds/Kconfig b/board/freescale/ls2085aqds/Kconfig
new file mode 100644
index 0000000..deb640d
--- /dev/null
+++ b/board/freescale/ls2085aqds/Kconfig
@@ -0,0 +1,16 @@
+
+if TARGET_LS2085AQDS
+
+config SYS_BOARD
+ default "ls2085aqds"
+
+config SYS_VENDOR
+ default "freescale"
+
+config SYS_SOC
+ default "fsl-lsch3"
+
+config SYS_CONFIG_NAME
+ default "ls2085aqds"
+
+endif
diff --git a/board/freescale/ls2085aqds/MAINTAINERS b/board/freescale/ls2085aqds/MAINTAINERS
new file mode 100644
index 0000000..fbed672
--- /dev/null
+++ b/board/freescale/ls2085aqds/MAINTAINERS
@@ -0,0 +1,8 @@
+LS2085A BOARD
+M: Prabhakar Kushwaha <prabhakar@freescale.com>
+S: Maintained
+F: board/freescale/ls2085aqds/
+F: board/freescale/ls2085a/ls2085aqds.c
+F: include/configs/ls2085aqds.h
+F: configs/ls2085aqds_defconfig
+F: configs/ls2085aqds_nand_defconfig
diff --git a/board/freescale/ls2085aqds/Makefile b/board/freescale/ls2085aqds/Makefile
new file mode 100644
index 0000000..da69a7d
--- /dev/null
+++ b/board/freescale/ls2085aqds/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright 2015 Freescale Semiconductor
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += ls2085aqds.o
+obj-y += ddr.o
+obj-y += eth.o
diff --git a/board/freescale/ls2085aqds/README b/board/freescale/ls2085aqds/README
new file mode 100644
index 0000000..fb3938e
--- /dev/null
+++ b/board/freescale/ls2085aqds/README
@@ -0,0 +1,129 @@
+Overview
+--------
+The LS2085A Development System (QDS) is a high-performance computing,
+evaluation, and development platform that supports the QorIQ LS2085A
+Layerscape Architecture processor. The LS2085AQDS provides validation and
+SW development platform for the Freescale LS2085A processor series, with
+a complete debugging environment.
+
+LS2085A SoC Overview
+------------------
+The LS2085A integrated multicore processor combines eight ARM Cortex-A57
+processor cores with high-performance data path acceleration logic and network
+and peripheral bus interfaces required for networking, telecom/datacom,
+wireless infrastructure, and mil/aerospace applications.
+
+The LS2085A SoC includes the following function and features:
+
+ - Eight 64-bit ARM Cortex-A57 CPUs
+ - 1 MB platform cache with ECC
+ - Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support
+ - One secondary 32-bit DDR4 SDRAM memory controller, intended for use by
+ the AIOP
+ - Data path acceleration architecture (DPAA2) incorporating acceleration for
+ the following functions:
+ - Packet parsing, classification, and distribution (WRIOP)
+ - Queue and Hardware buffer management for scheduling, packet sequencing, and
+ congestion management, buffer allocation and de-allocation (QBMan)
+ - Cryptography acceleration (SEC) at up to 10 Gbps
+ - RegEx pattern matching acceleration (PME) at up to 10 Gbps
+ - Decompression/compression acceleration (DCE) at up to 20 Gbps
+ - Accelerated I/O processing (AIOP) at up to 20 Gbps
+ - QDMA engine
+ - 16 SerDes lanes at up to 10.3125 GHz
+ - Ethernet interfaces
+ - Up to eight 10 Gbps Ethernet MACs
+ - Up to eight 1 / 2.5 Gbps Ethernet MACs
+ - High-speed peripheral interfaces
+ - Four PCIe 3.0 controllers, one supporting SR-IOV
+ - Additional peripheral interfaces
+ - Two serial ATA (SATA 3.0) controllers
+ - Two high-speed USB 3.0 controllers with integrated PHY
+ - Enhanced secure digital host controller (eSDXC/eMMC)
+ - Serial peripheral interface (SPI) controller
+ - Quad Serial Peripheral Interface (QSPI) Controller
+ - Four I2C controllers
+ - Two DUARTs
+ - Integrated flash controller (IFC 2.0) supporting NAND and NOR flash
+ - Support for hardware virtualization and partitioning enforcement
+ - QorIQ platform's trust architecture 3.0
+ - Service processor (SP) provides pre-boot initialization and secure-boot
+ capabilities
+
+ LS2085AQDS board Overview
+ -----------------------
+ - SERDES Connections, 16 lanes supporting:
+ - PCI Express - 3.0
+ - SGMII, SGMII 2.5
+ - QSGMII
+ - SATA 3.0
+ - XAUI
+ - XFI
+ - DDR Controller
+ - Two ports of 72-bits (8-bits ECC) DDR4. Each port supports four
+ chip-selects and two DIMM connectors. Support is up to 2133MT/s.
+ - One port of 40-bits (8-bits ECC) DDR4 which supports four chip-selects
+ and two DIMM connectors. Support is up to 1600MT/s.
+ -IFC/Local Bus
+ - IFC rev. 2.0 implementation supporting Little Endian connection scheme.
+ - One in-socket 128 MB NOR flash 16-bit data bus
+ - One 512 MB NAND flash with ECC support
+ - IFC Test Port
+ - PromJet Port
+ - FPGA connection
+ - USB 3.0
+ - Two high speed USB 3.0 ports
+ - First USB 3.0 port configured as Host with Type-A connector
+ - Second USB 3.0 port configured as OTG with micro-AB connector
+ - SDHC: PCIe x1 Right Angle connector for supporting following cards
+ - 1/4-/8-bit SD/MMC Legacy CARD supporting 3.3V devices only
+ - 1-/4-/8-bit SD/MMC Card supporting 1.8V devices only
+ - 4-bit eMMC Card Rev 4.4 (1.8V only)
+ - 8-bit eMMC Card Rev 4.5 (1.8V only)
+ - SD Card Rev 2.0 and Rev 3.0
+ - DSPI: 3 high-speed flash Memory for storage
+ - 16 MB high-speed flash Memory for boot code and storage (up to 108MHz)
+ - 8 MB high-speed flash Memory (up to 104 MHz)
+ - 512 MB low-speed flash Memory (up to 40 MHz)
+ - QSPI: via NAND/QSPI Card
+ - 4 I2C controllers
+ - Two SATA onboard connectors
+ - UART
+ - Two 4-pin (HW control) or four 2-pin (SW control) serial ports at up to 115.2 Kbit/s
+ - Two DB9 D-Type connectors supporting one Serial port each
+ - ARM JTAG support
+
+Memory map from core's view
+----------------------------
+0x00_0000_0000 .. 0x00_000F_FFFF Boot Rom
+0x00_0100_0000 .. 0x00_0FFF_FFFF CCSR
+0x00_1800_0000 .. 0x00_181F_FFFF OCRAM
+0x00_3000_0000 .. 0x00_3FFF_FFFF IFC region #1
+0x00_8000_0000 .. 0x00_FFFF_FFFF DDR region #1
+0x05_1000_0000 .. 0x05_FFFF_FFFF IFC region #2
+0x80_8000_0000 .. 0xFF_FFFF_FFFF DDR region #2
+
+Other addresses are either reserved, or not used directly by u-boot.
+This list should be updated when more addresses are used.
+
+IFC region map from core's view
+-------------------------------
+During boot i.e. IFC Region #1:-
+ 0x30000000 - 0x37ffffff : 128MB : NOR flash
+ 0x38000000 - 0x3BFFFFFF : 64MB : Promjet
+ 0x3C000000 - 0x40000000 : 64MB : FPGA etc
+
+After relocate to DDR i.e. IFC Region #2:-
+ 0x5_1000_0000..0x5_1fff_ffff Memory Hole
+ 0x5_2000_0000..0x5_3fff_ffff IFC CSx (FPGA, NAND and others 512MB)
+ 0x5_4000_0000..0x5_7fff_ffff ASIC or others 1GB
+ 0x5_8000_0000..0x5_bfff_ffff IFC CS0 1GB (NOR/Promjet)
+ 0x5_C000_0000..0x5_ffff_ffff IFC CS1 1GB (NOR/Promjet)
+
+Booting Options
+---------------
+a) Promjet Boot
+b) NOR boot
+c) NAND boot
+d) SD boot
+e) QSPI boot
diff --git a/board/freescale/ls2085aqds/ddr.c b/board/freescale/ls2085aqds/ddr.c
new file mode 100644
index 0000000..8d71ae1
--- /dev/null
+++ b/board/freescale/ls2085aqds/ddr.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fsl_ddr_sdram.h>
+#include <fsl_ddr_dimm_params.h>
+#include "ddr.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void fsl_ddr_board_options(memctl_options_t *popts,
+ dimm_params_t *pdimm,
+ unsigned int ctrl_num)
+{
+ u8 dq_mapping_0, dq_mapping_2, dq_mapping_3;
+ const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
+ ulong ddr_freq;
+ int slot;
+
+ if (ctrl_num > 2) {
+ printf("Not supported controller number %d\n", ctrl_num);
+ return;
+ }
+
+ for (slot = 0; slot < CONFIG_DIMM_SLOTS_PER_CTLR; slot++) {
+ if (pdimm[slot].n_ranks)
+ break;
+ }
+
+ if (slot >= CONFIG_DIMM_SLOTS_PER_CTLR)
+ return;
+
+ /*
+ * we use identical timing for all slots. If needed, change the code
+ * to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
+ */
+ if (popts->registered_dimm_en)
+ pbsp = rdimms[ctrl_num];
+ else
+ pbsp = udimms[ctrl_num];
+
+
+ /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr
+ * freqency and n_banks specified in board_specific_parameters table.
+ */
+ ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
+ while (pbsp->datarate_mhz_high) {
+ if (pbsp->n_ranks == pdimm[slot].n_ranks &&
+ (pdimm[slot].rank_density >> 30) >= pbsp->rank_gb) {
+ if (ddr_freq <= pbsp->datarate_mhz_high) {
+ popts->clk_adjust = pbsp->clk_adjust;
+ popts->wrlvl_start = pbsp->wrlvl_start;
+ popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
+ popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
+ goto found;
+ }
+ pbsp_highest = pbsp;
+ }
+ pbsp++;
+ }
+
+ if (pbsp_highest) {
+ printf("Error: board specific timing not found for data rate %lu MT/s\n"
+ "Trying to use the highest speed (%u) parameters\n",
+ ddr_freq, pbsp_highest->datarate_mhz_high);
+ popts->clk_adjust = pbsp_highest->clk_adjust;
+ popts->wrlvl_start = pbsp_highest->wrlvl_start;
+ popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
+ popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
+ } else {
+ panic("DIMM is not supported by this board");
+ }
+found:
+ debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
+ "\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, wrlvl_ctrl_3 0x%x\n",
+ pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
+ pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
+ pbsp->wrlvl_ctl_3);
+
+ if (ctrl_num == CONFIG_DP_DDR_CTRL) {
+ /* force DDR bus width to 32 bits */
+ popts->data_bus_width = 1;
+ popts->otf_burst_chop_en = 0;
+ popts->burst_length = DDR_BL8;
+ popts->bstopre = 0; /* enable auto precharge */
+ /*
+ * Layout optimization results byte mapping
+ * Byte 0 -> Byte ECC
+ * Byte 1 -> Byte 3
+ * Byte 2 -> Byte 2
+ * Byte 3 -> Byte 1
+ * Byte ECC -> Byte 0
+ */
+ dq_mapping_0 = pdimm[slot].dq_mapping[0];
+ dq_mapping_2 = pdimm[slot].dq_mapping[2];
+ dq_mapping_3 = pdimm[slot].dq_mapping[3];
+ pdimm[slot].dq_mapping[0] = pdimm[slot].dq_mapping[8];
+ pdimm[slot].dq_mapping[1] = pdimm[slot].dq_mapping[9];
+ pdimm[slot].dq_mapping[2] = pdimm[slot].dq_mapping[6];
+ pdimm[slot].dq_mapping[3] = pdimm[slot].dq_mapping[7];
+ pdimm[slot].dq_mapping[6] = dq_mapping_2;
+ pdimm[slot].dq_mapping[7] = dq_mapping_3;
+ pdimm[slot].dq_mapping[8] = dq_mapping_0;
+ pdimm[slot].dq_mapping[9] = 0;
+ pdimm[slot].dq_mapping[10] = 0;
+ pdimm[slot].dq_mapping[11] = 0;
+ pdimm[slot].dq_mapping[12] = 0;
+ pdimm[slot].dq_mapping[13] = 0;
+ pdimm[slot].dq_mapping[14] = 0;
+ pdimm[slot].dq_mapping[15] = 0;
+ pdimm[slot].dq_mapping[16] = 0;
+ pdimm[slot].dq_mapping[17] = 0;
+ }
+ /* To work at higher than 1333MT/s */
+ popts->half_strength_driver_enable = 0;
+ /*
+ * Write leveling override
+ */
+ popts->wrlvl_override = 1;
+ popts->wrlvl_sample = 0x0; /* 32 clocks */
+
+ /*
+ * Rtt and Rtt_WR override
+ */
+ popts->rtt_override = 0;
+
+ /* Enable ZQ calibration */
+ popts->zq_en = 1;
+
+ if (ddr_freq < 2350) {
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+ DDR_CDR2_VREF_RANGE_2;
+ } else {
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_100ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_100ohm) |
+ DDR_CDR2_VREF_RANGE_2;
+ }
+}
+
+phys_size_t initdram(int board_type)
+{
+ phys_size_t dram_size;
+
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+ return fsl_ddr_sdram_size();
+#else
+ puts("Initializing DDR....using SPD\n");
+
+ dram_size = fsl_ddr_sdram();
+#endif
+
+ return dram_size;
+}
+
+void dram_init_banksize(void)
+{
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+ phys_size_t dp_ddr_size;
+#endif
+
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
+ gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
+ gd->bd->bi_dram[1].size = gd->ram_size -
+ CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ } else {
+ gd->bd->bi_dram[0].size = gd->ram_size;
+ }
+
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+ /* initialize DP-DDR here */
+ puts("DP-DDR: ");
+ /*
+ * DDR controller use 0 as the base address for binding.
+ * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
+ */
+ dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
+ CONFIG_DP_DDR_CTRL,
+ CONFIG_DP_DDR_NUM_CTRLS,
+ CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
+ NULL, NULL, NULL);
+ if (dp_ddr_size) {
+ gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
+ gd->bd->bi_dram[2].size = dp_ddr_size;
+ } else {
+ puts("Not detected");
+ }
+#endif
+}
diff --git a/board/freescale/ls2085aqds/ddr.h b/board/freescale/ls2085aqds/ddr.h
new file mode 100644
index 0000000..b76ea61
--- /dev/null
+++ b/board/freescale/ls2085aqds/ddr.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DDR_H__
+#define __DDR_H__
+struct board_specific_parameters {
+ u32 n_ranks;
+ u32 datarate_mhz_high;
+ u32 rank_gb;
+ u32 clk_adjust;
+ u32 wrlvl_start;
+ u32 wrlvl_ctl_2;
+ u32 wrlvl_ctl_3;
+};
+
+/*
+ * These tables contain all valid speeds we want to override with board
+ * specific parameters. datarate_mhz_high values need to be in ascending order
+ * for each n_ranks group.
+ */
+
+static const struct board_specific_parameters udimm0[] = {
+ /*
+ * memory controller 0
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+ {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,},
+ {2, 1666, 0, 4, 7, 0x08090A0C, 0x0D0F100B,},
+ {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,},
+ {2, 2300, 0, 4, 8, 0x090A0C0F, 0x1012130C,},
+ {}
+};
+
+/* DP-DDR DIMM */
+static const struct board_specific_parameters udimm2[] = {
+ /*
+ * memory controller 2
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+ {2, 1350, 0, 4, 0xd, 0x0C0A0A00, 0x00000009,},
+ {2, 1666, 0, 4, 0xd, 0x0C0A0A00, 0x00000009,},
+ {2, 1900, 0, 4, 0xe, 0x0D0C0B00, 0x0000000A,},
+ {2, 2200, 0, 4, 0xe, 0x0D0C0B00, 0x0000000A,},
+ {}
+};
+
+static const struct board_specific_parameters rdimm0[] = {
+ /*
+ * memory controller 0
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+ {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,},
+ {2, 1666, 0, 4, 7, 0x08090A0C, 0x0D0F100B,},
+ {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,},
+ {2, 2200, 0, 4, 8, 0x090A0C0F, 0x1012130C,},
+ {}
+};
+
+/* DP-DDR DIMM */
+static const struct board_specific_parameters rdimm2[] = {
+ /*
+ * memory controller 2
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+ {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,},
+ {2, 1666, 0, 4, 7, 0x0B0A090C, 0x0D0F100B,},
+ {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,},
+ {2, 2200, 0, 4, 8, 0x090A0C0F, 0x1012130C,},
+ {}
+};
+
+static const struct board_specific_parameters *udimms[] = {
+ udimm0,
+ udimm0,
+ udimm2,
+};
+
+static const struct board_specific_parameters *rdimms[] = {
+ rdimm0,
+ rdimm0,
+ rdimm2,
+};
+
+
+#endif
diff --git a/board/freescale/ls2085aqds/eth.c b/board/freescale/ls2085aqds/eth.c
new file mode 100644
index 0000000..5ba4770
--- /dev/null
+++ b/board/freescale/ls2085aqds/eth.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <netdev.h>
+#include <asm/io.h>
+#include <asm/arch/fsl_serdes.h>
+#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+#include <fsl_mdio.h>
+#include <malloc.h>
+#include <fm_eth.h>
+#include <fsl-mc/ldpaa_wriop.h>
+
+#include "../common/qixis.h"
+
+#include "ls2085aqds_qixis.h"
+
+
+#ifdef CONFIG_FSL_MC_ENET
+ /* - In LS2085A there are only 16 SERDES lanes, spread across 2 SERDES banks.
+ * Bank 1 -> Lanes A, B, C, D, E, F, G, H
+ * Bank 2 -> Lanes A,B, C, D, E, F, G, H
+ */
+
+ /* Mapping of 16 SERDES lanes to LS2085A QDS board slots. A value of '0' here
+ * means that the mapping must be determined dynamically, or that the lane
+ * maps to something other than a board slot.
+ */
+
+static u8 lane_to_slot_fsm2[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* On the Vitesse VSC8234XHG SGMII riser card there are 4 SGMII PHYs
+ * housed.
+ */
+static int riser_phy_addr[] = {
+ SGMII_CARD_PORT1_PHY_ADDR,
+ SGMII_CARD_PORT2_PHY_ADDR,
+ SGMII_CARD_PORT3_PHY_ADDR,
+ SGMII_CARD_PORT4_PHY_ADDR,
+};
+
+/* Slot2 does not have EMI connections */
+#define EMI_NONE 0xFFFFFFFF
+#define EMI1_SLOT1 0
+#define EMI1_SLOT2 1
+#define EMI1_SLOT3 2
+#define EMI1_SLOT4 3
+#define EMI1_SLOT5 4
+#define EMI1_SLOT6 5
+#define EMI2 6
+#define SFP_TX 1
+
+static const char * const mdio_names[] = {
+ "LS2085A_QDS_MDIO0",
+ "LS2085A_QDS_MDIO1",
+ "LS2085A_QDS_MDIO2",
+ "LS2085A_QDS_MDIO3",
+ "LS2085A_QDS_MDIO4",
+ "LS2085A_QDS_MDIO5",
+ DEFAULT_WRIOP_MDIO2_NAME,
+};
+
+struct ls2085a_qds_mdio {
+ u8 muxval;
+ struct mii_dev *realbus;
+};
+
+static const char *ls2085a_qds_mdio_name_for_muxval(u8 muxval)
+{
+ return mdio_names[muxval];
+}
+
+struct mii_dev *mii_dev_for_muxval(u8 muxval)
+{
+ struct mii_dev *bus;
+ const char *name = ls2085a_qds_mdio_name_for_muxval(muxval);
+
+ if (!name) {
+ printf("No bus for muxval %x\n", muxval);
+ return NULL;
+ }
+
+ bus = miiphy_get_dev_by_name(name);
+
+ if (!bus) {
+ printf("No bus by name %s\n", name);
+ return NULL;
+ }
+
+ return bus;
+}
+
+static void ls2085a_qds_enable_SFP_TX(u8 muxval)
+{
+ u8 brdcfg9;
+
+ brdcfg9 = QIXIS_READ(brdcfg[9]);
+ brdcfg9 &= ~BRDCFG9_SFPTX_MASK;
+ brdcfg9 |= (muxval << BRDCFG9_SFPTX_SHIFT);
+ QIXIS_WRITE(brdcfg[9], brdcfg9);
+}
+
+static void ls2085a_qds_mux_mdio(u8 muxval)
+{
+ u8 brdcfg4;
+
+ if (muxval <= 5) {
+ brdcfg4 = QIXIS_READ(brdcfg[4]);
+ brdcfg4 &= ~BRDCFG4_EMISEL_MASK;
+ brdcfg4 |= (muxval << BRDCFG4_EMISEL_SHIFT);
+ QIXIS_WRITE(brdcfg[4], brdcfg4);
+ }
+}
+
+static int ls2085a_qds_mdio_read(struct mii_dev *bus, int addr,
+ int devad, int regnum)
+{
+ struct ls2085a_qds_mdio *priv = bus->priv;
+
+ ls2085a_qds_mux_mdio(priv->muxval);
+
+ return priv->realbus->read(priv->realbus, addr, devad, regnum);
+}
+
+static int ls2085a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
+ int regnum, u16 value)
+{
+ struct ls2085a_qds_mdio *priv = bus->priv;
+
+ ls2085a_qds_mux_mdio(priv->muxval);
+
+ return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
+}
+
+static int ls2085a_qds_mdio_reset(struct mii_dev *bus)
+{
+ struct ls2085a_qds_mdio *priv = bus->priv;
+
+ return priv->realbus->reset(priv->realbus);
+}
+
+static int ls2085a_qds_mdio_init(char *realbusname, u8 muxval)
+{
+ struct ls2085a_qds_mdio *pmdio;
+ struct mii_dev *bus = mdio_alloc();
+
+ if (!bus) {
+ printf("Failed to allocate ls2085a_qds MDIO bus\n");
+ return -1;
+ }
+
+ pmdio = malloc(sizeof(*pmdio));
+ if (!pmdio) {
+ printf("Failed to allocate ls2085a_qds private data\n");
+ free(bus);
+ return -1;
+ }
+
+ bus->read = ls2085a_qds_mdio_read;
+ bus->write = ls2085a_qds_mdio_write;
+ bus->reset = ls2085a_qds_mdio_reset;
+ sprintf(bus->name, ls2085a_qds_mdio_name_for_muxval(muxval));
+
+ pmdio->realbus = miiphy_get_dev_by_name(realbusname);
+
+ if (!pmdio->realbus) {
+ printf("No bus with name %s\n", realbusname);
+ free(bus);
+ free(pmdio);
+ return -1;
+ }
+
+ pmdio->muxval = muxval;
+ bus->priv = pmdio;
+
+ return mdio_register(bus);
+}
+
+/*
+ * Initialize the dpmac_info array.
+ *
+ */
+static void initialize_dpmac_to_slot(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
+ FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
+ >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
+ int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
+ FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
+ >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
+
+
+ switch (serdes1_prtcl) {
+ case 0x2A:
+ printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n",
+ serdes1_prtcl);
+ break;
+ default:
+ printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
+ serdes1_prtcl);
+ break;
+ }
+
+ switch (serdes2_prtcl) {
+ case 0x07:
+ case 0x08:
+ printf("qds: WRIOP: Supported SerDes Protocol 0x%02x\n",
+ serdes2_prtcl);
+ lane_to_slot_fsm2[0] = EMI1_SLOT4;
+ lane_to_slot_fsm2[1] = EMI1_SLOT4;
+ lane_to_slot_fsm2[2] = EMI1_SLOT4;
+ lane_to_slot_fsm2[3] = EMI1_SLOT4;
+ /* No MDIO physical connection */
+ lane_to_slot_fsm2[4] = EMI1_SLOT6;
+ lane_to_slot_fsm2[5] = EMI1_SLOT6;
+ lane_to_slot_fsm2[6] = EMI1_SLOT6;
+ lane_to_slot_fsm2[7] = EMI1_SLOT6;
+ break;
+ default:
+ printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
+ serdes2_prtcl);
+ break;
+ }
+}
+
+void ls2085a_handle_phy_interface_sgmii(int dpmac_id)
+{
+ int lane, slot;
+ struct mii_dev *bus;
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
+ FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
+ >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
+ int serdes2_prtcl = (in_le32(&gur->rcwsr[28]) &
+ FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK)
+ >> FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
+
+ switch (serdes1_prtcl) {
+ }
+
+ switch (serdes2_prtcl) {
+ case 0x07:
+ case 0x08:
+ lane = serdes_get_first_lane(FSL_SRDS_2, SGMII9 +
+ (dpmac_id - 9));
+ slot = lane_to_slot_fsm2[lane];
+
+ switch (++slot) {
+ case 1:
+ break;
+ case 3:
+ break;
+ case 4:
+ /* Slot housing a SGMII riser card? */
+ wriop_set_phy_address(dpmac_id,
+ riser_phy_addr[dpmac_id - 9]);
+ dpmac_info[dpmac_id].board_mux = EMI1_SLOT4;
+ bus = mii_dev_for_muxval(EMI1_SLOT4);
+ wriop_set_mdio(dpmac_id, bus);
+ dpmac_info[dpmac_id].phydev = phy_connect(
+ dpmac_info[dpmac_id].bus,
+ dpmac_info[dpmac_id].phy_addr,
+ NULL,
+ dpmac_info[dpmac_id].enet_if);
+ phy_config(dpmac_info[dpmac_id].phydev);
+ break;
+ case 5:
+ break;
+ case 6:
+ /* Slot housing a SGMII riser card? */
+ wriop_set_phy_address(dpmac_id,
+ riser_phy_addr[dpmac_id - 13]);
+ dpmac_info[dpmac_id].board_mux = EMI1_SLOT6;
+ bus = mii_dev_for_muxval(EMI1_SLOT6);
+ wriop_set_mdio(dpmac_id, bus);
+ break;
+ }
+ break;
+ default:
+ printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
+ serdes2_prtcl);
+ break;
+ }
+}
+void ls2085a_handle_phy_interface_xsgmii(int i)
+{
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ int serdes1_prtcl = (in_le32(&gur->rcwsr[28]) &
+ FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK)
+ >> FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
+
+ switch (serdes1_prtcl) {
+ case 0x2A:
+ /*
+ * XFI does not need a PHY to work, but to avoid U-boot use
+ * default PHY address which is zero to a MAC when it found
+ * a MAC has no PHY address, we give a PHY address to XFI
+ * MAC, and should not use a real XAUI PHY address, since
+ * MDIO can access it successfully, and then MDIO thinks
+ * the XAUI card is used for the XFI MAC, which will cause
+ * error.
+ */
+ wriop_set_phy_address(i, i + 4);
+ ls2085a_qds_enable_SFP_TX(SFP_TX);
+
+ break;
+ default:
+ printf("qds: WRIOP: Unsupported SerDes Protocol 0x%02x\n",
+ serdes1_prtcl);
+ break;
+ }
+}
+#endif
+
+int board_eth_init(bd_t *bis)
+{
+ int error;
+#ifdef CONFIG_FSL_MC_ENET
+ struct memac_mdio_info *memac_mdio0_info;
+ struct memac_mdio_info *memac_mdio1_info;
+ unsigned int i;
+
+ initialize_dpmac_to_slot();
+
+ memac_mdio0_info = (struct memac_mdio_info *)malloc(
+ sizeof(struct memac_mdio_info));
+ memac_mdio0_info->regs =
+ (struct memac_mdio_controller *)
+ CONFIG_SYS_FSL_WRIOP1_MDIO1;
+ memac_mdio0_info->name = DEFAULT_WRIOP_MDIO1_NAME;
+
+ /* Register the real MDIO1 bus */
+ fm_memac_mdio_init(bis, memac_mdio0_info);
+
+ memac_mdio1_info = (struct memac_mdio_info *)malloc(
+ sizeof(struct memac_mdio_info));
+ memac_mdio1_info->regs =
+ (struct memac_mdio_controller *)
+ CONFIG_SYS_FSL_WRIOP1_MDIO2;
+ memac_mdio1_info->name = DEFAULT_WRIOP_MDIO2_NAME;
+
+ /* Register the real MDIO2 bus */
+ fm_memac_mdio_init(bis, memac_mdio1_info);
+
+ /* Register the muxing front-ends to the MDIO buses */
+ ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT1);
+ ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT2);
+ ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT3);
+ ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT4);
+ ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT5);
+ ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO1_NAME, EMI1_SLOT6);
+
+ ls2085a_qds_mdio_init(DEFAULT_WRIOP_MDIO2_NAME, EMI2);
+
+ for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
+ switch (wriop_get_enet_if(i)) {
+ case PHY_INTERFACE_MODE_QSGMII:
+ break;
+ case PHY_INTERFACE_MODE_SGMII:
+ ls2085a_handle_phy_interface_sgmii(i);
+ break;
+ case PHY_INTERFACE_MODE_XGMII:
+ ls2085a_handle_phy_interface_xsgmii(i);
+ break;
+ default:
+ break;
+ }
+ }
+
+ error = cpu_eth_init(bis);
+#endif
+ error = pci_eth_init(bis);
+ return error;
+}
diff --git a/board/freescale/ls2085aqds/ls2085aqds.c b/board/freescale/ls2085aqds/ls2085aqds.c
new file mode 100644
index 0000000..6a22122
--- /dev/null
+++ b/board/freescale/ls2085aqds/ls2085aqds.c
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <netdev.h>
+#include <fsl_ifc.h>
+#include <fsl_ddr.h>
+#include <asm/io.h>
+#include <fdt_support.h>
+#include <libfdt.h>
+#include <fsl_debug_server.h>
+#include <fsl-mc/fsl_mc.h>
+#include <environment.h>
+#include <i2c.h>
+#include <asm/arch-fsl-lsch3/soc.h>
+
+#include "../common/qixis.h"
+#include "ls2085aqds_qixis.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+unsigned long long get_qixis_addr(void)
+{
+ unsigned long long addr;
+
+ if (gd->flags & GD_FLG_RELOC)
+ addr = QIXIS_BASE_PHYS;
+ else
+ addr = QIXIS_BASE_PHYS_EARLY;
+
+ /*
+ * IFC address under 256MB is mapped to 0x30000000, any address above
+ * is mapped to 0x5_10000000 up to 4GB.
+ */
+ addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000;
+
+ return addr;
+}
+
+int checkboard(void)
+{
+ char buf[64];
+ u8 sw;
+ static const char *const freq[] = {"100", "125", "156.25",
+ "100 separate SSCG"};
+ int clock;
+
+ 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);
+
+ sw = QIXIS_READ(brdcfg[0]);
+ sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
+
+ if (sw < 0x8)
+ printf("vBank: %d\n", sw);
+ else if (sw == 0x8)
+ puts("PromJet\n");
+ else if (sw == 0x9)
+ puts("NAND\n");
+ else if (sw == 0x15)
+ printf("IFCCard\n");
+ else
+ printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
+
+ printf("FPGA: v%d (%s), build %d",
+ (int)QIXIS_READ(scver), qixis_read_tag(buf),
+ (int)qixis_read_minor());
+ /* the timestamp string contains "\n" at the end */
+ printf(" on %s", qixis_read_time(buf));
+
+ /*
+ * Display the actual SERDES reference clocks as configured by the
+ * dip switches on the board. Note that the SWx registers could
+ * technically be set to force the reference clocks to match the
+ * values that the SERDES expects (or vice versa). For now, however,
+ * we just display both values and hope the user notices when they
+ * don't match.
+ */
+ puts("SERDES1 Reference : ");
+ sw = QIXIS_READ(brdcfg[2]);
+ clock = (sw >> 6) & 3;
+ printf("Clock1 = %sMHz ", freq[clock]);
+ clock = (sw >> 4) & 3;
+ printf("Clock2 = %sMHz", freq[clock]);
+
+ puts("\nSERDES2 Reference : ");
+ clock = (sw >> 2) & 3;
+ printf("Clock1 = %sMHz ", freq[clock]);
+ clock = (sw >> 0) & 3;
+ printf("Clock2 = %sMHz\n", freq[clock]);
+
+ return 0;
+}
+
+unsigned long get_board_sys_clk(void)
+{
+ u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
+
+ switch (sysclk_conf & 0x0F) {
+ case QIXIS_SYSCLK_83:
+ return 83333333;
+ case QIXIS_SYSCLK_100:
+ return 100000000;
+ case QIXIS_SYSCLK_125:
+ return 125000000;
+ case QIXIS_SYSCLK_133:
+ return 133333333;
+ case QIXIS_SYSCLK_150:
+ return 150000000;
+ case QIXIS_SYSCLK_160:
+ return 160000000;
+ case QIXIS_SYSCLK_166:
+ return 166666666;
+ }
+ return 66666666;
+}
+
+unsigned long get_board_ddr_clk(void)
+{
+ u8 ddrclk_conf = QIXIS_READ(brdcfg[1]);
+
+ switch ((ddrclk_conf & 0x30) >> 4) {
+ case QIXIS_DDRCLK_100:
+ return 100000000;
+ case QIXIS_DDRCLK_125:
+ return 125000000;
+ case QIXIS_DDRCLK_133:
+ return 133333333;
+ }
+ return 66666666;
+}
+
+int select_i2c_ch_pca9547(u8 ch)
+{
+ int ret;
+
+ ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
+ if (ret) {
+ puts("PCA: failed to select proper channel\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int board_init(void)
+{
+ init_final_memctl_regs();
+
+#ifdef CONFIG_ENV_IS_NOWHERE
+ gd->env_addr = (ulong)&default_environment[0];
+#endif
+ select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
+
+ return 0;
+}
+
+int board_early_init_f(void)
+{
+ fsl_lsch3_early_init_f();
+ return 0;
+}
+
+void detail_board_ddr_info(void)
+{
+ puts("\nDDR ");
+ print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
+ print_ddr_info(0);
+ if (gd->bd->bi_dram[2].size) {
+ puts("\nDP-DDR ");
+ print_size(gd->bd->bi_dram[2].size, "");
+ print_ddr_info(CONFIG_DP_DDR_CTRL);
+ }
+}
+
+int dram_init(void)
+{
+ gd->ram_size = initdram(0);
+
+ return 0;
+}
+
+#if defined(CONFIG_ARCH_MISC_INIT)
+int arch_misc_init(void)
+{
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ debug_server_init();
+#endif
+
+ return 0;
+}
+#endif
+
+unsigned long get_dram_size_to_hide(void)
+{
+ unsigned long dram_to_hide = 0;
+
+/* Carve the Debug Server private DRAM block from the end of DRAM */
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ dram_to_hide += debug_server_get_dram_block_size();
+#endif
+
+/* Carve the MC private DRAM block from the end of DRAM */
+#ifdef CONFIG_FSL_MC_ENET
+ dram_to_hide += mc_get_dram_block_size();
+#endif
+
+ return dram_to_hide;
+}
+
+#ifdef CONFIG_FSL_MC_ENET
+void fdt_fixup_board_enet(void *fdt)
+{
+ int offset;
+
+ offset = fdt_path_offset(fdt, "/fsl-mc");
+
+ if (offset < 0)
+ offset = fdt_path_offset(fdt, "/fsl,dprc@0");
+
+ if (offset < 0) {
+ printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
+ __func__, offset);
+ return;
+ }
+
+ if (get_mc_boot_status() == 0)
+ fdt_status_okay(fdt, offset);
+ else
+ fdt_status_fail(fdt, offset);
+}
+#endif
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ phys_addr_t base;
+ phys_size_t size;
+
+ 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);
+
+#ifdef CONFIG_FSL_MC_ENET
+ fdt_fixup_board_enet(blob);
+ fsl_mc_ldpaa_exit(bd);
+#endif
+
+ return 0;
+}
+#endif
+
+void qixis_dump_switch(void)
+{
+ int i, nr_of_cfgsw;
+
+ QIXIS_WRITE(cms[0], 0x00);
+ nr_of_cfgsw = QIXIS_READ(cms[1]);
+
+ puts("DIP switch settings dump:\n");
+ for (i = 1; i <= nr_of_cfgsw; i++) {
+ QIXIS_WRITE(cms[0], i);
+ printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1]));
+ }
+}
diff --git a/board/freescale/ls2085aqds/ls2085aqds_qixis.h b/board/freescale/ls2085aqds/ls2085aqds_qixis.h
new file mode 100644
index 0000000..e281e5f
--- /dev/null
+++ b/board/freescale/ls2085aqds/ls2085aqds_qixis.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LS2_QDS_QIXIS_H__
+#define __LS2_QDS_QIXIS_H__
+
+/* SYSCLK */
+#define QIXIS_SYSCLK_66 0x0
+#define QIXIS_SYSCLK_83 0x1
+#define QIXIS_SYSCLK_100 0x2
+#define QIXIS_SYSCLK_125 0x3
+#define QIXIS_SYSCLK_133 0x4
+#define QIXIS_SYSCLK_150 0x5
+#define QIXIS_SYSCLK_160 0x6
+#define QIXIS_SYSCLK_166 0x7
+
+/* DDRCLK */
+#define QIXIS_DDRCLK_66 0x0
+#define QIXIS_DDRCLK_100 0x1
+#define QIXIS_DDRCLK_125 0x2
+#define QIXIS_DDRCLK_133 0x3
+
+#define BRDCFG4_EMISEL_MASK 0xE0
+#define BRDCFG4_EMISEL_SHIFT 5
+#define BRDCFG9_SFPTX_MASK 0x10
+#define BRDCFG9_SFPTX_SHIFT 4
+#endif /*__LS2_QDS_QIXIS_H__*/
diff --git a/board/freescale/ls2085ardb/Kconfig b/board/freescale/ls2085ardb/Kconfig
new file mode 100644
index 0000000..85a3dcd
--- /dev/null
+++ b/board/freescale/ls2085ardb/Kconfig
@@ -0,0 +1,16 @@
+
+if TARGET_LS2085ARDB
+
+config SYS_BOARD
+ default "ls2085ardb"
+
+config SYS_VENDOR
+ default "freescale"
+
+config SYS_SOC
+ default "fsl-lsch3"
+
+config SYS_CONFIG_NAME
+ default "ls2085ardb"
+
+endif
diff --git a/board/freescale/ls2085ardb/MAINTAINERS b/board/freescale/ls2085ardb/MAINTAINERS
new file mode 100644
index 0000000..d5cce40
--- /dev/null
+++ b/board/freescale/ls2085ardb/MAINTAINERS
@@ -0,0 +1,8 @@
+LS2085A BOARD
+M: Prabhakar Kushwaha <prabhakar@freescale.com>
+S: Maintained
+F: board/freescale/ls2085ardb/
+F: board/freescale/ls2085a/ls2085ardb.c
+F: include/configs/ls2085ardb.h
+F: configs/ls2085ardb_defconfig
+F: configs/ls2085ardb_nand_defconfig
diff --git a/board/freescale/ls2085ardb/Makefile b/board/freescale/ls2085ardb/Makefile
new file mode 100644
index 0000000..0bfe21c
--- /dev/null
+++ b/board/freescale/ls2085ardb/Makefile
@@ -0,0 +1,8 @@
+#
+# Copyright 2015 Freescale Semiconductor
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += ls2085ardb.o
+obj-y += ddr.o
diff --git a/board/freescale/ls2085ardb/README b/board/freescale/ls2085ardb/README
new file mode 100644
index 0000000..cfd5185
--- /dev/null
+++ b/board/freescale/ls2085ardb/README
@@ -0,0 +1,109 @@
+Overview
+--------
+The LS2085A Reference Design (RDB) is a high-performance computing,
+evaluation, and development platform that supports the QorIQ LS2085A
+Layerscape Architecture processor.
+
+LS2085A SoC Overview
+------------------
+The LS2085A integrated multicore processor combines eight ARM Cortex-A57
+processor cores with high-performance data path acceleration logic and network
+and peripheral bus interfaces required for networking, telecom/datacom,
+wireless infrastructure, and mil/aerospace applications.
+
+The LS2085A SoC includes the following function and features:
+
+ - Eight 64-bit ARM Cortex-A57 CPUs
+ - 1 MB platform cache with ECC
+ - Two 64-bit DDR4 SDRAM memory controllers with ECC and interleaving support
+ - One secondary 32-bit DDR4 SDRAM memory controller, intended for use by
+ the AIOP
+ - Data path acceleration architecture (DPAA2) incorporating acceleration for
+ the following functions:
+ - Packet parsing, classification, and distribution (WRIOP)
+ - Queue and Hardware buffer management for scheduling, packet sequencing, and
+ congestion management, buffer allocation and de-allocation (QBMan)
+ - Cryptography acceleration (SEC) at up to 10 Gbps
+ - RegEx pattern matching acceleration (PME) at up to 10 Gbps
+ - Decompression/compression acceleration (DCE) at up to 20 Gbps
+ - Accelerated I/O processing (AIOP) at up to 20 Gbps
+ - QDMA engine
+ - 16 SerDes lanes at up to 10.3125 GHz
+ - Ethernet interfaces
+ - Up to eight 10 Gbps Ethernet MACs
+ - Up to eight 1 / 2.5 Gbps Ethernet MACs
+ - High-speed peripheral interfaces
+ - Four PCIe 3.0 controllers, one supporting SR-IOV
+ - Additional peripheral interfaces
+ - Two serial ATA (SATA 3.0) controllers
+ - Two high-speed USB 3.0 controllers with integrated PHY
+ - Enhanced secure digital host controller (eSDXC/eMMC)
+ - Serial peripheral interface (SPI) controller
+ - Quad Serial Peripheral Interface (QSPI) Controller
+ - Four I2C controllers
+ - Two DUARTs
+ - Integrated flash controller (IFC 2.0) supporting NAND and NOR flash
+ - Support for hardware virtualization and partitioning enforcement
+ - QorIQ platform's trust architecture 3.0
+ - Service processor (SP) provides pre-boot initialization and secure-boot
+ capabilities
+
+ LS2085ARDB board Overview
+ -----------------------
+ - SERDES Connections, 16 lanes supporting:
+ - PCI Express - 3.0
+ - SATA 3.0
+ - XFI
+ - DDR Controller
+ - Two ports of 72-bits (8-bits ECC) DDR4. Each port supports four
+ chip-selects and two DIMM connectors. Support is up to 2133MT/s.
+ - One port of 40-bits (8-bits ECC) DDR4 which supports four chip-selects
+ and two DIMM connectors. Support is up to 1600MT/s.
+ -IFC/Local Bus
+ - IFC rev. 2.0 implementation supporting Little Endian connection scheme.
+ - 128 MB NOR flash 16-bit data bus
+ - One 2 GB NAND flash with ECC support
+ - CPLD connection
+ - USB 3.0
+ - Two high speed USB 3.0 ports
+ - First USB 3.0 port configured as Host with Type-A connector
+ - Second USB 3.0 port configured as OTG with micro-AB connector
+ - SDHC adapter
+ - SD Card Rev 2.0 and Rev 3.0
+ - DSPI
+ - 128 MB high-speed flash Memory for boot code and storage (up to 108MHz)
+ - 4 I2C controllers
+ - Two SATA onboard connectors
+ - UART
+ - ARM JTAG support
+
+Memory map from core's view
+----------------------------
+0x00_0000_0000 .. 0x00_000F_FFFF Boot Rom
+0x00_0100_0000 .. 0x00_0FFF_FFFF CCSR
+0x00_1800_0000 .. 0x00_181F_FFFF OCRAM
+0x00_3000_0000 .. 0x00_3FFF_FFFF IFC region #1
+0x00_8000_0000 .. 0x00_FFFF_FFFF DDR region #1
+0x05_1000_0000 .. 0x05_FFFF_FFFF IFC region #2
+0x80_8000_0000 .. 0xFF_FFFF_FFFF DDR region #2
+
+Other addresses are either reserved, or not used directly by u-boot.
+This list should be updated when more addresses are used.
+
+IFC region map from core's view
+-------------------------------
+During boot i.e. IFC Region #1:-
+ 0x30000000 - 0x37ffffff : 128MB : NOR flash
+ 0x3C000000 - 0x40000000 : 64MB : CPLD
+
+After relocate to DDR i.e. IFC Region #2:-
+ 0x5_1000_0000..0x5_1fff_ffff Memory Hole
+ 0x5_2000_0000..0x5_3fff_ffff IFC CSx (CPLD, NAND and others 512MB)
+ 0x5_4000_0000..0x5_7fff_ffff ASIC or others 1GB
+ 0x5_8000_0000..0x5_bfff_ffff IFC CS0 1GB (NOR/Promjet)
+ 0x5_C000_0000..0x5_ffff_ffff IFC CS1 1GB (NOR/Promjet)
+
+Booting Options
+---------------
+a) NOR boot
+b) NAND boot
diff --git a/board/freescale/ls2085ardb/ddr.c b/board/freescale/ls2085ardb/ddr.c
new file mode 100644
index 0000000..8d71ae1
--- /dev/null
+++ b/board/freescale/ls2085ardb/ddr.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fsl_ddr_sdram.h>
+#include <fsl_ddr_dimm_params.h>
+#include "ddr.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void fsl_ddr_board_options(memctl_options_t *popts,
+ dimm_params_t *pdimm,
+ unsigned int ctrl_num)
+{
+ u8 dq_mapping_0, dq_mapping_2, dq_mapping_3;
+ const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
+ ulong ddr_freq;
+ int slot;
+
+ if (ctrl_num > 2) {
+ printf("Not supported controller number %d\n", ctrl_num);
+ return;
+ }
+
+ for (slot = 0; slot < CONFIG_DIMM_SLOTS_PER_CTLR; slot++) {
+ if (pdimm[slot].n_ranks)
+ break;
+ }
+
+ if (slot >= CONFIG_DIMM_SLOTS_PER_CTLR)
+ return;
+
+ /*
+ * we use identical timing for all slots. If needed, change the code
+ * to pbsp = rdimms[ctrl_num] or pbsp = udimms[ctrl_num];
+ */
+ if (popts->registered_dimm_en)
+ pbsp = rdimms[ctrl_num];
+ else
+ pbsp = udimms[ctrl_num];
+
+
+ /* Get clk_adjust, wrlvl_start, wrlvl_ctl, according to the board ddr
+ * freqency and n_banks specified in board_specific_parameters table.
+ */
+ ddr_freq = get_ddr_freq(ctrl_num) / 1000000;
+ while (pbsp->datarate_mhz_high) {
+ if (pbsp->n_ranks == pdimm[slot].n_ranks &&
+ (pdimm[slot].rank_density >> 30) >= pbsp->rank_gb) {
+ if (ddr_freq <= pbsp->datarate_mhz_high) {
+ popts->clk_adjust = pbsp->clk_adjust;
+ popts->wrlvl_start = pbsp->wrlvl_start;
+ popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
+ popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
+ goto found;
+ }
+ pbsp_highest = pbsp;
+ }
+ pbsp++;
+ }
+
+ if (pbsp_highest) {
+ printf("Error: board specific timing not found for data rate %lu MT/s\n"
+ "Trying to use the highest speed (%u) parameters\n",
+ ddr_freq, pbsp_highest->datarate_mhz_high);
+ popts->clk_adjust = pbsp_highest->clk_adjust;
+ popts->wrlvl_start = pbsp_highest->wrlvl_start;
+ popts->wrlvl_ctl_2 = pbsp->wrlvl_ctl_2;
+ popts->wrlvl_ctl_3 = pbsp->wrlvl_ctl_3;
+ } else {
+ panic("DIMM is not supported by this board");
+ }
+found:
+ debug("Found timing match: n_ranks %d, data rate %d, rank_gb %d\n"
+ "\tclk_adjust %d, wrlvl_start %d, wrlvl_ctrl_2 0x%x, wrlvl_ctrl_3 0x%x\n",
+ pbsp->n_ranks, pbsp->datarate_mhz_high, pbsp->rank_gb,
+ pbsp->clk_adjust, pbsp->wrlvl_start, pbsp->wrlvl_ctl_2,
+ pbsp->wrlvl_ctl_3);
+
+ if (ctrl_num == CONFIG_DP_DDR_CTRL) {
+ /* force DDR bus width to 32 bits */
+ popts->data_bus_width = 1;
+ popts->otf_burst_chop_en = 0;
+ popts->burst_length = DDR_BL8;
+ popts->bstopre = 0; /* enable auto precharge */
+ /*
+ * Layout optimization results byte mapping
+ * Byte 0 -> Byte ECC
+ * Byte 1 -> Byte 3
+ * Byte 2 -> Byte 2
+ * Byte 3 -> Byte 1
+ * Byte ECC -> Byte 0
+ */
+ dq_mapping_0 = pdimm[slot].dq_mapping[0];
+ dq_mapping_2 = pdimm[slot].dq_mapping[2];
+ dq_mapping_3 = pdimm[slot].dq_mapping[3];
+ pdimm[slot].dq_mapping[0] = pdimm[slot].dq_mapping[8];
+ pdimm[slot].dq_mapping[1] = pdimm[slot].dq_mapping[9];
+ pdimm[slot].dq_mapping[2] = pdimm[slot].dq_mapping[6];
+ pdimm[slot].dq_mapping[3] = pdimm[slot].dq_mapping[7];
+ pdimm[slot].dq_mapping[6] = dq_mapping_2;
+ pdimm[slot].dq_mapping[7] = dq_mapping_3;
+ pdimm[slot].dq_mapping[8] = dq_mapping_0;
+ pdimm[slot].dq_mapping[9] = 0;
+ pdimm[slot].dq_mapping[10] = 0;
+ pdimm[slot].dq_mapping[11] = 0;
+ pdimm[slot].dq_mapping[12] = 0;
+ pdimm[slot].dq_mapping[13] = 0;
+ pdimm[slot].dq_mapping[14] = 0;
+ pdimm[slot].dq_mapping[15] = 0;
+ pdimm[slot].dq_mapping[16] = 0;
+ pdimm[slot].dq_mapping[17] = 0;
+ }
+ /* To work at higher than 1333MT/s */
+ popts->half_strength_driver_enable = 0;
+ /*
+ * Write leveling override
+ */
+ popts->wrlvl_override = 1;
+ popts->wrlvl_sample = 0x0; /* 32 clocks */
+
+ /*
+ * Rtt and Rtt_WR override
+ */
+ popts->rtt_override = 0;
+
+ /* Enable ZQ calibration */
+ popts->zq_en = 1;
+
+ if (ddr_freq < 2350) {
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_60ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_60ohm) |
+ DDR_CDR2_VREF_RANGE_2;
+ } else {
+ popts->ddr_cdr1 = DDR_CDR1_DHC_EN |
+ DDR_CDR1_ODT(DDR_CDR_ODT_100ohm);
+ popts->ddr_cdr2 = DDR_CDR2_ODT(DDR_CDR_ODT_100ohm) |
+ DDR_CDR2_VREF_RANGE_2;
+ }
+}
+
+phys_size_t initdram(int board_type)
+{
+ phys_size_t dram_size;
+
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+ return fsl_ddr_sdram_size();
+#else
+ puts("Initializing DDR....using SPD\n");
+
+ dram_size = fsl_ddr_sdram();
+#endif
+
+ return dram_size;
+}
+
+void dram_init_banksize(void)
+{
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+ phys_size_t dp_ddr_size;
+#endif
+
+ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+ if (gd->ram_size > CONFIG_SYS_LS2_DDR_BLOCK1_SIZE) {
+ gd->bd->bi_dram[0].size = CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ gd->bd->bi_dram[1].start = CONFIG_SYS_DDR_BLOCK2_BASE;
+ gd->bd->bi_dram[1].size = gd->ram_size -
+ CONFIG_SYS_LS2_DDR_BLOCK1_SIZE;
+ } else {
+ gd->bd->bi_dram[0].size = gd->ram_size;
+ }
+
+#ifdef CONFIG_SYS_DP_DDR_BASE_PHY
+ /* initialize DP-DDR here */
+ puts("DP-DDR: ");
+ /*
+ * DDR controller use 0 as the base address for binding.
+ * It is mapped to CONFIG_SYS_DP_DDR_BASE for core to access.
+ */
+ dp_ddr_size = fsl_other_ddr_sdram(CONFIG_SYS_DP_DDR_BASE_PHY,
+ CONFIG_DP_DDR_CTRL,
+ CONFIG_DP_DDR_NUM_CTRLS,
+ CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR,
+ NULL, NULL, NULL);
+ if (dp_ddr_size) {
+ gd->bd->bi_dram[2].start = CONFIG_SYS_DP_DDR_BASE;
+ gd->bd->bi_dram[2].size = dp_ddr_size;
+ } else {
+ puts("Not detected");
+ }
+#endif
+}
diff --git a/board/freescale/ls2085ardb/ddr.h b/board/freescale/ls2085ardb/ddr.h
new file mode 100644
index 0000000..bda9d4a
--- /dev/null
+++ b/board/freescale/ls2085ardb/ddr.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __DDR_H__
+#define __DDR_H__
+struct board_specific_parameters {
+ u32 n_ranks;
+ u32 datarate_mhz_high;
+ u32 rank_gb;
+ u32 clk_adjust;
+ u32 wrlvl_start;
+ u32 wrlvl_ctl_2;
+ u32 wrlvl_ctl_3;
+};
+
+/*
+ * These tables contain all valid speeds we want to override with board
+ * specific parameters. datarate_mhz_high values need to be in ascending order
+ * for each n_ranks group.
+ */
+
+static const struct board_specific_parameters udimm0[] = {
+ /*
+ * memory controller 0
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+ {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,},
+ {2, 1666, 0, 4, 8, 0x08090B0D, 0x0E10100C,},
+ {2, 1900, 0, 4, 8, 0x090A0C0E, 0x1012120D,},
+ {2, 2300, 0, 4, 9, 0x0A0B0C10, 0x1114140E,},
+ {}
+};
+
+/* DP-DDR DIMM */
+static const struct board_specific_parameters udimm2[] = {
+ /*
+ * memory controller 2
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+ {2, 1350, 0, 4, 0xd, 0x0C0A0A00, 0x00000009,},
+ {2, 1666, 0, 4, 0xd, 0x0C0A0A00, 0x00000009,},
+ {2, 1900, 0, 4, 0xe, 0x0D0C0B00, 0x0000000A,},
+ {2, 2200, 0, 4, 0xe, 0x0D0C0B00, 0x0000000A,},
+ {}
+};
+
+static const struct board_specific_parameters rdimm0[] = {
+ /*
+ * memory controller 0
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+ {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,},
+ {2, 1666, 0, 4, 7, 0x08090A0C, 0x0D0F100B,},
+ {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,},
+ {2, 2200, 0, 4, 8, 0x090A0C0F, 0x1012130C,},
+ {}
+};
+
+/* DP-DDR DIMM */
+static const struct board_specific_parameters rdimm2[] = {
+ /*
+ * memory controller 2
+ * num| hi| rank| clk| wrlvl | wrlvl | wrlvl
+ * ranks| mhz| GB |adjst| start | ctl2 | ctl3
+ */
+ {2, 1350, 0, 4, 6, 0x0708090B, 0x0C0D0E09,},
+ {2, 1666, 0, 4, 7, 0x0B0A090C, 0x0D0F100B,},
+ {2, 1900, 0, 4, 7, 0x09090B0D, 0x0E10120B,},
+ {2, 2200, 0, 4, 8, 0x090A0C0F, 0x1012130C,},
+ {}
+};
+
+static const struct board_specific_parameters *udimms[] = {
+ udimm0,
+ udimm0,
+ udimm2,
+};
+
+static const struct board_specific_parameters *rdimms[] = {
+ rdimm0,
+ rdimm0,
+ rdimm2,
+};
+
+
+#endif
diff --git a/board/freescale/ls2085ardb/ls2085ardb.c b/board/freescale/ls2085ardb/ls2085ardb.c
new file mode 100644
index 0000000..d05f2bc
--- /dev/null
+++ b/board/freescale/ls2085ardb/ls2085ardb.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <malloc.h>
+#include <errno.h>
+#include <netdev.h>
+#include <fsl_ifc.h>
+#include <fsl_ddr.h>
+#include <asm/io.h>
+#include <fdt_support.h>
+#include <libfdt.h>
+#include <fsl_debug_server.h>
+#include <fsl-mc/fsl_mc.h>
+#include <environment.h>
+#include <i2c.h>
+#include <asm/arch-fsl-lsch3/soc.h>
+
+#include "../common/qixis.h"
+#include "ls2085ardb_qixis.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+unsigned long long get_qixis_addr(void)
+{
+ unsigned long long addr;
+
+ if (gd->flags & GD_FLG_RELOC)
+ addr = QIXIS_BASE_PHYS;
+ else
+ addr = QIXIS_BASE_PHYS_EARLY;
+
+ /*
+ * IFC address under 256MB is mapped to 0x30000000, any address above
+ * is mapped to 0x5_10000000 up to 4GB.
+ */
+ addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000;
+
+ return addr;
+}
+
+int checkboard(void)
+{
+ u8 sw;
+
+ 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);
+
+ sw = QIXIS_READ(brdcfg[0]);
+ sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT;
+
+ if (sw < 0x8)
+ printf("vBank: %d\n", sw);
+ else if (sw == 0x9)
+ puts("NAND\n");
+ else
+ printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH);
+
+ printf("FPGA: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata));
+
+ puts("SERDES1 Reference : ");
+ printf("Clock1 = 156.25MHz ");
+ printf("Clock2 = 156.25MHz");
+
+ puts("\nSERDES2 Reference : ");
+ printf("Clock1 = 100MHz ");
+ printf("Clock2 = 100MHz\n");
+
+ return 0;
+}
+
+unsigned long get_board_sys_clk(void)
+{
+ u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
+
+ switch (sysclk_conf & 0x0F) {
+ case QIXIS_SYSCLK_83:
+ return 83333333;
+ case QIXIS_SYSCLK_100:
+ return 100000000;
+ case QIXIS_SYSCLK_125:
+ return 125000000;
+ case QIXIS_SYSCLK_133:
+ return 133333333;
+ case QIXIS_SYSCLK_150:
+ return 150000000;
+ case QIXIS_SYSCLK_160:
+ return 160000000;
+ case QIXIS_SYSCLK_166:
+ return 166666666;
+ }
+ return 66666666;
+}
+
+int select_i2c_ch_pca9547(u8 ch)
+{
+ int ret;
+
+ ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
+ if (ret) {
+ puts("PCA: failed to select proper channel\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+int board_init(void)
+{
+ init_final_memctl_regs();
+
+#ifdef CONFIG_ENV_IS_NOWHERE
+ gd->env_addr = (ulong)&default_environment[0];
+#endif
+ select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
+
+ QIXIS_WRITE(rst_ctl, QIXIS_RST_CTL_RESET_EN);
+
+ return 0;
+}
+
+int board_early_init_f(void)
+{
+ fsl_lsch3_early_init_f();
+ return 0;
+}
+
+void detail_board_ddr_info(void)
+{
+ puts("\nDDR ");
+ print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, "");
+ print_ddr_info(0);
+ if (gd->bd->bi_dram[2].size) {
+ puts("\nDP-DDR ");
+ print_size(gd->bd->bi_dram[2].size, "");
+ print_ddr_info(CONFIG_DP_DDR_CTRL);
+ }
+}
+
+int dram_init(void)
+{
+ gd->ram_size = initdram(0);
+
+ return 0;
+}
+
+#if defined(CONFIG_ARCH_MISC_INIT)
+int arch_misc_init(void)
+{
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ debug_server_init();
+#endif
+
+ return 0;
+}
+#endif
+
+unsigned long get_dram_size_to_hide(void)
+{
+ unsigned long dram_to_hide = 0;
+
+/* Carve the Debug Server private DRAM block from the end of DRAM */
+#ifdef CONFIG_FSL_DEBUG_SERVER
+ dram_to_hide += debug_server_get_dram_block_size();
+#endif
+
+/* Carve the MC private DRAM block from the end of DRAM */
+#ifdef CONFIG_FSL_MC_ENET
+ 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;
+}
+
+#ifdef CONFIG_FSL_MC_ENET
+void fdt_fixup_board_enet(void *fdt)
+{
+ int offset;
+
+ offset = fdt_path_offset(fdt, "/fsl-mc");
+
+ if (offset < 0)
+ offset = fdt_path_offset(fdt, "/fsl,dprc@0");
+
+ if (offset < 0) {
+ printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n",
+ __func__, offset);
+ return;
+ }
+
+ if (get_mc_boot_status() == 0)
+ fdt_status_okay(fdt, offset);
+ else
+ fdt_status_fail(fdt, offset);
+}
+#endif
+
+#ifdef CONFIG_OF_BOARD_SETUP
+int ft_board_setup(void *blob, bd_t *bd)
+{
+ phys_addr_t base;
+ phys_size_t size;
+
+ 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);
+
+#ifdef CONFIG_FSL_MC_ENET
+ fdt_fixup_board_enet(blob);
+ fsl_mc_ldpaa_exit(bd);
+#endif
+
+ return 0;
+}
+#endif
+
+void qixis_dump_switch(void)
+{
+ int i, nr_of_cfgsw;
+
+ QIXIS_WRITE(cms[0], 0x00);
+ nr_of_cfgsw = QIXIS_READ(cms[1]);
+
+ puts("DIP switch settings dump:\n");
+ for (i = 1; i <= nr_of_cfgsw; i++) {
+ QIXIS_WRITE(cms[0], i);
+ printf("SW%d = (0x%02x)\n", i, QIXIS_READ(cms[1]));
+ }
+}
diff --git a/board/freescale/ls2085ardb/ls2085ardb_qixis.h b/board/freescale/ls2085ardb/ls2085ardb_qixis.h
new file mode 100644
index 0000000..cb60c00
--- /dev/null
+++ b/board/freescale/ls2085ardb/ls2085ardb_qixis.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LS2_RDB_QIXIS_H__
+#define __LS2_RDB_QIXIS_H__
+
+/* SYSCLK */
+#define QIXIS_SYSCLK_66 0x0
+#define QIXIS_SYSCLK_83 0x1
+#define QIXIS_SYSCLK_100 0x2
+#define QIXIS_SYSCLK_125 0x3
+#define QIXIS_SYSCLK_133 0x4
+#define QIXIS_SYSCLK_150 0x5
+#define QIXIS_SYSCLK_160 0x6
+#define QIXIS_SYSCLK_166 0x7
+
+#endif /*__LS2_RDB_QIXIS_H__*/
diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c
index 1cf0ab7..ebffe9a 100644
--- a/board/freescale/p1010rdb/p1010rdb.c
+++ b/board/freescale/p1010rdb/p1010rdb.c
@@ -77,10 +77,9 @@ struct cpld_data {
int board_early_init_f(void)
{
ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR);
- struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
-
+ struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
/* Clock configuration to access CPLD using IFC(GPCM) */
- setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
+ setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
/*
* Reset PCIe slots via GPIO4
*/
diff --git a/board/freescale/p1010rdb/spl.c b/board/freescale/p1010rdb/spl.c
index 11bd9cf..ee873b0 100644
--- a/board/freescale/p1010rdb/spl.c
+++ b/board/freescale/p1010rdb/spl.c
@@ -23,12 +23,12 @@ void board_init_f(ulong bootflag)
{
u32 plat_ratio;
ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;
- struct fsl_ifc *ifc = (void *)CONFIG_SYS_IFC_ADDR;
+ struct fsl_ifc ifc = {(void *)CONFIG_SYS_IFC_ADDR, (void *)NULL};
console_init_f();
/* Clock configuration to access CPLD using IFC(GPCM) */
- setbits_be32(&ifc->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
+ setbits_be32(&ifc.gregs->ifc_gcr, 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT);
#ifdef CONFIG_P1010RDB_PB
setbits_be32(&gur->pmuxcr2, MPC85xx_PMUXCR2_GPIO01_DRVVBUS);
diff --git a/common/board_r.c b/common/board_r.c
index 42ff18c..307124e 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -702,6 +702,12 @@ init_fnc_t init_sequence_r[] = {
/* TODO: could x86/PPC have this also perhaps? */
#ifdef CONFIG_ARM
initr_caches,
+ /* Note: For Freescale LS2 SoCs, new MMU table is created in DDR.
+ * A temporary mapping of IFC high region is since removed,
+ * so environmental variables in NOR flash is not availble
+ * until board_init() is called below to remap IFC to high
+ * region.
+ */
#endif
initr_reloc_global_data,
#if defined(CONFIG_SYS_INIT_RAM_LOCK) && defined(CONFIG_E500)
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 45e471c..5d8c9e6 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -36,9 +36,9 @@ static int mod_mem(cmd_tbl_t *, int, int, int, char * const []);
/* Display values from last command.
* Memory modify remembered values are different from display memory.
*/
-static uint dp_last_addr, dp_last_size;
-static uint dp_last_length = 0x40;
-static uint mm_last_addr, mm_last_size;
+static ulong dp_last_addr, dp_last_size;
+static ulong dp_last_length = 0x40;
+static ulong mm_last_addr, mm_last_size;
static ulong base_address = 0;
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 6a02c9e..690c9b0 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -125,7 +125,7 @@ __weak void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
typedef void __noreturn (*image_entry_noargs_t)(void);
image_entry_noargs_t image_entry =
- (image_entry_noargs_t) spl_image->entry_point;
+ (image_entry_noargs_t)(unsigned long)spl_image->entry_point;
debug("image entry point: 0x%X\n", spl_image->entry_point);
image_entry();
diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c
index b7801cb..b8c369d 100644
--- a/common/spl/spl_nand.c
+++ b/common/spl/spl_nand.c
@@ -91,7 +91,7 @@ void spl_nand_load_image(void)
sizeof(*header), (void *)header);
spl_parse_image_header(header);
nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
- spl_image.size, (void *)spl_image.load_addr);
+ spl_image.size, (void *)(unsigned long)spl_image.load_addr);
nand_deselect();
}
#endif
diff --git a/configs/ls1021aqds_ddr4_nor_lpuart_defconfig b/configs/ls1021aqds_ddr4_nor_lpuart_defconfig
new file mode 100644
index 0000000..4d2714b
--- /dev/null
+++ b/configs/ls1021aqds_ddr4_nor_lpuart_defconfig
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4,LPUART"
+CONFIG_ARM=y
+CONFIG_TARGET_LS1021AQDS=y
diff --git a/configs/ls2085aqds_defconfig b/configs/ls2085aqds_defconfig
new file mode 100644
index 0000000..e3a17a3
--- /dev/null
+++ b/configs/ls2085aqds_defconfig
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
+CONFIG_ARM=y
+CONFIG_TARGET_LS2085AQDS=y
diff --git a/configs/ls2085aqds_nand_defconfig b/configs/ls2085aqds_nand_defconfig
new file mode 100644
index 0000000..f84a426
--- /dev/null
+++ b/configs/ls2085aqds_nand_defconfig
@@ -0,0 +1,4 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4,NAND"
+CONFIG_SPL=y
+CONFIG_ARM=y
+CONFIG_TARGET_LS2085AQDS=y
diff --git a/configs/ls2085ardb_defconfig b/configs/ls2085ardb_defconfig
new file mode 100644
index 0000000..6b64f71
--- /dev/null
+++ b/configs/ls2085ardb_defconfig
@@ -0,0 +1,3 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4"
+CONFIG_ARM=y
+CONFIG_TARGET_LS2085ARDB=y
diff --git a/configs/ls2085ardb_nand_defconfig b/configs/ls2085ardb_nand_defconfig
new file mode 100644
index 0000000..74812f7
--- /dev/null
+++ b/configs/ls2085ardb_nand_defconfig
@@ -0,0 +1,4 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4,NAND"
+CONFIG_SPL=y
+CONFIG_ARM=y
+CONFIG_TARGET_LS2085ARDB=y
diff --git a/drivers/ddr/fsl/ctrl_regs.c b/drivers/ddr/fsl/ctrl_regs.c
index 3919257..8367c95 100644
--- a/drivers/ddr/fsl/ctrl_regs.c
+++ b/drivers/ddr/fsl/ctrl_regs.c
@@ -313,7 +313,10 @@ static void set_timing_cfg_0(const unsigned int ctrl_num,
#ifdef CONFIG_SYS_FSL_DDR4
/* tXP=max(4nCK, 6ns) */
int txp = max((int)mclk_ps * 4, 6000); /* unit=ps */
- trwt_mclk = 2;
+ unsigned int data_rate = get_ddr_freq(ctrl_num);
+
+ /* for faster clock, need more time for data setup */
+ trwt_mclk = (data_rate/1000000 > 1900) ? 3 : 2;
twrt_mclk = 1;
act_pd_exit_mclk = picos_to_mclk(ctrl_num, txp);
pre_pd_exit_mclk = act_pd_exit_mclk;
@@ -338,7 +341,7 @@ static void set_timing_cfg_0(const unsigned int ctrl_num,
*/
txp = max((int)mclk_ps * 3, (mclk_ps > 1540 ? 7500 : 6000));
- ip_rev = fsl_ddr_get_version();
+ ip_rev = fsl_ddr_get_version(ctrl_num);
if (ip_rev >= 0x40700) {
/*
* MRS_CYC = max(tMRD, tMOD)
@@ -544,7 +547,7 @@ static void set_timing_cfg_1(const unsigned int ctrl_num,
* we need set extend bit for it at
* TIMING_CFG_3[EXT_CASLAT]
*/
- if (fsl_ddr_get_version() <= 0x40400)
+ if (fsl_ddr_get_version(ctrl_num) <= 0x40400)
caslat_ctrl = 2 * cas_latency - 1;
else
caslat_ctrl = (cas_latency - 1) << 1;
@@ -1113,16 +1116,32 @@ static void set_ddr_sdram_mode_9(fsl_ddr_cfg_regs_t *ddr,
int i;
unsigned short esdmode4 = 0; /* Extended SDRAM mode 4 */
unsigned short esdmode5; /* Extended SDRAM mode 5 */
+ int rtt_park = 0;
- esdmode5 = 0x00000400; /* Data mask enabled */
+ if (ddr->cs[0].config & SDRAM_CS_CONFIG_EN) {
+ esdmode5 = 0x00000500; /* Data mask enable, RTT_PARK CS0 */
+ rtt_park = 1;
+ } else {
+ esdmode5 = 0x00000400; /* Data mask enabled */
+ }
ddr->ddr_sdram_mode_9 = (0
| ((esdmode4 & 0xffff) << 16)
| ((esdmode5 & 0xffff) << 0)
);
+
+ /* only mode_9 use 0x500, others use 0x400 */
+
debug("FSLDDR: ddr_sdram_mode_9) = 0x%08x\n", ddr->ddr_sdram_mode_9);
if (unq_mrs_en) { /* unique mode registers are supported */
for (i = 1; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
+ if (!rtt_park &&
+ (ddr->cs[i].config & SDRAM_CS_CONFIG_EN)) {
+ esdmode5 |= 0x00000500; /* RTT_PARK */
+ rtt_park = 1;
+ } else {
+ esdmode5 = 0x00000400;
+ }
switch (i) {
case 1:
ddr->ddr_sdram_mode_11 = (0
@@ -1970,31 +1989,41 @@ static void set_ddr_dq_mapping(fsl_ddr_cfg_regs_t *ddr,
const dimm_params_t *dimm_params)
{
unsigned int acc_ecc_en = (ddr->ddr_sdram_cfg >> 2) & 0x1;
+ int i;
+
+ for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
+ if (dimm_params[i].n_ranks)
+ break;
+ }
+ if (i >= CONFIG_DIMM_SLOTS_PER_CTLR) {
+ puts("DDR error: no DIMM found!\n");
+ return;
+ }
- ddr->dq_map_0 = ((dimm_params->dq_mapping[0] & 0x3F) << 26) |
- ((dimm_params->dq_mapping[1] & 0x3F) << 20) |
- ((dimm_params->dq_mapping[2] & 0x3F) << 14) |
- ((dimm_params->dq_mapping[3] & 0x3F) << 8) |
- ((dimm_params->dq_mapping[4] & 0x3F) << 2);
+ ddr->dq_map_0 = ((dimm_params[i].dq_mapping[0] & 0x3F) << 26) |
+ ((dimm_params[i].dq_mapping[1] & 0x3F) << 20) |
+ ((dimm_params[i].dq_mapping[2] & 0x3F) << 14) |
+ ((dimm_params[i].dq_mapping[3] & 0x3F) << 8) |
+ ((dimm_params[i].dq_mapping[4] & 0x3F) << 2);
- ddr->dq_map_1 = ((dimm_params->dq_mapping[5] & 0x3F) << 26) |
- ((dimm_params->dq_mapping[6] & 0x3F) << 20) |
- ((dimm_params->dq_mapping[7] & 0x3F) << 14) |
- ((dimm_params->dq_mapping[10] & 0x3F) << 8) |
- ((dimm_params->dq_mapping[11] & 0x3F) << 2);
+ ddr->dq_map_1 = ((dimm_params[i].dq_mapping[5] & 0x3F) << 26) |
+ ((dimm_params[i].dq_mapping[6] & 0x3F) << 20) |
+ ((dimm_params[i].dq_mapping[7] & 0x3F) << 14) |
+ ((dimm_params[i].dq_mapping[10] & 0x3F) << 8) |
+ ((dimm_params[i].dq_mapping[11] & 0x3F) << 2);
- ddr->dq_map_2 = ((dimm_params->dq_mapping[12] & 0x3F) << 26) |
- ((dimm_params->dq_mapping[13] & 0x3F) << 20) |
- ((dimm_params->dq_mapping[14] & 0x3F) << 14) |
- ((dimm_params->dq_mapping[15] & 0x3F) << 8) |
- ((dimm_params->dq_mapping[16] & 0x3F) << 2);
+ ddr->dq_map_2 = ((dimm_params[i].dq_mapping[12] & 0x3F) << 26) |
+ ((dimm_params[i].dq_mapping[13] & 0x3F) << 20) |
+ ((dimm_params[i].dq_mapping[14] & 0x3F) << 14) |
+ ((dimm_params[i].dq_mapping[15] & 0x3F) << 8) |
+ ((dimm_params[i].dq_mapping[16] & 0x3F) << 2);
/* dq_map for ECC[4:7] is set to 0 if accumulated ECC is enabled */
- ddr->dq_map_3 = ((dimm_params->dq_mapping[17] & 0x3F) << 26) |
- ((dimm_params->dq_mapping[8] & 0x3F) << 20) |
+ ddr->dq_map_3 = ((dimm_params[i].dq_mapping[17] & 0x3F) << 26) |
+ ((dimm_params[i].dq_mapping[8] & 0x3F) << 20) |
(acc_ecc_en ? 0 :
- (dimm_params->dq_mapping[9] & 0x3F) << 14) |
- dimm_params->dq_mapping_ors;
+ (dimm_params[i].dq_mapping[9] & 0x3F) << 14) |
+ dimm_params[i].dq_mapping_ors;
debug("FSLDDR: dq_map_0 = 0x%08x\n", ddr->dq_map_0);
debug("FSLDDR: dq_map_1 = 0x%08x\n", ddr->dq_map_1);
@@ -2357,7 +2386,7 @@ compute_fsl_memctl_config_regs(const unsigned int ctrl_num,
set_ddr_cdr1(ddr, popts);
set_ddr_cdr2(ddr, popts);
set_ddr_sdram_cfg(ddr, popts, common_dimm);
- ip_rev = fsl_ddr_get_version();
+ ip_rev = fsl_ddr_get_version(ctrl_num);
if (ip_rev > 0x40400)
unq_mrs_en = 1;
diff --git a/drivers/ddr/fsl/ddr4_dimm_params.c b/drivers/ddr/fsl/ddr4_dimm_params.c
index bbfb4ee..42834ca 100644
--- a/drivers/ddr/fsl/ddr4_dimm_params.c
+++ b/drivers/ddr/fsl/ddr4_dimm_params.c
@@ -135,7 +135,8 @@ unsigned int ddr_compute_dimm_parameters(const unsigned int ctrl_num,
if (spd->mem_type) {
if (spd->mem_type != SPD_MEMTYPE_DDR4) {
- printf("DIMM %u: is not a DDR4 SPD.\n", dimm_number);
+ printf("Ctrl %u DIMM %u: is not a DDR4 SPD.\n",
+ ctrl_num, dimm_number);
return 1;
}
} else {
diff --git a/drivers/ddr/fsl/fsl_ddr_gen4.c b/drivers/ddr/fsl/fsl_ddr_gen4.c
index d9fce7d..49e4688 100644
--- a/drivers/ddr/fsl/fsl_ddr_gen4.c
+++ b/drivers/ddr/fsl/fsl_ddr_gen4.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2014 Freescale Semiconductor, Inc.
+ * Copyright 2014-2015 Freescale Semiconductor, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -11,6 +11,22 @@
#include <fsl_immap.h>
#include <fsl_ddr.h>
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
+static void set_wait_for_bits_clear(void *ptr, u32 value, u32 bits)
+{
+ int timeout = 1000;
+
+ ddr_out32(ptr, value);
+
+ while (ddr_in32(ptr) & bits) {
+ udelay(100);
+ timeout--;
+ }
+ if (timeout <= 0)
+ puts("Error: A007865 wait for clear timeout.\n");
+}
+#endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */
+
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 4)
#error Invalid setting for CONFIG_CHIP_SELECTS_PER_CTRL
#endif
@@ -36,6 +52,16 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
defined(CONFIG_SYS_FSL_ERRATUM_A008514)
u32 *eddrtqcr1;
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
+ u32 temp32, mr6;
+#endif
+#ifdef CONFIG_FSL_DDR_BIST
+ u32 mtcr, err_detect, err_sbe;
+ u32 cs0_bnds, cs1_bnds, cs2_bnds, cs3_bnds, cs0_config;
+#endif
+#ifdef CONFIG_FSL_DDR_BIST
+ char buffer[CONFIG_SYS_CBSIZE];
+#endif
switch (ctrl_num) {
case 0:
@@ -214,6 +240,21 @@ void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
ddr_setbits32(ddr->debug[28], 0x9 << 20);
#endif
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
+ /* Part 1 of 2 */
+ /* This erraum only applies to verion 5.2.0 */
+ if (fsl_ddr_get_version(ctrl_num) == 0x50200) {
+ /* Disable DRAM VRef training */
+ ddr_out32(&ddr->ddr_cdr2,
+ regs->ddr_cdr2 & ~DDR_CDR2_VREF_TRAIN_EN);
+ /* Disable deskew */
+ ddr_out32(&ddr->debug[28], 0x400);
+ /* Disable D_INIT */
+ ddr_out32(&ddr->sdram_cfg_2,
+ regs->ddr_sdram_cfg_2 & ~SDRAM_CFG2_D_INIT);
+ ddr_out32(&ddr->debug[25], 0x9000);
+ }
+#endif
/*
* For RDIMMs, JEDEC spec requires clocks to be stable before reset is
* deasserted. Clocks start when any chip select is enabled and clock
@@ -261,6 +302,66 @@ step2:
mb();
isb();
+#ifdef CONFIG_SYS_FSL_ERRATUM_A008511
+ /* Part 2 of 2 */
+ /* This erraum only applies to verion 5.2.0 */
+ if (fsl_ddr_get_version(ctrl_num) == 0x50200) {
+ /* Wait for idle */
+ timeout = 200;
+ while (!(ddr_in32(&ddr->debug[1]) & 0x2) &&
+ (timeout > 0)) {
+ udelay(100);
+ timeout--;
+ }
+ if (timeout <= 0) {
+ printf("Controler %d timeout, debug_2 = %x\n",
+ ctrl_num, ddr_in32(&ddr->debug[1]));
+ }
+ /* Set VREF */
+ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
+ if (!(regs->cs[i].config & SDRAM_CS_CONFIG_EN))
+ continue;
+
+ mr6 = (regs->ddr_sdram_mode_10 >> 16) |
+ MD_CNTL_MD_EN |
+ MD_CNTL_CS_SEL(i) |
+ MD_CNTL_MD_SEL(6) |
+ 0x00200000;
+ temp32 = mr6 | 0xc0;
+ set_wait_for_bits_clear(&ddr->sdram_md_cntl,
+ temp32, MD_CNTL_MD_EN);
+ udelay(1);
+ debug("MR6 = 0x%08x\n", temp32);
+ temp32 = mr6 | 0xf0;
+ set_wait_for_bits_clear(&ddr->sdram_md_cntl,
+ temp32, MD_CNTL_MD_EN);
+ udelay(1);
+ debug("MR6 = 0x%08x\n", temp32);
+ temp32 = mr6 | 0x70;
+ set_wait_for_bits_clear(&ddr->sdram_md_cntl,
+ temp32, MD_CNTL_MD_EN);
+ udelay(1);
+ debug("MR6 = 0x%08x\n", temp32);
+ }
+ ddr_out32(&ddr->sdram_md_cntl, 0);
+ ddr_out32(&ddr->debug[28], 0); /* Enable deskew */
+ ddr_out32(&ddr->debug[1], 0x400); /* restart deskew */
+ /* wait for idle */
+ timeout = 200;
+ while (!(ddr_in32(&ddr->debug[1]) & 0x2) &&
+ (timeout > 0)) {
+ udelay(100);
+ timeout--;
+ }
+ if (timeout <= 0) {
+ printf("Controler %d timeout, debug_2 = %x\n",
+ ctrl_num, ddr_in32(&ddr->debug[1]));
+ }
+ /* Restore D_INIT */
+ ddr_out32(&ddr->sdram_cfg_2, regs->ddr_sdram_cfg_2);
+ }
+#endif /* CONFIG_SYS_FSL_ERRATUM_A008511 */
+
total_gb_size_per_controller = 0;
for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) {
if (!(regs->cs[i].config & 0x80000000))
@@ -309,4 +410,70 @@ step2:
ddr_out32(&ddr->sdram_cfg_2, temp_sdram_cfg);
}
#endif
+
+#ifdef CONFIG_FSL_DDR_BIST
+#define BIST_PATTERN1 0xFFFFFFFF
+#define BIST_PATTERN2 0x0
+#define BIST_CR 0x80010000
+#define BIST_CR_EN 0x80000000
+#define BIST_CR_STAT 0x00000001
+#define CTLR_INTLV_MASK 0x20000000
+ /* Perform build-in test on memory. Three-way interleaving is not yet
+ * supported by this code. */
+ if (getenv_f("ddr_bist", buffer, CONFIG_SYS_CBSIZE) >= 0) {
+ puts("Running BIST test. This will take a while...");
+ cs0_config = ddr_in32(&ddr->cs0_config);
+ if (cs0_config & CTLR_INTLV_MASK) {
+ cs0_bnds = ddr_in32(&cs0_bnds);
+ cs1_bnds = ddr_in32(&cs1_bnds);
+ cs2_bnds = ddr_in32(&cs2_bnds);
+ cs3_bnds = ddr_in32(&cs3_bnds);
+ /* set bnds to non-interleaving */
+ ddr_out32(&cs0_bnds, (cs0_bnds & 0xfffefffe) >> 1);
+ ddr_out32(&cs1_bnds, (cs1_bnds & 0xfffefffe) >> 1);
+ ddr_out32(&cs2_bnds, (cs2_bnds & 0xfffefffe) >> 1);
+ ddr_out32(&cs3_bnds, (cs3_bnds & 0xfffefffe) >> 1);
+ }
+ ddr_out32(&ddr->mtp1, BIST_PATTERN1);
+ ddr_out32(&ddr->mtp2, BIST_PATTERN1);
+ ddr_out32(&ddr->mtp3, BIST_PATTERN2);
+ ddr_out32(&ddr->mtp4, BIST_PATTERN2);
+ ddr_out32(&ddr->mtp5, BIST_PATTERN1);
+ ddr_out32(&ddr->mtp6, BIST_PATTERN1);
+ ddr_out32(&ddr->mtp7, BIST_PATTERN2);
+ ddr_out32(&ddr->mtp8, BIST_PATTERN2);
+ ddr_out32(&ddr->mtp9, BIST_PATTERN1);
+ ddr_out32(&ddr->mtp10, BIST_PATTERN2);
+ mtcr = BIST_CR;
+ ddr_out32(&ddr->mtcr, mtcr);
+ timeout = 100;
+ while (timeout > 0 && (mtcr & BIST_CR_EN)) {
+ mdelay(1000);
+ timeout--;
+ mtcr = ddr_in32(&ddr->mtcr);
+ }
+ if (timeout <= 0)
+ puts("Timeout\n");
+ else
+ puts("Done\n");
+ err_detect = ddr_in32(&ddr->err_detect);
+ err_sbe = ddr_in32(&ddr->err_sbe);
+ if (mtcr & BIST_CR_STAT) {
+ printf("BIST test failed on controller %d.\n",
+ ctrl_num);
+ }
+ if (err_detect || (err_sbe & 0xffff)) {
+ printf("ECC error detected on controller %d.\n",
+ ctrl_num);
+ }
+
+ if (cs0_config & CTLR_INTLV_MASK) {
+ /* restore bnds registers */
+ ddr_out32(&cs0_bnds, cs0_bnds);
+ ddr_out32(&cs1_bnds, cs1_bnds);
+ ddr_out32(&cs2_bnds, cs2_bnds);
+ ddr_out32(&cs3_bnds, cs3_bnds);
+ }
+ }
+#endif
}
diff --git a/drivers/ddr/fsl/interactive.c b/drivers/ddr/fsl/interactive.c
index 32ba6d8..d23e6e5 100644
--- a/drivers/ddr/fsl/interactive.c
+++ b/drivers/ddr/fsl/interactive.c
@@ -205,6 +205,8 @@ static void lowest_common_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
#define DIMM_PARM(x) {#x, offsetof(dimm_params_t, x), \
sizeof((dimm_params_t *)0)->x, 0}
+#define DIMM_PARM_HEX(x) {#x, offsetof(dimm_params_t, x), \
+ sizeof((dimm_params_t *)0)->x, 1}
static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
unsigned int ctrl_num,
@@ -220,6 +222,7 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
DIMM_PARM(primary_sdram_width),
DIMM_PARM(ec_sdram_width),
DIMM_PARM(registered_dimm),
+ DIMM_PARM(mirrored_dimm),
DIMM_PARM(device_width),
DIMM_PARM(n_row_addr),
@@ -274,7 +277,27 @@ static void fsl_ddr_dimm_parameters_edit(fsl_ddr_info_t *pinfo,
DIMM_PARM(tdqsq_max_ps),
DIMM_PARM(tqhs_ps),
#endif
-
+#ifdef CONFIG_SYS_FSL_DDR4
+ DIMM_PARM_HEX(dq_mapping[0]),
+ DIMM_PARM_HEX(dq_mapping[1]),
+ DIMM_PARM_HEX(dq_mapping[2]),
+ DIMM_PARM_HEX(dq_mapping[3]),
+ DIMM_PARM_HEX(dq_mapping[4]),
+ DIMM_PARM_HEX(dq_mapping[5]),
+ DIMM_PARM_HEX(dq_mapping[6]),
+ DIMM_PARM_HEX(dq_mapping[7]),
+ DIMM_PARM_HEX(dq_mapping[8]),
+ DIMM_PARM_HEX(dq_mapping[9]),
+ DIMM_PARM_HEX(dq_mapping[10]),
+ DIMM_PARM_HEX(dq_mapping[11]),
+ DIMM_PARM_HEX(dq_mapping[12]),
+ DIMM_PARM_HEX(dq_mapping[13]),
+ DIMM_PARM_HEX(dq_mapping[14]),
+ DIMM_PARM_HEX(dq_mapping[15]),
+ DIMM_PARM_HEX(dq_mapping[16]),
+ DIMM_PARM_HEX(dq_mapping[17]),
+ DIMM_PARM(dq_mapping_ors),
+#endif
DIMM_PARM(rank_density),
DIMM_PARM(capacity),
DIMM_PARM(base_address),
@@ -296,6 +319,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(primary_sdram_width),
DIMM_PARM(ec_sdram_width),
DIMM_PARM(registered_dimm),
+ DIMM_PARM(mirrored_dimm),
DIMM_PARM(device_width),
DIMM_PARM(n_row_addr),
@@ -314,6 +338,7 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(tckmax_ps),
DIMM_PARM(caslat_x),
+ DIMM_PARM_HEX(caslat_x),
DIMM_PARM(taa_ps),
DIMM_PARM(caslat_x_minus_1),
DIMM_PARM(caslat_x_minus_2),
@@ -322,6 +347,9 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(trcd_ps),
DIMM_PARM(trp_ps),
DIMM_PARM(tras_ps),
+#if defined(CONFIG_SYS_FSL_DDR4) || defined(CONFIG_SYS_FSL_DDR3)
+ DIMM_PARM(tfaw_ps),
+#endif
#ifdef CONFIG_SYS_FSL_DDR4
DIMM_PARM(trfc1_ps),
DIMM_PARM(trfc2_ps),
@@ -347,6 +375,27 @@ static void print_dimm_parameters(const dimm_params_t *pdimm)
DIMM_PARM(tdqsq_max_ps),
DIMM_PARM(tqhs_ps),
#endif
+#ifdef CONFIG_SYS_FSL_DDR4
+ DIMM_PARM_HEX(dq_mapping[0]),
+ DIMM_PARM_HEX(dq_mapping[1]),
+ DIMM_PARM_HEX(dq_mapping[2]),
+ DIMM_PARM_HEX(dq_mapping[3]),
+ DIMM_PARM_HEX(dq_mapping[4]),
+ DIMM_PARM_HEX(dq_mapping[5]),
+ DIMM_PARM_HEX(dq_mapping[6]),
+ DIMM_PARM_HEX(dq_mapping[7]),
+ DIMM_PARM_HEX(dq_mapping[8]),
+ DIMM_PARM_HEX(dq_mapping[9]),
+ DIMM_PARM_HEX(dq_mapping[10]),
+ DIMM_PARM_HEX(dq_mapping[11]),
+ DIMM_PARM_HEX(dq_mapping[12]),
+ DIMM_PARM_HEX(dq_mapping[13]),
+ DIMM_PARM_HEX(dq_mapping[14]),
+ DIMM_PARM_HEX(dq_mapping[15]),
+ DIMM_PARM_HEX(dq_mapping[16]),
+ DIMM_PARM_HEX(dq_mapping[17]),
+ DIMM_PARM(dq_mapping_ors),
+#endif
};
static const unsigned int n_opts = ARRAY_SIZE(options);
@@ -463,7 +512,7 @@ static void fsl_ddr_options_edit(fsl_ddr_info_t *pinfo,
CTRL_OPTIONS_CS(3, odt_rd_cfg),
CTRL_OPTIONS_CS(3, odt_wr_cfg),
#endif
-#if defined(CONFIG_SYS_FSL_DDR3)
+#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
CTRL_OPTIONS_CS(0, odt_rtt_norm),
CTRL_OPTIONS_CS(0, odt_rtt_wr),
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
@@ -753,7 +802,7 @@ static void print_memctl_options(const memctl_options_t *popts)
CTRL_OPTIONS_CS(3, odt_rd_cfg),
CTRL_OPTIONS_CS(3, odt_wr_cfg),
#endif
-#if defined(CONFIG_SYS_FSL_DDR3)
+#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
CTRL_OPTIONS_CS(0, odt_rtt_norm),
CTRL_OPTIONS_CS(0, odt_rtt_wr),
#if (CONFIG_CHIP_SELECTS_PER_CTRL > 1)
@@ -795,6 +844,7 @@ static void print_memctl_options(const memctl_options_t *popts)
CTRL_OPTIONS(twot_en),
CTRL_OPTIONS(threet_en),
CTRL_OPTIONS(registered_dimm_en),
+ CTRL_OPTIONS(mirrored_dimm),
CTRL_OPTIONS(ap_en),
CTRL_OPTIONS(x4_en),
CTRL_OPTIONS(bstopre),
diff --git a/drivers/ddr/fsl/lc_common_dimm_params.c b/drivers/ddr/fsl/lc_common_dimm_params.c
index b295344..b12eeb9 100644
--- a/drivers/ddr/fsl/lc_common_dimm_params.c
+++ b/drivers/ddr/fsl/lc_common_dimm_params.c
@@ -22,7 +22,7 @@ compute_cas_latency(const unsigned int ctrl_num,
unsigned int common_caslat;
unsigned int caslat_actual;
unsigned int retry = 16;
- unsigned int tmp;
+ unsigned int tmp = ~0;
const unsigned int mclk_ps = get_memory_clk_period_ps(ctrl_num);
#ifdef CONFIG_SYS_FSL_DDR3
const unsigned int taamax = 20000;
@@ -31,8 +31,7 @@ compute_cas_latency(const unsigned int ctrl_num,
#endif
/* compute the common CAS latency supported between slots */
- tmp = dimm_params[0].caslat_x;
- for (i = 1; i < number_of_dimms; i++) {
+ for (i = 0; i < number_of_dimms; i++) {
if (dimm_params[i].n_ranks)
tmp &= dimm_params[i].caslat_x;
}
diff --git a/drivers/ddr/fsl/main.c b/drivers/ddr/fsl/main.c
index b72b242..fa22383 100644
--- a/drivers/ddr/fsl/main.c
+++ b/drivers/ddr/fsl/main.c
@@ -453,7 +453,7 @@ fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step,
retval = compute_dimm_parameters(
i, spd, pdimm, j);
#ifdef CONFIG_SYS_DDR_RAW_TIMING
- if (!i && !j && retval) {
+ if (!j && retval) {
printf("SPD error on controller %d! "
"Trying fallback to raw timing "
"calculation\n", i);
diff --git a/drivers/ddr/fsl/options.c b/drivers/ddr/fsl/options.c
index 5beb11b..3b30fa2 100644
--- a/drivers/ddr/fsl/options.c
+++ b/drivers/ddr/fsl/options.c
@@ -728,7 +728,12 @@ unsigned int populate_memctl_options(int all_dimms_registered,
/* Choose ddr controller address mirror mode */
#if defined(CONFIG_SYS_FSL_DDR3) || defined(CONFIG_SYS_FSL_DDR4)
- popts->mirrored_dimm = pdimm[0].mirrored_dimm;
+ for (i = 0; i < CONFIG_DIMM_SLOTS_PER_CTLR; i++) {
+ if (pdimm[i].n_ranks) {
+ popts->mirrored_dimm = pdimm[i].mirrored_dimm;
+ break;
+ }
+ }
#endif
/* Global Timing Parameters. */
diff --git a/drivers/ddr/fsl/util.c b/drivers/ddr/fsl/util.c
index 664081b..ce55aea 100644
--- a/drivers/ddr/fsl/util.c
+++ b/drivers/ddr/fsl/util.c
@@ -23,12 +23,34 @@
#define ULL_8FS 0xFFFFFFFFULL
-u32 fsl_ddr_get_version(void)
+u32 fsl_ddr_get_version(unsigned int ctrl_num)
{
struct ccsr_ddr __iomem *ddr;
u32 ver_major_minor_errata;
- ddr = (void *)_DDR_ADDR;
+ switch (ctrl_num) {
+ case 0:
+ ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
+ break;
+#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 1)
+ case 1:
+ ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
+ break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 2)
+ case 2:
+ ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
+ break;
+#endif
+#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_NUM_DDR_CONTROLLERS > 3)
+ case 3:
+ ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
+ break;
+#endif
+ default:
+ printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
+ return 0;
+ }
ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;
@@ -212,7 +234,7 @@ void print_ddr_info(unsigned int start_ctrl)
/* Calculate CAS latency based on timing cfg values */
cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
- if (fsl_ddr_get_version() <= 0x40400)
+ if (fsl_ddr_get_version(0) <= 0x40400)
cas_lat += 1;
else
cas_lat += 2;
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index fc5ee35..42782cb 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -114,6 +114,9 @@ static u16 i2c_clk_div[50][2] = {
#ifndef CONFIG_SYS_MXC_I2C3_SPEED
#define CONFIG_SYS_MXC_I2C3_SPEED 100000
#endif
+#ifndef CONFIG_SYS_MXC_I2C4_SPEED
+#define CONFIG_SYS_MXC_I2C4_SPEED 100000
+#endif
#ifndef CONFIG_SYS_MXC_I2C1_SLAVE
#define CONFIG_SYS_MXC_I2C1_SLAVE 0
@@ -124,6 +127,9 @@ static u16 i2c_clk_div[50][2] = {
#ifndef CONFIG_SYS_MXC_I2C3_SLAVE
#define CONFIG_SYS_MXC_I2C3_SLAVE 0
#endif
+#ifndef CONFIG_SYS_MXC_I2C4_SLAVE
+#define CONFIG_SYS_MXC_I2C4_SLAVE 0
+#endif
/*
@@ -543,12 +549,17 @@ U_BOOT_I2C_ADAP_COMPLETE(mxc1, mxc_i2c_init, mxc_i2c_probe,
mxc_i2c_set_bus_speed,
CONFIG_SYS_MXC_I2C2_SPEED,
CONFIG_SYS_MXC_I2C2_SLAVE, 1)
-#if defined(CONFIG_MX31) || defined(CONFIG_MX35) ||\
- defined(CONFIG_MX51) || defined(CONFIG_MX53) ||\
- defined(CONFIG_MX6) || defined(CONFIG_LS102XA)
+#ifdef CONFIG_SYS_I2C_MXC_I2C3
U_BOOT_I2C_ADAP_COMPLETE(mxc2, mxc_i2c_init, mxc_i2c_probe,
mxc_i2c_read, mxc_i2c_write,
mxc_i2c_set_bus_speed,
CONFIG_SYS_MXC_I2C3_SPEED,
CONFIG_SYS_MXC_I2C3_SLAVE, 2)
#endif
+#ifdef CONFIG_SYS_I2C_MXC_I2C4
+U_BOOT_I2C_ADAP_COMPLETE(mxc3, mxc_i2c_init, mxc_i2c_probe,
+ mxc_i2c_read, mxc_i2c_write,
+ mxc_i2c_set_bus_speed,
+ CONFIG_SYS_MXC_I2C4_SPEED,
+ CONFIG_SYS_MXC_I2C4_SLAVE, 3)
+#endif
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 842209a..25630c3 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpc.o
obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o
obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
+obj-$(CONFIG_FSL_DEBUG_SERVER) += fsl_debug_server.o
obj-$(CONFIG_FSL_IIM) += fsl_iim.o
obj-$(CONFIG_GPIO_LED) += gpio_led.o
obj-$(CONFIG_I2C_EEPROM) += i2c_eeprom.o
diff --git a/drivers/misc/fsl_debug_server.c b/drivers/misc/fsl_debug_server.c
new file mode 100644
index 0000000..e080fe6
--- /dev/null
+++ b/drivers/misc/fsl_debug_server.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+
+#include <fsl_debug_server.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+static int debug_server_ver_info_maj, debug_server_ver_info_min;
+
+/**
+ * Copying Debug Server firmware to DDR
+ */
+static int debug_server_copy_image(const char *title, u64 image_addr,
+ u32 image_size, u64 debug_server_ram_addr)
+{
+ debug("%s copied to address %p\n", title,
+ (void *)debug_server_ram_addr);
+ memcpy((void *)debug_server_ram_addr, (void *)image_addr, image_size);
+
+ return 0;
+}
+
+/**
+ * Debug Server FIT image parser checks if the image is in FIT
+ * format, verifies integrity of the image and calculates
+ * raw image address and size values.
+ *
+ * Returns 0 if success and -1 if any of the above mentioned
+ * task fail.
+ **/
+int debug_server_parse_firmware_fit_image(const void **raw_image_addr,
+ size_t *raw_image_size)
+{
+ int format;
+ void *fit_hdr;
+ int node_offset;
+ const void *data;
+ size_t size;
+ const char *uname = "firmware";
+ char *desc;
+ char *debug_server_ver_info;
+ char *debug_server_ver_info_major, *debug_server_ver_info_minor;
+
+ /* Check if the image is in NOR flash */
+#ifdef CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
+ fit_hdr = (void *)CONFIG_SYS_DEBUG_SERVER_FW_ADDR;
+#else
+#error "CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR not defined"
+#endif
+
+ /* Check if Image is in FIT format */
+ format = genimg_get_format(fit_hdr);
+ if (format != IMAGE_FORMAT_FIT) {
+ printf("Error! Not a FIT image\n");
+ goto out_error;
+ }
+
+ if (!fit_check_format(fit_hdr)) {
+ printf("Error! Bad FIT image format\n");
+ goto out_error;
+ }
+
+ node_offset = fit_image_get_node(fit_hdr, uname);
+ if (node_offset < 0) {
+ printf("Error! Can not find %s subimage\n", uname);
+ goto out_error;
+ }
+
+ /* Verify Debug Server firmware image */
+ if (!fit_image_verify(fit_hdr, node_offset)) {
+ printf("Error! Bad Debug Server firmware hash");
+ goto out_error;
+ }
+
+ if (fit_get_desc(fit_hdr, node_offset, &desc) < 0) {
+ printf("Error! Failed to get Debug Server fw description");
+ goto out_error;
+ }
+
+ debug_server_ver_info = strstr(desc, "Version");
+ debug_server_ver_info_major = strtok(debug_server_ver_info, ".");
+ debug_server_ver_info_minor = strtok(NULL, ".");
+
+ debug_server_ver_info_maj =
+ simple_strtoul(debug_server_ver_info_major, NULL, 10);
+ debug_server_ver_info_min =
+ simple_strtoul(debug_server_ver_info_minor, NULL, 10);
+
+ /* Debug server version checking */
+ if ((debug_server_ver_info_maj < DEBUG_SERVER_VER_MAJOR) ||
+ (debug_server_ver_info_min < DEBUG_SERVER_VER_MINOR)) {
+ printf("Debug server FW mismatches the min version required\n");
+ printf("Expected:%d.%d, Got %d.%d\n",
+ DEBUG_SERVER_VER_MAJOR, DEBUG_SERVER_VER_MINOR,
+ debug_server_ver_info_maj,
+ debug_server_ver_info_min);
+ goto out_error;
+ }
+
+ /* Get address and size of raw image */
+ fit_image_get_data(fit_hdr, node_offset, &data, &size);
+
+ *raw_image_addr = data;
+ *raw_image_size = size;
+
+ return 0;
+
+out_error:
+ return -1;
+}
+
+/**
+ * Return the actual size of the Debug Server private DRAM block.
+ *
+ * NOTE: For now this function always returns the minimum required size,
+ * However, in the future, the actual size may be obtained from an environment
+ * variable.
+ */
+unsigned long debug_server_get_dram_block_size(void)
+{
+ return CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE;
+}
+
+int debug_server_init(void)
+{
+ struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
+ int error, timeout = CONFIG_SYS_DEBUG_SERVER_TIMEOUT;
+ int debug_server_boot_status;
+ u64 debug_server_ram_addr, debug_server_ram_size;
+ const void *raw_image_addr;
+ size_t raw_image_size = 0;
+
+ debug("debug_server_init called\n");
+ /*
+ * The Debug Server private DRAM block was already carved at the end of
+ * DRAM by board_init_f() using CONFIG_SYS_MEM_TOP_HIDE:
+ */
+ debug_server_ram_size = debug_server_get_dram_block_size();
+ if (gd->bd->bi_dram[1].start)
+ debug_server_ram_addr =
+ gd->bd->bi_dram[1].start + gd->bd->bi_dram[1].size;
+ else
+ debug_server_ram_addr =
+ gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
+
+ error = debug_server_parse_firmware_fit_image(&raw_image_addr,
+ &raw_image_size);
+ if (error != 0)
+ goto out;
+
+ debug("debug server (ram addr = 0x%llx, ram size = 0x%llx)\n",
+ debug_server_ram_addr, debug_server_ram_size);
+ /*
+ * Load the Debug Server FW at the beginning of the Debug Server
+ * private DRAM block:
+ */
+ debug_server_copy_image("Debug Server Firmware",
+ (u64)raw_image_addr, raw_image_size,
+ debug_server_ram_addr);
+
+ /* flush dcache */
+ flush_dcache_range((unsigned long)debug_server_ram_addr,
+ (unsigned long)debug_server_ram_addr +
+ (unsigned long)debug_server_ram_size);
+
+ /*
+ * Tell SP that the Debug Server FW is about to be launched. Before that
+ * populate the following:
+ * 1. Write the size allocated to SP Memory region into Bits {31:16} of
+ * SCRATCHRW5.
+ * 2. Write the start address of the SP memory regions into
+ * SCRATCHRW5 (Bits {15:0}, contain most significant bits, Bits
+ * {47:32} of the SP Memory Region physical start address
+ * (SoC address)) and SCRATCHRW6 (Bits {31:0}).
+ * 3. To know the Debug Server FW boot status, set bit 0 of SCRATCHRW11
+ * to 1. The Debug Server sets this to 0 to indicate a
+ * successul boot.
+ * 4. Wakeup SP by writing 0x1F to VSG GIC reg VIGR2.
+ */
+
+ /* 512 MB */
+ out_le32(&gur->scratchrw[5 - 1],
+ (u32)((u64)debug_server_ram_addr >> 32) | (0x000D << 16));
+ out_le32(&gur->scratchrw[6 - 1],
+ ((u32)debug_server_ram_addr) & 0xFFFFFFFF);
+
+ out_le32(&gur->scratchrw[11 - 1], DEBUG_SERVER_INIT_STATUS);
+ /* Allow the changes to reflect in GUR block */
+ mb();
+
+ /*
+ * Program VGIC to raise an interrupt to SP
+ */
+ out_le32(CONFIG_SYS_FSL_SP_VSG_GIC_VIGR2, 0x1F);
+ /* Allow the changes to reflect in VIGR2 */
+ mb();
+
+ dmb();
+ debug("Polling for Debug server to launch ...\n");
+
+ while (1) {
+ debug_server_boot_status = in_le32(&gur->scratchrw[11 - 1]);
+ if (!(debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK))
+ break;
+
+ udelay(1); /* throttle polling */
+ if (timeout-- <= 0)
+ break;
+ }
+
+ if (timeout <= 0) {
+ printf("Debug Server FW timed out (boot status: 0x%x)\n",
+ debug_server_boot_status);
+ error = -ETIMEDOUT;
+ goto out;
+ }
+
+ if (debug_server_boot_status & DEBUG_SERVER_INIT_STATUS_MASK) {
+ printf("Debug server FW error'ed out (boot status: 0x%x)\n",
+ debug_server_boot_status);
+ error = -ENODEV;
+ goto out;
+ }
+
+ printf("Debug server booted\n");
+ printf("Detected firmware %d.%d, (boot status: 0x0%x)\n",
+ debug_server_ver_info_maj, debug_server_ver_info_min,
+ debug_server_boot_status);
+
+out:
+ if (error != 0)
+ debug_server_boot_status = -error;
+ else
+ debug_server_boot_status = 0;
+
+ return debug_server_boot_status;
+}
+
diff --git a/drivers/misc/fsl_ifc.c b/drivers/misc/fsl_ifc.c
index 3902e9f..a33efdb 100644
--- a/drivers/misc/fsl_ifc.c
+++ b/drivers/misc/fsl_ifc.c
@@ -168,4 +168,25 @@ void init_final_memctl_regs(void)
#ifdef CONFIG_SYS_CSPR0_FINAL
set_ifc_cspr(IFC_CS0, CONFIG_SYS_CSPR0_FINAL);
#endif
+#ifdef CONFIG_SYS_AMASK0_FINAL
+ set_ifc_amask(IFC_CS0, CONFIG_SYS_AMASK0);
+#endif
+#ifdef CONFIG_SYS_CSPR1_FINAL
+ set_ifc_cspr(IFC_CS1, CONFIG_SYS_CSPR1_FINAL);
+#endif
+#ifdef CONFIG_SYS_AMASK1_FINAL
+ set_ifc_amask(IFC_CS1, CONFIG_SYS_AMASK1_FINAL);
+#endif
+#ifdef CONFIG_SYS_CSPR2_FINAL
+ set_ifc_cspr(IFC_CS2, CONFIG_SYS_CSPR2_FINAL);
+#endif
+#ifdef CONFIG_SYS_AMASK2_FINAL
+ set_ifc_amask(IFC_CS2, CONFIG_SYS_AMASK2);
+#endif
+#ifdef CONFIG_SYS_CSPR3_FINAL
+ set_ifc_cspr(IFC_CS3, CONFIG_SYS_CSPR3_FINAL);
+#endif
+#ifdef CONFIG_SYS_AMASK3_FINAL
+ set_ifc_amask(IFC_CS3, CONFIG_SYS_AMASK3);
+#endif
}
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index db4d251..10ec216 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -105,7 +105,8 @@ static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
else if (cmd->resp_type & MMC_RSP_PRESENT)
xfertyp |= XFERTYP_RSPTYP_48;
-#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) || defined(CONFIG_LS102XA)
+#if defined(CONFIG_MX53) || defined(CONFIG_PPC_T4240) || \
+ defined(CONFIG_LS102XA) || defined(CONFIG_LS2085A)
if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
xfertyp |= XFERTYP_CMDTYP_ABORT;
#endif
@@ -183,7 +184,9 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
int timeout;
struct fsl_esdhc_cfg *cfg = mmc->priv;
struct fsl_esdhc *regs = (struct fsl_esdhc *)cfg->esdhc_base;
-
+#ifdef CONFIG_LS2085A
+ dma_addr_t addr;
+#endif
uint wml_value;
wml_value = data->blocksize/4;
@@ -194,8 +197,16 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
+#ifdef CONFIG_LS2085A
+ addr = virt_to_phys((void *)(data->dest));
+ if (upper_32_bits(addr))
+ printf("Error found for upper 32 bits\n");
+ else
+ esdhc_write32(&regs->dsaddr, lower_32_bits(addr));
+#else
esdhc_write32(&regs->dsaddr, (u32)data->dest);
#endif
+#endif
} else {
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
flush_dcache_range((ulong)data->src,
@@ -212,8 +223,16 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
wml_value << 16);
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
+#ifdef CONFIG_LS2085A
+ addr = virt_to_phys((void *)(data->src));
+ if (upper_32_bits(addr))
+ printf("Error found for upper 32 bits\n");
+ else
+ esdhc_write32(&regs->dsaddr, lower_32_bits(addr));
+#else
esdhc_write32(&regs->dsaddr, (u32)data->src);
#endif
+#endif
}
esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
@@ -259,10 +278,23 @@ static int esdhc_setup_data(struct mmc *mmc, struct mmc_data *data)
static void check_and_invalidate_dcache_range
(struct mmc_cmd *cmd,
struct mmc_data *data) {
+#ifdef CONFIG_LS2085A
+ unsigned start = 0;
+#else
unsigned start = (unsigned)data->dest ;
+#endif
unsigned size = roundup(ARCH_DMA_MINALIGN,
data->blocks*data->blocksize);
unsigned end = start+size ;
+#ifdef CONFIG_LS2085A
+ dma_addr_t addr;
+
+ addr = virt_to_phys((void *)(data->dest));
+ if (upper_32_bits(addr))
+ printf("Error found for upper 32 bits\n");
+ else
+ start = lower_32_bits(addr);
+#endif
invalidate_dcache_range(start, end);
}
#endif
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c
index 7903eeb..79fa88b 100644
--- a/drivers/mtd/nand/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/fsl_ifc_nand.c
@@ -46,7 +46,7 @@ struct fsl_ifc_ctrl {
struct fsl_ifc_mtd *chips[MAX_BANKS];
/* device info */
- struct fsl_ifc *regs;
+ struct fsl_ifc regs;
uint8_t __iomem *addr; /* Address of assigned IFC buffer */
unsigned int cs_nand; /* On which chipsel NAND is connected */
unsigned int page; /* Last page written to / read from */
@@ -225,7 +225,7 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob)
struct nand_chip *chip = mtd->priv;
struct fsl_ifc_mtd *priv = chip->priv;
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
- struct fsl_ifc *ifc = ctrl->regs;
+ struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
int buf_num;
ctrl->page = page_addr;
@@ -289,10 +289,10 @@ static int fsl_ifc_run_command(struct mtd_info *mtd)
struct nand_chip *chip = mtd->priv;
struct fsl_ifc_mtd *priv = chip->priv;
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
- struct fsl_ifc *ifc = ctrl->regs;
+ struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
u32 time_start;
- u32 eccstat[4] = {0};
+ u32 eccstat[8] = {0};
int i;
/* set the chip select for NAND Transaction */
@@ -325,8 +325,15 @@ static int fsl_ifc_run_command(struct mtd_info *mtd)
int sector = bufnum * chip->ecc.steps;
int sector_end = sector + chip->ecc.steps - 1;
- for (i = sector / 4; i <= sector_end / 4; i++)
+ for (i = sector / 4; i <= sector_end / 4; i++) {
+ if (i >= ARRAY_SIZE(eccstat)) {
+ printf("%s: eccstat too small for %d\n",
+ __func__, i);
+ return -EIO;
+ }
+
eccstat[i] = ifc_in32(&ifc->ifc_nand.nand_eccstat[i]);
+ }
for (i = sector; i <= sector_end; i++) {
errors = check_read_ecc(mtd, ctrl, eccstat, i);
@@ -362,7 +369,7 @@ static void fsl_ifc_do_read(struct nand_chip *chip,
{
struct fsl_ifc_mtd *priv = chip->priv;
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
- struct fsl_ifc *ifc = ctrl->regs;
+ struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
/* Program FIR/IFC_NAND_FCR0 for Small/Large page */
if (mtd->writesize > 512) {
@@ -400,7 +407,7 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command,
struct nand_chip *chip = mtd->priv;
struct fsl_ifc_mtd *priv = chip->priv;
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
- struct fsl_ifc *ifc = ctrl->regs;
+ struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
/* clear the read buffer */
ctrl->read_bytes = 0;
@@ -690,7 +697,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip)
{
struct fsl_ifc_mtd *priv = chip->priv;
struct fsl_ifc_ctrl *ctrl = priv->ctrl;
- struct fsl_ifc *ifc = ctrl->regs;
+ struct fsl_ifc_runtime *ifc = ctrl->regs.rregs;
u32 nand_fsr;
if (ctrl->status != IFC_NAND_EVTER_STAT_OPC)
@@ -747,24 +754,33 @@ static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
static void fsl_ifc_ctrl_init(void)
{
+ uint32_t ver = 0;
ifc_ctrl = kzalloc(sizeof(*ifc_ctrl), GFP_KERNEL);
if (!ifc_ctrl)
return;
- ifc_ctrl->regs = IFC_BASE_ADDR;
+ ifc_ctrl->regs.gregs = IFC_FCM_BASE_ADDR;
+
+ ver = ifc_in32(&ifc_ctrl->regs.gregs->ifc_rev);
+ if (ver >= FSL_IFC_V2_0_0)
+ ifc_ctrl->regs.rregs =
+ (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_64KOFFSET;
+ else
+ ifc_ctrl->regs.rregs =
+ (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_4KOFFSET;
/* clear event registers */
- ifc_out32(&ifc_ctrl->regs->ifc_nand.nand_evter_stat, ~0U);
- ifc_out32(&ifc_ctrl->regs->ifc_nand.pgrdcmpl_evt_stat, ~0U);
+ ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.nand_evter_stat, ~0U);
+ ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.pgrdcmpl_evt_stat, ~0U);
/* Enable error and event for any detected errors */
- ifc_out32(&ifc_ctrl->regs->ifc_nand.nand_evter_en,
+ ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.nand_evter_en,
IFC_NAND_EVTER_EN_OPC_EN |
IFC_NAND_EVTER_EN_PGRDCMPL_EN |
IFC_NAND_EVTER_EN_FTOER_EN |
IFC_NAND_EVTER_EN_WPER_EN);
- ifc_out32(&ifc_ctrl->regs->ifc_nand.ncfgr, 0x0);
+ ifc_out32(&ifc_ctrl->regs.rregs->ifc_nand.ncfgr, 0x0);
}
static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
@@ -773,7 +789,7 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip)
static int fsl_ifc_sram_init(uint32_t ver)
{
- struct fsl_ifc *ifc = ifc_ctrl->regs;
+ struct fsl_ifc_runtime *ifc = ifc_ctrl->regs.rregs;
uint32_t cs = 0, csor = 0, csor_8k = 0, csor_ext = 0;
uint32_t ncfgr = 0;
u32 timeo = (CONFIG_SYS_HZ * 10) / 1000;
@@ -799,13 +815,13 @@ static int fsl_ifc_sram_init(uint32_t ver)
cs = ifc_ctrl->cs_nand >> IFC_NAND_CSEL_SHIFT;
/* Save CSOR and CSOR_ext */
- csor = ifc_in32(&ifc_ctrl->regs->csor_cs[cs].csor);
- csor_ext = ifc_in32(&ifc_ctrl->regs->csor_cs[cs].csor_ext);
+ csor = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor);
+ csor_ext = ifc_in32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext);
/* chage PageSize 8K and SpareSize 1K*/
csor_8k = (csor & ~(CSOR_NAND_PGS_MASK)) | 0x0018C000;
- ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor_8k);
- ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, 0x0000400);
+ ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor, csor_8k);
+ ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext, 0x0000400);
/* READID */
ifc_out32(&ifc->ifc_nand.nand_fir0,
@@ -845,8 +861,8 @@ static int fsl_ifc_sram_init(uint32_t ver)
ifc_out32(&ifc->ifc_nand.nand_evter_stat, ifc_ctrl->status);
/* Restore CSOR and CSOR_ext */
- ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor, csor);
- ifc_out32(&ifc_ctrl->regs->csor_cs[cs].csor_ext, csor_ext);
+ ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor, csor);
+ ifc_out32(&ifc_ctrl->regs.gregs->csor_cs[cs].csor_ext, csor_ext);
return 0;
}
@@ -857,6 +873,7 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr)
struct nand_chip *nand;
struct fsl_ifc_mtd *priv;
struct nand_ecclayout *layout;
+ struct fsl_ifc_fcm *gregs = NULL;
uint32_t cspr = 0, csor = 0, ver = 0;
int ret = 0;
@@ -872,14 +889,15 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr)
priv->ctrl = ifc_ctrl;
priv->vbase = addr;
+ gregs = ifc_ctrl->regs.gregs;
/* Find which chip select it is connected to.
*/
for (priv->bank = 0; priv->bank < MAX_BANKS; priv->bank++) {
phys_addr_t phys_addr = virt_to_phys(addr);
- cspr = ifc_in32(&ifc_ctrl->regs->cspr_cs[priv->bank].cspr);
- csor = ifc_in32(&ifc_ctrl->regs->csor_cs[priv->bank].csor);
+ cspr = ifc_in32(&gregs->cspr_cs[priv->bank].cspr);
+ csor = ifc_in32(&gregs->csor_cs[priv->bank].csor);
if ((cspr & CSPR_V) && (cspr & CSPR_MSEL) == CSPR_MSEL_NAND &&
(cspr & CSPR_BA) == CSPR_PHYS_ADDR(phys_addr)) {
@@ -998,7 +1016,7 @@ static int fsl_ifc_chip_init(int devnum, u8 *addr)
nand->ecc.mode = NAND_ECC_SOFT;
}
- ver = ifc_in32(&ifc_ctrl->regs->ifc_rev);
+ ver = ifc_in32(&gregs->ifc_rev);
if (ver >= FSL_IFC_V1_1_0)
ret = fsl_ifc_sram_init(ver);
if (ret)
diff --git a/drivers/mtd/nand/fsl_ifc_spl.c b/drivers/mtd/nand/fsl_ifc_spl.c
index fb827c5..fccbfb5 100644
--- a/drivers/mtd/nand/fsl_ifc_spl.c
+++ b/drivers/mtd/nand/fsl_ifc_spl.c
@@ -48,11 +48,25 @@ static inline int check_read_ecc(uchar *buf, u32 *eccstat,
return 0;
}
+static inline struct fsl_ifc_runtime *runtime_regs_address(void)
+{
+ struct fsl_ifc regs = {(void *)CONFIG_SYS_IFC_ADDR, NULL};
+ int ver = 0;
+
+ ver = ifc_in32(&regs.gregs->ifc_rev);
+ if (ver >= FSL_IFC_V2_0_0)
+ regs.rregs = (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_64KOFFSET;
+ else
+ regs.rregs = (void *)CONFIG_SYS_IFC_ADDR + IFC_RREGS_4KOFFSET;
+
+ return regs.rregs;
+}
+
static inline void nand_wait(uchar *buf, int bufnum, int page_size)
{
- struct fsl_ifc *ifc = IFC_BASE_ADDR;
+ struct fsl_ifc_runtime *ifc = runtime_regs_address();
u32 status;
- u32 eccstat[4];
+ u32 eccstat[8];
int bufperpage = page_size / 512;
int bufnum_end, i;
@@ -90,7 +104,8 @@ static inline int bad_block(uchar *marker, int port_size)
int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
{
- struct fsl_ifc *ifc = IFC_BASE_ADDR;
+ struct fsl_ifc_fcm *gregs = (void *)CONFIG_SYS_IFC_ADDR;
+ struct fsl_ifc_runtime *ifc = NULL;
uchar *buf = (uchar *)CONFIG_SYS_NAND_BASE;
int page_size;
int port_size;
@@ -107,6 +122,8 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
int pg_no;
uchar *dst = vdst;
+ ifc = runtime_regs_address();
+
/* Get NAND Flash configuration */
csor = CONFIG_SYS_NAND_CSOR;
cspr = CONFIG_SYS_NAND_CSPR;
@@ -130,7 +147,7 @@ int nand_spl_load_image(uint32_t offs, unsigned int uboot_size, void *vdst)
bad_marker = 5;
}
- ver = ifc_in32(&ifc->ifc_rev);
+ ver = ifc_in32(&gregs->ifc_rev);
if (ver >= FSL_IFC_V2_0_0)
bufnum_mask = (bufnum_mask * 2) + 1;
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index f24443d..150470c 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -69,4 +69,6 @@ obj-$(CONFIG_XILINX_LL_TEMAC) += xilinx_ll_temac.o xilinx_ll_temac_mdio.o \
xilinx_ll_temac_fifo.o xilinx_ll_temac_sdma.o
obj-$(CONFIG_ZYNQ_GEM) += zynq_gem.o
obj-$(CONFIG_FSL_MC_ENET) += fsl-mc/
+obj-$(CONFIG_FSL_MC_ENET) += ldpaa_eth/
+obj-$(CONFIG_FSL_MEMAC) += fm/memac_phy.o
obj-$(CONFIG_VSC9953) += vsc9953.o
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 2d66690..96e6bb0 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -2174,7 +2174,7 @@ e1000_copper_link_preconfig(struct e1000_hw *hw)
DEBUGOUT("Error, did not detect valid phy.\n");
return ret_val;
}
- DEBUGOUT("Phy ID = %x \n", hw->phy_id);
+ DEBUGOUT("Phy ID = %x\n", hw->phy_id);
/* Set PHY to class A mode (if necessary) */
ret_val = e1000_set_phy_mode(hw);
@@ -3485,11 +3485,11 @@ e1000_config_fc_after_link_up(struct e1000_hw *hw)
* some "sticky" (latched) bits.
*/
if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
- DEBUGOUT("PHY Read Error \n");
+ DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
if (e1000_read_phy_reg(hw, PHY_STATUS, &mii_status_reg) < 0) {
- DEBUGOUT("PHY Read Error \n");
+ DEBUGOUT("PHY Read Error\n");
return -E1000_ERR_PHY;
}
@@ -5152,7 +5152,7 @@ e1000_poll(struct eth_device *nic)
if (!(le32_to_cpu(rd->status)) & E1000_RXD_STAT_DD)
return 0;
- /*DEBUGOUT("recv: packet len=%d \n", rd->length); */
+ /* DEBUGOUT("recv: packet len=%d\n", rd->length); */
/* Packet received, make sure the data are re-loaded from RAM. */
len = le32_to_cpu(rd->length);
invalidate_dcache_range((unsigned long)packet,
diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c
index 55e76a7..d7a37f3 100644
--- a/drivers/net/fm/eth.c
+++ b/drivers/net/fm/eth.c
@@ -15,7 +15,7 @@
#include <phy.h>
#include <asm/fsl_dtsec.h>
#include <asm/fsl_tgec.h>
-#include <asm/fsl_memac.h>
+#include <fsl_memac.h>
#include "fm.h"
diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c
index 60e898c..81a64bf 100644
--- a/drivers/net/fm/memac.c
+++ b/drivers/net/fm/memac.c
@@ -12,7 +12,7 @@
#include <phy.h>
#include <asm/types.h>
#include <asm/io.h>
-#include <asm/fsl_memac.h>
+#include <fsl_memac.h>
#include "fm.h"
diff --git a/drivers/net/fm/memac_phy.c b/drivers/net/fm/memac_phy.c
index a155d89..4ab78e6 100644
--- a/drivers/net/fm/memac_phy.c
+++ b/drivers/net/fm/memac_phy.c
@@ -10,9 +10,28 @@
#include <miiphy.h>
#include <phy.h>
#include <asm/io.h>
-#include <asm/fsl_memac.h>
+#include <fsl_memac.h>
#include <fm_eth.h>
+#ifdef CONFIG_SYS_MEMAC_LITTLE_ENDIAN
+#define memac_out_32(a, v) out_le32(a, v)
+#define memac_clrbits_32(a, v) clrbits_le32(a, v)
+#define memac_setbits_32(a, v) setbits_le32(a, v)
+#else
+#define memac_out_32(a, v) out_be32(a, v)
+#define memac_clrbits_32(a, v) clrbits_be32(a, v)
+#define memac_setbits_32(a, v) setbits_be32(a, v)
+#endif
+
+static u32 memac_in_32(u32 *reg)
+{
+#ifdef CONFIG_SYS_MEMAC_LITTLE_ENDIAN
+ return in_le32(reg);
+#else
+ return in_be32(reg);
+#endif
+}
+
/*
* Write value to the PHY for this device to the register at regnum, waiting
* until the write is done before it returns. All PHY configuration has to be
@@ -28,31 +47,31 @@ int memac_mdio_write(struct mii_dev *bus, int port_addr, int dev_addr,
if (dev_addr == MDIO_DEVAD_NONE) {
c45 = 0; /* clause 22 */
dev_addr = regnum & 0x1f;
- clrbits_be32(&regs->mdio_stat, MDIO_STAT_ENC);
+ memac_clrbits_32(&regs->mdio_stat, MDIO_STAT_ENC);
} else
- setbits_be32(&regs->mdio_stat, MDIO_STAT_ENC);
+ memac_setbits_32(&regs->mdio_stat, MDIO_STAT_ENC);
/* Wait till the bus is free */
- while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+ while ((memac_in_32(&regs->mdio_stat)) & MDIO_STAT_BSY)
;
/* Set the port and dev addr */
mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
- out_be32(&regs->mdio_ctl, mdio_ctl);
+ memac_out_32(&regs->mdio_ctl, mdio_ctl);
/* Set the register address */
if (c45)
- out_be32(&regs->mdio_addr, regnum & 0xffff);
+ memac_out_32(&regs->mdio_addr, regnum & 0xffff);
/* Wait till the bus is free */
- while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+ while ((memac_in_32(&regs->mdio_stat)) & MDIO_STAT_BSY)
;
/* Write the value to the register */
- out_be32(&regs->mdio_data, MDIO_DATA(value));
+ memac_out_32(&regs->mdio_data, MDIO_DATA(value));
/* Wait till the MDIO write is complete */
- while ((in_be32(&regs->mdio_data)) & MDIO_DATA_BSY)
+ while ((memac_in_32(&regs->mdio_data)) & MDIO_DATA_BSY)
;
return 0;
@@ -75,39 +94,39 @@ int memac_mdio_read(struct mii_dev *bus, int port_addr, int dev_addr,
return 0xffff;
c45 = 0; /* clause 22 */
dev_addr = regnum & 0x1f;
- clrbits_be32(&regs->mdio_stat, MDIO_STAT_ENC);
+ memac_clrbits_32(&regs->mdio_stat, MDIO_STAT_ENC);
} else
- setbits_be32(&regs->mdio_stat, MDIO_STAT_ENC);
+ memac_setbits_32(&regs->mdio_stat, MDIO_STAT_ENC);
/* Wait till the bus is free */
- while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+ while ((memac_in_32(&regs->mdio_stat)) & MDIO_STAT_BSY)
;
/* Set the Port and Device Addrs */
mdio_ctl = MDIO_CTL_PORT_ADDR(port_addr) | MDIO_CTL_DEV_ADDR(dev_addr);
- out_be32(&regs->mdio_ctl, mdio_ctl);
+ memac_out_32(&regs->mdio_ctl, mdio_ctl);
/* Set the register address */
if (c45)
- out_be32(&regs->mdio_addr, regnum & 0xffff);
+ memac_out_32(&regs->mdio_addr, regnum & 0xffff);
/* Wait till the bus is free */
- while ((in_be32(&regs->mdio_stat)) & MDIO_STAT_BSY)
+ while ((memac_in_32(&regs->mdio_stat)) & MDIO_STAT_BSY)
;
/* Initiate the read */
mdio_ctl |= MDIO_CTL_READ;
- out_be32(&regs->mdio_ctl, mdio_ctl);
+ memac_out_32(&regs->mdio_ctl, mdio_ctl);
/* Wait till the MDIO write is complete */
- while ((in_be32(&regs->mdio_data)) & MDIO_DATA_BSY)
+ while ((memac_in_32(&regs->mdio_data)) & MDIO_DATA_BSY)
;
/* Return all Fs if nothing was there */
- if (in_be32(&regs->mdio_stat) & MDIO_STAT_RD_ER)
+ if (memac_in_32(&regs->mdio_stat) & MDIO_STAT_RD_ER)
return 0xffff;
- return in_be32(&regs->mdio_data) & 0xffff;
+ return memac_in_32(&regs->mdio_data) & 0xffff;
}
int memac_mdio_reset(struct mii_dev *bus)
@@ -143,8 +162,9 @@ int fm_memac_mdio_init(bd_t *bis, struct memac_mdio_info *info)
* like T2080QDS, this bit default is '0', which leads to MDIO failure
* on XAUI PHY, so set this bit definitely.
*/
- setbits_be32(&((struct memac_mdio_controller *)info->regs)->mdio_stat,
- MDIO_STAT_CLKDIV(258) | MDIO_STAT_NEG);
+ memac_setbits_32(
+ &((struct memac_mdio_controller *)info->regs)->mdio_stat,
+ MDIO_STAT_CLKDIV(258) | MDIO_STAT_NEG);
return mdio_register(bus);
}
diff --git a/drivers/net/fsl-mc/Makefile b/drivers/net/fsl-mc/Makefile
index 206ac6b..7563a5f 100644
--- a/drivers/net/fsl-mc/Makefile
+++ b/drivers/net/fsl-mc/Makefile
@@ -7,4 +7,8 @@
# Layerscape MC driver
obj-y += mc.o \
mc_sys.o \
- dpmng.o
+ dpmng.o \
+ dprc.o \
+ dpbp.o \
+ dpni.o
+obj-y += dpio/
diff --git a/drivers/net/fsl-mc/dpbp.c b/drivers/net/fsl-mc/dpbp.c
new file mode 100644
index 0000000..3853e58
--- /dev/null
+++ b/drivers/net/fsl-mc/dpbp.c
@@ -0,0 +1,102 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpbp.h>
+
+int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_OPEN,
+ MC_CMD_PRI_LOW, 0);
+ DPBP_CMD_OPEN(cmd, dpbp_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return err;
+}
+
+int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_CLOSE, MC_CMD_PRI_HIGH,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_ENABLE, MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_DISABLE,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_RESET,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpbp_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_ATTR,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPBP_RSP_GET_ATTRIBUTES(cmd, attr);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/dpio/Makefile b/drivers/net/fsl-mc/dpio/Makefile
new file mode 100644
index 0000000..1ccefc0
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright 2014 Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+# Layerscape MC DPIO driver
+obj-y += dpio.o \
+ qbman_portal.o
diff --git a/drivers/net/fsl-mc/dpio/dpio.c b/drivers/net/fsl-mc/dpio/dpio.c
new file mode 100644
index 0000000..b07eff7
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/dpio.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpio.h>
+
+int dpio_open(struct fsl_mc_io *mc_io, int dpio_id, uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_OPEN,
+ MC_CMD_PRI_LOW, 0);
+ DPIO_CMD_OPEN(cmd, dpio_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpio_close(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_CLOSE,
+ MC_CMD_PRI_HIGH, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_enable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_ENABLE,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_disable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_DISABLE,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_RESET,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpio_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPIO_CMDID_GET_ATTR,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPIO_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c
new file mode 100644
index 0000000..dd2a7de
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.c
@@ -0,0 +1,593 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "qbman_portal.h"
+
+/* QBMan portal management command codes */
+#define QBMAN_MC_ACQUIRE 0x30
+#define QBMAN_WQCHAN_CONFIGURE 0x46
+
+/* CINH register offsets */
+#define QBMAN_CINH_SWP_EQAR 0x8c0
+#define QBMAN_CINH_SWP_DCAP 0xac0
+#define QBMAN_CINH_SWP_SDQCR 0xb00
+#define QBMAN_CINH_SWP_RAR 0xcc0
+
+/* CENA register offsets */
+#define QBMAN_CENA_SWP_EQCR(n) (0x000 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_DQRR(n) (0x200 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_RCR(n) (0x400 + ((uint32_t)(n) << 6))
+#define QBMAN_CENA_SWP_CR 0x600
+#define QBMAN_CENA_SWP_RR(vb) (0x700 + ((uint32_t)(vb) >> 1))
+#define QBMAN_CENA_SWP_VDQCR 0x780
+
+/* Reverse mapping of QBMAN_CENA_SWP_DQRR() */
+#define QBMAN_IDX_FROM_DQRR(p) (((unsigned long)p & 0xff) >> 6)
+
+/*******************************/
+/* Pre-defined attribute codes */
+/*******************************/
+
+struct qb_attr_code code_generic_verb = QB_CODE(0, 0, 7);
+struct qb_attr_code code_generic_rslt = QB_CODE(0, 8, 8);
+
+/*************************/
+/* SDQCR attribute codes */
+/*************************/
+
+/* we put these here because at least some of them are required by
+ * qbman_swp_init() */
+struct qb_attr_code code_sdqcr_dct = QB_CODE(0, 24, 2);
+struct qb_attr_code code_sdqcr_fc = QB_CODE(0, 29, 1);
+struct qb_attr_code code_sdqcr_tok = QB_CODE(0, 16, 8);
+#define CODE_SDQCR_DQSRC(n) QB_CODE(0, n, 1)
+enum qbman_sdqcr_dct {
+ qbman_sdqcr_dct_null = 0,
+ qbman_sdqcr_dct_prio_ics,
+ qbman_sdqcr_dct_active_ics,
+ qbman_sdqcr_dct_active
+};
+enum qbman_sdqcr_fc {
+ qbman_sdqcr_fc_one = 0,
+ qbman_sdqcr_fc_up_to_3 = 1
+};
+
+/*********************************/
+/* Portal constructor/destructor */
+/*********************************/
+
+/* Software portals should always be in the power-on state when we initialise,
+ * due to the CCSR-based portal reset functionality that MC has. */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
+{
+ int ret;
+ struct qbman_swp *p = kmalloc(sizeof(*p), GFP_KERNEL);
+
+ if (!p)
+ return NULL;
+ p->desc = d;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit = QB_VALID_BIT;
+ p->sdq = 0;
+ 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 */
+ p->vdq.valid_bit = QB_VALID_BIT;
+ p->dqrr.next_idx = 0;
+ p->dqrr.valid_bit = QB_VALID_BIT;
+ ret = qbman_swp_sys_init(&p->sys, d);
+ if (ret) {
+ free(p);
+ printf("qbman_swp_sys_init() failed %d\n", ret);
+ return NULL;
+ }
+ qbman_cinh_write(&p->sys, QBMAN_CINH_SWP_SDQCR, p->sdq);
+ return p;
+}
+
+/***********************/
+/* Management commands */
+/***********************/
+
+/*
+ * Internal code common to all types of management commands.
+ */
+
+void *qbman_swp_mc_start(struct qbman_swp *p)
+{
+ void *ret;
+#ifdef QBMAN_CHECKING
+ BUG_ON(p->mc.check != swp_mc_can_start);
+#endif
+ ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
+#ifdef QBMAN_CHECKING
+ if (!ret)
+ p->mc.check = swp_mc_can_submit;
+#endif
+ return ret;
+}
+
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb)
+{
+ uint32_t *v = cmd;
+#ifdef QBMAN_CHECKING
+ BUG_ON(!p->mc.check != swp_mc_can_submit);
+#endif
+ lwsync();
+ /* TBD: "|=" is going to hurt performance. Need to move as many fields
+ * out of word zero, and for those that remain, the "OR" needs to occur
+ * at the caller side. This debug check helps to catch cases where the
+ * caller wants to OR but has forgotten to do so. */
+ BUG_ON((*v & cmd_verb) != *v);
+ *v = cmd_verb | p->mc.valid_bit;
+ qbman_cena_write_complete(&p->sys, QBMAN_CENA_SWP_CR, cmd);
+ /* TODO: add prefetch support for GPP */
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_poll;
+#endif
+}
+
+void *qbman_swp_mc_result(struct qbman_swp *p)
+{
+ uint32_t *ret, verb;
+#ifdef QBMAN_CHECKING
+ BUG_ON(p->mc.check != swp_mc_can_poll);
+#endif
+ ret = qbman_cena_read(&p->sys, QBMAN_CENA_SWP_RR(p->mc.valid_bit));
+ /* Remove the valid-bit - command completed iff the rest is non-zero */
+ verb = ret[0] & ~QB_VALID_BIT;
+ if (!verb)
+ return NULL;
+#ifdef QBMAN_CHECKING
+ p->mc.check = swp_mc_can_start;
+#endif
+ p->mc.valid_bit ^= QB_VALID_BIT;
+ return ret;
+}
+
+/***********/
+/* Enqueue */
+/***********/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_eq_cmd = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_eq_orp_en = QB_CODE(0, 2, 1);
+static struct qb_attr_code code_eq_tgt_id = QB_CODE(2, 0, 24);
+/* static struct qb_attr_code code_eq_tag = QB_CODE(3, 0, 32); */
+static struct qb_attr_code code_eq_qd_en = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_eq_qd_bin = QB_CODE(4, 0, 16);
+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 */
+ qbman_eq_cmd_empty,
+ /* DMA an enqueue response once complete */
+ qbman_eq_cmd_respond,
+ /* DMA an enqueue response only if the enqueue fails */
+ qbman_eq_cmd_respond_reject
+};
+
+void qbman_eq_desc_clear(struct qbman_eq_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *d, int respond_success)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_orp_en, cl, 0);
+ qb_attr_code_encode(&code_eq_cmd, cl,
+ respond_success ? qbman_eq_cmd_respond :
+ qbman_eq_cmd_respond_reject);
+}
+
+void qbman_eq_desc_set_response(struct qbman_eq_desc *d,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ 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(&code_eq_rsp_stash, cl, !!stash);
+}
+
+
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *d, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_eq_qd_en, cl, 1);
+ qb_attr_code_encode(&code_eq_tgt_id, cl, qdid);
+ qb_attr_code_encode(&code_eq_qd_bin, cl, qd_bin);
+ qb_attr_code_encode(&code_eq_qd_pri, cl, qd_prio);
+}
+
+#define EQAR_IDX(eqar) ((eqar) & 0x7)
+#define EQAR_VB(eqar) ((eqar) & 0x80)
+#define EQAR_SUCCESS(eqar) ((eqar) & 0x100)
+
+int qbman_swp_enqueue(struct qbman_swp *s, const struct qbman_eq_desc *d,
+ const struct qbman_fd *fd)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t eqar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_EQAR);
+ debug("EQAR=%08x\n", eqar);
+ if (!EQAR_SUCCESS(eqar))
+ return -EBUSY;
+ p = qbman_cena_write_start(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)));
+ word_copy(&p[1], &cl[1], 7);
+ word_copy(&p[8], fd, sizeof(*fd) >> 2);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p[0] = cl[0] | EQAR_VB(eqar);
+ qbman_cena_write_complete(&s->sys,
+ QBMAN_CENA_SWP_EQCR(EQAR_IDX(eqar)),
+ p);
+ return 0;
+}
+
+/***************************/
+/* Volatile (pull) dequeue */
+/***************************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_pull_dct = QB_CODE(0, 0, 2);
+static struct qb_attr_code code_pull_dt = QB_CODE(0, 2, 2);
+static struct qb_attr_code code_pull_rls = QB_CODE(0, 4, 1);
+static struct qb_attr_code code_pull_stash = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_pull_numframes = QB_CODE(0, 8, 4);
+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_pull_dt_workqueue,
+ qb_pull_dt_framequeue
+};
+
+void qbman_pull_desc_clear(struct qbman_pull_desc *d)
+{
+ memset(d, 0, sizeof(*d));
+}
+
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *d,
+ struct ldpaa_dq *storage,
+ dma_addr_t storage_phys,
+ int stash)
+{
+ uint32_t *cl = qb_cl(d);
+
+ /* Squiggle the pointer 'storage' into the extra 2 words of the
+ * descriptor (which aren't copied to the hw command) */
+ *(void **)&cl[4] = storage;
+ if (!storage) {
+ qb_attr_code_encode(&code_pull_rls, cl, 0);
+ return;
+ }
+ 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));
+}
+
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *d, uint8_t numframes)
+{
+ uint32_t *cl = qb_cl(d);
+
+ BUG_ON(!numframes || (numframes > 16));
+ qb_attr_code_encode(&code_pull_numframes, cl,
+ (uint32_t)(numframes - 1));
+}
+
+void qbman_pull_desc_set_token(struct qbman_pull_desc *d, uint8_t token)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_token, cl, token);
+}
+
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *d, uint32_t fqid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_pull_dct, cl, 1);
+ qb_attr_code_encode(&code_pull_dt, cl, qb_pull_dt_framequeue);
+ qb_attr_code_encode(&code_pull_dqsource, cl, fqid);
+}
+
+int qbman_swp_pull(struct qbman_swp *s, struct qbman_pull_desc *d)
+{
+ uint32_t *p;
+ uint32_t *cl = qb_cl(d);
+
+ /* TODO: convert to atomic_t */
+ if (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);
+ word_copy(&p[1], &cl[1], 3);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit */
+ p[0] = cl[0] | s->vdq.valid_bit;
+ s->vdq.valid_bit ^= QB_VALID_BIT;
+ qbman_cena_write_complete(&s->sys, QBMAN_CENA_SWP_VDQCR, p);
+ return 0;
+}
+
+/****************/
+/* Polling DQRR */
+/****************/
+
+static struct qb_attr_code code_dqrr_verb = QB_CODE(0, 0, 8);
+static struct qb_attr_code code_dqrr_response = QB_CODE(0, 0, 7);
+static struct qb_attr_code code_dqrr_stat = QB_CODE(0, 8, 8);
+
+#define QBMAN_DQRR_RESPONSE_DQ 0x60
+#define QBMAN_DQRR_RESPONSE_FQRN 0x21
+#define QBMAN_DQRR_RESPONSE_FQRNI 0x22
+#define QBMAN_DQRR_RESPONSE_FQPN 0x24
+#define QBMAN_DQRR_RESPONSE_FQDAN 0x25
+#define QBMAN_DQRR_RESPONSE_CDAN 0x26
+#define QBMAN_DQRR_RESPONSE_CSCN_MEM 0x27
+#define QBMAN_DQRR_RESPONSE_CGCU 0x28
+#define QBMAN_DQRR_RESPONSE_BPSCN 0x29
+#define QBMAN_DQRR_RESPONSE_CSCN_WQ 0x2a
+
+
+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order. */
+const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *s)
+{
+ 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);
+
+ verb = qb_attr_code_decode(&code_dqrr_verb, p);
+ /* If the valid-bit isn't of the expected polarity, nothing there */
+ if ((verb & QB_VALID_BIT) != s->dqrr.valid_bit) {
+ qbman_cena_invalidate_prefetch(&s->sys,
+ 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 */
+ /* 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;
+ }
+ qbman_cena_invalidate_prefetch(&s->sys,
+ QBMAN_CENA_SWP_DQRR(s->dqrr.next_idx));
+ return dq;
+}
+
+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
+void qbman_swp_dqrr_consume(struct qbman_swp *s, const struct ldpaa_dq *dq)
+{
+ qbman_cinh_write(&s->sys, QBMAN_CINH_SWP_DCAP, QBMAN_IDX_FROM_DQRR(dq));
+}
+
+/*********************************/
+/* Polling user-provided storage */
+/*********************************/
+
+void qbman_dq_entry_set_oldtoken(struct ldpaa_dq *dq,
+ unsigned int num_entries,
+ uint8_t oldtoken)
+{
+ memset(dq, oldtoken, num_entries * sizeof(*dq));
+}
+
+int qbman_dq_entry_has_newtoken(struct qbman_swp *s,
+ const struct ldpaa_dq *dq,
+ uint8_t newtoken)
+{
+ /* To avoid converting the little-endian DQ entry to host-endian prior
+ * to us knowing whether there is a valid entry or not (and run the
+ * risk of corrupting the incoming hardware LE write), we detect in
+ * hardware endianness rather than host. This means we need a different
+ * "code" depending on whether we are BE or LE in software, which is
+ * where DQRR_TOK_OFFSET comes in... */
+ static struct qb_attr_code code_dqrr_tok_detect =
+ QB_CODE(0, DQRR_TOK_OFFSET, 8);
+ /* The user trying to poll for a result treats "dq" as const. It is
+ * however the same address that was provided to us non-const in the
+ * first place, for directing hardware DMA to. So we can cast away the
+ * const because it is mutable from our perspective. */
+ uint32_t *p = qb_cl((struct ldpaa_dq *)dq);
+ uint32_t token;
+
+ token = qb_attr_code_decode(&code_dqrr_tok_detect, &p[1]);
+ if (token != newtoken)
+ return 0;
+
+ /* Only now do we convert from hardware to host endianness. Also, as we
+ * are returning success, the user has promised not to call us again, so
+ * there's no risk of us converting the endianness twice... */
+ make_le32_n(p, 16);
+
+ /* VDQCR "no longer busy" hook - not quite the same as DQRR, because the
+ * fact "VDQCR" shows busy doesn't mean that the result we're looking at
+ * is from the same command. Eg. we may be looking at our 10th dequeue
+ * result from our first VDQCR command, yet the second dequeue command
+ * could have been kicked off already, after seeing the 1st result. Ie.
+ * the result we're looking at is not necessarily proof that we can
+ * 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;
+ return 1;
+}
+
+/********************************/
+/* Categorising dequeue entries */
+/********************************/
+
+static inline int __qbman_dq_entry_is_x(const struct ldpaa_dq *dq, uint32_t x)
+{
+ const uint32_t *p = qb_cl(dq);
+ uint32_t response_verb = qb_attr_code_decode(&code_dqrr_response, p);
+
+ return response_verb == x;
+}
+
+int qbman_dq_entry_is_DQ(const struct ldpaa_dq *dq)
+{
+ return __qbman_dq_entry_is_x(dq, QBMAN_DQRR_RESPONSE_DQ);
+}
+
+/*********************************/
+/* Parsing frame dequeue results */
+/*********************************/
+
+/* These APIs assume qbman_dq_entry_is_DQ() is TRUE */
+
+uint32_t ldpaa_dq_flags(const struct ldpaa_dq *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return qb_attr_code_decode(&code_dqrr_stat, p);
+}
+
+const struct dpaa_fd *ldpaa_dq_fd(const struct ldpaa_dq *dq)
+{
+ const uint32_t *p = qb_cl(dq);
+
+ return (const struct dpaa_fd *)&p[8];
+}
+
+/******************/
+/* Buffer release */
+/******************/
+
+/* These should be const, eventually */
+/* static struct qb_attr_code code_release_num = QB_CODE(0, 0, 3); */
+static struct qb_attr_code code_release_set_me = QB_CODE(0, 5, 1);
+static struct qb_attr_code code_release_bpid = QB_CODE(0, 16, 16);
+
+void qbman_release_desc_clear(struct qbman_release_desc *d)
+{
+ uint32_t *cl;
+
+ memset(d, 0, sizeof(*d));
+ cl = qb_cl(d);
+ qb_attr_code_encode(&code_release_set_me, cl, 1);
+}
+
+void qbman_release_desc_set_bpid(struct qbman_release_desc *d, uint32_t bpid)
+{
+ uint32_t *cl = qb_cl(d);
+
+ qb_attr_code_encode(&code_release_bpid, cl, bpid);
+}
+
+#define RAR_IDX(rar) ((rar) & 0x7)
+#define RAR_VB(rar) ((rar) & 0x80)
+#define RAR_SUCCESS(rar) ((rar) & 0x100)
+
+int qbman_swp_release(struct qbman_swp *s, const struct qbman_release_desc *d,
+ const uint64_t *buffers, unsigned int num_buffers)
+{
+ uint32_t *p;
+ const uint32_t *cl = qb_cl(d);
+ uint32_t rar = qbman_cinh_read(&s->sys, QBMAN_CINH_SWP_RAR);
+ debug("RAR=%08x\n", rar);
+ if (!RAR_SUCCESS(rar))
+ return -EBUSY;
+ BUG_ON(!num_buffers || (num_buffers > 7));
+ /* Start the release command */
+ p = qbman_cena_write_start(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)));
+ /* Copy the caller's buffer pointers to the command */
+ u64_to_le32_copy(&p[2], buffers, num_buffers);
+ lwsync();
+ /* Set the verb byte, have to substitute in the valid-bit and the number
+ * of buffers. */
+ p[0] = cl[0] | RAR_VB(rar) | num_buffers;
+ qbman_cena_write_complete(&s->sys,
+ QBMAN_CENA_SWP_RCR(RAR_IDX(rar)),
+ p);
+ return 0;
+}
+
+/*******************/
+/* Buffer acquires */
+/*******************/
+
+/* These should be const, eventually */
+static struct qb_attr_code code_acquire_bpid = QB_CODE(0, 16, 16);
+static struct qb_attr_code code_acquire_num = QB_CODE(1, 0, 3);
+static struct qb_attr_code code_acquire_r_num = QB_CODE(1, 0, 3);
+
+int qbman_swp_acquire(struct qbman_swp *s, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers)
+{
+ uint32_t *p;
+ uint32_t verb, rslt, num;
+
+ BUG_ON(!num_buffers || (num_buffers > 7));
+
+ /* Start the management command */
+ p = qbman_swp_mc_start(s);
+
+ if (!p)
+ return -EBUSY;
+
+ /* Encode the caller-provided attributes */
+ qb_attr_code_encode(&code_acquire_bpid, p, bpid);
+ qb_attr_code_encode(&code_acquire_num, p, num_buffers);
+
+ /* Complete the management command */
+ p = qbman_swp_mc_complete(s, p, p[0] | QBMAN_MC_ACQUIRE);
+
+ /* Decode the outcome */
+ verb = qb_attr_code_decode(&code_generic_verb, p);
+ rslt = qb_attr_code_decode(&code_generic_rslt, p);
+ num = qb_attr_code_decode(&code_acquire_r_num, p);
+ BUG_ON(verb != QBMAN_MC_ACQUIRE);
+
+ /* Determine success or failure */
+ if (unlikely(rslt != QBMAN_MC_RSLT_OK)) {
+ printf("Acquire buffers from BPID 0x%x failed, code=0x%02x\n",
+ bpid, rslt);
+ return -EIO;
+ }
+ BUG_ON(num > num_buffers);
+ /* Copy the acquired buffers to the caller's array */
+ u64_from_le32_copy(buffers, &p[2], num);
+ return (int)num;
+}
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.h b/drivers/net/fsl-mc/dpio/qbman_portal.h
new file mode 100644
index 0000000..bb67c3b
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "qbman_private.h"
+#include <fsl-mc/fsl_qbman_portal.h>
+#include <fsl-mc/fsl_dpaa_fd.h>
+
+/* All QBMan command and result structures use this "valid bit" encoding */
+#define QB_VALID_BIT ((uint32_t)0x80)
+
+/* Management command result codes */
+#define QBMAN_MC_RSLT_OK 0xf0
+
+/* --------------------- */
+/* portal data structure */
+/* --------------------- */
+
+struct qbman_swp {
+ const struct qbman_swp_desc *desc;
+ /* The qbman_sys (ie. arch/OS-specific) support code can put anything it
+ * needs in here. */
+ struct qbman_swp_sys sys;
+ /* Management commands */
+ struct {
+#ifdef QBMAN_CHECKING
+ enum swp_mc_check {
+ swp_mc_can_start, /* call __qbman_swp_mc_start() */
+ swp_mc_can_submit, /* call __qbman_swp_mc_submit() */
+ swp_mc_can_poll, /* call __qbman_swp_mc_result() */
+ } check;
+#endif
+ uint32_t valid_bit; /* 0x00 or 0x80 */
+ } mc;
+ /* Push dequeues */
+ uint32_t sdq;
+ /* Volatile dequeues */
+ struct {
+ /* VDQCR supports a "1 deep pipeline", meaning that if you know
+ * the last-submitted command is already executing in the
+ * hardware (as evidenced by at least 1 valid dequeue result),
+ * you can write another dequeue command to the register, the
+ * hardware will start executing it as soon as the
+ * already-executing command terminates. (This minimises latency
+ * and stalls.) With that in mind, this "busy" variable refers
+ * 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;
+ 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
+ * 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
+ * dequeue result location is not already equal to the command's
+ * token value. */
+ struct ldpaa_dq *storage; /* NULL if DQRR */
+ uint32_t token;
+ } vdq;
+ /* DQRR */
+ struct {
+ uint32_t next_idx;
+ uint32_t valid_bit;
+ } dqrr;
+};
+
+/* -------------------------- */
+/* portal management commands */
+/* -------------------------- */
+
+/* Different management commands all use this common base layer of code to issue
+ * commands and poll for results. The first function returns a pointer to where
+ * the caller should fill in their MC command (though they should ignore the
+ * verb byte), the second function commits merges in the caller-supplied command
+ * verb (which should not include the valid-bit) and submits the command to
+ * hardware, and the third function checks for a completed response (returns
+ * non-NULL if only if the response is complete). */
+void *qbman_swp_mc_start(struct qbman_swp *p);
+void qbman_swp_mc_submit(struct qbman_swp *p, void *cmd, uint32_t cmd_verb);
+void *qbman_swp_mc_result(struct qbman_swp *p);
+
+/* Wraps up submit + poll-for-result */
+static inline void *qbman_swp_mc_complete(struct qbman_swp *swp, void *cmd,
+ uint32_t cmd_verb)
+{
+ int loopvar;
+
+ qbman_swp_mc_submit(swp, cmd, cmd_verb);
+ DBG_POLL_START(loopvar);
+ do {
+ DBG_POLL_CHECK(loopvar);
+ cmd = qbman_swp_mc_result(swp);
+ } while (!cmd);
+ return cmd;
+}
+
+/* ------------ */
+/* qb_attr_code */
+/* ------------ */
+
+/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
+ * is either serving as a configuration command or a query result. The
+ * representation is inherently little-endian, as the indexing of the words is
+ * itself little-endian in nature and layerscape is little endian for anything
+ * that crosses a word boundary too (64-bit fields are the obvious examples).
+ */
+struct qb_attr_code {
+ unsigned int word; /* which uint32_t[] array member encodes the field */
+ unsigned int lsoffset; /* encoding offset from ls-bit */
+ unsigned int width; /* encoding width. (bool must be 1.) */
+};
+
+/* Macros to define codes */
+#define QB_CODE(a, b, c) { a, b, c}
+
+/* decode a field from a cacheline */
+static inline uint32_t qb_attr_code_decode(const struct qb_attr_code *code,
+ const uint32_t *cacheline)
+{
+ 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)
+{
+ cacheline[code->word] =
+ r32_uint32_t(code->lsoffset, code->width, cacheline[code->word])
+ | e32_uint32_t(code->lsoffset, code->width, val);
+}
+
+/* ---------------------- */
+/* Descriptors/cachelines */
+/* ---------------------- */
+
+/* To avoid needless dynamic allocation, the driver API often gives the caller
+ * 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
+ * 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
+ * order for the compiler to know its size, but the internal details are not
+ * exposed. The following macro is used within the driver for converting *any*
+ * descriptor pointer to a usable array pointer. The use of a macro (instead of
+ * an inline) is necessary to work with different descriptor types and to work
+ * correctly with const and non-const inputs (and similarly-qualified outputs).
+ */
+#define qb_cl(d) (&(d)->dont_manipulate_directly[0])
diff --git a/drivers/net/fsl-mc/dpio/qbman_private.h b/drivers/net/fsl-mc/dpio/qbman_private.h
new file mode 100644
index 0000000..2d2556b
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/qbman_private.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* Perform extra checking */
+#include <common.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <linux/types.h>
+#include <linux/compat.h>
+#include <malloc.h>
+#include <fsl-mc/fsl_qbman_base.h>
+
+#define QBMAN_CHECKING
+
+/* Any time there is a register interface which we poll on, this provides a
+ * "break after x iterations" scheme for it. It's handy for debugging, eg.
+ * where you don't want millions of lines of log output from a polling loop
+ * that won't, because such things tend to drown out the earlier log output
+ * that might explain what caused the problem. (NB: put ";" after each macro!)
+ * TODO: we should probably remove this once we're done sanitising the
+ * simulator...
+ */
+#define DBG_POLL_START(loopvar) (loopvar = 10)
+#define DBG_POLL_CHECK(loopvar) \
+ do {if (!(loopvar--)) BUG_ON(NULL == "DBG_POLL_CHECK"); } while (0)
+
+/* For CCSR or portal-CINH registers that contain fields at arbitrary offsets
+ * and widths, these macro-generated encode/decode/isolate/remove inlines can
+ * be used.
+ *
+ * Eg. to "d"ecode a 14-bit field out of a register (into a "uint16_t" type),
+ * where the field is located 3 bits "up" from the least-significant bit of the
+ * register (ie. the field location within the 32-bit register corresponds to a
+ * mask of 0x0001fff8), you would do;
+ * uint16_t field = d32_uint16_t(3, 14, reg_value);
+ *
+ * Or to "e"ncode a 1-bit boolean value (input type is "int", zero is FALSE,
+ * non-zero is TRUE, so must convert all non-zero inputs to 1, hence the "!!"
+ * operator) into a register at bit location 0x00080000 (19 bits "in" from the
+ * LS bit), do;
+ * reg_value |= e32_int(19, 1, !!field);
+ *
+ * If you wish to read-modify-write a register, such that you leave the 14-bit
+ * field as-is but have all other fields set to zero, then "i"solate the 14-bit
+ * value using;
+ * reg_value = i32_uint16_t(3, 14, reg_value);
+ *
+ * Alternatively, you could "r"emove the 1-bit boolean field (setting it to
+ * zero) but leaving all other fields as-is;
+ * reg_val = r32_int(19, 1, reg_value);
+ *
+ */
+#define MAKE_MASK32(width) (width == 32 ? 0xffffffff : \
+ (uint32_t)((1 << width) - 1))
+#define DECLARE_CODEC32(t) \
+static inline uint32_t e32_##t(uint32_t lsoffset, uint32_t width, t val) \
+{ \
+ BUG_ON(width > (sizeof(t) * 8)); \
+ return ((uint32_t)val & MAKE_MASK32(width)) << lsoffset; \
+} \
+static inline t d32_##t(uint32_t lsoffset, uint32_t width, uint32_t val) \
+{ \
+ BUG_ON(width > (sizeof(t) * 8)); \
+ return (t)((val >> lsoffset) & MAKE_MASK32(width)); \
+} \
+static inline uint32_t i32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ BUG_ON(width > (sizeof(t) * 8)); \
+ return e32_##t(lsoffset, width, d32_##t(lsoffset, width, val)); \
+} \
+static inline uint32_t r32_##t(uint32_t lsoffset, uint32_t width, \
+ uint32_t val) \
+{ \
+ BUG_ON(width > (sizeof(t) * 8)); \
+ return ~(MAKE_MASK32(width) << lsoffset) & val; \
+}
+DECLARE_CODEC32(uint32_t)
+DECLARE_CODEC32(uint16_t)
+DECLARE_CODEC32(uint8_t)
+DECLARE_CODEC32(int)
+
+ /*********************/
+ /* Debugging assists */
+ /*********************/
+
+static inline void __hexdump(unsigned long start, unsigned long end,
+ unsigned long p, size_t sz, const unsigned char *c)
+{
+ while (start < end) {
+ unsigned int pos = 0;
+ char buf[64];
+ int nl = 0;
+
+ pos += sprintf(buf + pos, "%08lx: ", start);
+ do {
+ if ((start < p) || (start >= (p + sz)))
+ pos += sprintf(buf + pos, "..");
+ else
+ pos += sprintf(buf + pos, "%02x", *(c++));
+ if (!(++start & 15)) {
+ buf[pos++] = '\n';
+ nl = 1;
+ } else {
+ nl = 0;
+ if (!(start & 1))
+ buf[pos++] = ' ';
+ if (!(start & 3))
+ buf[pos++] = ' ';
+ }
+ } while (start & 15);
+ if (!nl)
+ buf[pos++] = '\n';
+ buf[pos] = '\0';
+ debug("%s", buf);
+ }
+}
+static inline void hexdump(const void *ptr, size_t sz)
+{
+ unsigned long p = (unsigned long)ptr;
+ unsigned long start = p & ~(unsigned long)15;
+ unsigned long end = (p + sz + 15) & ~(unsigned long)15;
+ const unsigned char *c = ptr;
+
+ __hexdump(start, end, p, sz, c);
+}
+
+#if defined(__BIG_ENDIAN)
+#define DQRR_TOK_OFFSET 0
+#else
+#define DQRR_TOK_OFFSET 24
+#endif
+
+/* Similarly-named functions */
+#define upper32(a) upper_32_bits(a)
+#define lower32(a) lower_32_bits(a)
+
+ /****************/
+ /* arch assists */
+ /****************/
+
+static inline void dcbz(void *ptr)
+{
+ uint32_t *p = ptr;
+ BUG_ON((unsigned long)ptr & 63);
+ p[0] = 0;
+ p[1] = 0;
+ p[2] = 0;
+ p[3] = 0;
+ p[4] = 0;
+ p[5] = 0;
+ p[6] = 0;
+ p[7] = 0;
+ p[8] = 0;
+ p[9] = 0;
+ p[10] = 0;
+ p[11] = 0;
+ p[12] = 0;
+ p[13] = 0;
+ p[14] = 0;
+ p[15] = 0;
+}
+
+#define lwsync()
+
+#include "qbman_sys.h"
diff --git a/drivers/net/fsl-mc/dpio/qbman_sys.h b/drivers/net/fsl-mc/dpio/qbman_sys.h
new file mode 100644
index 0000000..235d641
--- /dev/null
+++ b/drivers/net/fsl-mc/dpio/qbman_sys.h
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/* qbman_sys_decl.h and qbman_sys.h are the two platform-specific files in the
+ * driver. They are only included via qbman_private.h, which is itself a
+ * platform-independent file and is included by all the other driver source.
+ *
+ * qbman_sys_decl.h is included prior to all other declarations and logic, and
+ * it exists to provide compatibility with any linux interfaces our
+ * single-source driver code is dependent on (eg. kmalloc). Ie. this file
+ * provides linux compatibility.
+ *
+ * This qbman_sys.h header, on the other hand, is included *after* any common
+ * and platform-neutral declarations and logic in qbman_private.h, and exists to
+ * implement any platform-specific logic of the qbman driver itself. Ie. it is
+ * *not* to provide linux compatibility.
+ */
+
+/* Trace the 3 different classes of read/write access to QBMan. #undef as
+ * required. */
+#undef QBMAN_CCSR_TRACE
+#undef QBMAN_CINH_TRACE
+#undef QBMAN_CENA_TRACE
+
+/* Temporarily define this to get around the fact that cache enabled mapping is
+ * not working right now. Will remove this after uboot could map the cache
+ * enabled portal memory.
+ */
+#define QBMAN_CINH_ONLY
+
+static inline void word_copy(void *d, const void *s, unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = s;
+
+ while (cnt--)
+ *(dd++) = *(ss++);
+}
+
+/* Currently, the CENA support code expects each 32-bit word to be written in
+ * host order, and these are converted to hardware (little-endian) order on
+ * command submission. However, 64-bit quantities are must be written (and read)
+ * as two 32-bit words with the least-significant word first, irrespective of
+ * host endianness. */
+static inline void u64_to_le32_copy(void *d, const uint64_t *s,
+ unsigned int cnt)
+{
+ uint32_t *dd = d;
+ const uint32_t *ss = (const uint32_t *)s;
+
+ while (cnt--) {
+ /* TBD: the toolchain was choking on the use of 64-bit types up
+ * until recently so this works entirely with 32-bit variables.
+ * When 64-bit types become usable again, investigate better
+ * ways of doing this. */
+#if defined(__BIG_ENDIAN)
+ *(dd++) = ss[1];
+ *(dd++) = ss[0];
+ ss += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+static inline void u64_from_le32_copy(uint64_t *d, const void *s,
+ unsigned int cnt)
+{
+ const uint32_t *ss = s;
+ uint32_t *dd = (uint32_t *)d;
+
+ while (cnt--) {
+#if defined(__BIG_ENDIAN)
+ dd[1] = *(ss++);
+ dd[0] = *(ss++);
+ dd += 2;
+#else
+ *(dd++) = *(ss++);
+ *(dd++) = *(ss++);
+#endif
+ }
+}
+
+/* Convert a host-native 32bit value into little endian */
+#if defined(__BIG_ENDIAN)
+static inline uint32_t make_le32(uint32_t val)
+{
+ return ((val & 0xff) << 24) | ((val & 0xff00) << 8) |
+ ((val & 0xff0000) >> 8) | ((val & 0xff000000) >> 24);
+}
+#else
+#define make_le32(val) (val)
+#endif
+static inline void make_le32_n(uint32_t *val, unsigned int num)
+{
+ while (num--) {
+ *val = make_le32(*val);
+ val++;
+ }
+}
+
+ /******************/
+ /* Portal access */
+ /******************/
+struct qbman_swp_sys {
+ /* On GPP, the sys support for qbman_swp is here. The CENA region isi
+ * not an mmap() of the real portal registers, but an allocated
+ * place-holder, because the actual writes/reads to/from the portal are
+ * marshalled from these allocated areas using QBMan's "MC access
+ * registers". CINH accesses are atomic so there's no need for a
+ * place-holder. */
+ void *cena;
+ void __iomem *addr_cena;
+ void __iomem *addr_cinh;
+};
+
+/* P_OFFSET is (ACCESS_CMD,0,12) - offset within the portal
+ * C is (ACCESS_CMD,12,1) - is inhibited? (0==CENA, 1==CINH)
+ * SWP_IDX is (ACCESS_CMD,16,10) - Software portal index
+ * P is (ACCESS_CMD,28,1) - (0==special portal, 1==any portal)
+ * T is (ACCESS_CMD,29,1) - Command type (0==READ, 1==WRITE)
+ * E is (ACCESS_CMD,31,1) - Command execute (1 to issue, poll for 0==complete)
+ */
+
+static inline void qbman_cinh_write(struct qbman_swp_sys *s, uint32_t offset,
+ uint32_t val)
+{
+ __raw_writel(val, s->addr_cinh + offset);
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_write(%p:0x%03x) 0x%08x\n",
+ s->addr_cinh, offset, val);
+#endif
+}
+
+static inline uint32_t qbman_cinh_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t reg = __raw_readl(s->addr_cinh + offset);
+
+#ifdef QBMAN_CINH_TRACE
+ pr_info("qbman_cinh_read(%p:0x%03x) 0x%08x\n",
+ s->addr_cinh, offset, reg);
+#endif
+ return reg;
+}
+
+static inline void *qbman_cena_write_start(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+ void *shadow = s->cena + offset;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_start(%p:0x%03x) %p\n",
+ s->addr_cena, offset, shadow);
+#endif
+ BUG_ON(offset & 63);
+ dcbz(shadow);
+ return shadow;
+}
+
+static inline void qbman_cena_write_complete(struct qbman_swp_sys *s,
+ uint32_t offset, void *cmd)
+{
+ const uint32_t *shadow = cmd;
+ int loop;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_write_complete(%p:0x%03x) %p\n",
+ s->addr_cena, offset, shadow);
+ hexdump(cmd, 64);
+#endif
+ for (loop = 15; loop >= 0; loop--)
+#ifdef QBMAN_CINH_ONLY
+ __raw_writel(shadow[loop], s->addr_cinh +
+ offset + loop * 4);
+#else
+ __raw_writel(shadow[loop], s->addr_cena +
+ offset + loop * 4);
+#endif
+}
+
+static inline void *qbman_cena_read(struct qbman_swp_sys *s, uint32_t offset)
+{
+ uint32_t *shadow = s->cena + offset;
+ unsigned int loop;
+
+#ifdef QBMAN_CENA_TRACE
+ pr_info("qbman_cena_read(%p:0x%03x) %p\n",
+ s->addr_cena, offset, shadow);
+#endif
+
+ for (loop = 0; loop < 16; loop++)
+#ifdef QBMAN_CINH_ONLY
+ shadow[loop] = __raw_readl(s->addr_cinh + offset
+ + loop * 4);
+#else
+ shadow[loop] = __raw_readl(s->addr_cena + offset
+ + loop * 4);
+#endif
+#ifdef QBMAN_CENA_TRACE
+ hexdump(shadow, 64);
+#endif
+ return shadow;
+}
+
+static inline void qbman_cena_invalidate_prefetch(struct qbman_swp_sys *s,
+ uint32_t offset)
+{
+}
+
+ /******************/
+ /* Portal support */
+ /******************/
+
+/* The SWP_CFG portal register is special, in that it is used by the
+ * platform-specific code rather than the platform-independent code in
+ * qbman_portal.c. So use of it is declared locally here. */
+#define QBMAN_CINH_SWP_CFG 0xd00
+
+/* For MC portal use, we always configure with
+ * DQRR_MF is (SWP_CFG,20,3) - DQRR max fill (<- 0x4)
+ * EST is (SWP_CFG,16,3) - EQCR_CI stashing threshold (<- 0x0)
+ * RPM is (SWP_CFG,12,2) - RCR production notification mode (<- 0x3)
+ * DCM is (SWP_CFG,10,2) - DQRR consumption notification mode (<- 0x2)
+ * EPM is (SWP_CFG,8,2) - EQCR production notification mode (<- 0x3)
+ * SD is (SWP_CFG,5,1) - memory stashing drop enable (<- FALSE)
+ * SP is (SWP_CFG,4,1) - memory stashing priority (<- TRUE)
+ * SE is (SWP_CFG,3,1) - memory stashing enable (<- 0x0)
+ * DP is (SWP_CFG,2,1) - dequeue stashing priority (<- TRUE)
+ * DE is (SWP_CFG,1,1) - dequeue stashing enable (<- 0x0)
+ * EP is (SWP_CFG,0,1) - EQCR_CI stashing priority (<- FALSE)
+ */
+static inline uint32_t qbman_set_swp_cfg(uint8_t max_fill, uint8_t wn,
+ uint8_t est, uint8_t rpm, uint8_t dcm,
+ uint8_t epm, int sd, int sp, int se,
+ int dp, int de, int ep)
+{
+ uint32_t reg;
+
+ reg = e32_uint8_t(20, 3, max_fill) | e32_uint8_t(16, 3, est) |
+ e32_uint8_t(12, 2, rpm) | e32_uint8_t(10, 2, dcm) |
+ e32_uint8_t(8, 2, epm) | e32_int(5, 1, sd) |
+ e32_int(4, 1, sp) | e32_int(3, 1, se) | e32_int(2, 1, dp) |
+ e32_int(1, 1, de) | e32_int(0, 1, ep) | e32_uint8_t(14, 1, wn);
+ return reg;
+}
+
+static inline int qbman_swp_sys_init(struct qbman_swp_sys *s,
+ const struct qbman_swp_desc *d)
+{
+ uint32_t reg;
+
+ s->addr_cena = d->cena_bar;
+ s->addr_cinh = d->cinh_bar;
+ s->cena = (void *)valloc(CONFIG_SYS_PAGE_SIZE);
+ memset((void *)s->cena, 0x00, CONFIG_SYS_PAGE_SIZE);
+ if (!s->cena) {
+ printf("Could not allocate page for cena shadow\n");
+ return -1;
+ }
+
+#ifdef QBMAN_CHECKING
+ /* We should never be asked to initialise for a portal that isn't in
+ * the power-on state. (Ie. don't forget to reset portals when they are
+ * decommissioned!)
+ */
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ BUG_ON(reg);
+#endif
+#ifdef QBMAN_CINH_ONLY
+ reg = qbman_set_swp_cfg(4, 1, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0);
+#else
+ reg = qbman_set_swp_cfg(4, 0, 0, 3, 2, 3, 0, 1, 0, 1, 0, 0);
+#endif
+ qbman_cinh_write(s, QBMAN_CINH_SWP_CFG, reg);
+ reg = qbman_cinh_read(s, QBMAN_CINH_SWP_CFG);
+ if (!reg) {
+ printf("The portal is not enabled!\n");
+ free(s->cena);
+ return -1;
+ }
+ return 0;
+}
+
+static inline void qbman_swp_sys_finish(struct qbman_swp_sys *s)
+{
+ free((void *)s->cena);
+}
diff --git a/drivers/net/fsl-mc/dpmng.c b/drivers/net/fsl-mc/dpmng.c
index cc14c7b..01ee112 100644
--- a/drivers/net/fsl-mc/dpmng.c
+++ b/drivers/net/fsl-mc/dpmng.c
@@ -1,4 +1,4 @@
-/* Copyright 2014 Freescale Semiconductor Inc.
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -26,66 +26,3 @@ int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info)
return 0;
}
-
-int dpmng_reset_aiop(struct fsl_mc_io *mc_io, int container_id,
- int aiop_tile_id)
-{
- struct mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_AIOP,
- MC_CMD_PRI_LOW, 0);
- DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
-
-int dpmng_load_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id,
- uint64_t img_iova,
- uint32_t img_size)
-{
- struct mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMNG_CMDID_LOAD_AIOP,
- MC_CMD_PRI_LOW,
- 0);
- DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size,
- img_iova);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
-
-int dpmng_run_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id,
- const struct dpmng_aiop_run_cfg *cfg)
-{
- struct mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RUN_AIOP,
- MC_CMD_PRI_LOW,
- 0);
- DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
-
-int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io)
-{
- struct mc_command cmd = { 0 };
-
- /* prepare command */
- cmd.header = mc_encode_cmd_header(DPMNG_CMDID_RESET_MC_PORTAL,
- MC_CMD_PRI_LOW,
- 0);
-
- /* send command to mc*/
- return mc_send_command(mc_io, &cmd);
-}
diff --git a/drivers/net/fsl-mc/dpni.c b/drivers/net/fsl-mc/dpni.c
new file mode 100644
index 0000000..b384401
--- /dev/null
+++ b/drivers/net/fsl-mc/dpni.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dpni.h>
+
+int dpni_open(struct fsl_mc_io *mc_io, int dpni_id, uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_OPEN,
+ MC_CMD_PRI_LOW, 0);
+ DPNI_CMD_OPEN(cmd, dpni_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dpni_close(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_CLOSE,
+ MC_CMD_PRI_HIGH, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_POOLS,
+ MC_CMD_PRI_LOW,
+ token);
+ DPNI_CMD_SET_POOLS(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_enable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ENABLE,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_disable(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_DISABLE,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_reset(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_RESET,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_ATTR(cmd, attr);
+
+ return 0;
+}
+
+int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_RX_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_RX_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_rx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_RX_BUFFER_LAYOUT(cmd, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_tx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_TX_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_tx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_TX_BUFFER_LAYOUT(cmd, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_CONF_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_TX_CONF_BUFFER_LAYOUT(cmd, layout);
+
+ return 0;
+}
+
+int dpni_set_tx_conf_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONF_BUFFER_LAYOUT,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_TX_CONF_BUFFER_LAYOUT(cmd, layout);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_qdid(struct fsl_mc_io *mc_io, uint16_t token, uint16_t *qdid)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_QDID,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_QDID(cmd, *qdid);
+
+ return 0;
+}
+
+int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t *data_offset)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_DATA_OFFSET,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_TX_DATA_OFFSET(cmd, *data_offset);
+
+ return 0;
+}
+
+int dpni_get_counter(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ enum dpni_counter counter,
+ uint64_t *value)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_COUNTER,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_GET_COUNTER(cmd, counter);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_COUNTER(cmd, *value);
+
+ return 0;
+}
+
+int dpni_set_counter(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ enum dpni_counter counter,
+ uint64_t value)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_COUNTER,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_COUNTER(cmd, counter, value);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_link_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_LINK_CFG(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_link_state *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_STATE,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_LINK_STATE(cmd, state);
+
+ return 0;
+}
+
+
+int dpni_set_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_PRIM_MAC,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_primary_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_PRIM_MAC,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr);
+
+ return 0;
+}
+
+int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_ADD_MAC_ADDR,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_ADD_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6])
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_REMOVE_MAC_ADDR,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_REMOVE_MAC_ADDR(cmd, mac_addr);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_set_tx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t *flow_id,
+ const struct dpni_tx_flow_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_FLOW,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_TX_FLOW(cmd, *flow_id, cfg);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_SET_TX_FLOW(cmd, *flow_id);
+
+ return 0;
+}
+
+int dpni_get_tx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t flow_id,
+ struct dpni_tx_flow_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_FLOW,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_GET_TX_FLOW(cmd, flow_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_TX_FLOW(cmd, attr);
+
+ return 0;
+}
+
+int dpni_set_rx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t tc_id,
+ uint16_t flow_id,
+ const struct dpni_queue_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_RX_FLOW,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_SET_RX_FLOW(cmd, tc_id, flow_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_rx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t tc_id,
+ uint16_t flow_id,
+ struct dpni_queue_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_RX_FLOW,
+ MC_CMD_PRI_LOW, token);
+ DPNI_CMD_GET_RX_FLOW(cmd, tc_id, flow_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPNI_RSP_GET_RX_FLOW(cmd, attr);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/dprc.c b/drivers/net/fsl-mc/dprc.c
new file mode 100644
index 0000000..d481200
--- /dev/null
+++ b/drivers/net/fsl-mc/dprc.c
@@ -0,0 +1,283 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dprc.h>
+
+int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONT_ID,
+ MC_CMD_PRI_LOW, 0);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_CONTAINER_ID(cmd, *container_id);
+
+ return 0;
+}
+
+int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_OPEN, MC_CMD_PRI_LOW,
+ 0);
+ DPRC_CMD_OPEN(cmd, container_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
+
+ return 0;
+}
+
+int dprc_close(struct fsl_mc_io *mc_io, uint16_t token)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_CLOSE, MC_CMD_PRI_HIGH,
+ token);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_reset_container(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ int child_container_id)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_RESET_CONT,
+ MC_CMD_PRI_LOW, token);
+ DPRC_CMD_RESET_CONTAINER(cmd, child_container_id);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dprc_attributes *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_ATTR,
+ MC_CMD_PRI_LOW,
+ token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_ATTRIBUTES(cmd, attr);
+
+ return 0;
+}
+
+int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_COUNT,
+ MC_CMD_PRI_LOW, token);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_OBJ_COUNT(cmd, *obj_count);
+
+ return 0;
+}
+
+int dprc_get_obj(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ int obj_index,
+ struct dprc_obj_desc *obj_desc)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ,
+ MC_CMD_PRI_LOW,
+ token);
+ DPRC_CMD_GET_OBJ(cmd, obj_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_OBJ(cmd, obj_desc);
+
+ return 0;
+}
+
+int dprc_get_res_count(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *type,
+ int *res_count)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ *res_count = 0;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_COUNT,
+ MC_CMD_PRI_LOW, token);
+ DPRC_CMD_GET_RES_COUNT(cmd, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_RES_COUNT(cmd, *res_count);
+
+ return 0;
+}
+
+int dprc_get_res_ids(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *type,
+ struct dprc_res_ids_range_desc *range_desc)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_RES_IDS,
+ MC_CMD_PRI_LOW, token);
+ DPRC_CMD_GET_RES_IDS(cmd, range_desc, type);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_RES_IDS(cmd, range_desc);
+
+ return 0;
+}
+
+int dprc_get_obj_region(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *obj_type,
+ int obj_id,
+ uint8_t region_index,
+ struct dprc_region_desc *region_desc)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_OBJ_REG,
+ MC_CMD_PRI_LOW, token);
+ DPRC_CMD_GET_OBJ_REGION(cmd, obj_type, obj_id, region_index);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_OBJ_REGION(cmd, region_desc);
+
+ return 0;
+}
+
+int dprc_connect(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint1,
+ const struct dprc_endpoint *endpoint2)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_CONNECT,
+ MC_CMD_PRI_LOW,
+ token);
+ DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_disconnect(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_DISCONNECT,
+ MC_CMD_PRI_LOW,
+ token);
+ DPRC_CMD_DISCONNECT(cmd, endpoint);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dprc_get_connection(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint1,
+ struct dprc_endpoint *endpoint2,
+ int *state)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_CONNECTION,
+ MC_CMD_PRI_LOW,
+ token);
+ DPRC_CMD_GET_CONNECTION(cmd, endpoint1);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ /* retrieve response parameters */
+ DPRC_RSP_GET_CONNECTION(cmd, endpoint2, *state);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/fsl_dpmng_cmd.h b/drivers/net/fsl-mc/fsl_dpmng_cmd.h
index c9fe021..33f84f3 100644
--- a/drivers/net/fsl-mc/fsl_dpmng_cmd.h
+++ b/drivers/net/fsl-mc/fsl_dpmng_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright 2014 Freescale Semiconductor Inc.
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -7,10 +7,6 @@
/* Command IDs */
#define DPMNG_CMDID_GET_VERSION 0x831
-#define DPMNG_CMDID_RESET_AIOP 0x832
-#define DPMNG_CMDID_LOAD_AIOP 0x833
-#define DPMNG_CMDID_RUN_AIOP 0x834
-#define DPMNG_CMDID_RESET_MC_PORTAL 0x835
/* cmd, param, offset, width, type, arg_name */
#define DPMNG_RSP_GET_VERSION(cmd, mc_ver_info) \
@@ -20,30 +16,4 @@ do { \
MC_RSP_OP(cmd, 1, 0, 32, uint32_t, mc_ver_info->minor); \
} while (0)
-/* cmd, param, offset, width, type, arg_name */
-#define DPMNG_CMD_RESET_AIOP(cmd, container_id, aiop_tile_id) \
-do { \
- MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
- MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
-} while (0)
-
-/* cmd, param, offset, width, type, arg_name */
-#define DPMNG_CMD_LOAD_AIOP(cmd, container_id, aiop_tile_id, img_size, \
- img_iova) \
-do { \
- MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
- MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
- MC_CMD_OP(cmd, 1, 0, 32, uint32_t, img_size); \
- MC_CMD_OP(cmd, 2, 0, 64, uint64_t, img_iova); \
-} while (0)
-
-/* cmd, param, offset, width, type, arg_name */
-#define DPMNG_CMD_RUN_AIOP(cmd, container_id, aiop_tile_id, cfg) \
-do { \
- MC_CMD_OP(cmd, 0, 0, 32, int, aiop_tile_id); \
- MC_CMD_OP(cmd, 0, 32, 32, int, container_id); \
- MC_CMD_OP(cmd, 1, 0, 32, uint32_t, cfg->cores_mask); \
- MC_CMD_OP(cmd, 2, 0, 64, uint64_t, cfg->options); \
-} while (0)
-
#endif /* __FSL_DPMNG_CMD_H */
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index 74b0085..c5c44bc 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -3,16 +3,75 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
-
#include <errno.h>
#include <asm/io.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>
+
+#define MC_RAM_BASE_ADDR_ALIGNMENT (512UL * 1024 * 1024)
+#define MC_RAM_BASE_ADDR_ALIGNMENT_MASK (~(MC_RAM_BASE_ADDR_ALIGNMENT - 1))
+#define MC_RAM_SIZE_ALIGNMENT (256UL * 1024 * 1024)
+
+#define MC_MEM_SIZE_ENV_VAR "mcmemsize"
+#define MC_BOOT_TIMEOUT_ENV_VAR "mcboottimeout"
DECLARE_GLOBAL_DATA_PTR;
static int mc_boot_status;
+struct fsl_mc_io *dflt_mc_io = NULL;
+uint16_t dflt_dprc_handle = 0;
+struct fsl_dpbp_obj *dflt_dpbp = NULL;
+struct fsl_dpio_obj *dflt_dpio = NULL;
+uint16_t dflt_dpio_handle = 0;
+
+#ifdef DEBUG
+void dump_ram_words(const char *title, void *addr)
+{
+ int i;
+ uint32_t *words = addr;
+
+ printf("Dumping beginning of %s (%p):\n", title, addr);
+ for (i = 0; i < 16; i++)
+ printf("%#x ", words[i]);
+ printf("\n");
+}
+
+void dump_mc_ccsr_regs(struct mc_ccsr_registers __iomem *mc_ccsr_regs)
+{
+ printf("MC CCSR registers:\n"
+ "reg_gcr1 %#x\n"
+ "reg_gsr %#x\n"
+ "reg_sicbalr %#x\n"
+ "reg_sicbahr %#x\n"
+ "reg_sicapr %#x\n"
+ "reg_mcfbalr %#x\n"
+ "reg_mcfbahr %#x\n"
+ "reg_mcfapr %#x\n"
+ "reg_psr %#x\n",
+ mc_ccsr_regs->reg_gcr1,
+ mc_ccsr_regs->reg_gsr,
+ mc_ccsr_regs->reg_sicbalr,
+ mc_ccsr_regs->reg_sicbahr,
+ mc_ccsr_regs->reg_sicapr,
+ mc_ccsr_regs->reg_mcfbalr,
+ mc_ccsr_regs->reg_mcfbahr,
+ mc_ccsr_regs->reg_mcfapr,
+ mc_ccsr_regs->reg_psr);
+}
+#else
+
+#define dump_ram_words(title, addr)
+#define dump_mc_ccsr_regs(mc_ccsr_regs)
+
+#endif /* DEBUG */
+
+#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
/**
* Copying MC firmware or DPL image to DDR
*/
@@ -21,6 +80,7 @@ static int mc_copy_image(const char *title,
{
debug("%s copied to address %p\n", title, (void *)mc_ram_addr);
memcpy((void *)mc_ram_addr, (void *)image_addr, image_size);
+ flush_dcache_range(mc_ram_addr, mc_ram_addr + image_size);
return 0;
}
@@ -82,23 +142,254 @@ int parse_mc_firmware_fit_image(const void **raw_image_addr,
return 0;
}
+#endif
+
+/*
+ * Calculates the values to be used to specify the address range
+ * for the MC private DRAM block, in the MCFBALR/MCFBAHR registers.
+ * It returns the highest 512MB-aligned address within the given
+ * address range, in '*aligned_base_addr', and the number of 256 MiB
+ * blocks in it, in 'num_256mb_blocks'.
+ */
+static int calculate_mc_private_ram_params(u64 mc_private_ram_start_addr,
+ size_t mc_ram_size,
+ u64 *aligned_base_addr,
+ u8 *num_256mb_blocks)
+{
+ u64 addr;
+ u16 num_blocks;
+
+ if (mc_ram_size % MC_RAM_SIZE_ALIGNMENT != 0) {
+ printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
+ mc_ram_size);
+ return -EINVAL;
+ }
+
+ num_blocks = mc_ram_size / MC_RAM_SIZE_ALIGNMENT;
+ if (num_blocks < 1 || num_blocks > 0xff) {
+ printf("fsl-mc: ERROR: invalid MC private RAM size (%lu)\n",
+ mc_ram_size);
+ return -EINVAL;
+ }
+
+ addr = (mc_private_ram_start_addr + mc_ram_size - 1) &
+ MC_RAM_BASE_ADDR_ALIGNMENT_MASK;
+
+ if (addr < mc_private_ram_start_addr) {
+ printf("fsl-mc: ERROR: bad start address %#llx\n",
+ mc_private_ram_start_addr);
+ return -EFAULT;
+ }
+
+ *aligned_base_addr = addr;
+ *num_256mb_blocks = num_blocks;
+ return 0;
+}
+
+static int load_mc_dpc(u64 mc_ram_addr, size_t mc_ram_size)
+{
+ u64 mc_dpc_offset;
+#ifndef CONFIG_SYS_LS_MC_DPC_IN_DDR
+ int error;
+ void *dpc_fdt_hdr;
+ int dpc_size;
+#endif
+
+#ifdef CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET
+ BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET & 0x3) != 0 ||
+ CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET > 0xffffffff);
+
+ mc_dpc_offset = CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET;
+#else
+#error "CONFIG_SYS_LS_MC_DRAM_DPC_OFFSET not defined"
+#endif
+
+ /*
+ * Load the MC DPC blob in the MC private DRAM block:
+ */
+#ifdef CONFIG_SYS_LS_MC_DPC_IN_DDR
+ printf("MC DPC is preloaded to %#llx\n", mc_ram_addr + mc_dpc_offset);
+#else
+ /*
+ * Get address and size of the DPC blob stored in flash:
+ */
+#ifdef CONFIG_SYS_LS_MC_DPC_IN_NOR
+ dpc_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPC_ADDR;
+#else
+#error "No CONFIG_SYS_LS_MC_DPC_IN_xxx defined"
+#endif
+
+ error = fdt_check_header(dpc_fdt_hdr);
+ if (error != 0) {
+ /*
+ * 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");
+ 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",
+ dpc_size);
+ return -EINVAL;
+ }
+
+ mc_copy_image("MC DPC blob",
+ (u64)dpc_fdt_hdr, dpc_size, mc_ram_addr + mc_dpc_offset);
+#endif /* not defined CONFIG_SYS_LS_MC_DPC_IN_DDR */
+
+ dump_ram_words("DPC", (void *)(mc_ram_addr + mc_dpc_offset));
+ return 0;
+}
-int mc_init(bd_t *bis)
+static int load_mc_dpl(u64 mc_ram_addr, size_t mc_ram_size)
+{
+ u64 mc_dpl_offset;
+#ifndef CONFIG_SYS_LS_MC_DPL_IN_DDR
+ int error;
+ void *dpl_fdt_hdr;
+ int dpl_size;
+#endif
+
+#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
+ BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
+ CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
+
+ mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
+#else
+#error "CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET not defined"
+#endif
+
+ /*
+ * Load the MC DPL blob in the MC private DRAM block:
+ */
+#ifdef CONFIG_SYS_LS_MC_DPL_IN_DDR
+ printf("MC DPL is preloaded to %#llx\n", mc_ram_addr + mc_dpl_offset);
+#else
+ /*
+ * Get address and size of the DPL blob stored in flash:
+ */
+#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
+ dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
+#else
+#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
+#endif
+
+ error = fdt_check_header(dpl_fdt_hdr);
+ if (error != 0) {
+ printf("fsl-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",
+ dpl_size);
+ return -EINVAL;
+ }
+
+ mc_copy_image("MC DPL blob",
+ (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
+#endif /* not defined CONFIG_SYS_LS_MC_DPL_IN_DDR */
+
+ dump_ram_words("DPL", (void *)(mc_ram_addr + mc_dpl_offset));
+ return 0;
+}
+
+/**
+ * Return the MC boot timeout value in milliseconds
+ */
+static unsigned long get_mc_boot_timeout_ms(void)
+{
+ unsigned long timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS;
+
+ char *timeout_ms_env_var = getenv(MC_BOOT_TIMEOUT_ENV_VAR);
+
+ if (timeout_ms_env_var) {
+ timeout_ms = simple_strtoul(timeout_ms_env_var, NULL, 10);
+ if (timeout_ms == 0) {
+ printf("fsl-mc: WARNING: Invalid value for \'"
+ MC_BOOT_TIMEOUT_ENV_VAR
+ "\' environment variable: %lu\n",
+ timeout_ms);
+
+ timeout_ms = CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS;
+ }
+ }
+
+ return timeout_ms;
+}
+
+static int wait_for_mc(bool booting_mc, u32 *final_reg_gsr)
+{
+ u32 reg_gsr;
+ u32 mc_fw_boot_status;
+ unsigned long timeout_ms = get_mc_boot_timeout_ms();
+ 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 */
+ reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
+ mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
+ if (mc_fw_boot_status & 0x1)
+ break;
+
+ timeout_ms--;
+ if (timeout_ms == 0)
+ break;
+ }
+
+ 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");
+
+ /* TODO: Get an error status from an MC CCSR register */
+ return -ETIMEDOUT;
+ }
+
+ if (mc_fw_boot_status != 0x1) {
+ /*
+ * TODO: Identify critical errors from the GSR register's FS
+ * field and for those errors, set error to -ENODEV or other
+ * 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);
+ }
+ }
+
+ *final_reg_gsr = reg_gsr;
+ return 0;
+}
+
+int mc_init(void)
{
int error = 0;
- int timeout = 200000;
+ int portal_id = 0;
struct mc_ccsr_registers __iomem *mc_ccsr_regs = MC_CCSR_BASE_ADDR;
u64 mc_ram_addr;
- u64 mc_dpl_offset;
u32 reg_gsr;
- u32 mc_fw_boot_status;
- void *dpl_fdt_hdr;
- int dpl_size;
+ u32 reg_mcfbalr;
+#ifndef CONFIG_SYS_LS_MC_FW_IN_DDR
const void *raw_image_addr;
size_t raw_image_size = 0;
- struct fsl_mc_io mc_io;
- int portal_id;
+#endif
struct mc_version mc_ver_info;
+ u64 mc_ram_aligned_base_addr;
+ u8 mc_ram_num_256mb_blocks;
+ size_t mc_ram_size = mc_get_dram_block_size();
/*
* The MC private DRAM block was already carved at the end of DRAM
@@ -112,6 +403,20 @@ int mc_init(bd_t *bis)
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,
+ &mc_ram_num_256mb_blocks);
+ if (error != 0)
+ goto out;
+
/*
* Management Complex cores should be held at reset out of POR.
* U-boot should be the first software to touch MC. To be safe,
@@ -127,6 +432,9 @@ int mc_init(bd_t *bis)
out_le32(&mc_ccsr_regs->reg_gcr1, 0);
dmb();
+#ifdef CONFIG_SYS_LS_MC_FW_IN_DDR
+ printf("MC firmware is preloaded to %#llx\n", mc_ram_addr);
+#else
error = parse_mc_firmware_fit_image(&raw_image_addr, &raw_image_size);
if (error != 0)
goto out;
@@ -135,83 +443,34 @@ int mc_init(bd_t *bis)
*/
mc_copy_image("MC Firmware",
(u64)raw_image_addr, raw_image_size, mc_ram_addr);
-
- /*
- * Get address and size of the DPL blob stored in flash:
- */
-#ifdef CONFIG_SYS_LS_MC_DPL_IN_NOR
- dpl_fdt_hdr = (void *)CONFIG_SYS_LS_MC_DPL_ADDR;
-#else
-#error "No CONFIG_SYS_LS_MC_DPL_IN_xxx defined"
#endif
+ dump_ram_words("firmware", (void *)mc_ram_addr);
- error = fdt_check_header(dpl_fdt_hdr);
- if (error != 0) {
- printf("fsl-mc: ERROR: Bad DPL image (bad header)\n");
- goto out;
- }
-
- 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",
- dpl_size);
- error = -EINVAL;
+ error = load_mc_dpc(mc_ram_addr, mc_ram_size);
+ if (error != 0)
goto out;
- }
- /*
- * Calculate offset in the MC private DRAM block at which the MC DPL
- * blob is to be placed:
- */
-#ifdef CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET
- BUILD_BUG_ON((CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET & 0x3) != 0 ||
- CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET > 0xffffffff);
-
- mc_dpl_offset = CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET;
-#else
- mc_dpl_offset = mc_get_dram_block_size() -
- roundup(CONFIG_SYS_LS_MC_DPL_MAX_LENGTH, 4096);
-
- if ((mc_dpl_offset & 0x3) != 0 || mc_dpl_offset > 0xffffffff) {
- printf("%s: Invalid MC DPL offset: %llu\n",
- __func__, mc_dpl_offset);
- error = -EINVAL;
+ error = load_mc_dpl(mc_ram_addr, mc_ram_size);
+ if (error != 0)
goto out;
- }
-#endif
-
- /*
- * Load the MC DPL blob at the far end of the MC private DRAM block:
- *
- * TODO: Should we place the DPL at a different location to match
- * assumptions of MC firmware about its memory layout?
- */
- mc_copy_image("MC DPL blob",
- (u64)dpl_fdt_hdr, dpl_size, mc_ram_addr + mc_dpl_offset);
debug("mc_ccsr_regs %p\n", mc_ccsr_regs);
+ dump_mc_ccsr_regs(mc_ccsr_regs);
/*
- * Tell MC where the MC Firmware image was loaded in DDR:
+ * Tell MC what is the address range of the DRAM block assigned to it:
*/
- out_le32(&mc_ccsr_regs->reg_mcfbalr, (u32)mc_ram_addr);
- out_le32(&mc_ccsr_regs->reg_mcfbahr, (u32)((u64)mc_ram_addr >> 32));
+ reg_mcfbalr = (u32)mc_ram_aligned_base_addr |
+ (mc_ram_num_256mb_blocks - 1);
+ 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);
/*
- * Tell MC where the DPL blob was loaded in DDR, by indicating
- * its offset relative to the beginning of the DDR block
- * allocated to the MC firmware. The MC firmware is responsible
- * for checking that there is no overlap between the DPL blob
- * and the runtime heap and stack of the MC firmware itself.
- *
- * NOTE: bits [31:2] of this offset need to be stored in bits [29:0] of
- * the GSR MC CCSR register. So, this offset is assumed to be 4-byte
- * aligned.
- * Care must be taken not to write 1s into bits 31 and 30 of the GSR in
- * this case as the SoC COP or PIC will be signaled.
+ * Tell the MC that we want delayed DPL deployment.
*/
- out_le32(&mc_ccsr_regs->reg_gsr, (u32)(mc_dpl_offset >> 2));
+ out_le32(&mc_ccsr_regs->reg_gsr, 0xDD00);
printf("\nfsl-mc: Booting Management Complex ...\n");
@@ -219,38 +478,9 @@ int mc_init(bd_t *bis)
* Deassert reset and release MC core 0 to run
*/
out_le32(&mc_ccsr_regs->reg_gcr1, GCR1_P1_DE_RST | GCR1_M_ALL_DE_RST);
- dmb();
- debug("Polling mc_ccsr_regs->reg_gsr ...\n");
-
- for (;;) {
- reg_gsr = in_le32(&mc_ccsr_regs->reg_gsr);
- mc_fw_boot_status = (reg_gsr & GSR_FS_MASK);
- if (mc_fw_boot_status & 0x1)
- break;
-
- udelay(1000); /* throttle polling */
- if (timeout-- <= 0)
- break;
- }
-
- if (timeout <= 0) {
- printf("fsl-mc: timeout booting management complex firmware\n");
-
- /* TODO: Get an error status from an MC CCSR register */
- error = -ETIMEDOUT;
+ error = wait_for_mc(true, &reg_gsr);
+ if (error != 0)
goto out;
- }
-
- if (mc_fw_boot_status != 0x1) {
- /*
- * TODO: Identify critical errors from the GSR register's FS
- * field and for those errors, set error to -ENODEV or other
- * appropriate errno, so that the status property is set to
- * failure in the fsl,dprc device tree node.
- */
- printf("fsl-mc: WARNING: Firmware booted with error (GSR: %#x)\n",
- reg_gsr);
- }
/*
* TODO: need to obtain the portal_id for the root container from the
@@ -259,13 +489,20 @@ int mc_init(bd_t *bis)
portal_id = 0;
/*
- * Check that the MC firmware is responding portal commands:
+ * Initialize the global default MC portal
+ * And check that the MC firmware is responding portal commands:
*/
- mc_io.mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
+ dflt_mc_io = (struct fsl_mc_io *)malloc(sizeof(struct fsl_mc_io));
+ if (!dflt_mc_io) {
+ printf(" No memory: malloc() failed\n");
+ return -ENOMEM;
+ }
+
+ dflt_mc_io->mmio_regs = SOC_MC_PORTAL_ADDR(portal_id);
debug("Checking access to MC portal of root DPRC container (portal_id %d, portal physical addr %p)\n",
- portal_id, mc_io.mmio_regs);
+ portal_id, dflt_mc_io->mmio_regs);
- error = mc_get_version(&mc_io, &mc_ver_info);
+ error = mc_get_version(dflt_mc_io, &mc_ver_info);
if (error != 0) {
printf("fsl-mc: ERROR: Firmware version check failed (error: %d)\n",
error);
@@ -282,7 +519,16 @@ int mc_init(bd_t *bis)
printf("fsl-mc: Management Complex booted (version: %d.%d.%d, boot status: %#x)\n",
mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision,
- mc_fw_boot_status);
+ reg_gsr & GSR_FS_MASK);
+
+ /*
+ * Tell the MC to deploy the DPL:
+ */
+ out_le32(&mc_ccsr_regs->reg_gsr, 0x0);
+ printf("\nfsl-mc: Deploying data path layout ...\n");
+ error = wait_for_mc(false, &reg_gsr);
+ if (error != 0)
+ goto out;
out:
if (error != 0)
mc_boot_status = -error;
@@ -299,12 +545,242 @@ int get_mc_boot_status(void)
/**
* Return the actual size of the MC private DRAM block.
- *
- * NOTE: For now this function always returns the minimum required size,
- * However, in the future, the actual size may be obtained from an environment
- * variable.
*/
unsigned long mc_get_dram_block_size(void)
{
- return CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
+ unsigned long dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
+
+ char *dram_block_size_env_var = getenv(MC_MEM_SIZE_ENV_VAR);
+
+ if (dram_block_size_env_var) {
+ dram_block_size = simple_strtoul(dram_block_size_env_var, NULL,
+ 10);
+
+ if (dram_block_size < CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE) {
+ printf("fsl-mc: WARNING: Invalid value for \'"
+ MC_MEM_SIZE_ENV_VAR
+ "\' environment variable: %lu\n",
+ dram_block_size);
+
+ dram_block_size = CONFIG_SYS_LS_MC_DRAM_BLOCK_MIN_SIZE;
+ }
+ }
+
+ return dram_block_size;
+}
+
+int dpio_init(struct dprc_obj_desc obj_desc)
+{
+ struct qbman_swp_desc p_des;
+ struct dpio_attr attr;
+ int err = 0;
+
+ dflt_dpio = (struct fsl_dpio_obj *)malloc(sizeof(struct fsl_dpio_obj));
+ if (!dflt_dpio) {
+ printf(" No memory: malloc() failed\n");
+ return -ENOMEM;
+ }
+
+ dflt_dpio->dpio_id = obj_desc.id;
+
+ err = dpio_open(dflt_mc_io, obj_desc.id, &dflt_dpio_handle);
+ if (err) {
+ printf("dpio_open() failed\n");
+ goto err_open;
+ }
+
+ err = dpio_get_attributes(dflt_mc_io, dflt_dpio_handle, &attr);
+ if (err) {
+ printf("dpio_get_attributes() failed %d\n", err);
+ goto err_get_attr;
+ }
+
+ err = dpio_enable(dflt_mc_io, dflt_dpio_handle);
+ if (err) {
+ 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,
+ 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;
+
+ dflt_dpio->sw_portal = qbman_swp_init(&p_des);
+ if (dflt_dpio->sw_portal == NULL) {
+ printf("qbman_swp_init() failed\n");
+ goto err_get_swp_init;
+ }
+ return 0;
+
+err_get_swp_init:
+err_get_enable:
+ dpio_disable(dflt_mc_io, dflt_dpio_handle);
+err_get_attr:
+ dpio_close(dflt_mc_io, dflt_dpio_handle);
+err_open:
+ free(dflt_dpio);
+ return err;
+}
+
+int dpbp_init(struct dprc_obj_desc obj_desc)
+{
+ dflt_dpbp = (struct fsl_dpbp_obj *)malloc(sizeof(struct fsl_dpbp_obj));
+ if (!dflt_dpbp) {
+ printf(" No memory: malloc() failed\n");
+ return -ENOMEM;
+ }
+ dflt_dpbp->dpbp_attr.id = obj_desc.id;
+
+ return 0;
+}
+
+int dprc_init_container_obj(struct dprc_obj_desc obj_desc, uint16_t dprc_handle)
+{
+ int error = 0, state = 0;
+ struct dprc_endpoint dpni_endpoint, dpmac_endpoint;
+ if (!strcmp(obj_desc.type, "dpbp")) {
+ if (!dflt_dpbp) {
+ error = dpbp_init(obj_desc);
+ if (error < 0)
+ printf("dpbp_init failed\n");
+ }
+ } else if (!strcmp(obj_desc.type, "dpio")) {
+ if (!dflt_dpio) {
+ error = dpio_init(obj_desc);
+ if (error < 0)
+ printf("dpio_init failed\n");
+ }
+ } else if (!strcmp(obj_desc.type, "dpni")) {
+ strcpy(dpni_endpoint.type, obj_desc.type);
+ dpni_endpoint.id = obj_desc.id;
+ error = dprc_get_connection(dflt_mc_io, dprc_handle,
+ &dpni_endpoint, &dpmac_endpoint, &state);
+ if (!strcmp(dpmac_endpoint.type, "dpmac"))
+ error = ldpaa_eth_init(obj_desc);
+ if (error < 0)
+ printf("ldpaa_eth_init failed\n");
+ }
+
+ return error;
+}
+
+int dprc_scan_container_obj(uint16_t dprc_handle, char *obj_type, int i)
+{
+ int error = 0;
+ struct dprc_obj_desc obj_desc;
+
+ memset((void *)&obj_desc, 0x00, sizeof(struct dprc_obj_desc));
+
+ error = dprc_get_obj(dflt_mc_io, dprc_handle,
+ i, &obj_desc);
+ if (error < 0) {
+ printf("dprc_get_obj(i=%d) failed: %d\n",
+ i, error);
+ return error;
+ }
+
+ if (!strcmp(obj_desc.type, obj_type)) {
+ debug("Discovered object: type %s, id %d, req %s\n",
+ obj_desc.type, obj_desc.id, obj_type);
+
+ error = dprc_init_container_obj(obj_desc, dprc_handle);
+ if (error < 0) {
+ printf("dprc_init_container_obj(i=%d) failed: %d\n",
+ i, error);
+ return error;
+ }
+ }
+
+ return error;
+}
+
+int fsl_mc_ldpaa_init(bd_t *bis)
+{
+ int i, error = 0;
+ int dprc_opened = 0, container_id;
+ int num_child_objects = 0;
+
+ error = mc_init();
+ if (error < 0)
+ goto error;
+
+ error = dprc_get_container_id(dflt_mc_io, &container_id);
+ if (error < 0) {
+ printf("dprc_get_container_id() failed: %d\n", error);
+ goto error;
+ }
+
+ debug("fsl-mc: Container id=0x%x\n", container_id);
+
+ error = dprc_open(dflt_mc_io, container_id, &dflt_dprc_handle);
+ if (error < 0) {
+ printf("dprc_open() failed: %d\n", error);
+ goto error;
+ }
+ dprc_opened = true;
+
+ error = dprc_get_obj_count(dflt_mc_io,
+ dflt_dprc_handle,
+ &num_child_objects);
+ if (error < 0) {
+ printf("dprc_get_obj_count() failed: %d\n", error);
+ goto error;
+ }
+ debug("Total child in container %d = %d\n", container_id,
+ num_child_objects);
+
+ if (num_child_objects != 0) {
+ /*
+ * Discover objects currently in the DPRC container in the MC:
+ */
+ for (i = 0; i < num_child_objects; i++)
+ error = dprc_scan_container_obj(dflt_dprc_handle,
+ "dpbp", i);
+
+ for (i = 0; i < num_child_objects; i++)
+ error = dprc_scan_container_obj(dflt_dprc_handle,
+ "dpio", i);
+
+ for (i = 0; i < num_child_objects; i++)
+ error = dprc_scan_container_obj(dflt_dprc_handle,
+ "dpni", i);
+ }
+error:
+ if (dprc_opened)
+ dprc_close(dflt_mc_io, dflt_dprc_handle);
+
+ return error;
+}
+
+void fsl_mc_ldpaa_exit(bd_t *bis)
+{
+ int err;
+
+ if (get_mc_boot_status() == 0) {
+ err = dpio_disable(dflt_mc_io, dflt_dpio_handle);
+ if (err < 0) {
+ printf("dpio_disable() failed: %d\n", err);
+ return;
+ }
+ err = dpio_reset(dflt_mc_io, dflt_dpio_handle);
+ if (err < 0) {
+ printf("dpio_reset() failed: %d\n", err);
+ return;
+ }
+ err = dpio_close(dflt_mc_io, dflt_dpio_handle);
+ if (err < 0) {
+ printf("dpio_close() failed: %d\n", err);
+ return;
+ }
+
+ free(dflt_dpio);
+ free(dflt_dpbp);
+ }
+
+ if (dflt_mc_io)
+ free(dflt_mc_io);
}
diff --git a/drivers/net/fsl-mc/mc_sys.c b/drivers/net/fsl-mc/mc_sys.c
index 7c8e003..3fc1f98 100644
--- a/drivers/net/fsl-mc/mc_sys.c
+++ b/drivers/net/fsl-mc/mc_sys.c
@@ -1,7 +1,7 @@
/*
* Freescale Layerscape MC I/O wrapper
*
- * Copyright (C) 2014 Freescale Semiconductor, Inc.
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
* Author: German Rivera <German.Rivera@freescale.com>
*
* SPDX-License-Identifier: GPL-2.0+
@@ -32,7 +32,7 @@ int mc_send_command(struct fsl_mc_io *mc_io,
struct mc_command *cmd)
{
enum mc_cmd_status status;
- int timeout = 2000;
+ int timeout = 6000;
mc_write_command(mc_io->mmio_regs, cmd);
@@ -52,7 +52,7 @@ int mc_send_command(struct fsl_mc_io *mc_io,
if (status != MC_CMD_STATUS_OK) {
printf("Error: MC command failed (portal: %p, obj handle: %#x, command: %#x, status: %#x)\n",
mc_io->mmio_regs,
- (unsigned int)MC_CMD_HDR_READ_AUTHID(cmd->header),
+ (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header),
(unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header),
(unsigned int)status);
diff --git a/drivers/net/ldpaa_eth/Makefile b/drivers/net/ldpaa_eth/Makefile
new file mode 100644
index 0000000..c37633f
--- /dev/null
+++ b/drivers/net/ldpaa_eth/Makefile
@@ -0,0 +1,9 @@
+#
+# Copyright 2014 Freescale Semiconductor, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += ldpaa_wriop.o
+obj-y += ldpaa_eth.o
+obj-$(CONFIG_LS2085A) += ls2085a.o
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
new file mode 100644
index 0000000..d4be1ba
--- /dev/null
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <malloc.h>
+#include <net.h>
+#include <hwconfig.h>
+#include <phy.h>
+#include <linux/compat.h>
+
+#include "ldpaa_eth.h"
+
+#undef CONFIG_PHYLIB
+static int init_phy(struct eth_device *dev)
+{
+ /*TODO for external PHY */
+
+ return 0;
+}
+
+static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
+ const struct dpaa_fd *fd)
+{
+ u64 fd_addr;
+ uint16_t fd_offset;
+ uint32_t fd_length;
+ 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);
+ fd_offset = ldpaa_fd_get_offset(fd);
+ fd_length = ldpaa_fd_get_len(fd);
+
+ debug("Rx frame:data addr=0x%p size=0x%x\n", (u64 *)fd_addr, fd_length);
+
+ if (fd->simple.frc & LDPAA_FD_FRC_FASV) {
+ /* Read the frame annotation status word and check for errors */
+ fas = (struct ldpaa_fas *)
+ ((uint8_t *)(fd_addr) +
+ priv->buf_layout.private_data_size);
+ status = le32_to_cpu(fas->status);
+ if (status & LDPAA_ETH_RX_ERR_MASK) {
+ printf("Rx frame error(s): 0x%08x\n",
+ status & LDPAA_ETH_RX_ERR_MASK);
+ goto error;
+ } else if (status & LDPAA_ETH_RX_UNSUPP_MASK) {
+ printf("Unsupported feature in bitmask: 0x%08x\n",
+ status & LDPAA_ETH_RX_UNSUPP_MASK);
+ goto error;
+ }
+ }
+
+ debug("Rx frame: To Upper layer\n");
+ net_process_received_packet((uint8_t *)(fd_addr) + fd_offset,
+ fd_length);
+
+error:
+ 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);
+ do {
+ /* Release buffer into the QBMAN */
+ err = qbman_swp_release(swp, &releasedesc, &fd_addr, 1);
+ } while (err == -EBUSY);
+ return;
+}
+
+static int ldpaa_eth_pull_dequeue_rx(struct eth_device *dev)
+{
+ 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;
+ 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->rx_dflt_fqid);
+
+ err = qbman_swp_pull(swp, &pulldesc);
+ if (err < 0) {
+ printf("Dequeue 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 RX frames:");
+ debug("No frame delivered\n");
+
+ qbman_swp_dqrr_consume(swp, dq);
+ break;
+ }
+
+ fd = ldpaa_dq_fd(dq);
+
+ /* Obtain FD and process it */
+ 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);
+ break;
+ }
+ }
+
+ return err;
+}
+
+static int ldpaa_eth_tx(struct eth_device *net_dev, void *buf, int len)
+{
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
+ struct dpaa_fd fd;
+ u64 buffer_start;
+ int data_offset, err;
+ struct qbman_swp *swp = dflt_dpio->sw_portal;
+ struct qbman_eq_desc ed;
+
+ /* Setup the FD fields */
+ memset(&fd, 0, sizeof(fd));
+
+ data_offset = priv->tx_data_offset;
+
+ do {
+ err = qbman_swp_acquire(dflt_dpio->sw_portal,
+ dflt_dpbp->dpbp_attr.bpid,
+ &buffer_start, 1);
+ } while (err == -EBUSY);
+
+ if (err < 0) {
+ printf("qbman_swp_acquire() failed\n");
+ return -ENOMEM;
+ }
+
+ debug("TX data: malloc buffer start=0x%p\n", (u64 *)buffer_start);
+
+ memcpy(((uint8_t *)(buffer_start) + data_offset), buf, len);
+
+ flush_dcache_range(buffer_start, buffer_start +
+ LDPAA_ETH_RX_BUFFER_SIZE);
+
+ ldpaa_fd_set_addr(&fd, (u64)buffer_start);
+ ldpaa_fd_set_offset(&fd, (uint16_t)(data_offset));
+ ldpaa_fd_set_bpid(&fd, dflt_dpbp->dpbp_attr.bpid);
+ ldpaa_fd_set_len(&fd, len);
+
+ fd.simple.ctrl = LDPAA_FD_CTRL_ASAL | LDPAA_FD_CTRL_PTA |
+ LDPAA_FD_CTRL_PTV1;
+
+ 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)
+ printf("error enqueueing Tx frame\n");
+
+ mdelay(1);
+
+ err = ldpaa_eth_pull_dequeue_tx_conf(priv);
+ if (err < 0)
+ printf("error Tx Conf frame\n");
+
+ return err;
+}
+
+static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
+{
+ 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;
+
+ if (net_dev->state == ETH_STATE_ACTIVE)
+ return 0;
+
+ /* DPNI initialization */
+ err = ldpaa_dpni_setup(priv);
+ if (err < 0)
+ goto err_dpni_setup;
+
+ err = ldpaa_dpbp_setup();
+ if (err < 0)
+ goto err_dpbp_setup;
+
+ /* DPNI binding DPBP */
+ err = ldpaa_dpni_bind(priv);
+ if (err)
+ goto err_bind;
+
+ err = dpni_get_primary_mac_addr(dflt_mc_io, priv->dpni_handle,
+ mac_addr);
+ if (err) {
+ printf("dpni_get_primary_mac_addr() failed\n");
+ return err;
+ }
+
+ memcpy(net_dev->enetaddr, mac_addr, 0x6);
+
+ /* setup the MAC address */
+ if (net_dev->enetaddr[0] & 0x01) {
+ printf("%s: MacAddress is multcast address\n", __func__);
+ return 1;
+ }
+
+#ifdef CONFIG_PHYLIB
+ /* TODO Check this path */
+ err = phy_startup(priv->phydev);
+ if (err) {
+ printf("%s: Could not initialize\n", priv->phydev->dev->name);
+ return err;
+ }
+#else
+ priv->phydev->speed = SPEED_1000;
+ priv->phydev->link = 1;
+ priv->phydev->duplex = DUPLEX_FULL;
+#endif
+
+ err = dpni_enable(dflt_mc_io, priv->dpni_handle);
+ if (err < 0) {
+ printf("dpni_enable() failed\n");
+ return err;
+ }
+
+ /* TODO: support multiple Rx flows */
+ err = dpni_get_rx_flow(dflt_mc_io, priv->dpni_handle, 0, 0,
+ &rx_queue_attr);
+ if (err) {
+ printf("dpni_get_rx_flow() failed\n");
+ goto err_rx_flow;
+ }
+
+ priv->rx_dflt_fqid = rx_queue_attr.fqid;
+
+ err = dpni_get_qdid(dflt_mc_io, priv->dpni_handle, &priv->tx_qdid);
+ if (err) {
+ printf("dpni_get_qdid() failed\n");
+ 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);
+err_bind:
+ ldpaa_dpbp_free();
+err_dpbp_setup:
+ dpni_close(dflt_mc_io, priv->dpni_handle);
+err_dpni_setup:
+ return err;
+}
+
+static void ldpaa_eth_stop(struct eth_device *net_dev)
+{
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
+ int err = 0;
+
+ if ((net_dev->state == ETH_STATE_PASSIVE) ||
+ (net_dev->state == ETH_STATE_INIT))
+ return;
+ /* Stop Tx and Rx traffic */
+ err = dpni_disable(dflt_mc_io, priv->dpni_handle);
+ if (err < 0)
+ printf("dpni_disable() failed\n");
+
+#ifdef CONFIG_PHYLIB
+ phy_shutdown(priv->phydev);
+#endif
+
+ ldpaa_dpbp_free();
+ dpni_reset(dflt_mc_io, priv->dpni_handle);
+ dpni_close(dflt_mc_io, priv->dpni_handle);
+}
+
+static void ldpaa_dpbp_drain_cnt(int count)
+{
+ uint64_t buf_array[7];
+ void *addr;
+ int ret, i;
+
+ BUG_ON(count > 7);
+
+ do {
+ ret = qbman_swp_acquire(dflt_dpio->sw_portal,
+ dflt_dpbp->dpbp_attr.bpid,
+ buf_array, count);
+ if (ret < 0) {
+ printf("qbman_swp_acquire() failed\n");
+ return;
+ }
+ for (i = 0; i < ret; i++) {
+ addr = (void *)buf_array[i];
+ debug("Free: buffer addr =0x%p\n", addr);
+ free(addr);
+ }
+ } while (ret);
+}
+
+static void ldpaa_dpbp_drain(void)
+{
+ int i;
+ for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7)
+ ldpaa_dpbp_drain_cnt(7);
+}
+
+static int ldpaa_bp_add_7(uint16_t bpid)
+{
+ uint64_t buf_array[7];
+ u8 *addr;
+ int i;
+ struct qbman_release_desc rd;
+
+ for (i = 0; i < 7; i++) {
+ addr = memalign(L1_CACHE_BYTES, LDPAA_ETH_RX_BUFFER_SIZE);
+ if (!addr) {
+ printf("addr allocation failed\n");
+ goto err_alloc;
+ }
+ memset(addr, 0x00, LDPAA_ETH_RX_BUFFER_SIZE);
+ flush_dcache_range((u64)addr,
+ (u64)(addr + LDPAA_ETH_RX_BUFFER_SIZE));
+
+ buf_array[i] = (uint64_t)addr;
+ debug("Release: buffer addr =0x%p\n", addr);
+ }
+
+release_bufs:
+ /* In case the portal is busy, retry until successful.
+ * This function is guaranteed to succeed in a reasonable amount
+ * of time.
+ */
+
+ do {
+ mdelay(1);
+ qbman_release_desc_clear(&rd);
+ qbman_release_desc_set_bpid(&rd, bpid);
+ } while (qbman_swp_release(dflt_dpio->sw_portal, &rd, buf_array, i));
+
+ return i;
+
+err_alloc:
+ if (i)
+ goto release_bufs;
+
+ return 0;
+}
+
+static int ldpaa_dpbp_seed(uint16_t bpid)
+{
+ int i;
+ int count;
+
+ for (i = 0; i < LDPAA_ETH_NUM_BUFS; i += 7) {
+ count = ldpaa_bp_add_7(bpid);
+ if (count < 7)
+ printf("Buffer Seed= %d\n", count);
+ }
+
+ return 0;
+}
+
+static int ldpaa_dpbp_setup(void)
+{
+ int err;
+
+ err = dpbp_open(dflt_mc_io, dflt_dpbp->dpbp_attr.id,
+ &dflt_dpbp->dpbp_handle);
+ if (err) {
+ printf("dpbp_open() failed\n");
+ goto err_open;
+ }
+
+ err = dpbp_enable(dflt_mc_io, dflt_dpbp->dpbp_handle);
+ if (err) {
+ printf("dpbp_enable() failed\n");
+ goto err_enable;
+ }
+
+ err = dpbp_get_attributes(dflt_mc_io, dflt_dpbp->dpbp_handle,
+ &dflt_dpbp->dpbp_attr);
+ if (err) {
+ printf("dpbp_get_attributes() failed\n");
+ goto err_get_attr;
+ }
+
+ err = ldpaa_dpbp_seed(dflt_dpbp->dpbp_attr.bpid);
+ if (err) {
+ printf("Buffer seeding failed for DPBP %d (bpid=%d)\n",
+ dflt_dpbp->dpbp_attr.id, dflt_dpbp->dpbp_attr.bpid);
+ goto err_seed;
+ }
+
+ return 0;
+
+err_seed:
+err_get_attr:
+ dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle);
+err_enable:
+ dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle);
+err_open:
+ return err;
+}
+
+static void ldpaa_dpbp_free(void)
+{
+ ldpaa_dpbp_drain();
+ dpbp_disable(dflt_mc_io, dflt_dpbp->dpbp_handle);
+ dpbp_reset(dflt_mc_io, dflt_dpbp->dpbp_handle);
+ dpbp_close(dflt_mc_io, dflt_dpbp->dpbp_handle);
+}
+
+static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv)
+{
+ int err;
+
+ /* and get a handle for the DPNI this interface is associate with */
+ err = dpni_open(dflt_mc_io, priv->dpni_id, &priv->dpni_handle);
+ if (err) {
+ printf("dpni_open() failed\n");
+ goto err_open;
+ }
+
+ err = dpni_get_attributes(dflt_mc_io, priv->dpni_handle,
+ &priv->dpni_attrs);
+ if (err) {
+ printf("dpni_get_attributes() failed (err=%d)\n", err);
+ goto err_get_attr;
+ }
+
+ /* Configure our buffers' layout */
+ priv->buf_layout.options = DPNI_BUF_LAYOUT_OPT_PARSER_RESULT |
+ DPNI_BUF_LAYOUT_OPT_FRAME_STATUS |
+ DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
+ priv->buf_layout.pass_parser_result = true;
+ priv->buf_layout.pass_frame_status = true;
+ priv->buf_layout.private_data_size = LDPAA_ETH_SWA_SIZE;
+ /* ...rx, ... */
+ err = dpni_set_rx_buffer_layout(dflt_mc_io, priv->dpni_handle,
+ &priv->buf_layout);
+ if (err) {
+ printf("dpni_set_rx_buffer_layout() failed");
+ goto err_buf_layout;
+ }
+
+ /* ... tx, ... */
+ priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PARSER_RESULT;
+ err = dpni_set_tx_buffer_layout(dflt_mc_io, priv->dpni_handle,
+ &priv->buf_layout);
+ if (err) {
+ printf("dpni_set_tx_buffer_layout() failed");
+ goto err_buf_layout;
+ }
+
+ /* ... tx-confirm. */
+ priv->buf_layout.options &= ~DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE;
+ err = dpni_set_tx_conf_buffer_layout(dflt_mc_io, priv->dpni_handle,
+ &priv->buf_layout);
+ if (err) {
+ printf("dpni_set_tx_conf_buffer_layout() failed");
+ goto err_buf_layout;
+ }
+
+ /* Now that we've set our tx buffer layout, retrieve the minimum
+ * required tx data offset.
+ */
+ err = dpni_get_tx_data_offset(dflt_mc_io, priv->dpni_handle,
+ &priv->tx_data_offset);
+ if (err) {
+ printf("dpni_get_tx_data_offset() failed\n");
+ goto err_data_offset;
+ }
+
+ /* Warn in case TX data offset is not multiple of 64 bytes. */
+ WARN_ON(priv->tx_data_offset % 64);
+
+ /* Accomodate SWA space. */
+ priv->tx_data_offset += LDPAA_ETH_SWA_SIZE;
+ debug("priv->tx_data_offset=%d\n", priv->tx_data_offset);
+
+ return 0;
+
+err_data_offset:
+err_buf_layout:
+err_get_attr:
+ dpni_close(dflt_mc_io, priv->dpni_handle);
+err_open:
+ return err;
+}
+
+static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
+{
+ struct dpni_pools_cfg pools_params;
+ struct dpni_tx_flow_cfg dflt_tx_flow;
+ int err = 0;
+
+ pools_params.num_dpbp = 1;
+ pools_params.pools[0].dpbp_id = (uint16_t)dflt_dpbp->dpbp_attr.id;
+ pools_params.pools[0].buffer_size = LDPAA_ETH_RX_BUFFER_SIZE;
+ err = dpni_set_pools(dflt_mc_io, priv->dpni_handle, &pools_params);
+ if (err) {
+ printf("dpni_set_pools() failed\n");
+ return err;
+ }
+
+ priv->tx_flow_id = DPNI_NEW_FLOW_ID;
+ memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
+
+ err = dpni_set_tx_flow(dflt_mc_io, priv->dpni_handle,
+ &priv->tx_flow_id, &dflt_tx_flow);
+ if (err) {
+ printf("dpni_set_tx_flow() failed\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int ldpaa_eth_netdev_init(struct eth_device *net_dev)
+{
+ int err;
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
+
+ sprintf(net_dev->name, "DPNI%d", priv->dpni_id);
+
+ net_dev->iobase = 0;
+ net_dev->init = ldpaa_eth_open;
+ net_dev->halt = ldpaa_eth_stop;
+ net_dev->send = ldpaa_eth_tx;
+ net_dev->recv = ldpaa_eth_pull_dequeue_rx;
+/*
+ TODO: PHY MDIO information
+ priv->bus = info->bus;
+ priv->phyaddr = info->phy_addr;
+ priv->enet_if = info->enet_if;
+*/
+
+ if (init_phy(net_dev))
+ return 0;
+
+ err = eth_register(net_dev);
+ if (err < 0) {
+ printf("eth_register() = %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+int ldpaa_eth_init(struct dprc_obj_desc obj_desc)
+{
+ struct eth_device *net_dev = NULL;
+ struct ldpaa_eth_priv *priv = NULL;
+ int err = 0;
+
+
+ /* Net device */
+ net_dev = (struct eth_device *)malloc(sizeof(struct eth_device));
+ if (!net_dev) {
+ printf("eth_device malloc() failed\n");
+ return -ENOMEM;
+ }
+ memset(net_dev, 0, sizeof(struct eth_device));
+
+ /* alloc the ldpaa ethernet private struct */
+ priv = (struct ldpaa_eth_priv *)malloc(sizeof(struct ldpaa_eth_priv));
+ if (!priv) {
+ printf("ldpaa_eth_priv malloc() failed\n");
+ return -ENOMEM;
+ }
+ memset(priv, 0, sizeof(struct ldpaa_eth_priv));
+
+ net_dev->priv = (void *)priv;
+ priv->net_dev = (struct eth_device *)net_dev;
+ priv->dpni_id = obj_desc.id;
+
+ err = ldpaa_eth_netdev_init(net_dev);
+ if (err)
+ goto err_netdev_init;
+
+ debug("ldpaa ethernet: Probed interface %s\n", net_dev->name);
+ return 0;
+
+err_netdev_init:
+ free(priv);
+ net_dev->priv = NULL;
+ free(net_dev);
+
+ return err;
+}
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h
new file mode 100644
index 0000000..3107ab6
--- /dev/null
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.h
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LDPAA_ETH_H
+#define __LDPAA_ETH_H
+
+#include <linux/netdevice.h>
+#include <fsl-mc/fsl_mc.h>
+#include <fsl-mc/fsl_dpaa_fd.h>
+#include <fsl-mc/fsl_dprc.h>
+#include <fsl-mc/fsl_dpni.h>
+#include <fsl-mc/fsl_dpbp.h>
+#include <fsl-mc/fsl_dpio.h>
+#include <fsl-mc/fsl_qbman_portal.h>
+#include <fsl-mc/fsl_mc_private.h>
+
+
+enum ldpaa_eth_type {
+ LDPAA_ETH_1G_E,
+ LDPAA_ETH_10G_E,
+};
+
+/* Arbitrary values for now, but we'll need to tune */
+#define LDPAA_ETH_NUM_BUFS (2 * 7)
+#define LDPAA_ETH_REFILL_THRESH (LDPAA_ETH_NUM_BUFS/2)
+#define LDPAA_ETH_RX_BUFFER_SIZE 2048
+
+/* Hardware requires alignment for ingress/egress buffer addresses
+ * and ingress buffer lengths.
+ */
+#define LDPAA_ETH_BUF_ALIGN 64
+
+/* So far we're only accomodating a skb backpointer in the frame's
+ * software annotation, but the hardware options are either 0 or 64.
+ */
+#define LDPAA_ETH_SWA_SIZE 64
+
+/* Annotation valid bits in FD FRC */
+#define LDPAA_FD_FRC_FASV 0x8000
+#define LDPAA_FD_FRC_FAEADV 0x4000
+#define LDPAA_FD_FRC_FAPRV 0x2000
+#define LDPAA_FD_FRC_FAIADV 0x1000
+#define LDPAA_FD_FRC_FASWOV 0x0800
+#define LDPAA_FD_FRC_FAICFDV 0x0400
+
+/* Annotation bits in FD CTRL */
+#define LDPAA_FD_CTRL_ASAL 0x00020000 /* ASAL = 128 */
+#define LDPAA_FD_CTRL_PTA 0x00800000
+#define LDPAA_FD_CTRL_PTV1 0x00400000
+
+/* TODO: we may want to move this and other WRIOP related defines
+ * to a separate header
+ */
+/* Frame annotation status */
+struct ldpaa_fas {
+ u8 reserved;
+ u8 ppid;
+ __le16 ifpid;
+ __le32 status;
+} __packed;
+
+/* Debug frame, otherwise supposed to be discarded */
+#define LDPAA_ETH_FAS_DISC 0x80000000
+/* MACSEC frame */
+#define LDPAA_ETH_FAS_MS 0x40000000
+#define LDPAA_ETH_FAS_PTP 0x08000000
+/* Ethernet multicast frame */
+#define LDPAA_ETH_FAS_MC 0x04000000
+/* Ethernet broadcast frame */
+#define LDPAA_ETH_FAS_BC 0x02000000
+#define LDPAA_ETH_FAS_KSE 0x00040000
+#define LDPAA_ETH_FAS_EOFHE 0x00020000
+#define LDPAA_ETH_FAS_MNLE 0x00010000
+#define LDPAA_ETH_FAS_TIDE 0x00008000
+#define LDPAA_ETH_FAS_PIEE 0x00004000
+/* Frame length error */
+#define LDPAA_ETH_FAS_FLE 0x00002000
+/* Frame physical error; our favourite pastime */
+#define LDPAA_ETH_FAS_FPE 0x00001000
+#define LDPAA_ETH_FAS_PTE 0x00000080
+#define LDPAA_ETH_FAS_ISP 0x00000040
+#define LDPAA_ETH_FAS_PHE 0x00000020
+#define LDPAA_ETH_FAS_BLE 0x00000010
+/* L3 csum validation performed */
+#define LDPAA_ETH_FAS_L3CV 0x00000008
+/* L3 csum error */
+#define LDPAA_ETH_FAS_L3CE 0x00000004
+/* L4 csum validation performed */
+#define LDPAA_ETH_FAS_L4CV 0x00000002
+/* L4 csum error */
+#define LDPAA_ETH_FAS_L4CE 0x00000001
+/* These bits always signal errors */
+#define LDPAA_ETH_RX_ERR_MASK (LDPAA_ETH_FAS_DISC | \
+ LDPAA_ETH_FAS_KSE | \
+ LDPAA_ETH_FAS_EOFHE | \
+ LDPAA_ETH_FAS_MNLE | \
+ LDPAA_ETH_FAS_TIDE | \
+ LDPAA_ETH_FAS_PIEE | \
+ LDPAA_ETH_FAS_FLE | \
+ LDPAA_ETH_FAS_FPE | \
+ LDPAA_ETH_FAS_PTE | \
+ LDPAA_ETH_FAS_ISP | \
+ LDPAA_ETH_FAS_PHE | \
+ LDPAA_ETH_FAS_BLE | \
+ LDPAA_ETH_FAS_L3CE | \
+ LDPAA_ETH_FAS_L4CE)
+/* Unsupported features in the ingress */
+#define LDPAA_ETH_RX_UNSUPP_MASK LDPAA_ETH_FAS_MS
+/* TODO trim down the bitmask; not all of them apply to Tx-confirm */
+#define LDPAA_ETH_TXCONF_ERR_MASK (LDPAA_ETH_FAS_KSE | \
+ LDPAA_ETH_FAS_EOFHE | \
+ LDPAA_ETH_FAS_MNLE | \
+ LDPAA_ETH_FAS_TIDE)
+
+struct ldpaa_eth_priv {
+ struct eth_device *net_dev;
+ int dpni_id;
+ uint16_t dpni_handle;
+ struct dpni_attr dpni_attrs;
+ /* Insofar as the MC is concerned, we're using one layout on all 3 types
+ * of buffers (Rx, Tx, Tx-Conf).
+ */
+ struct dpni_buffer_layout buf_layout;
+ uint16_t tx_data_offset;
+
+ 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 */
+ struct phy_device *phydev;
+};
+
+extern struct fsl_mc_io *dflt_mc_io;
+extern struct fsl_dpbp_obj *dflt_dpbp;
+extern struct fsl_dpio_obj *dflt_dpio;
+
+static void ldpaa_dpbp_drain_cnt(int count);
+static void ldpaa_dpbp_drain(void);
+static int ldpaa_dpbp_seed(uint16_t bpid);
+static void ldpaa_dpbp_free(void);
+static int ldpaa_dpni_setup(struct ldpaa_eth_priv *priv);
+static int ldpaa_dpbp_setup(void);
+static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv);
+#endif /* __LDPAA_H */
diff --git a/drivers/net/ldpaa_eth/ldpaa_wriop.c b/drivers/net/ldpaa_eth/ldpaa_wriop.c
new file mode 100644
index 0000000..926057a
--- /dev/null
+++ b/drivers/net/ldpaa_eth/ldpaa_wriop.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/types.h>
+#include <malloc.h>
+#include <net.h>
+#include <linux/compat.h>
+#include <asm/arch/fsl_serdes.h>
+#include <fsl-mc/ldpaa_wriop.h>
+
+struct wriop_dpmac_info dpmac_info[NUM_WRIOP_PORTS];
+
+__weak phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtc)
+{
+ return PHY_INTERFACE_MODE_NONE;
+}
+
+void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl)
+{
+ phy_interface_t enet_if;
+ int index = dpmac_id + sd * 8;
+
+ dpmac_info[index].enabled = 0;
+ dpmac_info[index].id = 0;
+ dpmac_info[index].enet_if = PHY_INTERFACE_MODE_NONE;
+
+ enet_if = wriop_dpmac_enet_if(index, lane_prtcl);
+ if (enet_if != PHY_INTERFACE_MODE_NONE) {
+ dpmac_info[index].enabled = 1;
+ dpmac_info[index].id = index;
+ dpmac_info[index].enet_if = enet_if;
+ }
+}
+
+/*TODO what it do */
+static int wriop_dpmac_to_index(int dpmac_id)
+{
+ int i;
+
+ for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
+ if (dpmac_info[i].id == dpmac_id)
+ return i;
+ }
+
+ return -1;
+}
+
+void wriop_disable_dpmac(int dpmac_id)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return;
+
+ dpmac_info[i].enabled = 0;
+ wriop_dpmac_disable(dpmac_id);
+}
+
+void wriop_enable_dpmac(int dpmac_id)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return;
+
+ dpmac_info[i].enabled = 1;
+ wriop_dpmac_enable(dpmac_id);
+}
+
+void wriop_set_mdio(int dpmac_id, struct mii_dev *bus)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return;
+
+ dpmac_info[i].bus = bus;
+}
+
+struct mii_dev *wriop_get_mdio(int dpmac_id)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return NULL;
+
+ return dpmac_info[i].bus;
+}
+
+void wriop_set_phy_address(int dpmac_id, int address)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return;
+
+ dpmac_info[i].phy_addr = address;
+}
+
+int wriop_get_phy_address(int dpmac_id)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return -1;
+
+ return dpmac_info[i].phy_addr;
+}
+
+void wriop_set_phy_dev(int dpmac_id, struct phy_device *phydev)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return;
+
+ dpmac_info[i].phydev = phydev;
+}
+
+struct phy_device *wriop_get_phy_dev(int dpmac_id)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return NULL;
+
+ return dpmac_info[i].phydev;
+}
+
+phy_interface_t wriop_get_enet_if(int dpmac_id)
+{
+ int i = wriop_dpmac_to_index(dpmac_id);
+
+ if (i == -1)
+ return PHY_INTERFACE_MODE_NONE;
+
+ if (dpmac_info[i].enabled)
+ return dpmac_info[i].enet_if;
+
+ return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/drivers/net/ldpaa_eth/ls2085a.c b/drivers/net/ldpaa_eth/ls2085a.c
new file mode 100644
index 0000000..6b7960a
--- /dev/null
+++ b/drivers/net/ldpaa_eth/ls2085a.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <common.h>
+#include <phy.h>
+#include <fsl-mc/ldpaa_wriop.h>
+#include <asm/io.h>
+#include <asm/arch-fsl-lsch3/immap_lsch3.h>
+#include <asm/arch/fsl_serdes.h>
+#include <fsl-mc/ldpaa_wriop.h>
+
+u32 dpmac_to_devdisr[] = {
+ [WRIOP1_DPMAC1] = FSL_CHASSIS3_DEVDISR2_DPMAC1,
+ [WRIOP1_DPMAC2] = FSL_CHASSIS3_DEVDISR2_DPMAC2,
+ [WRIOP1_DPMAC3] = FSL_CHASSIS3_DEVDISR2_DPMAC3,
+ [WRIOP1_DPMAC4] = FSL_CHASSIS3_DEVDISR2_DPMAC4,
+ [WRIOP1_DPMAC5] = FSL_CHASSIS3_DEVDISR2_DPMAC5,
+ [WRIOP1_DPMAC6] = FSL_CHASSIS3_DEVDISR2_DPMAC6,
+ [WRIOP1_DPMAC7] = FSL_CHASSIS3_DEVDISR2_DPMAC7,
+ [WRIOP1_DPMAC8] = FSL_CHASSIS3_DEVDISR2_DPMAC8,
+ [WRIOP1_DPMAC9] = FSL_CHASSIS3_DEVDISR2_DPMAC9,
+ [WRIOP1_DPMAC10] = FSL_CHASSIS3_DEVDISR2_DPMAC10,
+ [WRIOP1_DPMAC11] = FSL_CHASSIS3_DEVDISR2_DPMAC11,
+ [WRIOP1_DPMAC12] = FSL_CHASSIS3_DEVDISR2_DPMAC12,
+ [WRIOP1_DPMAC13] = FSL_CHASSIS3_DEVDISR2_DPMAC13,
+ [WRIOP1_DPMAC14] = FSL_CHASSIS3_DEVDISR2_DPMAC14,
+ [WRIOP1_DPMAC15] = FSL_CHASSIS3_DEVDISR2_DPMAC15,
+ [WRIOP1_DPMAC16] = FSL_CHASSIS3_DEVDISR2_DPMAC16,
+ [WRIOP1_DPMAC17] = FSL_CHASSIS3_DEVDISR2_DPMAC17,
+ [WRIOP1_DPMAC18] = FSL_CHASSIS3_DEVDISR2_DPMAC18,
+ [WRIOP1_DPMAC19] = FSL_CHASSIS3_DEVDISR2_DPMAC19,
+ [WRIOP1_DPMAC20] = FSL_CHASSIS3_DEVDISR2_DPMAC20,
+ [WRIOP1_DPMAC21] = FSL_CHASSIS3_DEVDISR2_DPMAC21,
+ [WRIOP1_DPMAC22] = FSL_CHASSIS3_DEVDISR2_DPMAC22,
+ [WRIOP1_DPMAC23] = FSL_CHASSIS3_DEVDISR2_DPMAC23,
+ [WRIOP1_DPMAC24] = FSL_CHASSIS3_DEVDISR2_DPMAC24,
+};
+
+static int is_device_disabled(int dpmac_id)
+{
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+ u32 devdisr2 = in_le32(&gur->devdisr2);
+
+ return dpmac_to_devdisr[dpmac_id] & devdisr2;
+}
+
+void wriop_dpmac_disable(int dpmac_id)
+{
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+
+ setbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]);
+}
+
+void wriop_dpmac_enable(int dpmac_id)
+{
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+
+ clrbits_le32(&gur->devdisr2, dpmac_to_devdisr[dpmac_id]);
+}
+
+phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtcl)
+{
+ enum srds_prtcl;
+
+ if (is_device_disabled(dpmac_id + 1))
+ return PHY_INTERFACE_MODE_NONE;
+
+ if (lane_prtcl >= SGMII1 && lane_prtcl <= SGMII16)
+ return PHY_INTERFACE_MODE_SGMII;
+
+ if (lane_prtcl >= XFI1 && lane_prtcl <= XFI8)
+ return PHY_INTERFACE_MODE_XGMII;
+
+ if (lane_prtcl >= XAUI1 && lane_prtcl <= XAUI2)
+ return PHY_INTERFACE_MODE_XGMII;
+
+ if (lane_prtcl >= QSGMII_A && lane_prtcl <= QSGMII_D)
+ return PHY_INTERFACE_MODE_QSGMII;
+
+ return PHY_INTERFACE_MODE_NONE;
+}
diff --git a/drivers/net/phy/cortina.c b/drivers/net/phy/cortina.c
index 254f056..3a2b3bb 100644
--- a/drivers/net/phy/cortina.c
+++ b/drivers/net/phy/cortina.c
@@ -186,8 +186,8 @@ void cs4340_upload_firmware(struct phy_device *phydev)
while (*addr != 0x0a) {
line_temp[i++] = *addr++;
if (0x50 < i) {
- printf("Not found Cortina PHY ucode at 0x%x\n",
- CONFIG_CORTINA_FW_ADDR);
+ printf("Not found Cortina PHY ucode at 0x%p\n",
+ (char *)CONFIG_CORTINA_FW_ADDR);
return;
}
}
diff --git a/drivers/net/vsc9953.c b/drivers/net/vsc9953.c
index 9fc3c18..fed7358 100644
--- a/drivers/net/vsc9953.c
+++ b/drivers/net/vsc9953.c
@@ -9,7 +9,7 @@
#include <asm/io.h>
#include <asm/fsl_serdes.h>
#include <fm_eth.h>
-#include <asm/fsl_memac.h>
+#include <fsl_memac.h>
#include <vsc9953.h>
static struct vsc9953_info vsc9953_l2sw = {
diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index bcad8f2..402c519 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -11,7 +11,6 @@
#include <asm/io.h>
#include <errno.h>
#include <malloc.h>
-#include <asm/pcie_layerscape.h>
#ifndef CONFIG_SYS_PCI_MEMORY_BUS
#define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE
@@ -50,11 +49,20 @@
#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
#define PCIE_ATU_UPPER_TARGET 0x91C
+/* LUT registers */
+#define PCIE_LUT_BASE 0x80000
+#define PCIE_LUT_DBG 0x7FC
+
+#define PCIE_DBI_RO_WR_EN 0x8bc
+
#define PCIE_LINK_CAP 0x7c
#define PCIE_LINK_SPEED_MASK 0xf
#define PCIE_LINK_STA 0x82
-#define PCIE_DBI_SIZE (4 * 1024) /* 4K */
+#define LTSSM_STATE_MASK 0x3f
+#define LTSSM_PCIE_L0 0x11 /* L0 state */
+
+#define PCIE_DBI_SIZE 0x100000 /* 1M */
struct ls_pcie {
int idx;
@@ -104,8 +112,6 @@ struct ls_pcie_info {
/* PEX1/2 Misc Ports Status Register */
#define LTSSM_STATE_SHIFT 20
-#define LTSSM_STATE_MASK 0x3f
-#define LTSSM_PCIE_L0 0x11 /* L0 state */
static int ls_pcie_link_state(struct ls_pcie *pcie)
{
@@ -122,18 +128,18 @@ static int ls_pcie_link_state(struct ls_pcie *pcie)
return 1;
}
#else
-#define PCIE_LDBG 0x7FC
-
static int ls_pcie_link_state(struct ls_pcie *pcie)
{
u32 state;
- state = readl(pcie->dbi + PCIE_LDBG);
- if (state)
- return 1;
+ state = readl(pcie->dbi + PCIE_LUT_BASE + PCIE_LUT_DBG) &
+ LTSSM_STATE_MASK;
+ if (state < LTSSM_PCIE_L0) {
+ debug("....PCIe link error. LTSSM=0x%02x.\n", state);
+ return 0;
+ }
- debug("....PCIe link error.\n");
- return 0;
+ return 1;
}
#endif
@@ -149,7 +155,11 @@ static int ls_pcie_link_up(struct ls_pcie *pcie)
/* Try to download speed to gen1 */
cap = readl(pcie->dbi + PCIE_LINK_CAP);
writel((cap & (~PCIE_LINK_SPEED_MASK)) | 1, pcie->dbi + PCIE_LINK_CAP);
- udelay(2000);
+ /*
+ * Notice: the following delay has critical impact on link training
+ * if too short (<30ms) the link doesn't get up.
+ */
+ mdelay(100);
state = ls_pcie_link_state(pcie);
if (state)
return state;
@@ -251,6 +261,10 @@ static int ls_pcie_addr_valid(struct pci_controller *hose, pci_dev_t d)
if (PCI_DEV(d) > 0)
return -EINVAL;
+ /* Controller does not support multi-function in RC mode */
+ if ((PCI_BUS(d) == hose->first_busno) && (PCI_FUNC(d) > 0))
+ return -EINVAL;
+
return 0;
}
@@ -327,8 +341,12 @@ static void ls_pcie_setup_ctrl(struct ls_pcie *pcie,
pci_hose_write_config_dword(hose, dev, PCI_BASE_ADDRESS_0, 0);
/* program correct class for RC */
+ writel(1, pcie->dbi + PCIE_DBI_RO_WR_EN);
pci_hose_write_config_word(hose, dev, PCI_CLASS_DEVICE,
PCI_CLASS_BRIDGE_PCI);
+#ifndef CONFIG_LS102XA
+ writel(0, pcie->dbi + PCIE_DBI_RO_WR_EN);
+#endif
}
int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
@@ -417,9 +435,9 @@ int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
}
/* Print the negotiated PCIe link width */
- pci_hose_read_config_word(hose, dev, PCIE_LINK_STA, &temp16);
- printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4,
- (temp16 & 0xf), info->regs);
+ pci_hose_read_config_word(hose, pdev, PCIE_LINK_STA, &temp16);
+ printf("x%d gen%d, regs @ 0x%lx\n", (temp16 & 0x3f0) >> 4,
+ (temp16 & 0xf), info->regs);
if (ep_mode)
return busno;
@@ -486,7 +504,7 @@ static void ft_pcie_ls_setup(void *blob, const char *pci_compat,
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
}
-void ft_pcie_setup(void *blob, bd_t *bd)
+void ft_pci_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_PCIE1
ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE1_ADDR, PCIE1);
@@ -506,7 +524,7 @@ void ft_pcie_setup(void *blob, bd_t *bd)
}
#else
-void ft_pcie_setup(void *blob, bd_t *bd)
+void ft_pci_setup(void *blob, bd_t *bd)
{
}
#endif
diff --git a/drivers/qe/qe.c b/drivers/qe/qe.c
index d24651b..84e1433 100644
--- a/drivers/qe/qe.c
+++ b/drivers/qe/qe.c
@@ -196,6 +196,18 @@ void u_qe_init(void)
}
#endif
+#ifdef CONFIG_U_QE
+void u_qe_resume(void)
+{
+ qe_map_t *qe_immrr;
+ uint qe_base = CONFIG_SYS_IMMR + QE_IMMR_OFFSET; /* QE immr base */
+ qe_immrr = (qe_map_t *)qe_base;
+
+ u_qe_firmware_resume((const void *)CONFIG_SYS_QE_FW_ADDR, qe_immrr);
+ out_be32(&qe_immrr->iram.iready, QE_IRAM_READY);
+}
+#endif
+
void qe_reset(void)
{
qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
@@ -580,6 +592,76 @@ int u_qe_upload_firmware(const struct qe_firmware *firmware)
}
#endif
+#ifdef CONFIG_U_QE
+int u_qe_firmware_resume(const struct qe_firmware *firmware, qe_map_t *qe_immrr)
+{
+ unsigned int i;
+ unsigned int j;
+ const struct qe_header *hdr;
+ const u32 *code;
+#ifdef CONFIG_DEEP_SLEEP
+#ifdef CONFIG_PPC
+ ccsr_gur_t __iomem *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
+#else
+ struct ccsr_gur __iomem *gur = (void *)CONFIG_SYS_FSL_GUTS_ADDR;
+#endif
+#endif
+
+ if (!firmware)
+ return -EINVAL;
+
+ hdr = &firmware->header;
+
+ /* Check the magic */
+ if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
+ (hdr->magic[2] != 'F')) {
+#ifdef CONFIG_DEEP_SLEEP
+ setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_QE_DISABLE);
+#endif
+ return -EPERM;
+ }
+
+ /*
+ * If the microcode calls for it, split the I-RAM.
+ */
+ if (!firmware->split) {
+ out_be16(&qe_immrr->cp.cercr,
+ in_be16(&qe_immrr->cp.cercr) | QE_CP_CERCR_CIR);
+ }
+
+ /* Loop through each microcode. */
+ for (i = 0; i < firmware->count; i++) {
+ const struct qe_microcode *ucode = &firmware->microcode[i];
+
+ /* Upload a microcode if it's present */
+ if (!ucode->code_offset)
+ return 0;
+
+ code = (const void *)firmware + be32_to_cpu(ucode->code_offset);
+
+ /* Use auto-increment */
+ out_be32(&qe_immrr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
+ QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
+
+ for (i = 0; i < be32_to_cpu(ucode->count); i++)
+ out_be32(&qe_immrr->iram.idata, be32_to_cpu(code[i]));
+
+ /* Program the traps for this processor */
+ for (j = 0; j < 16; j++) {
+ u32 trap = be32_to_cpu(ucode->traps[j]);
+
+ if (trap)
+ out_be32(&qe_immrr->rsp[i].tibcr[j], trap);
+ }
+
+ /* Enable traps */
+ out_be32(&qe_immrr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
+ }
+
+ return 0;
+}
+#endif
+
struct qe_firmware_info *qe_get_firmware_info(void)
{
return qe_firmware_uploaded ? &qe_firmware_info : NULL;
diff --git a/drivers/qe/qe.h b/drivers/qe/qe.h
index 33878f8..77b18e9 100644
--- a/drivers/qe/qe.h
+++ b/drivers/qe/qe.h
@@ -11,6 +11,9 @@
#define __QE_H__
#include "common.h"
+#ifdef CONFIG_U_QE
+#include <linux/immap_qe.h>
+#endif
#define QE_NUM_OF_BRGS 16
#define UCC_MAX_NUM 8
@@ -288,6 +291,9 @@ void qe_reset(void);
#ifdef CONFIG_U_QE
void u_qe_init(void);
int u_qe_upload_firmware(const struct qe_firmware *firmware);
+void u_qe_resume(void);
+int u_qe_firmware_resume(const struct qe_firmware *firmware,
+ qe_map_t *qe_immrr);
#endif
#endif /* __QE_H__ */
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 5d4288d..2dca524 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -259,10 +259,11 @@ static int fdt_fixup_usb_erratum(void *blob, const char *prop_erratum,
void fdt_fixup_dr_usb(void *blob, bd_t *bd)
{
static const char * const modes[] = { "host", "peripheral", "otg" };
- static const char * const phys[] = { "ulpi", "utmi" };
+ static const char * const phys[] = { "ulpi", "utmi", "utmi_dual" };
int usb_erratum_a006261_off = -1;
int usb_erratum_a007075_off = -1;
int usb_erratum_a007792_off = -1;
+ int usb_erratum_a005697_off = -1;
int usb_mode_off = -1;
int usb_phy_off = -1;
char str[5];
@@ -303,6 +304,9 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd)
dr_phy_type = phys[phy_idx];
}
+ if (has_dual_phy())
+ dr_phy_type = phys[2];
+
usb_mode_off = fdt_fixup_usb_mode_phy_type(blob,
dr_mode_type, NULL,
usb_mode_off);
@@ -325,6 +329,7 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd)
if (usb_erratum_a006261_off < 0)
return;
}
+
if (has_erratum_a007075()) {
usb_erratum_a007075_off = fdt_fixup_usb_erratum
(blob,
@@ -333,6 +338,7 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd)
if (usb_erratum_a007075_off < 0)
return;
}
+
if (has_erratum_a007792()) {
usb_erratum_a007792_off = fdt_fixup_usb_erratum
(blob,
@@ -341,6 +347,14 @@ void fdt_fixup_dr_usb(void *blob, bd_t *bd)
if (usb_erratum_a007792_off < 0)
return;
}
+ if (has_erratum_a005697()) {
+ usb_erratum_a005697_off = fdt_fixup_usb_erratum
+ (blob,
+ "fsl,usb-erratum-a005697",
+ usb_erratum_a005697_off);
+ if (usb_erratum_a005697_off < 0)
+ return;
+ }
}
}
#endif
diff --git a/include/config_fsl_secboot.h b/include/config_fsl_secboot.h
new file mode 100644
index 0000000..050b157
--- /dev/null
+++ b/include/config_fsl_secboot.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_FSL_SECBOOT_H
+#define __CONFIG_FSL_SECBOOT_H
+
+#ifdef CONFIG_SECURE_BOOT
+
+#ifndef CONFIG_CMD_ESBC_VALIDATE
+#define CONFIG_CMD_ESBC_VALIDATE
+#endif
+
+#ifndef CONFIG_EXTRA_ENV
+#define CONFIG_EXTRA_ENV ""
+#endif
+
+/*
+ * Control should not reach back to uboot after validation of images
+ * for secure boot flow and therefore bootscript should have
+ * the bootm command. If control reaches back to uboot anyhow
+ * after validating images, core should just spin.
+ */
+
+/*
+ * Define the key hash for boot script here if public/private key pair used to
+ * sign bootscript are different from the SRK hash put in the fuse
+ * Example of defining KEY_HASH is
+ * #define CONFIG_BOOTSCRIPT_KEY_HASH \
+ * "41066b564c6ffcef40ccbc1e0a5d0d519604000c785d97bbefd25e4d288d1c8b"
+ */
+
+#ifdef CONFIG_BOOTSCRIPT_KEY_HASH
+#define CONFIG_SECBOOT \
+ "setenv bs_hdraddr " __stringify(CONFIG_BOOTSCRIPT_HDR_ADDR)";" \
+ "setenv bootargs \'root=/dev/ram rw console=ttyS0,115200 " \
+ "ramdisk_size=600000\';" \
+ CONFIG_EXTRA_ENV \
+ "esbc_validate $bs_hdraddr " \
+ __stringify(CONFIG_BOOTSCRIPT_KEY_HASH)";" \
+ "source $img_addr;" \
+ "esbc_halt\0"
+#else
+#define CONFIG_SECBOOT \
+ "setenv bs_hdraddr " __stringify(CONFIG_BOOTSCRIPT_HDR_ADDR)";" \
+ "setenv bootargs \'root=/dev/ram rw console=ttyS0,115200 " \
+ "ramdisk_size=600000\';" \
+ CONFIG_EXTRA_ENV \
+ "esbc_validate $bs_hdraddr;" \
+ "source $img_addr;" \
+ "esbc_halt\0"
+#endif
+
+/* For secure boot flow, default environment used will be used */
+#if defined(CONFIG_SYS_RAMBOOT)
+#if defined(CONFIG_RAMBOOT_SPIFLASH)
+#undef CONFIG_ENV_IS_IN_SPI_FLASH
+#elif defined(CONFIG_RAMBOOT_NAND)
+#undef CONFIG_ENV_IS_IN_NAND
+#elif defined(CONFIG_RAMBOOT_SDCARD)
+#undef CONFIG_ENV_IS_IN_MMC
+#endif
+#else /*CONFIG_SYS_RAMBOOT*/
+#undef CONFIG_ENV_IS_IN_FLASH
+#endif
+
+#define CONFIG_ENV_IS_NOWHERE
+
+/*
+ * 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
+
+/*
+ * CONFIG_ZERO_BOOTDELAY_CHECK should not be defined for
+ * secure boot flow as defining this would enable a user to
+ * reach uboot prompt by pressing some key before start of
+ * autoboot
+ */
+#undef CONFIG_ZERO_BOOTDELAY_CHECK
+
+#endif
+#endif
diff --git a/include/configs/aristainetos.h b/include/configs/aristainetos.h
index 3066fd0..cc26790 100644
--- a/include/configs/aristainetos.h
+++ b/include/configs/aristainetos.h
@@ -262,6 +262,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
#define CONFIG_SYS_I2C_SLAVE 0x7f
#define CONFIG_SYS_I2C_NOPROBES { {0, 0x00} }
diff --git a/include/configs/cm_fx6.h b/include/configs/cm_fx6.h
index 4207504..d6e5a2b 100644
--- a/include/configs/cm_fx6.h
+++ b/include/configs/cm_fx6.h
@@ -245,6 +245,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
#define CONFIG_SYS_MXC_I2C3_SPEED 400000
diff --git a/include/configs/embestmx6boards.h b/include/configs/embestmx6boards.h
index b4b3ae8..e9f5bed 100644
--- a/include/configs/embestmx6boards.h
+++ b/include/configs/embestmx6boards.h
@@ -55,6 +55,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* USB Configs */
diff --git a/include/configs/flea3.h b/include/configs/flea3.h
index 854ae90..5f7cad8 100644
--- a/include/configs/flea3.h
+++ b/include/configs/flea3.h
@@ -52,6 +52,7 @@
*/
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_SPD_BUS_NUM 2 /* I2C3 */
#define CONFIG_SYS_MXC_I2C3_SLAVE 0xfe
#define CONFIG_MXC_SPI
diff --git a/include/configs/gw_ventana.h b/include/configs/gw_ventana.h
index 620f950..9bc3250 100644
--- a/include/configs/gw_ventana.h
+++ b/include/configs/gw_ventana.h
@@ -95,6 +95,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
#define CONFIG_I2C_GSC 0
#define CONFIG_I2C_PMIC 1
diff --git a/include/configs/imx31_phycore.h b/include/configs/imx31_phycore.h
index 49039d6..db197f3 100644
--- a/include/configs/imx31_phycore.h
+++ b/include/configs/imx31_phycore.h
@@ -38,6 +38,7 @@
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_CLK_OFFSET I2C2_CLK_OFFSET
#define CONFIG_MXC_UART
diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h
index 5de416d..9a8fd50 100644
--- a/include/configs/ls1021aqds.h
+++ b/include/configs/ls1021aqds.h
@@ -389,6 +389,7 @@ unsigned long get_board_ddr_clk(void);
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
/*
* I2C bus multiplexer
@@ -655,6 +656,7 @@ unsigned long get_board_ddr_clk(void);
#ifdef CONFIG_SECURE_BOOT
#define CONFIG_CMD_BLOB
+#include <asm/fsl_secure_boot.h>
#endif
#endif
diff --git a/include/configs/ls1021atwr.h b/include/configs/ls1021atwr.h
index a13876b..729205f 100644
--- a/include/configs/ls1021atwr.h
+++ b/include/configs/ls1021atwr.h
@@ -205,6 +205,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
/* EEPROM */
#ifndef CONFIG_SD_BOOT
diff --git a/include/configs/ls2085a_common.h b/include/configs/ls2085a_common.h
index e0435cc..e270fc8 100644
--- a/include/configs/ls2085a_common.h
+++ b/include/configs/ls2085a_common.h
@@ -19,8 +19,20 @@
#define CONFIG_ARM_ERRATA_828024
#define CONFIG_ARM_ERRATA_826974
+#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
+#endif
+
+/* We need architecture specific misc initializations */
+#define CONFIG_ARCH_MISC_INIT
+
/* Link Definitions */
-#define CONFIG_SYS_TEXT_BASE 0x30001000
+#ifdef CONFIG_SPL
+#define CONFIG_SYS_TEXT_BASE 0x80400000
+#else
+#define CONFIG_SYS_TEXT_BASE 0x30100000
+#endif
#ifdef CONFIG_EMU
#define CONFIG_SYS_NO_FLASH
@@ -39,13 +51,13 @@
#define CONFIG_FIT
#define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */
+#ifndef CONFIG_SPL
#define CONFIG_FSL_DDR_INTERACTIVE /* Interactive debugging */
+#endif
#ifndef CONFIG_SYS_FSL_DDR4
#define CONFIG_SYS_FSL_DDR3 /* Use DDR3 memory */
#define CONFIG_SYS_DDR_RAW_TIMING
#endif
-#define CONFIG_DIMM_SLOTS_PER_CTLR 1
-#define CONFIG_CHIP_SELECTS_PER_CTRL 4
#define CONFIG_SYS_FSL_DDR_INTLV_256B /* force 256 byte interleaving */
@@ -69,23 +81,26 @@
#define CONFIG_SYS_DP_DDR_BASE_PHY 0
#define CONFIG_DP_DDR_CTRL 2
#define CONFIG_DP_DDR_NUM_CTRLS 1
-#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1
/* Generic Timer Definitions */
-#define COUNTER_FREQUENCY 12000000 /* 12MHz */
+/*
+ * This is not an accurate number. It is used in start.S. The frequency
+ * will be udpated later when get_bus_freq(0) is available.
+ */
+#define COUNTER_FREQUENCY 25000000 /* 25MHz */
/* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128 * 1024)
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2048 * 1024)
/* I2C */
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
-#define CONFIG_SYS_MXC_I2C1_SPEED 40000000
-#define CONFIG_SYS_MXC_I2C2_SPEED 40000000
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
+#define CONFIG_SYS_I2C_MXC_I2C4 /* enable I2C bus 4 */
/* Serial Port */
-#define CONFIG_CONS_INDEX 2
+#define CONFIG_CONS_INDEX 1
#define CONFIG_SYS_NS16550
#define CONFIG_SYS_NS16550_SERIAL
#define CONFIG_SYS_NS16550_REG_SIZE 1
@@ -96,131 +111,98 @@
/* IFC */
#define CONFIG_FSL_IFC
-#define CONFIG_SYS_NOR0_CSPR_EXT (0x0)
-#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024)
+
/*
- * During booting, CS0 needs to be at the region of 0x30000000, i.e. the IFC
- * address 0. But this region is limited to 256MB. To accommodate bigger NOR
- * flash and other devices, we will map CS0 to 0x580000000 after relocation.
+ * During booting, IFC is mapped at the region of 0x30000000.
+ * But this region is limited to 256MB. To accommodate NOR, promjet
+ * and FPGA. This region is divided as below:
+ * 0x30000000 - 0x37ffffff : 128MB : NOR flash
+ * 0x38000000 - 0x3BFFFFFF : 64MB : Promjet
+ * 0x3C000000 - 0x40000000 : 64MB : FPGA etc
+ *
+ * To accommodate bigger NOR flash and other devices, we will map IFC
+ * chip selects to as below:
+ * 0x5_1000_0000..0x5_1fff_ffff Memory Hole
+ * 0x5_2000_0000..0x5_3fff_ffff IFC CSx (FPGA, NAND and others 512MB)
+ * 0x5_4000_0000..0x5_7fff_ffff ASIC or others 1GB
+ * 0x5_8000_0000..0x5_bfff_ffff IFC CS0 1GB (NOR/Promjet)
+ * 0x5_C000_0000..0x5_ffff_ffff IFC CS1 1GB (NOR/Promjet)
+ *
+ * For e.g. NOR flash at CS0 will be mapped to 0x580000000 after relocation.
* CONFIG_SYS_FLASH_BASE has the final address (core view)
* CONFIG_SYS_FLASH_BASE_PHYS has the final address (IFC view)
* CONFIG_SYS_FLASH_BASE_PHYS_EARLY has the temporary IFC address
* CONFIG_SYS_TEXT_BASE is linked to 0x30000000 for booting
*/
+
#define CONFIG_SYS_FLASH_BASE 0x580000000ULL
#define CONFIG_SYS_FLASH_BASE_PHYS 0x80000000
#define CONFIG_SYS_FLASH_BASE_PHYS_EARLY 0x00000000
-/*
- * NOR Flash Timing Params
- */
-#define CONFIG_SYS_NOR0_CSPR \
- (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \
- CSPR_PORT_SIZE_16 | \
- CSPR_MSEL_NOR | \
- CSPR_V)
-#define CONFIG_SYS_NOR0_CSPR_EARLY \
- (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \
- CSPR_PORT_SIZE_16 | \
- CSPR_MSEL_NOR | \
- CSPR_V)
-#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12)
-#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x1) | \
- FTIM0_NOR_TEADC(0x1) | \
- FTIM0_NOR_TEAHC(0x1))
-#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x1) | \
- FTIM1_NOR_TRAD_NOR(0x1))
-#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x0) | \
- FTIM2_NOR_TCH(0x0) | \
- FTIM2_NOR_TWP(0x1))
-#define CONFIG_SYS_NOR_FTIM3 0x04000000
-#define CONFIG_SYS_IFC_CCR 0x01000000
+#define CONFIG_SYS_FLASH1_BASE_PHYS 0xC0000000
+#define CONFIG_SYS_FLASH1_BASE_PHYS_EARLY 0x8000000
#ifndef CONFIG_SYS_NO_FLASH
#define CONFIG_FLASH_CFI_DRIVER
#define CONFIG_SYS_FLASH_CFI
#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
#define CONFIG_SYS_FLASH_QUIET_TEST
-#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */
-
-#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */
-#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */
-#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */
-#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */
+#endif
-#define CONFIG_SYS_FLASH_EMPTY_INFO
-#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
+#ifndef __ASSEMBLY__
+unsigned long long get_qixis_addr(void);
#endif
+#define QIXIS_BASE get_qixis_addr()
+#define QIXIS_BASE_PHYS 0x20000000
+#define QIXIS_BASE_PHYS_EARLY 0xC000000
+#define QIXIS_STAT_PRES1 0xb
+#define QIXIS_SDID_MASK 0x07
+#define QIXIS_ESDHC_NO_ADAPTER 0x7
+
+#define CONFIG_SYS_NAND_BASE 0x530000000ULL
+#define CONFIG_SYS_NAND_BASE_PHYS 0x30000000
-#define CONFIG_NAND_FSL_IFC
-#define CONFIG_SYS_NAND_MAX_ECCPOS 256
-#define CONFIG_SYS_NAND_MAX_OOBFREE 2
-#define CONFIG_SYS_NAND_BASE 0x520000000
-#define CONFIG_SYS_NAND_BASE_PHYS 0x20000000
-
-#define CONFIG_SYS_NAND_CSPR_EXT (0x0)
-#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \
- | CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \
- | CSPR_MSEL_NAND /* MSEL = NAND */ \
- | CSPR_V)
-#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024)
-
-#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 = 2Byes */ \
- | CSOR_NAND_PGS_2K /* Page Size = 2K */ \
- | CSOR_NAND_SPRZ_64/* Spare size = 64 */ \
- | CSOR_NAND_PB(64)) /*Pages Per Block = 64*/
-
-#define CONFIG_SYS_NAND_ONFI_DETECTION
-
-/* ONFI NAND Flash mode0 Timing Params */
-#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x07) | \
- FTIM0_NAND_TWP(0x18) | \
- FTIM0_NAND_TWCHT(0x07) | \
- FTIM0_NAND_TWH(0x0a))
-#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x32) | \
- FTIM1_NAND_TWBE(0x39) | \
- FTIM1_NAND_TRR(0x0e) | \
- FTIM1_NAND_TRP(0x18))
-#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x0f) | \
- FTIM2_NAND_TREH(0x0a) | \
- FTIM2_NAND_TWHRE(0x1e))
-#define CONFIG_SYS_NAND_FTIM3 0x0
-
-#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
-#define CONFIG_SYS_MAX_NAND_DEVICE 1
-#define CONFIG_CMD_NAND
-
-#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024)
-
-#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT
-#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY
-#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR
-#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK
-#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR
-#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0
-#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1
-#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2
-#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3
+/* Debug Server firmware */
+#define CONFIG_SYS_DEBUG_SERVER_DRAM_BLOCK_MIN_SIZE (512UL * 1024 * 1024)
+/* 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)
-#define CONFIG_SYS_LS_MC_FW_IN_NOR
-#define CONFIG_SYS_LS_MC_FW_ADDR 0x580200000ULL
-#define CONFIG_SYS_LS_MC_DPL_IN_NOR
-#define CONFIG_SYS_LS_MC_DPL_ADDR 0x5806C0000ULL
/* TODO Actual DPL max length needs to be confirmed with the MC FW team */
-#define CONFIG_SYS_LS_MC_DPL_MAX_LENGTH (256 * 1024)
-#define CONFIG_SYS_LS_MC_DRAM_DPL_OFFSET 0xe00000
-
-/* Carve the MC private DRAM block from the end of DRAM */
-#ifdef CONFIG_FSL_MC_ENET
-#define CONFIG_SYS_MEM_TOP_HIDE mc_get_dram_block_size()
+#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
+
+/* Carve out a DDR region which will not be used by u-boot/Linux */
+#if defined(CONFIG_FSL_MC_ENET) || defined(CONFIG_FSL_DEBUG_SERVER)
+#define CONFIG_SYS_MEM_TOP_HIDE get_dram_size_to_hide()
#endif
+/* PCIe */
+#define CONFIG_PCIE1 /* PCIE controler 1 */
+#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_SYS_PCI_64BIT
+
+#define CONFIG_SYS_PCIE_CFG0_PHYS_OFF 0x00000000
+#define CONFIG_SYS_PCIE_CFG0_SIZE 0x00001000 /* 4k */
+#define CONFIG_SYS_PCIE_CFG1_PHYS_OFF 0x00001000
+#define CONFIG_SYS_PCIE_CFG1_SIZE 0x00001000 /* 4k */
+
+#define CONFIG_SYS_PCIE_IO_BUS 0x00000000
+#define CONFIG_SYS_PCIE_IO_PHYS_OFF 0x00010000
+#define CONFIG_SYS_PCIE_IO_SIZE 0x00010000 /* 64k */
+
+#define CONFIG_SYS_PCIE_MEM_BUS 0x40000000
+#define CONFIG_SYS_PCIE_MEM_PHYS_OFF 0x40000000
+#define CONFIG_SYS_PCIE_MEM_SIZE 0x40000000 /* 1G */
+
/* Command line configuration */
#define CONFIG_CMD_CACHE
#define CONFIG_CMD_BDI
@@ -228,6 +210,7 @@
#define CONFIG_CMD_ENV
#define CONFIG_CMD_FLASH
#define CONFIG_CMD_IMI
+#define CONFIG_CMD_LOADB
#define CONFIG_CMD_MEMORY
#define CONFIG_CMD_MII
#define CONFIG_CMD_NET
@@ -237,8 +220,6 @@
#define CONFIG_CMD_BOOTD
#define CONFIG_CMD_ECHO
#define CONFIG_CMD_SOURCE
-#define CONFIG_CMD_FAT
-#define CONFIG_DOS_PARTITION
/* Miscellaneous configurable options */
#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_DDR_SDRAM_BASE + 0x10000000)
@@ -247,9 +228,6 @@
/* Physical Memory Map */
/* fixme: these need to be checked against the board */
#define CONFIG_CHIP_SELECTS_PER_CTRL 4
-#define CONFIG_SYS_CLK_FREQ 100000000
-#define CONFIG_DDR_CLK_FREQ 133333333
-
#define CONFIG_NR_DRAM_BANKS 3
@@ -265,7 +243,7 @@
"kernel_addr=0x100000\0" \
"ramdisk_addr=0x800000\0" \
"ramdisk_size=0x2000000\0" \
- "fdt_high=0xffffffffffffffff\0" \
+ "fdt_high=0xa0000000\0" \
"initrd_high=0xffffffffffffffff\0" \
"kernel_start=0x581200000\0" \
"kernel_load=0xa0000000\0" \
@@ -278,15 +256,11 @@
"hugepages=16"
#define CONFIG_BOOTCOMMAND "cp.b $kernel_start $kernel_load " \
"$kernel_size && bootm $kernel_load"
-#define CONFIG_BOOTDELAY 1
-
-/* Store environment at top of flash */
-#define CONFIG_ENV_IS_NOWHERE 1
-#define CONFIG_ENV_SIZE 0x1000
+#define CONFIG_BOOTDELAY 10
/* Monitor Command Prompt */
#define CONFIG_SYS_CBSIZE 512 /* Console I/O Buffer Size */
-#define CONFIG_SYS_PROMPT "> "
+#define CONFIG_SYS_PROMPT "=> "
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
sizeof(CONFIG_SYS_PROMPT) + 16)
#define CONFIG_SYS_HUSH_PARSER
@@ -294,10 +268,36 @@
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot args buffer */
#define CONFIG_SYS_LONGHELP
#define CONFIG_CMDLINE_EDITING 1
+#define CONFIG_AUTO_COMPLETE
#define CONFIG_SYS_MAXARGS 64 /* max command args */
#ifndef __ASSEMBLY__
-unsigned long mc_get_dram_block_size(void);
+unsigned long get_dram_size_to_hide(void);
#endif
+#define CONFIG_PANIC_HANG /* do not reset board on panic */
+
+#define CONFIG_SPL_BSS_START_ADDR 0x80100000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x00100000
+#define CONFIG_SPL_DRIVERS_MISC_SUPPORT
+#define CONFIG_SPL_ENV_SUPPORT
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_I2C_SUPPORT
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv8/u-boot-spl.lds"
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_MAX_SIZE 0x16000
+#define CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_STACK (CONFIG_SYS_FSL_OCRAM_BASE + 0x9ff0)
+#define CONFIG_SPL_TARGET "u-boot-with-spl.bin"
+#define CONFIG_SPL_TEXT_BASE 0x1800a000
+
+#define CONFIG_SYS_NAND_U_BOOT_DST 0x80400000
+#define CONFIG_SYS_NAND_U_BOOT_START CONFIG_SYS_NAND_U_BOOT_DST
+#define CONFIG_SYS_SPL_MALLOC_SIZE 0x00100000
+#define CONFIG_SYS_SPL_MALLOC_START 0x80200000
+#define CONFIG_SYS_MONITOR_LEN (512 * 1024)
+
#endif /* __LS2_COMMON_H */
diff --git a/include/configs/ls2085a_emu.h b/include/configs/ls2085a_emu.h
index a02d694..2d68e1b 100644
--- a/include/configs/ls2085a_emu.h
+++ b/include/configs/ls2085a_emu.h
@@ -12,6 +12,12 @@
#define CONFIG_IDENT_STRING " LS2085A-EMU"
#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-EMU"
+#define CONFIG_SYS_CLK_FREQ 100000000
+#define CONFIG_DDR_CLK_FREQ 133333333
+
+#define CONFIG_SYS_MXC_I2C1_SPEED 40000000
+#define CONFIG_SYS_MXC_I2C2_SPEED 40000000
+
#define CONFIG_DDR_SPD
#define CONFIG_SYS_FSL_DDR_EMU /* Support emulator */
#define SPD_EEPROM_ADDRESS1 0x51
@@ -19,6 +25,65 @@
#define SPD_EEPROM_ADDRESS3 0x53
#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1
#define CONFIG_SYS_SPD_BUS_NUM 1 /* SPD on I2C bus 1 */
+#define CONFIG_DIMM_SLOTS_PER_CTLR 1
+#define CONFIG_CHIP_SELECTS_PER_CTRL 4
+#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1
#define CONFIG_FSL_DDR_SYNC_REFRESH
+
+#define CONFIG_SYS_NOR0_CSPR_EXT (0x0)
+#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024)
+/*
+ * NOR Flash Timing Params
+ */
+#define CONFIG_SYS_NOR0_CSPR \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR0_CSPR_EARLY \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12)
+#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x1) | \
+ FTIM0_NOR_TEADC(0x1) | \
+ FTIM0_NOR_TEAHC(0x1))
+#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x1) | \
+ FTIM1_NOR_TRAD_NOR(0x1))
+#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x0) | \
+ FTIM2_NOR_TCH(0x0) | \
+ FTIM2_NOR_TWP(0x1))
+#define CONFIG_SYS_NOR_FTIM3 0x04000000
+#define CONFIG_SYS_IFC_CCR 0x01000000
+
+#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT
+#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY
+#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR
+#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK
+#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR
+#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0
+#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1
+#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2
+#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3
+
+/* Debug Server firmware */
+#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
+#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580C00000ULL
+
+/*
+ * This trick allows users to load MC images into DDR directly without
+ * copying from NOR flash. It dramatically improves speed.
+ */
+#define CONFIG_SYS_LS_MC_FW_IN_DDR
+#define CONFIG_SYS_LS_MC_DPL_IN_DDR
+#define CONFIG_SYS_LS_MC_DPC_IN_DDR
+
+#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 200000
+
+/* Store environment at top of flash */
+#define CONFIG_ENV_IS_NOWHERE 1
+#define CONFIG_ENV_SIZE 0x1000
+
#endif /* __LS2_EMU_H */
diff --git a/include/configs/ls2085a_simu.h b/include/configs/ls2085a_simu.h
index af34f3f..d0d2eed 100644
--- a/include/configs/ls2085a_simu.h
+++ b/include/configs/ls2085a_simu.h
@@ -12,10 +12,112 @@
#define CONFIG_IDENT_STRING " LS2085A-SIMU"
#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-SIMU"
+#define CONFIG_SYS_CLK_FREQ 100000000
+#define CONFIG_DDR_CLK_FREQ 133333333
+
+#define CONFIG_SYS_MXC_I2C1_SPEED 40000000
+#define CONFIG_SYS_MXC_I2C2_SPEED 40000000
+
+#define CONFIG_DIMM_SLOTS_PER_CTLR 1
+#define CONFIG_CHIP_SELECTS_PER_CTRL 4
+#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1
+
/* SMSC 91C111 ethernet configuration */
#define CONFIG_SMC91111
#define CONFIG_SMC91111_BASE (0x2210000)
+#define CONFIG_SYS_NOR0_CSPR_EXT (0x0)
+#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024)
+
+/*
+ * NOR Flash Timing Params
+ */
+#define CONFIG_SYS_NOR0_CSPR \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR0_CSPR_EARLY \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12)
+#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x1) | \
+ FTIM0_NOR_TEADC(0x1) | \
+ FTIM0_NOR_TEAHC(0x1))
+#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x1) | \
+ FTIM1_NOR_TRAD_NOR(0x1))
+#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x0) | \
+ FTIM2_NOR_TCH(0x0) | \
+ FTIM2_NOR_TWP(0x1))
+#define CONFIG_SYS_NOR_FTIM3 0x04000000
+#define CONFIG_SYS_IFC_CCR 0x01000000
+
+#ifndef CONFIG_SYS_NO_FLASH
+#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */
+
+#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */
+#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */
+#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */
+#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */
+
+#define CONFIG_SYS_FLASH_EMPTY_INFO
+#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE }
+#endif
+
+#define CONFIG_NAND_FSL_IFC
+#define CONFIG_SYS_NAND_MAX_ECCPOS 256
+#define CONFIG_SYS_NAND_MAX_OOBFREE 2
+
+
+#define CONFIG_SYS_NAND_CSPR_EXT (0x0)
+#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \
+ | CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \
+ | CSPR_MSEL_NAND /* MSEL = NAND */ \
+ | CSPR_V)
+#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024)
+
+#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 = 2Byes */ \
+ | CSOR_NAND_PGS_2K /* Page Size = 2K */ \
+ | CSOR_NAND_SPRZ_64/* Spare size = 64 */ \
+ | CSOR_NAND_PB(64)) /*Pages Per Block = 64*/
+
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+
+/* ONFI NAND Flash mode0 Timing Params */
+#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x07) | \
+ FTIM0_NAND_TWP(0x18) | \
+ FTIM0_NAND_TWCHT(0x07) | \
+ FTIM0_NAND_TWH(0x0a))
+#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x32) | \
+ FTIM1_NAND_TWBE(0x39) | \
+ FTIM1_NAND_TRR(0x0e) | \
+ FTIM1_NAND_TRP(0x18))
+#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x0f) | \
+ FTIM2_NAND_TREH(0x0a) | \
+ FTIM2_NAND_TWHRE(0x1e))
+#define CONFIG_SYS_NAND_FTIM3 0x0
+
+#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_MTD_NAND_VERIFY_WRITE
+#define CONFIG_CMD_NAND
+
+#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024)
+
+#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT
+#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY
+#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR
+#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK
+#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR
+#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0
+#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1
+#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2
+#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3
#define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_NAND_CSPR_EXT
#define CONFIG_SYS_CSPR1 CONFIG_SYS_NAND_CSPR
#define CONFIG_SYS_AMASK1 CONFIG_SYS_NAND_AMASK
@@ -25,4 +127,24 @@
#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NAND_FTIM2
#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NAND_FTIM3
+/* Debug Server firmware */
+#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
+#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580C00000ULL
+
+/* MC firmware */
+#define CONFIG_SYS_LS_MC_FW_IN_NOR
+#define CONFIG_SYS_LS_MC_FW_ADDR 0x580200000ULL
+
+#define CONFIG_SYS_LS_MC_DPL_IN_NOR
+#define CONFIG_SYS_LS_MC_DPL_ADDR 0x5806C0000ULL
+
+#define CONFIG_SYS_LS_MC_DPC_IN_NOR
+#define CONFIG_SYS_LS_MC_DPC_ADDR 0x5806F8000ULL
+
+#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 200000
+
+/* Store environment at top of flash */
+#define CONFIG_ENV_IS_NOWHERE 1
+#define CONFIG_ENV_SIZE 0x1000
+
#endif /* __LS2_SIMU_H */
diff --git a/include/configs/ls2085aqds.h b/include/configs/ls2085aqds.h
new file mode 100644
index 0000000..711d529
--- /dev/null
+++ b/include/configs/ls2085aqds.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LS2_QDS_H
+#define __LS2_QDS_H
+
+#include "ls2085a_common.h"
+#include <config_cmd_default.h>
+
+#define CONFIG_IDENT_STRING " LS2085A-QDS"
+#define CONFIG_BOOTP_VCI_STRING "U-boot.LS2085A-QDS"
+
+#define CONFIG_DISPLAY_BOARDINFO
+
+#ifndef __ASSEMBLY__
+unsigned long get_board_sys_clk(void);
+unsigned long get_board_ddr_clk(void);
+#endif
+
+#define CONFIG_SYS_CLK_FREQ get_board_sys_clk()
+#define CONFIG_DDR_CLK_FREQ get_board_ddr_clk()
+#define COUNTER_FREQUENCY_REAL (CONFIG_SYS_CLK_FREQ/4)
+
+#define CONFIG_DDR_SPD
+#define CONFIG_DDR_ECC
+#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER
+#define CONFIG_MEM_INIT_VALUE 0xdeadbeef
+#define SPD_EEPROM_ADDRESS1 0x51
+#define SPD_EEPROM_ADDRESS2 0x52
+#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_SPD_BUS_NUM 0 /* SPD on I2C bus 0 */
+#define CONFIG_DIMM_SLOTS_PER_CTLR 2
+#define CONFIG_CHIP_SELECTS_PER_CTRL 4
+#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1
+#define CONFIG_FSL_DDR_BIST /* enable built-in memory test */
+
+/* undefined CONFIG_FSL_DDR_SYNC_REFRESH for simulator */
+
+#define CONFIG_SYS_NOR0_CSPR_EXT (0x0)
+#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024)
+#define CONFIG_SYS_NOR_AMASK_EARLY IFC_AMASK(64*1024*1024)
+
+#define CONFIG_SYS_NOR0_CSPR \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR0_CSPR_EARLY \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR1_CSPR \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH1_BASE_PHYS) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR1_CSPR_EARLY \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH1_BASE_PHYS_EARLY) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12)
+#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x4) | \
+ FTIM0_NOR_TEADC(0x5) | \
+ FTIM0_NOR_TEAHC(0x5))
+#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x35) | \
+ FTIM1_NOR_TRAD_NOR(0x1a) |\
+ FTIM1_NOR_TSEQRAD_NOR(0x13))
+#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x4) | \
+ FTIM2_NOR_TCH(0x4) | \
+ FTIM2_NOR_TWPH(0x0E) | \
+ FTIM2_NOR_TWP(0x1c))
+#define CONFIG_SYS_NOR_FTIM3 0x04000000
+#define CONFIG_SYS_IFC_CCR 0x01000000
+
+#ifndef CONFIG_SYS_NO_FLASH
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+#define CONFIG_SYS_FLASH_QUIET_TEST
+#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */
+
+#define CONFIG_SYS_MAX_FLASH_BANKS 2 /* number of banks */
+#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */
+#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */
+#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */
+
+#define CONFIG_SYS_FLASH_EMPTY_INFO
+#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE,\
+ CONFIG_SYS_FLASH_BASE + 0x40000000}
+#endif
+
+#define CONFIG_NAND_FSL_IFC
+#define CONFIG_SYS_NAND_MAX_ECCPOS 256
+#define CONFIG_SYS_NAND_MAX_OOBFREE 2
+
+
+#define CONFIG_SYS_NAND_CSPR_EXT (0x0)
+#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \
+ | CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \
+ | CSPR_MSEL_NAND /* MSEL = NAND */ \
+ | CSPR_V)
+#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024)
+
+#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 = 3Byes */ \
+ | CSOR_NAND_PGS_2K /* Page Size = 2K */ \
+ | CSOR_NAND_SPRZ_64/* Spare size = 64 */ \
+ | CSOR_NAND_PB(64)) /*Pages Per Block = 64*/
+
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+
+/* ONFI NAND Flash mode0 Timing Params */
+#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x07) | \
+ FTIM0_NAND_TWP(0x18) | \
+ FTIM0_NAND_TWCHT(0x07) | \
+ FTIM0_NAND_TWH(0x0a))
+#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x32) | \
+ FTIM1_NAND_TWBE(0x39) | \
+ FTIM1_NAND_TRR(0x0e) | \
+ FTIM1_NAND_TRP(0x18))
+#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x0f) | \
+ FTIM2_NAND_TREH(0x0a) | \
+ FTIM2_NAND_TWHRE(0x1e))
+#define CONFIG_SYS_NAND_FTIM3 0x0
+
+#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_MTD_NAND_VERIFY_WRITE
+#define CONFIG_CMD_NAND
+
+#define CONFIG_SYS_NAND_BLOCK_SIZE (128 * 1024)
+
+#define CONFIG_FSL_QIXIS /* use common QIXIS code */
+#define QIXIS_LBMAP_SWITCH 0x06
+#define QIXIS_LBMAP_MASK 0x0f
+#define QIXIS_LBMAP_SHIFT 0
+#define QIXIS_LBMAP_DFLTBANK 0x00
+#define QIXIS_LBMAP_ALTBANK 0x04
+#define QIXIS_LBMAP_NAND 0x09
+#define QIXIS_RST_CTL_RESET 0x31
+#define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20
+#define QIXIS_RCFG_CTL_RECONFIG_START 0x21
+#define QIXIS_RCFG_CTL_WATCHDOG_ENBLE 0x08
+#define QIXIS_RCW_SRC_NAND 0x107
+#define QIXIS_RST_FORCE_MEM 0x01
+
+#define CONFIG_SYS_CSPR3_EXT (0x0)
+#define CONFIG_SYS_CSPR3 (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS_EARLY) \
+ | CSPR_PORT_SIZE_8 \
+ | CSPR_MSEL_GPCM \
+ | CSPR_V)
+#define CONFIG_SYS_CSPR3_FINAL (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS) \
+ | CSPR_PORT_SIZE_8 \
+ | CSPR_MSEL_GPCM \
+ | CSPR_V)
+
+#define CONFIG_SYS_AMASK3 IFC_AMASK(64*1024)
+#define CONFIG_SYS_CSOR3 CSOR_GPCM_ADM_SHIFT(12)
+/* QIXIS Timing parameters for IFC CS3 */
+#define CONFIG_SYS_CS3_FTIM0 (FTIM0_GPCM_TACSE(0x0e) | \
+ FTIM0_GPCM_TEADC(0x0e) | \
+ FTIM0_GPCM_TEAHC(0x0e))
+#define CONFIG_SYS_CS3_FTIM1 (FTIM1_GPCM_TACO(0xff) | \
+ FTIM1_GPCM_TRAD(0x3f))
+#define CONFIG_SYS_CS3_FTIM2 (FTIM2_GPCM_TCS(0xf) | \
+ FTIM2_GPCM_TCH(0xf) | \
+ FTIM2_GPCM_TWP(0x3E))
+#define CONFIG_SYS_CS3_FTIM3 0x0
+
+#if defined(CONFIG_SPL) && defined(CONFIG_NAND)
+#define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_NOR0_CSPR_EXT
+#define CONFIG_SYS_CSPR1 CONFIG_SYS_NOR0_CSPR_EARLY
+#define CONFIG_SYS_CSPR1_FINAL CONFIG_SYS_NOR0_CSPR
+#define CONFIG_SYS_AMASK1 CONFIG_SYS_NOR_AMASK
+#define CONFIG_SYS_CSOR1 CONFIG_SYS_NOR_CSOR
+#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NOR_FTIM0
+#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NOR_FTIM1
+#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NOR_FTIM2
+#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NOR_FTIM3
+#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NOR0_CSPR_EXT
+#define CONFIG_SYS_CSPR2 CONFIG_SYS_NOR1_CSPR_EARLY
+#define CONFIG_SYS_CSPR2_FINAL CONFIG_SYS_NOR1_CSPR
+#define CONFIG_SYS_AMASK2 CONFIG_SYS_NOR_AMASK_EARLY
+#define CONFIG_SYS_AMASK2_FINAL CONFIG_SYS_NOR_AMASK
+#define CONFIG_SYS_CSOR2 CONFIG_SYS_NOR_CSOR
+#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NOR_FTIM0
+#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NOR_FTIM1
+#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NOR_FTIM2
+#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NOR_FTIM3
+#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NAND_CSPR_EXT
+#define CONFIG_SYS_CSPR0 CONFIG_SYS_NAND_CSPR
+#define CONFIG_SYS_AMASK0 CONFIG_SYS_NAND_AMASK
+#define CONFIG_SYS_CSOR0 CONFIG_SYS_NAND_CSOR
+#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NAND_FTIM0
+#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NAND_FTIM1
+#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NAND_FTIM2
+#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NAND_FTIM3
+
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET (896 * 1024)
+#define CONFIG_ENV_SECT_SIZE 0x20000
+#define CONFIG_ENV_SIZE 0x2000
+#define CONFIG_SPL_PAD_TO 0x20000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS (256 * 1024)
+#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 * 1024)
+#else
+#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT
+#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY
+#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR
+#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK
+#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR
+#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0
+#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1
+#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2
+#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3
+#define CONFIG_SYS_CSPR1_EXT CONFIG_SYS_NOR0_CSPR_EXT
+#define CONFIG_SYS_CSPR1 CONFIG_SYS_NOR1_CSPR_EARLY
+#define CONFIG_SYS_CSPR1_FINAL CONFIG_SYS_NOR1_CSPR
+#define CONFIG_SYS_AMASK1 CONFIG_SYS_NOR_AMASK_EARLY
+#define CONFIG_SYS_AMASK1_FINAL CONFIG_SYS_NOR_AMASK
+#define CONFIG_SYS_CSOR1 CONFIG_SYS_NOR_CSOR
+#define CONFIG_SYS_CS1_FTIM0 CONFIG_SYS_NOR_FTIM0
+#define CONFIG_SYS_CS1_FTIM1 CONFIG_SYS_NOR_FTIM1
+#define CONFIG_SYS_CS1_FTIM2 CONFIG_SYS_NOR_FTIM2
+#define CONFIG_SYS_CS1_FTIM3 CONFIG_SYS_NOR_FTIM3
+#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NAND_CSPR_EXT
+#define CONFIG_SYS_CSPR2 CONFIG_SYS_NAND_CSPR
+#define CONFIG_SYS_AMASK2 CONFIG_SYS_NAND_AMASK
+#define CONFIG_SYS_CSOR2 CONFIG_SYS_NAND_CSOR
+#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NAND_FTIM0
+#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NAND_FTIM1
+#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NAND_FTIM2
+#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NAND_FTIM3
+
+#define CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x200000)
+#define CONFIG_ENV_SECT_SIZE 0x20000
+#define CONFIG_ENV_SIZE 0x2000
+#endif
+
+/* Debug Server firmware */
+#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
+#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580D00000ULL
+
+/* MC firmware */
+#define CONFIG_SYS_LS_MC_FW_IN_NOR
+#define CONFIG_SYS_LS_MC_FW_ADDR 0x580300000ULL
+
+#define CONFIG_SYS_LS_MC_DPL_IN_NOR
+#define CONFIG_SYS_LS_MC_DPL_ADDR 0x580700000ULL
+
+#define CONFIG_SYS_LS_MC_DPC_IN_NOR
+#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL
+
+#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
+
+/*
+ * I2C
+ */
+#define I2C_MUX_PCA_ADDR 0x77
+#define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/
+
+/* I2C bus multiplexer */
+#define I2C_MUX_CH_DEFAULT 0x8
+
+/*
+ * MMC
+ */
+#ifdef CONFIG_MMC
+#define CONFIG_ESDHC_DETECT_QUIRK ((readb(QIXIS_BASE + QIXIS_STAT_PRES1) & \
+ QIXIS_SDID_MASK) != QIXIS_ESDHC_NO_ADAPTER)
+#endif
+
+/*
+ * RTC configuration
+ */
+#define RTC
+#define CONFIG_RTC_DS3231 1
+#define CONFIG_SYS_I2C_RTC_ADDR 0x68
+
+/* EEPROM */
+#define CONFIG_ID_EEPROM
+#define CONFIG_CMD_EEPROM
+#define CONFIG_SYS_I2C_EEPROM_NXID
+#define CONFIG_SYS_EEPROM_BUS_NUM 0
+#define CONFIG_SYS_I2C_EEPROM_ADDR 0x57
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5
+
+#define CONFIG_FSL_MEMAC
+#define CONFIG_PCI /* Enable PCIE */
+#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */
+
+#ifdef CONFIG_PCI
+#define CONFIG_NET_MULTI
+#define CONFIG_PCI_PNP
+#define CONFIG_E1000
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_NET
+#endif
+
+/* MMC */
+#define CONFIG_MMC
+#ifdef CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_FSL_ESDHC
+#define CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33
+#define CONFIG_GENERIC_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_DOS_PARTITION
+#endif
+
+/* Initial environment variables */
+#undef CONFIG_EXTRA_ENV_SETTINGS
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "hwconfig=fsl_ddr:bank_intlv=auto\0" \
+ "loadaddr=0x80100000\0" \
+ "kernel_addr=0x100000\0" \
+ "ramdisk_addr=0x800000\0" \
+ "ramdisk_size=0x2000000\0" \
+ "fdt_high=0xa0000000\0" \
+ "initrd_high=0xffffffffffffffff\0" \
+ "kernel_start=0x581100000\0" \
+ "kernel_load=0xa0000000\0" \
+ "kernel_size=0x1000000\0"
+
+#ifdef CONFIG_FSL_MC_ENET
+#define CONFIG_FSL_MEMAC
+#define CONFIG_PHYLIB
+#define CONFIG_PHYLIB_10G
+#define CONFIG_CMD_MII
+#define CONFIG_PHY_VITESSE
+#define CONFIG_PHY_REALTEK
+#define CONFIG_PHY_TERANETICS
+#define SGMII_CARD_PORT1_PHY_ADDR 0x1C
+#define SGMII_CARD_PORT2_PHY_ADDR 0x1d
+#define SGMII_CARD_PORT3_PHY_ADDR 0x1E
+#define SGMII_CARD_PORT4_PHY_ADDR 0x1F
+
+#define CONFIG_MII /* MII PHY management */
+#define CONFIG_ETHPRIME "DPNI1"
+#define CONFIG_PHY_GIGE /* Include GbE speed/duplex detection */
+
+#endif
+
+#endif /* __LS2_QDS_H */
diff --git a/include/configs/ls2085ardb.h b/include/configs/ls2085ardb.h
new file mode 100644
index 0000000..d1c2548
--- /dev/null
+++ b/include/configs/ls2085ardb.h
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LS2_RDB_H
+#define __LS2_RDB_H
+
+#include "ls2085a_common.h"
+#include <config_cmd_default.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_DISPLAY_BOARDINFO
+
+#ifndef __ASSEMBLY__
+unsigned long get_board_sys_clk(void);
+#endif
+
+#define CONFIG_SYS_CLK_FREQ get_board_sys_clk()
+#define CONFIG_DDR_CLK_FREQ 133333333
+#define COUNTER_FREQUENCY_REAL (CONFIG_SYS_CLK_FREQ/4)
+
+#define CONFIG_DDR_SPD
+#define CONFIG_DDR_ECC
+#define CONFIG_ECC_INIT_VIA_DDRCONTROLLER
+#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_ADDRESS5 0x55
+#define SPD_EEPROM_ADDRESS6 0x56 /* dummy address */
+#define SPD_EEPROM_ADDRESS SPD_EEPROM_ADDRESS1
+#define CONFIG_SYS_SPD_BUS_NUM 0 /* SPD on I2C bus 0 */
+#define CONFIG_DIMM_SLOTS_PER_CTLR 2
+#define CONFIG_CHIP_SELECTS_PER_CTRL 4
+#define CONFIG_DP_DDR_DIMM_SLOTS_PER_CTLR 1
+#define CONFIG_FSL_DDR_BIST /* enable built-in memory test */
+
+/* undefined CONFIG_FSL_DDR_SYNC_REFRESH for simulator */
+
+#define CONFIG_SYS_NOR0_CSPR_EXT (0x0)
+#define CONFIG_SYS_NOR_AMASK IFC_AMASK(128*1024*1024)
+#define CONFIG_SYS_NOR_AMASK_EARLY IFC_AMASK(64*1024*1024)
+
+#define CONFIG_SYS_NOR0_CSPR \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR0_CSPR_EARLY \
+ (CSPR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS_EARLY) | \
+ CSPR_PORT_SIZE_16 | \
+ CSPR_MSEL_NOR | \
+ CSPR_V)
+#define CONFIG_SYS_NOR_CSOR CSOR_NOR_ADM_SHIFT(12)
+#define CONFIG_SYS_NOR_FTIM0 (FTIM0_NOR_TACSE(0x4) | \
+ FTIM0_NOR_TEADC(0x5) | \
+ FTIM0_NOR_TEAHC(0x5))
+#define CONFIG_SYS_NOR_FTIM1 (FTIM1_NOR_TACO(0x35) | \
+ FTIM1_NOR_TRAD_NOR(0x1a) |\
+ FTIM1_NOR_TSEQRAD_NOR(0x13))
+#define CONFIG_SYS_NOR_FTIM2 (FTIM2_NOR_TCS(0x4) | \
+ FTIM2_NOR_TCH(0x4) | \
+ FTIM2_NOR_TWPH(0x0E) | \
+ FTIM2_NOR_TWP(0x1c))
+#define CONFIG_SYS_NOR_FTIM3 0x04000000
+#define CONFIG_SYS_IFC_CCR 0x01000000
+
+#ifndef CONFIG_SYS_NO_FLASH
+#define CONFIG_FLASH_CFI_DRIVER
+#define CONFIG_SYS_FLASH_CFI
+#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
+#define CONFIG_SYS_FLASH_QUIET_TEST
+#define CONFIG_FLASH_SHOW_PROGRESS 45 /* count down from 45/5: 9..1 */
+
+#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* number of banks */
+#define CONFIG_SYS_MAX_FLASH_SECT 1024 /* sectors per device */
+#define CONFIG_SYS_FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */
+#define CONFIG_SYS_FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */
+
+#define CONFIG_SYS_FLASH_EMPTY_INFO
+#define CONFIG_SYS_FLASH_BANKS_LIST { CONFIG_SYS_FLASH_BASE,\
+ CONFIG_SYS_FLASH_BASE + 0x40000000}
+#endif
+
+#define CONFIG_NAND_FSL_IFC
+#define CONFIG_SYS_NAND_MAX_ECCPOS 256
+#define CONFIG_SYS_NAND_MAX_OOBFREE 2
+
+
+#define CONFIG_SYS_NAND_CSPR_EXT (0x0)
+#define CONFIG_SYS_NAND_CSPR (CSPR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \
+ | CSPR_PORT_SIZE_8 /* Port Size = 8 bit */ \
+ | CSPR_MSEL_NAND /* MSEL = NAND */ \
+ | CSPR_V)
+#define CONFIG_SYS_NAND_AMASK IFC_AMASK(64 * 1024)
+
+#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 = 3Byes */ \
+ | CSOR_NAND_PGS_4K /* Page Size = 4K */ \
+ | CSOR_NAND_SPRZ_224 /* Spare size = 224 */ \
+ | CSOR_NAND_PB(128)) /* Pages Per Block 128*/
+
+#define CONFIG_SYS_NAND_ONFI_DETECTION
+
+/* ONFI NAND Flash mode0 Timing Params */
+#define CONFIG_SYS_NAND_FTIM0 (FTIM0_NAND_TCCST(0x0e) | \
+ FTIM0_NAND_TWP(0x30) | \
+ FTIM0_NAND_TWCHT(0x0e) | \
+ FTIM0_NAND_TWH(0x14))
+#define CONFIG_SYS_NAND_FTIM1 (FTIM1_NAND_TADLE(0x64) | \
+ FTIM1_NAND_TWBE(0xab) | \
+ FTIM1_NAND_TRR(0x1c) | \
+ FTIM1_NAND_TRP(0x30))
+#define CONFIG_SYS_NAND_FTIM2 (FTIM2_NAND_TRAD(0x1e) | \
+ FTIM2_NAND_TREH(0x14) | \
+ FTIM2_NAND_TWHRE(0x3c))
+#define CONFIG_SYS_NAND_FTIM3 0x0
+
+#define CONFIG_SYS_NAND_BASE_LIST { CONFIG_SYS_NAND_BASE }
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_MTD_NAND_VERIFY_WRITE
+#define CONFIG_CMD_NAND
+
+#define CONFIG_SYS_NAND_BLOCK_SIZE (512 * 1024)
+
+#define CONFIG_FSL_QIXIS /* use common QIXIS code */
+#define QIXIS_LBMAP_SWITCH 0x06
+#define QIXIS_LBMAP_MASK 0x0f
+#define QIXIS_LBMAP_SHIFT 0
+#define QIXIS_LBMAP_DFLTBANK 0x00
+#define QIXIS_LBMAP_ALTBANK 0x04
+#define QIXIS_LBMAP_NAND 0x09
+#define QIXIS_RST_CTL_RESET 0x31
+#define QIXIS_RST_CTL_RESET_EN 0x30
+#define QIXIS_RCFG_CTL_RECONFIG_IDLE 0x20
+#define QIXIS_RCFG_CTL_RECONFIG_START 0x21
+#define QIXIS_RCFG_CTL_WATCHDOG_ENBLE 0x08
+#define QIXIS_RCW_SRC_NAND 0x119
+#define QIXIS_RST_FORCE_MEM 0x01
+
+#define CONFIG_SYS_CSPR3_EXT (0x0)
+#define CONFIG_SYS_CSPR3 (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS_EARLY) \
+ | CSPR_PORT_SIZE_8 \
+ | CSPR_MSEL_GPCM \
+ | CSPR_V)
+#define CONFIG_SYS_CSPR3_FINAL (CSPR_PHYS_ADDR(QIXIS_BASE_PHYS) \
+ | CSPR_PORT_SIZE_8 \
+ | CSPR_MSEL_GPCM \
+ | CSPR_V)
+
+#define CONFIG_SYS_AMASK3 IFC_AMASK(64*1024)
+#define CONFIG_SYS_CSOR3 CSOR_GPCM_ADM_SHIFT(12)
+/* QIXIS Timing parameters for IFC CS3 */
+#define CONFIG_SYS_CS3_FTIM0 (FTIM0_GPCM_TACSE(0x0e) | \
+ FTIM0_GPCM_TEADC(0x0e) | \
+ FTIM0_GPCM_TEAHC(0x0e))
+#define CONFIG_SYS_CS3_FTIM1 (FTIM1_GPCM_TACO(0xff) | \
+ FTIM1_GPCM_TRAD(0x3f))
+#define CONFIG_SYS_CS3_FTIM2 (FTIM2_GPCM_TCS(0xf) | \
+ FTIM2_GPCM_TCH(0xf) | \
+ FTIM2_GPCM_TWP(0x3E))
+#define CONFIG_SYS_CS3_FTIM3 0x0
+
+#if defined(CONFIG_SPL) && defined(CONFIG_NAND)
+#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NOR0_CSPR_EXT
+#define CONFIG_SYS_CSPR2 CONFIG_SYS_NOR0_CSPR_EARLY
+#define CONFIG_SYS_CSPR2_FINAL CONFIG_SYS_NOR0_CSPR
+#define CONFIG_SYS_AMASK2 CONFIG_SYS_NOR_AMASK
+#define CONFIG_SYS_CSOR2 CONFIG_SYS_NOR_CSOR
+#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NOR_FTIM0
+#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NOR_FTIM1
+#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NOR_FTIM2
+#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NOR_FTIM3
+#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NAND_CSPR_EXT
+#define CONFIG_SYS_CSPR0 CONFIG_SYS_NAND_CSPR
+#define CONFIG_SYS_AMASK0 CONFIG_SYS_NAND_AMASK
+#define CONFIG_SYS_CSOR0 CONFIG_SYS_NAND_CSOR
+#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NAND_FTIM0
+#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NAND_FTIM1
+#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NAND_FTIM2
+#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NAND_FTIM3
+
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET (2048 * 1024)
+#define CONFIG_ENV_SECT_SIZE 0x20000
+#define CONFIG_ENV_SIZE 0x2000
+#define CONFIG_SPL_PAD_TO 0x80000
+#define CONFIG_SYS_NAND_U_BOOT_OFFS (1024 * 1024)
+#define CONFIG_SYS_NAND_U_BOOT_SIZE (512 * 1024)
+#else
+#define CONFIG_SYS_CSPR0_EXT CONFIG_SYS_NOR0_CSPR_EXT
+#define CONFIG_SYS_CSPR0 CONFIG_SYS_NOR0_CSPR_EARLY
+#define CONFIG_SYS_CSPR0_FINAL CONFIG_SYS_NOR0_CSPR
+#define CONFIG_SYS_AMASK0 CONFIG_SYS_NOR_AMASK
+#define CONFIG_SYS_CSOR0 CONFIG_SYS_NOR_CSOR
+#define CONFIG_SYS_CS0_FTIM0 CONFIG_SYS_NOR_FTIM0
+#define CONFIG_SYS_CS0_FTIM1 CONFIG_SYS_NOR_FTIM1
+#define CONFIG_SYS_CS0_FTIM2 CONFIG_SYS_NOR_FTIM2
+#define CONFIG_SYS_CS0_FTIM3 CONFIG_SYS_NOR_FTIM3
+#define CONFIG_SYS_CSPR2_EXT CONFIG_SYS_NAND_CSPR_EXT
+#define CONFIG_SYS_CSPR2 CONFIG_SYS_NAND_CSPR
+#define CONFIG_SYS_AMASK2 CONFIG_SYS_NAND_AMASK
+#define CONFIG_SYS_CSOR2 CONFIG_SYS_NAND_CSOR
+#define CONFIG_SYS_CS2_FTIM0 CONFIG_SYS_NAND_FTIM0
+#define CONFIG_SYS_CS2_FTIM1 CONFIG_SYS_NAND_FTIM1
+#define CONFIG_SYS_CS2_FTIM2 CONFIG_SYS_NAND_FTIM2
+#define CONFIG_SYS_CS2_FTIM3 CONFIG_SYS_NAND_FTIM3
+
+#define CONFIG_ENV_IS_IN_FLASH
+#define CONFIG_ENV_ADDR (CONFIG_SYS_FLASH_BASE + 0x200000)
+#define CONFIG_ENV_SECT_SIZE 0x20000
+#define CONFIG_ENV_SIZE 0x2000
+#endif
+
+/* Debug Server firmware */
+#define CONFIG_SYS_DEBUG_SERVER_FW_IN_NOR
+#define CONFIG_SYS_DEBUG_SERVER_FW_ADDR 0x580D00000ULL
+
+/* MC firmware */
+#define CONFIG_SYS_LS_MC_FW_IN_NOR
+#define CONFIG_SYS_LS_MC_FW_ADDR 0x580300000ULL
+
+#define CONFIG_SYS_LS_MC_DPL_IN_NOR
+#define CONFIG_SYS_LS_MC_DPL_ADDR 0x580700000ULL
+
+#define CONFIG_SYS_LS_MC_DPC_IN_NOR
+#define CONFIG_SYS_LS_MC_DPC_ADDR 0x580800000ULL
+
+#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000
+
+/*
+ * I2C
+ */
+#define I2C_MUX_PCA_ADDR 0x77
+#define I2C_MUX_PCA_ADDR_PRI 0x77 /* Primary Mux*/
+
+/* I2C bus multiplexer */
+#define I2C_MUX_CH_DEFAULT 0x8
+
+/*
+ * RTC configuration
+ */
+#define RTC
+#define CONFIG_RTC_DS3231 1
+#define CONFIG_SYS_I2C_RTC_ADDR 0x68
+
+/* EEPROM */
+#define CONFIG_ID_EEPROM
+#define CONFIG_CMD_EEPROM
+#define CONFIG_SYS_I2C_EEPROM_NXID
+#define CONFIG_SYS_EEPROM_BUS_NUM 0
+#define CONFIG_SYS_I2C_EEPROM_ADDR 0x57
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 1
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 3
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5
+
+#define CONFIG_FSL_MEMAC
+#define CONFIG_PCI /* Enable PCIE */
+#define CONFIG_PCIE_LAYERSCAPE /* Use common FSL Layerscape PCIe code */
+
+#ifdef CONFIG_PCI
+#define CONFIG_NET_MULTI
+#define CONFIG_PCI_PNP
+#define CONFIG_E1000
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_NET
+#endif
+
+/* MMC */
+#define CONFIG_MMC
+#ifdef CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_FSL_ESDHC
+#define CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33
+#define CONFIG_GENERIC_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_DOS_PARTITION
+#endif
+
+/* Initial environment variables */
+#undef CONFIG_EXTRA_ENV_SETTINGS
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "hwconfig=fsl_ddr:bank_intlv=auto\0" \
+ "loadaddr=0x80100000\0" \
+ "kernel_addr=0x100000\0" \
+ "ramdisk_addr=0x800000\0" \
+ "ramdisk_size=0x2000000\0" \
+ "fdt_high=0xa0000000\0" \
+ "initrd_high=0xffffffffffffffff\0" \
+ "kernel_start=0x581100000\0" \
+ "kernel_load=0xa0000000\0" \
+ "kernel_size=0x1000000\0"
+
+#endif /* __LS2_RDB_H */
diff --git a/include/configs/m53evk.h b/include/configs/m53evk.h
index c133ba9..c348d38 100644
--- a/include/configs/m53evk.h
+++ b/include/configs/m53evk.h
@@ -176,6 +176,7 @@
#ifdef CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_RTC_BUS_NUM 1 /* I2C2 */
#endif
diff --git a/include/configs/mx35pdk.h b/include/configs/mx35pdk.h
index f8cd39d..244a9ab 100644
--- a/include/configs/mx35pdk.h
+++ b/include/configs/mx35pdk.h
@@ -42,6 +42,7 @@
*/
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_MXC_SPI
#define CONFIG_MXC_GPIO
diff --git a/include/configs/mx53ard.h b/include/configs/mx53ard.h
index 9b003fc..7c3dc20 100644
--- a/include/configs/mx53ard.h
+++ b/include/configs/mx53ard.h
@@ -48,6 +48,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
/* MMC Configs */
#define CONFIG_FSL_ESDHC
diff --git a/include/configs/mx53evk.h b/include/configs/mx53evk.h
index fb2072d..22a9fc4 100644
--- a/include/configs/mx53evk.h
+++ b/include/configs/mx53evk.h
@@ -41,6 +41,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
/* PMIC Configs */
#define CONFIG_POWER
diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h
index 3551e02..a56e72e 100644
--- a/include/configs/mx53loco.h
+++ b/include/configs/mx53loco.h
@@ -76,6 +76,7 @@
/* I2C Configs */
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
/* PMIC Controller */
#define CONFIG_POWER
diff --git a/include/configs/mx53smd.h b/include/configs/mx53smd.h
index 3da0ef4..0785491 100644
--- a/include/configs/mx53smd.h
+++ b/include/configs/mx53smd.h
@@ -38,6 +38,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
/* MMC Configs */
#define CONFIG_FSL_ESDHC
diff --git a/include/configs/mx6qsabreauto.h b/include/configs/mx6qsabreauto.h
index 51042ca..2260344 100644
--- a/include/configs/mx6qsabreauto.h
+++ b/include/configs/mx6qsabreauto.h
@@ -56,6 +56,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* NAND flash command */
diff --git a/include/configs/mx6sabresd.h b/include/configs/mx6sabresd.h
index 99d9d4d..dab2fd2 100644
--- a/include/configs/mx6sabresd.h
+++ b/include/configs/mx6sabresd.h
@@ -52,6 +52,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* PMIC */
diff --git a/include/configs/mx6slevk.h b/include/configs/mx6slevk.h
index dad49f9..cd023de 100644
--- a/include/configs/mx6slevk.h
+++ b/include/configs/mx6slevk.h
@@ -52,6 +52,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* PMIC */
diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h
index a29d62f..248303c 100644
--- a/include/configs/mx6sxsabresd.h
+++ b/include/configs/mx6sxsabresd.h
@@ -176,6 +176,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* PMIC */
diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h
index 8ef4b73..883d8a7 100644
--- a/include/configs/nitrogen6x.h
+++ b/include/configs/nitrogen6x.h
@@ -63,6 +63,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
#define CONFIG_I2C_EDID
diff --git a/include/configs/novena.h b/include/configs/novena.h
index 3809c6c..5f83469 100644
--- a/include/configs/novena.h
+++ b/include/configs/novena.h
@@ -141,6 +141,7 @@
/* I2C */
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_I2C_MULTI_BUS
#define CONFIG_I2C_MXC
#define CONFIG_SYS_I2C_SPEED 100000
diff --git a/include/configs/ot1200.h b/include/configs/ot1200.h
index 3c60b4f..200f40a 100644
--- a/include/configs/ot1200.h
+++ b/include/configs/ot1200.h
@@ -62,6 +62,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* OCOTP Configs */
diff --git a/include/configs/platinum.h b/include/configs/platinum.h
index 134bb45..91ffc7c 100644
--- a/include/configs/platinum.h
+++ b/include/configs/platinum.h
@@ -62,6 +62,7 @@
/* I2C config */
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* MMC config */
diff --git a/include/configs/tbs2910.h b/include/configs/tbs2910.h
index 7089378..3a88f22 100644
--- a/include/configs/tbs2910.h
+++ b/include/configs/tbs2910.h
@@ -199,6 +199,7 @@
#ifdef CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
#define CONFIG_I2C_EDID
#endif
diff --git a/include/configs/titanium.h b/include/configs/titanium.h
index f9e00c5..320d76c 100644
--- a/include/configs/titanium.h
+++ b/include/configs/titanium.h
@@ -44,6 +44,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* MMC Configs */
diff --git a/include/configs/tqma6.h b/include/configs/tqma6.h
index a099687..99c5f82 100644
--- a/include/configs/tqma6.h
+++ b/include/configs/tqma6.h
@@ -80,6 +80,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_I2C_MULTI_BUS
#define CONFIG_SYS_I2C_SPEED 100000
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
index b586803..b2c3614 100644
--- a/include/configs/wandboard.h
+++ b/include/configs/wandboard.h
@@ -62,6 +62,7 @@
#define CONFIG_CMD_I2C
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_I2C_SPEED 100000
/* MMC Configuration */
diff --git a/include/configs/woodburn_common.h b/include/configs/woodburn_common.h
index 48b8692..d0895cf 100644
--- a/include/configs/woodburn_common.h
+++ b/include/configs/woodburn_common.h
@@ -47,6 +47,7 @@
*/
#define CONFIG_SYS_I2C
#define CONFIG_SYS_I2C_MXC
+#define CONFIG_SYS_I2C_MXC_I2C3 /* enable I2C bus 3 */
#define CONFIG_SYS_SPD_BUS_NUM 0
#define CONFIG_MXC_SPI
#define CONFIG_MXC_GPIO
diff --git a/include/fsl-mc/fsl_dpaa_fd.h b/include/fsl-mc/fsl_dpaa_fd.h
new file mode 100644
index 0000000..6d0ffa8
--- /dev/null
+++ b/include/fsl-mc/fsl_dpaa_fd.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef __FSL_DPAA_FD_H
+#define __FSL_DPAA_FD_H
+
+/* Place-holder for FDs, we represent it via the simplest form that we need for
+ * now. Different overlays may be needed to support different options, etc. (It
+ * is impractical to define One True Struct, because the resulting encoding
+ * routines (lots of read-modify-writes) would be worst-case performance whether
+ * or not circumstances required them.) */
+struct dpaa_fd {
+ union {
+ u32 words[8];
+ struct dpaa_fd_simple {
+ u32 addr_lo;
+ u32 addr_hi;
+ u32 len;
+ /* offset in the MS 16 bits, BPID in the LS 16 bits */
+ u32 bpid_offset;
+ u32 frc; /* frame context */
+ /* "err", "va", "cbmt", "asal", [...] */
+ u32 ctrl;
+ /* flow context */
+ u32 flc_lo;
+ u32 flc_hi;
+ } simple;
+ };
+};
+
+enum dpaa_fd_format {
+ dpaa_fd_single = 0,
+ dpaa_fd_list,
+ dpaa_fd_sg
+};
+
+static inline u64 ldpaa_fd_get_addr(const struct dpaa_fd *fd)
+{
+ return (u64)((((uint64_t)fd->simple.addr_hi) << 32)
+ + fd->simple.addr_lo);
+}
+
+static inline void ldpaa_fd_set_addr(struct dpaa_fd *fd, u64 addr)
+{
+ fd->simple.addr_hi = upper_32_bits(addr);
+ fd->simple.addr_lo = lower_32_bits(addr);
+}
+
+static inline u32 ldpaa_fd_get_len(const struct dpaa_fd *fd)
+{
+ return fd->simple.len;
+}
+
+static inline void ldpaa_fd_set_len(struct dpaa_fd *fd, u32 len)
+{
+ fd->simple.len = len;
+}
+
+static inline uint16_t ldpaa_fd_get_offset(const struct dpaa_fd *fd)
+{
+ return (uint16_t)(fd->simple.bpid_offset >> 16) & 0x0FFF;
+}
+
+static inline void ldpaa_fd_set_offset(struct dpaa_fd *fd, uint16_t offset)
+{
+ fd->simple.bpid_offset &= 0xF000FFFF;
+ fd->simple.bpid_offset |= (u32)offset << 16;
+}
+
+static inline uint16_t ldpaa_fd_get_bpid(const struct dpaa_fd *fd)
+{
+ return (uint16_t)(fd->simple.bpid_offset & 0xFFFF);
+}
+
+static inline void ldpaa_fd_set_bpid(struct dpaa_fd *fd, uint16_t bpid)
+{
+ fd->simple.bpid_offset &= 0xFFFF0000;
+ fd->simple.bpid_offset |= (u32)bpid;
+}
+
+/* When frames are dequeued, the FDs show up inside "dequeue" result structures
+ * (if at all, not all dequeue results contain valid FDs). This structure type
+ * is intentionally defined without internal detail, and the only reason it
+ * isn't declared opaquely (without size) is to allow the user to provide
+ * suitably-sized (and aligned) memory for these entries. */
+struct ldpaa_dq {
+ uint32_t dont_manipulate_directly[16];
+};
+
+/* Parsing frame dequeue results */
+#define LDPAA_DQ_STAT_FQEMPTY 0x80
+#define LDPAA_DQ_STAT_HELDACTIVE 0x40
+#define LDPAA_DQ_STAT_FORCEELIGIBLE 0x20
+#define LDPAA_DQ_STAT_VALIDFRAME 0x10
+#define LDPAA_DQ_STAT_ODPVALID 0x04
+#define LDPAA_DQ_STAT_VOLATILE 0x02
+#define LDPAA_DQ_STAT_EXPIRED 0x01
+uint32_t ldpaa_dq_flags(const struct ldpaa_dq *);
+static inline int ldpaa_dq_is_pull(const struct ldpaa_dq *dq)
+{
+ return (int)(ldpaa_dq_flags(dq) & LDPAA_DQ_STAT_VOLATILE);
+}
+static inline int ldpaa_dq_is_pull_complete(
+ const struct ldpaa_dq *dq)
+{
+ return (int)(ldpaa_dq_flags(dq) & LDPAA_DQ_STAT_EXPIRED);
+}
+/* seqnum/odpid are valid only if VALIDFRAME and ODPVALID flags are TRUE */
+uint16_t ldpaa_dq_seqnum(const struct ldpaa_dq *);
+uint16_t ldpaa_dq_odpid(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_fqid(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_byte_count(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_frame_count(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_fqd_ctx_hi(const struct ldpaa_dq *);
+uint32_t ldpaa_dq_fqd_ctx_lo(const struct ldpaa_dq *);
+/* get the Frame Descriptor */
+const struct dpaa_fd *ldpaa_dq_fd(const struct ldpaa_dq *);
+
+#endif /* __FSL_DPAA_FD_H */
diff --git a/include/fsl-mc/fsl_dpbp.h b/include/fsl-mc/fsl_dpbp.h
new file mode 100644
index 0000000..7f0075c
--- /dev/null
+++ b/include/fsl-mc/fsl_dpbp.h
@@ -0,0 +1,143 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+/*!
+ * @file fsl_dpbp.h
+ * @brief Data Path Buffer Pool API
+ */
+#ifndef __FSL_DPBP_H
+#define __FSL_DPBP_H
+
+/* DPBP Version */
+#define DPBP_VER_MAJOR 2
+#define DPBP_VER_MINOR 0
+
+/* Command IDs */
+#define DPBP_CMDID_CLOSE 0x800
+#define DPBP_CMDID_OPEN 0x804
+
+#define DPBP_CMDID_ENABLE 0x002
+#define DPBP_CMDID_DISABLE 0x003
+#define DPBP_CMDID_GET_ATTR 0x004
+#define DPBP_CMDID_RESET 0x005
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_CMD_OPEN(cmd, dpbp_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpbp_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPBP_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, attr->bpid); \
+ MC_RSP_OP(cmd, 0, 32, 32, int, attr->id);\
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\
+} while (0)
+
+/* Data Path Buffer Pool API
+ * Contains initialization APIs and runtime control APIs for DPBP
+ */
+
+struct fsl_mc_io;
+
+/**
+ * dpbp_open() - Open a control session for the specified object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dpbp_id: DPBP 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 dpbp_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
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_open(struct fsl_mc_io *mc_io, int dpbp_id, uint16_t *token);
+
+/**
+ * dpbp_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_close(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpbp_enable() - Enable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+
+int dpbp_enable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpbp_disable() - Disable the DPBP.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_disable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpbp_reset() - Reset the DPBP, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_reset(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * struct dpbp_attr - Structure representing DPBP attributes
+ * @id: DPBP object ID
+ * @version: DPBP version
+ * @bpid: Hardware buffer pool ID; should be used as an argument in
+ * acquire/release operations on buffers
+ */
+struct dpbp_attr {
+ int id;
+ /**
+ * struct version - Structure representing DPBP version
+ * @major: DPBP major version
+ * @minor: DPBP minor version
+ */
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } version;
+ uint16_t bpid;
+};
+
+
+/**
+ * dpbp_get_attributes - Retrieve DPBP attributes.
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPBP object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpbp_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpbp_attr *attr);
+
+/** @} */
+
+#endif /* __FSL_DPBP_H */
diff --git a/include/fsl-mc/fsl_dpio.h b/include/fsl-mc/fsl_dpio.h
new file mode 100644
index 0000000..e84b419
--- /dev/null
+++ b/include/fsl-mc/fsl_dpio.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_DPIO_H
+#define _FSL_DPIO_H
+
+/* DPIO Version */
+#define DPIO_VER_MAJOR 2
+#define DPIO_VER_MINOR 1
+
+/* Command IDs */
+#define DPIO_CMDID_CLOSE 0x800
+#define DPIO_CMDID_OPEN 0x803
+
+#define DPIO_CMDID_ENABLE 0x002
+#define DPIO_CMDID_DISABLE 0x003
+#define DPIO_CMDID_GET_ATTR 0x004
+#define DPIO_CMDID_RESET 0x005
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_CMD_OPEN(cmd, dpio_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpio_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPIO_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
+ 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, 3, 0, 16, uint16_t, attr->version.major);\
+ MC_RSP_OP(cmd, 3, 16, 16, uint16_t, attr->version.minor);\
+} while (0)
+
+/* Data Path I/O Portal API
+ * Contains initialization APIs and runtime control APIs for DPIO
+ */
+
+struct fsl_mc_io;
+/**
+ * dpio_open() - Open a control session for the specified 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.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+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
+ * @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.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_close(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * enum dpio_channel_mode - DPIO notification channel mode
+ * @DPIO_NO_CHANNEL: No support for notification channel
+ * @DPIO_LOCAL_CHANNEL: Notifications on data availability can be received by a
+ * dedicated channel in the DPIO; user should point the queue's
+ * destination in the relevant interface to this DPIO
+ */
+enum dpio_channel_mode {
+ DPIO_NO_CHANNEL = 0,
+ DPIO_LOCAL_CHANNEL = 1,
+};
+
+/**
+ * dpio_enable() - Enable the DPIO, allow I/O portal operations.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_enable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpio_disable() - Disable the DPIO, stop any I/O portal operation.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_disable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpio_reset() - Reset the DPIO, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPIO object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpio_reset(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * 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_id: Software portal ID
+ * @channel_mode: Notification channel mode
+ * @num_priorities: Number of priorities for the notification channel (1-8);
+ * relevant only if 'channel_mode = DPIO_LOCAL_CHANNEL'
+ */
+struct dpio_attr {
+ int id;
+ /**
+ * struct version - DPIO version
+ * @major: DPIO major version
+ * @minor: DPIO minor version
+ */
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } version;
+ uint64_t qbman_portal_ce_paddr;
+ uint64_t qbman_portal_ci_paddr;
+ uint16_t qbman_portal_id;
+ enum dpio_channel_mode channel_mode;
+ uint8_t num_priorities;
+};
+
+/**
+ * dpio_get_attributes() - Retrieve DPIO attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPIO object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise
+ */
+int dpio_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpio_attr *attr);
+
+#endif /* _FSL_DPIO_H */
diff --git a/include/fsl-mc/fsl_dpmng.h b/include/fsl-mc/fsl_dpmng.h
index c2e1ddd..986e7c8 100644
--- a/include/fsl-mc/fsl_dpmng.h
+++ b/include/fsl-mc/fsl_dpmng.h
@@ -1,121 +1,44 @@
-/* Copyright 2014 Freescale Semiconductor Inc.
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
-/*!
- * @file fsl_dpmng.h
- * @brief Management Complex General API
- */
-
#ifndef __FSL_DPMNG_H
#define __FSL_DPMNG_H
-/*!
- * @Group grp_dpmng Management Complex General API
- *
- * @brief Contains general API for the Management Complex firmware
- * @{
+/* Management Complex General API
+ * Contains general API for the Management Complex firmware
*/
struct fsl_mc_io;
/**
- * @brief Management Complex firmware version information
+ * Management Complex firmware version information
*/
-#define MC_VER_MAJOR 4
+#define MC_VER_MAJOR 6
#define MC_VER_MINOR 0
+/**
+ * struct mc_versoin
+ * @major: Major version number: incremented on API compatibility changes
+ * @minor: Minor version number: incremented on API additions (that are
+ * backward compatible); reset when major version is incremented
+ * @revision: Internal revision number: incremented on implementation changes
+ * and/or bug fixes that have no impact on API
+ */
struct mc_version {
uint32_t major;
- /*!< Major version number: incremented on API compatibility changes */
uint32_t minor;
- /*!< Minor version number: incremented on API additions (that are
- * backward compatible); reset when major version is incremented
- */
uint32_t revision;
- /*!< Internal revision number: incremented on implementation changes
- * and/or bug fixes that have no impact on API
- */
};
/**
- * @brief Retrieves the Management Complex firmware version information
- *
- * @param[in] mc_io Pointer to opaque I/O object
- * @param[out] mc_ver_info Pointer to version information structure
+ * mc_get_version() - Retrieves the Management Complex firmware
+ * version information
+ * @mc_io: Pointer to opaque I/O object
+ * @mc_ver_info: Returned version information structure
*
- * @returns '0' on Success; Error code otherwise.
+ * Return: '0' on Success; Error code otherwise.
*/
int mc_get_version(struct fsl_mc_io *mc_io, struct mc_version *mc_ver_info);
-/**
- * @brief Resets an AIOP tile
- *
- * @param[in] mc_io Pointer to opaque I/O object
- * @param[in] container_id AIOP container ID
- * @param[in] aiop_tile_id AIOP tile ID to reset
- *
- * @returns '0' on Success; Error code otherwise.
- */
-int dpmng_reset_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id);
-
-/**
- * @brief Loads an image to AIOP tile
- *
- * @param[in] mc_io Pointer to opaque I/O object
- * @param[in] container_id AIOP container ID
- * @param[in] aiop_tile_id AIOP tile ID to reset
- * @param[in] img_iova I/O virtual address of AIOP ELF image
- * @param[in] img_size Size of AIOP ELF image in memory (in bytes)
- *
- * @returns '0' on Success; Error code otherwise.
- */
-int dpmng_load_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id,
- uint64_t img_iova,
- uint32_t img_size);
-
-/**
- * @brief AIOP run configuration
- */
-struct dpmng_aiop_run_cfg {
- uint32_t cores_mask;
- /*!< Mask of AIOP cores to run (core 0 in most significant bit) */
- uint64_t options;
- /*!< Execution options (currently none defined) */
-};
-
-/**
- * @brief Starts AIOP tile execution
- *
- * @param[in] mc_io Pointer to MC portal's I/O object
- * @param[in] container_id AIOP container ID
- * @param[in] aiop_tile_id AIOP tile ID to reset
- * @param[in] cfg AIOP run configuration
- *
- * @returns '0' on Success; Error code otherwise.
- */
-int dpmng_run_aiop(struct fsl_mc_io *mc_io,
- int container_id,
- int aiop_tile_id,
- const struct dpmng_aiop_run_cfg *cfg);
-
-/**
- * @brief Resets MC portal
- *
- * This function closes all object handles (tokens) that are currently
- * open in the MC portal on which the command is submitted. This allows
- * cleanup of stale handles that belong to non-functional user processes.
- *
- * @param[in] mc_io Pointer to MC portal's I/O object
- *
- * @returns '0' on Success; Error code otherwise.
- */
-int dpmng_reset_mc_portal(struct fsl_mc_io *mc_io);
-
-/** @} */
-
#endif /* __FSL_DPMNG_H */
diff --git a/include/fsl-mc/fsl_dpni.h b/include/fsl-mc/fsl_dpni.h
new file mode 100644
index 0000000..67c087d
--- /dev/null
+++ b/include/fsl-mc/fsl_dpni.h
@@ -0,0 +1,1093 @@
+/*
+ * Copyright (C) 2013-2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _FSL_DPNI_H
+#define _FSL_DPNI_H
+
+/* DPNI Version */
+#define DPNI_VER_MAJOR 4
+#define DPNI_VER_MINOR 0
+
+/* Command IDs */
+#define DPNI_CMDID_OPEN 0x801
+#define DPNI_CMDID_CLOSE 0x800
+
+#define DPNI_CMDID_ENABLE 0x002
+#define DPNI_CMDID_DISABLE 0x003
+#define DPNI_CMDID_GET_ATTR 0x004
+#define DPNI_CMDID_RESET 0x005
+
+#define DPNI_CMDID_SET_POOLS 0x200
+#define DPNI_CMDID_GET_RX_BUFFER_LAYOUT 0x201
+#define DPNI_CMDID_SET_RX_BUFFER_LAYOUT 0x202
+#define DPNI_CMDID_GET_TX_BUFFER_LAYOUT 0x203
+#define DPNI_CMDID_SET_TX_BUFFER_LAYOUT 0x204
+#define DPNI_CMDID_SET_TX_CONF_BUFFER_LAYOUT 0x205
+#define DPNI_CMDID_GET_TX_CONF_BUFFER_LAYOUT 0x206
+
+#define DPNI_CMDID_GET_QDID 0x210
+#define DPNI_CMDID_GET_TX_DATA_OFFSET 0x212
+#define DPNI_CMDID_GET_COUNTER 0x213
+#define DPNI_CMDID_SET_COUNTER 0x214
+#define DPNI_CMDID_GET_LINK_STATE 0x215
+#define DPNI_CMDID_SET_LINK_CFG 0x21A
+
+#define DPNI_CMDID_SET_PRIM_MAC 0x224
+#define DPNI_CMDID_GET_PRIM_MAC 0x225
+#define DPNI_CMDID_ADD_MAC_ADDR 0x226
+#define DPNI_CMDID_REMOVE_MAC_ADDR 0x227
+
+#define DPNI_CMDID_SET_TX_FLOW 0x236
+#define DPNI_CMDID_GET_TX_FLOW 0x237
+#define DPNI_CMDID_SET_RX_FLOW 0x238
+#define DPNI_CMDID_GET_RX_FLOW 0x239
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_OPEN(cmd, dpni_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, dpni_id)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_POOLS(cmd, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_dpbp); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, cfg->pools[0].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 32, 16, uint16_t, cfg->pools[0].buffer_size);\
+ MC_CMD_OP(cmd, 1, 0, 32, int, cfg->pools[1].dpbp_id); \
+ MC_CMD_OP(cmd, 4, 48, 16, uint16_t, cfg->pools[1].buffer_size);\
+ MC_CMD_OP(cmd, 1, 32, 32, int, cfg->pools[2].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 0, 16, uint16_t, cfg->pools[2].buffer_size);\
+ MC_CMD_OP(cmd, 2, 0, 32, int, cfg->pools[3].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 16, 16, uint16_t, cfg->pools[3].buffer_size);\
+ MC_CMD_OP(cmd, 2, 32, 32, int, cfg->pools[4].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 32, 16, uint16_t, cfg->pools[4].buffer_size);\
+ MC_CMD_OP(cmd, 3, 0, 32, int, cfg->pools[5].dpbp_id); \
+ MC_CMD_OP(cmd, 5, 48, 16, uint16_t, cfg->pools[5].buffer_size);\
+ MC_CMD_OP(cmd, 3, 32, 32, int, cfg->pools[6].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 0, 16, uint16_t, cfg->pools[6].buffer_size);\
+ MC_CMD_OP(cmd, 4, 0, 32, int, cfg->pools[7].dpbp_id); \
+ MC_CMD_OP(cmd, 6, 16, 16, uint16_t, cfg->pools[7].buffer_size);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_ATTR(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
+ 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, 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, 2, 24, 8, uint8_t, attr->max_qos_entries); \
+ MC_RSP_OP(cmd, 2, 32, 8, uint8_t, attr->max_qos_key_size); \
+ MC_RSP_OP(cmd, 2, 40, 8, uint8_t, attr->max_dist_key_size); \
+ MC_RSP_OP(cmd, 3, 0, 8, uint8_t, attr->max_dist_per_tc[0]); \
+ MC_RSP_OP(cmd, 3, 8, 8, uint8_t, attr->max_dist_per_tc[1]); \
+ MC_RSP_OP(cmd, 3, 16, 8, uint8_t, attr->max_dist_per_tc[2]); \
+ MC_RSP_OP(cmd, 3, 24, 8, uint8_t, attr->max_dist_per_tc[3]); \
+ MC_RSP_OP(cmd, 3, 32, 8, uint8_t, attr->max_dist_per_tc[4]); \
+ MC_RSP_OP(cmd, 3, 40, 8, uint8_t, attr->max_dist_per_tc[5]); \
+ MC_RSP_OP(cmd, 3, 48, 8, uint8_t, attr->max_dist_per_tc[6]); \
+ MC_RSP_OP(cmd, 3, 56, 8, uint8_t, attr->max_dist_per_tc[7]); \
+ MC_RSP_OP(cmd, 4, 0, 16, uint16_t, \
+ attr->ipr_cfg.max_reass_frm_size); \
+ 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); \
+ 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, \
+ attr->ipr_cfg.max_open_frames_ipv6); \
+ MC_RSP_OP(cmd, 5, 32, 16, uint16_t, attr->version.major);\
+ MC_RSP_OP(cmd, 5, 48, 16, uint16_t, attr->version.minor);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_RX_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \
+ MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_TX_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_TX_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \
+ MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_TX_CONF_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_RSP_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_RSP_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_RSP_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_RSP_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_RSP_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_TX_CONF_BUFFER_LAYOUT(cmd, layout) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, uint16_t, layout->private_data_size); \
+ MC_CMD_OP(cmd, 0, 16, 16, uint16_t, layout->data_align); \
+ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, layout->options); \
+ MC_CMD_OP(cmd, 1, 0, 1, int, layout->pass_timestamp); \
+ MC_CMD_OP(cmd, 1, 1, 1, int, layout->pass_parser_result); \
+ MC_CMD_OP(cmd, 1, 2, 1, int, layout->pass_frame_status); \
+ MC_CMD_OP(cmd, 1, 16, 16, uint16_t, layout->data_head_room); \
+ MC_CMD_OP(cmd, 1, 32, 16, uint16_t, layout->data_tail_room); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_QDID(cmd, qdid) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, qdid)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_TX_DATA_OFFSET(cmd, data_offset) \
+ MC_RSP_OP(cmd, 0, 0, 16, uint16_t, data_offset)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_COUNTER(cmd, counter) \
+ MC_CMD_OP(cmd, 0, 0, 16, enum dpni_counter, counter)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_COUNTER(cmd, value) \
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, value)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_COUNTER(cmd, counter, value) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 16, enum dpni_counter, counter); \
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, value); \
+} while (0)
+
+/* 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, 2, 0, 64, uint64_t, cfg->options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#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, 2, 0, 64, uint64_t, state->options);\
+} while (0)
+
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_PRIMARY_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_RSP_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_RSP_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_RSP_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_RSP_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_ADD_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_REMOVE_MAC_ADDR(cmd, mac_addr) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, mac_addr[5]); \
+ MC_CMD_OP(cmd, 0, 24, 8, uint8_t, mac_addr[4]); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, mac_addr[3]); \
+ MC_CMD_OP(cmd, 0, 40, 8, uint8_t, mac_addr[2]); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, mac_addr[1]); \
+ MC_CMD_OP(cmd, 0, 56, 8, uint8_t, mac_addr[0]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_TX_FLOW(cmd, flow_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, \
+ cfg->conf_err_cfg.queue_cfg.dest_cfg.dest_id);\
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, \
+ cfg->conf_err_cfg.queue_cfg.dest_cfg.priority);\
+ MC_CMD_OP(cmd, 0, 40, 2, enum dpni_dest, \
+ cfg->conf_err_cfg.queue_cfg.dest_cfg.dest_type);\
+ MC_CMD_OP(cmd, 0, 42, 1, int, cfg->conf_err_cfg.errors_only);\
+ MC_CMD_OP(cmd, 0, 43, 1, int, cfg->l3_chksum_gen);\
+ MC_CMD_OP(cmd, 0, 44, 1, int, cfg->l4_chksum_gen);\
+ MC_CMD_OP(cmd, 0, 45, 1, int, \
+ cfg->conf_err_cfg.use_default_queue);\
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id);\
+ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, \
+ cfg->conf_err_cfg.queue_cfg.user_ctx);\
+ MC_CMD_OP(cmd, 2, 0, 32, uint32_t, cfg->options);\
+ MC_CMD_OP(cmd, 2, 32, 32, uint32_t, \
+ cfg->conf_err_cfg.queue_cfg.options);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_SET_TX_FLOW(cmd, flow_id) \
+ MC_RSP_OP(cmd, 0, 48, 16, uint16_t, flow_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_TX_FLOW(cmd, flow_id) \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_TX_FLOW(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, \
+ attr->conf_err_attr.queue_attr.dest_cfg.dest_id);\
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, \
+ attr->conf_err_attr.queue_attr.dest_cfg.priority);\
+ MC_RSP_OP(cmd, 0, 40, 2, enum dpni_dest, \
+ attr->conf_err_attr.queue_attr.dest_cfg.dest_type);\
+ MC_RSP_OP(cmd, 0, 42, 1, int, attr->conf_err_attr.errors_only);\
+ MC_RSP_OP(cmd, 0, 43, 1, int, attr->l3_chksum_gen);\
+ MC_RSP_OP(cmd, 0, 44, 1, int, attr->l4_chksum_gen);\
+ MC_RSP_OP(cmd, 0, 45, 1, int, \
+ attr->conf_err_attr.use_default_queue);\
+ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, \
+ attr->conf_err_attr.queue_attr.user_ctx);\
+ MC_RSP_OP(cmd, 2, 32, 32, uint32_t, \
+ attr->conf_err_attr.queue_attr.fqid);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_SET_RX_FLOW(cmd, tc_id, flow_id, cfg) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, cfg->dest_cfg.dest_id); \
+ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->dest_cfg.priority);\
+ MC_CMD_OP(cmd, 0, 40, 2, enum dpni_dest, cfg->dest_cfg.dest_type);\
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id); \
+ 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); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_CMD_GET_RX_FLOW(cmd, tc_id, flow_id) \
+do { \
+ MC_CMD_OP(cmd, 0, 16, 8, uint8_t, tc_id); \
+ MC_CMD_OP(cmd, 0, 48, 16, uint16_t, flow_id); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPNI_RSP_GET_RX_FLOW(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->dest_cfg.dest_id); \
+ MC_RSP_OP(cmd, 0, 32, 8, uint8_t, attr->dest_cfg.priority);\
+ 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); \
+} while (0)
+
+enum net_prot {
+ NET_PROT_NONE = 0,
+ NET_PROT_PAYLOAD,
+ NET_PROT_ETH,
+ NET_PROT_VLAN,
+ NET_PROT_IPV4,
+ NET_PROT_IPV6,
+ NET_PROT_IP,
+ NET_PROT_TCP,
+ NET_PROT_UDP,
+ NET_PROT_UDP_LITE,
+ NET_PROT_IPHC,
+ NET_PROT_SCTP,
+ NET_PROT_SCTP_CHUNK_DATA,
+ NET_PROT_PPPOE,
+ NET_PROT_PPP,
+ NET_PROT_PPPMUX,
+ NET_PROT_PPPMUX_SUBFRM,
+ NET_PROT_L2TPV2,
+ NET_PROT_L2TPV3_CTRL,
+ NET_PROT_L2TPV3_SESS,
+ NET_PROT_LLC,
+ NET_PROT_LLC_SNAP,
+ NET_PROT_NLPID,
+ NET_PROT_SNAP,
+ NET_PROT_MPLS,
+ NET_PROT_IPSEC_AH,
+ NET_PROT_IPSEC_ESP,
+ NET_PROT_UDP_ENC_ESP, /* RFC 3948 */
+ NET_PROT_MACSEC,
+ NET_PROT_GRE,
+ NET_PROT_MINENCAP,
+ NET_PROT_DCCP,
+ NET_PROT_ICMP,
+ NET_PROT_IGMP,
+ NET_PROT_ARP,
+ NET_PROT_CAPWAP_DATA,
+ NET_PROT_CAPWAP_CTRL,
+ NET_PROT_RFC2684,
+ NET_PROT_ICMPV6,
+ NET_PROT_FCOE,
+ NET_PROT_FIP,
+ NET_PROT_ISCSI,
+ NET_PROT_GTP,
+ NET_PROT_USER_DEFINED_L2,
+ NET_PROT_USER_DEFINED_L3,
+ NET_PROT_USER_DEFINED_L4,
+ NET_PROT_USER_DEFINED_L5,
+ NET_PROT_USER_DEFINED_SHIM1,
+ NET_PROT_USER_DEFINED_SHIM2,
+
+ NET_PROT_DUMMY_LAST
+};
+
+/* Data Path Network Interface API
+ * Contains initialization APIs and runtime control APIs for DPNI
+ */
+
+struct fsl_mc_io;
+
+/* General DPNI macros */
+
+/* Maximum number of traffic classes */
+#define DPNI_MAX_TC 8
+/* Maximum number of buffer pools per DPNI */
+#define DPNI_MAX_DPBP 8
+
+/* All traffic classes considered; see dpni_set_rx_flow() */
+#define DPNI_ALL_TCS (uint8_t)(-1)
+/* All flows within traffic class considered; see dpni_set_rx_flow() */
+#define DPNI_ALL_TC_FLOWS (uint16_t)(-1)
+/* Generate new flow ID; see dpni_set_tx_flow() */
+#define DPNI_NEW_FLOW_ID (uint16_t)(-1)
+
+/**
+ * dpni_open() - Open a control session for the specified object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @dpni_id: DPNI 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 dpni_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.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_open(struct fsl_mc_io *mc_io, int dpni_id, uint16_t *token);
+
+/**
+ * dpni_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_close(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * struct dpni_ipr_cfg - Structure representing IP reassembly configuration
+ * @max_reass_frm_size: Maximum size of the reassembled frame
+ * @min_frag_size_ipv4: Minimum fragment size of IPv4 fragments
+ * @min_frag_size_ipv6: Minimum fragment size of IPv6 fragments
+ * @max_open_frames_ipv4: Maximum concurrent IPv4 packets in reassembly process
+ * @max_open_frames_ipv6: Maximum concurrent IPv6 packets in reassembly process
+ */
+struct dpni_ipr_cfg {
+ uint16_t max_reass_frm_size;
+ uint16_t min_frag_size_ipv4;
+ uint16_t min_frag_size_ipv6;
+ uint16_t max_open_frames_ipv4;
+ uint16_t max_open_frames_ipv6;
+};
+
+/**
+ * struct dpni_pools_cfg - Structure representing buffer pools configuration
+ * @num_dpbp: Number of DPBPs
+ * @pools: Array of buffer pools parameters; The number of valid entries
+ * must match 'num_dpbp' value
+ */
+struct dpni_pools_cfg {
+ uint8_t num_dpbp;
+ /**
+ * struct pools - Buffer pools parameters
+ * @dpbp_id: DPBP object ID
+ * @buffer_size: Buffer size
+ */
+ struct {
+ int dpbp_id;
+ uint16_t buffer_size;
+ } pools[DPNI_MAX_DPBP];
+};
+
+/**
+ * dpni_set_pools() - Set buffer pools configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @cfg: Buffer pools configuration
+ *
+ * mandatory for DPNI operation
+ * warning:Allowed only when DPNI is disabled
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_pools(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_pools_cfg *cfg);
+
+/**
+ * dpni_enable() - Enable the DPNI, allow sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_enable(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * dpni_disable() - Disable the DPNI, stop sending and receiving frames.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_disable(struct fsl_mc_io *mc_io, uint16_t token);
+
+
+/**
+ * @dpni_reset() - Reset the DPNI, returns the object to initial state.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_reset(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * struct dpni_attr - Structure representing DPNI attributes
+ * @id: DPNI object ID
+ * @version: DPNI version
+ * @start_hdr: Indicates the packet starting header for parsing
+ * @options: Mask of available options; reflects the value as was given in
+ * object's creation
+ * @max_senders: Maximum number of different senders; used as the number
+ * of dedicated Tx flows;
+ * @max_tcs: Maximum number of traffic classes (for both Tx and Rx)
+ * @max_dist_per_tc: Maximum distribution size per Rx traffic class;
+ * Set to the required value minus 1
+ * @max_unicast_filters: Maximum number of unicast filters
+ * @max_multicast_filters: Maximum number of multicast filters
+ * @max_vlan_filters: Maximum number of VLAN filters
+ * @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
+ * @ipr_cfg: IP reassembly configuration
+ */
+struct dpni_attr {
+ int id;
+ /**
+ * struct version - DPNI version
+ * @major: DPNI major version
+ * @minor: DPNI minor version
+ */
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } version;
+ enum net_prot start_hdr;
+ uint64_t options;
+ uint8_t max_senders;
+ uint8_t max_tcs;
+ uint8_t max_dist_per_tc[DPNI_MAX_TC];
+ uint8_t max_unicast_filters;
+ uint8_t max_multicast_filters;
+ uint8_t max_vlan_filters;
+ uint8_t max_qos_entries;
+ uint8_t max_qos_key_size;
+ uint8_t max_dist_key_size;
+ struct dpni_ipr_cfg ipr_cfg;
+};
+/**
+ * dpni_get_attributes() - Retrieve DPNI attributes.
+ * @mc_io: Pointer to MC portal's I/O objec
+ * @token: Token of DPNI object
+ * @attr: Returned object's attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_attr *attr);
+
+/* DPNI buffer layout modification options */
+
+/* Select to modify the time-stamp setting */
+#define DPNI_BUF_LAYOUT_OPT_TIMESTAMP 0x00000001
+/* Select to modify the parser-result setting; not applicable for Tx */
+#define DPNI_BUF_LAYOUT_OPT_PARSER_RESULT 0x00000002
+/* Select to modify the frame-status setting */
+#define DPNI_BUF_LAYOUT_OPT_FRAME_STATUS 0x00000004
+/* Select to modify the private-data-size setting */
+#define DPNI_BUF_LAYOUT_OPT_PRIVATE_DATA_SIZE 0x00000008
+/* Select to modify the data-alignment setting */
+#define DPNI_BUF_LAYOUT_OPT_DATA_ALIGN 0x00000010
+/* Select to modify the data-head-room setting */
+#define DPNI_BUF_LAYOUT_OPT_DATA_HEAD_ROOM 0x00000020
+/*!< Select to modify the data-tail-room setting */
+#define DPNI_BUF_LAYOUT_OPT_DATA_TAIL_ROOM 0x00000040
+
+/**
+ * struct dpni_buffer_layout - Structure representing DPNI buffer layout
+ * @options: Flags representing the suggested modifications to the buffer
+ * layout; Use any combination of 'DPNI_BUF_LAYOUT_OPT_<X>' flags
+ * @pass_timestamp: Pass timestamp value
+ * @pass_parser_result: Pass parser results
+ * @pass_frame_status: Pass frame status
+ * @private_data_size: Size kept for private data (in bytes)
+ * @data_align: Data alignment
+ * @data_head_room: Data head room
+ * @data_tail_room: Data tail room
+ */
+struct dpni_buffer_layout {
+ uint32_t options;
+ int pass_timestamp;
+ int pass_parser_result;
+ int pass_frame_status;
+ uint16_t private_data_size;
+ uint16_t data_align;
+ uint16_t data_head_room;
+ uint16_t data_tail_room;
+};
+
+/**
+ * dpni_get_rx_buffer_layout() - Retrieve Rx buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+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
+ * @token: Token of DPNI object
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+int dpni_set_rx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dpni_buffer_layout *layout);
+
+/**
+ * dpni_get_tx_buffer_layout() - Retrieve Tx buffer layout attributes.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_tx_buffer_layout(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ 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
+ *
+ * @returns '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.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Returns buffer layout attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+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.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @layout: Buffer layout configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Allowed only when DPNI is disabled
+ */
+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
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @spid: Returned aiop storage-profile ID
+ *
+ * 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);
+
+/**
+ * dpni_get_tx_data_offset() - Get the Tx data offset (from start of buffer)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @data_offset: Tx data offset (from start of buffer)
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_tx_data_offset(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t *data_offset);
+
+/**
+ * enum dpni_counter - DPNI counter types
+ * @DPNI_CNT_ING_FRAME: Counts ingress frames
+ * @DPNI_CNT_ING_BYTE: Counts ingress bytes
+ * @DPNI_CNT_ING_FRAME_DROP: Counts ingress frames dropped due to explicit
+ * 'drop' setting
+ * @DPNI_CNT_ING_FRAME_DISCARD: Counts ingress frames discarded due to errors
+ * @DPNI_CNT_ING_MCAST_FRAME: Counts ingress multicast frames
+ * @DPNI_CNT_ING_MCAST_BYTE: Counts ingress multicast bytes
+ * @DPNI_CNT_ING_BCAST_FRAME: Counts ingress broadcast frames
+ * @DPNI_CNT_ING_BCAST_BYTES: Counts ingress broadcast bytes
+ * @DPNI_CNT_EGR_FRAME: Counts egress frames
+ * @DPNI_CNT_EGR_BYTE: Counts egress bytes
+ * @DPNI_CNT_EGR_FRAME_DISCARD: Counts egress frames discarded due to errors
+ */
+enum dpni_counter {
+ DPNI_CNT_ING_FRAME = 0x0,
+ DPNI_CNT_ING_BYTE = 0x1,
+ DPNI_CNT_ING_FRAME_DROP = 0x2,
+ DPNI_CNT_ING_FRAME_DISCARD = 0x3,
+ DPNI_CNT_ING_MCAST_FRAME = 0x4,
+ DPNI_CNT_ING_MCAST_BYTE = 0x5,
+ DPNI_CNT_ING_BCAST_FRAME = 0x6,
+ DPNI_CNT_ING_BCAST_BYTES = 0x7,
+ DPNI_CNT_EGR_FRAME = 0x8,
+ DPNI_CNT_EGR_BYTE = 0x9,
+ DPNI_CNT_EGR_FRAME_DISCARD = 0xa
+};
+
+/**
+ * dpni_get_counter() - Read a specific DPNI counter
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @counter: The requested counter
+ * @value: Returned counter's current value
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_counter(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ enum dpni_counter counter,
+ uint64_t *value);
+
+/**
+ * dpni_set_counter() - Set (or clear) a specific DPNI counter
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @counter: The requested counter
+ * @value: New counter value; typically pass '0' for resetting
+ * the counter.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_counter(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ enum dpni_counter counter,
+ uint64_t value);
+/**
+ * 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;
+ uint64_t options;
+};
+
+/**
+ * dpni_set_link_cfg() - set the link configuration.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @cfg: Link configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_link_cfg *cfg);
+
+/**
+ * struct dpni_link_state - Structure representing DPNI link state
+ * @rate: Rate
+ * @options: Mask of available options; use 'DPNI_LINK_OPT_<X>' values
+ * @up: Link state; '0' for down, '1' for up
+ */
+struct dpni_link_state {
+ uint64_t rate;
+ uint64_t options;
+ int up;
+};
+
+/**
+ * dpni_get_link_state() - Return the link state (either up or down)
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @state: Returned link state;
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_link_state(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dpni_link_state *state);
+
+/**
+ * dpni_set_primary_mac_addr() - Set the primary MAC address
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to set as primary address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+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
+ * @token: Token of DPNI object
+ * @mac_addr: Returned MAC address
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+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
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to add
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_add_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * dpni_remove_mac_addr() - Remove MAC address filter
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @mac_addr: MAC address to remove
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_remove_mac_addr(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const uint8_t mac_addr[6]);
+
+/**
+ * enum dpni_dest - DPNI destination types
+ * 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
+ * @DPNI_DEST_DPIO: The queue is set in schedule mode and generates FQDAN
+ * notifications to the specified DPIO; user is expected to dequeue
+ * from the queue only after notification is received
+ * @DPNI_DEST_DPCON: The queue is set in schedule mode and does not generate
+ * FQDAN notifications, but is connected to the specified DPCON
+ * object; user is expected to dequeue from the DPCON channel
+ */
+enum dpni_dest {
+ DPNI_DEST_NONE = 0,
+ DPNI_DEST_DPIO = 1,
+ DPNI_DEST_DPCON = 2
+};
+
+/**
+ * struct dpni_dest_cfg - Structure representing DPNI destination parameters
+ * @dest_type: Destination type
+ * @dest_id: Either DPIO ID or DPCON ID, depending on the destination type
+ * @priority: Priority selection within the DPIO or DPCON channel; valid values
+ * are 0-1 or 0-7, depending on the number of priorities in that
+ * channel; not relevant for 'DPNI_DEST_NONE' option
+ */
+struct dpni_dest_cfg {
+ enum dpni_dest dest_type;
+ int dest_id;
+ uint8_t priority;
+};
+
+/* 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
+
+/**
+ * struct dpni_queue_cfg - Structure representing queue configuration
+ * @options: Flags representing the suggested modifications to the queue;
+ * Use any combination of 'DPNI_QUEUE_OPT_<X>' flags
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame; valid only if 'DPNI_QUEUE_OPT_USER_CTX'
+ * is contained in 'options'
+ * @dest_cfg: Queue destination parameters;
+ * valid only if 'DPNI_QUEUE_OPT_DEST' is contained in 'options'
+ */
+struct dpni_queue_cfg {
+ uint32_t options;
+ uint64_t user_ctx;
+ struct dpni_dest_cfg dest_cfg;
+};
+
+/**
+ * struct dpni_queue_attr - Structure representing queue attributes
+ * @user_ctx: User context value provided in the frame descriptor of each
+ * dequeued frame
+ * @dest_cfg: Queue destination 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;
+ uint32_t fqid;
+};
+
+/* DPNI Tx flow modification options */
+
+/* Select to modify the settings for dedicate Tx confirmation/error */
+#define DPNI_TX_FLOW_OPT_TX_CONF_ERROR 0x00000001
+/*!< Select to modify the Tx confirmation and/or error setting */
+#define DPNI_TX_FLOW_OPT_ONLY_TX_ERROR 0x00000002
+/*!< Select to modify the queue configuration */
+#define DPNI_TX_FLOW_OPT_QUEUE 0x00000004
+/*!< Select to modify the L3 checksum generation setting */
+#define DPNI_TX_FLOW_OPT_L3_CHKSUM_GEN 0x00000010
+/*!< Select to modify the L4 checksum generation setting */
+#define DPNI_TX_FLOW_OPT_L4_CHKSUM_GEN 0x00000020
+
+/**
+ * struct dpni_tx_flow_cfg - Structure representing Tx flow configuration
+ * @options: Flags representing the suggested modifications to the Tx flow;
+ * Use any combination 'DPNI_TX_FLOW_OPT_<X>' flags
+ * @conf_err_cfg: Tx confirmation and error configuration; these settings are
+ * ignored if 'DPNI_OPT_PRIVATE_TX_CONF_ERROR_DISABLED' was set at
+ * DPNI creation
+ * @l3_chksum_gen: Set to '1' to enable L3 checksum generation; '0' to disable;
+ * valid only if 'DPNI_TX_FLOW_OPT_L3_CHKSUM_GEN' is contained in
+ * 'options'
+ * @l4_chksum_gen: Set to '1' to enable L4 checksum generation; '0' to disable;
+ * valid only if 'DPNI_TX_FLOW_OPT_L4_CHKSUM_GEN' is contained in
+ * 'options'
+ */
+struct dpni_tx_flow_cfg {
+ uint32_t options;
+ /**
+ * struct cnf_err_cfg - Tx confirmation and error configuration
+ * @use_default_queue: Set to '1' to use the common (default) Tx
+ * confirmation and error queue; Set to '0' to use the
+ * private Tx confirmation and error queue; valid only if
+ * 'DPNI_TX_FLOW_OPT_TX_CONF_ERROR' is contained in
+ * 'options'
+ * @errors_only: Set to '1' to report back only error frames;
+ * Set to '0' to confirm transmission/error for all
+ * transmitted frames;
+ * valid only if 'DPNI_TX_FLOW_OPT_ONLY_TX_ERROR' is
+ * contained in 'options' and 'use_default_queue = 0';
+ * @queue_cfg: Queue configuration; valid only if
+ * 'DPNI_TX_FLOW_OPT_QUEUE' is contained in 'options'
+ */
+ struct {
+ int use_default_queue;
+ int errors_only;
+ struct dpni_queue_cfg queue_cfg;
+ } conf_err_cfg;
+ int l3_chksum_gen;
+ int l4_chksum_gen;
+};
+
+/**
+ * dpni_set_tx_flow() - Set Tx flow configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @flow_id: Provides (or returns) the sender's flow ID;
+ * for each new sender set (*flow_id) to
+ * 'DPNI_NEW_FLOW_ID' to generate a new flow_id;
+ * this ID should be used as the QDBIN argument
+ * in enqueue operations
+ * @cfg: Tx flow configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_tx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t *flow_id,
+ const struct dpni_tx_flow_cfg *cfg);
+
+/**
+ * struct dpni_tx_flow_attr - Structure representing Tx flow attributes
+ * @conf_err_attr: Tx confirmation and error attributes
+ * @l3_chksum_gen: '1' if L3 checksum generation is enabled; '0' if disabled
+ * @l4_chksum_gen: '1' if L4 checksum generation is enabled; '0' if disabled
+ */
+struct dpni_tx_flow_attr {
+ /**
+ * struct conf_err_attr - Tx confirmation and error attributes
+ * @use_default_queue: '1' if using common (default) Tx confirmation and
+ * error queue;
+ * '0' if using private Tx confirmation and error
+ * queue
+ * @errors_only: '1' if only error frames are reported back; '0' if all
+ * transmitted frames are confirmed
+ * @queue_attr: Queue attributes
+ */
+ struct {
+ int use_default_queue;
+ int errors_only;
+ struct dpni_queue_attr queue_attr;
+ } conf_err_attr;
+ int l3_chksum_gen;
+ int l4_chksum_gen;
+};
+
+/**
+ * dpni_get_tx_flow() - Get Tx flow attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @flow_id: The sender's flow ID, as returned by the
+ * dpni_set_tx_flow() function
+ * @attr: Returned Tx flow attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_tx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint16_t flow_id,
+ struct dpni_tx_flow_attr *attr);
+
+/**
+ * dpni_set_rx_flow() - Set Rx flow configuration
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7);
+ * use 'DPNI_ALL_TCS' to set all TCs and all flows
+ * @flow_id Rx flow id within the traffic class; use
+ * 'DPNI_ALL_TC_FLOWS' to set all flows within
+ * this tc_id; ignored if tc_id is set to
+ * 'DPNI_ALL_TCS';
+ * @cfg: Rx flow configuration
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_set_rx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t tc_id,
+ uint16_t flow_id,
+ const struct dpni_queue_cfg *cfg);
+
+/**
+ * dpni_get_rx_flow() - Get Rx flow attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPNI object
+ * @tc_id: Traffic class selection (0-7)
+ * @flow_id: Rx flow id within the traffic class
+ * @attr: Returned Rx flow attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dpni_get_rx_flow(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ uint8_t tc_id,
+ uint16_t flow_id,
+ struct dpni_queue_attr *attr);
+
+#endif /* _FSL_DPNI_H */
diff --git a/include/fsl-mc/fsl_dprc.h b/include/fsl-mc/fsl_dprc.h
new file mode 100644
index 0000000..f837e89
--- /dev/null
+++ b/include/fsl-mc/fsl_dprc.h
@@ -0,0 +1,659 @@
+/*
+ * Freescale Layerscape MC I/O wrapper
+ *
+ * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
+ * Author: German Rivera <German.Rivera@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _FSL_DPRC_H
+#define _FSL_DPRC_H
+
+/* DPRC Version */
+#define DPRC_VER_MAJOR 2
+#define DPRC_VER_MINOR 0
+
+/* Command IDs */
+#define DPRC_CMDID_CLOSE 0x800
+#define DPRC_CMDID_OPEN 0x805
+
+#define DPRC_CMDID_GET_ATTR 0x004
+#define DPRC_CMDID_RESET_CONT 0x005
+
+#define DPRC_CMDID_GET_CONT_ID 0x830
+#define DPRC_CMDID_GET_OBJ_COUNT 0x159
+#define DPRC_CMDID_GET_OBJ 0x15A
+#define DPRC_CMDID_GET_RES_COUNT 0x15B
+#define DPRC_CMDID_GET_RES_IDS 0x15C
+#define DPRC_CMDID_GET_OBJ_REG 0x15E
+
+#define DPRC_CMDID_CONNECT 0x167
+#define DPRC_CMDID_DISCONNECT 0x168
+#define DPRC_CMDID_GET_CONNECTION 0x16C
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_CONTAINER_ID(cmd, container_id) \
+ MC_RSP_OP(cmd, 0, 0, 32, int, container_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_OPEN(cmd, container_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, container_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_RESET_CONTAINER(cmd, child_container_id) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, child_container_id)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_ATTRIBUTES(cmd, attr) \
+do { \
+ MC_RSP_OP(cmd, 0, 0, 32, int, attr->container_id); \
+ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->icid); \
+ MC_RSP_OP(cmd, 1, 0, 32, uint32_t, attr->options);\
+ MC_RSP_OP(cmd, 1, 32, 32, int, attr->portal_id); \
+ MC_RSP_OP(cmd, 2, 0, 16, uint16_t, attr->version.major);\
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, attr->version.minor);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_OBJ_COUNT(cmd, obj_count) \
+ MC_RSP_OP(cmd, 0, 32, 32, int, obj_count)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_OBJ(cmd, obj_index) \
+ MC_CMD_OP(cmd, 0, 0, 32, int, obj_index)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_OBJ(cmd, obj_desc) \
+do { \
+ MC_RSP_OP(cmd, 0, 32, 32, int, obj_desc->id); \
+ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, obj_desc->vendor); \
+ MC_RSP_OP(cmd, 1, 16, 8, uint8_t, obj_desc->irq_count); \
+ MC_RSP_OP(cmd, 1, 24, 8, uint8_t, obj_desc->region_count); \
+ MC_RSP_OP(cmd, 1, 32, 32, uint32_t, obj_desc->state);\
+ MC_RSP_OP(cmd, 2, 0, 16, uint16_t, obj_desc->ver_major);\
+ MC_RSP_OP(cmd, 2, 16, 16, uint16_t, obj_desc->ver_minor);\
+ MC_RSP_OP(cmd, 3, 0, 8, char, obj_desc->type[0]);\
+ MC_RSP_OP(cmd, 3, 8, 8, char, obj_desc->type[1]);\
+ MC_RSP_OP(cmd, 3, 16, 8, char, obj_desc->type[2]);\
+ MC_RSP_OP(cmd, 3, 24, 8, char, obj_desc->type[3]);\
+ MC_RSP_OP(cmd, 3, 32, 8, char, obj_desc->type[4]);\
+ MC_RSP_OP(cmd, 3, 40, 8, char, obj_desc->type[5]);\
+ MC_RSP_OP(cmd, 3, 48, 8, char, obj_desc->type[6]);\
+ MC_RSP_OP(cmd, 3, 56, 8, char, obj_desc->type[7]);\
+ MC_RSP_OP(cmd, 4, 0, 8, char, obj_desc->type[8]);\
+ MC_RSP_OP(cmd, 4, 8, 8, char, obj_desc->type[9]);\
+ MC_RSP_OP(cmd, 4, 16, 8, char, obj_desc->type[10]);\
+ MC_RSP_OP(cmd, 4, 24, 8, char, obj_desc->type[11]);\
+ MC_RSP_OP(cmd, 4, 32, 8, char, obj_desc->type[12]);\
+ 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]);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_RES_COUNT(cmd, type) \
+do { \
+ MC_CMD_OP(cmd, 1, 0, 8, char, type[0]);\
+ MC_CMD_OP(cmd, 1, 8, 8, char, type[1]);\
+ MC_CMD_OP(cmd, 1, 16, 8, char, type[2]);\
+ MC_CMD_OP(cmd, 1, 24, 8, char, type[3]);\
+ MC_CMD_OP(cmd, 1, 32, 8, char, type[4]);\
+ MC_CMD_OP(cmd, 1, 40, 8, char, type[5]);\
+ MC_CMD_OP(cmd, 1, 48, 8, char, type[6]);\
+ MC_CMD_OP(cmd, 1, 56, 8, char, type[7]);\
+ MC_CMD_OP(cmd, 2, 0, 8, char, type[8]);\
+ MC_CMD_OP(cmd, 2, 8, 8, char, type[9]);\
+ MC_CMD_OP(cmd, 2, 16, 8, char, type[10]);\
+ MC_CMD_OP(cmd, 2, 24, 8, char, type[11]);\
+ MC_CMD_OP(cmd, 2, 32, 8, char, type[12]);\
+ MC_CMD_OP(cmd, 2, 40, 8, char, type[13]);\
+ MC_CMD_OP(cmd, 2, 48, 8, char, type[14]);\
+ MC_CMD_OP(cmd, 2, 56, 8, char, type[15]);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_RES_COUNT(cmd, res_count) \
+ MC_RSP_OP(cmd, 0, 0, 32, int, res_count)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_RES_IDS(cmd, range_desc, type) \
+do { \
+ MC_CMD_OP(cmd, 0, 42, 7, enum dprc_iter_status, \
+ range_desc->iter_status); \
+ MC_CMD_OP(cmd, 1, 0, 32, int, range_desc->base_id); \
+ MC_CMD_OP(cmd, 1, 32, 32, int, range_desc->last_id);\
+ MC_CMD_OP(cmd, 2, 0, 8, char, type[0]);\
+ MC_CMD_OP(cmd, 2, 8, 8, char, type[1]);\
+ MC_CMD_OP(cmd, 2, 16, 8, char, type[2]);\
+ MC_CMD_OP(cmd, 2, 24, 8, char, type[3]);\
+ MC_CMD_OP(cmd, 2, 32, 8, char, type[4]);\
+ MC_CMD_OP(cmd, 2, 40, 8, char, type[5]);\
+ MC_CMD_OP(cmd, 2, 48, 8, char, type[6]);\
+ MC_CMD_OP(cmd, 2, 56, 8, char, type[7]);\
+ MC_CMD_OP(cmd, 3, 0, 8, char, type[8]);\
+ MC_CMD_OP(cmd, 3, 8, 8, char, type[9]);\
+ MC_CMD_OP(cmd, 3, 16, 8, char, type[10]);\
+ MC_CMD_OP(cmd, 3, 24, 8, char, type[11]);\
+ MC_CMD_OP(cmd, 3, 32, 8, char, type[12]);\
+ MC_CMD_OP(cmd, 3, 40, 8, char, type[13]);\
+ MC_CMD_OP(cmd, 3, 48, 8, char, type[14]);\
+ MC_CMD_OP(cmd, 3, 56, 8, char, type[15]);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_RES_IDS(cmd, range_desc) \
+do { \
+ MC_RSP_OP(cmd, 0, 42, 7, enum dprc_iter_status, \
+ range_desc->iter_status);\
+ MC_RSP_OP(cmd, 1, 0, 32, int, range_desc->base_id); \
+ MC_RSP_OP(cmd, 1, 32, 32, int, range_desc->last_id);\
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_OBJ_REGION(cmd, obj_type, obj_id, region_index) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, obj_id); \
+ MC_CMD_OP(cmd, 0, 48, 8, uint8_t, region_index);\
+ MC_CMD_OP(cmd, 3, 0, 8, char, obj_type[0]);\
+ MC_CMD_OP(cmd, 3, 8, 8, char, obj_type[1]);\
+ MC_CMD_OP(cmd, 3, 16, 8, char, obj_type[2]);\
+ MC_CMD_OP(cmd, 3, 24, 8, char, obj_type[3]);\
+ MC_CMD_OP(cmd, 3, 32, 8, char, obj_type[4]);\
+ MC_CMD_OP(cmd, 3, 40, 8, char, obj_type[5]);\
+ MC_CMD_OP(cmd, 3, 48, 8, char, obj_type[6]);\
+ MC_CMD_OP(cmd, 3, 56, 8, char, obj_type[7]);\
+ MC_CMD_OP(cmd, 4, 0, 8, char, obj_type[8]);\
+ MC_CMD_OP(cmd, 4, 8, 8, char, obj_type[9]);\
+ MC_CMD_OP(cmd, 4, 16, 8, char, obj_type[10]);\
+ MC_CMD_OP(cmd, 4, 24, 8, char, obj_type[11]);\
+ MC_CMD_OP(cmd, 4, 32, 8, char, obj_type[12]);\
+ MC_CMD_OP(cmd, 4, 40, 8, char, obj_type[13]);\
+ MC_CMD_OP(cmd, 4, 48, 8, char, obj_type[14]);\
+ MC_CMD_OP(cmd, 4, 56, 8, char, obj_type[15]);\
+} while (0)
+
+/* 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, 2, 0, 32, uint32_t, region_desc->size); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_CONNECT(cmd, endpoint1, endpoint2) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, endpoint1->id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, endpoint1->interface_id); \
+ MC_CMD_OP(cmd, 1, 0, 32, int, endpoint2->id); \
+ MC_CMD_OP(cmd, 1, 32, 32, int, endpoint2->interface_id); \
+ MC_CMD_OP(cmd, 2, 0, 8, char, endpoint1->type[0]); \
+ MC_CMD_OP(cmd, 2, 8, 8, char, endpoint1->type[1]); \
+ MC_CMD_OP(cmd, 2, 16, 8, char, endpoint1->type[2]); \
+ MC_CMD_OP(cmd, 2, 24, 8, char, endpoint1->type[3]); \
+ MC_CMD_OP(cmd, 2, 32, 8, char, endpoint1->type[4]); \
+ MC_CMD_OP(cmd, 2, 40, 8, char, endpoint1->type[5]); \
+ MC_CMD_OP(cmd, 2, 48, 8, char, endpoint1->type[6]); \
+ MC_CMD_OP(cmd, 2, 56, 8, char, endpoint1->type[7]); \
+ MC_CMD_OP(cmd, 3, 0, 8, char, endpoint1->type[8]); \
+ MC_CMD_OP(cmd, 3, 8, 8, char, endpoint1->type[9]); \
+ MC_CMD_OP(cmd, 3, 16, 8, char, endpoint1->type[10]); \
+ MC_CMD_OP(cmd, 3, 24, 8, char, endpoint1->type[11]); \
+ MC_CMD_OP(cmd, 3, 32, 8, char, endpoint1->type[12]); \
+ MC_CMD_OP(cmd, 3, 40, 8, char, endpoint1->type[13]); \
+ MC_CMD_OP(cmd, 3, 48, 8, char, endpoint1->type[14]); \
+ MC_CMD_OP(cmd, 3, 56, 8, char, endpoint1->type[15]); \
+ MC_CMD_OP(cmd, 5, 0, 8, char, endpoint2->type[0]); \
+ MC_CMD_OP(cmd, 5, 8, 8, char, endpoint2->type[1]); \
+ MC_CMD_OP(cmd, 5, 16, 8, char, endpoint2->type[2]); \
+ MC_CMD_OP(cmd, 5, 24, 8, char, endpoint2->type[3]); \
+ MC_CMD_OP(cmd, 5, 32, 8, char, endpoint2->type[4]); \
+ MC_CMD_OP(cmd, 5, 40, 8, char, endpoint2->type[5]); \
+ MC_CMD_OP(cmd, 5, 48, 8, char, endpoint2->type[6]); \
+ MC_CMD_OP(cmd, 5, 56, 8, char, endpoint2->type[7]); \
+ MC_CMD_OP(cmd, 6, 0, 8, char, endpoint2->type[8]); \
+ MC_CMD_OP(cmd, 6, 8, 8, char, endpoint2->type[9]); \
+ MC_CMD_OP(cmd, 6, 16, 8, char, endpoint2->type[10]); \
+ MC_CMD_OP(cmd, 6, 24, 8, char, endpoint2->type[11]); \
+ MC_CMD_OP(cmd, 6, 32, 8, char, endpoint2->type[12]); \
+ MC_CMD_OP(cmd, 6, 40, 8, char, endpoint2->type[13]); \
+ MC_CMD_OP(cmd, 6, 48, 8, char, endpoint2->type[14]); \
+ MC_CMD_OP(cmd, 6, 56, 8, char, endpoint2->type[15]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_DISCONNECT(cmd, endpoint) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, endpoint->id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, endpoint->interface_id); \
+ MC_CMD_OP(cmd, 1, 0, 8, char, endpoint->type[0]); \
+ MC_CMD_OP(cmd, 1, 8, 8, char, endpoint->type[1]); \
+ MC_CMD_OP(cmd, 1, 16, 8, char, endpoint->type[2]); \
+ MC_CMD_OP(cmd, 1, 24, 8, char, endpoint->type[3]); \
+ MC_CMD_OP(cmd, 1, 32, 8, char, endpoint->type[4]); \
+ MC_CMD_OP(cmd, 1, 40, 8, char, endpoint->type[5]); \
+ MC_CMD_OP(cmd, 1, 48, 8, char, endpoint->type[6]); \
+ MC_CMD_OP(cmd, 1, 56, 8, char, endpoint->type[7]); \
+ MC_CMD_OP(cmd, 2, 0, 8, char, endpoint->type[8]); \
+ MC_CMD_OP(cmd, 2, 8, 8, char, endpoint->type[9]); \
+ MC_CMD_OP(cmd, 2, 16, 8, char, endpoint->type[10]); \
+ MC_CMD_OP(cmd, 2, 24, 8, char, endpoint->type[11]); \
+ MC_CMD_OP(cmd, 2, 32, 8, char, endpoint->type[12]); \
+ MC_CMD_OP(cmd, 2, 40, 8, char, endpoint->type[13]); \
+ MC_CMD_OP(cmd, 2, 48, 8, char, endpoint->type[14]); \
+ MC_CMD_OP(cmd, 2, 56, 8, char, endpoint->type[15]); \
+} while (0)
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_CMD_GET_CONNECTION(cmd, endpoint1) \
+do { \
+ MC_CMD_OP(cmd, 0, 0, 32, int, endpoint1->id); \
+ MC_CMD_OP(cmd, 0, 32, 32, int, endpoint1->interface_id); \
+ MC_CMD_OP(cmd, 1, 0, 8, char, endpoint1->type[0]); \
+ MC_CMD_OP(cmd, 1, 8, 8, char, endpoint1->type[1]); \
+ MC_CMD_OP(cmd, 1, 16, 8, char, endpoint1->type[2]); \
+ MC_CMD_OP(cmd, 1, 24, 8, char, endpoint1->type[3]); \
+ MC_CMD_OP(cmd, 1, 32, 8, char, endpoint1->type[4]); \
+ MC_CMD_OP(cmd, 1, 40, 8, char, endpoint1->type[5]); \
+ MC_CMD_OP(cmd, 1, 48, 8, char, endpoint1->type[6]); \
+ MC_CMD_OP(cmd, 1, 56, 8, char, endpoint1->type[7]); \
+ MC_CMD_OP(cmd, 2, 0, 8, char, endpoint1->type[8]); \
+ MC_CMD_OP(cmd, 2, 8, 8, char, endpoint1->type[9]); \
+ MC_CMD_OP(cmd, 2, 16, 8, char, endpoint1->type[10]); \
+ MC_CMD_OP(cmd, 2, 24, 8, char, endpoint1->type[11]); \
+ MC_CMD_OP(cmd, 2, 32, 8, char, endpoint1->type[12]); \
+ MC_CMD_OP(cmd, 2, 40, 8, char, endpoint1->type[13]); \
+ MC_CMD_OP(cmd, 2, 48, 8, char, endpoint1->type[14]); \
+ MC_CMD_OP(cmd, 2, 56, 8, char, endpoint1->type[15]); \
+} while (0)
+
+
+/* cmd, param, offset, width, type, arg_name */
+#define DPRC_RSP_GET_CONNECTION(cmd, endpoint2, state) \
+do { \
+ MC_RSP_OP(cmd, 3, 0, 32, int, endpoint2->id); \
+ MC_RSP_OP(cmd, 3, 32, 32, int, endpoint2->interface_id); \
+ MC_RSP_OP(cmd, 4, 0, 8, char, endpoint2->type[0]); \
+ MC_RSP_OP(cmd, 4, 8, 8, char, endpoint2->type[1]); \
+ MC_RSP_OP(cmd, 4, 16, 8, char, endpoint2->type[2]); \
+ MC_RSP_OP(cmd, 4, 24, 8, char, endpoint2->type[3]); \
+ MC_RSP_OP(cmd, 4, 32, 8, char, endpoint2->type[4]); \
+ MC_RSP_OP(cmd, 4, 40, 8, char, endpoint2->type[5]); \
+ MC_RSP_OP(cmd, 4, 48, 8, char, endpoint2->type[6]); \
+ MC_RSP_OP(cmd, 4, 56, 8, char, endpoint2->type[7]); \
+ MC_RSP_OP(cmd, 5, 0, 8, char, endpoint2->type[8]); \
+ MC_RSP_OP(cmd, 5, 8, 8, char, endpoint2->type[9]); \
+ MC_RSP_OP(cmd, 5, 16, 8, char, endpoint2->type[10]); \
+ MC_RSP_OP(cmd, 5, 24, 8, char, endpoint2->type[11]); \
+ MC_RSP_OP(cmd, 5, 32, 8, char, endpoint2->type[12]); \
+ MC_RSP_OP(cmd, 5, 40, 8, char, endpoint2->type[13]); \
+ MC_RSP_OP(cmd, 5, 48, 8, char, endpoint2->type[14]); \
+ MC_RSP_OP(cmd, 5, 56, 8, char, endpoint2->type[15]); \
+ MC_RSP_OP(cmd, 6, 0, 32, int, state); \
+} while (0)
+
+/* Data Path Resource Container API
+ * Contains DPRC API for managing and querying DPAA resources
+ */
+struct fsl_mc_io;
+
+/**
+ * Set this value as the icid value in dprc_cfg structure when creating a
+ * container, in case the ICID is not selected by the user and should be
+ * allocated by the DPRC from the pool of ICIDs.
+ */
+#define DPRC_GET_ICID_FROM_POOL (uint16_t)(~(0))
+
+/**
+ * Set this value as the portal_id value in dprc_cfg structure when creating a
+ * container, in case the portal ID is not specifically selected by the
+ * user and should be allocated by the DPRC from the pool of portal ids.
+ */
+#define DPRC_GET_PORTAL_ID_FROM_POOL (int)(~(0))
+
+/**
+ * dprc_get_container_id() - Get container ID associated with a given portal.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @container_id: Requested container ID
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_container_id(struct fsl_mc_io *mc_io, int *container_id);
+
+/**
+ * dprc_open() - Open DPRC object for use
+ * @mc_io: Pointer to MC portal's I/O object
+ * @container_id: Container ID to open
+ * @token: Returned token of DPRC object
+ *
+ * Return: '0' on Success; Error code otherwise.
+ *
+ * @warning Required before any operation on the object.
+ */
+int dprc_open(struct fsl_mc_io *mc_io, int container_id, uint16_t *token);
+
+/**
+ * dprc_close() - Close the control session of the object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ *
+ * After this function is called, no further operations are
+ * allowed on the object without opening a new control session.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_close(struct fsl_mc_io *mc_io, uint16_t token);
+
+/**
+ * Container general options
+ *
+ * These options may be selected at container creation by the container creator
+ * and can be retrieved using dprc_get_attributes()
+ */
+
+/* Spawn Policy Option allowed - Indicates that the new container is allowed
+ * to spawn and have its own child containers.
+ */
+#define DPRC_CFG_OPT_SPAWN_ALLOWED 0x00000001
+
+/* General Container allocation policy - Indicates that the new container is
+ * allowed to allocate requested resources from its parent container; if not
+ * set, the container is only allowed to use resources in its own pools; Note
+ * that this is a container's global policy, but the parent container may
+ * override it and set specific quota per resource type.
+ */
+#define DPRC_CFG_OPT_ALLOC_ALLOWED 0x00000002
+
+/* Object initialization allowed - software context associated with this
+ * container is allowed to invoke object initialization operations.
+ */
+#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
+ * of network objects.
+ */
+#define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED 0x00000008
+
+/* IOMMU bypass - indicates whether objects of this container are permitted
+ * to bypass the IOMMU.
+ */
+#define DPRC_CFG_OPT_IOMMU_BYPASS 0x00000010
+
+/* AIOP - Indicates that container belongs to AIOP. */
+#define DPRC_CFG_OPT_AIOP 0x00000020
+
+/**
+ * struct dprc_cfg - Container configuration options
+ * @icid: Container's ICID; if set to 'DPRC_GET_ICID_FROM_POOL', a free
+ * ICID value is allocated by the DPRC
+ * @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
+ */
+struct dprc_cfg {
+ uint16_t icid;
+ int portal_id;
+ uint64_t options;
+};
+
+/**
+ * dprc_reset_container - Reset child container.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @child_container_id: ID of the container to reset
+ *
+ * In case a software context crashes or becomes non-responsive, the parent
+ * may wish to reset its resources container before the software context is
+ * restarted.
+ *
+ * This routine informs all objects assigned to the child container that the
+ * container is being reset, so they may perform any cleanup operations that are
+ * needed. All objects handles that were owned by the child container shall be
+ * closed.
+ *
+ * Note that such request may be submitted even if the child software context
+ * has not crashed, but the resulting object cleanup operations will not be
+ * aware of that.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_reset_container(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ int child_container_id);
+
+/**
+ * struct dprc_attributes - Container attributes
+ * @container_id: Container's ID
+ * @icid: Container's ICID
+ * @portal_id: Container's portal ID
+ * @options: Container's options as set at container's creation
+ * @version: DPRC version
+ */
+struct dprc_attributes {
+ int container_id;
+ uint16_t icid;
+ int portal_id;
+ uint64_t options;
+ /**
+ * struct version - DPRC version
+ * @major: DPRC major version
+ * @minor: DPRC minor version
+ */
+ struct {
+ uint16_t major;
+ uint16_t minor;
+ } version;
+};
+
+/**
+ * dprc_get_attributes() - Obtains container attributes
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @attributes Returned container attributes
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_attributes(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ struct dprc_attributes *attributes);
+
+/**
+ * dprc_get_obj_count() - Obtains the number of objects in the DPRC
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @obj_count: Number of objects assigned to the DPRC
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_obj_count(struct fsl_mc_io *mc_io, uint16_t token, int *obj_count);
+
+/* Objects Attributes Flags */
+
+/* Opened state - Indicates that an object is open by at least one owner */
+#define DPRC_OBJ_STATE_OPEN 0x00000001
+/* Plugged state - Indicates that the object is plugged */
+#define DPRC_OBJ_STATE_PLUGGED 0x00000002
+
+/**
+ * struct dprc_obj_desc - Object descriptor, returned from dprc_get_obj()
+ * @type: Type of object: NULL terminated string
+ * @id: ID of logical object resource
+ * @vendor: Object vendor identifier
+ * @ver_major: Major version number
+ * @ver_minor: Minor version number
+ * @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
+ */
+struct dprc_obj_desc {
+ char type[16];
+ int id;
+ uint16_t vendor;
+ uint16_t ver_major;
+ uint16_t ver_minor;
+ uint8_t irq_count;
+ uint8_t region_count;
+ uint32_t state;
+};
+
+/**
+ * dprc_get_obj() - Get general information on an object
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @obj_index: Index of the object to be queried (< obj_count)
+ * @obj_desc: Returns the requested object descriptor
+ *
+ * The object descriptors are retrieved one by one by incrementing
+ * obj_index up to (not including) the value of obj_count returned
+ * from dprc_get_obj_count(). dprc_get_obj_count() must
+ * be called prior to dprc_get_obj().
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_obj(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ int obj_index,
+ 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
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @type: pool type
+ * @res_count: Returned number of free resources of the given
+ * resource type that are assigned to this DPRC
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_res_count(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *type,
+ int *res_count);
+
+/**
+ * enum dprc_iter_status - Iteration status
+ * @DPRC_ITER_STATUS_FIRST: Perform first iteration
+ * @DPRC_ITER_STATUS_MORE: Indicates more/next iteration is needed
+ * @DPRC_ITER_STATUS_LAST: Indicates last iteration
+ */
+enum dprc_iter_status {
+ DPRC_ITER_STATUS_FIRST = 0,
+ DPRC_ITER_STATUS_MORE = 1,
+ DPRC_ITER_STATUS_LAST = 2
+};
+
+/**
+ * struct dprc_res_ids_range_desc - Resource ID range descriptor
+ * @base_id: Base resource ID of this range
+ * @last_id: Last resource ID of this range
+ * @iter_status: Iteration status - should be set to DPRC_ITER_STATUS_FIRST at
+ * first iteration; while the returned marker is DPRC_ITER_STATUS_MORE,
+ * additional iterations are needed, until the returned marker is
+ * DPRC_ITER_STATUS_LAST
+ */
+struct dprc_res_ids_range_desc {
+ int base_id;
+ int last_id;
+ enum dprc_iter_status iter_status;
+};
+
+/**
+ * dprc_get_res_ids() - Obtains IDs of free resources in the container
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @type: pool type
+ * @range_desc: range descriptor
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_res_ids(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *type,
+ struct dprc_res_ids_range_desc *range_desc);
+
+/**
+ * struct dprc_region_desc - Mappable region descriptor
+ * @base_paddr: Region base physical address
+ * @size: Region size (in bytes)
+ */
+struct dprc_region_desc {
+ uint64_t base_paddr;
+ uint32_t size;
+};
+
+/**
+ * dprc_get_obj_region() - Get region information for a specified object.
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @obj_type; Object type as returned in dprc_get_obj()
+ * @obj_id: Unique object instance as returned in dprc_get_obj()
+ * @region_index: The specific region to query
+ * @region_desc: Returns the requested region descriptor
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_get_obj_region(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ char *obj_type,
+ int obj_id,
+ uint8_t region_index,
+ struct dprc_region_desc *region_desc);
+/**
+ * struct dprc_endpoint - Endpoint description for link connect/disconnect
+ * operations
+ * @type: Endpoint object type: NULL terminated string
+ * @id: Endpoint object ID
+ * @interface_id: Interface ID; should be set for endpoints with multiple
+ * interfaces ("dpsw", "dpdmux"); for others, always set to 0
+ */
+struct dprc_endpoint {
+ char type[16];
+ int id;
+ int interface_id;
+};
+
+/**
+ * dprc_connect() - Connect two endpoints to create a network link between them
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @endpoint1: Endpoint 1 configuration parameters
+ * @endpoint2: Endpoint 2 configuration parameters
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_connect(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint1,
+ const struct dprc_endpoint *endpoint2);
+
+/**
+ * dprc_disconnect() - Disconnect one endpoint to remove its network connection
+ * @mc_io: Pointer to MC portal's I/O object
+ * @token: Token of DPRC object
+ * @endpoint: Endpoint configuration parameters
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+int dprc_disconnect(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint);
+
+/**
+* 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
+* @endpoint1 Endpoint 1 configuration parameters
+* @endpoint2 Returned endpoint 2 configuration parameters
+* @state: Returned link state: 1 - link is up, 0 - link is down
+*
+* Return: '0' on Success; -ENAVAIL if connection does not exist.
+*/
+int dprc_get_connection(struct fsl_mc_io *mc_io,
+ uint16_t token,
+ const struct dprc_endpoint *endpoint1,
+ struct dprc_endpoint *endpoint2,
+ int *state);
+
+#endif /* _FSL_DPRC_H */
diff --git a/include/fsl-mc/fsl_mc.h b/include/fsl-mc/fsl_mc.h
index b9f089e..ec24415 100644
--- a/include/fsl-mc/fsl_mc.h
+++ b/include/fsl-mc/fsl_mc.h
@@ -53,7 +53,8 @@ struct mc_ccsr_registers {
u32 reg_error[];
};
-int mc_init(bd_t *bis);
-
int get_mc_boot_status(void);
+unsigned long mc_get_dram_block_size(void);
+int fsl_mc_ldpaa_init(bd_t *bis);
+void fsl_mc_ldpaa_exit(bd_t *bis);
#endif
diff --git a/include/fsl-mc/fsl_mc_cmd.h b/include/fsl-mc/fsl_mc_cmd.h
index e7fcb5b..cb39c39 100644
--- a/include/fsl-mc/fsl_mc_cmd.h
+++ b/include/fsl-mc/fsl_mc_cmd.h
@@ -1,4 +1,4 @@
-/* Copyright 2014 Freescale Semiconductor Inc.
+/* Copyright 2013-2015 Freescale Semiconductor Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
@@ -41,9 +41,9 @@ enum mc_cmd_status {
#define MC_CMD_HDR_CMDID_O 52 /* Command ID field offset */
#define MC_CMD_HDR_CMDID_S 12 /* Command ID field size */
-#define MC_CMD_HDR_AUTHID_O 38 /* Authentication ID field offset */
-#define MC_CMD_HDR_AUTHID_S 10 /* Authentication ID field size */
#define MC_CMD_HDR_STATUS_O 16 /* Status field offset */
+#define MC_CMD_HDR_TOKEN_O 38 /* Token field offset */
+#define MC_CMD_HDR_TOKEN_S 10 /* Token field size */
#define MC_CMD_HDR_STATUS_S 8 /* Status field size*/
#define MC_CMD_HDR_PRI_O 15 /* Priority field offset */
#define MC_CMD_HDR_PRI_S 1 /* Priority field size */
@@ -52,12 +52,15 @@ enum mc_cmd_status {
((enum mc_cmd_status)u64_dec((_hdr), \
MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S))
-#define MC_CMD_HDR_READ_AUTHID(_hdr) \
- ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S))
+#define MC_CMD_HDR_READ_TOKEN(_hdr) \
+ ((uint16_t)u64_dec((_hdr), MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S))
#define MC_CMD_PRI_LOW 0 /*!< Low Priority command indication */
#define MC_CMD_PRI_HIGH 1 /*!< High Priority command indication */
+#define MC_EXT_OP(_ext, _param, _offset, _width, _type, _arg) \
+ ((_ext)[_param] |= u64_enc((_offset), (_width), _arg))
+
#define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \
((_cmd).params[_param] |= u64_enc((_offset), (_width), _arg))
@@ -66,12 +69,12 @@ enum mc_cmd_status {
static inline uint64_t mc_encode_cmd_header(uint16_t cmd_id,
uint8_t priority,
- uint16_t auth_id)
+ uint16_t token)
{
uint64_t hdr;
hdr = u64_enc(MC_CMD_HDR_CMDID_O, MC_CMD_HDR_CMDID_S, cmd_id);
- hdr |= u64_enc(MC_CMD_HDR_AUTHID_O, MC_CMD_HDR_AUTHID_S, auth_id);
+ hdr |= u64_enc(MC_CMD_HDR_TOKEN_O, MC_CMD_HDR_TOKEN_S, token);
hdr |= u64_enc(MC_CMD_HDR_PRI_O, MC_CMD_HDR_PRI_S, priority);
hdr |= u64_enc(MC_CMD_HDR_STATUS_O, MC_CMD_HDR_STATUS_S,
MC_CMD_STATUS_READY);
diff --git a/include/fsl-mc/fsl_mc_private.h b/include/fsl-mc/fsl_mc_private.h
new file mode 100644
index 0000000..9f06978
--- /dev/null
+++ b/include/fsl-mc/fsl_mc_private.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_MC_PRIVATE_H_
+#define _FSL_MC_PRIVATE_H_
+
+#include <errno.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <linux/compat.h>
+#include <linux/types.h>
+#include <linux/stringify.h>
+
+#include <fsl-mc/fsl_mc_sys.h>
+#include <fsl-mc/fsl_mc_cmd.h>
+#include <fsl-mc/fsl_dprc.h>
+#include <fsl-mc/fsl_dpbp.h>
+
+extern struct fsl_mc_io *dflt_mc_io;
+
+/**
+ * struct dpbp_node - DPBP strucuture
+ * @uint16_t handle: DPBP object handle
+ * @int dpbp_id: DPBP id
+ */
+struct fsl_dpbp_obj {
+ uint16_t dpbp_handle;
+ struct dpbp_attr dpbp_attr;
+};
+
+extern struct fsl_dpbp_obj *dflt_dpbp;
+
+/**
+ * struct fsl_dpio_obj - DPIO strucuture
+ * @int dpio_id: DPIO id
+ * @struct qbman_swp *sw_portal: SW portal object
+ */
+struct fsl_dpio_obj {
+ int dpio_id;
+ struct qbman_swp *sw_portal; /** SW portal object */
+};
+
+extern struct fsl_dpio_obj *dflt_dpio;
+
+int mc_init(void);
+int ldpaa_eth_init(struct dprc_obj_desc obj_desc);
+#endif /* _FSL_MC_PRIVATE_H_ */
diff --git a/include/fsl-mc/fsl_qbman_base.h b/include/fsl-mc/fsl_qbman_base.h
new file mode 100644
index 0000000..c92cbe1
--- /dev/null
+++ b/include/fsl-mc/fsl_qbman_base.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_QBMAN_BASE_H
+#define _FSL_QBMAN_BASE_H
+
+/* Descriptor for a QBMan instance on the SoC. On partitions/targets that do not
+ * control this QBMan instance, these values may simply be place-holders. The
+ * idea is simply that we be able to distinguish between them, eg. so that SWP
+ * descriptors can identify which QBMan instance they belong to. */
+struct qbman_block_desc {
+ void *ccsr_reg_bar; /* CCSR register map */
+ int irq_rerr; /* Recoverable error interrupt line */
+ int irq_nrerr; /* Non-recoverable error interrupt line */
+};
+
+/* Descriptor for a QBMan software portal, expressed in terms that make sense to
+ * the user context. Ie. on MC, this information is likely to be true-physical,
+ * and instantiated statically at compile-time. On GPP, this information is
+ * likely to be obtained via "discovery" over a partition's "layerscape bus"
+ * (ie. in response to a MC portal command), and would take into account any
+ * virtualisation of the GPP user's address space and/or interrupt numbering. */
+struct qbman_swp_desc {
+ const struct qbman_block_desc *block; /* The QBMan instance */
+ void *cena_bar; /* Cache-enabled portal register map */
+ void *cinh_bar; /* Cache-inhibited portal register map */
+};
+
+/* Driver object for managing a QBMan portal */
+struct qbman_swp;
+
+/* Place-holder for FDs, we represent it via the simplest form that we need for
+ * now. Different overlays may be needed to support different options, etc. (It
+ * is impractical to define One True Struct, because the resulting encoding
+ * routines (lots of read-modify-writes) would be worst-case performance whether
+ * or not circumstances required them.)
+ *
+ * Note, as with all data-structures exchanged between software and hardware (be
+ * they located in the portal register map or DMA'd to and from main-memory),
+ * the driver ensures that the caller of the driver API sees the data-structures
+ * in host-endianness. "struct qbman_fd" is no exception. The 32-bit words
+ * contained within this structure are represented in host-endianness, even if
+ * hardware always treats them as little-endian. As such, if any of these fields
+ * are interpreted in a binary (rather than numerical) fashion by hardware
+ * blocks (eg. accelerators), then the user should be careful. We illustrate
+ * with an example;
+ *
+ * Suppose the desired behaviour of an accelerator is controlled by the "frc"
+ * field of the FDs that are sent to it. Suppose also that the behaviour desired
+ * by the user corresponds to an "frc" value which is expressed as the literal
+ * sequence of bytes 0xfe, 0xed, 0xab, and 0xba. So "frc" should be the 32-bit
+ * value in which 0xfe is the first byte and 0xba is the last byte, and as
+ * hardware is little-endian, this amounts to a 32-bit "value" of 0xbaabedfe. If
+ * the software is little-endian also, this can simply be achieved by setting
+ * frc=0xbaabedfe. On the other hand, if software is big-endian, it should set
+ * frc=0xfeedabba! The best away of avoiding trouble with this sort of thing is
+ * to treat the 32-bit words as numerical values, in which the offset of a field
+ * from the beginning of the first byte (as required or generated by hardware)
+ * is numerically encoded by a left-shift (ie. by raising the field to a
+ * corresponding power of 2). Ie. in the current example, software could set
+ * "frc" in the following way, and it would work correctly on both little-endian
+ * and big-endian operation;
+ * fd.frc = (0xfe << 0) | (0xed << 8) | (0xab << 16) | (0xba << 24);
+ */
+struct qbman_fd {
+ union {
+ uint32_t words[8];
+ struct qbman_fd_simple {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t len;
+ /* offset in the MS 16 bits, BPID in the LS 16 bits */
+ uint32_t bpid_offset;
+ uint32_t frc; /* frame context */
+ /* "err", "va", "cbmt", "asal", [...] */
+ uint32_t ctrl;
+ /* flow context */
+ uint32_t flc_lo;
+ uint32_t flc_hi;
+ } simple;
+ };
+};
+
+#endif /* !_FSL_QBMAN_BASE_H */
diff --git a/include/fsl-mc/fsl_qbman_portal.h b/include/fsl-mc/fsl_qbman_portal.h
new file mode 100644
index 0000000..2aadad8
--- /dev/null
+++ b/include/fsl-mc/fsl_qbman_portal.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_QBMAN_PORTAL_H
+#define _FSL_QBMAN_PORTAL_H
+
+#include <fsl-mc/fsl_qbman_base.h>
+
+/* Create and destroy a functional object representing the given QBMan portal
+ * descriptor. */
+struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *);
+
+ /************/
+ /* Dequeues */
+ /************/
+
+/* See the QBMan driver API documentation for details on the enqueue
+ * mechanisms. NB: the use of a 'ldpaa_' prefix for this type is because it is
+ * primarily used by the "DPIO" layer that sits above (and hides) the QBMan
+ * driver. The structure is defined in the DPIO interface, but to avoid circular
+ * dependencies we just pre/re-declare it here opaquely. */
+struct ldpaa_dq;
+
+
+/* ------------------- */
+/* Pull-mode dequeuing */
+/* ------------------- */
+
+struct qbman_pull_desc {
+ uint32_t dont_manipulate_directly[6];
+};
+
+/* Clear the contents of a descriptor to default/starting state. */
+void qbman_pull_desc_clear(struct qbman_pull_desc *);
+/* If not called, or if called with 'storage' as NULL, the result pull dequeues
+ * will produce results to DQRR. If 'storage' is non-NULL, then results are
+ * produced to the given memory location (using the physical/DMA address which
+ * the caller provides in 'storage_phys'), and 'stash' controls whether or not
+ * those writes to main-memory express a cache-warming attribute. */
+void qbman_pull_desc_set_storage(struct qbman_pull_desc *,
+ struct ldpaa_dq *storage,
+ dma_addr_t storage_phys,
+ int stash);
+/* numframes must be between 1 and 16, inclusive */
+void qbman_pull_desc_set_numframes(struct qbman_pull_desc *, uint8_t numframes);
+/* token is the value that shows up in the dequeue results that can be used to
+ * detect when the results have been published, and is not really used when
+ * dequeue results go to DQRR. The easiest technique is to zero result "storage"
+ * before issuing a pull dequeue, and use any non-zero 'token' value. */
+void qbman_pull_desc_set_token(struct qbman_pull_desc *, uint8_t token);
+/* Exactly one of the following descriptor "actions" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - pull dequeue from the given frame queue (FQ)
+ * - pull dequeue from any FQ in the given work queue (WQ)
+ * - pull dequeue from any FQ in any WQ in the given channel
+ */
+void qbman_pull_desc_set_fq(struct qbman_pull_desc *, uint32_t fqid);
+
+/* Issue the pull dequeue command */
+int qbman_swp_pull(struct qbman_swp *, struct qbman_pull_desc *);
+
+/* -------------------------------- */
+/* Polling DQRR for dequeue results */
+/* -------------------------------- */
+
+/* NULL return if there are no unconsumed DQRR entries. Returns a DQRR entry
+ * only once, so repeated calls can return a sequence of DQRR entries, without
+ * requiring they be consumed immediately or in any particular order. */
+const struct ldpaa_dq *qbman_swp_dqrr_next(struct qbman_swp *);
+/* Consume DQRR entries previously returned from qbman_swp_dqrr_next(). */
+void qbman_swp_dqrr_consume(struct qbman_swp *, const struct ldpaa_dq *);
+
+/* ------------------------------------------------- */
+/* Polling user-provided storage for dequeue results */
+/* ------------------------------------------------- */
+
+/* Only used for user-provided storage of dequeue results, not DQRR. Prior to
+ * being used, the storage must set "oldtoken", so that the driver notices when
+ * hardware has filled it in with results using a "newtoken". NB, for efficiency
+ * purposes, the driver will perform any required endianness conversion to
+ * ensure that the user's dequeue result storage is in host-endian format
+ * (whether or not that is the same as the little-endian format that hardware
+ * DMA'd to the user's storage). As such, once the user has called
+ * qbman_dq_entry_has_newtoken() and been returned a valid dequeue result, they
+ * should not call it again on the same memory location (except of course if
+ * another dequeue command has been executed to produce a new result to that
+ * location).
+ */
+void qbman_dq_entry_set_oldtoken(struct ldpaa_dq *,
+ unsigned int num_entries,
+ uint8_t oldtoken);
+int qbman_dq_entry_has_newtoken(struct qbman_swp *,
+ const struct ldpaa_dq *,
+ uint8_t newtoken);
+
+/* -------------------------------------------------------- */
+/* Parsing dequeue entries (DQRR and user-provided storage) */
+/* -------------------------------------------------------- */
+
+/* DQRR entries may contain non-dequeue results, ie. notifications */
+int qbman_dq_entry_is_DQ(const struct ldpaa_dq *);
+
+ /************/
+ /* Enqueues */
+ /************/
+
+struct qbman_eq_desc {
+ uint32_t dont_manipulate_directly[8];
+};
+
+
+/* Clear the contents of a descriptor to default/starting state. */
+void qbman_eq_desc_clear(struct qbman_eq_desc *);
+/* Exactly one of the following descriptor "actions" should be set. (Calling
+ * any one of these will replace the effect of any prior call to one of these.)
+ * - enqueue without order-restoration
+ * - enqueue with order-restoration
+ * - fill a hole in the order-restoration sequence, without any enqueue
+ * - advance NESN (Next Expected Sequence Number), without any enqueue
+ * 'respond_success' indicates whether an enqueue response should be DMA'd
+ * after success (otherwise a response is DMA'd only after failure).
+ * 'incomplete' indicates that other fragments of the same 'seqnum' are yet to
+ * be enqueued.
+ */
+void qbman_eq_desc_set_no_orp(struct qbman_eq_desc *, int respond_success);
+void qbman_eq_desc_set_response(struct qbman_eq_desc *,
+ dma_addr_t storage_phys,
+ int stash);
+/* token is the value that shows up in an enqueue response that can be used to
+ * detect when the results have been published. The easiest technique is to zero
+ * result "storage" before issuing an enqueue, and use any non-zero 'token'
+ * value. */
+void qbman_eq_desc_set_token(struct qbman_eq_desc *, uint8_t token);
+/* Exactly one of the following descriptor "targets" should be set. (Calling any
+ * one of these will replace the effect of any prior call to one of these.)
+ * - enqueue to a frame queue
+ * - enqueue to a queuing destination
+ * Note, that none of these will have any affect if the "action" type has been
+ * set to "orp_hole" or "orp_nesn".
+ */
+void qbman_eq_desc_set_fq(struct qbman_eq_desc *, uint32_t fqid);
+void qbman_eq_desc_set_qd(struct qbman_eq_desc *, uint32_t qdid,
+ uint32_t qd_bin, uint32_t qd_prio);
+
+/* Issue an enqueue command. ('fd' should only be NULL if the "action" of the
+ * descriptor is "orp_hole" or "orp_nesn".) */
+int qbman_swp_enqueue(struct qbman_swp *, const struct qbman_eq_desc *,
+ const struct qbman_fd *fd);
+
+ /*******************/
+ /* Buffer releases */
+ /*******************/
+
+struct qbman_release_desc {
+ uint32_t dont_manipulate_directly[1];
+};
+
+/* Clear the contents of a descriptor to default/starting state. */
+void qbman_release_desc_clear(struct qbman_release_desc *);
+/* Set the ID of the buffer pool to release to */
+void qbman_release_desc_set_bpid(struct qbman_release_desc *, uint32_t bpid);
+/* Issue a release command. 'num_buffers' must be less than 8. */
+int qbman_swp_release(struct qbman_swp *, const struct qbman_release_desc *,
+ const uint64_t *buffers, unsigned int num_buffers);
+
+ /*******************/
+ /* Buffer acquires */
+ /*******************/
+
+int qbman_swp_acquire(struct qbman_swp *, uint32_t bpid, uint64_t *buffers,
+ unsigned int num_buffers);
+#endif /* !_FSL_QBMAN_PORTAL_H */
diff --git a/include/fsl-mc/ldpaa_wriop.h b/include/fsl-mc/ldpaa_wriop.h
new file mode 100644
index 0000000..ca8e440
--- /dev/null
+++ b/include/fsl-mc/ldpaa_wriop.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2015 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __LDPAA_WRIOP_H
+#define __LDPAA_WRIOP_H
+
+ #include <phy.h>
+
+enum wriop_port {
+ WRIOP1_DPMAC1 = 1,
+ WRIOP1_DPMAC2,
+ WRIOP1_DPMAC3,
+ WRIOP1_DPMAC4,
+ WRIOP1_DPMAC5,
+ WRIOP1_DPMAC6,
+ WRIOP1_DPMAC7,
+ WRIOP1_DPMAC8,
+ WRIOP1_DPMAC9,
+ WRIOP1_DPMAC10,
+ WRIOP1_DPMAC11,
+ WRIOP1_DPMAC12,
+ WRIOP1_DPMAC13,
+ WRIOP1_DPMAC14,
+ WRIOP1_DPMAC15,
+ WRIOP1_DPMAC16,
+ WRIOP1_DPMAC17,
+ WRIOP1_DPMAC18,
+ WRIOP1_DPMAC19,
+ WRIOP1_DPMAC20,
+ WRIOP1_DPMAC21,
+ WRIOP1_DPMAC22,
+ WRIOP1_DPMAC23,
+ WRIOP1_DPMAC24,
+ NUM_WRIOP_PORTS,
+};
+
+struct wriop_dpmac_info {
+ u8 enabled;
+ u8 id;
+ u8 phy_addr;
+ u8 board_mux;
+ void *phy_regs;
+ phy_interface_t enet_if;
+ struct phy_device *phydev;
+ struct mii_dev *bus;
+};
+
+extern struct wriop_dpmac_info dpmac_info[NUM_WRIOP_PORTS];
+
+#define DEFAULT_WRIOP_MDIO1_NAME "FSL_MDIO0"
+#define DEFAULT_WRIOP_MDIO2_NAME "FSL_MDIO1"
+
+void wriop_init_dpmac(int, int, int);
+void wriop_disable_dpmac(int);
+void wriop_enable_dpmac(int);
+void wriop_set_mdio(int, struct mii_dev *);
+struct mii_dev *wriop_get_mdio(int);
+void wriop_set_phy_address(int, int);
+int wriop_get_phy_address(int);
+void wriop_set_phy_dev(int, struct phy_device *);
+struct phy_device *wriop_get_phy_dev(int);
+phy_interface_t wriop_get_enet_if(int);
+
+void wriop_dpmac_disable(int);
+void wriop_dpmac_enable(int);
+phy_interface_t wriop_dpmac_enet_if(int, int);
+#endif /* __LDPAA_WRIOP_H */
diff --git a/include/fsl_ddr.h b/include/fsl_ddr.h
index feccef9..4099a74 100644
--- a/include/fsl_ddr.h
+++ b/include/fsl_ddr.h
@@ -34,9 +34,7 @@
#define ddr_clrsetbits32(a, clear, set) clrsetbits_be32(a, clear, set)
#endif
-#define _DDR_ADDR CONFIG_SYS_FSL_DDR_ADDR
-
-u32 fsl_ddr_get_version(void);
+u32 fsl_ddr_get_version(unsigned int ctrl_num);
#if defined(CONFIG_DDR_SPD) || defined(CONFIG_SPD_EEPROM)
/*
diff --git a/include/fsl_ddr_sdram.h b/include/fsl_ddr_sdram.h
index 095b33e..e5b6e03 100644
--- a/include/fsl_ddr_sdram.h
+++ b/include/fsl_ddr_sdram.h
@@ -155,6 +155,8 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
#define MD_CNTL_CKE_CNTL_HIGH 0x00200000
#define MD_CNTL_WRCW 0x00080000
#define MD_CNTL_MD_VALUE(x) (x & 0x0000FFFF)
+#define MD_CNTL_CS_SEL(x) (((x) & 0x7) << 28)
+#define MD_CNTL_MD_SEL(x) (((x) & 0xf) << 24)
/* DDR_CDR1 */
#define DDR_CDR1_DHC_EN 0x80000000
@@ -165,6 +167,7 @@ typedef struct ddr4_spd_eeprom_s generic_spd_eeprom_t;
#define DDR_CDR2_ODT(x) (x & DDR_CDR2_ODT_MASK)
#define DDR_CDR2_VREF_OVRD(x) (0x00008080 | ((((x) - 37) & 0x3F) << 8))
#define DDR_CDR2_VREF_TRAIN_EN 0x00000080
+#define DDR_CDR2_VREF_RANGE_2 0x00000040
#if (defined(CONFIG_SYS_FSL_DDR_VER) && \
(CONFIG_SYS_FSL_DDR_VER >= FSL_DDR_VER_4_7))
diff --git a/include/fsl_debug_server.h b/include/fsl_debug_server.h
new file mode 100644
index 0000000..28d8adb
--- /dev/null
+++ b/include/fsl_debug_server.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __FSL_DBG_SERVER_H__
+#define __FSL_DBG_SERVER_H__
+
+#include <asm/io.h>
+#include <common.h>
+
+/*
+ * Define Debug Server firmware version information
+ */
+
+/* Major version number: incremented on API compatibility changes */
+#define DEBUG_SERVER_VER_MAJOR 0
+
+/* Minor version number: incremented on API additions (backward
+ * compatible); reset when major version is incremented.
+ */
+#define DEBUG_SERVER_VER_MINOR 1
+
+#define DEBUG_SERVER_INIT_STATUS (1 << 0)
+#define DEBUG_SERVER_INIT_STATUS_MASK (0x00000001)
+
+int debug_server_init(void);
+unsigned long debug_server_get_dram_block_size(void);
+
+#endif /* __FSL_DBG_SERVER_H__ */
+
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index 57295b4..41bf05b 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -158,7 +158,11 @@
#define ESDHC_VENDORSPEC_VSELECT 0x00000002 /* Use 1.8V */
struct fsl_esdhc_cfg {
+#ifdef CONFIG_LS2085A
+ u64 esdhc_base;
+#else
u32 esdhc_base;
+#endif
u32 sdhc_clk;
u8 max_bus_width;
struct mmc_config cfg;
diff --git a/include/fsl_ifc.h b/include/fsl_ifc.h
index 11474b7..a7ddd5f 100644
--- a/include/fsl_ifc.h
+++ b/include/fsl_ifc.h
@@ -790,24 +790,36 @@ extern void print_ifc_regs(void);
extern void init_early_memctl_regs(void);
void init_final_memctl_regs(void);
-#define IFC_BASE_ADDR ((struct fsl_ifc *)CONFIG_SYS_IFC_ADDR)
-
-#define get_ifc_cspr_ext(i) (ifc_in32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext))
-#define get_ifc_cspr(i) (ifc_in32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr))
-#define get_ifc_csor_ext(i) (ifc_in32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext))
-#define get_ifc_csor(i) (ifc_in32(&(IFC_BASE_ADDR)->csor_cs[i].csor))
-#define get_ifc_amask(i) (ifc_in32(&(IFC_BASE_ADDR)->amask_cs[i].amask))
-#define get_ifc_ftim(i, j) (ifc_in32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j]))
-
-#define set_ifc_cspr_ext(i, v) \
- (ifc_out32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr_ext, v))
-#define set_ifc_cspr(i, v) (ifc_out32(&(IFC_BASE_ADDR)->cspr_cs[i].cspr, v))
-#define set_ifc_csor_ext(i, v) \
- (ifc_out32(&(IFC_BASE_ADDR)->csor_cs[i].csor_ext, v))
-#define set_ifc_csor(i, v) (ifc_out32(&(IFC_BASE_ADDR)->csor_cs[i].csor, v))
-#define set_ifc_amask(i, v) (ifc_out32(&(IFC_BASE_ADDR)->amask_cs[i].amask, v))
-#define set_ifc_ftim(i, j, v) \
- (ifc_out32(&(IFC_BASE_ADDR)->ftim_cs[i].ftim[j], v))
+#define IFC_RREGS_4KOFFSET (4*1024)
+#define IFC_RREGS_64KOFFSET (64*1024)
+
+#define IFC_FCM_BASE_ADDR \
+ ((struct fsl_ifc_fcm *)CONFIG_SYS_IFC_ADDR)
+
+#define get_ifc_cspr_ext(i) \
+ (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext))
+#define get_ifc_cspr(i) \
+ (ifc_in32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr))
+#define get_ifc_csor_ext(i) \
+ (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext))
+#define get_ifc_csor(i) \
+ (ifc_in32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor))
+#define get_ifc_amask(i) \
+ (ifc_in32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask))
+#define get_ifc_ftim(i, j) \
+ (ifc_in32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j]))
+#define set_ifc_cspr_ext(i, v) \
+ (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr_ext, v))
+#define set_ifc_cspr(i, v) \
+ (ifc_out32(&(IFC_FCM_BASE_ADDR)->cspr_cs[i].cspr, v))
+#define set_ifc_csor_ext(i, v) \
+ (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor_ext, v))
+#define set_ifc_csor(i, v) \
+ (ifc_out32(&(IFC_FCM_BASE_ADDR)->csor_cs[i].csor, v))
+#define set_ifc_amask(i, v) \
+ (ifc_out32(&(IFC_FCM_BASE_ADDR)->amask_cs[i].amask, v))
+#define set_ifc_ftim(i, j, v) \
+ (ifc_out32(&(IFC_FCM_BASE_ADDR)->ftim_cs[i].ftim[j], v))
enum ifc_chip_sel {
IFC_CS0,
@@ -869,20 +881,26 @@ struct fsl_ifc_nand {
u32 nand_evter_en;
u32 res17[0x2];
u32 nand_evter_intr_en;
- u32 res18[0x2];
+ u32 nand_vol_addr_stat;
+ u32 res18;
u32 nand_erattr0;
u32 nand_erattr1;
u32 res19[0x10];
u32 nand_fsr;
- u32 res20;
- u32 nand_eccstat[4];
- u32 res21[0x20];
+ u32 res20[0x3];
+ u32 nand_eccstat[6];
+ u32 res21[0x1c];
u32 nanndcr;
u32 res22[0x2];
u32 nand_autoboot_trgr;
u32 res23;
u32 nand_mdr;
- u32 res24[0x5C];
+ u32 res24[0x1c];
+ u32 nand_dll_lowcfg0;
+ u32 nand_dll_lowcfg1;
+ u32 res25;
+ u32 nand_dll_lowstat;
+ u32 res26[0x3C];
};
/*
@@ -917,7 +935,6 @@ struct fsl_ifc_gpcm {
u32 gpcm_erattr1;
u32 gpcm_erattr2;
u32 gpcm_stat;
- u32 res4[0x1F3];
};
#ifdef CONFIG_SYS_FSL_IFC_BANK_COUNT
@@ -965,9 +982,11 @@ struct fsl_ifc_ftim {
};
/*
- * IFC Controller Registers
+ * IFC Controller Global Registers
+ * FCM - Flash control machine
*/
-struct fsl_ifc {
+
+struct fsl_ifc_fcm {
u32 ifc_rev;
u32 res1[0x2];
struct fsl_ifc_cspr cspr_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT];
@@ -979,7 +998,8 @@ struct fsl_ifc {
struct fsl_ifc_ftim ftim_cs[CONFIG_SYS_FSL_IFC_BANK_COUNT];
u8 res5[IFC_FTIM_REG_LEN - IFC_FTIM_USED_LEN];
u32 rb_stat;
- u32 res6[0x2];
+ u32 rb_map;
+ u32 wp_map;
u32 ifc_gcr;
u32 res7[0x2];
u32 cm_evter_stat;
@@ -993,12 +1013,20 @@ struct fsl_ifc {
u32 res11[0x2];
u32 ifc_ccr;
u32 ifc_csr;
- u32 res12[0x2EB];
+ u32 ddr_ccr_low;
+};
+
+struct fsl_ifc_runtime {
struct fsl_ifc_nand ifc_nand;
struct fsl_ifc_nor ifc_nor;
struct fsl_ifc_gpcm ifc_gpcm;
};
+struct fsl_ifc {
+ struct fsl_ifc_fcm *gregs;
+ struct fsl_ifc_runtime *rregs;
+};
+
#ifdef CONFIG_SYS_FSL_ERRATUM_IFC_A002769
#undef CSPR_MSEL_NOR
#define CSPR_MSEL_NOR CSPR_MSEL_GPCM
diff --git a/arch/powerpc/include/asm/fsl_memac.h b/include/fsl_memac.h
index bed2a40..bed2a40 100644
--- a/arch/powerpc/include/asm/fsl_memac.h
+++ b/include/fsl_memac.h
diff --git a/include/fsl_usb.h b/include/fsl_usb.h
index d251f5d..33d9f03 100644
--- a/include/fsl_usb.h
+++ b/include/fsl_usb.h
@@ -87,6 +87,33 @@ struct ccsr_usb_phy {
/* USB Erratum Checking code */
#ifdef CONFIG_PPC
+static inline bool has_dual_phy(void)
+{
+ u32 svr = get_svr();
+ u32 soc = SVR_SOC_VER(svr);
+
+ switch (soc) {
+ case SVR_T1023:
+ case SVR_T1024:
+ case SVR_T1013:
+ case SVR_T1014:
+ return IS_SVR_REV(svr, 1, 0);
+ case SVR_T1040:
+ case SVR_T1042:
+ case SVR_T1020:
+ case SVR_T1022:
+ case SVR_T2080:
+ case SVR_T2081:
+ return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1);
+ case SVR_T4240:
+ case SVR_T4160:
+ case SVR_T4080:
+ return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 2, 0);
+ }
+
+ return false;
+}
+
static inline bool has_erratum_a006261(void)
{
u32 svr = get_svr();
@@ -155,8 +182,13 @@ static inline bool has_erratum_a007792(void)
case SVR_T4240:
case SVR_T4160:
return IS_SVR_REV(svr, 2, 0);
- case SVR_T1040:
+ case SVR_T1024:
+ case SVR_T1023:
return IS_SVR_REV(svr, 1, 0);
+ case SVR_T1040:
+ case SVR_T1042:
+ case SVR_T1020:
+ case SVR_T1022:
case SVR_T2080:
case SVR_T2081:
return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1);
@@ -164,7 +196,25 @@ static inline bool has_erratum_a007792(void)
return false;
}
+static inline bool has_erratum_a005697(void)
+{
+ u32 svr = get_svr();
+ u32 soc = SVR_SOC_VER(svr);
+
+ switch (soc) {
+ case SVR_9131:
+ case SVR_9132:
+ return IS_SVR_REV(svr, 1, 0) || IS_SVR_REV(svr, 1, 1);
+ }
+ return false;
+}
+
#else
+static inline bool has_dual_phy(void)
+{
+ return false;
+}
+
static inline bool has_erratum_a006261(void)
{
return false;
@@ -184,5 +234,10 @@ static inline bool has_erratum_a007792(void)
{
return false;
}
+
+static inline bool has_erratum_a005697(void)
+{
+ return false;
+}
#endif
#endif /*_ASM_FSL_USB_H_ */
diff --git a/include/linux/immap_qe.h b/include/linux/immap_qe.h
index b317dcb..6d1f88e 100644
--- a/include/linux/immap_qe.h
+++ b/include/linux/immap_qe.h
@@ -24,6 +24,18 @@
#endif
#endif
+#ifdef CONFIG_LS102XA
+#define QE_MURAM_SIZE 0x6000UL
+#define MAX_QE_RISC 1
+#define QE_NUM_OF_SNUM 28
+#endif
+
+#ifdef CONFIG_PPC
+#define QE_IMMR_OFFSET 0x00140000
+#else
+#define QE_IMMR_OFFSET 0x01400000
+#endif
+
/* QE I-RAM */
typedef struct qe_iram {
u32 iadd; /* I-RAM Address Register */