ソースを参照

Merge branch 'CR_2522_ECO_EVB_samin.guo' into 'jh7110-master'

CR_2522: support gamc with jh7110B-evb

See merge request sdk/u-boot!16
andy.hu 1 年間 前
コミット
3853ecfd3c

+ 11 - 1
arch/riscv/dts/starfive_evb.dts

@@ -58,13 +58,23 @@
 
 &gmac0 {
 	status = "okay";
+	#address-cells = <1>;
+	#size-cells = <0>;
+	phy0: ethernet-phy@0 {
+		rxc_dly_en = <1>;
+		tx_delay_sel_fe = <5>;
+		tx_delay_sel = <0xb>;
+		tx_inverted_10 = <0x0>;
+		tx_inverted_100 = <0x0>;
+		tx_inverted_1000 = <0x0>;
+	};
 };
 
 &gmac1 {
 	status = "okay";
 	#address-cells = <1>;
 	#size-cells = <0>;
-	phy0: ethernet-phy@0 {
+	phy1: ethernet-phy@1 {
 		rxc-skew-ps = <1060>;
 		txc-skew-ps = <1800>;
 		reg = <0>;

+ 10 - 0
arch/riscv/include/asm/arch-jh7110/jh7110-regs.h

@@ -15,6 +15,7 @@
 #define AON_SYSCON_BASE	0x17010000
 #define SYS_CRG_BASE		0x13020000
 #define AON_CRG_BASE		0x17000000
+#define AON_IOMUX_BASE		0x17020000
 #define STG_CRG_BASE		0x10230000
 #define CLK_ENABLE_MASK		0x80000000U
 #define SYS_CRG_RESET_ASSERT3_SHIFT	0X304U
@@ -25,8 +26,16 @@
 #define SYS_SYSCON_144			0x90U
 #define GMAC5_0_SEL_I_SHIFT             0x12U
 #define GMAC5_0_SEL_I_MASK              0x1C0000U
+#define GMAC5_0_CLK_TX_SHIFT            0x14
+#define GMAC5_0_CLK_RX_SHIFT            0x1C
+#define GMAC5_0_CLK_TX_BIT              0x18
+#define GMAC5_0_CLK_TX_MASK             0x1000000U
 #define GMAC5_1_SEL_I_SHIFT             0x2U
 #define GMAC5_1_SEL_I_MASK              0x1CU
+#define GMAC5_1_CLK_TX_SHIFT            0x1A4
+#define GMAC5_1_CLK_RX_SHIFT            0x19C
+#define GMAC5_1_CLK_TX_BIT              0x18
+#define GMAC5_1_CLK_TX_MASK             0x1000000U
 
 /*usb cfg*/
 #define STG_SYSCON_4			0x4U
@@ -67,6 +76,7 @@
 #define PCIE_USB3_RX_STANDBY_MASK	0x80U
 #define PCIE_USB3_PHY_ENABLE_SHIFT	0x4U
 #define PCIE_USB3_PHY_ENABLE_MASK	0x10U
+#define AON_GPIO_DIN_REG		0x2c
 
 /*timer cfg*/
 #define TIMER_CLK_APB_SHIFT		0x1F0U

+ 4 - 1
board/starfive/evb/spl.c

@@ -89,7 +89,10 @@ void board_init_f(ulong dummy)
 		CLK_AON_APB_FUNC_SW_MASK,
 		BIT(CLK_AON_APB_FUNC_SW_SHIFT) & CLK_AON_APB_FUNC_SW_MASK);
 
-
+	/* switch qspi clk to pll0 */
+	clrsetbits_le32(SYS_CRG_BASE + CLK_QSPI_REF_OFFSET,
+			CLK_QSPI_REF_SW_MASK,
+			BIT(CLK_QSPI_REF_SW_SHIFT) & CLK_QSPI_REF_SW_MASK);
 
 	/*set GPIO to 1.8v*/
 	setbits_le32(SYS_SYSCON_BASE + 0xC, 0xf);

+ 70 - 11
board/starfive/evb/starfive_evb.c

@@ -17,6 +17,12 @@
 #include <linux/bitops.h>
 #include <asm/arch/gpio.h>
 
+enum chip_type_t {
+	CHIP_A = 0,
+	CHIP_B,
+	CHIP_MAX,
+};
+
 #define SYS_CLOCK_ENABLE(clk) \
 	setbits_le32(SYS_CRG_BASE + clk, CLK_ENABLE_MASK)
 
@@ -50,21 +56,56 @@ static void jh7110_timer_init(void)
 			SYS_CRG_RESET_STATUS3_SHIFT, TIMER_RSTN_TIMER3_SHIFT);
 }
 
