nbhw18: dynamically enable devices in dts according to current serdes config
BugzID: 52859
This commit is contained in:
parent
b43929b7e4
commit
f9ad35b73a
|
|
@ -51,6 +51,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
#define BD_ADDRESS (0x0000) /* Board descriptor at beginning of EEPROM */
|
||||
#define PD_ADDRESS (0x0200) /* Product descriptor */
|
||||
#define PARTITION_ADDRESS (0x0600) /* Partition Table */
|
||||
#define SERDES_CONFIG_ADDRESS (0x0800) /* SERDES config address */
|
||||
|
||||
#define DEV_CS0_BASE 0xfd000000
|
||||
|
||||
|
|
@ -95,9 +96,57 @@ static int _bd_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
typedef struct EEPROM_SERDES_CONFIG {
|
||||
uint8_t magic[2];
|
||||
uint8_t version;
|
||||
uint8_t spare_0;
|
||||
uint8_t serdes_cfg[6];
|
||||
uint8_t spare1[2];
|
||||
uint32_t crc32;
|
||||
} EEPROM_SERDES_CONFIG;
|
||||
|
||||
static struct EEPROM_SERDES_CONFIG eeprom_serdes_config;
|
||||
|
||||
static void read_eeprom_serdes_config(void)
|
||||
{
|
||||
uint32_t crc;
|
||||
if (i2c_read(BD_EEPROM_ADDR, SERDES_CONFIG_ADDRESS, 2, (uint8_t *)&eeprom_serdes_config, sizeof(eeprom_serdes_config))) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
crc = crc32(0, (uint8_t *)&eeprom_serdes_config, sizeof(eeprom_serdes_config)-4);
|
||||
|
||||
if ((eeprom_serdes_config.magic[0] != 0x83) ||
|
||||
(eeprom_serdes_config.magic[1] != 0xfb) ||
|
||||
(eeprom_serdes_config.version != 0x01) ||
|
||||
(eeprom_serdes_config.crc32 != crc))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
printf("Valid user serdes config found\n");
|
||||
return;
|
||||
|
||||
fail:
|
||||
memset(&eeprom_serdes_config, 0xff, sizeof(eeprom_serdes_config));
|
||||
printf("No user serdes config found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
static uint8_t get_eeprom_serdes_config(int serdes_index)
|
||||
{
|
||||
if ((serdes_index<0) || (serdes_index>=sizeof(eeprom_serdes_config.serdes_cfg))) return 0xff;
|
||||
return eeprom_serdes_config.serdes_cfg[serdes_index];
|
||||
}
|
||||
|
||||
|
||||
static inline int __maybe_unused read_eeprom(void)
|
||||
{
|
||||
return _bd_init();
|
||||
int res = _bd_init();
|
||||
|
||||
read_eeprom_serdes_config();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/* TODO: Create DA9063 Accessor Module */
|
||||
|
|
@ -261,7 +310,17 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count)
|
|||
board_serdes_map[5].serdes_type = SGMII2;
|
||||
} else {
|
||||
for (i = 0; i < ARRAY_SIZE(board_serdes_map); i++) {
|
||||
enum serdes_type type = bd_get_serdes_type(i);
|
||||
enum serdes_type type;
|
||||
uint8_t user_config = get_eeprom_serdes_config(i);
|
||||
|
||||
if (user_config != 0xff) {
|
||||
/* if we have a user config we use that one */
|
||||
type = (enum serdes_type)user_config;
|
||||
} else {
|
||||
/* otherwise we use the config from the bd */
|
||||
type = bd_get_serdes_type(i);
|
||||
}
|
||||
|
||||
/* Do not touch serdes */
|
||||
if (type < LAST_SERDES_TYPE) {
|
||||
if ((type >= SGMII0) && (type <= SGMII2)) {
|
||||
|
|
@ -633,7 +692,7 @@ static void set_devicetree_name(void)
|
|||
/* add hardware versions to environment */
|
||||
if (bd_get_devicetree(devicetreename, sizeof(devicetreename)) != 0) {
|
||||
printf("Devicetree name not found, use legacy name\n");
|
||||
strcpy(devicetreename, "am335x-nbhw16.dtb");
|
||||
strcpy(devicetreename, "armada-385-nbhw18-prod1.dtb");
|
||||
}
|
||||
|
||||
env_set("fdt_image", devicetreename);
|
||||
|
|
@ -768,3 +827,95 @@ int pcie_lane_by_slot(int slot)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void ft_enable_node(void* blob, const char* name)
|
||||
{
|
||||
int node_ofs = -1;
|
||||
|
||||
node_ofs = fdt_path_offset(blob, name);
|
||||
if (node_ofs >= 0) {
|
||||
fdt_setprop_string(blob, node_ofs, "status", "okay");
|
||||
}
|
||||
}
|
||||
|
||||
static void ft_eth1_sgmii0(void *blob)
|
||||
{
|
||||
printf("FT: enable eth phy on sgmii0\n");
|
||||
ft_enable_node(blob, "/soc/internal-regs/ethernet_phy@70000");
|
||||
}
|
||||
|
||||
static void ft_dsa_sgmii0(void *blob)
|
||||
{
|
||||
printf("FT: enable dsa on sgmii0\n");
|
||||
ft_enable_node(blob, "/soc/internal-regs/ethernet_dsa@70000");
|
||||
ft_enable_node(blob, "/dsa_eth0@0");
|
||||
}
|
||||
|
||||
static void ft_dsa_sgmii1(void *blob)
|
||||
{
|
||||
printf("FT: enable dsa on sgmii1\n");
|
||||
ft_enable_node(blob, "/soc/internal-regs/ethernet_dsa@30000");
|
||||
ft_enable_node(blob, "/dsa_eth1@0");
|
||||
}
|
||||
|
||||
static void ft_sfp_sgmii1(void *blob)
|
||||
{
|
||||
/* Depending if the second ethernet port is in use
|
||||
or not the sfp has a different interface name.
|
||||
So enable the proper one. */
|
||||
if (board_serdes_map[0].serdes_type==SGMII0) {
|
||||
printf("FT: enable sfp for cfg1\n");
|
||||
ft_enable_node(blob, "/soc/internal-regs/ethernet_sfp_cfg1@30000");
|
||||
} else {
|
||||
printf("FT: enable sfp for cfg0\n");
|
||||
ft_enable_node(blob, "/soc/internal-regs/ethernet_sfp_cfg0@30000");
|
||||
}
|
||||
}
|
||||
|
||||
int ft_board_setup(void *blob, bd_t *bd)
|
||||
{
|
||||
struct serdes_map* sm;
|
||||
u8 sm_count;
|
||||
|
||||
/* Enabled all components in dts depending on
|
||||
current serdes configuration */
|
||||
|
||||
/* Determine SERDES configuration */
|
||||
hws_board_topology_load(&sm, &sm_count);
|
||||
|
||||
/* Second ethernet port (SERDES0) can only be
|
||||
connected to SGMII0. SO check, if we need to enable it. */
|
||||
switch (board_serdes_map[0].serdes_type) {
|
||||
case SGMII0 :
|
||||
ft_eth1_sgmii0(blob);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
/* The PoE switch (SERDES1) can be connected either to
|
||||
SGMII0 or SGMII1. So check, if we need to enable one of those. */
|
||||
switch (board_serdes_map[1].serdes_type) {
|
||||
case SGMII0 :
|
||||
ft_dsa_sgmii0(blob);
|
||||
break;
|
||||
case SGMII1 :
|
||||
ft_dsa_sgmii1(blob);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
/* SFP (SERDES2) can only be connected to SGMII1. So check,
|
||||
if we need to enable it. */
|
||||
switch (board_serdes_map[2].serdes_type) {
|
||||
case SGMII1 :
|
||||
ft_sfp_sgmii1(blob);
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,6 +84,8 @@
|
|||
#define CONFIG_WATCHDOG
|
||||
#endif
|
||||
|
||||
#define CONFIG_OF_BOARD_SETUP
|
||||
|
||||
#define CONFIG_SYS_ALT_MEMTEST
|
||||
|
||||
#ifndef CONFIG_SPL_BUILD
|
||||
|
|
|
|||
Loading…
Reference in New Issue