mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
Merge "drivers: net: ipq9574: Add SKU Validation"
This commit is contained in:
commit
d9e69aa54b
8 changed files with 292 additions and 38 deletions
|
|
@ -16,4 +16,21 @@
|
|||
/ {
|
||||
machid = <0x1050200>;
|
||||
config_name = "config@db-al01-c3";
|
||||
|
||||
ess-switch {
|
||||
/* Overriding port6 configuration to support AQ instead
|
||||
* of QCA808x
|
||||
*/
|
||||
/delete-property/qca808x_gpio;
|
||||
/delete-property/qca808x_gpio_cnt;
|
||||
switch_mac_mode2 = <PORT_WRAPPER_USXGMII>;
|
||||
aquantia_port = <4 5>;
|
||||
aquantia_port_cnt = <2>;
|
||||
port_phy_info {
|
||||
port@5 {
|
||||
phy_address = <0>;
|
||||
phy_type = <AQ_PHY_TYPE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,4 +16,52 @@
|
|||
/ {
|
||||
machid = <0x1050201>;
|
||||
config_name = "config@db-al02-c3";
|
||||
|
||||
aliases {
|
||||
i2c0 = "/i2c@78B9000";
|
||||
};
|
||||
|
||||
i2c@78B9000 {
|
||||
compatible = "qcom,qup-i2c";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x78B9000 0x600>;
|
||||
clock-frequency = <400000>;
|
||||
i2c_gpio {
|
||||
gpio1 {
|
||||
gpio = <50>;
|
||||
func = <2>;
|
||||
pull = <GPIO_PULL_UP>;
|
||||
drvstr = <GPIO_8MA>;
|
||||
oe = <GPIO_OE_ENABLE>;
|
||||
};
|
||||
|
||||
gpio2 {
|
||||
gpio = <51>;
|
||||
func = <2>;
|
||||
pull = <GPIO_PULL_UP>;
|
||||
drvstr = <GPIO_8MA>;
|
||||
oe = <GPIO_OE_ENABLE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ess-switch {
|
||||
/* Overriding port5 configuration to support SFP instead
|
||||
* of QCA808x.
|
||||
*/
|
||||
/delete-property/qca808x_gpio;
|
||||
/delete-property/qca808x_gpio_cnt;
|
||||
switch_mac_mode1 = <PORT_WRAPPER_10GBASE_R>;
|
||||
sfp_gpio = <61>;
|
||||
sfp_gpio_cnt = <1>;
|
||||
sfp_port = <4>;
|
||||
sfp_port_cnt = <1>;
|
||||
port_phy_info {
|
||||
port@4 {
|
||||
/delete-property/phy_address;
|
||||
phy_type = <SFP_PHY_TYPE>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -425,7 +425,57 @@ void ipq_fdt_fixup_usb_device_mode(void *blob)
|
|||
printf("%s: invalid param for usb_mode\n", __func__);
|
||||
}
|
||||
|
||||
int ipq_validate_qfrom_fuse(unsigned int reg_add, int pos)
|
||||
{
|
||||
return (readl(reg_add) & (1 << pos));
|
||||
}
|
||||
|
||||
int is_uniphy_enabled(int uniphy_index)
|
||||
{
|
||||
int bit = 0;
|
||||
|
||||
switch(uniphy_index) {
|
||||
case 0:
|
||||
bit = UNIPHY_0_DISABLE_BIT;
|
||||
break;
|
||||
case 1:
|
||||
bit = UNIPHY_1_DISABLE_BIT;
|
||||
break;
|
||||
case 2:
|
||||
bit = UNIPHY_2_DISABLE_BIT;
|
||||
break;
|
||||
default:
|
||||
printf("In ipq9574: Max 3 Uniphy's can be supported\n");
|
||||
break;
|
||||
}
|
||||
return !ipq_validate_qfrom_fuse(
|
||||
QFPROM_CORR_FEATURE_CONFIG_ROW2_MSB, bit);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_IPQ
|
||||
int ipq_sku_pci_validation(int pci_id)
|
||||
{
|
||||
int pos = 0;
|
||||
|
||||
switch(pci_id){
|
||||
case 0:
|
||||
pos = PCIE_0_CLOCK_DISABLE_BIT;
|
||||
break;
|
||||
case 1:
|
||||
pos = PCIE_1_CLOCK_DISABLE_BIT;
|
||||
break;
|
||||
case 2:
|
||||
pos = PCIE_2_CLOCK_DISABLE_BIT;
|
||||
break;
|
||||
case 3:
|
||||
pos = PCIE_3_CLOCK_DISABLE_BIT;
|
||||
break;
|
||||
}
|
||||
|
||||
return ipq_validate_qfrom_fuse(
|
||||
QFPROM_CORR_FEATURE_CONFIG_ROW1_MSB, pos);
|
||||
}
|
||||
|
||||
void board_pci_init(int id)
|
||||
{
|
||||
int node, gpio_node, pci_no;
|
||||
|
|
@ -438,11 +488,16 @@ void board_pci_init(int id)
|
|||
return;
|
||||
}
|
||||
|
||||
pci_no = fdtdec_get_int(gd->fdt_blob, node, "id", 0);
|
||||
|
||||
if (ipq_sku_pci_validation(pci_no)){
|
||||
printf("PCIe%d disabled \n", pci_no);
|
||||
}
|
||||
|
||||
gpio_node = fdt_subnode_offset(gd->fdt_blob, node, "pci_gpio");
|
||||
if (gpio_node >= 0)
|
||||
qca_gpio_init(gpio_node);
|
||||
|
||||
pci_no = fdtdec_get_int(gd->fdt_blob, node, "id", 0);
|
||||
pcie_v2_clock_init(pci_no);
|
||||
|
||||
return;
|
||||
|
|
@ -569,6 +624,27 @@ int set_uuid_bootargs(char *boot_args, char *part_name, int buflen, bool gpt_fla
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_IPQ9574_EDMA
|
||||
int get_sfp_gpio(int sfp_gpio[2])
|
||||
{
|
||||
int sfp_gpio_cnt = -1, node;
|
||||
int res = -1;
|
||||
|
||||
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
|
||||
if (node >= 0) {
|
||||
sfp_gpio_cnt = fdtdec_get_uint(gd->fdt_blob, node, "sfp_gpio_cnt", -1);
|
||||
if (sfp_gpio_cnt >= 1) {
|
||||
res = fdtdec_get_int_array(gd->fdt_blob, node, "sfp_gpio",
|
||||
(u32 *)sfp_gpio, sfp_gpio_cnt);
|
||||
if (res >= 0)
|
||||
return sfp_gpio_cnt;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int get_aquantia_gpio(int aquantia_gpio[2])
|
||||
{
|
||||
int aquantia_gpio_cnt = -1, node;
|
||||
|
|
@ -626,6 +702,24 @@ int get_qca807x_gpio(int qca807x_gpio[2])
|
|||
return res;
|
||||
}
|
||||
|
||||
void sfp_reset_init(void)
|
||||
{
|
||||
int sfp_gpio[2] = {-1, -1}, sfp_gpio_cnt, i;
|
||||
unsigned int *sfp_gpio_base;
|
||||
uint32_t cfg;
|
||||
|
||||
sfp_gpio_cnt = get_sfp_gpio(sfp_gpio);
|
||||
if (sfp_gpio_cnt >= 1) {
|
||||
for (i = 0; i < sfp_gpio_cnt; i++) {
|
||||
if (sfp_gpio[i] >= 0) {
|
||||
sfp_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(sfp_gpio[i]);
|
||||
cfg = GPIO_OE | GPIO_DRV_8_MA | GPIO_PULL_UP;
|
||||
writel(cfg, sfp_gpio_base);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void aquantia_phy_reset_init(void)
|
||||
{
|
||||
int aquantia_gpio[2] = {-1, -1}, aquantia_gpio_cnt, i;
|
||||
|
|
@ -923,9 +1017,6 @@ void noc_clock_init(void)
|
|||
|
||||
reg_val = readl(GCC_MEM_NOC_SNOC_AXI_CBCR);
|
||||
writel(reg_val | GCC_CBCR_CLK_ENABLE, GCC_MEM_NOC_SNOC_AXI_CBCR);
|
||||
|
||||
reg_val = readl(GCC_IMEM_AXI_CBCR);
|
||||
writel(reg_val | GCC_CBCR_CLK_ENABLE, GCC_IMEM_AXI_CBCR);
|
||||
}
|
||||
|
||||
void fixed_clock_init(void)
|
||||
|
|
@ -1049,6 +1140,7 @@ void bring_phy_out_of_reset(void)
|
|||
qca807x_phy_reset_init();
|
||||
aquantia_phy_reset_init();
|
||||
qca808x_phy_reset_init();
|
||||
sfp_reset_init();
|
||||
mdelay(500);
|
||||
qca807x_phy_reset_init_done();
|
||||
aquantia_phy_reset_init_done();
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@
|
|||
#define GCC_NSSNOC_SNOC_CBCR 0x1817028
|
||||
#define GCC_NSSNOC_SNOC_1_CBCR 0x181707C
|
||||
#define GCC_MEM_NOC_SNOC_AXI_CBCR 0x1819018
|
||||
#define GCC_IMEM_AXI_CBCR 0x180E004
|
||||
#define NSS_CC_UNIPHY_PORT1_RX_ADDR 0x39B28904
|
||||
#define NSS_CC_PPE_RESET_ADDR 0x39B28A08
|
||||
#define NSS_CC_UNIPHY_MISC_RESET 0x39B28A24
|
||||
|
|
@ -261,6 +260,23 @@ unsigned int __invoke_psci_fn_smc(unsigned int, unsigned int,
|
|||
*/
|
||||
#define EUD_EUD_EN2 0x7A000
|
||||
|
||||
/*
|
||||
* QFPROM Register for SKU Validation
|
||||
*/
|
||||
#define QFPROM_CORR_FEATURE_CONFIG_ROW1_MSB 0xA401C
|
||||
#define QFPROM_CORR_FEATURE_CONFIG_ROW2_MSB 0xA4024
|
||||
|
||||
#define PCIE_0_CLOCK_DISABLE_BIT 2
|
||||
#define PCIE_1_CLOCK_DISABLE_BIT 3
|
||||
#define PCIE_2_CLOCK_DISABLE_BIT 4
|
||||
#define PCIE_3_CLOCK_DISABLE_BIT 5
|
||||
|
||||
#define UNIPHY_0_DISABLE_BIT 23
|
||||
#define UNIPHY_1_DISABLE_BIT 24
|
||||
#define UNIPHY_2_DISABLE_BIT 25
|
||||
|
||||
int ipq_validate_qfrom_fuse(unsigned int reg_add, int pos);
|
||||
|
||||
/**
|
||||
* Number of RAM partition entries which are usable by APPS.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -941,11 +941,13 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
fal_port_duplex_t duplex;
|
||||
char *lstatus[] = {"up", "Down"};
|
||||
char *dp[] = {"Half", "Full"};
|
||||
int linkup=0;
|
||||
int linkup = 0;
|
||||
int clk[4] = {0};
|
||||
int phy_addr, node, aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1;
|
||||
int phy_addr = -1, node = -1;
|
||||
int aquantia_port[2] = {-1, -1}, aquantia_port_cnt = -1;
|
||||
int sfp_port[2] = {-1, -1}, sfp_port_cnt = -1;
|
||||
int sgmii_mode = -1, sfp_mode = -1, sgmii_fiber = -1;
|
||||
int phy_node = -1, res = -1;
|
||||
int sgmii_mode;
|
||||
|
||||
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
|
||||
|
||||
|
|
@ -956,7 +958,16 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
res = fdtdec_get_int_array(gd->fdt_blob, node, "aquantia_port",
|
||||
(u32 *)aquantia_port, aquantia_port_cnt);
|
||||
if (res < 0)
|
||||
printf("Error: Aquantia port details not provided in DT");
|
||||
printf("Error: Aquantia port details not provided in DT\n");
|
||||
}
|
||||
|
||||
sfp_port_cnt = fdtdec_get_uint(gd->fdt_blob, node, "sfp_port_cnt", -1);
|
||||
|
||||
if (sfp_port_cnt >= 1) {
|
||||
res = fdtdec_get_int_array(gd->fdt_blob, node, "sfp_port",
|
||||
(u32 *)sfp_port, sfp_port_cnt);
|
||||
if (res < 0)
|
||||
printf("Error: SFP port details not provided in DT\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -967,33 +978,68 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
* else we will return with -1;
|
||||
*/
|
||||
for (i = 0; i < IPQ9574_PHY_MAX; i++) {
|
||||
if (!priv->ops[i]) {
|
||||
printf("Phy ops not mapped\n");
|
||||
continue;
|
||||
}
|
||||
phy_get_ops = priv->ops[i];
|
||||
|
||||
if (!phy_get_ops->phy_get_link_status ||
|
||||
!phy_get_ops->phy_get_speed ||
|
||||
!phy_get_ops->phy_get_duplex) {
|
||||
printf("Error:Link status/Get speed/Get duplex not mapped\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (phy_node >= 0) {
|
||||
/*
|
||||
* For each ethernet port, one node should be added
|
||||
* inside port_phyinfo with appropriate phy address
|
||||
if (i == sfp_port[0] || i == sfp_port[1]) {
|
||||
status = phy_status_get_from_ppe(i);
|
||||
duplex = FAL_FULL_DUPLEX;
|
||||
/* SFP Port can be enabled in USXGMII0 or USXGMII1 i.e
|
||||
* SFP Port can be port5 or port6 (with port id - 4 or 5).
|
||||
* Port5 (port id - 4) -> Serdes1
|
||||
* Port6 (port id - 5) -> Serdes2
|
||||
*/
|
||||
phy_addr = phy_info[i]->phy_address;
|
||||
if (i == 4) {
|
||||
sfp_mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode1", -1);
|
||||
if (sfp_mode < 0) {
|
||||
printf("Error: switch_mac_mode1 not specified in dts\n");
|
||||
return sfp_mode;
|
||||
}
|
||||
} else if (i == 5) {
|
||||
sfp_mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode2", -1);
|
||||
if (sfp_mode < 0) {
|
||||
printf("Error: switch_mac_mode2 not specified in dts\n");
|
||||
return sfp_mode;
|
||||
}
|
||||
} else {
|
||||
printf("Error: SFP Port can be enabled in USXGMII0 or USXGMII1 (Port5 or Port6) only in ipq9574 platform\n");
|
||||
}
|
||||
if (sfp_mode == EPORT_WRAPPER_SGMII_FIBER) {
|
||||
sgmii_fiber = 1;
|
||||
curr_speed[i] = FAL_SPEED_1000;
|
||||
} else if (sfp_mode == EPORT_WRAPPER_10GBASE_R) {
|
||||
sgmii_fiber = 0;
|
||||
curr_speed[i] = FAL_SPEED_10000;
|
||||
} else {
|
||||
printf("Error: Wrong mode specified for SFP Port in DT\n");
|
||||
return sfp_mode;
|
||||
}
|
||||
} else {
|
||||
printf("Error:Phy addresses not configured in DT\n");
|
||||
return -1;
|
||||
}
|
||||
if (!priv->ops[i]) {
|
||||
printf("Phy ops not mapped\n");
|
||||
continue;
|
||||
}
|
||||
phy_get_ops = priv->ops[i];
|
||||
|
||||
status = phy_get_ops->phy_get_link_status(priv->mac_unit, phy_addr);
|
||||
phy_get_ops->phy_get_speed(priv->mac_unit, phy_addr, &curr_speed[i]);
|
||||
phy_get_ops->phy_get_duplex(priv->mac_unit, phy_addr, &duplex);
|
||||
if (!phy_get_ops->phy_get_link_status ||
|
||||
!phy_get_ops->phy_get_speed ||
|
||||
!phy_get_ops->phy_get_duplex) {
|
||||
printf("Error:Link status/Get speed/Get duplex not mapped\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (phy_node >= 0) {
|
||||
/*
|
||||
* For each ethernet port, one node should be added
|
||||
* inside port_phyinfo with appropriate phy address
|
||||
*/
|
||||
phy_addr = phy_info[i]->phy_address;
|
||||
} else {
|
||||
printf("Error:Phy addresses not configured in DT\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = phy_get_ops->phy_get_link_status(priv->mac_unit, phy_addr);
|
||||
phy_get_ops->phy_get_speed(priv->mac_unit, phy_addr, &curr_speed[i]);
|
||||
phy_get_ops->phy_get_duplex(priv->mac_unit, phy_addr, &duplex);
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
linkup++;
|
||||
|
|
@ -1092,6 +1138,11 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
clk[0] = 0x204;
|
||||
clk[2] = 0x304;
|
||||
}
|
||||
} else if (i == sfp_port[0] || i == sfp_port[1]) {
|
||||
if (i == 4) {
|
||||
clk[0] = 0x401;
|
||||
clk[2] = 0x501;
|
||||
}
|
||||
}
|
||||
if (phy_node >= 0) {
|
||||
if (phy_info[i]->phy_type == QCA8081_PHY_TYPE) {
|
||||
|
|
@ -1190,12 +1241,31 @@ static int ipq9574_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
}
|
||||
}
|
||||
|
||||
if (i == sfp_port[0] || i == sfp_port[1]) {
|
||||
if (sgmii_fiber) {
|
||||
ppe_port_bridge_txmac_set(i + 1, 1);
|
||||
if (i == 4)
|
||||
ppe_uniphy_mode_set(0x1, EPORT_WRAPPER_SGMII_FIBER);
|
||||
else
|
||||
ppe_uniphy_mode_set(0x2, EPORT_WRAPPER_SGMII_FIBER);
|
||||
ppe_port_mux_mac_type_set(i + 1, EPORT_WRAPPER_SGMII_FIBER);
|
||||
} else {
|
||||
if (i == 4)
|
||||
ppe_uniphy_mode_set(0x1, EPORT_WRAPPER_10GBASE_R);
|
||||
else
|
||||
ppe_uniphy_mode_set(0x2, EPORT_WRAPPER_10GBASE_R);
|
||||
ppe_port_mux_mac_type_set(i + 1, EPORT_WRAPPER_10GBASE_R);
|
||||
}
|
||||
}
|
||||
|
||||
ipq9574_speed_clock_set(i, clk);
|
||||
|
||||
ipq9574_port_mac_clock_reset(i);
|
||||
|
||||
if (i == aquantia_port[0] || i == aquantia_port[1])
|
||||
ipq9574_uxsgmii_speed_set(i, mac_speed, duplex, status);
|
||||
else if (i == sfp_port[0] || i == sfp_port[1])
|
||||
ipq9574_10g_r_speed_set(i, status);
|
||||
else
|
||||
ipq9574_pqsgmii_speed_set(i, mac_speed, status);
|
||||
}
|
||||
|
|
@ -1962,8 +2032,9 @@ int ipq9574_edma_init(void *edma_board_cfg)
|
|||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("\nphy chip id: 0x%x id not matching for phy id: 0x%x",
|
||||
phy_chip_id, phy_id);
|
||||
if (phy_info[phy_id]->phy_type != SFP_PHY_TYPE)
|
||||
printf("\nphy chip id: 0x%x id not matching for phy id: 0x%x",
|
||||
phy_chip_id, phy_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ DECLARE_GLOBAL_DATA_PTR;
|
|||
|
||||
#define pr_info(fmt, args...) printf(fmt, ##args);
|
||||
|
||||
extern int is_uniphy_enabled(int uniphy_index);
|
||||
extern void uniphy_port5_clock_source_set(void);
|
||||
|
||||
/*
|
||||
|
|
@ -857,10 +858,12 @@ void ipq9574_ppe_interface_mode_init(void)
|
|||
if (mode1 == EPORT_WRAPPER_MAX) {
|
||||
ppe_port_mux_mac_type_set(PORT5, mode0);
|
||||
uniphy_port5_clock_source_set();
|
||||
} else {
|
||||
} else if (is_uniphy_enabled(PPE_UNIPHY_INSTANCE1)) {
|
||||
ppe_port_mux_mac_type_set(PORT5, mode1);
|
||||
}
|
||||
ppe_port_mux_mac_type_set(PORT6, mode2);
|
||||
if (is_uniphy_enabled(PPE_UNIPHY_INSTANCE2)) {
|
||||
ppe_port_mux_mac_type_set(PORT6, mode2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ union ipo_action_u {
|
|||
#define IPQ9574_PORT_MUX_CTRL_DEFAULT 0x0
|
||||
|
||||
#define PORT_PHY_STATUS_ADDRESS 0x44
|
||||
#define PORT_PHY_STATUS_PORT5_1_OFFSET 16
|
||||
#define PORT_PHY_STATUS_PORT5_1_OFFSET 8
|
||||
#define PORT_PHY_STATUS_PORT6_OFFSET 16
|
||||
|
||||
#define IPQ9574_PPE_IPE_L3_BASE_ADDR 0x200000
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#include <fdtdec.h>
|
||||
#include "ipq_phy.h"
|
||||
|
||||
extern int is_uniphy_enabled(int uniphy_index);
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
extern int ipq_mdio_write(int mii_id,
|
||||
int regnum, u16 value);
|
||||
|
|
@ -436,6 +438,11 @@ static void ppe_uniphy_usxgmii_mode_set(uint32_t uniphy_index)
|
|||
|
||||
void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode)
|
||||
{
|
||||
if (!is_uniphy_enabled(uniphy_index)) {
|
||||
printf("Uniphy %u is disabled\n", uniphy_index);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(mode) {
|
||||
case EPORT_WRAPPER_PSGMII:
|
||||
ppe_uniphy_psgmii_mode_set(uniphy_index);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue