ipq807x: Enabled napa phy for HK07

Change-Id: I1865a8336fc9763e1c541f5b6346ddbce7cb6eb9
Signed-off-by: Sham Muthayyan <smuthayy@codeaurora.org>
This commit is contained in:
Sham Muthayyan 2018-06-11 19:48:14 +05:30 committed by Gerrit - the friendly Code Review server
parent b8f8d40827
commit 8550018c8e
7 changed files with 124 additions and 7 deletions

View file

@ -27,7 +27,9 @@
ess-switch {
switch_mac_mode = <0x0>;
switch_mac_mode1 = <0xFF>;
switch_mac_mode2 = <0xFF>;
switch_mac_mode2 = <0x6>;
8081_port = <5>;
napa_gpio = <44>;
};
};

View file

@ -311,6 +311,19 @@ int get_aquantia_gpio()
return aquantia_gpio;
}
int get_napa_gpio()
{
int napa_gpio = -1, node;
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
if (node >= 0)
napa_gpio = fdtdec_get_uint(gd->fdt_blob, node, "napa_gpio", -1);
else
return node;
return napa_gpio;
}
void aquantia_phy_reset_init(void)
{
int aquantia_gpio = -1, node;
@ -330,6 +343,29 @@ void aquantia_phy_reset_init(void)
}
}
void napa_phy_reset_init(void)
{
int napa_gpio = -1, node;
unsigned int *napa_gpio_base;
napa_gpio = get_napa_gpio();
if (napa_gpio >=0) {
napa_gpio_base = (unsigned int *)GPIO_CONFIG_ADDR(napa_gpio);
writel(0x203, napa_gpio_base);
gpio_direction_output(napa_gpio, 0x0);
}
}
void napa_phy_reset_init_done(void)
{
int napa_gpio;
napa_gpio = get_napa_gpio();
if (napa_gpio >= 0) {
gpio_set_value(napa_gpio, 0x1);
}
}
void aquantia_phy_reset_init_done(void)
{
int aquantia_gpio;
@ -403,9 +439,11 @@ void eth_clock_enable(void)
writel(0x203, tlmm_base);
writel(0, tlmm_base + 0x4);
aquantia_phy_reset_init();
napa_phy_reset_init();
mdelay(500);
writel(2, tlmm_base + 0x4);
aquantia_phy_reset_init_done();
napa_phy_reset_init_done();
mdelay(500);
}

View file

