mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-03-03 16:04:47 +01:00
ipq807x: Add the multiple phy support
Change-Id: I8d22e267ccad0f8f14532e46f379e45faf32bad5 Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
This commit is contained in:
parent
11d70f9af5
commit
6a012e63d6
6 changed files with 81 additions and 64 deletions
|
|
@ -40,7 +40,6 @@ extern loff_t board_env_size;
|
|||
|
||||
extern int ipq_spi_init(u16);
|
||||
extern int ipq807x_edma_init(void *cfg);
|
||||
extern int ipq_qca8075_phy_init(struct phy_ops **ops);
|
||||
|
||||
const char *rsvd_node = "/reserved-memory";
|
||||
const char *del_node[] = {"uboot",
|
||||
|
|
@ -231,8 +230,6 @@ int board_eth_init(bd_t *bis)
|
|||
int ret=0;
|
||||
int tlmm_base = 0x1025000;
|
||||
|
||||
ipq807x_register_switch(ipq_qca8075_phy_init);
|
||||
|
||||
/*
|
||||
* ethernet clk rcgr block init -- start
|
||||
* these clk init will be moved to sbl later
|
||||
|
|
|
|||
|
|
@ -43,17 +43,15 @@ static struct ipq807x_eth_dev *ipq807x_edma_dev[IPQ807X_EDMA_DEV];
|
|||
|
||||
uchar ipq807x_def_enetaddr[6] = {0x00, 0x03, 0x7F, 0xBA, 0xDB, 0xAD};
|
||||
|
||||
static int (*ipq807x_switch_init)(struct phy_ops **ops);
|
||||
extern void qca8075_ess_reset(void);
|
||||
extern void psgmii_self_test(void);
|
||||
extern void clear_self_test_config(void);
|
||||
extern int ipq_sw_mdio_init(const char *);
|
||||
extern void ipq_qca8075_dump_phy_regs(u32);
|
||||
|
||||
void ipq807x_register_switch(int(*sw_init)(struct phy_ops **ops))
|
||||
{
|
||||
ipq807x_switch_init = sw_init;
|
||||
}
|
||||
extern int ipq_mdio_read(int mii_id,
|
||||
int regnum, ushort *data);
|
||||
extern void ipq_qca8075_phy_map_ops(struct phy_ops **ops);
|
||||
extern int ipq_qca8075_phy_init(struct phy_ops **ops);
|
||||
|
||||
/*
|
||||
* EDMA hardware instance
|
||||
|
|
@ -868,20 +866,7 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
char *lstatus[] = {"up", "Down"};
|
||||
char *dp[] = {"Half", "Full"};
|
||||
int linkup=0;
|
||||
int mac_speed = 0, speed_clock1 = 0, speed_clock2 = 0;
|
||||
if (!priv->ops) {
|
||||
printf ("Phy ops not mapped\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
phy_get_ops = priv->ops;
|
||||
|
||||
if (!phy_get_ops->phy_get_link_status ||
|
||||
!phy_get_ops->phy_get_speed ||
|
||||
!phy_get_ops->phy_get_duplex) {
|
||||
printf ("Link status/Get speed/Get duplex not mapped\n");
|
||||
return -1;
|
||||
}
|
||||
int mac_speed, speed_clock1, speed_clock2;
|
||||
|
||||
/*
|
||||
* Check PHY link, speed, Duplex on all phys.
|
||||
|
|
@ -889,39 +874,52 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
* else we will return with -1;
|
||||
*/
|
||||
for (i = 0; i < PHY_MAX; i++) {
|
||||
if (!priv->ops[i]) {
|
||||
printf ("Phy ops not mapped\n");
|
||||
return -1;
|
||||
}
|
||||
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 ("Link status/Get speed/Get duplex not mapped\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
status = phy_get_ops->phy_get_link_status(priv->mac_unit, i);
|
||||
if (status == 0)
|
||||
linkup++;
|
||||
phy_get_ops->phy_get_speed(priv->mac_unit, i, &speed);
|
||||
phy_get_ops->phy_get_duplex(priv->mac_unit, i, &duplex);
|
||||
switch (speed) {
|
||||
case FAL_SPEED_10:
|
||||
mac_speed = 0x0;
|
||||
speed_clock1 = 0x109;
|
||||
speed_clock2 = 0x9;
|
||||
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], speed,
|
||||
dp[duplex]);
|
||||
break;
|
||||
case FAL_SPEED_100:
|
||||
mac_speed = 0x1;
|
||||
speed_clock1 = 0x101;
|
||||
speed_clock2 = 0x4;
|
||||
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], speed,
|
||||
dp[duplex]);
|
||||
break;
|
||||
case FAL_SPEED_1000:
|
||||
mac_speed = 0x2;
|
||||
speed_clock1 = 0x101;
|
||||
speed_clock2 = 0x0;
|
||||
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], speed,
|
||||
dp[duplex]);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown speed\n");
|
||||
break;
|
||||
case FAL_SPEED_10:
|
||||
mac_speed = 0x0;
|
||||
speed_clock1 = 0x109;
|
||||
speed_clock2 = 0x9;
|
||||
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], speed,
|
||||
dp[duplex]);
|
||||
break;
|
||||
case FAL_SPEED_100:
|
||||
mac_speed = 0x1;
|
||||
speed_clock1 = 0x101;
|
||||
speed_clock2 = 0x4;
|
||||
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], speed,
|
||||
dp[duplex]);
|
||||
break;
|
||||
case FAL_SPEED_1000:
|
||||
mac_speed = 0x2;
|
||||
speed_clock1 = 0x101;
|
||||
speed_clock2 = 0x0;
|
||||
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], speed,
|
||||
dp[duplex]);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown speed\n");
|
||||
break;
|
||||
}
|
||||
ipq807x_pqsgmii_speed_clock_set(i, mac_speed, speed_clock1, speed_clock2);
|
||||
}
|
||||
|
|
@ -1536,12 +1534,12 @@ int ipq807x_edma_init(void *edma_board_cfg)
|
|||
struct ipq807x_edma_common_info *c_info[IPQ807X_EDMA_DEV];
|
||||
struct ipq807x_edma_hw *hw[IPQ807X_EDMA_DEV];
|
||||
uchar enet_addr[IPQ807X_EDMA_DEV * 6];
|
||||
int i;
|
||||
int i, phy_id;
|
||||
uint32_t phy_chip_id, phy_chip_id1, phy_chip_id2;
|
||||
int ret = -1;
|
||||
ipq807x_edma_board_cfg_t ledma_cfg, *edma_cfg;
|
||||
static int sw_init_done = 0;
|
||||
|
||||
|
||||
memset(c_info, 0, (sizeof(c_info) * IPQ807X_EDMA_DEV));
|
||||
memset(enet_addr, 0, sizeof(enet_addr));
|
||||
memset(&ledma_cfg, 0, sizeof(ledma_cfg));
|
||||
|
|
@ -1621,13 +1619,27 @@ int ipq807x_edma_init(void *edma_board_cfg)
|
|||
if (ret)
|
||||
goto init_failed;
|
||||
|
||||
for (phy_id = 0; phy_id < PHY_MAX; phy_id++) {
|
||||
|
||||
if (!sw_init_done) {
|
||||
if (ipq807x_switch_init(&ipq807x_edma_dev[i]->ops) == 0) {
|
||||
sw_init_done = 1;
|
||||
} else {
|
||||
printf ("SW inits failed\n");
|
||||
goto init_failed;
|
||||
phy_chip_id1 = ipq_mdio_read(phy_id, QCA_PHY_ID1, NULL);
|
||||
phy_chip_id2 = ipq_mdio_read(phy_id, 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:
|
||||
case QCA8075_PHY_V1_1_2P:
|
||||
|
||||
if (!sw_init_done) {
|
||||
if (ipq_qca8075_phy_init(&ipq807x_edma_dev[i]->ops[phy_id]) == 0) {
|
||||
sw_init_done = 1;
|
||||
}
|
||||
} else {
|
||||
ipq_qca8075_phy_map_ops(&ipq807x_edma_dev[i]->ops[phy_id]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ipq_qca8075_phy_map_ops(&ipq807x_edma_dev[i]->ops[phy_id]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -251,6 +251,7 @@ struct ipq807x_edma_common_info {
|
|||
struct ipq807x_edma_hw hw;
|
||||
};
|
||||
|
||||
#define MAX_PHY 6
|
||||
struct ipq807x_eth_dev {
|
||||
u8 *phy_address;
|
||||
uint no_of_phys;
|
||||
|
|
@ -264,7 +265,7 @@ struct ipq807x_eth_dev {
|
|||
u32 padding;
|
||||
struct eth_device *dev;
|
||||
struct ipq807x_edma_common_info *c_info;
|
||||
struct phy_ops *ops;
|
||||
struct phy_ops *ops[MAX_PHY];
|
||||
const char phy_name[MDIO_NAME_LEN];
|
||||
} __attribute__ ((aligned(8)));
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,12 @@
|
|||
#define GP_PU_RES(x) (x << 13)
|
||||
#define QCA8075_RST_VAL (GP_PULL_DOWN | GP_OE_EN | \
|
||||
GP_VM_EN | GP_PU_RES(2))
|
||||
#define QCA8075_PHY_V1_0_5P 0x004DD0B0
|
||||
#define QCA8075_PHY_V1_1_5P 0x004DD0B1
|
||||
#define QCA8075_PHY_V1_1_2P 0x004DD0B2
|
||||
#define QCA_PHY_ID1 0x2
|
||||
#define QCA_PHY_ID2 0x3
|
||||
|
||||
|
||||
/* Phy preferred medium type */
|
||||
typedef enum {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ extern int ipq_mdio_write(int mii_id,
|
|||
extern int ipq_mdio_read(int mii_id,
|
||||
int regnum, ushort *data);
|
||||
|
||||
struct phy_ops *qca8075_ops;
|
||||
static u32 qca8075_id;
|
||||
static u16 qca8075_phy_reg_write(u32 dev_id, u32 phy_id,
|
||||
u32 reg_id, u16 reg_val)
|
||||
|
|
@ -728,11 +729,15 @@ void ipq_qca8075_dump_phy_regs(u32 phy_id)
|
|||
#undef REG_LEN
|
||||
}
|
||||
|
||||
void ipq_qca8075_phy_map_ops(struct phy_ops **ops)
|
||||
{
|
||||
*ops = qca8075_ops;
|
||||
}
|
||||
|
||||
int ipq_qca8075_phy_init(struct phy_ops **ops)
|
||||
{
|
||||
u16 phy_data;
|
||||
u32 phy_id = 0;
|
||||
struct phy_ops *qca8075_ops;
|
||||
|
||||
qca8075_ops = (struct phy_ops *)malloc(sizeof(struct phy_ops));
|
||||
if (!qca8075_ops)
|
||||
|
|
|
|||
|
|
@ -14,10 +14,6 @@
|
|||
#ifndef _QCA8075_PHY_H_
|
||||
#define _QCA8075_PHY_H_
|
||||
|
||||
#define QCA8075_PHY_V1_0_5P 0x004DD0B0
|
||||
#define QCA8075_PHY_V1_1_5P 0x004DD0B1
|
||||
#define QCA8075_PHY_V1_1_2P 0x004DD0B2
|
||||
|
||||
#define QCA8075_PHY_CONTROL 0
|
||||
#define QCA8075_PHY_STATUS 1
|
||||
#define QCA8075_PHY_ID1 2
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue