GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,34 @@
if TARGET_LX2160ARDB
config SYS_BOARD
default "lx2160a"
config SYS_VENDOR
default "freescale"
config SYS_SOC
default "fsl-layerscape"
config SYS_CONFIG_NAME
default "lx2160ardb"
source "board/freescale/common/Kconfig"
endif
if TARGET_LX2160AQDS
config SYS_BOARD
default "lx2160a"
config SYS_VENDOR
default "freescale"
config SYS_SOC
default "fsl-layerscape"
config SYS_CONFIG_NAME
default "lx2160aqds"
source "board/freescale/common/Kconfig"
endif
@@ -0,0 +1,26 @@
LX2160ARDB BOARD
M: Priyanka Jain <priyanka.jain@nxp.com>
S: Maintained
F: board/freescale/lx2160a/
F: include/configs/lx2160a_common.h
F: include/configs/lx2160ardb.h
F: configs/lx2160ardb_tfa_defconfig
F: arch/arm/dts/fsl-lx2160a-rdb.dts
LX2160ARDB_SECURE_BOOT BOARD
M: Udit Agarwal <udit.agarwal@nxp.com>
S: Maintained
F: configs/lx2160ardb_tfa_SECURE_BOOT_defconfig
LX2160AQDS BOARD
M: Pankaj Bansal <pankaj.bansal@nxp.com>
S: Maintained
F: board/freescale/lx2160a/eth_lx2160aqds.h
F: include/configs/lx2160aqds.h
F: configs/lx2160aqds_tfa_defconfig
F: arch/arm/dts/fsl-lx2160a-qds.dts
LX2160AQDS_SECURE_BOOT BOARD
M: Udit Agarwal <udit.agarwal@nxp.com>
S: Maintained
F: configs/lx2160aqds_tfa_SECURE_BOOT_defconfig
@@ -0,0 +1,10 @@
#
# Copyright 2018 Freescale Semiconductor
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += lx2160a.o
obj-y += ddr.o
obj-$(CONFIG_TARGET_LX2160ARDB) += eth_lx2160ardb.o
obj-$(CONFIG_TARGET_LX2160AQDS) += eth_lx2160aqds.o
@@ -0,0 +1,197 @@
Overview
--------
The LX2160A Reference Design (RDB) is a high-performance computing,
evaluation, and development platform that supports the QorIQ LX2160A
Layerscape Architecture processor and its personalities.
LX2160A SoC Overview
--------------------------------------
For details, please refer arch/arm/cpu/armv8/fsl-layerscape/doc/README.soc
LX2160ARDB board Overview
----------------------
DDR Memory
Two ports of 72-bits (8-bits ECC) DDR4.
Each port supports four chip-selects and two DIMM
connectors. Data rate upto 3.2 GT/s.
SERDES ports
Thress serdes controllers (24 lanes)
Serdes1: Supports two USXGMII connectors, each connected through
Aquantia AQR107 phy, two 25GbE SFP+ modules connected through an Inphi
IN112525 phy and one 40 GbE QSFP+ module connected through an Inphi
CS4223 phy.
Serdes2: Supports one PCIe x4 (Gen1/2/3/4) connector, four SATA 3.0
connectors
Serdes3: Supports one PCIe x8 (Gen1/2/3/4) connector
eSDHC
eSDHC1: Supports a SD connector for connecting SD cards
eSDHC2: Supports 128GB Micron MTFC128GAJAECE-IT eMMC
Octal SPI (XSPI)
Supports two 64 MB onbpard octal SPI flash memories, one SPI emulator
for off-board emulation
I2C All system devices on I2C1 multiplexed using PCA9547 multiplexer
Serial Ports
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
Serial Ports Two UART ports
Ethernet Two RGMII interfaces
Debug ARM JTAG support
Booting Options
---------------
a) Flexspi boot
b) SD boot
Memory map for Flexspi flash
----------------------------
Image Flash Offset
bl2_flexspi_nor.pbl (RCW+PBI+bl2.pbl) 0x00000000
fip.bin (bl31 + bl33(u-boot) +
header for Secure-boot(secure-boot only)) 0x00100000
Boot firmware Environment 0x00500000
DDR PHY Firmware (fip_ddr_all.bin) 0x00800000
DPAA2 MC Firmware 0x00A00000
DPAA2 DPL 0x00D00000
DPAA2 DPC 0x00E00000
Kernel.itb 0x01000000
Memory map for sd card
----------------------------
Image SD card Offset
bl2_sd.pbl (RCW+PBI+bl2.pbl) 0x00008
fip.bin (bl31 + bl33(u-boot) +
header for Secure-boot(secure-boot only)) 0x00800
Boot firmware Environment 0x02800
DDR PHY Firmware (fip_ddr_all.bin) 0x04000
DPAA2 MC Firmware 0x05000
DPAA2 DPL 0x06800
DPAA2 DPC 0x07000
Kernel.itb 0x08000
LX2160AQDS board Overview
----------------------
Various Mezzanine cards and their connection for different SERDES protocols is
as below:
SERDES1 |CARDS
-----------------------------------------------------------------------
1 |Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108)
|Connect I/O cable to IO_SLOT1(J110)
|Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
3 |Mezzanine:X-M11-USXGMII (29828)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108)
|Connect I/O cable to IO_SLOT1(J110)
|Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
7 |Mezzanine:X-M11-USXGMII (29828)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108)
|Connect I/O cable to IO_SLOT1(J110)
|Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
8 |Mezzanine:X-M12-XFI (29829)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108)
|Connect I/O cable to IO_SLOT1(J110)
|Mezzanine:X-M12-XFI (29829)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
13 |Mezzanine:X-M8-100G (29734)
|Connect Hydra Cable (HDR-198816-XX-ECUE) to SD_SLOT1 (J108)
|Connect I/O cable to IO_SLOT1(J110)
|Mezzanine:X-M8-100G (29734)
|Connect Hydra Cable (HDR-198816-XX-ECUE) to SD_SLOT2(J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
15 |Mezzanine:X-M8-100G (29734)
|Connect Hydra Cable (HDR-198816-XX-ECUE) to SD_SLOT1 (J108)
|Connect I/O cable to IO_SLOT1(J110)
|Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
17 |Mezzanine:X-M13-25G (32133)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108)
|Connect I/O cable to IO_SLOT1(J110)
|Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT2 (J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
19 |Mezzanine:X-M11-USXGMII (29828), X-M13-25G (32133)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT1 (J108)
|Connect M11 I/O cable to IO_SLOT1(J110), M13 I/O cable to IO_SLOT6(J125)
|Mezzanine:X-M7-40G (29738)
|Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT2 (J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
20 |Mezzanine:X-M7-40G (29738)
|Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT1 (J108)
|Connect I/O cable to IO_SLOT1(J108)
|Mezzanine:X-M7-40G (29738)
|Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT2 (J111)
|Connect I/O cable to IO_SLOT2(J113)
------------------------------------------------------------------------
SERDES2 |CARDS
-----------------------------------------------------------------------
2 |Mezzanine:X-M6-PCIE-X8 (29737) *
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT3 (J114)
|Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT4 (J117)
|Connect I/O cable to IO_SLOT3(J116)
------------------------------------------------------------------------
3 |Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT3 (J114)
|Connect I/O cable to IO_SLOT3(J116)
|Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT4 (J117)
|Connect I/O cable to IO_SLOT4(J119)
------------------------------------------------------------------------
5 |Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT3 (J114)
|Connect I/O cable to IO_SLOT3(J116)
|Mezzanine:X-M5-SATA (29687)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT4 (J117)
|Connect I/O cable to IO_SLOT4(J119)
------------------------------------------------------------------------
11 |Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT3 (J114)
|Connect I/O cable to IO_SLOT7(J127)
|Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT4 (J117)
|Connect I/O cable to IO_SLOT8(J131)
------------------------------------------------------------------------
SERDES3 |CARDS
-----------------------------------------------------------------------
2 |Mezzanine:X-M6-PCIE-X8 (29737) *
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT5 (J120)
|Connect Straight Cable (HDR-198816-XX-ECUE) to SD_SLOT6 (J123)
|Connect I/O cable to IO_SLOT5(J122)
-------------------------------------------------------------------------
3 |Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT5 (J120)
|Connect I/O cable to IO_SLOT5(J122)
|Mezzanine:X-M4-PCIE-SGMII (29733)
|Connect Hydra Cable (HDR-198564-01-ECUE) to SD_SLOT6 (J123)
|Connect I/O cable to IO_SLOT6(J125)
-------------------------------------------------------------------------
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
*/
#include <common.h>
#include <fsl_ddr_sdram.h>
#include <fsl_ddr_dimm_params.h>
DECLARE_GLOBAL_DATA_PTR;
int fsl_initdram(void)
{
gd->ram_size = tfa_get_dram_size();
if (!gd->ram_size)
gd->ram_size = fsl_ddr_sdram_size();
return 0;
}
@@ -0,0 +1,832 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018-2019 NXP
*
*/
#include <common.h>
#include <env.h>
#include <hwconfig.h>
#include <command.h>
#include <netdev.h>
#include <malloc.h>
#include <fsl_mdio.h>
#include <miiphy.h>
#include <phy.h>
#include <fm_eth.h>
#include <asm/io.h>
#include <exports.h>
#include <asm/arch/fsl_serdes.h>
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/ldpaa_wriop.h>
#include "../common/qixis.h"
DECLARE_GLOBAL_DATA_PTR;
#define EMI_NONE 0
#define EMI1 1 /* Mdio Bus 1 */
#define EMI2 2 /* Mdio Bus 2 */
#if defined(CONFIG_FSL_MC_ENET)
enum io_slot {
IO_SLOT_NONE = 0,
IO_SLOT_1,
IO_SLOT_2,
IO_SLOT_3,
IO_SLOT_4,
IO_SLOT_5,
IO_SLOT_6,
IO_SLOT_7,
IO_SLOT_8,
EMI1_RGMII1,
EMI1_RGMII2,
IO_SLOT_MAX
};
struct lx2160a_qds_mdio {
enum io_slot ioslot : 4;
u8 realbusnum : 4;
struct mii_dev *realbus;
};
/* structure explaining the phy configuration on 8 lanes of a serdes*/
struct serdes_phy_config {
u8 serdes; /* serdes protocol */
struct phy_config {
u8 dpmacid;
/* -1 terminated array */
int phy_address[WRIOP_MAX_PHY_NUM + 1];
u8 mdio_bus;
enum io_slot ioslot;
} phy_config[SRDS_MAX_LANES];
};
/* Table defining the phy configuration on 8 lanes of a serdes.
* Various assumptions have been made while defining this table.
* e.g. for serdes1 protocol 19 it is being assumed that X-M11-USXGMII
* card is being used for dpmac 3-4. (X-M12-XFI could also have been used)
* And also that this card is connected to IO Slot 1 (could have been connected
* to any of the 8 IO slots (IO slot 1 - IO slot 8)).
* similarly, it is also being assumed that MDIO 1 is selected on X-M7-40G card
* used in serdes1 protocol 19 (could have selected MDIO 2)
* To override these settings "dpmac" environment variable can be used after
* defining "dpmac_override" in hwconfig environment variable.
* This table has limited serdes protocol entries. It can be expanded as per
* requirement.
*/
static const struct serdes_phy_config serdes1_phy_config[] = {
{3, {{WRIOP1_DPMAC3, {AQ_PHY_ADDR1, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC4, {AQ_PHY_ADDR2, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC5, {AQ_PHY_ADDR3, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC6, {AQ_PHY_ADDR4, -1},
EMI1, IO_SLOT_1} } },
{7, {{WRIOP1_DPMAC3, {AQ_PHY_ADDR1, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC4, {AQ_PHY_ADDR2, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC5, {AQ_PHY_ADDR3, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC6, {AQ_PHY_ADDR4, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC7, {SGMII_CARD_PORT1_PHY_ADDR, -1},
EMI1, IO_SLOT_2},
{WRIOP1_DPMAC8, {SGMII_CARD_PORT2_PHY_ADDR, -1},
EMI1, IO_SLOT_2},
{WRIOP1_DPMAC9, {SGMII_CARD_PORT3_PHY_ADDR, -1},
EMI1, IO_SLOT_2},
{WRIOP1_DPMAC10, {SGMII_CARD_PORT4_PHY_ADDR, -1},
EMI1, IO_SLOT_2} } },
{8, {} },
{13, {{WRIOP1_DPMAC1, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC2, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_2} } },
{14, {{WRIOP1_DPMAC1, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_1} } },
{15, {{WRIOP1_DPMAC1, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC2, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_1} } },
{17, {{WRIOP1_DPMAC3, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC4, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC5, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC6, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_1} } },
{19, {{WRIOP1_DPMAC2, {CORTINA_PHY_ADDR1, -1},
EMI1, IO_SLOT_2},
{WRIOP1_DPMAC3, {AQ_PHY_ADDR1, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC4, {AQ_PHY_ADDR2, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC5, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_6},
{WRIOP1_DPMAC6, {INPHI_PHY_ADDR1, INPHI_PHY_ADDR2, -1},
EMI1, IO_SLOT_6} } },
{20, {{WRIOP1_DPMAC1, {CORTINA_PHY_ADDR1, -1},
EMI1, IO_SLOT_1},
{WRIOP1_DPMAC2, {CORTINA_PHY_ADDR1, -1},
EMI1, IO_SLOT_2} } }
};
static const struct serdes_phy_config serdes2_phy_config[] = {
{2, {} },
{3, {} },
{5, {} },
{11, {{WRIOP1_DPMAC12, {SGMII_CARD_PORT2_PHY_ADDR, -1},
EMI1, IO_SLOT_7},
{WRIOP1_DPMAC17, {SGMII_CARD_PORT3_PHY_ADDR, -1},
EMI1, IO_SLOT_7},
{WRIOP1_DPMAC18, {SGMII_CARD_PORT4_PHY_ADDR, -1},
EMI1, IO_SLOT_7},
{WRIOP1_DPMAC16, {SGMII_CARD_PORT2_PHY_ADDR, -1},
EMI1, IO_SLOT_8},
{WRIOP1_DPMAC13, {SGMII_CARD_PORT3_PHY_ADDR, -1},
EMI1, IO_SLOT_8},
{WRIOP1_DPMAC14, {SGMII_CARD_PORT4_PHY_ADDR, -1},
EMI1, IO_SLOT_8} } },
};
static const struct serdes_phy_config serdes3_phy_config[] = {
{2, {} },
{3, {} }
};
static inline
const struct phy_config *get_phy_config(u8 serdes,
const struct serdes_phy_config *table,
u8 table_size)
{
int i;
for (i = 0; i < table_size; i++) {
if (table[i].serdes == serdes)
return table[i].phy_config;
}
return NULL;
}
/* BRDCFG4 controls EMI routing for the board.
* Bits Function
* 7-6 EMI Interface #1 Primary Routing (CFG_MUX1_EMI1) (1.8V):
* EMI1 00= On-board PHY #1
* 01= On-board PHY #2
* 10= (reserved)
* 11= Slots 1..8 multiplexer and translator.
* 5-3 EMI Interface #1 Secondary Routing (CFG_MUX2_EMI1) (2.5V):
* EMI1X 000= Slot #1
* 001= Slot #2
* 010= Slot #3
* 011= Slot #4
* 100= Slot #5
* 101= Slot #6
* 110= Slot #7
* 111= Slot #8
* 2-0 EMI Interface #2 Routing (CFG_MUX_EMI2):
* EMI2 000= Slot #1 (secondary EMI)
* 001= Slot #2 (secondary EMI)
* 010= Slot #3 (secondary EMI)
* 011= Slot #4 (secondary EMI)
* 100= Slot #5 (secondary EMI)
* 101= Slot #6 (secondary EMI)
* 110= Slot #7 (secondary EMI)
* 111= Slot #8 (secondary EMI)
*/
static int lx2160a_qds_get_mdio_mux_val(u8 realbusnum, enum io_slot ioslot)
{
switch (realbusnum) {
case EMI1:
switch (ioslot) {
case EMI1_RGMII1:
return 0;
case EMI1_RGMII2:
return 0x40;
default:
return (((ioslot - 1) << BRDCFG4_EMI1SEL_SHIFT) | 0xC0);
}
break;
case EMI2:
return ((ioslot - 1) << BRDCFG4_EMI2SEL_SHIFT);
default:
return -1;
}
}
static void lx2160a_qds_mux_mdio(struct lx2160a_qds_mdio *priv)
{
u8 brdcfg4, mux_val, reg;
brdcfg4 = QIXIS_READ(brdcfg[4]);
reg = brdcfg4;
mux_val = lx2160a_qds_get_mdio_mux_val(priv->realbusnum, priv->ioslot);
switch (priv->realbusnum) {
case EMI1:
brdcfg4 &= ~BRDCFG4_EMI1SEL_MASK;
brdcfg4 |= mux_val;
break;
case EMI2:
brdcfg4 &= ~BRDCFG4_EMI2SEL_MASK;
brdcfg4 |= mux_val;
break;
}
if (brdcfg4 ^ reg)
QIXIS_WRITE(brdcfg[4], brdcfg4);
}
static int lx2160a_qds_mdio_read(struct mii_dev *bus, int addr,
int devad, int regnum)
{
struct lx2160a_qds_mdio *priv = bus->priv;
lx2160a_qds_mux_mdio(priv);
return priv->realbus->read(priv->realbus, addr, devad, regnum);
}
static int lx2160a_qds_mdio_write(struct mii_dev *bus, int addr, int devad,
int regnum, u16 value)
{
struct lx2160a_qds_mdio *priv = bus->priv;
lx2160a_qds_mux_mdio(priv);
return priv->realbus->write(priv->realbus, addr, devad, regnum, value);
}
static int lx2160a_qds_mdio_reset(struct mii_dev *bus)
{
struct lx2160a_qds_mdio *priv = bus->priv;
return priv->realbus->reset(priv->realbus);
}
static struct mii_dev *lx2160a_qds_mdio_init(u8 realbusnum, enum io_slot ioslot)
{
struct lx2160a_qds_mdio *pmdio;
struct mii_dev *bus;
/*should be within MDIO_NAME_LEN*/
char dummy_mdio_name[] = "LX2160A_QDS_MDIO1_IOSLOT1";
if (realbusnum == EMI2) {
if (ioslot < IO_SLOT_1 || ioslot > IO_SLOT_8) {
printf("invalid ioslot %d\n", ioslot);
return NULL;
}
} else if (realbusnum == EMI1) {
if (ioslot < IO_SLOT_1 || ioslot > EMI1_RGMII2) {
printf("invalid ioslot %d\n", ioslot);
return NULL;
}
} else {
printf("not supported real mdio bus %d\n", realbusnum);
return NULL;
}
if (ioslot == EMI1_RGMII1)
strcpy(dummy_mdio_name, "LX2160A_QDS_MDIO1_RGMII1");
else if (ioslot == EMI1_RGMII2)
strcpy(dummy_mdio_name, "LX2160A_QDS_MDIO1_RGMII2");
else
sprintf(dummy_mdio_name, "LX2160A_QDS_MDIO%d_IOSLOT%d",
realbusnum, ioslot);
bus = miiphy_get_dev_by_name(dummy_mdio_name);
if (bus)
return bus;
bus = mdio_alloc();
if (!bus) {
printf("Failed to allocate %s bus\n", dummy_mdio_name);
return NULL;
}
pmdio = malloc(sizeof(*pmdio));
if (!pmdio) {
printf("Failed to allocate %s private data\n", dummy_mdio_name);
free(bus);
return NULL;
}
switch (realbusnum) {
case EMI1:
pmdio->realbus =
miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME);
break;
case EMI2:
pmdio->realbus =
miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
break;
}
if (!pmdio->realbus) {
printf("No real mdio bus num %d found\n", realbusnum);
free(bus);
free(pmdio);
return NULL;
}
pmdio->realbusnum = realbusnum;
pmdio->ioslot = ioslot;
bus->read = lx2160a_qds_mdio_read;
bus->write = lx2160a_qds_mdio_write;
bus->reset = lx2160a_qds_mdio_reset;
strcpy(bus->name, dummy_mdio_name);
bus->priv = pmdio;
if (!mdio_register(bus))
return bus;
printf("No bus with name %s\n", dummy_mdio_name);
free(bus);
free(pmdio);
return NULL;
}
static inline void do_phy_config(const struct phy_config *phy_config)
{
struct mii_dev *bus;
int i, phy_num, phy_address;
for (i = 0; i < SRDS_MAX_LANES; i++) {
if (!phy_config[i].dpmacid)
continue;
for (phy_num = 0;
phy_num < ARRAY_SIZE(phy_config[i].phy_address);
phy_num++) {
phy_address = phy_config[i].phy_address[phy_num];
if (phy_address == -1)
break;
wriop_set_phy_address(phy_config[i].dpmacid,
phy_num, phy_address);
}
/*Register the muxing front-ends to the MDIO buses*/
bus = lx2160a_qds_mdio_init(phy_config[i].mdio_bus,
phy_config[i].ioslot);
if (!bus)
printf("could not get bus for mdio %d ioslot %d\n",
phy_config[i].mdio_bus,
phy_config[i].ioslot);
else
wriop_set_mdio(phy_config[i].dpmacid, bus);
}
}
static inline void do_dpmac_config(int dpmac, const char *arg_dpmacid,
char *env_dpmac)
{
const char *ret;
size_t len;
u8 realbusnum, ioslot;
struct mii_dev *bus;
int phy_num;
char *phystr = "phy00";
/*search phy in dpmac arg*/
for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
sprintf(phystr, "phy%d", phy_num + 1);
ret = hwconfig_subarg_f(arg_dpmacid, phystr, &len, env_dpmac);
if (!ret) {
/*look for phy instead of phy1*/
if (!phy_num)
ret = hwconfig_subarg_f(arg_dpmacid, "phy",
&len, env_dpmac);
if (!ret)
continue;
}
if (len != 4 || strncmp(ret, "0x", 2))
printf("invalid phy format in %s variable.\n"
"specify phy%d for %s in hex format e.g. 0x12\n",
env_dpmac, phy_num + 1, arg_dpmacid);
else
wriop_set_phy_address(dpmac, phy_num,
simple_strtoul(ret, NULL, 16));
}
/*search mdio in dpmac arg*/
ret = hwconfig_subarg_f(arg_dpmacid, "mdio", &len, env_dpmac);
if (ret)
realbusnum = *ret - '0';
else
realbusnum = EMI_NONE;
if (realbusnum) {
/*search io in dpmac arg*/
ret = hwconfig_subarg_f(arg_dpmacid, "io", &len, env_dpmac);
if (ret)
ioslot = *ret - '0';
else
ioslot = IO_SLOT_NONE;
/*Register the muxing front-ends to the MDIO buses*/
bus = lx2160a_qds_mdio_init(realbusnum, ioslot);
if (!bus)
printf("could not get bus for mdio %d ioslot %d\n",
realbusnum, ioslot);
else
wriop_set_mdio(dpmac, bus);
}
}
#endif
int board_eth_init(bd_t *bis)
{
#if defined(CONFIG_FSL_MC_ENET)
struct memac_mdio_info mdio_info;
struct memac_mdio_controller *regs;
int i;
const char *ret;
char *env_dpmac;
char dpmacid[] = "dpmac00", srds[] = "00_00_00";
size_t len;
struct mii_dev *bus;
const struct phy_config *phy_config;
struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
u32 srds_s1, srds_s2, srds_s3;
srds_s1 = in_le32(&gur->rcwsr[28]) &
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
srds_s2 = in_le32(&gur->rcwsr[28]) &
FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_MASK;
srds_s2 >>= FSL_CHASSIS3_RCWSR28_SRDS2_PRTCL_SHIFT;
srds_s3 = in_le32(&gur->rcwsr[28]) &
FSL_CHASSIS3_RCWSR28_SRDS3_PRTCL_MASK;
srds_s3 >>= FSL_CHASSIS3_RCWSR28_SRDS3_PRTCL_SHIFT;
sprintf(srds, "%d_%d_%d", srds_s1, srds_s2, srds_s3);
regs = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1;
mdio_info.regs = regs;
mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME;
/*Register the EMI 1*/
fm_memac_mdio_init(bis, &mdio_info);
regs = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2;
mdio_info.regs = regs;
mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME;
/*Register the EMI 2*/
fm_memac_mdio_init(bis, &mdio_info);
/* "dpmac" environment variable can be used after
* defining "dpmac_override" in hwconfig environment variable.
*/
if (hwconfig("dpmac_override")) {
env_dpmac = env_get("dpmac");
if (env_dpmac) {
ret = hwconfig_arg_f("srds", &len, env_dpmac);
if (ret) {
if (strncmp(ret, srds, strlen(srds))) {
printf("SERDES configuration changed.\n"
"previous: %.*s, current: %s.\n"
"update dpmac variable.\n",
(int)len, ret, srds);
}
} else {
printf("SERDES configuration not found.\n"
"Please add srds:%s in dpmac variable\n",
srds);
}
for (i = WRIOP1_DPMAC1; i < NUM_WRIOP_PORTS; i++) {
/* Look for dpmac1 to dpmac24(current max) arg
* in dpmac environment variable
*/
sprintf(dpmacid, "dpmac%d", i);
ret = hwconfig_arg_f(dpmacid, &len, env_dpmac);
if (ret)
do_dpmac_config(i, dpmacid, env_dpmac);
}
} else {
printf("Warning: environment dpmac not found.\n"
"DPAA network interfaces may not work\n");
}
} else {
/*Look for phy config for serdes1 in phy config table*/
phy_config = get_phy_config(srds_s1, serdes1_phy_config,
ARRAY_SIZE(serdes1_phy_config));
if (!phy_config) {
printf("%s WRIOP: Unsupported SerDes1 Protocol %d\n",
__func__, srds_s1);
} else {
do_phy_config(phy_config);
}
phy_config = get_phy_config(srds_s2, serdes2_phy_config,
ARRAY_SIZE(serdes2_phy_config));
if (!phy_config) {
printf("%s WRIOP: Unsupported SerDes2 Protocol %d\n",
__func__, srds_s2);
} else {
do_phy_config(phy_config);
}
phy_config = get_phy_config(srds_s3, serdes3_phy_config,
ARRAY_SIZE(serdes3_phy_config));
if (!phy_config) {
printf("%s WRIOP: Unsupported SerDes3 Protocol %d\n",
__func__, srds_s3);
} else {
do_phy_config(phy_config);
}
}
if (wriop_get_enet_if(WRIOP1_DPMAC17) == PHY_INTERFACE_MODE_RGMII_ID) {
wriop_set_phy_address(WRIOP1_DPMAC17, 0, RGMII_PHY_ADDR1);
bus = lx2160a_qds_mdio_init(EMI1, EMI1_RGMII1);
if (!bus)
printf("could not get bus for RGMII1\n");
else
wriop_set_mdio(WRIOP1_DPMAC17, bus);
}
if (wriop_get_enet_if(WRIOP1_DPMAC18) == PHY_INTERFACE_MODE_RGMII_ID) {
wriop_set_phy_address(WRIOP1_DPMAC18, 0, RGMII_PHY_ADDR2);
bus = lx2160a_qds_mdio_init(EMI1, EMI1_RGMII2);
if (!bus)
printf("could not get bus for RGMII2\n");
else
wriop_set_mdio(WRIOP1_DPMAC18, bus);
}
cpu_eth_init(bis);
#endif /* CONFIG_FMAN_ENET */
#ifdef CONFIG_PHY_AQUANTIA
/*
* Export functions to be used by AQ firmware
* upload application
*/
gd->jt->strcpy = strcpy;
gd->jt->mdelay = mdelay;
gd->jt->mdio_get_current_dev = mdio_get_current_dev;
gd->jt->phy_find_by_mask = phy_find_by_mask;
gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname;
gd->jt->miiphy_set_current_dev = miiphy_set_current_dev;
#endif
return pci_eth_init(bis);
}
#if defined(CONFIG_RESET_PHY_R)
void reset_phy(void)
{
#if defined(CONFIG_FSL_MC_ENET)
mc_env_boot();
#endif
}
#endif /* CONFIG_RESET_PHY_R */
#if defined(CONFIG_FSL_MC_ENET)
int fdt_fixup_dpmac_phy_handle(void *fdt, int dpmac_id, int node_phandle)
{
int offset;
int ret;
char dpmac_str[] = "dpmacs@00";
const char *phy_string;
offset = fdt_path_offset(fdt, "/soc/fsl-mc/dpmacs");
if (offset < 0)
offset = fdt_path_offset(fdt, "/fsl-mc/dpmacs");
if (offset < 0) {
printf("dpmacs node not found in device tree\n");
return offset;
}
sprintf(dpmac_str, "dpmac@%x", dpmac_id);
debug("dpmac_str = %s\n", dpmac_str);
offset = fdt_subnode_offset(fdt, offset, dpmac_str);
if (offset < 0) {
printf("%s node not found in device tree\n", dpmac_str);
return offset;
}
ret = fdt_appendprop_cell(fdt, offset, "phy-handle", node_phandle);
if (ret)
printf("%d@%s %d\n", __LINE__, __func__, ret);
phy_string = phy_string_for_interface(wriop_get_enet_if(dpmac_id));
ret = fdt_setprop_string(fdt, offset, "phy-connection-type",
phy_string);
if (ret)
printf("%d@%s %d\n", __LINE__, __func__, ret);
return ret;
}
int fdt_get_ioslot_offset(void *fdt, struct mii_dev *mii_dev, int fpga_offset)
{
char mdio_ioslot_str[] = "mdio@00";
struct lx2160a_qds_mdio *priv;
u64 reg;
u32 phandle;
int offset, mux_val;
/*Test if the MDIO bus is real mdio bus or muxing front end ?*/
if (strncmp(mii_dev->name, "LX2160A_QDS_MDIO",
strlen("LX2160A_QDS_MDIO")))
return -1;
/*Get the real MDIO bus num and ioslot info from bus's priv data*/
priv = mii_dev->priv;
debug("real_bus_num = %d, ioslot = %d\n",
priv->realbusnum, priv->ioslot);
if (priv->realbusnum == EMI1)
reg = CONFIG_SYS_FSL_WRIOP1_MDIO1;
else
reg = CONFIG_SYS_FSL_WRIOP1_MDIO2;
offset = fdt_node_offset_by_compat_reg(fdt, "fsl,fman-memac-mdio", reg);
if (offset < 0) {
printf("mdio@%llx node not found in device tree\n", reg);
return offset;
}
phandle = fdt_get_phandle(fdt, offset);
phandle = cpu_to_fdt32(phandle);
offset = fdt_node_offset_by_prop_value(fdt, -1, "mdio-parent-bus",
&phandle, 4);
if (offset < 0) {
printf("mdio-mux-%d node not found in device tree\n",
priv->realbusnum == EMI1 ? 1 : 2);
return offset;
}
mux_val = lx2160a_qds_get_mdio_mux_val(priv->realbusnum, priv->ioslot);
if (priv->realbusnum == EMI1)
mux_val >>= BRDCFG4_EMI1SEL_SHIFT;
else
mux_val >>= BRDCFG4_EMI2SEL_SHIFT;
sprintf(mdio_ioslot_str, "mdio@%x", (u8)mux_val);
offset = fdt_subnode_offset(fdt, offset, mdio_ioslot_str);
if (offset < 0) {
printf("%s node not found in device tree\n", mdio_ioslot_str);
return offset;
}
return offset;
}
int fdt_create_phy_node(void *fdt, int offset, u8 phyaddr, int *subnodeoffset,
struct phy_device *phy_dev, int phandle)
{
char phy_node_name[] = "ethernet-phy@00";
char phy_id_compatible_str[] = "ethernet-phy-id0000.0000,";
int ret;
sprintf(phy_node_name, "ethernet-phy@%x", phyaddr);
debug("phy_node_name = %s\n", phy_node_name);
*subnodeoffset = fdt_add_subnode(fdt, offset, phy_node_name);
if (*subnodeoffset <= 0) {
printf("Could not add subnode %s inside node %s err = %s\n",
phy_node_name, fdt_get_name(fdt, offset, NULL),
fdt_strerror(*subnodeoffset));
return *subnodeoffset;
}
sprintf(phy_id_compatible_str, "ethernet-phy-id%04x.%04x,",
phy_dev->phy_id >> 16, phy_dev->phy_id & 0xFFFF);
debug("phy_id_compatible_str %s\n", phy_id_compatible_str);
ret = fdt_setprop_string(fdt, *subnodeoffset, "compatible",
phy_id_compatible_str);
if (ret) {
printf("%d@%s %d\n", __LINE__, __func__, ret);
goto out;
}
if (phy_dev->is_c45) {
ret = fdt_appendprop_string(fdt, *subnodeoffset, "compatible",
"ethernet-phy-ieee802.3-c45");
if (ret) {
printf("%d@%s %d\n", __LINE__, __func__, ret);
goto out;
}
} else {
ret = fdt_appendprop_string(fdt, *subnodeoffset, "compatible",
"ethernet-phy-ieee802.3-c22");
if (ret) {
printf("%d@%s %d\n", __LINE__, __func__, ret);
goto out;
}
}
ret = fdt_setprop_cell(fdt, *subnodeoffset, "reg", phyaddr);
if (ret) {
printf("%d@%s %d\n", __LINE__, __func__, ret);
goto out;
}
ret = fdt_set_phandle(fdt, *subnodeoffset, phandle);
if (ret) {
printf("%d@%s %d\n", __LINE__, __func__, ret);
goto out;
}
out:
if (ret)
fdt_del_node(fdt, *subnodeoffset);
return ret;
}
int fdt_fixup_board_phy(void *fdt)
{
int fpga_offset, offset, subnodeoffset;
struct mii_dev *mii_dev;
struct list_head *mii_devs, *entry;
int ret, dpmac_id, phandle, i;
struct phy_device *phy_dev;
char ethname[ETH_NAME_LEN];
phy_interface_t phy_iface;
ret = 0;
/* we know FPGA is connected to i2c0, therefore search path directly,
* instead of compatible property, as it saves time
*/
fpga_offset = fdt_path_offset(fdt, "/soc/i2c@2000000/fpga");
if (fpga_offset < 0)
fpga_offset = fdt_path_offset(fdt, "/i2c@2000000/fpga");
if (fpga_offset < 0) {
printf("i2c@2000000/fpga node not found in device tree\n");
return fpga_offset;
}
phandle = fdt_alloc_phandle(fdt);
mii_devs = mdio_get_list_head();
list_for_each(entry, mii_devs) {
mii_dev = list_entry(entry, struct mii_dev, link);
debug("mii_dev name : %s\n", mii_dev->name);
offset = fdt_get_ioslot_offset(fdt, mii_dev, fpga_offset);
if (offset < 0)
continue;
// Look for phy devices attached to MDIO bus muxing front end
// and create their entries with compatible being the device id
for (i = 0; i < PHY_MAX_ADDR; i++) {
phy_dev = mii_dev->phymap[i];
if (!phy_dev)
continue;
// TODO: use sscanf instead of loop
dpmac_id = WRIOP1_DPMAC1;
while (dpmac_id < NUM_WRIOP_PORTS) {
phy_iface = wriop_get_enet_if(dpmac_id);
snprintf(ethname, ETH_NAME_LEN, "DPMAC%d@%s",
dpmac_id,
phy_string_for_interface(phy_iface));
if (strcmp(ethname, phy_dev->dev->name) == 0)
break;
dpmac_id++;
}
if (dpmac_id == NUM_WRIOP_PORTS)
continue;
ret = fdt_create_phy_node(fdt, offset, i,
&subnodeoffset,
phy_dev, phandle);
if (ret)
break;
ret = fdt_fixup_dpmac_phy_handle(fdt,
dpmac_id, phandle);
if (ret) {
fdt_del_node(fdt, subnodeoffset);
break;
}
/* calculate offset again as new node addition may have
* changed offset;
*/
offset = fdt_get_ioslot_offset(fdt, mii_dev,
fpga_offset);
phandle++;
}
if (ret)
break;
}
return ret;
}
#endif // CONFIG_FSL_MC_ENET
@@ -0,0 +1,210 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018 NXP
*
*/
#include <common.h>
#include <command.h>
#include <netdev.h>
#include <malloc.h>
#include <fsl_mdio.h>
#include <miiphy.h>
#include <phy.h>
#include <fm_eth.h>
#include <asm/io.h>
#include <exports.h>
#include <asm/arch/fsl_serdes.h>
#include <fsl-mc/fsl_mc.h>
#include <fsl-mc/ldpaa_wriop.h>
DECLARE_GLOBAL_DATA_PTR;
static bool get_inphi_phy_id(struct mii_dev *bus, int addr, int devad)
{
int phy_reg;
u32 phy_id;
phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
phy_id = (phy_reg & 0xffff) << 16;
phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
phy_id |= (phy_reg & 0xffff);
if (phy_id == PHY_UID_IN112525_S03)
return true;
else
return false;
}
int board_eth_init(bd_t *bis)
{
#if defined(CONFIG_FSL_MC_ENET)
struct memac_mdio_info mdio_info;
struct memac_mdio_controller *reg;
int i, interface;
struct mii_dev *dev;
struct ccsr_gur *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
u32 srds_s1;
srds_s1 = in_le32(&gur->rcwsr[28]) &
FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_MASK;
srds_s1 >>= FSL_CHASSIS3_RCWSR28_SRDS1_PRTCL_SHIFT;
reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO1;
mdio_info.regs = reg;
mdio_info.name = DEFAULT_WRIOP_MDIO1_NAME;
/* Register the EMI 1 */
fm_memac_mdio_init(bis, &mdio_info);
reg = (struct memac_mdio_controller *)CONFIG_SYS_FSL_WRIOP1_MDIO2;
mdio_info.regs = reg;
mdio_info.name = DEFAULT_WRIOP_MDIO2_NAME;
/* Register the EMI 2 */
fm_memac_mdio_init(bis, &mdio_info);
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
switch (srds_s1) {
case 19:
wriop_set_phy_address(WRIOP1_DPMAC2, 0,
CORTINA_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC3, 0,
AQR107_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC4, 0,
AQR107_PHY_ADDR2);
if (get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) {
wriop_set_phy_address(WRIOP1_DPMAC5, 0,
INPHI_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC6, 0,
INPHI_PHY_ADDR1);
}
wriop_set_phy_address(WRIOP1_DPMAC17, 0,
RGMII_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC18, 0,
RGMII_PHY_ADDR2);
break;
case 18:
wriop_set_phy_address(WRIOP1_DPMAC7, 0,
CORTINA_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC8, 0,
CORTINA_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC9, 0,
CORTINA_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC10, 0,
CORTINA_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC3, 0,
AQR107_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC4, 0,
AQR107_PHY_ADDR2);
if (get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) {
wriop_set_phy_address(WRIOP1_DPMAC5, 0,
INPHI_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC6, 0,
INPHI_PHY_ADDR1);
}
wriop_set_phy_address(WRIOP1_DPMAC17, 0,
RGMII_PHY_ADDR1);
wriop_set_phy_address(WRIOP1_DPMAC18, 0,
RGMII_PHY_ADDR2);
break;
default:
printf("SerDes1 protocol 0x%x is not supported on LX2160ARDB\n",
srds_s1);
goto next;
}
for (i = WRIOP1_DPMAC2; i <= WRIOP1_DPMAC10; i++) {
interface = wriop_get_enet_if(i);
switch (interface) {
case PHY_INTERFACE_MODE_XGMII:
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME);
wriop_set_mdio(i, dev);
break;
case PHY_INTERFACE_MODE_25G_AUI:
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
wriop_set_mdio(i, dev);
break;
case PHY_INTERFACE_MODE_XLAUI:
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME);
wriop_set_mdio(i, dev);
break;
default:
break;
}
}
for (i = WRIOP1_DPMAC17; i <= WRIOP1_DPMAC18; i++) {
interface = wriop_get_enet_if(i);
switch (interface) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO1_NAME);
wriop_set_mdio(i, dev);
break;
default:
break;
}
}
next:
cpu_eth_init(bis);
#endif /* CONFIG_FSL_MC_ENET */
#ifdef CONFIG_PHY_AQUANTIA
/*
* Export functions to be used by AQ firmware
* upload application
*/
gd->jt->strcpy = strcpy;
gd->jt->mdelay = mdelay;
gd->jt->mdio_get_current_dev = mdio_get_current_dev;
gd->jt->phy_find_by_mask = phy_find_by_mask;
gd->jt->mdio_phydev_for_ethname = mdio_phydev_for_ethname;
gd->jt->miiphy_set_current_dev = miiphy_set_current_dev;
#endif
return pci_eth_init(bis);
}
#if defined(CONFIG_RESET_PHY_R)
void reset_phy(void)
{
#if defined(CONFIG_FSL_MC_ENET)
mc_env_boot();
#endif
}
#endif /* CONFIG_RESET_PHY_R */
int fdt_fixup_board_phy(void *fdt)
{
int mdio_offset;
int ret;
struct mii_dev *dev;
ret = 0;
dev = miiphy_get_dev_by_name(DEFAULT_WRIOP_MDIO2_NAME);
if (!get_inphi_phy_id(dev, INPHI_PHY_ADDR1, MDIO_MMD_VEND1)) {
mdio_offset = fdt_path_offset(fdt, "/soc/mdio@0x8B97000");
if (mdio_offset < 0)
mdio_offset = fdt_path_offset(fdt, "/mdio@0x8B97000");
if (mdio_offset < 0) {
printf("mdio@0x8B9700 node not found in dts\n");
return mdio_offset;
}
ret = fdt_setprop_string(fdt, mdio_offset, "status",
"disabled");
if (ret) {
printf("Could not set disable mdio@0x8B97000 %s\n",
fdt_strerror(ret));
return ret;
}
}
return ret;
}
@@ -0,0 +1,706 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2018-2019 NXP
*/
#include <common.h>
#include <dm.h>
#include <dm/platform_data/serial_pl01x.h>
#include <i2c.h>
#include <malloc.h>
#include <errno.h>
#include <netdev.h>
#include <fsl_ddr.h>
#include <fsl_sec.h>
#include <asm/io.h>
#include <fdt_support.h>
#include <linux/libfdt.h>
#include <fsl-mc/fsl_mc.h>
#include <env_internal.h>
#include <efi_loader.h>
#include <asm/arch/mmu.h>
#include <hwconfig.h>
#include <asm/arch/clock.h>
#include <asm/arch/config.h>
#include <asm/arch/fsl_serdes.h>
#include <asm/arch/soc.h>
#include "../common/qixis.h"
#include "../common/vid.h"
#include <fsl_immap.h>
#include <asm/arch-fsl-layerscape/fsl_icid.h>
#ifdef CONFIG_EMC2305
#include "../common/emc2305.h"
#endif
#ifdef CONFIG_TARGET_LX2160AQDS
#define CFG_MUX_I2C_SDHC(reg, value) ((reg & 0x3f) | value)
#define SET_CFG_MUX1_SDHC1_SDHC(reg) (reg & 0x3f)
#define SET_CFG_MUX2_SDHC1_SPI(reg, value) ((reg & 0xcf) | value)
#define SET_CFG_MUX3_SDHC1_SPI(reg, value) ((reg & 0xf8) | value)
#define SET_CFG_MUX_SDHC2_DSPI(reg, value) ((reg & 0xf8) | value)
#define SET_CFG_MUX1_SDHC1_DSPI(reg, value) ((reg & 0x3f) | value)
#define SDHC1_BASE_PMUX_DSPI 2
#define SDHC2_BASE_PMUX_DSPI 2
#define IIC5_PMUX_SPI3 3
#endif /* CONFIG_TARGET_LX2160AQDS */
DECLARE_GLOBAL_DATA_PTR;
static struct pl01x_serial_platdata serial0 = {
#if CONFIG_CONS_INDEX == 0
.base = CONFIG_SYS_SERIAL0,
#elif CONFIG_CONS_INDEX == 1
.base = CONFIG_SYS_SERIAL1,
#else
#error "Unsupported console index value."
#endif
.type = TYPE_PL011,
};
U_BOOT_DEVICE(nxp_serial0) = {
.name = "serial_pl01x",
.platdata = &serial0,
};
static struct pl01x_serial_platdata serial1 = {
.base = CONFIG_SYS_SERIAL1,
.type = TYPE_PL011,
};
U_BOOT_DEVICE(nxp_serial1) = {
.name = "serial_pl01x",
.platdata = &serial1,
};
int select_i2c_ch_pca9547(u8 ch)
{
int ret;
#ifndef CONFIG_DM_I2C
ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1);
#else
struct udevice *dev;
ret = i2c_get_chip_for_busnum(0, I2C_MUX_PCA_ADDR_PRI, 1, &dev);
if (!ret)
ret = dm_i2c_write(dev, 0, &ch, 1);
#endif
if (ret) {
puts("PCA: failed to select proper channel\n");
return ret;
}
return 0;
}
static void uart_get_clock(void)
{
serial0.clock = get_serial_clock();
serial1.clock = get_serial_clock();
}
int board_early_init_f(void)
{
#ifdef CONFIG_SYS_I2C_EARLY_INIT
i2c_early_init_f();
#endif
/* get required clock for UART IP */
uart_get_clock();
#ifdef CONFIG_EMC2305
select_i2c_ch_pca9547(I2C_MUX_CH_EMC2305);
emc2305_init();
set_fan_speed(I2C_EMC2305_PWM);
select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
#endif
fsl_lsch3_early_init_f();
return 0;
}
#ifdef CONFIG_OF_BOARD_FIXUP
int board_fix_fdt(void *fdt)
{
char *reg_names, *reg_name;
int names_len, old_name_len, new_name_len, remaining_names_len;
struct str_map {
char *old_str;
char *new_str;
} reg_names_map[] = {
{ "ccsr", "dbi" },
{ "pf_ctrl", "ctrl" }
};
int off = -1, i;
if (IS_SVR_REV(get_svr(), 1, 0))
return 0;
off = fdt_node_offset_by_compatible(fdt, -1, "fsl,lx2160a-pcie");
while (off != -FDT_ERR_NOTFOUND) {
fdt_setprop(fdt, off, "compatible", "fsl,ls-pcie",
strlen("fsl,ls-pcie") + 1);
reg_names = (char *)fdt_getprop(fdt, off, "reg-names",
&names_len);
if (!reg_names)
continue;
reg_name = reg_names;
remaining_names_len = names_len - (reg_name - reg_names);
for (i = 0; (i < ARRAY_SIZE(reg_names_map)) && names_len; i++) {
old_name_len = strlen(reg_names_map[i].old_str);
new_name_len = strlen(reg_names_map[i].new_str);
if (memcmp(reg_name, reg_names_map[i].old_str,
old_name_len) == 0) {
/* first only leave required bytes for new_str
* and copy rest of the string after it
*/
memcpy(reg_name + new_name_len,
reg_name + old_name_len,
remaining_names_len - old_name_len);
/* Now copy new_str */
memcpy(reg_name, reg_names_map[i].new_str,
new_name_len);
names_len -= old_name_len;
names_len += new_name_len;
}
reg_name = memchr(reg_name, '\0', remaining_names_len);
if (!reg_name)
break;
reg_name += 1;
remaining_names_len = names_len -
(reg_name - reg_names);
}
fdt_setprop(fdt, off, "reg-names", reg_names, names_len);
off = fdt_node_offset_by_compatible(fdt, off,
"fsl,lx2160a-pcie");
}
return 0;
}
#endif
#if defined(CONFIG_TARGET_LX2160AQDS)
void esdhc_dspi_status_fixup(void *blob)
{
const char esdhc0_path[] = "/soc/esdhc@2140000";
const char esdhc1_path[] = "/soc/esdhc@2150000";
const char dspi0_path[] = "/soc/dspi@2100000";
const char dspi1_path[] = "/soc/dspi@2110000";
const char dspi2_path[] = "/soc/dspi@2120000";
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
u32 sdhc1_base_pmux;
u32 sdhc2_base_pmux;
u32 iic5_pmux;
/* Check RCW field sdhc1_base_pmux to enable/disable
* esdhc0/dspi0 DT node
*/
sdhc1_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1])
& FSL_CHASSIS3_SDHC1_BASE_PMUX_MASK;
sdhc1_base_pmux >>= FSL_CHASSIS3_SDHC1_BASE_PMUX_SHIFT;
if (sdhc1_base_pmux == SDHC1_BASE_PMUX_DSPI) {
do_fixup_by_path(blob, dspi0_path, "status", "okay",
sizeof("okay"), 1);
do_fixup_by_path(blob, esdhc0_path, "status", "disabled",
sizeof("disabled"), 1);
} else {
do_fixup_by_path(blob, esdhc0_path, "status", "okay",
sizeof("okay"), 1);
do_fixup_by_path(blob, dspi0_path, "status", "disabled",
sizeof("disabled"), 1);
}
/* Check RCW field sdhc2_base_pmux to enable/disable
* esdhc1/dspi1 DT node
*/
sdhc2_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR13_REGSR - 1])
& FSL_CHASSIS3_SDHC2_BASE_PMUX_MASK;
sdhc2_base_pmux >>= FSL_CHASSIS3_SDHC2_BASE_PMUX_SHIFT;
if (sdhc2_base_pmux == SDHC2_BASE_PMUX_DSPI) {
do_fixup_by_path(blob, dspi1_path, "status", "okay",
sizeof("okay"), 1);
do_fixup_by_path(blob, esdhc1_path, "status", "disabled",
sizeof("disabled"), 1);
} else {
do_fixup_by_path(blob, esdhc1_path, "status", "okay",
sizeof("okay"), 1);
do_fixup_by_path(blob, dspi1_path, "status", "disabled",
sizeof("disabled"), 1);
}
/* Check RCW field IIC5 to enable dspi2 DT node */
iic5_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1])
& FSL_CHASSIS3_IIC5_PMUX_MASK;
iic5_pmux >>= FSL_CHASSIS3_IIC5_PMUX_SHIFT;
if (iic5_pmux == IIC5_PMUX_SPI3) {
do_fixup_by_path(blob, dspi2_path, "status", "okay",
sizeof("okay"), 1);
}
}
#endif
int esdhc_status_fixup(void *blob, const char *compat)
{
#if defined(CONFIG_TARGET_LX2160AQDS)
/* Enable esdhc and dspi DT nodes based on RCW fields */
esdhc_dspi_status_fixup(blob);
#else
/* Enable both esdhc DT nodes for LX2160ARDB */
do_fixup_by_compat(blob, compat, "status", "okay",
sizeof("okay"), 1);
#endif
return 0;
}
#if defined(CONFIG_VID)
int i2c_multiplexer_select_vid_channel(u8 channel)
{
return select_i2c_ch_pca9547(channel);
}
int init_func_vid(void)
{
if (adjust_vdd(0) < 0)
printf("core voltage not adjusted\n");
return 0;
}
#endif
int checkboard(void)
{
enum boot_src src = get_boot_src();
char buf[64];
u8 sw;
#ifdef CONFIG_TARGET_LX2160AQDS
int clock;
static const char *const freq[] = {"100", "125", "156.25",
"161.13", "322.26", "", "", "",
"", "", "", "", "", "", "",
"100 separate SSCG"};
#endif
cpu_name(buf);
#ifdef CONFIG_TARGET_LX2160AQDS
printf("Board: %s-QDS, ", buf);
#else
printf("Board: %s-RDB, ", buf);
#endif
sw = QIXIS_READ(arch);
printf("Board version: %c, boot from ", (sw & 0xf) - 1 + 'A');
if (src == BOOT_SOURCE_SD_MMC) {
puts("SD\n");
} else {
sw = QIXIS_READ(brdcfg[0]);
sw = (sw >> QIXIS_XMAP_SHIFT) & QIXIS_XMAP_MASK;
switch (sw) {
case 0:
case 4:
puts("FlexSPI DEV#0\n");
break;
case 1:
puts("FlexSPI DEV#1\n");
break;
case 2:
case 3:
puts("FlexSPI EMU\n");
break;
default:
printf("invalid setting, xmap: %d\n", sw);
break;
}
}
#ifdef CONFIG_TARGET_LX2160AQDS
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));
puts("SERDES1 Reference : ");
sw = QIXIS_READ(brdcfg[2]);
clock = sw >> 4;
printf("Clock1 = %sMHz ", freq[clock]);
clock = sw & 0x0f;
printf("Clock2 = %sMHz", freq[clock]);
sw = QIXIS_READ(brdcfg[3]);
puts("\nSERDES2 Reference : ");
clock = sw >> 4;
printf("Clock1 = %sMHz ", freq[clock]);
clock = sw & 0x0f;
printf("Clock2 = %sMHz", freq[clock]);
sw = QIXIS_READ(brdcfg[12]);
puts("\nSERDES3 Reference : ");
clock = sw >> 4;
printf("Clock1 = %sMHz Clock2 = %sMHz\n", freq[clock], freq[clock]);
#else
printf("FPGA: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata));
puts("SERDES1 Reference: Clock1 = 161.13MHz Clock2 = 161.13MHz\n");
puts("SERDES2 Reference: Clock1 = 100MHz Clock2 = 100MHz\n");
puts("SERDES3 Reference: Clock1 = 100MHz Clock2 = 100MHz\n");
#endif
return 0;
}
#ifdef CONFIG_TARGET_LX2160AQDS
/*
* implementation of CONFIG_ESDHC_DETECT_QUIRK Macro.
*/
u8 qixis_esdhc_detect_quirk(void)
{
/* for LX2160AQDS res1[1] @ offset 0x1A is SDHC1 Control/Status (SDHC1)
* SDHC1 Card ID:
* Specifies the type of card installed in the SDHC1 adapter slot.
* 000= (reserved)
* 001= eMMC V4.5 adapter is installed.
* 010= SD/MMC 3.3V adapter is installed.
* 011= eMMC V4.4 adapter is installed.
* 100= eMMC V5.0 adapter is installed.
* 101= MMC card/Legacy (3.3V) adapter is installed.
* 110= SDCard V2/V3 adapter installed.
* 111= no adapter is installed.
*/
return ((QIXIS_READ(res1[1]) & QIXIS_SDID_MASK) !=
QIXIS_ESDHC_NO_ADAPTER);
}
int config_board_mux(void)
{
u8 reg11, reg5, reg13;
struct ccsr_gur __iomem *gur = (void *)(CONFIG_SYS_FSL_GUTS_ADDR);
u32 sdhc1_base_pmux;
u32 sdhc2_base_pmux;
u32 iic5_pmux;
/* Routes {I2C2_SCL, I2C2_SDA} to SDHC1 as {SDHC1_CD_B, SDHC1_WP}.
* Routes {I2C3_SCL, I2C3_SDA} to CAN transceiver as {CAN1_TX,CAN1_RX}.
* Routes {I2C4_SCL, I2C4_SDA} to CAN transceiver as {CAN2_TX,CAN2_RX}.
* Qixis and remote systems are isolated from the I2C1 bus.
* Processor connections are still available.
* SPI2 CS2_B controls EN25S64 SPI memory device.
* SPI3 CS2_B controls EN25S64 SPI memory device.
* EC2 connects to PHY #2 using RGMII protocol.
* CLK_OUT connects to FPGA for clock measurement.
*/
reg5 = QIXIS_READ(brdcfg[5]);
reg5 = CFG_MUX_I2C_SDHC(reg5, 0x40);
QIXIS_WRITE(brdcfg[5], reg5);
/* Check RCW field sdhc1_base_pmux
* esdhc0 : sdhc1_base_pmux = 0
* dspi0 : sdhc1_base_pmux = 2
*/
sdhc1_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1])
& FSL_CHASSIS3_SDHC1_BASE_PMUX_MASK;
sdhc1_base_pmux >>= FSL_CHASSIS3_SDHC1_BASE_PMUX_SHIFT;
if (sdhc1_base_pmux == SDHC1_BASE_PMUX_DSPI) {
reg11 = QIXIS_READ(brdcfg[11]);
reg11 = SET_CFG_MUX1_SDHC1_DSPI(reg11, 0x40);
QIXIS_WRITE(brdcfg[11], reg11);
} else {
/* - Routes {SDHC1_CMD, SDHC1_CLK } to SDHC1 adapter slot.
* {SDHC1_DAT3, SDHC1_DAT2} to SDHC1 adapter slot.
* {SDHC1_DAT1, SDHC1_DAT0} to SDHC1 adapter slot.
*/
reg11 = QIXIS_READ(brdcfg[11]);
reg11 = SET_CFG_MUX1_SDHC1_SDHC(reg11);
QIXIS_WRITE(brdcfg[11], reg11);
}
/* Check RCW field sdhc2_base_pmux
* esdhc1 : sdhc2_base_pmux = 0 (default)
* dspi1 : sdhc2_base_pmux = 2
*/
sdhc2_base_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR13_REGSR - 1])
& FSL_CHASSIS3_SDHC2_BASE_PMUX_MASK;
sdhc2_base_pmux >>= FSL_CHASSIS3_SDHC2_BASE_PMUX_SHIFT;
if (sdhc2_base_pmux == SDHC2_BASE_PMUX_DSPI) {
reg13 = QIXIS_READ(brdcfg[13]);
reg13 = SET_CFG_MUX_SDHC2_DSPI(reg13, 0x01);
QIXIS_WRITE(brdcfg[13], reg13);
} else {
reg13 = QIXIS_READ(brdcfg[13]);
reg13 = SET_CFG_MUX_SDHC2_DSPI(reg13, 0x00);
QIXIS_WRITE(brdcfg[13], reg13);
}
/* Check RCW field IIC5 to enable dspi2 DT nodei
* dspi2: IIC5 = 3
*/
iic5_pmux = gur_in32(&gur->rcwsr[FSL_CHASSIS3_RCWSR12_REGSR - 1])
& FSL_CHASSIS3_IIC5_PMUX_MASK;
iic5_pmux >>= FSL_CHASSIS3_IIC5_PMUX_SHIFT;
if (iic5_pmux == IIC5_PMUX_SPI3) {
/* - Routes {SDHC1_DAT4} to SPI3 devices as {SPI3_M_CS0_B}. */
reg11 = QIXIS_READ(brdcfg[11]);
reg11 = SET_CFG_MUX2_SDHC1_SPI(reg11, 0x10);
QIXIS_WRITE(brdcfg[11], reg11);
/* - Routes {SDHC1_DAT5, SDHC1_DAT6} nowhere.
* {SDHC1_DAT7, SDHC1_DS } to {nothing, SPI3_M0_CLK }.
* {I2C5_SCL, I2C5_SDA } to {SPI3_M0_MOSI, SPI3_M0_MISO}.
*/
reg11 = QIXIS_READ(brdcfg[11]);
reg11 = SET_CFG_MUX3_SDHC1_SPI(reg11, 0x01);
QIXIS_WRITE(brdcfg[11], reg11);
} else {
/* Routes {SDHC1_DAT4} to SDHC1 adapter slot */
reg11 = QIXIS_READ(brdcfg[11]);
reg11 = SET_CFG_MUX2_SDHC1_SPI(reg11, 0x00);
QIXIS_WRITE(brdcfg[11], reg11);
/* - Routes {SDHC1_DAT5, SDHC1_DAT6} to SDHC1 adapter slot.
* {SDHC1_DAT7, SDHC1_DS } to SDHC1 adapter slot.
* {I2C5_SCL, I2C5_SDA } to SDHC1 adapter slot.
*/
reg11 = QIXIS_READ(brdcfg[11]);
reg11 = SET_CFG_MUX3_SDHC1_SPI(reg11, 0x00);
QIXIS_WRITE(brdcfg[11], reg11);
}
return 0;
}
#elif defined(CONFIG_TARGET_LX2160ARDB)
int config_board_mux(void)
{
u8 brdcfg;
brdcfg = QIXIS_READ(brdcfg[4]);
/* The BRDCFG4 register controls general board configuration.
*|-------------------------------------------|
*|Field | Function |
*|-------------------------------------------|
*|5 | CAN I/O Enable (net CFG_CAN_EN_B):|
*|CAN_EN | 0= CAN transceivers are disabled. |
*| | 1= CAN transceivers are enabled. |
*|-------------------------------------------|
*/
brdcfg |= BIT_MASK(5);
QIXIS_WRITE(brdcfg[4], brdcfg);
return 0;
}
#else
int config_board_mux(void)
{
return 0;
}
#endif
unsigned long get_board_sys_clk(void)
{
#ifdef CONFIG_TARGET_LX2160AQDS
u8 sysclk_conf = QIXIS_READ(brdcfg[1]);
switch (sysclk_conf & 0x03) {
case QIXIS_SYSCLK_100:
return 100000000;
case QIXIS_SYSCLK_125:
return 125000000;
case QIXIS_SYSCLK_133:
return 133333333;
}
return 100000000;
#else
return 100000000;
#endif
}
unsigned long get_board_ddr_clk(void)
{
#ifdef CONFIG_TARGET_LX2160AQDS
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 100000000;
#else
return 100000000;
#endif
}
int board_init(void)
{
#if defined(CONFIG_FSL_MC_ENET) && defined(CONFIG_TARGET_LX2160ARDB)
u32 __iomem *irq_ccsr = (u32 __iomem *)ISC_BASE;
#endif
#ifdef CONFIG_ENV_IS_NOWHERE
gd->env_addr = (ulong)&default_environment[0];
#endif
select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT);
#if defined(CONFIG_FSL_MC_ENET) && defined(CONFIG_TARGET_LX2160ARDB)
/* invert AQR107 IRQ pins polarity */
out_le32(irq_ccsr + IRQCR_OFFSET / 4, AQR107_IRQ_MASK);
#endif
#ifdef CONFIG_FSL_CAAM
sec_init();
#endif
return 0;
}
void detail_board_ddr_info(void)
{
int i;
u64 ddr_size = 0;
puts("\nDDR ");
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++)
ddr_size += gd->bd->bi_dram[i].size;
print_size(ddr_size, "");
print_ddr_info(0);
}
#if defined(CONFIG_ARCH_MISC_INIT)
int arch_misc_init(void)
{
config_board_mux();
return 0;
}
#endif
#ifdef CONFIG_FSL_MC_ENET
extern int fdt_fixup_board_phy(void *fdt);
void fdt_fixup_board_enet(void *fdt)
{
int offset;
offset = fdt_path_offset(fdt, "/soc/fsl-mc");
if (offset < 0)
offset = fdt_path_offset(fdt, "/fsl-mc");
if (offset < 0) {
printf("%s: fsl-mc node not found in device tree (error %d)\n",
__func__, offset);
return;
}
if (get_mc_boot_status() == 0 &&
(is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0)) {
fdt_status_okay(fdt, offset);
fdt_fixup_board_phy(fdt);
} else {
fdt_status_fail(fdt, offset);
}
}
void board_quiesce_devices(void)
{
fsl_mc_ldpaa_exit(gd->bd);
}
#endif
#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
int i;
u16 mc_memory_bank = 0;
u64 *base;
u64 *size;
u64 mc_memory_base = 0;
u64 mc_memory_size = 0;
u16 total_memory_banks;
ft_cpu_setup(blob, bd);
fdt_fixup_mc_ddr(&mc_memory_base, &mc_memory_size);
if (mc_memory_base != 0)
mc_memory_bank++;
total_memory_banks = CONFIG_NR_DRAM_BANKS + mc_memory_bank;
base = calloc(total_memory_banks, sizeof(u64));
size = calloc(total_memory_banks, sizeof(u64));
/* fixup DT for the three GPP DDR banks */
for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
base[i] = gd->bd->bi_dram[i].start;
size[i] = gd->bd->bi_dram[i].size;
}
#ifdef CONFIG_RESV_RAM
/* reduce size if reserved memory is within this bank */
if (gd->arch.resv_ram >= base[0] &&
gd->arch.resv_ram < base[0] + size[0])
size[0] = gd->arch.resv_ram - base[0];
else if (gd->arch.resv_ram >= base[1] &&
gd->arch.resv_ram < base[1] + size[1])
size[1] = gd->arch.resv_ram - base[1];
else if (gd->arch.resv_ram >= base[2] &&
gd->arch.resv_ram < base[2] + size[2])
size[2] = gd->arch.resv_ram - base[2];
#endif
if (mc_memory_base != 0) {
for (i = 0; i <= total_memory_banks; i++) {
if (base[i] == 0 && size[i] == 0) {
base[i] = mc_memory_base;
size[i] = mc_memory_size;
break;
}
}
}
fdt_fixup_memory_banks(blob, base, size, total_memory_banks);
#ifdef CONFIG_USB
fsl_fdt_fixup_dr_usb(blob, bd);
#endif
#ifdef CONFIG_FSL_MC_ENET
fdt_fsl_mc_fixup_iommu_map_entry(blob);
fdt_fixup_board_enet(blob);
#endif
fdt_fixup_icid(blob);
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]));
}
}