-static void jh7110_gmac_init(int id)
+static void jh7110_gmac_sel_tx_to_rgmii(int id)
 {
 	switch (id) {
 	case 0:
-		clrsetbits_le32(AON_SYSCON_BASE + AON_SYSCFG_12,
-			GMAC5_0_SEL_I_MASK,
-			BIT(GMAC5_0_SEL_I_SHIFT) & GMAC5_0_SEL_I_MASK);
+		clrsetbits_le32(AON_CRG_BASE + GMAC5_0_CLK_TX_SHIFT,
+		GMAC5_0_CLK_TX_MASK,
+		BIT(GMAC5_0_CLK_TX_BIT) & GMAC5_0_CLK_TX_MASK);
+		break;
+	case 1:
+		clrsetbits_le32(SYS_CRG_BASE + GMAC5_1_CLK_TX_SHIFT,
+		GMAC5_1_CLK_TX_MASK,
+		BIT(GMAC5_1_CLK_TX_BIT) & GMAC5_1_CLK_TX_MASK);
 		break;
+	default:
+		break;
+	}
+}
 
+static void jh7110_gmac_io_pad(int id)
+{
+	u32 cap = BIT(0); /* 2.5V */
+
+	switch (id) {
+	case 0:
+		/* Improved GMAC0 TX I/O PAD capability */
+		clrsetbits_le32(AON_IOMUX_BASE + 0x78, 0x3, cap & 0x3);
+		clrsetbits_le32(AON_IOMUX_BASE + 0x7c, 0x3, cap & 0x3);
+		clrsetbits_le32(AON_IOMUX_BASE + 0x80, 0x3, cap & 0x3);
+		clrsetbits_le32(AON_IOMUX_BASE + 0x84, 0x3, cap & 0x3);
+		clrsetbits_le32(AON_IOMUX_BASE + 0x88, 0x3, cap & 0x3);
+		break;
 	case 1:
-		clrsetbits_le32(SYS_SYSCON_BASE + SYS_SYSCON_144,
-			GMAC5_1_SEL_I_MASK,
-			BIT(GMAC5_1_SEL_I_SHIFT) & GMAC5_1_SEL_I_MASK);
+		/* Improved GMAC1 TX I/O PAD capability */
+		clrsetbits_le32(SYS_IOMUX_BASE + 0x26c, 0x3, cap & 0x3);
+		clrsetbits_le32(SYS_IOMUX_BASE + 0x270, 0x3, cap & 0x3);
+		clrsetbits_le32(SYS_IOMUX_BASE + 0x274, 0x3, cap & 0x3);
+		clrsetbits_le32(SYS_IOMUX_BASE + 0x278, 0x3, cap & 0x3);
+		clrsetbits_le32(SYS_IOMUX_BASE + 0x27c, 0x3, cap & 0x3);
 		break;
+	}
+}
 
+static void jh7110_gmac_init(int id, u32 chip)
+{
+	switch (chip) {
+	case CHIP_B:
+		jh7110_gmac_sel_tx_to_rgmii(id);
+		jh7110_gmac_io_pad(id);
+		break;
+	case CHIP_A:
 	default:
 		break;
 	}
@@ -139,6 +180,24 @@ static void jh7110_usb_init(bool usb2_enable)
 
 }
 
