mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2025-12-10 07:44:53 +01:00
drivers: net: ipq6018: enable qca8x8x switch support
This patch enables qca8x8x switch support on ipq6018.
Change-Id: I5e037071dad112558682255f99bac2adb2b411b5
Signed-off-by: Ram Kumar D <quic_ramd@quicinc.com>
(cherry picked from commit c2c5de2497)
This commit is contained in:
parent
b3e02bf4d0
commit
199fa1dfb6
3 changed files with 123 additions and 2 deletions
|
|
@ -46,6 +46,7 @@ static struct ipq6018_eth_dev *ipq6018_edma_dev[IPQ6018_EDMA_DEV];
|
|||
|
||||
uchar ipq6018_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
|
||||
phy_info_t *phy_info[IPQ6018_PHY_MAX] = {0};
|
||||
phy_info_t *swt_info[QCA8084_MAX_PORTS] = {0};
|
||||
int sgmii_mode[2] = {0};
|
||||
|
||||
extern void qca8075_ess_reset(void);
|
||||
|
|
@ -65,6 +66,16 @@ extern int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id);
|
|||
extern int ipq_board_fw_download(unsigned int phy_addr);
|
||||
static int tftp_acl_our_port;
|
||||
|
||||
#ifdef CONFIG_QCA8084_SWT_MODE
|
||||
extern int ipq_qca8084_hw_init(phy_info_t * phy_info[]);
|
||||
extern void ipq_phy_addr_fixup(void);
|
||||
extern void ipq_clock_init(void);
|
||||
extern int ipq_qca8084_link_update(phy_info_t * phy_info[]);
|
||||
extern void ipq_qca8084_switch_hw_reset(int gpio);
|
||||
|
||||
static int qca8084_swt_port = -1;
|
||||
#endif /* CONFIG_QCA8084_SWT_MODE */
|
||||
|
||||
/*
|
||||
* EDMA hardware instance
|
||||
*/
|
||||
|
|
@ -988,6 +999,9 @@ static int ipq6018_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
continue;
|
||||
}
|
||||
|
||||
if(phy_info[i]->phy_type == UNUSED_PHY_TYPE)
|
||||
continue;
|
||||
|
||||
if (i == sfp_port) {
|
||||
status = phy_status_get_from_ppe(i);
|
||||
duplex = FAL_FULL_DUPLEX;
|
||||
|
|
@ -1007,6 +1021,12 @@ static int ipq6018_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
printf("\nError: wrong mode specified for SFP Port");
|
||||
return sfp_mode;
|
||||
}
|
||||
#ifdef CONFIG_QCA8084_SWT_MODE
|
||||
} else if ((qca8084_swt_port == i)&& (phy_info[i]->phy_type == QCA8084_PHY_TYPE)) {
|
||||
if (!ipq_qca8084_link_update(swt_info))
|
||||
linkup++;
|
||||
continue;
|
||||
#endif /* CONFIG_QCA8084_SWT_MODE */
|
||||
} else {
|
||||
if (!priv->ops[i]) {
|
||||
printf ("Phy ops not mapped\n");
|
||||
|
|
@ -1710,6 +1730,36 @@ void get_phy_address(int offset)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QCA8084_SWT_MODE
|
||||
void get_phy_qca8084_address(int offset)
|
||||
{
|
||||
int phy_type;
|
||||
int phy_address;
|
||||
int forced_speed, forced_duplex;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < QCA8084_MAX_PORTS; i++)
|
||||
swt_info[i] = ipq6018_alloc_mem(sizeof(phy_info_t));
|
||||
i = 0;
|
||||
for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0;
|
||||
offset = fdt_next_subnode(gd->fdt_blob, offset)) {
|
||||
|
||||
phy_address = fdtdec_get_uint(gd->fdt_blob,
|
||||
offset, "phy_address", 0);
|
||||
phy_type = fdtdec_get_uint(gd->fdt_blob,
|
||||
offset, "phy_type", 0);
|
||||
forced_speed = fdtdec_get_uint(gd->fdt_blob,
|
||||
offset, "forced-speed", 0);
|
||||
forced_duplex = fdtdec_get_uint(gd->fdt_blob,
|
||||
offset, "forced-duplex", 0);
|
||||
swt_info[i]->phy_address = phy_address;
|
||||
swt_info[i]->forced_speed = forced_speed;
|
||||
swt_info[i]->forced_duplex = forced_duplex;
|
||||
swt_info[i++]->phy_type = phy_type;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int ipq6018_edma_init(void *edma_board_cfg)
|
||||
{
|
||||
struct eth_device *dev[IPQ6018_EDMA_DEV];
|
||||
|
|
@ -1723,6 +1773,12 @@ int ipq6018_edma_init(void *edma_board_cfg)
|
|||
static int sw_init_done = 0;
|
||||
int port_8033 = -1, node, phy_addr, aquantia_port = -1;
|
||||
int mode, phy_node = -1;
|
||||
#ifdef CONFIG_QCA8084_SWT_MODE
|
||||
static int qca8084_init_done = 0;
|
||||
int phy_type = 0;
|
||||
int qca8084_gpio = 0;
|
||||
int swt_node = -1;
|
||||
#endif /* CONFIG_QCA8084_SWT_MODE */
|
||||
|
||||
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
|
||||
if (node >= 0)
|
||||
|
|
@ -1731,6 +1787,19 @@ int ipq6018_edma_init(void *edma_board_cfg)
|
|||
if (node >= 0)
|
||||
aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port", -1);
|
||||
|
||||
#ifdef CONFIG_QCA8084_SWT_MODE
|
||||
qca8084_swt_port = fdtdec_get_uint(gd->fdt_blob, node, "qca8084_swt_port", -1);
|
||||
qca8084_gpio = fdtdec_get_uint(gd->fdt_blob, node, "qca808x_gpio", 0);
|
||||
if (qca8084_swt_port != -1) {
|
||||
if (qca8084_gpio)
|
||||
ipq_qca8084_switch_hw_reset(qca8084_gpio);
|
||||
}
|
||||
|
||||
swt_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/qca8084_swt_info");
|
||||
if (swt_node >= 0)
|
||||
get_phy_qca8084_address(swt_node);
|
||||
#endif
|
||||
|
||||
phy_node = fdt_path_offset(gd->fdt_blob, "/ess-switch/port_phyinfo");
|
||||
if (phy_node >= 0)
|
||||
get_phy_address(phy_node);
|
||||
|
|
@ -1821,8 +1890,14 @@ int ipq6018_edma_init(void *edma_board_cfg)
|
|||
goto init_failed;
|
||||
|
||||
for (phy_id = 0; phy_id < IPQ6018_PHY_MAX; phy_id++) {
|
||||
if(phy_info[phy_id]->phy_type == UNUSED_PHY_TYPE)
|
||||
continue;
|
||||
|
||||
if (phy_node >= 0) {
|
||||
phy_addr = phy_info[phy_id]->phy_address;
|
||||
#ifdef CONFIG_QCA8084_SWT_MODE
|
||||
phy_type = phy_info[phy_id]->phy_type;
|
||||
#endif
|
||||
} else {
|
||||
if (phy_id == port_8033)
|
||||
phy_addr = QCA8033_PHY_ADDR;
|
||||
|
|
@ -1832,6 +1907,18 @@ int ipq6018_edma_init(void *edma_board_cfg)
|
|||
phy_addr = phy_id;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_QCA8084_PHY
|
||||
if (phy_type == QCA8084_PHY_TYPE) {
|
||||
if ((qca8084_swt_port == phy_id) ||
|
||||
!qca8084_init_done) {
|
||||
ipq_phy_addr_fixup();
|
||||
ipq_clock_init();
|
||||
if (qca8084_swt_port != phy_id)
|
||||
qca8084_init_done = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
phy_chip_id1 = ipq_mdio_read(phy_addr, QCA_PHY_ID1, NULL);
|
||||
phy_chip_id2 = ipq_mdio_read(phy_addr, QCA_PHY_ID2, NULL);
|
||||
phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;
|
||||
|
|
@ -1840,6 +1927,7 @@ int ipq6018_edma_init(void *edma_board_cfg)
|
|||
phy_chip_id2 = ipq_mdio_read(phy_addr, (1<<30) |(1<<16) | QCA_PHY_ID2, NULL);
|
||||
phy_chip_id = (phy_chip_id1 << 16) | phy_chip_id2;
|
||||
}
|
||||
|
||||
switch(phy_chip_id) {
|
||||
case QCA8075_PHY_V1_0_5P:
|
||||
case QCA8075_PHY_V1_1_5P:
|
||||
|
|
@ -1879,6 +1967,10 @@ int ipq6018_edma_init(void *edma_board_cfg)
|
|||
ipq_board_fw_download(phy_addr);
|
||||
ipq_qca_aquantia_phy_init(&ipq6018_edma_dev[i]->ops[phy_id], phy_addr);
|
||||
break;
|
||||
#endif
|
||||
#ifdef CONFIG_QCA8084_PHY_MODE
|
||||
case QCA8084_PHY:
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ipq_qca8075_phy_map_ops(&ipq6018_edma_dev[i]->ops[phy_id]);
|
||||
|
|
@ -1891,6 +1983,23 @@ int ipq6018_edma_init(void *edma_board_cfg)
|
|||
if (ret)
|
||||
goto init_failed;
|
||||
|
||||
#ifdef CONFIG_QCA8084_SWT_MODE
|
||||
/** QCA8084 switch specific configurations */
|
||||
if (qca8084_swt_port != -1) {
|
||||
/** Force speed alder 1st port for QCA8084 switch mode */
|
||||
ipq6018_speed_clock_set(qca8084_swt_port, 0x100, 0x0);
|
||||
|
||||
/** Force Link-speed: 1000M
|
||||
* Force Link-status: enable */
|
||||
ipq6018_pqsgmii_speed_set(qca8084_swt_port, 0x2, 0x0);
|
||||
|
||||
ret = ipq_qca8084_hw_init(swt_info);
|
||||
if (ret < 0) {
|
||||
printf("Error: ipq_qca8084_hw_init failed \n");
|
||||
qca8084_swt_port = -1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
eth_register(dev[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,8 +130,15 @@ static void ppe_uniphy_qsgmii_mode_set(uint32_t uniphy_index)
|
|||
|
||||
static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t mode)
|
||||
{
|
||||
writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_MISC2_REG_OFFSET);
|
||||
if (mode == PORT_WRAPPER_SGMII_PLUS) {
|
||||
writel(UNIPHY_MISC2_REG_SGMII_PLUS_MODE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) +
|
||||
UNIPHY_MISC2_REG_OFFSET);
|
||||
} else {
|
||||
writel(UNIPHY_MISC2_REG_SGMII_MODE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) +
|
||||
UNIPHY_MISC2_REG_OFFSET);
|
||||
}
|
||||
|
||||
writel(UNIPHY_PLL_RESET_REG_VALUE, PPE_UNIPHY_BASE +
|
||||
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
|
||||
|
|
|
|||
|
|
@ -28,4 +28,9 @@
|
|||
#define MALIBU_PHY_TYPE 0x1
|
||||
#define QCA8081_PHY_TYPE 0x2
|
||||
#define AQ_PHY_TYPE 0x3
|
||||
#define QCA8084_PHY_TYPE 0x6
|
||||
#define UNUSED_PHY_TYPE 0xFF
|
||||
|
||||
/* QCA8x8x internal PHY mode type */
|
||||
#define EPORT_WRAPPER_SGMII_PLUS 0xc
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue