- Armada XP etc: Move to DM_I2C (Stefan)
- Some mvebu comphy + mox + fdt_support changes (Marek & Pali)
- mvebu: a38x: improve USB3 serdes configuration (Stefan Eichenberger)
- mvebu: Some maintainer updates (Pali)
- mvebu: Misc minor cleanup (Pali)
This commit is contained in:
Tom Rini 2021-12-19 08:59:59 -05:00
commit e9d7888da8
39 changed files with 673 additions and 400 deletions

View File

@ -274,10 +274,24 @@ F: drivers/ata/ahci_mvebu.c
F: drivers/ddr/marvell/
F: drivers/gpio/mvebu_gpio.c
F: drivers/spi/kirkwood_spi.c
F: drivers/pci/pci_mvebu.c
F: drivers/pci/pcie_dw_mvebu.c
F: drivers/watchdog/orion_wdt.c
ARM MARVELL PCIE CONTROLLER DRIVERS
M: Pali Rohár <pali@kernel.org>
M: Stefan Roese <sr@denx.de>
S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-marvell.git
F: drivers/pci/pci-aardvark.c
F: drivers/pci/pci_mvebu.c
ARM MARVELL SERIAL DRIVERS
M: Pali Rohár <pali@kernel.org>
M: Stefan Roese <sr@denx.de>
S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-marvell.git
F: drivers/serial/serial_mvebu_a3700.c
ARM MARVELL PXA
M: Marek Vasut <marex@denx.de>
S: Maintained

View File

@ -184,13 +184,13 @@ void ft_cpu_setup(void *blob, struct bd_info *bd)
#if defined(CONFIG_QSPI_BOOT) || defined(CONFIG_SD_BOOT_QSPI)
off = fdt_node_offset_by_compat_reg(blob, FSL_IFC_COMPAT,
CONFIG_SYS_IFC_ADDR);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
#else
off = fdt_node_offset_by_compat_reg(blob, FSL_QSPI_COMPAT,
QSPI0_BASE_ADDR);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
off = fdt_node_offset_by_compat_reg(blob, FSL_DSPI_COMPAT,
DSPI1_BASE_ADDR);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
#endif
}

View File

@ -80,24 +80,6 @@
};
};
&comphy {
max-lanes = <3>;
phy0 {
phy-type = <COMPHY_TYPE_USB3_HOST0>;
phy-speed = <COMPHY_SPEED_5G>;
};
phy1 {
phy-type = <COMPHY_TYPE_PEX0>;
phy-speed = <COMPHY_SPEED_2_5G>;
};
phy2 {
phy-type = <COMPHY_TYPE_SATA0>;
phy-speed = <COMPHY_SPEED_5G>;
};
};
&eth0 {
status = "okay";
pinctrl-names = "default";
@ -119,6 +101,7 @@
/* CON3 */
&sata {
status = "okay";
phys = <&comphy2 0>;
};
&sdhci0 {
@ -200,6 +183,7 @@
/* CON31 */
&usb3 {
status = "okay";
phys = <&comphy0 0>;
};
&pcie0 {
@ -207,4 +191,5 @@
pinctrl-0 = <&pcie_pins>;
reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
status = "okay";
phys = <&comphy1 0>;
};

View File

@ -94,24 +94,6 @@
};
};
&comphy {
max-lanes = <3>;
phy0 {
phy-type = <COMPHY_TYPE_SGMII1>;
phy-speed = <COMPHY_SPEED_3_125G>;
};
phy1 {
phy-type = <COMPHY_TYPE_PEX0>;
phy-speed = <COMPHY_SPEED_5G>;
};
phy2 {
phy-type = <COMPHY_TYPE_USB3_HOST0>;
phy-speed = <COMPHY_SPEED_5G>;
};
};
&eth0 {
status = "okay";
pinctrl-names = "default";
@ -120,6 +102,11 @@
phy = <&eth_phy1>;
};
&eth1 {
phy-mode = "2500base-x";
phys = <&comphy0 1>;
};
&i2c0 {
pinctrl-names = "default";
pinctrl-0 = <&i2c1_pins>;
@ -222,6 +209,7 @@
&usb3 {
vbus-supply = <&reg_usb3_vbus>;
status = "okay";
phys = <&comphy2 0>;
};
&pcie0 {
@ -229,4 +217,5 @@
pinctrl-0 = <&pcie_pins>;
reset-gpios = <&gpiosb 3 GPIO_ACTIVE_LOW>;
status = "disabled";
phys = <&comphy1 0>;
};

View File

@ -106,36 +106,21 @@
};
};
&comphy {
phy0 {
phy-type = <COMPHY_TYPE_SGMII1>;
phy-speed = <COMPHY_SPEED_1_25G>;
};
phy1 {
phy-type = <COMPHY_TYPE_SGMII0>;
phy-speed = <COMPHY_SPEED_1_25G>;
};
phy2 {
phy-type = <COMPHY_TYPE_USB3_HOST1>;
phy-speed = <COMPHY_SPEED_5G>;
};
};
&eth0 {
pinctrl-0 = <&pcie_pins>;
status = "okay";
phy-mode = "2500base-x";
phy-mode = "sgmii";
managed = "in-band-status";
phy = <&ethphy0>;
phys = <&comphy1 0>;
};
&eth1 {
status = "okay";
phy-mode = "2500base-x";
phy-mode = "sgmii";
managed = "in-band-status";
phy = <&ethphy1>;
phys = <&comphy0 1>;
};
&i2c0 {

View File

@ -316,9 +316,23 @@
compatible = "marvell,mvebu-comphy", "marvell,comphy-armada-3700";
reg = <0x18300 0x28>,
<0x1f300 0x3d000>;
mux-bitcount = <4>;
mux-lane-order = <1 0 2>;
max-lanes = <3>;
#address-cells = <1>;
#size-cells = <0>;
comphy0: phy@0 {
reg = <0>;
#phy-cells = <1>;
};
comphy1: phy@1 {
reg = <1>;
#phy-cells = <1>;
};
comphy2: phy@2 {
reg = <2>;
#phy-cells = <1>;
};
};
};

View File

@ -71,6 +71,8 @@
spi0 = &spi0;
spi1 = &spi1;
ethernet0 = &eth0;
i2c0 = &i2c0;
i2c1 = &i2c1;
};
memory {
@ -156,6 +158,16 @@
};
};
&i2c0 {
status = "okay";
clock-frequency = <100000>;
};
&i2c1 {
status = "okay";
clock-frequency = <100000>;
};
&spi0 {
status = "okay";
u-boot,dm-pre-reloc;

View File

@ -459,18 +459,41 @@ struct op_params usb3_electrical_config_serdes_rev1_params[] = {
};
struct op_params usb3_electrical_config_serdes_rev2_params[] = {
/* Spread Spectrum Clock Enable */
{LANE_CFG4_REG, 0x800, 0x80, {0x80}, 0, 0},
/* Spread Spectrum Clock Enable, CFG_DFE_OVERRIDE and PIN_DFE_PAT_DIS */
{LANE_CFG4_REG, 0x800, 0xc2, {0xc0}, 0, 0},
/* CFG_SQ_DET_SEL and CFG_RX_INIT_SEL */
{LANE_CFG5_REG, 0x800, 0x3, {0x3}, 0, 0},
/* G2_TX_SSC_AMP[6:0]=4.5k_p_pM and TX emphasis mode=m_v */
{G2_SETTINGS_2_REG, 0x800, 0xfe40, {0x4440}, 0, 0},
/* G2_RX SELMUFF, SELMUFI, SELMUPF and SELMUPI */
/* FFE Setting Force, FFE_RES[2:0]=0x6 and FFE_CAP[3:0]=0xf */
{G2_SETTINGS_3_REG, 0x800, 0xff, {0xef}, 0, 0},
/* G2_DFE_RES[1:0]=0x0(3mV)*/
{G2_SETTINGS_4_REG, 0x800, 0x300, {0x300}, 0, 0},
/* HPF_Bw[1:0]=0x3 */
{PLLINTP_REG1, 0x800, 0x300, {0x300}, 0, 0},
/* TXIMPCAL_TH[3:0]=0x3, RXIMPCAL_TH[3:0]=0x0 */
{VTHIMPCAL_CTRL_REG, 0x800, 0xff00, {0x3000}, 0, 0},
/* CFG_SQ_DET_SEL and CFG_RX_INIT_SEL*/
{LANE_CFG5_REG, 0x800, 0x3, {0x3}, 0, 0},
/* REFCLK_SEL(25Mhz), ICP_FORCE, ICP[3:0]=0xa(210uA); */
{MISC_REG, 0x800, 0x42f, {0x42a}, 0, 0},
/* REF_FREF_SEL[4:0]=0x2(25Mhz) */
{POWER_AND_PLL_CTRL_REG, 0x800, 0x1f, {0x02}, 0, 0},
/*
* G2_RX SELMUFF[1:0]=3, G2_RX_SELMUFI[1:0]=3, G2_RX_SELMUPF[2:0]=2
* and G2_RX_SELMUPI[2:0]=2
*/
{G2_SETTINGS_1_REG, 0x800, 0x3ff, {0x3d2}, 0, 0},
/* Dtl Clamping disable and Dtl-clamping-Sel(6000ppm) */
{RX_REG2, 0x800, 0xf0, {0x70}, 0, 0},
/* tx_amp_pipe_v0[4:0]=0x1a */
{PCIE_REG1, 0x800, 0xf80, {0xd00}, 0, 0},
/* vco_cal_vth_sel */
{REF_REG0, 0x800, 0x38, {0x20}, 0, 0},
/* Spread Spectrum Clock Enable */
{LANE_CFG5_REG, 0x800, 0x4, {0x4}, 0, 0},
/* PRD_TXDEEMPH0 */
{LANE_CFG0_REG, 0x800, 0x1, {0x1}, 0, 0},
/* MODE_MARGIN_OVERRIDE */
{GLOBAL_TEST_CTRL, 0x800, 0x4, {0x4}, 0, 0},
};
/* PEX and USB3 - TX config seq */
@ -490,11 +513,11 @@ struct op_params pex_and_usb3_tx_config_params1[] = {
/* 10ms delay */
{0x0, 0x0, 0x0, {0x0, 0x0}, 10, 0},
/* os_ph_offset_force (align 90) */
{RX_REG3, 0x800, 0xff, {0xdc, NO_DATA}, 0, 0},
{RX_REG3, 0x800, 0xff, {0xdc, 0xd8}, 0, 0},
/* Set os_ph_valid */
{RX_REG3, 0x800, 0x100, {0x100, NO_DATA}, 0, 0},
{RX_REG3, 0x800, 0x100, {0x100, 0x100}, 0, 0},
/* Unset os_ph_valid */
{RX_REG3, 0x800, 0x100, {0x0, NO_DATA}, 0, 0},
{RX_REG3, 0x800, 0x100, {0x0, 0x0}, 0, 0},
};
struct op_params pex_and_usb3_tx_config_params2[] = {
@ -1204,7 +1227,7 @@ int hws_serdes_seq_db_init(void)
sizeof(usb3_electrical_config_serdes_rev2_params) /
sizeof(struct op_params);
}
serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].data_arr_idx = USB3;
serdes_seq_db[USB3_ELECTRICAL_CONFIG_SEQ].data_arr_idx = 0;
/* USB3_TX_CONFIG_SEQ sequence init */
serdes_seq_db[USB3_TX_CONFIG_SEQ1].op_params_ptr =

View File

@ -50,6 +50,7 @@
#define MISC_REG 0xa013c
#define GLUE_REG 0xa0140
#define GENERATION_DIVIDER_FORCE_REG 0xa0144
#define PLLINTP_REG1 0xa0150
#define PCIE_REG0 0xa0120
#define LANE_ALIGN_REG0 0xa0124
#define SQUELCH_FFE_SETTING_REG 0xa0018
@ -78,6 +79,7 @@
#define LANE_CFG4_REG 0xa0620
#define LANE_CFG5_REG 0xa0624
#define GLOBAL_CLK_CTRL 0xa0704
#define GLOBAL_TEST_CTRL 0xa0708
#define GLOBAL_MISC_CTRL 0xa0718
#define GLOBAL_CLK_SRC_HI 0xa0710

View File

@ -77,6 +77,7 @@ static u32 board_id_get(void)
__weak u8 board_sat_r_get(u8 dev_num, u8 reg)
{
struct udevice *udev;
u8 data;
u8 *dev;
u32 board_id = board_id_get();
@ -107,8 +108,11 @@ __weak u8 board_sat_r_get(u8 dev_num, u8 reg)
}
/* Read MPP module ID */
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
ret = i2c_read(dev[dev_num], 0, 1, (u8 *)&data, 1);
ret = i2c_get_chip_for_busnum(0, dev[dev_num], 1, &udev);
if (ret)
return MV_ERROR;
ret = dm_i2c_read(udev, 0, &data, 1);
if (ret)
return MV_ERROR;
@ -124,13 +128,18 @@ static int board_modules_scan(void)
/* Perform scan only for DB board */
if ((board_id == DB_88F78XX0_BP_ID) ||
(board_id == DB_88F78XX0_BP_REV2_ID)) {
struct udevice *udev;
/* reset modules flags */
config_module = 0;
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
ret = i2c_get_chip_for_busnum(0, MV_BOARD_PEX_MODULE_ADDR,
1, &udev);
if (ret)
return MV_ERROR;
/* SERDES module (only PEX model is supported now) */
ret = i2c_read(MV_BOARD_PEX_MODULE_ADDR, 0, 1, (u8 *)&val, 1);
ret = dm_i2c_read(udev, 0, &val, 1);
if (ret)
return MV_ERROR;

View File

@ -5,7 +5,6 @@
#include <common.h>
#include <dm.h>
#include <debug_uart.h>
#include <fdtdec.h>
#include <hang.h>
#include <image.h>
@ -250,18 +249,6 @@ void board_init_f(ulong dummy)
*/
board_early_init_f();
/* Example code showing how to enable the debug UART on MVEBU */
#ifdef EARLY_UART
/*
* Debug UART can be used from here if required:
*
* debug_uart_init();
* printch('a');
* printhex8(0x1234);
* printascii("string");
*/
#endif
/*
* Use special translation offset for SPL. This needs to be
* configured *before* spl_init() is called as this function
@ -273,7 +260,7 @@ void board_init_f(ulong dummy)
ret = spl_init();
if (ret) {
debug("spl_init() failed: %d\n", ret);
printf("spl_init() failed: %d\n", ret);
hang();
}
@ -289,7 +276,7 @@ void board_init_f(ulong dummy)
/* Setup DDR */
ret = ddr3_init();
if (ret) {
debug("ddr3_init() failed: %d\n", ret);
printf("ddr3_init() failed: %d\n", ret);
hang();
}
#endif

View File

@ -41,22 +41,14 @@
#define ARMADA_37XX_SPI_DOUT (MVEBU_REGISTER(0x10608))
#define ARMADA_37XX_SPI_DIN (MVEBU_REGISTER(0x1060c))
#define ETH1_PATH "/soc/internal-regs@d0000000/ethernet@40000"
#define MDIO_PATH "/soc/internal-regs@d0000000/mdio@32004"
#define SFP_GPIO_PATH "/soc/internal-regs@d0000000/spi@10600/moxtet@1/gpio@0"
#define PCIE_PATH "/soc/pcie@d0070000"
#define SFP_PATH "/sfp"
#define LED_PATH "/leds/led"
#define BUTTON_PATH "/gpio-keys/reset"
DECLARE_GLOBAL_DATA_PTR;
#if defined(CONFIG_OF_BOARD_FIXUP)
int board_fix_fdt(void *blob)
{
enum fdt_status status_pcie, status_eth1;
u8 topology[MAX_MOX_MODULES];
int i, size, node;
bool enable;
int i, size, ret;
/*
* SPI driver is not loaded in driver model yet, but we have to find out
@ -64,15 +56,20 @@ int board_fix_fdt(void *blob)
* to read SPI by reading/writing SPI registers directly
*/
writel(0x10df, ARMADA_37XX_SPI_CFG);
/* put pin from GPIO to SPI mode */
clrbits_le32(ARMADA_37XX_NB_GPIO_SEL, BIT(12));
/* configure cpol, cpha, prescale */
writel(0x10df, ARMADA_37XX_SPI_CFG);
mdelay(1);
/* enable SPI CS1 */
setbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17));
while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2))
udelay(1);
status_pcie = FDT_STATUS_DISABLED;
status_eth1 = FDT_STATUS_DISABLED;
for (i = 0; i < MAX_MOX_MODULES; ++i) {
writel(0x0, ARMADA_37XX_SPI_DOUT);
@ -84,6 +81,11 @@ int board_fix_fdt(void *blob)
break;
topology[i] &= 0xf;
if (topology[i] == MOX_MODULE_SFP ||
topology[i] == MOX_MODULE_TOPAZ ||
topology[i] == MOX_MODULE_PERIDOT)
status_eth1 = FDT_STATUS_OKAY;
}
size = i;
@ -91,24 +93,21 @@ int board_fix_fdt(void *blob)
/* disable SPI CS1 */
clrbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17));
ret = fdt_set_status_by_alias(blob, "ethernet1", status_eth1);
if (ret < 0)
printf("Cannot set status for eth1 in U-Boot's device tree: %s!\n",
fdt_strerror(ret));
if (size > 1 && (topology[1] == MOX_MODULE_PCI ||
topology[1] == MOX_MODULE_USB3 ||
topology[1] == MOX_MODULE_PASSPCI))
enable = true;
else
enable = false;
status_pcie = FDT_STATUS_OKAY;
node = fdt_path_offset(blob, PCIE_PATH);
if (node < 0) {
printf("Cannot find PCIe node in U-Boot's device tree!\n");
return 0;
}
if (fdt_setprop_string(blob, node, "status",
enable ? "okay" : "disabled") < 0) {
printf("Cannot %s PCIe in U-Boot's device tree!\n",
enable ? "enable" : "disable");
ret = fdt_set_status_by_compatible(blob, "marvell,armada-3700-pcie",
status_pcie);
if (ret < 0) {
printf("Cannot set status for PCIe in U-Boot's device tree: %s!\n",
fdt_strerror(ret));
return 0;
}
@ -416,12 +415,18 @@ static bool read_reset_button(void)
struct udevice *button, *led;
int i;
if (device_get_global_by_ofnode(ofnode_path(BUTTON_PATH), &button)) {
if (device_get_global_by_ofnode(
ofnode_first_subnode(ofnode_by_compatible(ofnode_null(),
"gpio-keys")),
&button)) {
printf("Cannot find reset button!\n");
return false;
}
if (device_get_global_by_ofnode(ofnode_path(LED_PATH), &led)) {
if (device_get_global_by_ofnode(
ofnode_first_subnode(ofnode_by_compatible(ofnode_null(),
"gpio-leds")),
&led)) {
printf("Cannot find status LED!\n");
return false;
}
@ -664,74 +669,6 @@ handle_reset_btn:
#if defined(CONFIG_OF_BOARD_SETUP)
static int vnode_by_path(void *blob, const char *fmt, va_list ap)
{
char path[128];
vsnprintf(path, 128, fmt, ap);
return fdt_path_offset(blob, path);
}
static int node_by_path(void *blob, const char *fmt, ...)
{
va_list ap;
int res;
va_start(ap, fmt);
res = vnode_by_path(blob, fmt, ap);
va_end(ap);
return res;
}
static int phandle_by_path(void *blob, const char *fmt, ...)
{
va_list ap;
int node, phandle, res;
va_start(ap, fmt);
node = vnode_by_path(blob, fmt, ap);
va_end(ap);
if (node < 0)
return node;
phandle = fdt_get_phandle(blob, node);
if (phandle > 0)
return phandle;
phandle = fdt_get_max_phandle(blob);
if (phandle < 0)
return phandle;
phandle += 1;
res = fdt_setprop_u32(blob, node, "linux,phandle", phandle);
if (res < 0)
return res;
res = fdt_setprop_u32(blob, node, "phandle", phandle);
if (res < 0)
return res;
return phandle;
}
static int enable_by_path(void *blob, const char *fmt, ...)
{
va_list ap;
int node;
va_start(ap, fmt);
node = vnode_by_path(blob, fmt, ap);
va_end(ap);
if (node < 0)
return node;
return fdt_setprop_string(blob, node, "status", "okay");
}
static bool is_topaz(int id)
{
return topaz && id == peridot + topaz - 1;
@ -744,12 +681,22 @@ static int switch_addr(int id)
static int setup_switch(void *blob, int id)
{
int res, addr, i, node, phandle;
int res, addr, i, node;
char mdio_path[64];
node = fdt_node_offset_by_compatible(blob, -1, "marvell,orion-mdio");
if (node < 0)
return node;
res = fdt_get_path(blob, node, mdio_path, sizeof(mdio_path));
if (res < 0)
return res;
addr = switch_addr(id);
/* first enable the switch by setting status = "okay" */
res = enable_by_path(blob, MDIO_PATH "/switch%i@%x", id, addr);
res = fdt_status_okay_by_pathf(blob, "%s/switch%i@%x", mdio_path, id,
addr);
if (res < 0)
return res;
@ -758,13 +705,13 @@ static int setup_switch(void *blob, int id)
* enable corresponding ports
*/
if (id < peridot + topaz - 1) {
res = enable_by_path(blob,
MDIO_PATH "/switch%i@%x/ports/port@a",
id, addr);
res = fdt_status_okay_by_pathf(blob,
"%s/switch%i@%x/ports/port@a",
mdio_path, id, addr);
} else if (id == peridot - 1 && !topaz && sfp) {
res = enable_by_path(blob,
MDIO_PATH "/switch%i@%x/ports/port-sfp@a",
id, addr);
res = fdt_status_okay_by_pathf(blob,
"%s/switch%i@%x/ports/port-sfp@a",
mdio_path, id, addr);
} else {
res = 0;
}
@ -775,18 +722,21 @@ static int setup_switch(void *blob, int id)
return 0;
/* finally change link property if needed */
node = node_by_path(blob, MDIO_PATH "/switch%i@%x/ports/port@a", id,
addr);
node = fdt_node_offset_by_pathf(blob, "%s/switch%i@%x/ports/port@a",
mdio_path, id, addr);
if (node < 0)
return node;
for (i = id + 1; i < peridot + topaz; ++i) {
phandle = phandle_by_path(blob,
MDIO_PATH "/switch%i@%x/ports/port@%x",
i, switch_addr(i),
is_topaz(i) ? 5 : 9);
if (phandle < 0)
return phandle;
unsigned int phandle;
phandle = fdt_create_phandle_by_pathf(blob,
"%s/switch%i@%x/ports/port@%x",
mdio_path, i,
switch_addr(i),
is_topaz(i) ? 5 : 9);
if (!phandle)
return -FDT_ERR_NOPHANDLES;
if (i == id + 1)
res = fdt_setprop_u32(blob, node, "link", phandle);
@ -799,38 +749,17 @@ static int setup_switch(void *blob, int id)
return 0;
}
static int remove_disabled_nodes(void *blob)
{
while (1) {
int res, offset;
offset = fdt_node_offset_by_prop_value(blob, -1, "status",
"disabled", 9);
if (offset < 0)
break;
res = fdt_del_node(blob, offset);
if (res < 0)
return res;
}
return 0;
}
int ft_board_setup(void *blob, struct bd_info *bd)
{
int node, phandle, res;
int res;
/*
* If MOX B (PCI), MOX F (USB) or MOX G (Passthrough PCI) modules are
* connected, enable the PCIe node.
*/
if (pci || usb || passpci) {
node = fdt_path_offset(blob, PCIE_PATH);
if (node < 0)
return node;
res = fdt_setprop_string(blob, node, "status", "okay");
res = fdt_status_okay_by_compatible(blob,
"marvell,armada-3700-pcie");
if (res < 0)
return res;
@ -847,7 +776,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
if (peridot || topaz) {
int i;
res = enable_by_path(blob, ETH1_PATH);
res = fdt_status_okay_by_alias(blob, "ethernet1");
if (res < 0)
return res;
@ -865,20 +794,25 @@ int ft_board_setup(void *blob, struct bd_info *bd)
* Also enable and configure SFP GPIO controller node.
*/
if (sfp) {
res = enable_by_path(blob, SFP_PATH);
int node;
res = fdt_status_okay_by_compatible(blob, "sff,sfp");
if (res < 0)
return res;
res = enable_by_path(blob, ETH1_PATH);
res = fdt_status_okay_by_alias(blob, "ethernet1");
if (res < 0)
return res;
if (!peridot) {
phandle = phandle_by_path(blob, SFP_PATH);
if (phandle < 0)
return res;
unsigned int phandle;
node = node_by_path(blob, ETH1_PATH);
phandle = fdt_create_phandle_by_compatible(blob,
"sff,sfp");
if (!phandle)
return -FDT_ERR_NOPHANDLES;
node = fdt_path_offset(blob, "ethernet1");
if (node < 0)
return node;
@ -892,7 +826,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
return res;
}
res = enable_by_path(blob, SFP_GPIO_PATH);
res = fdt_status_okay_by_compatible(blob, "cznic,moxtet-gpio");
if (res < 0)
return res;
@ -900,7 +834,8 @@ int ft_board_setup(void *blob, struct bd_info *bd)
char newname[16];
/* moxtet-sfp is on non-zero position, change default */
node = node_by_path(blob, SFP_GPIO_PATH);
node = fdt_node_offset_by_compatible(blob, -1,
"cznic,moxtet-gpio");
if (node < 0)
return node;
@ -919,7 +854,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
fdt_fixup_ethernet(blob);
/* Finally remove disabled nodes, as per Rob Herring's request. */
remove_disabled_nodes(blob);
fdt_delete_disabled_nodes(blob);
return 0;
}

View File

@ -205,7 +205,7 @@ static int fdt_fix_mix(const void *fdt)
int env_lmac = -1;
int lmac_fdt_node = -1;
int mix_fdt_node = -1;
int lmac_phandle;
unsigned int lmac_phandle;
char *compat;
/* Get the lmac for this environment variable */
@ -229,8 +229,7 @@ static int fdt_fix_mix(const void *fdt)
}
}
lmac_phandle = fdt_alloc_phandle((void *)fdt);
fdt_set_phandle((void *)fdt, lmac_fdt_node, lmac_phandle);
lmac_phandle = fdt_create_phandle((void *)fdt, lmac_fdt_node);
/* Get the fdt mix node corresponding to this lmac */
mix_fdt_node = get_mix_fdt_node(fdt, env_node, env_lmac);

View File

@ -775,10 +775,11 @@ 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;
int ret, dpmac_id, i;
struct phy_device *phy_dev;
char ethname[ETH_NAME_LEN];
phy_interface_t phy_iface;
uint32_t phandle;
ret = 0;
/* we know FPGA is connected to i2c0, therefore search path directly,
@ -794,7 +795,10 @@ int fdt_fixup_board_phy(void *fdt)
return fpga_offset;
}
phandle = fdt_alloc_phandle(fdt);
ret = fdt_generate_phandle(fdt, &phandle);
if (ret < 0)
return ret;
mii_devs = mdio_get_list_head();
list_for_each(entry, mii_devs) {

View File

@ -787,10 +787,11 @@ 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;
int ret, dpmac_id, i;
struct phy_device *phy_dev;
char ethname[ETH_NAME_LEN];
phy_interface_t phy_iface;
uint32_t phandle;
ret = 0;
/* we know FPGA is connected to i2c0, therefore search path directly,
@ -806,7 +807,10 @@ int fdt_fixup_board_phy(void *fdt)
return fpga_offset;
}
phandle = fdt_alloc_phandle(fdt);
ret = fdt_generate_phandle(fdt, &phandle);
if (ret < 0)
return ret;
mii_devs = mdio_get_list_head();
list_for_each(entry, mii_devs) {

View File

@ -1681,8 +1681,7 @@ void ft_early_fixup(void *blob, int board_type)
* disable serial2 node for GW54xx for compatibility with older
* 3.10.x kernel that improperly had this node enabled in the DT
*/
fdt_set_status_by_alias(blob, "serial2", FDT_STATUS_DISABLED,
0);
fdt_set_status_by_alias(blob, "serial2", FDT_STATUS_DISABLED);
/* GW54xx-E adds WDOG2_B external reset */
if (rev < 'E')

View File

@ -75,7 +75,7 @@ int ft_board_setup(void *blob, struct bd_info *bd)
if (CONFIG_IS_ENABLED(SL28_SPL_LOADS_OPTEE_BL32)) {
node = fdt_node_offset_by_compatible(blob, -1, "linaro,optee-tz");
if (node)
fdt_set_node_status(blob, node, FDT_STATUS_OKAY, 0);
fdt_set_node_status(blob, node, FDT_STATUS_OKAY);
}
return 0;

View File

@ -298,10 +298,19 @@ int board_late_init(void)
bootcount_inc();
if (bootcount > PEX_SWITCH_NOT_FOUNT_LIMIT) {
printf("Issuing power-switch via uC!\n");
struct udevice *dev;
printf("Issuing power-switch via uC!\n");
i2c_set_bus_num(STM_I2C_BUS);
ret = i2c_get_chip_for_busnum(STM_I2C_BUS, STM_I2C_ADDR,
1, &dev);
if (ret) {
printf("Error selecting STM on I2C bus (ret=%d)\n",
ret);
printf("Issuing soft-reset...\n");
/* default handling: SOFT reset */
do_reset(NULL, 0, 0, NULL);
}
i2c_buf[0] = STM_I2C_ADDR << 1;
i2c_buf[1] = 0xc5; /* cmd */
i2c_buf[2] = 0x01; /* enable */
@ -313,7 +322,7 @@ int board_late_init(void)
i2c_buf[6] = 0x00;
i2c_buf[7] = crc8(0x72, &i2c_buf[0], 7);
ret = i2c_write(STM_I2C_ADDR, 0, 0, &i2c_buf[1], 7);
ret = dm_i2c_write(dev, 0, &i2c_buf[1], 7);
if (ret) {
printf("I2C write error (ret=%d)\n", ret);
printf("Issuing soft-reset...\n");

View File

@ -695,6 +695,29 @@ int fdt_shrink_to_minimum(void *blob, uint extrasize)
return actualsize;
}
/**
* fdt_delete_disabled_nodes: Delete all nodes with status == "disabled"
*
* @blob: ptr to device tree
*/
int fdt_delete_disabled_nodes(void *blob)
{
while (1) {
int ret, offset;
offset = fdt_node_offset_by_prop_value(blob, -1, "status",
"disabled", 9);
if (offset < 0)
break;
ret = fdt_del_node(blob, offset);
if (ret < 0)
return ret;
}
return 0;
}
#ifdef CONFIG_PCI
#define CONFIG_SYS_PCI_NR_INBOUND_WIN 4
@ -1463,22 +1486,35 @@ int fdt_node_offset_by_compat_reg(void *blob, const char *compat,
return -FDT_ERR_NOTFOUND;
}
static int vnode_offset_by_pathf(void *blob, const char *fmt, va_list ap)
{
char path[512];
int len;
len = vsnprintf(path, sizeof(path), fmt, ap);
if (len < 0 || len + 1 > sizeof(path))
return -FDT_ERR_NOSPACE;
return fdt_path_offset(blob, path);
}
/**
* fdt_alloc_phandle: Return next free phandle value
* fdt_node_offset_by_pathf: Find node offset by sprintf formatted path
*
* @blob: ptr to device tree
* @fmt: path format
* @ap: vsnprintf arguments
*/
int fdt_alloc_phandle(void *blob)
int fdt_node_offset_by_pathf(void *blob, const char *fmt, ...)
{
int offset;
uint32_t phandle = 0;
va_list ap;
int res;
for (offset = fdt_next_node(blob, -1, NULL); offset >= 0;
offset = fdt_next_node(blob, offset, NULL)) {
phandle = max(phandle, fdt_get_phandle(blob, offset));
}
va_start(ap, fmt);
res = vnode_offset_by_pathf(blob, fmt, ap);
va_end(ap);
return phandle + 1;
return res;
}
/*
@ -1522,7 +1558,7 @@ int fdt_set_phandle(void *fdt, int nodeoffset, uint32_t phandle)
}
/*
* fdt_create_phandle: Create a phandle property for the given node
* fdt_create_phandle: Get or create a phandle property for the given node
*
* @fdt: ptr to device tree
* @nodeoffset: node to update
@ -1530,13 +1566,19 @@ int fdt_set_phandle(void *fdt, int nodeoffset, uint32_t phandle)
unsigned int fdt_create_phandle(void *fdt, int nodeoffset)
{
/* see if there is a phandle already */
int phandle = fdt_get_phandle(fdt, nodeoffset);
uint32_t phandle = fdt_get_phandle(fdt, nodeoffset);
/* if we got 0, means no phandle so create one */
if (phandle == 0) {
int ret;
phandle = fdt_alloc_phandle(fdt);
ret = fdt_generate_phandle(fdt, &phandle);
if (ret < 0) {
printf("Can't generate phandle: %s\n",
fdt_strerror(ret));
return 0;
}
ret = fdt_set_phandle(fdt, nodeoffset, phandle);
if (ret < 0) {
printf("Can't set phandle %u: %s\n", phandle,
@ -1548,19 +1590,60 @@ unsigned int fdt_create_phandle(void *fdt, int nodeoffset)
return phandle;
}
/**
* fdt_create_phandle_by_compatible: Get or create a phandle for first node with
* given compatible
*
* @fdt: ptr to device tree
* @compat: node's compatible string
*/
unsigned int fdt_create_phandle_by_compatible(void *fdt, const char *compat)
{
int offset = fdt_node_offset_by_compatible(fdt, -1, compat);
if (offset < 0) {
printf("Can't find node with compatible \"%s\": %s\n", compat,
fdt_strerror(offset));
return 0;
}
return fdt_create_phandle(fdt, offset);
}
/**
* fdt_create_phandle_by_pathf: Get or create a phandle for node given by
* sprintf-formatted path
*
* @fdt: ptr to device tree
* @fmt, ...: path format string and arguments to pass to sprintf
*/
unsigned int fdt_create_phandle_by_pathf(void *fdt, const char *fmt, ...)
{
va_list ap;
int offset;
va_start(ap, fmt);
offset = vnode_offset_by_pathf(fdt, fmt, ap);
va_end(ap);
if (offset < 0) {
printf("Can't find node by given path: %s\n",
fdt_strerror(offset));
return 0;
}
return fdt_create_phandle(fdt, offset);
}
/*
* fdt_set_node_status: Set status for the given node
*
* @fdt: ptr to device tree
* @nodeoffset: node to update
* @status: FDT_STATUS_OKAY, FDT_STATUS_DISABLED,
* FDT_STATUS_FAIL, FDT_STATUS_FAIL_ERROR_CODE
* @error_code: optional, only used if status is FDT_STATUS_FAIL_ERROR_CODE
* @status: FDT_STATUS_OKAY, FDT_STATUS_DISABLED, FDT_STATUS_FAIL
*/
int fdt_set_node_status(void *fdt, int nodeoffset,
enum fdt_status status, unsigned int error_code)
int fdt_set_node_status(void *fdt, int nodeoffset, enum fdt_status status)
{
char buf[16];
int ret = 0;
if (nodeoffset < 0)
@ -1576,10 +1659,6 @@ int fdt_set_node_status(void *fdt, int nodeoffset,
case FDT_STATUS_FAIL:
ret = fdt_setprop_string(fdt, nodeoffset, "status", "fail");
break;
case FDT_STATUS_FAIL_ERROR_CODE:
sprintf(buf, "fail-%d", error_code);
ret = fdt_setprop_string(fdt, nodeoffset, "status", buf);
break;
default:
printf("Invalid fdt status: %x\n", status);
ret = -1;
@ -1594,16 +1673,57 @@ int fdt_set_node_status(void *fdt, int nodeoffset,
*
* @fdt: ptr to device tree
* @alias: alias of node to update
* @status: FDT_STATUS_OKAY, FDT_STATUS_DISABLED,
* FDT_STATUS_FAIL, FDT_STATUS_FAIL_ERROR_CODE
* @error_code: optional, only used if status is FDT_STATUS_FAIL_ERROR_CODE
* @status: FDT_STATUS_OKAY, FDT_STATUS_DISABLED, FDT_STATUS_FAIL
*/
int fdt_set_status_by_alias(void *fdt, const char* alias,
enum fdt_status status, unsigned int error_code)
enum fdt_status status)
{
int offset = fdt_path_offset(fdt, alias);
return fdt_set_node_status(fdt, offset, status, error_code);
return fdt_set_node_status(fdt, offset, status);
}
/**
* fdt_set_status_by_compatible: Set node status for first node with given
* compatible
*
* @fdt: ptr to device tree
* @compat: node's compatible string
* @status: FDT_STATUS_OKAY, FDT_STATUS_DISABLED, FDT_STATUS_FAIL
*/
int fdt_set_status_by_compatible(void *fdt, const char *compat,
enum fdt_status status)
{
int offset = fdt_node_offset_by_compatible(fdt, -1, compat);
if (offset < 0)
return offset;
return fdt_set_node_status(fdt, offset, status);
}
/**
* fdt_set_status_by_pathf: Set node status for node given by sprintf-formatted
* path
*
* @fdt: ptr to device tree
* @status: FDT_STATUS_OKAY, FDT_STATUS_DISABLED, FDT_STATUS_FAIL
* @fmt, ...: path format string and arguments to pass to sprintf
*/
int fdt_set_status_by_pathf(void *fdt, enum fdt_status status, const char *fmt,
...)
{
va_list ap;
int offset;
va_start(ap, fmt);
offset = vnode_offset_by_pathf(fdt, fmt, ap);
va_end(ap);
if (offset < 0)
return offset;
return fdt_set_node_status(fdt, offset, status);
}
#if defined(CONFIG_VIDEO) || defined(CONFIG_LCD)

View File

@ -50,10 +50,8 @@ CONFIG_ENV_SPI_MAX_HZ=50000000
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SPL_OF_TRANSLATE=y
CONFIG_SATA_MV=y
CONFIG_SYS_I2C_LEGACY=y
CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_SYS_I2C_SLAVE=0x0
# CONFIG_MMC is not set
CONFIG_MTD=y
CONFIG_MTD_RAW_NAND=y

View File

@ -55,10 +55,8 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=50000000
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SPL_OF_TRANSLATE=y
CONFIG_SYS_I2C_LEGACY=y
CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_SYS_I2C_SLAVE=0x0
# CONFIG_MMC is not set
CONFIG_MTD=y
CONFIG_SPI_FLASH_STMICRO=y

View File

@ -37,10 +37,8 @@ CONFIG_USE_ENV_SPI_MAX_HZ=y
CONFIG_ENV_SPI_MAX_HZ=50000000
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_SPL_OF_TRANSLATE=y
CONFIG_SYS_I2C_LEGACY=y
CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_SYS_I2C_SLAVE=0x0
# CONFIG_MMC is not set
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_SPANSION=y

View File

@ -58,10 +58,8 @@ CONFIG_SATA_MV=y
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_BOOTCOUNT_RAM=y
CONFIG_FPGA_ALTERA=y
CONFIG_SYS_I2C_LEGACY=y
CONFIG_SPL_SYS_I2C_LEGACY=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_MVTWSI=y
CONFIG_SYS_I2C_SLAVE=0x0
# CONFIG_MMC is not set
CONFIG_SF_DEFAULT_SPEED=27777777
CONFIG_SPI_FLASH_MACRONIX=y

View File

@ -373,7 +373,6 @@ int ddr3_load_dqs_patterns(MV_DRAM_INFO *dram_info);
void ddr3_static_training_init(void);
u8 ddr3_get_eprom_fabric(void);
void ddr3_set_performance_params(MV_DRAM_INFO *dram_info);
int ddr3_dram_sram_burst(u32 src, u32 dst, u32 len);
void ddr3_save_training(MV_DRAM_INFO *dram_info);

View File

@ -361,12 +361,18 @@ static u32 ddr3_init_main(void)
__maybe_unused u32 ddr_width = BUS_WIDTH;
__maybe_unused int status;
__maybe_unused u32 win_backup[16];
__maybe_unused struct udevice *udev;
__maybe_unused int ret;
/* SoC/Board special Initializtions */
fab_opt = ddr3_get_fab_opt();
#ifdef CONFIG_SPD_EEPROM
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
ret = i2c_get_chip_for_busnum(0, BUS_WIDTH_ECC_TWSI_ADDR, 1, &udev);
if (ret) {
printf("Cannot find SPD EEPROM\n");
return MV_DDR3_TRAINING_ERR_BAD_DIMM_SETUP;
}
#endif
ddr3_print_version();
@ -438,7 +444,7 @@ static u32 ddr3_init_main(void)
#if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT)
ecc = 0;
if (ddr3_check_config(BUS_WIDTH_ECC_TWSI_ADDR, CONFIG_ECC))
if (ddr3_check_config(udev, CONFIG_ECC))
ecc = 1;
#endif
@ -483,7 +489,7 @@ static u32 ddr3_init_main(void)
* Dynamically Set 32Bit and ECC for AXP (Relevant only for
* Marvell DB boards)
*/
if (ddr3_check_config(BUS_WIDTH_ECC_TWSI_ADDR, CONFIG_BUS_WIDTH)) {
if (ddr3_check_config(udev, CONFIG_BUS_WIDTH)) {
ddr_width = 32;
DEBUG_INIT_S("DDR3 Training Sequence - DRAM bus width 32Bit\n");
}
@ -904,7 +910,7 @@ void ddr3_static_mc_init(void)
* Notes: Only Available for ArmadaXP/Armada 370 DB boards
* Returns: None.
*/
int ddr3_check_config(u32 twsi_addr, MV_CONFIG_TYPE config_type)
int ddr3_check_config(struct udevice *udev, MV_CONFIG_TYPE config_type)
{
#ifdef AUTO_DETECTION_SUPPORT
u8 data = 0;
@ -916,7 +922,7 @@ int ddr3_check_config(u32 twsi_addr, MV_CONFIG_TYPE config_type)
else
offset = 0;
ret = i2c_read(twsi_addr, offset, 1, (u8 *)&data, 1);
ret = dm_i2c_read(udev, offset, &data, 1);
if (!ret) {
switch (config_type) {
case CONFIG_ECC:
@ -943,30 +949,6 @@ int ddr3_check_config(u32 twsi_addr, MV_CONFIG_TYPE config_type)
return 0;
}
#if defined(DB_88F78X60_REV2)
/*
* Name: ddr3_get_eprom_fabric - Get Fabric configuration from EPROM
* Desc:
* Args: twsi Address
* Notes: Only Available for ArmadaXP DB Rev2 boards
* Returns: None.
*/
u8 ddr3_get_eprom_fabric(void)
{
#ifdef AUTO_DETECTION_SUPPORT
u8 data = 0;
int ret;
ret = i2c_read(NEW_FABRIC_TWSI_ADDR, 1, 1, (u8 *)&data, 1);
if (!ret)
return data & 0x1F;
#endif
return 0;
}
#endif
/*
* Name: ddr3_cl_to_valid_cl - this return register matching CL value
* Desc:

View File

@ -98,11 +98,10 @@ int ddr3_hw_training(u32 target_freq, u32 ddr_width,
void ddr3_print_version(void);
void fix_pll_val(u8 target_fab);
u8 ddr3_get_eprom_fabric(void);
u32 ddr3_get_fab_opt(void);
u32 ddr3_get_cpu_freq(void);
u32 ddr3_get_vco_freq(void);
int ddr3_check_config(u32 addr, MV_CONFIG_TYPE config_type);
int ddr3_check_config(struct udevice *udev, MV_CONFIG_TYPE config_type);
u32 ddr3_get_static_mc_value(u32 reg_addr, u32 offset1, u32 mask1, u32 offset2,
u32 mask2);
u32 ddr3_cl_to_valid_cl(u32 cl);

View File

@ -209,13 +209,19 @@ static u32 ddr3_get_dimm_num(u32 *dimm_addr)
/* Read the dimm eeprom */
for (dimm_cur_addr = MAX_DIMM_ADDR; dimm_cur_addr > MIN_DIMM_ADDR;
dimm_cur_addr--) {
struct udevice *udev;
data[SPD_DEV_TYPE_BYTE] = 0;
/* Far-End DIMM must be connected */
if ((dimm_num == 0) && (dimm_cur_addr < FAR_END_DIMM_ADDR))
return 0;
ret = i2c_read(dimm_cur_addr, 0, 1, (uchar *)data, 3);
ret = i2c_get_chip_for_busnum(0, dimm_cur_addr, 1, &udev);
if (ret)
continue;
ret = dm_i2c_read(udev, 0, data, 3);
if (!ret) {
if (data[SPD_DEV_TYPE_BYTE] == SPD_MEM_TYPE_DDR3) {
dimm_addr[dimm_num] = dimm_cur_addr;
@ -245,9 +251,15 @@ int ddr3_spd_init(MV_DIMM_INFO *info, u32 dimm_addr, u32 dimm_width)
__maybe_unused u8 vendor_high, vendor_low;
if (dimm_addr != 0) {
struct udevice *udev;
memset(spd_data, 0, SPD_SIZE * sizeof(u8));
ret = i2c_read(dimm_addr, 0, 1, (uchar *)spd_data, SPD_SIZE);
ret = i2c_get_chip_for_busnum(0, dimm_addr, 1, &udev);
if (ret)
return MV_DDR3_TRAINING_ERR_TWSI_FAIL;
ret = dm_i2c_read(udev, 0, spd_data, SPD_SIZE);
if (ret)
return MV_DDR3_TRAINING_ERR_TWSI_FAIL;
}

View File

@ -106,7 +106,7 @@ static int fdt_qportal(void *blob, int off, int id, char *name,
enum fsl_dpaa_dev dev, int create)
{
int childoff, dev_off, ret = 0;
u32 dev_handle;
unsigned int dev_handle;
#ifdef CONFIG_FSL_CORENET
int num;
u32 liodns[2];
@ -142,11 +142,9 @@ static int fdt_qportal(void *blob, int off, int id, char *name,
if (childoff > 0) {
dev_handle = fdt_get_phandle(blob, dev_off);
if (dev_handle <= 0) {
dev_handle = fdt_alloc_phandle(blob);
ret = fdt_set_phandle(blob, dev_off,
dev_handle);
if (ret < 0)
return ret;
dev_handle = fdt_create_phandle(blob, dev_off);
if (!dev_handle)
return -FDT_ERR_NOPHANDLES;
}
ret = fdt_setprop(blob, childoff, "dev-handle",

View File

@ -21,6 +21,7 @@
*
* Author: Victor Gu <xigu@marvell.com>
* Hezi Shahmoon <hezi.shahmoon@marvell.com>
* Pali Rohár <pali@kernel.org>
*
*/

View File

@ -7,6 +7,7 @@
* Ported to U-Boot by:
* Anton Schubert <anton.schubert@gmx.de>
* Stefan Roese <sr@denx.de>
* Pali Rohár <pali@kernel.org>
*/
#include <common.h>

View File

@ -584,9 +584,9 @@ static void ft_pcie_rc_fix(void *blob, struct ls_pcie_rc *pcie_rc)
return;
if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE)
fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
fdt_set_node_status(blob, off, FDT_STATUS_OKAY);
else
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
}
static void ft_pcie_ep_fix(void *blob, struct ls_pcie_rc *pcie_rc)
@ -600,9 +600,9 @@ static void ft_pcie_ep_fix(void *blob, struct ls_pcie_rc *pcie_rc)
return;
if (pcie_rc->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL)
fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
fdt_set_node_status(blob, off, FDT_STATUS_OKAY);
else
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
}
static void ft_pcie_ls_setup(void *blob, struct ls_pcie_rc *pcie_rc)

View File

@ -193,9 +193,9 @@ static void ft_pcie_ep_layerscape_gen4_fix(void *blob, struct ls_pcie_g4 *pcie)
}
if (pcie->enabled && pcie->mode == PCI_HEADER_TYPE_NORMAL)
fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
fdt_set_node_status(blob, off, FDT_STATUS_OKAY);
else
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
}
static void ft_pcie_rc_layerscape_gen4_fix(void *blob, struct ls_pcie_g4 *pcie)
@ -214,9 +214,9 @@ static void ft_pcie_rc_layerscape_gen4_fix(void *blob, struct ls_pcie_g4 *pcie)
}
if (pcie->enabled && pcie->mode == PCI_HEADER_TYPE_BRIDGE)
fdt_set_node_status(blob, off, FDT_STATUS_OKAY, 0);
fdt_set_node_status(blob, off, FDT_STATUS_OKAY);
else
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0);
fdt_set_node_status(blob, off, FDT_STATUS_DISABLED);
}
static void ft_pcie_layerscape_gen4_setup(void *blob, struct ls_pcie_g4 *pcie)

View File

@ -11,6 +11,7 @@
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
#include <linux/delay.h>
#include <phy.h>
#include "comphy_a3700.h"
@ -982,6 +983,138 @@ void comphy_dedicated_phys_init(void)
debug_exit();
}
static int find_available_node_by_compatible(int offset, const char *compatible)
{
do {
offset = fdt_node_offset_by_compatible(gd->fdt_blob, offset,
compatible);
} while (offset > 0 && !fdtdec_get_is_enabled(gd->fdt_blob, offset));
return offset;
}
static bool comphy_a3700_find_lane(const int nodes[3], int node,
int port, int *lane, int *invert)
{
int res, i, j;
for (i = 0; ; i++) {
struct fdtdec_phandle_args args;
res = fdtdec_parse_phandle_with_args(gd->fdt_blob, node, "phys",
"#phy-cells", 0, i, &args);
if (res)
return false;
for (j = 0; j < 3; j++) {
if (nodes[j] >= 0 && args.node == nodes[j] &&
(args.args_count >= 1 ? args.args[0] : 0) == port) {
*lane = j;
*invert = args.args_count >= 2 ? args.args[1]
: 0;
return true;
}
}
}
return false;
}
static void comphy_a3700_fill_cfg(struct chip_serdes_phy_config *cfg,
const int nodes[3], const char *compatible,
int type)
{
int node, lane, port, speed, invert;
port = (type == COMPHY_TYPE_SGMII1) ? 1 : 0;
node = -1;
while (1) {
node = find_available_node_by_compatible(node, compatible);
if (node < 0)
return;
if (comphy_a3700_find_lane(nodes, node, port, &lane, &invert))
break;
}
if (cfg->comphy_map_data[lane].type != COMPHY_TYPE_UNCONNECTED) {
printf("Error: More PHYs defined for lane %d, skipping\n",
lane);
return;
}
if (type == COMPHY_TYPE_SGMII0 || type == COMPHY_TYPE_SGMII1) {
const char *phy_mode;
phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
if (phy_mode &&
!strcmp(phy_mode,
phy_string_for_interface(PHY_INTERFACE_MODE_2500BASEX)))
speed = COMPHY_SPEED_3_125G;
else
speed = COMPHY_SPEED_1_25G;
} else if (type == COMPHY_TYPE_SATA0) {
speed = COMPHY_SPEED_6G;
} else {
speed = COMPHY_SPEED_5G;
}
cfg->comphy_map_data[lane].type = type;
cfg->comphy_map_data[lane].speed = speed;
cfg->comphy_map_data[lane].invert = invert;
}
static const fdt32_t comphy_a3700_mux_lane_order[3] = {
__constant_cpu_to_be32(1),
__constant_cpu_to_be32(0),
__constant_cpu_to_be32(2),
};
int comphy_a3700_init_serdes_map(int node, struct chip_serdes_phy_config *cfg)
{
int comphy_nodes[3];
int child, i;
for (i = 0; i < ARRAY_SIZE(comphy_nodes); i++)
comphy_nodes[i] = -FDT_ERR_NOTFOUND;
fdt_for_each_subnode(child, gd->fdt_blob, node) {
if (!fdtdec_get_is_enabled(gd->fdt_blob, child))
continue;
i = fdtdec_get_int(gd->fdt_blob, child, "reg", -1);
if (i < 0 || i >= ARRAY_SIZE(comphy_nodes))
continue;
comphy_nodes[i] = child;
}
for (i = 0; i < ARRAY_SIZE(comphy_nodes); i++) {
cfg->comphy_map_data[i].type = COMPHY_TYPE_UNCONNECTED;
cfg->comphy_map_data[i].speed = COMPHY_SPEED_INVALID;
}
comphy_a3700_fill_cfg(cfg, comphy_nodes, "marvell,armada3700-u3d",
COMPHY_TYPE_USB3_DEVICE);
comphy_a3700_fill_cfg(cfg, comphy_nodes, "marvell,armada3700-xhci",
COMPHY_TYPE_USB3_HOST0);
comphy_a3700_fill_cfg(cfg, comphy_nodes, "marvell,armada-3700-pcie",
COMPHY_TYPE_PEX0);
comphy_a3700_fill_cfg(cfg, comphy_nodes, "marvell,armada-3700-ahci",
COMPHY_TYPE_SATA0);
comphy_a3700_fill_cfg(cfg, comphy_nodes, "marvell,armada-3700-neta",
COMPHY_TYPE_SGMII0);
comphy_a3700_fill_cfg(cfg, comphy_nodes, "marvell,armada-3700-neta",
COMPHY_TYPE_SGMII1);
cfg->comphy_lanes_count = 3;
cfg->comphy_mux_bitcount = 4;
cfg->comphy_mux_lane_order = comphy_a3700_mux_lane_order;
return 0;
}
int comphy_a3700_init(struct chip_serdes_phy_config *chip_cfg,
struct comphy_map *serdes_map)
{

View File

@ -86,11 +86,8 @@ __weak int comphy_update_map(struct comphy_map *serdes_map, int count)
static int comphy_probe(struct udevice *dev)
{
const void *blob = gd->fdt_blob;
int node = dev_of_offset(dev);
struct chip_serdes_phy_config *chip_cfg = dev_get_priv(dev);
int subnode;
int lane;
int last_idx = 0;
static int current_idx;
int res;
@ -104,30 +101,14 @@ static int comphy_probe(struct udevice *dev)
if (IS_ERR(chip_cfg->hpipe3_base_addr))
return PTR_ERR(chip_cfg->hpipe3_base_addr);
chip_cfg->comphy_lanes_count = fdtdec_get_int(blob, node,
"max-lanes", 0);
if (chip_cfg->comphy_lanes_count <= 0) {
dev_err(dev, "comphy max lanes is wrong\n");
return -EINVAL;
}
chip_cfg->comphy_mux_bitcount = fdtdec_get_int(blob, node,
"mux-bitcount", 0);
if (chip_cfg->comphy_mux_bitcount <= 0) {
dev_err(dev, "comphy mux bit count is wrong\n");
return -EINVAL;
}
chip_cfg->comphy_mux_lane_order =
fdtdec_locate_array(blob, node, "mux-lane-order",
chip_cfg->comphy_lanes_count);
if (device_is_compatible(dev, "marvell,comphy-armada-3700")) {
chip_cfg->comphy_init_map = comphy_a3700_init_serdes_map;
chip_cfg->ptr_comphy_chip_init = comphy_a3700_init;
chip_cfg->rx_training = NULL;
}
if (device_is_compatible(dev, "marvell,comphy-cp110")) {
chip_cfg->comphy_init_map = comphy_cp110_init_serdes_map;
chip_cfg->ptr_comphy_chip_init = comphy_cp110_init;
chip_cfg->rx_training = comphy_cp110_sfi_rx_training;
}
@ -141,39 +122,9 @@ static int comphy_probe(struct udevice *dev)
return -ENODEV;
}
lane = 0;
fdt_for_each_subnode(subnode, blob, node) {
/* Skip disabled ports */
if (!fdtdec_get_is_enabled(blob, subnode))
continue;
chip_cfg->comphy_map_data[lane].type =
fdtdec_get_int(blob, subnode, "phy-type",
COMPHY_TYPE_INVALID);
if (chip_cfg->comphy_map_data[lane].type ==
COMPHY_TYPE_INVALID) {
printf("no phy type for lane %d, setting lane as unconnected\n",
lane + 1);
continue;
}
chip_cfg->comphy_map_data[lane].speed =
fdtdec_get_int(blob, subnode, "phy-speed",
COMPHY_SPEED_INVALID);
chip_cfg->comphy_map_data[lane].invert =
fdtdec_get_int(blob, subnode, "phy-invert",
COMPHY_POLARITY_NO_INVERT);
chip_cfg->comphy_map_data[lane].clk_src =
fdtdec_get_bool(blob, subnode, "clk-src");
chip_cfg->comphy_map_data[lane].end_point =
fdtdec_get_bool(blob, subnode, "end_point");
lane++;
}
res = chip_cfg->comphy_init_map(node, chip_cfg);
if (res < 0)
return res;
res = comphy_update_map(chip_cfg->comphy_map_data, chip_cfg->comphy_lanes_count);
if (res < 0)

View File

@ -32,6 +32,7 @@ struct comphy_mux_data {
struct chip_serdes_phy_config {
struct comphy_mux_data *mux_data;
int (*comphy_init_map)(int, struct chip_serdes_phy_config *);
int (*ptr_comphy_chip_init)(struct chip_serdes_phy_config *,
struct comphy_map *);
int (*rx_training)(struct chip_serdes_phy_config *, u32);
@ -85,9 +86,20 @@ static inline void reg_set16(void __iomem *addr, u16 data, u16 mask)
/* SoC specific init functions */
#ifdef CONFIG_ARMADA_3700
int comphy_a3700_init_serdes_map(int node, struct chip_serdes_phy_config *cfg);
int comphy_a3700_init(struct chip_serdes_phy_config *ptr_chip_cfg,
struct comphy_map *serdes_map);
#else
static inline int
comphy_a3700_init_serdes_map(int node, struct chip_serdes_phy_config *cfg)
{
/*
* This function should never be called in this configuration, so
* lets return an error here.
*/
return -1;
}
static inline int comphy_a3700_init(struct chip_serdes_phy_config *ptr_chip_cfg,
struct comphy_map *serdes_map)
{
@ -100,11 +112,22 @@ static inline int comphy_a3700_init(struct chip_serdes_phy_config *ptr_chip_cfg,
#endif
#ifdef CONFIG_ARMADA_8K
int comphy_cp110_init_serdes_map(int node, struct chip_serdes_phy_config *cfg);
int comphy_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg,
struct comphy_map *serdes_map);
int comphy_cp110_sfi_rx_training(struct chip_serdes_phy_config *ptr_chip_cfg,
u32 lane);
#else
static inline int
comphy_cp110_init_serdes_map(int node, struct chip_serdes_phy_config *cfg)
{
/*
* This function should never be called in this configuration, so
* lets return an error here.
*/
return -1;
}
static inline int comphy_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg,
struct comphy_map *serdes_map)
{

View File

@ -554,6 +554,64 @@ void comphy_dedicated_phys_init(void)
debug_exit();
}
int comphy_cp110_init_serdes_map(int node, struct chip_serdes_phy_config *cfg)
{
int lane, subnode;
cfg->comphy_lanes_count = fdtdec_get_int(gd->fdt_blob, node,
"max-lanes", 0);
if (cfg->comphy_lanes_count <= 0) {
printf("comphy max lanes is wrong\n");
return -EINVAL;
}
cfg->comphy_mux_bitcount = fdtdec_get_int(gd->fdt_blob, node,
"mux-bitcount", 0);
if (cfg->comphy_mux_bitcount <= 0) {
printf("comphy mux bit count is wrong\n");
return -EINVAL;
}
cfg->comphy_mux_lane_order = fdtdec_locate_array(gd->fdt_blob, node,
"mux-lane-order",
cfg->comphy_lanes_count);
lane = 0;
fdt_for_each_subnode(subnode, gd->fdt_blob, node) {
/* Skip disabled ports */
if (!fdtdec_get_is_enabled(gd->fdt_blob, subnode))
continue;
cfg->comphy_map_data[lane].type =
fdtdec_get_int(gd->fdt_blob, subnode, "phy-type",
COMPHY_TYPE_INVALID);
if (cfg->comphy_map_data[lane].type == COMPHY_TYPE_INVALID) {
printf("no phy type for lane %d, setting lane as unconnected\n",
lane + 1);
continue;
}
cfg->comphy_map_data[lane].speed =
fdtdec_get_int(gd->fdt_blob, subnode, "phy-speed",
COMPHY_SPEED_INVALID);
cfg->comphy_map_data[lane].invert =
fdtdec_get_int(gd->fdt_blob, subnode, "phy-invert",
COMPHY_POLARITY_NO_INVERT);
cfg->comphy_map_data[lane].clk_src =
fdtdec_get_bool(gd->fdt_blob, subnode, "clk-src");
cfg->comphy_map_data[lane].end_point =
fdtdec_get_bool(gd->fdt_blob, subnode, "end_point");
lane++;
}
return 0;
}
int comphy_cp110_init(struct chip_serdes_phy_config *ptr_chip_cfg,
struct comphy_map *serdes_map)
{

View File

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016 Stefan Roese <sr@denx.de>
* Copyright (C) 2021 Pali Rohár <pali@kernel.org>
*/
#include <common.h>

View File

@ -228,6 +228,8 @@ void set_working_fdt_addr(ulong addr);
int fdt_shrink_to_minimum(void *blob, uint extrasize);
int fdt_increase_size(void *fdt, int add_len);
int fdt_delete_disabled_nodes(void *blob);
int fdt_fixup_nor_flash_size(void *blob);
struct node_info;
@ -285,9 +287,13 @@ int fdt_get_dma_range(const void *blob, int node_offset, phys_addr_t *cpu,
int fdt_node_offset_by_compat_reg(void *blob, const char *compat,
phys_addr_t compat_off);
int fdt_alloc_phandle(void *blob);
int fdt_node_offset_by_pathf(void *blob, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
int fdt_set_phandle(void *fdt, int nodeoffset, uint32_t phandle);
unsigned int fdt_create_phandle(void *fdt, int nodeoffset);
unsigned int fdt_create_phandle_by_compatible(void *fdt, const char *compat);
unsigned int fdt_create_phandle_by_pathf(void *fdt, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
int fdt_add_edid(void *blob, const char *compat, unsigned char *buf);
int fdt_verify_alias_address(void *fdt, int anode, const char *alias,
@ -300,38 +306,61 @@ enum fdt_status {
FDT_STATUS_OKAY,
FDT_STATUS_DISABLED,
FDT_STATUS_FAIL,
FDT_STATUS_FAIL_ERROR_CODE,
};
int fdt_set_node_status(void *fdt, int nodeoffset,
enum fdt_status status, unsigned int error_code);
int fdt_set_node_status(void *fdt, int nodeoffset, enum fdt_status status);
static inline int fdt_status_okay(void *fdt, int nodeoffset)
{
return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_OKAY, 0);
return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_OKAY);
}
static inline int fdt_status_disabled(void *fdt, int nodeoffset)
{
return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_DISABLED, 0);
return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_DISABLED);
}
static inline int fdt_status_fail(void *fdt, int nodeoffset)
{
return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_FAIL, 0);
return fdt_set_node_status(fdt, nodeoffset, FDT_STATUS_FAIL);
}
int fdt_set_status_by_alias(void *fdt, const char *alias,
enum fdt_status status, unsigned int error_code);
enum fdt_status status);
static inline int fdt_status_okay_by_alias(void *fdt, const char *alias)
{
return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_OKAY, 0);
return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_OKAY);
}
static inline int fdt_status_disabled_by_alias(void *fdt, const char *alias)
{
return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_DISABLED, 0);
return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_DISABLED);
}
static inline int fdt_status_fail_by_alias(void *fdt, const char *alias)
{
return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_FAIL, 0);
return fdt_set_status_by_alias(fdt, alias, FDT_STATUS_FAIL);
}
int fdt_set_status_by_compatible(void *fdt, const char *compat,
enum fdt_status status);
static inline int fdt_status_okay_by_compatible(void *fdt, const char *compat)
{
return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_OKAY);
}
static inline int fdt_status_disabled_by_compatible(void *fdt,
const char *compat)
{
return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_DISABLED);
}
static inline int fdt_status_fail_by_compatible(void *fdt, const char *compat)
{
return fdt_set_status_by_compatible(fdt, compat, FDT_STATUS_FAIL);
}
int fdt_set_status_by_pathf(void *fdt, enum fdt_status status, const char *fmt,
...) __attribute__ ((format (printf, 3, 4)));
#define fdt_status_okay_by_pathf(fdt, fmt, ...) \
fdt_set_status_by_pathf((fdt), FDT_STATUS_OKAY, (fmt), ##__VA_ARGS__)
#define fdt_status_disabled_by_pathf(fdt, fmt, ...) \
fdt_set_status_by_pathf((fdt), FDT_STATUS_DISABLED, (fmt), ##__VA_ARGS__)
#define fdt_status_fail_by_pathf(fdt, fmt, ...) \
fdt_set_status_by_pathf((fdt), FDT_STATUS_FAIL, (fmt), ##__VA_ARGS__)
/* Helper to read a big number; size is in cells (not bytes) */
static inline u64 fdt_read_number(const fdt32_t *cell, int size)
{

View File

@ -39,6 +39,10 @@
(__u64)(((__u64)(x) & (__u64)0x00ff000000000000ULL) >> 40) | \
(__u64)(((__u64)(x) & (__u64)0xff00000000000000ULL) >> 56) ))
#define ___constant_swab16(x) ___swab16(x)
#define ___constant_swab32(x) ___swab32(x)
#define ___constant_swab64(x) ___swab64(x)
/*
* provide defaults when no architecture-specific optimization is detected
*/