[Feature][API-1175]compatible with Marvellq2220 B1 phy
Change-Id: Icd53ca5f63179f1b3bad37649cd71d47db0b036b
diff --git a/src/kernel/linux/v4.19/drivers/net/phy/marvell-88q.c b/src/kernel/linux/v4.19/drivers/net/phy/marvell-88q.c
index ca19b11..6a292ef 100755
--- a/src/kernel/linux/v4.19/drivers/net/phy/marvell-88q.c
+++ b/src/kernel/linux/v4.19/drivers/net/phy/marvell-88q.c
@@ -12,7 +12,8 @@
#include <linux/delay.h>
-#define PHY_ID_88Q2220 0x002b0b21
+#define PHY_ID_88Q2220_B0 0x002b0b21
+#define PHY_ID_88Q2220_B1 0x002b0b22
#define Q2110_PMA_PMD_CTRL (MII_ADDR_C45 | 0x10000)
/* 1 = PMA/PMD reset, 0 = Normal */
@@ -89,10 +90,10 @@
val = phy_write(phydev, Q2110_T1_PMA_PMD_CTRL, val);
if (val < 0)
return val;
-
+/*
phy_write(phydev, (MII_ADDR_C45 | 0x030900), 0x8000);
phy_write(phydev, (MII_ADDR_C45 | 0x03FFE4), 0x000C);
-
+*/
printk("q2110 dts init ok!!\n");
return 0;
@@ -143,7 +144,7 @@
return 0;
}
-static int q2110_config_init(struct phy_device *phydev)
+static int q2220_b0_config_init(struct phy_device *phydev)
{
int i=0,mrvlId;
phydev->supported =
@@ -152,6 +153,8 @@
SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full;
phydev->state = PHY_NOLINK;
phydev->autoneg = AUTONEG_DISABLE;
+
+ printk("PHY_DEVICE is B0");
phy_write(phydev, MII_ADDR_C45 | 0x038033, 0x6801);
phy_write(phydev, MII_ADDR_C45 | 0x070200, 0x0000U);
phy_write(phydev, MII_ADDR_C45 | 0x010000, 0x840);
@@ -172,6 +175,84 @@
phy_write(phydev, MII_ADDR_C45 | 0x078031, 0xC28);
phy_write(phydev, MII_ADDR_C45 | 0x03FFDB, 0xFC10);
phy_write(phydev, MII_ADDR_C45 | 0x03FE1B, 0x58);
+//cheng.c modify for ethernet can not link up with golden device
+ phy_write(phydev, MII_ADDR_C45 | 0x03803A, 0xDA44);
+ phy_write(phydev, MII_ADDR_C45 | 0x038039, 0x2C0B);
+
+ phy_write(phydev, MII_ADDR_C45 | 0x038027, 0x1);//TC10 sleep/wakeup capability support
+ q2110_timing_init(phydev);
+
+ q2110_dts_init(phydev);
+
+ //softResetGe
+ phy_write(phydev, (MII_ADDR_C45 | 0x03FE1B), 0x48);
+ phy_write(phydev, (MII_ADDR_C45 | 0x030900), 0x8000);
+ phy_write(phydev, (MII_ADDR_C45 | 0x03FFE4), 0x000C);
+ phy_write(phydev, (MII_ADDR_C45 | 0x03FE1B), 0x58);
+
+ #if 0
+ //FE/100BT1
+ phy_write(phydev, (MII_ADDR_C45 | 0x030900), 0x8000);
+ phy_write(phydev, (MII_ADDR_C45 | 0x03FFE4), 0x000C);
+ #endif
+ printk("phy init ok\n");
+ return 0;
+}
+
+static int q2220_b1_config_init(struct phy_device *phydev)
+{
+
+ phydev->supported =
+ SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full;
+ phydev->advertising =
+ SUPPORTED_1000baseT_Full | SUPPORTED_100baseT_Full;
+ phydev->state = PHY_NOLINK;
+ phydev->autoneg = AUTONEG_DISABLE;
+
+
+ printk("PHY_DEVICE is B1");
+ /* set power management state breakpoint (internal state) */
+ phy_write(phydev, MII_ADDR_C45 | 0x03FFE4, 0x0007);
+ /* disable ANEG */
+ phy_write(phydev, MII_ADDR_C45 | 0x070200, 0x0000U);
+ /* prepare to write init code */
+ /* enable TXDAC setting overwrite bit */
+ phy_write(phydev, MII_ADDR_C45 | 0x03ffe3, 0x7000);
+ /* set IEEE power down */
+ phy_write(phydev, MII_ADDR_C45 | 0x010000, 0x0840);
+ /* wait 3 ms to get to ON_TBGB State and send out WUP if needed */
+ mdelay(3);
+ /* exit standby state(internal state) */
+ phy_write(phydev, MII_ADDR_C45 | 0x03FE1B, 0x0048);
+ /* exit IEEE power down */
+ phy_write(phydev, MII_ADDR_C45 | 0x010000, 0x0000);
+ phy_write(phydev, MII_ADDR_C45 | 0x030000, 0x0000);
+ /* configure TC10 loc_act_detect for rev B1 */
+ phy_write(phydev, MII_ADDR_C45 | 0x03FCAD, 0x030C);
+ phy_write(phydev, MII_ADDR_C45 | 0x038032, 0x6001);
+ phy_write(phydev, MII_ADDR_C45 | 0x03FDFF, 0x05A5);
+ phy_write(phydev, MII_ADDR_C45 | 0x03FDEC, 0xDBAF);
+ phy_write(phydev, MII_ADDR_C45 | 0x03FCAB, 0x1054);
+ phy_write(phydev, MII_ADDR_C45 | 0x03FCAC, 0x1483);
+ /* set DISABLE_WAIT_COMM to 0 for WUR */
+ phy_write(phydev, MII_ADDR_C45 | 0x038033, 0xC801);
+ /* send_s detection threshold, slave and master */
+ phy_write(phydev, MII_ADDR_C45 | 0x78032, 0x2020);
+ phy_write(phydev, MII_ADDR_C45 | 0x78031, 0xA28);
+ phy_write(phydev, MII_ADDR_C45 | 0x78031, 0xC28);
+ /* disable DCL calibratin during tear down */
+ phy_write(phydev, MII_ADDR_C45 | 0x03FFDB, 0xFC10);
+ /* disable RESET of DCL*/
+ phy_write(phydev, MII_ADDR_C45 | 0x03FE1B, 0x58);
+ /* update Initial FFE Coefficients */
+ phy_write(phydev, MII_ADDR_C45 | 0x03FBBA, 0x0CB2);
+ phy_write(phydev, MII_ADDR_C45 | 0x03FBBB, 0x0C4A);
+ /* Toggle Squelch override */
+ phy_write(phydev, MII_ADDR_C45 | 0x048178, 0x7540);
+ phy_write(phydev, MII_ADDR_C45 | 0x048178, 0x5540);
+ /* aneg set pga gain and amp */
+ phy_write(phydev, MII_ADDR_C45 | 0x03FE5F, 0xE8);
+ phy_write(phydev, MII_ADDR_C45 | 0x03FE05, 0x755C);
phy_write(phydev, MII_ADDR_C45 | 0x03803A, 0xDA44);
phy_write(phydev, MII_ADDR_C45 | 0x038039, 0x2C0B);
@@ -180,6 +261,18 @@
q2110_timing_init(phydev);
q2110_dts_init(phydev);
+
+ //softResetGe
+ phy_write(phydev, (MII_ADDR_C45 | 0x03FE1B), 0x48);
+ phy_write(phydev, (MII_ADDR_C45 | 0x030900), 0x8000);
+ phy_write(phydev, (MII_ADDR_C45 | 0x03FFE4), 0x000C);
+ phy_write(phydev, (MII_ADDR_C45 | 0x03FE1B), 0x58);
+
+ #if 0
+ //FE/100BT1
+ phy_write(phydev, (MII_ADDR_C45 | 0x030900), 0x8000);
+ phy_write(phydev, (MII_ADDR_C45 | 0x03FFE4), 0x000C);
+ #endif
printk("phy init ok\n");
return 0;
}
@@ -206,7 +299,6 @@
static int q2110_read_status(struct phy_device *phydev)
{
-
int val;
unsigned int regVal1, regVal2, regVal3;
@@ -268,7 +360,7 @@
return 0;
//xf.li 2022/11/9 modify for API-647
}
-int q2220_resume(struct phy_device *phydev)
+int q2220_b0_resume(struct phy_device *phydev)
{
//xf.li 2022/11/9 modify for API-647
if(if_suspend == 1)
@@ -288,7 +380,38 @@
gpio_direction_output(NAD_RESET_PHY1, 1);
gpio_direction_output(205 + 268, 0);
mdelay(10);//at lest 4ms for reset phy
- q2110_config_init(phydev);
+ q2220_b0_config_init(phydev);
+ if_suspend = 0;
+ }
+ else
+ {
+ printk("q2220_resume: no suspend! In boot state.");
+ }
+ return 0;
+ //xf.li 2022/11/9 modify for API-647
+}
+
+int q2220_b1_resume(struct phy_device *phydev)
+{
+ //xf.li 2022/11/9 modify for API-647
+ if(if_suspend == 1)
+ {
+ printk("phy awake start\n");
+ gpio_direction_output(205 + 268, 1);
+ gpio_direction_output(PHY_POWER_SUPPLY, 1);
+ mdelay(1);
+ gpio_direction_output(NAD_WAKEUP_PHY1, 1);
+ mdelay(10);
+ gpio_direction_output(NAD_WAKEUP_PHY1, 0);
+ mdelay(5);
+ gpio_direction_output(NAD_RESET_PHY1, 1);
+ mdelay(1000);
+ gpio_direction_output(NAD_RESET_PHY1, 0);
+ mdelay(30);
+ gpio_direction_output(NAD_RESET_PHY1, 1);
+ gpio_direction_output(205 + 268, 0);
+ mdelay(10);//at lest 4ms for reset phy
+ q2220_b1_config_init(phydev);
if_suspend = 0;
}
else
@@ -300,23 +423,37 @@
}
-
-static int q2110_match_phy_device(struct phy_device *phydev)
+static int q2220_b0_match_phy_device(struct phy_device *phydev)
{
- return (phydev->c45_ids.device_ids[1] & 0xffffffff) == PHY_ID_88Q2220;
+ return ((phydev->c45_ids.device_ids[1] & 0xffffffff) == PHY_ID_88Q2220_B0);
+}
+
+static int q2220_b1_match_phy_device(struct phy_device *phydev)
+{
+ return ((phydev->c45_ids.device_ids[1] & 0xffffffff) == PHY_ID_88Q2220_B1);
}
static struct phy_driver marvell_88q_driver[] = {
{
- .phy_id = PHY_ID_88Q2220,
+ .phy_id = PHY_ID_88Q2220_B0,
.phy_id_mask = 0xfffffff0,
- .name = "Marvell 88Q2220",
- .config_init = q2110_config_init,
- .match_phy_device = q2110_match_phy_device,
+ .name = "Marvell 88Q2220 B0",
+ .config_init = q2220_b0_config_init,
+ .match_phy_device = q2220_b0_match_phy_device,
.set_loopback = &q2110_loopback,
.read_status = q2110_read_status,
.suspend = q2220_suspend,
- .resume = q2220_resume,
+ .resume = q2220_b0_resume,
+ }, {
+ .phy_id = PHY_ID_88Q2220_B1,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Marvell 88Q2220 B1",
+ .config_init = q2220_b1_config_init,
+ .match_phy_device = q2220_b1_match_phy_device,
+ .set_loopback = &q2110_loopback,
+ .read_status = q2110_read_status,
+ .suspend = q2220_suspend,
+ .resume = q2220_b1_resume,
}
};