@ -61,6 +61,7 @@ extern int ipq_qca8033_phy_init(struct phy_ops **ops, u32 phy_id);
extern int ipq_qca_aquantia_phy_init(struct phy_ops **ops, u32 phy_id);
static int tftp_acl_our_port;
static int uniphy_phy_mode;
/*
* EDMA hardware instance
*/
@ -914,7 +915,8 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
char *dp[] = {"Half", "Full"};
int linkup=0;
int mac_speed = 0, speed_clock1 = 0, speed_clock2 = 0;
int phy_addr, port_8033 = -1, node, aquantia_port = -1;
int phy_addr, port_8033 = -1, node, aquantia_port = -1, port_8081 = -1;
int sgmii_mode = 0;
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
if (node >= 0)
@ -922,6 +924,9 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
if (node >= 0)
aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port", -1);
if (node >= 0)
port_8081 = fdtdec_get_uint(gd->fdt_blob, node, "8081_port", -1);
/*
* Check PHY link, speed, Duplex on all phys.
* we will proceed even if single link is up
@ -943,6 +948,8 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
if (i == port_8033)
phy_addr = QCA8033_PHY_ADDR;
if (i == port_8081)
phy_addr = QCA8081_PHY_ADDR;
else if (i == aquantia_port)
phy_addr = AQU_PHY_ADDR;
else
@ -969,6 +976,8 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
priv->mac_unit, i, lstatus[status], speed,
dp[duplex]);
if (i == port_8081)
sgmii_mode = 1;
break;
case FAL_SPEED_100:
mac_speed = 0x1;
@ -985,6 +994,8 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
priv->mac_unit, i, lstatus[status], speed,
dp[duplex]);
if (i == port_8081)
sgmii_mode = 1;
break;
case FAL_SPEED_1000:
mac_speed = 0x2;
@ -998,6 +1009,8 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
printf ("eth%d PHY%d %s Speed :%d %s duplex\n",
priv->mac_unit, i, lstatus[status], speed,
dp[duplex]);
if (i == port_8081)
sgmii_mode = 1;
break;
case FAL_SPEED_10000:
mac_speed = 0x3;
@ -1008,12 +1021,23 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
dp[duplex]);
break;
case FAL_SPEED_2500:
mac_speed = 0x4;
speed_clock1 = 0x107;
if (i == port_8081)
mac_speed = 0x2;
else
mac_speed = 0x4;
if (port_8081 == 4)
speed_clock1 = 0x301;
else if (port_8081 == 5)
speed_clock1 = 0x101;
else
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]);
if (i == port_8081)
sgmii_mode = 0;
break;
case FAL_SPEED_5000:
mac_speed = 0x5;
@ -1027,6 +1051,20 @@ static int ipq807x_eth_init(struct eth_device *eth_dev, bd_t *this)
printf("Unknown speed\n");
break;
}
if (i == port_8081) {
if (sgmii_mode != uniphy_phy_mode) {
uniphy_phy_mode = sgmii_mode;
if (sgmii_mode) {
ppe_port_bridge_txmac_set(i, 1);
ppe_uniphy_mode_set(0x2, PORT_WRAPPER_SGMII0_RGMII4);
} else {
ppe_port_bridge_txmac_set(i, 1);
ppe_uniphy_mode_set(0x2, PORT_WRAPPER_SGMII_PLUS);
}
}
}
ipq807x_speed_clock_set(i, speed_clock1, speed_clock2);
if (i == aquantia_port)
ipq807x_uxsgmii_speed_set(i, mac_speed, duplex, status);
@ -1649,7 +1687,7 @@ int ipq807x_edma_init(void *edma_board_cfg)
int ret = -1;
ipq807x_edma_board_cfg_t ledma_cfg, *edma_cfg;
static int sw_init_done = 0;
int port_8033 = -1, node, phy_addr, aquantia_port = -1;
int port_8033 = -1, port_8081 = -1, node, phy_addr, aquantia_port = -1;
int mode;
node = fdt_path_offset(gd->fdt_blob, "/ess-switch");
@ -1659,6 +1697,9 @@ int ipq807x_edma_init(void *edma_board_cfg)
if (node >= 0)
aquantia_port = fdtdec_get_uint(gd->fdt_blob, node, "aquantia_port", -1);
if (node >= 0)
port_8081 = fdtdec_get_uint(gd->fdt_blob, node, "8081_port", -1);
mode = fdtdec_get_uint(gd->fdt_blob, node, "switch_mac_mode", -1);
if (mode < 0) {
printf("Error: switch_mac_mode not specified in dts");
@ -1749,6 +1790,8 @@ int ipq807x_edma_init(void *edma_board_cfg)
phy_addr = QCA8033_PHY_ADDR;
else if (phy_id == aquantia_port)
phy_addr = AQU_PHY_ADDR;
else if (phy_id == port_8081)
phy_addr = QCA8081_PHY_ADDR;
else
phy_addr = phy_id;
@ -1781,6 +1824,9 @@ int ipq807x_edma_init(void *edma_board_cfg)
case QCA8033_PHY:
ipq_qca8033_phy_init(&ipq807x_edma_dev[i]->ops[phy_id], phy_addr);
break;
case QCA8081_PHY:
ipq_qca8081_phy_init(&ipq807x_edma_dev[i]->ops[phy_id], phy_addr);
break;
case AQUANTIA_PHY_107:
case AQUANTIA_PHY_109:
case AQUANTIA_PHY_111:

View file

@ -1075,7 +1075,7 @@ static void ppe_port_mux_set(int port_id, int port_type)
port_mux_ctrl.bf.port4_pcs_sel = PORT4_PCS_SEL_GMII_FROM_PCS0;
if (port_id == PORT5) {
if (port_type == PORT_GMAC_TYPE) {
port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS1;
port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS0;
port_mux_ctrl.bf.port5_gmac_sel = PORT5_GMAC_SEL_GMAC;
} else if (port_type == PORT_XGMAC_TYPE) {
port_mux_ctrl.bf.port5_pcs_sel = PORT5_PCS_SEL_GMII_FROM_PCS1;
@ -1104,6 +1104,9 @@ static void ppe_port_mux_mac_type_set(int port_id, int mode)
case PORT_WRAPPER_SGMII0_RGMII4:
port_type = PORT_GMAC_TYPE;
break;
case PORT_WRAPPER_SGMII_PLUS:
port_type = PORT_GMAC_TYPE;
break;
case PORT_WRAPPER_USXGMII:
port_type = PORT_XGMAC_TYPE;
break;

View file

@ -143,6 +143,7 @@ static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t channel)
else if (channel == 4)
reg_value |= UNIPHY_CH4_CH1_0_SGMII;
} else {
reg_value &= ~UNIPHY_SG_PLUS_MODE;
reg_value |= UNIPHY_SG_MODE;
}
writel(reg_value, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
@ -150,6 +151,25 @@ static void ppe_uniphy_sgmii_mode_set(uint32_t uniphy_index, uint32_t channel)
ppe_gcc_uniphy_soft_reset(uniphy_index);
}
static void ppe_uniphy_sgmii_plus_mode_set(uint32_t uniphy_index)
{
uint32_t reg_value;
writel(UNIPHY_MISC2_REG_SGMII_PLUS_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);
udelay(500);
writel(UNIPHY_PLL_RESET_REG_DEFAULT_VALUE, PPE_UNIPHY_BASE +
(uniphy_index * PPE_UNIPHY_REG_INC) + UNIPHY_PLL_RESET_REG_OFFSET);
ppe_gcc_uniphy_xpcs_reset(uniphy_index, true);
writel(0x800, PPE_UNIPHY_BASE + (uniphy_index * PPE_UNIPHY_REG_INC)
+ PPE_UNIPHY_MODE_CONTROL);
ppe_gcc_uniphy_soft_reset(uniphy_index);
ppe_uniphy_calibration(uniphy_index);
}
static int ppe_uniphy_10g_r_linkup(uint32_t uniphy_index)
{
uint32_t reg_value = 0;
@ -219,6 +239,9 @@ void ppe_uniphy_mode_set(uint32_t uniphy_index, uint32_t mode)
case PORT_WRAPPER_SGMII4_RGMII4:
ppe_uniphy_sgmii_mode_set(uniphy_index, 4);
break;
case PORT_WRAPPER_SGMII_PLUS:
ppe_uniphy_sgmii_plus_mode_set(uniphy_index);
break;
case PORT_WRAPPER_USXGMII:
ppe_uniphy_usxgmii_mode_set(uniphy_index);
break;

View file

@ -29,7 +29,8 @@
#define PPE_UNIPHY_BASE 0X07A00000
#define PPE_UNIPHY_REG_INC 0x10000
#define PPE_UNIPHY_MODE_CONTROL 0x46C
#define UNIPHY_SG_MODE 0x400
#define UNIPHY_SG_MODE 0x420
#define UNIPHY_SG_PLUS_MODE 0x800
#define UNIPHY_CH0_PSGMII_QSGMII 0x200
#define UNIPHY_CH4_CH1_0_SGMII 0x4
#define UNIPHY_CH1_CH0_SGMII 0x2
@ -37,6 +38,7 @@
#define UNIPHY_MISC2_REG_OFFSET 0x218
#define UNIPHY_MISC2_REG_SGMII_MODE 0x30
#define UNIPHY_MISC2_REG_SGMII_PLUS_MODE 0x50
#define UNIPHY_MISC2_REG_VALUE 0x70

View file

@ -37,6 +37,8 @@
#define QCA8075_PHY_V1_1_2P 0x004DD0B2
#define QCA8033_PHY 0x004DD074
#define QCA8033_PHY_ADDR 0x6
#define QCA8081_PHY 0x004DD100
#define QCA8081_PHY_ADDR 0x1C
#define AQUANTIA_PHY_107 0x03a1b4e2
#define AQUANTIA_PHY_109 0x03a1b502
#define AQUANTIA_PHY_111 0x03a1b610
@ -90,6 +92,7 @@ enum port_wrapper_cfg {
PORT_WRAPPER_SGMII1_RGMII4,
PORT_WRAPPER_SGMII4_RGMII4,
PORT_WRAPPER_QSGMII,
PORT_WRAPPER_SGMII_PLUS,
};