+static u32 get_chip_type(void)
+{
+	u32 value;
+
+	value = in_le32(AON_IOMUX_BASE + AON_GPIO_DIN_REG);
+	value = (value & BIT(3)) >> 3;
+	switch (value) {
+	case CHIP_B:
+		env_set("chip_vision", "B");
+		break;
+	case CHIP_A:
+	default:
+		env_set("chip_vision", "A");
+		break;
+	}
+	return value;
+}
+
 static void jh7110_mmc_init(int id)
 {
 	if (id == 0) {
@@ -176,12 +235,8 @@ int board_init(void)
 	/*enable hart1-hart4 prefetcher*/
 	enable_prefetcher();
 
-	jh7110_gmac_init(0);
-	jh7110_gmac_init(1);
 	jh7110_timer_init();
-
 	jh7110_usb_init(true);
-
 	jh7110_mmc_init(0);
 	jh7110_mmc_init(1);
 
@@ -194,6 +249,7 @@ int misc_init_r(void)
 {
 	char mac0[6] = {0x66, 0x34, 0xb0, 0x6c, 0xde, 0xad};
 	char mac1[6] = {0x66, 0x34, 0xb0, 0x7c, 0xae, 0x5d};
+	u32 chip;
 
 #if CONFIG_IS_ENABLED(STARFIVE_OTP)
 	struct udevice *dev;
@@ -221,6 +277,9 @@ err:
 	eth_env_set_enetaddr("eth0addr", mac0);
 	eth_env_set_enetaddr("eth1addr", mac1);
 
+	chip = get_chip_type();
+	jh7110_gmac_init(0, chip);
+	jh7110_gmac_init(1, chip);
 	return 0;
 }
 #endif

+ 3 - 1
configs/starfive_evb_defconfig

@@ -27,6 +27,8 @@ CONFIG_USE_BOOTARGS=y
 CONFIG_BOOTARGS="console=ttyS0,115200  debug rootwait  earlycon=sbi "
 CONFIG_USE_BOOTCOMMAND=y
 CONFIG_BOOTCOMMAND="fatload mmc 0:3 $kernel_addr_r jh7110_uEnv.txt; env import -t $kernel_addr_r $filesize;run boot2"
+CONFIG_USE_PREBOOT=y
+CONFIG_PREBOOT="run chipa_set_uboot"
 CONFIG_LOG_MAX_LEVEL=4
 CONFIG_SPL_LOG=y
 CONFIG_DISPLAY_CPUINFO=y
@@ -63,7 +65,7 @@ CONFIG_SPL_CLK_JH7110=y
 CONFIG_MMC_DW=y
 CONFIG_MMC_DW_SNPS=y
 CONFIG_SF_DEFAULT_MODE=0x0
-CONFIG_SF_DEFAULT_SPEED=50000000
+CONFIG_SF_DEFAULT_SPEED=100000000
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_SPANSION=y
 CONFIG_PHY_MARVELL=y

+ 269 - 173
drivers/net/phy/motorcomm.c

@@ -25,30 +25,70 @@
 #include <config.h>
 #include <common.h>
 #include <phy.h>
+#include <bitfield.h>
 
 #define REG_PHY_SPEC_STATUS	0x11
 #define REG_DEBUG_ADDR_OFFSET	0x1e
 #define REG_DEBUG_DATA		0x1f
 #define EXTREG_SLEEP_CONTROL	0x27
 
-#define YT8512_DUPLEX		0x2000
-#define YT8521_SPEED_MODE	0xc000
-#define YT8521_DUPLEX		0x2000
-#define YT8521_SPEED_MODE_BIT	14
-#define YT8521_DUPLEX_BIT	13
-#define YT8521_LINK_STATUS_BIT	10
-
-#define YT8521_EXTREG_SMI_SDS_PHY	0xa000
-#define YT8521_EXTREG_CHIP_CONFIG	0xa001
-#define YT8521_RXC_DLY_EN_BIT		8
-#define YT8521_EXTREG_RGMII_CONFIG1	0xa003
-#define YT8521_RX_DELAY_SEL_MASK	0x3C00UL
-#define YT8521_TX_DELAY_SEL_FE_MASK	0xF0UL
-#define YT8521_TX_DELAY_SEL_MASK	0xFUL
+#define YTPHY_EXTREG_CHIP_CONFIG	0xa001
+#define YTPHY_EXTREG_RGMII_CONFIG1	0xa003
+#define YTPHY_PAD_DRIVES_STRENGTH_CFG	0xa010
+#define YTPHY_DUPLEX		0x2000
+#define YTPHY_DUPLEX_BIT	13
+#define YTPHY_SPEED_MODE	0xc000
+#define YTPHY_SPEED_MODE_BIT	14
+#define YTPHY_RGMII_SW_DR_MASK	GENMASK(5, 4)
 
+#define YT8521_EXT_CLK_GATE	0xc
+#define YT8521_EN_SLEEP_SW_BIT	15
 
 #define SPEED_UNKNOWN		-1
 
+#define PHY_ID_YT8531                   0x4f51e91b
+#define MOTORCOMM_PHY_ID_MASK           0x00000fff
+
+#define YT8512_EXTREG_LED0              0x40c0
+#define YT8512_EXTREG_LED1              0x40c3
+
+#define YT8512_EXTREG_SLEEP_CONTROL1    0x2027
+
+#define YT8512_LED0_ACT_BLK_IND         0x1000
+#define YT8512_LED0_DIS_LED_AN_TRY      0x0001
+#define YT8512_LED0_BT_BLK_EN           0x0002
+#define YT8512_LED0_HT_BLK_EN           0x0004
+#define YT8512_LED0_COL_BLK_EN          0x0008
+#define YT8512_LED0_BT_ON_EN            0x0010
+#define YT8512_LED1_BT_ON_EN            0x0010
+#define YT8512_LED1_TXACT_BLK_EN        0x0100
+#define YT8512_LED1_RXACT_BLK_EN        0x0200
+
+#define YT8512_EN_SLEEP_SW_BIT          15
+
+struct ytphy_reg_field {
+	const char	*name;
+	const u8	size;	/* Size of the bitfield, in bits */
+	const u8	off;	/* Offset from bit 0 */
+	const u8	dflt;	/* Default value */
+};
+
+static const struct ytphy_reg_field ytphy_rxtxd_grp[] = {
+	{ "rx_delay_sel", 4, 10, 0x0 },
+	{ "tx_delay_sel_fe", 4, 4, 0xf },
+	{ "tx_delay_sel", 4, 0, 0x1 }
+};
+
+static const struct ytphy_reg_field ytphy_txinver_grp[] = {
+	{ "tx_inverted_1000", 1, 14, 0x0 },
+	{ "tx_inverted_100", 1, 14, 0x0 },
+	{ "tx_inverted_10", 1, 14, 0x0 }
+};
+
+static const struct ytphy_reg_field ytphy_rxden_grp[] = {
+	{ "rxc_dly_en", 1, 8, 0x1 }
+};
+
 static int ytphy_read_ext(struct phy_device *phydev, u32 regnum)
 {
 	int ret;
@@ -71,216 +111,261 @@ static int ytphy_write_ext(struct phy_device *phydev, u32 regnum, u16 val)
 	return phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA, val);
 }
 
-static int yt8511_config(struct phy_device *phydev)
+static int ytphy_parse_status(struct phy_device *phydev)
 {
-	u16 val = 0;
-	int err = 0;
+	int val;
+	int speed, speed_mode, duplex;
 
-	genphy_config_aneg(phydev);
+	val = phy_read(phydev, MDIO_DEVAD_NONE, REG_PHY_SPEC_STATUS);
+	if (val < 0)
+		return val;
 
-	/* disable sleep mode */
-	err = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_ADDR_OFFSET, EXTREG_SLEEP_CONTROL);
-	if (err < 0) {
-		printf("%s: write EXTREG_SLEEP_CONTROL error!\n", __func__);
-		return err;
+	duplex = (val & YTPHY_DUPLEX) >> YTPHY_DUPLEX_BIT;
+	speed_mode = (val & YTPHY_SPEED_MODE) >> YTPHY_SPEED_MODE_BIT;
+	switch (speed_mode) {
+	case 2:
+		speed = SPEED_1000;
+		break;
+	case 1:
+		speed = SPEED_100;
+		break;
+	default:
+		speed = SPEED_10;
+		break;
 	}
 
-	val = phy_read(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA);
-	val &= ~(1 << 15);
-	err = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA, val);
-	if (err < 0) {
-		printf("%s: write REG_DEBUG_DATA error!\n", __func__);
-		return err;
-	}
+	phydev->speed = speed;
+	phydev->duplex = duplex;
 
-	/* config PLL clock */
-	err = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_ADDR_OFFSET, 0xc);
-	if (err < 0) {
-		printf("%s: write 0xc error!\n", __func__);
-		return err;
+	return 0;
+}
+
+static int ytphy_of_inverted(struct phy_device *phydev)
+{
+	ofnode node;
+	u32 val;
+	u32 inver_10;
+	u32 inver_100;
+	u32 inver_1000;
+
+	node = phydev->node;
+	if (!ofnode_valid(node)) {
+		/* Look for a PHY node under the Ethernet node */
+		node = dev_read_subnode(phydev->dev, "ethernet-phy");
 	}
 
-	val = phy_read(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA);
-	/* ext reg 0xc.b[2:1]
-	 * 00-----25M from pll;
-	 * 01---- 25M from xtl;(default)
-	 * 10-----62.5M from pll;
-	 * 11----125M from pll(here set to this value)
-	 */
-
-	val &= ~(3 << 1);	/*00-----25M from pll*/
-	val |= (1 << 1);	/*01-----25M from xtl; (default)*/
-	err = phy_write(phydev, MDIO_DEVAD_NONE, REG_DEBUG_DATA, val);
-	if (err < 0) {
-		printf("%s: set PLL error!\n", __func__);
-		return err;
+	if (!ofnode_valid(node)) /* No node found*/
+		return 0;
+
+	val = ytphy_read_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1);
+	inver_10 = ofnode_read_u32_default(node, "tx_inverted_10", 0);
+	inver_100 = ofnode_read_u32_default(node, "tx_inverted_100", 0);
+	inver_1000 = ofnode_read_u32_default(node, "tx_inverted_1000", 0);
+
+	switch (phydev->speed) {
+	case SPEED_1000:
+		val = bitfield_replace(val, ytphy_txinver_grp[0].off,
+				ytphy_txinver_grp[0].size, inver_1000);
+		break;
+	case SPEED_100:
+		val = bitfield_replace(val, ytphy_txinver_grp[1].off,
+				ytphy_txinver_grp[1].size, inver_100);
+		break;
+	case SPEED_10:
+		val = bitfield_replace(val, ytphy_txinver_grp[2].off,
+				ytphy_txinver_grp[2].size, inver_10);
+		break;
+	default:
+		printf("UNKOWN SPEED\n");
+		break;
 	}
 
-	return 0;
+	return ytphy_write_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1, val);
 }
 
-static int yt8521_config(struct phy_device *phydev)
+static int ytphy_startup(struct phy_device *phydev)
 {
-	int ret, val;
-	int  regnum;
+	int retval;
 
-	ret = 0;
-	ytphy_write_ext(phydev, YT8521_EXTREG_SMI_SDS_PHY, 0);
+	retval = genphy_update_link(phydev);
+	if (retval)
+		return retval;
+	ytphy_parse_status(phydev);
 
-	genphy_config_aneg(phydev);
+	ytphy_of_inverted(phydev);
 
-	/* disable auto sleep */
-	val = ytphy_read_ext(phydev, EXTREG_SLEEP_CONTROL);
-	if (val < 0) {
-		regnum = EXTREG_SLEEP_CONTROL;
-		goto err;
-	}
+	return 0;
+}
 
-	val &= ~(1 << 15);
-	ret = ytphy_write_ext(phydev, EXTREG_SLEEP_CONTROL, val);
-	if (ret < 0) {
-		regnum = EXTREG_SLEEP_CONTROL;
-		goto err;
+static int ytphy_of_config(struct phy_device *phydev)
+{
+	ofnode node;
+	u32 val;
+	u32 cfg;
+	int i;
+
+	node = phydev->node;
+	if (!ofnode_valid(node)) {
+		/* Look for a PHY node under the Ethernet node */
+		node = dev_read_subnode(phydev->dev, "ethernet-phy");
 	}
 
-	/*  enable tx delay 450ps per step */
-	val = ytphy_read_ext(phydev, YT8521_EXTREG_RGMII_CONFIG1);
-	if (val < 0) {
-		regnum = YT8521_EXTREG_RGMII_CONFIG1;
-		goto err;
-	}
+	if (!ofnode_valid(node)) /* No node found*/
+		return 0;
 
-	val &= ~(YT8521_RX_DELAY_SEL_MASK
-		|YT8521_TX_DELAY_SEL_FE_MASK
-		|YT8521_TX_DELAY_SEL_MASK);
-	val |= 0x5B;
-	ret = ytphy_write_ext(phydev, YT8521_EXTREG_RGMII_CONFIG1, val);
-	if (ret < 0) {
-		regnum = YT8521_EXTREG_RGMII_CONFIG1;
-		goto err;
-	}
+	/*read rxc_dly_en config*/
+	cfg = ofnode_read_u32_default(node, ytphy_rxden_grp[0].name, ~0);
+	if (cfg != -1) {
 
-	/* disable rx delay */
-	val = ytphy_read_ext(phydev, YT8521_EXTREG_CHIP_CONFIG);
-	if (val < 0) {
-		regnum = YT8521_EXTREG_CHIP_CONFIG;
-		goto err;
-	}
-	val &= ~(1 << 8);
-	val |=BIT(YT8521_RXC_DLY_EN_BIT);
-	ret = ytphy_write_ext(phydev, YT8521_EXTREG_CHIP_CONFIG, val);
-	if (ret < 0) {
-		regnum = YT8521_EXTREG_CHIP_CONFIG;
-		goto err;
-	}
+		val = ytphy_read_ext(phydev, YTPHY_EXTREG_CHIP_CONFIG);
 
-	/* enable RXC clock when no wire plug */
-	ret = ytphy_write_ext(phydev, YT8521_EXTREG_SMI_SDS_PHY, 0);
-	if (ret < 0) {
-		regnum = YT8521_EXTREG_SMI_SDS_PHY;
-		goto err;
-	}
+		/*check the cfg overflow or not*/
+		cfg = (cfg > ((1 << ytphy_rxden_grp[0].size) - 1)) ?
+			((1 << ytphy_rxden_grp[0].size) - 1) : cfg;
 
-	val = ytphy_read_ext(phydev, 0xc);
-	if (val < 0) {
-		regnum = 0xc;
-		goto err;
+		val = bitfield_replace(val, ytphy_rxden_grp[0].off,
+			ytphy_rxden_grp[0].size, cfg);
+		ytphy_write_ext(phydev, YTPHY_EXTREG_CHIP_CONFIG, val);
 	}
 
-	val &= ~(1 << 12);
-	ret = ytphy_write_ext(phydev, 0xc, val);
-	if (ret < 0) {
-		regnum = 0xc;
-		goto err;
+	/* set drive strenght of rxd/rx_ctl rgmii pad */
+	val = ytphy_read_ext(phydev, YTPHY_PAD_DRIVES_STRENGTH_CFG);
+	val |= YTPHY_RGMII_SW_DR_MASK;
+	ytphy_write_ext(phydev, YTPHY_PAD_DRIVES_STRENGTH_CFG, val);
+
+	val = ytphy_read_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1);
+	for (i = 0; i < ARRAY_SIZE(ytphy_rxtxd_grp); i++) {
+
+		cfg = ofnode_read_u32_default(node,
+			ytphy_rxtxd_grp[i].name, ~0);
+		cfg = (cfg != -1) ? cfg : ytphy_rxtxd_grp[i].dflt;
+
+		/*check the cfg overflow or not*/
+		cfg = (cfg > ((1 << ytphy_rxtxd_grp[i].size) - 1)) ?
+			((1 << ytphy_rxtxd_grp[i].size) - 1) : cfg;
+
+		val = bitfield_replace(val, ytphy_rxtxd_grp[i].off,
+				ytphy_rxtxd_grp[i].size, cfg);
 	}
 
-	return 0;
-err:
-	printf("%s operate reg %d err.\n", __func__, regnum);
-	return ret;
+	return ytphy_write_ext(phydev, YTPHY_EXTREG_RGMII_CONFIG1, val);
 }
 
-static int yt8521_adjust_status(struct phy_device *phydev, int val, int is_utp)
+static int yt8512_led_init(struct phy_device *phydev)
 {
-	int speed_mode, duplex;
-	int speed = SPEED_UNKNOWN;
+	int ret;
+	int val;
+	int mask;
 
-	duplex = (val & YT8512_DUPLEX) >> YT8521_DUPLEX_BIT;
-	speed_mode = (val & YT8521_SPEED_MODE) >> YT8521_SPEED_MODE_BIT;
-	switch (speed_mode) {
-	case 0:
-		if (is_utp)
-			speed = SPEED_10;
-		break;
-	case 1:
-		speed = SPEED_100;
-		break;
-	case 2:
-		speed = SPEED_1000;
-		break;
-	case 3:
-		break;
-	default:
-		speed = SPEED_UNKNOWN;
-		break;
-	}
+	val = ytphy_read_ext(phydev, YT8512_EXTREG_LED0);
+	if (val < 0)
+		return val;
 
-	phydev->speed = speed;
-	phydev->duplex = duplex;
+	val |= YT8512_LED0_ACT_BLK_IND;
 
-	return 0;
+	mask = YT8512_LED0_DIS_LED_AN_TRY | YT8512_LED0_BT_BLK_EN |
+	YT8512_LED0_HT_BLK_EN | YT8512_LED0_COL_BLK_EN |
+	YT8512_LED0_BT_ON_EN;
+	val &= ~mask;
+
+	ret = ytphy_write_ext(phydev, YT8512_EXTREG_LED0, val);
+	if (ret < 0)
+		return ret;
+
+	val = ytphy_read_ext(phydev, YT8512_EXTREG_LED1);
+	if (val < 0)
+		return val;
+
+	val |= YT8512_LED1_BT_ON_EN;
+
+	mask = YT8512_LED1_TXACT_BLK_EN | YT8512_LED1_RXACT_BLK_EN;
+	val &= ~mask;
+
+	ret = ytphy_write_ext(phydev, YT8512_LED1_BT_ON_EN, val);
+
+	return ret;
 }
 
-static int yt8521_parse_status(struct phy_device *phydev)
+static int yt8512_config(struct phy_device *phydev)
 {
-	int ret, val, link, link_utp;
+	int ret;
+	int val;
 
-	/* reading UTP */
-	ret = ytphy_write_ext(phydev, 0xa000, 0);
+	ret = 0;
+	genphy_config_aneg(phydev);
+
+	ret = yt8512_led_init(phydev);
+
+	/* disable auto sleep */
+	val = ytphy_read_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1);
+	if (val < 0)
+		return val;
+
+	val &= (~BIT(YT8512_EN_SLEEP_SW_BIT));
+
+	ret = ytphy_write_ext(phydev, YT8512_EXTREG_SLEEP_CONTROL1, val);
 	if (ret < 0)
 		return ret;
 
-	val = phy_read(phydev, MDIO_DEVAD_NONE, REG_PHY_SPEC_STATUS);
+	return ret;
+}
+
+static int yt8521_config(struct phy_device *phydev)
+{
+	int ret, val;
+
+	ret = 0;
+	genphy_config_aneg(phydev);
+
+	/* disable auto sleep */
+	val = ytphy_read_ext(phydev, EXTREG_SLEEP_CONTROL);
 	if (val < 0)
 		return val;
 
-	link = val & (BIT(YT8521_LINK_STATUS_BIT));
-	if (link) {
-		link_utp = 1;
-		yt8521_adjust_status(phydev, val, 1);
-	} else {
-		link_utp = 0;
-	}
+	val &= ~(1 << YT8521_EN_SLEEP_SW_BIT);
+	ret = ytphy_write_ext(phydev, EXTREG_SLEEP_CONTROL, val);
+	if (ret < 0)
+		return ret;
 
-	if (link_utp) {
-		phydev->link = 1;
-		ytphy_write_ext(phydev, 0xa000, 0);
-	} else {
-		phydev->link = 0;
-	}
+	/*set delay config*/
+	ret = ytphy_of_config(phydev);
+	if (ret < 0)
+		return ret;
+
+	val = ytphy_read_ext(phydev, YT8521_EXT_CLK_GATE);
+	if (val < 0)
+		return val;
+
+	val &= ~(1 << 12);
+	ret = ytphy_write_ext(phydev, YT8521_EXT_CLK_GATE, val);
+	if (ret < 0)
+		return ret;
 
 	return 0;
 }
 
-static int yt8521_startup(struct phy_device *phydev)
+static int yt8531_config(struct phy_device *phydev)
 {
-	int retval;
+	int ret;
 
-	retval = genphy_update_link(phydev);
-	if (retval)
-		return retval;
+	ret = 0;
+	genphy_config_aneg(phydev);
 
-	return yt8521_parse_status(phydev);
+	/*set delay config*/
+	ret = ytphy_of_config(phydev);
+	if (ret < 0)
+		return ret;
+	return 0;
 }
 
-static struct phy_driver YT8511_driver = {
-	.name = "YuTai YT8511",
-	.uid = 0x0000010a,
-	.mask = 0x00000fff,
-	.features = PHY_GBIT_FEATURES,
-	.config = &yt8511_config,
-	.startup = &genphy_startup,
-	.shutdown = &genphy_shutdown,
+static struct phy_driver YT8512_driver = {
+	.name          = "YuTai YT8512",
+	.uid           = 0x00000118,
+	.mask          = 0x00000fff,
+	.features      = PHY_GBIT_FEATURES,
+	.config        = &yt8512_config,
+	.startup       = &ytphy_startup,
+	.shutdown      = &genphy_shutdown,
 };
 
 static struct phy_driver YT8521_driver = {
@@ -289,14 +374,25 @@ static struct phy_driver YT8521_driver = {
 	.mask = 0x00000fff,
 	.features = PHY_GBIT_FEATURES,
 	.config = &yt8521_config,
-	.startup = &yt8521_startup,
+	.startup = &ytphy_startup,
 	.shutdown = &genphy_shutdown,
 };
 
+static struct phy_driver YT8531_driver = {
+	.name          = "YT8531 Gigabit Ethernet",
+	.uid           = PHY_ID_YT8531,
+	.mask          = MOTORCOMM_PHY_ID_MASK,
+	.features      = PHY_GBIT_FEATURES,
+	.config        = &yt8531_config,
+	.startup       = &ytphy_startup,
+	.shutdown      = &genphy_shutdown,
+};
+
 int phy_yutai_init(void)
 {
-	phy_register(&YT8511_driver);
+	phy_register(&YT8512_driver);
 	phy_register(&YT8521_driver);
+	phy_register(&YT8531_driver);
 
 	return 0;
 }

+ 20 - 0
include/configs/starfive-evb.h

@@ -98,6 +98,24 @@
 #define TYPE_GUID_LOADER2	"2E54B353-1271-4842-806F-E436D6AF6985"
 #define TYPE_GUID_SYSTEM	"0FC63DAF-8483-4772-8E79-3D69D8477DE4"
 
+#define CHIPA_GMAC_SET \
+	"chipa_gmac_set="	\
+	"fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_10 <0x1>;"	\
+	"fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_100 <0x1>;"	\
+	"fdt set /soc/ethernet@16030000/ethernet-phy@0 tx_inverted_1000 <0x1>;\0"
+
+#define CHIPA_SET	\
+	"chipa_set="				\
+	"if test ${chip_vision} = B; then "	\
+		"run chipa_gmac_set;"		\
+	"fi; \0"				\
+	"chipa_set_uboot="			\
+	"fdt addr ${fdtcontroladdr};"		\
+	"run chipa_set;\0"			\
+	"chipa_set_linux="			\
+	"fdt addr ${fdt_addr_r};"		\
+	"run chipa_set;\0"
+
 #define PARTS_DEFAULT							\
 	"name=loader1,start=17K,size=1M,type=${type_guid_gpt_loader1};" \
 	"name=loader2,size=4MB,type=${type_guid_gpt_loader2};"		\
@@ -113,6 +131,8 @@
 	"script_size_f=0x1000\0"			\
 	"pxefile_addr_r=0x88200000\0"			\
 	"ramdisk_addr_r=0x88300000\0"			\
+	CHIPA_GMAC_SET					\
+	CHIPA_SET					\
 	"type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \
 	"type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \
 	"type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0"	\