mirror of
https://git.codelinaro.org/clo/qsdk/oss/boot/u-boot-2016.git
synced 2026-03-14 21:10:27 +01:00
ipq807x: Added the USXMII speed and clock
Change-Id: Ieb3e01eef27807091e0a1670d6b7c25334bed396 Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
This commit is contained in:
parent
92f52b796e
commit
b89040defa
6 changed files with 277 additions and 7 deletions
|
|
@ -872,11 +872,14 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
char *dp[] = {"Half", "Full"};
|
||||
int linkup=0;
|
||||
int mac_speed, speed_clock1, speed_clock2;
|
||||
int phy_addr, port_8033 = -1, node;
|
||||
int phy_addr, port_8033 = -1, node, aquantia_port = -1;
|
||||
|
||||
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
|
||||
if (node >= 0)
|
||||
port_8033 = fdtdec_get_uint(gd->fdt_blob, node, "8033_port", -1);
|
||||
|
||||
if (node >= 0)
|
||||
aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port", -1);
|
||||
/*
|
||||
* Check PHY link, speed, Duplex on all phys.
|
||||
* we will proceed even if single link is up
|
||||
|
|
@ -898,6 +901,8 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
|
||||
if (i == port_8033)
|
||||
phy_addr = QCA8033_PHY_ADDR;
|
||||
else if (i == aquantia_port)
|
||||
phy_addr = AQU_PHY_ADDR;
|
||||
else
|
||||
phy_addr = i;
|
||||
|
||||
|
|
@ -908,6 +913,10 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
phy_get_ops->phy_get_duplex(priv->mac_unit, phy_addr, &duplex);
|
||||
switch (speed) {
|
||||
case FAL_SPEED_10:
|
||||
if (i == aquantia_port) {
|
||||
printf("10M speed not supported\n");
|
||||
continue;
|
||||
}
|
||||
mac_speed = 0x0;
|
||||
speed_clock1 = 0x109;
|
||||
speed_clock2 = 0x9;
|
||||
|
|
@ -917,7 +926,10 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
break;
|
||||
case FAL_SPEED_100:
|
||||
mac_speed = 0x1;
|
||||
speed_clock1 = 0x101;
|
||||
if (i == aquantia_port)
|
||||
speed_clock1 = 0x109;
|
||||
else
|
||||
speed_clock1 = 0x101;
|
||||
speed_clock2 = 0x4;
|
||||
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], speed,
|
||||
|
|
@ -925,17 +937,48 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
|
|||
break;
|
||||
case FAL_SPEED_1000:
|
||||
mac_speed = 0x2;
|
||||
if (i == aquantia_port)
|
||||
speed_clock1 = 0x104;
|
||||
else
|
||||
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;
|
||||
case FAL_SPEED_10000:
|
||||
mac_speed = 0x3;
|
||||
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;
|
||||
case FAL_SPEED_2500:
|
||||
mac_speed = 0x4;
|
||||
speed_clock1 = 0x107;
|
||||
speed_clock2 = 0x0;
|
||||
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
|
||||
priv->mac_unit, i, lstatus[status], speed,
|
||||
dp[duplex]);
|
||||
break;
|
||||
case FAL_SPEED_5000:
|
||||
mac_speed = 0x5;
|
||||
speed_clock1 = 0x103;
|
||||
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);
|
||||
ipq807x_speed_clock_set(i, speed_clock1, speed_clock2);
|
||||
if (i == aquantia_port)
|
||||
ipq807x_uxsgmii_speed_set(i, mac_speed, duplex);
|
||||
else
|
||||
ipq807x_pqsgmii_speed_set(i, mac_speed);
|
||||
}
|
||||
|
||||
if (linkup <= 0) {
|
||||
|
|
|
|||
|
|
@ -307,6 +307,8 @@ typedef struct {
|
|||
} ipq807x_edma_board_cfg_t;
|
||||
|
||||
extern void ipq807x_ppe_provision_init(void);
|
||||
extern void ipq807x_pqsgmii_speed_clock_set(int port, int speed, int speed_clock1, int speed_clock2);
|
||||
extern void ipq807x_speed_clock_set(int port, int speed_clock1, int speed_clock2);
|
||||
extern void ipq807x_pqsgmii_speed_set(int port, int speed);
|
||||
extern void ipq807x_uxsgmii_speed_set(int port, int speed, int duplex);
|
||||
|
||||
#endif /* ___IPQ807X_EDMA__ */
|
||||
|
|
|
|||
|
|
@ -106,11 +106,12 @@ static void ipq807x_gmac_enable(void)
|
|||
*/
|
||||
static void ipq807x_gmac_port_enable(int port)
|
||||
{
|
||||
ipq807x_ppe_reg_write(IPQ807X_PPE_MAC_ENABLE + (0x200 * port), 0x13);
|
||||
ipq807x_ppe_reg_write(IPQ807X_PPE_MAC_ENABLE + (0x200 * port), 0x70);
|
||||
ipq807x_ppe_reg_write(IPQ807X_PPE_MAC_SPEED + (0x200 * port), 0x2);
|
||||
ipq807x_ppe_reg_write(IPQ807X_PPE_MAC_MIB_CTL + (0x200 * port), 0x1);
|
||||
}
|
||||
void ipq807x_pqsgmii_speed_clock_set(int port, int speed, int speed_clock1, int speed_clock2)
|
||||
|
||||
void ipq807x_speed_clock_set(int port, int speed_clock1, int speed_clock2)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -120,9 +121,122 @@ void ipq807x_pqsgmii_speed_clock_set(int port, int speed, int speed_clock1, int
|
|||
writel(speed_clock1, GCC_NSS_PORT1_RX_CFG_RCGR + i*8 + port*0x10);
|
||||
writel(0x1, GCC_NSS_PORT1_RX_CMD_RCGR + i*8 + port*0x10);
|
||||
}
|
||||
ipq807x_ppe_reg_write(IPQ807X_PPE_MAC_SPEED + (0x200 * port), speed);
|
||||
}
|
||||
|
||||
void ipq807x_pqsgmii_speed_set(int port, int speed)
|
||||
{
|
||||
ipq807x_ppe_reg_write(IPQ807X_PPE_MAC_SPEED + (0x200 * port), speed);
|
||||
ipq807x_ppe_reg_write(IPQ807X_PPE_MAC_ENABLE + (0x200 * port), 0x73);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ppe_xgmac_speed_set(uint32_t uniphy_index, int speed)
|
||||
{
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
ipq807x_ppe_reg_read(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
|
||||
(uniphy_index * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), ®_value);
|
||||
|
||||
switch(speed) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
reg_value &=~USS;
|
||||
reg_value |=SS(XGMAC_SPEED_SELECT_1000M);
|
||||
break;
|
||||
case 3:
|
||||
reg_value |=USS;
|
||||
reg_value |=SS(XGMAC_SPEED_SELECT_10000M);
|
||||
break;
|
||||
case 4:
|
||||
reg_value |=USS;
|
||||
reg_value |=SS(XGMAC_SPEED_SELECT_2500M);
|
||||
break;
|
||||
case 5:
|
||||
reg_value |=USS;
|
||||
reg_value |=SS(XGMAC_SPEED_SELECT_5000M);
|
||||
break;
|
||||
}
|
||||
reg_value |=JD;
|
||||
ipq807x_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
|
||||
(uniphy_index * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value);
|
||||
|
||||
}
|
||||
|
||||
void ppe_port_bridge_txmac_set(int port_id)
|
||||
{
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
ipq807x_ppe_reg_read(IPE_L2_BASE_ADDR + PORT_BRIDGE_CTRL_ADDRESS +
|
||||
(port_id * PORT_BRIDGE_CTRL_INC), ®_value);
|
||||
reg_value |= TX_MAC_EN;
|
||||
ipq807x_ppe_reg_write(IPE_L2_BASE_ADDR + PORT_BRIDGE_CTRL_ADDRESS +
|
||||
(port_id * PORT_BRIDGE_CTRL_INC), reg_value);
|
||||
|
||||
}
|
||||
|
||||
void ppe_port_txmac_status_set(uint32_t uniphy_index)
|
||||
{
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
ipq807x_ppe_reg_read(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
|
||||
(uniphy_index * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), ®_value);
|
||||
|
||||
reg_value |=TE;
|
||||
ipq807x_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
|
||||
(uniphy_index * NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION), reg_value);
|
||||
|
||||
}
|
||||
|
||||
void ppe_port_rxmac_status_set(uint32_t uniphy_index)
|
||||
{
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
ipq807x_ppe_reg_read(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
|
||||
NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION +
|
||||
(uniphy_index * MAC_RX_CONFIGURATION_ADDRESS), ®_value);
|
||||
|
||||
reg_value |= 0x5ee00c0;
|
||||
reg_value |=RE;
|
||||
reg_value |=ACS;
|
||||
reg_value |=CST;
|
||||
ipq807x_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
|
||||
NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION +
|
||||
(uniphy_index * MAC_RX_CONFIGURATION_ADDRESS), reg_value);
|
||||
|
||||
}
|
||||
|
||||
void ppe_mac_packet_filter_set(uint32_t uniphy_index)
|
||||
{
|
||||
ipq807x_ppe_reg_write(PPE_SWITCH_NSS_SWITCH_XGMAC0 +
|
||||
MAC_PACKET_FILTER_ADDRESS +
|
||||
(uniphy_index * MAC_PACKET_FILTER_INC), 0x81);
|
||||
}
|
||||
|
||||
void ipq807x_uxsgmii_speed_set(int port, int speed, int duplex,
|
||||
int speed_clock1, int speed_clock2)
|
||||
{
|
||||
uint32_t uniphy_index;
|
||||
|
||||
/* Setting the speed only for PORT5 and PORT6 */
|
||||
if (port == (PORT5 - PPE_UNIPHY_INSTANCE1))
|
||||
uniphy_index = PPE_UNIPHY_INSTANCE1;
|
||||
if (port == (PORT6 - PPE_UNIPHY_INSTANCE1))
|
||||
uniphy_index = PPE_UNIPHY_INSTANCE2;
|
||||
else
|
||||
return;
|
||||
|
||||
ppe_uniphy_usxgmii_autoneg_completed(uniphy_index);
|
||||
ppe_uniphy_usxgmii_speed_set(uniphy_index, speed);
|
||||
ppe_xgmac_speed_set(uniphy_index - 1, speed);
|
||||
ppe_uniphy_usxgmii_duplex_set(uniphy_index, duplex);
|
||||
ppe_uniphy_usxgmii_port_reset(uniphy_index);
|
||||
ppe_port_bridge_txmac_set(port + 1);
|
||||
ppe_port_txmac_status_set(uniphy_index - 1);
|
||||
ppe_port_rxmac_status_set(uniphy_index - 1);
|
||||
ppe_mac_packet_filter_set(uniphy_index - 1);
|
||||
}
|
||||
/*
|
||||
* ipq807x_ppe_flow_port_map_tbl_port_num_set()
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -156,4 +156,27 @@ union port_mux_ctrl_u {
|
|||
#define IPQ807X_PPE_PORT_XGMAC2_BITPOS (1 << IPQ807X_PPE_PORT_XGMAC2)
|
||||
#define IPQ807X_PPE_PORT_CRYPTO1_BITPOS (1 << IPQ807X_PPE_PORT_CRYPTO1)
|
||||
|
||||
#define PPE_SWITCH_NSS_SWITCH_XGMAC0 0x3000
|
||||
#define NSS_SWITCH_XGMAC_MAC_TX_CONFIGURATION 0x4000
|
||||
#define USS (1 << 31)
|
||||
#define SS(i) (i << 29)
|
||||
#define JD (1 << 16)
|
||||
#define TE (1 << 0)
|
||||
#define NSS_SWITCH_XGMAC_MAC_RX_CONFIGURATION 0x4000
|
||||
#define MAC_RX_CONFIGURATION_ADDRESS 0x4
|
||||
#define RE (1 << 0)
|
||||
#define ACS (1 << 1)
|
||||
#define CST (1 << 2)
|
||||
#define MAC_PACKET_FILTER_INC 0x4000
|
||||
#define MAC_PACKET_FILTER_ADDRESS 0x8
|
||||
|
||||
#define XGMAC_SPEED_SELECT_10000M 0
|
||||
#define XGMAC_SPEED_SELECT_5000M 1
|
||||
#define XGMAC_SPEED_SELECT_2500M 2
|
||||
#define XGMAC_SPEED_SELECT_1000M 3
|
||||
|
||||
#define IPE_L2_BASE_ADDR 0x060000
|
||||
#define PORT_BRIDGE_CTRL_ADDRESS 0x300
|
||||
#define PORT_BRIDGE_CTRL_INC 0x4
|
||||
#define TX_MAC_EN (1 << 16)
|
||||
|
||||
|
|
|
|||
|
|
@ -193,3 +193,87 @@ void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ppe_uniphy_usxgmii_autoneg_completed(uint32_t uniphy_index)
|
||||
{
|
||||
uint32_t autoneg_complete = 0, retries = 100;
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
while (autoneg_complete != 0x1) {
|
||||
mdelay(1);
|
||||
if (retries-- == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
reg_value = csr1_read(uniphy_index, VR_MII_AN_INTR_STS);
|
||||
autoneg_complete = reg_value & 0x1;
|
||||
}
|
||||
reg_value &= ~CL37_ANCMPLT_INTR;
|
||||
csr1_write(uniphy_index, VR_MII_AN_INTR_STS, reg_value);
|
||||
}
|
||||
|
||||
void ppe_uniphy_usxgmii_speed_set(uint32_t uniphy_index, int speed)
|
||||
{
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
reg_value = csr1_read(uniphy_index, SR_MII_CTRL_ADDRESS);
|
||||
reg_value |= DUPLEX_MODE;
|
||||
|
||||
switch(speed) {
|
||||
case 0:
|
||||
reg_value &=~SS5;
|
||||
reg_value &=~SS6;
|
||||
reg_value &=~SS13;
|
||||
break;
|
||||
case 1:
|
||||
reg_value &=~SS5;
|
||||
reg_value &=~SS6;
|
||||
reg_value |=SS13;
|
||||
break;
|
||||
case 2:
|
||||
reg_value &=~SS5;
|
||||
reg_value |=SS6;
|
||||
reg_value &=~SS13;
|
||||
break;
|
||||
case 3:
|
||||
reg_value &=~SS5;
|
||||
reg_value |=SS6;
|
||||
reg_value |=SS13;
|
||||
break;
|
||||
case 4:
|
||||
reg_value |=SS5;
|
||||
reg_value &=~SS6;
|
||||
reg_value &=~SS13;
|
||||
break;
|
||||
case 5:
|
||||
reg_value |=SS5;
|
||||
reg_value &=~SS6;
|
||||
reg_value |=SS13;
|
||||
break;
|
||||
}
|
||||
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
|
||||
|
||||
}
|
||||
|
||||
void ppe_uniphy_usxgmii_duplex_set(uint32_t uniphy_index, int duplex)
|
||||
{
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
reg_value = csr1_read(uniphy_index, SR_MII_CTRL_ADDRESS);
|
||||
|
||||
if (duplex & 0x1)
|
||||
reg_value |= DUPLEX_MODE;
|
||||
else
|
||||
reg_value &= ~DUPLEX_MODE;
|
||||
|
||||
csr1_write(uniphy_index, SR_MII_CTRL_ADDRESS, reg_value);
|
||||
}
|
||||
|
||||
void ppe_uniphy_usxgmii_port_reset(uint32_t uniphy_index)
|
||||
{
|
||||
uint32_t reg_value = 0;
|
||||
|
||||
reg_value = csr1_read(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS);
|
||||
reg_value |= USRA_RST;
|
||||
csr1_write(uniphy_index, VR_XS_PCS_DIG_CTRL1_ADDRESS, reg_value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,3 +67,7 @@ enum port_wrapper_cfg {
|
|||
#define CL37_ANCMPLT_INTR (1 << 0)
|
||||
|
||||
void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode);
|
||||
void ppe_uniphy_usxgmii_port_reset(uint32_t uniphy_index);
|
||||
void ppe_uniphy_usxgmii_duplex_set(uint32_t uniphy_index, int duplex);
|
||||
void ppe_uniphy_usxgmii_speed_set(uint32_t uniphy_index, int speed);
|
||||
void ppe_uniphy_usxgmii_autoneg_completed(uint32_t uniphy_index);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue