Commit 761d4be5 authored by Iyappan Subramanian's avatar Iyappan Subramanian Committed by David S. Miller
Browse files

drivers: net: xgene: fix RGMII 10/100Mb mode



This patch fixes the RGMII 10/100M mode by reprogramming the clock.

Signed-off-by: default avatarIyappan Subramanian <isubramanian@apm.com>
Tested-by: default avatarFushen Chen <fchen@apm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b73c8bfd
Loading
Loading
Loading
Loading
+47 −2
Original line number Original line Diff line number Diff line
@@ -459,6 +459,45 @@ static void xgene_gmac_reset(struct xgene_enet_pdata *pdata)
	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0);
	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0);
}
}


static void xgene_enet_configure_clock(struct xgene_enet_pdata *pdata)
{
	struct device *dev = &pdata->pdev->dev;

	if (dev->of_node) {
		struct clk *parent = clk_get_parent(pdata->clk);

		switch (pdata->phy_speed) {
		case SPEED_10:
			clk_set_rate(parent, 2500000);
			break;
		case SPEED_100:
			clk_set_rate(parent, 25000000);
			break;
		default:
			clk_set_rate(parent, 125000000);
			break;
		}
	}
#ifdef CONFIG_ACPI
	else {
		switch (pdata->phy_speed) {
		case SPEED_10:
			acpi_evaluate_object(ACPI_HANDLE(dev),
					     "S10", NULL, NULL);
			break;
		case SPEED_100:
			acpi_evaluate_object(ACPI_HANDLE(dev),
					     "S100", NULL, NULL);
			break;
		default:
			acpi_evaluate_object(ACPI_HANDLE(dev),
					     "S1G", NULL, NULL);
			break;
		}
	}
#endif
}

static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
{
{
	struct device *dev = &pdata->pdev->dev;
	struct device *dev = &pdata->pdev->dev;
@@ -477,12 +516,14 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
	switch (pdata->phy_speed) {
	switch (pdata->phy_speed) {
	case SPEED_10:
	case SPEED_10:
		ENET_INTERFACE_MODE2_SET(&mc2, 1);
		ENET_INTERFACE_MODE2_SET(&mc2, 1);
		intf_ctl &= ~(ENET_LHD_MODE | ENET_GHD_MODE);
		CFG_MACMODE_SET(&icm0, 0);
		CFG_MACMODE_SET(&icm0, 0);
		CFG_WAITASYNCRD_SET(&icm2, 500);
		CFG_WAITASYNCRD_SET(&icm2, 500);
		rgmii &= ~CFG_SPEED_1250;
		rgmii &= ~CFG_SPEED_1250;
		break;
		break;
	case SPEED_100:
	case SPEED_100:
		ENET_INTERFACE_MODE2_SET(&mc2, 1);
		ENET_INTERFACE_MODE2_SET(&mc2, 1);
		intf_ctl &= ~ENET_GHD_MODE;
		intf_ctl |= ENET_LHD_MODE;
		intf_ctl |= ENET_LHD_MODE;
		CFG_MACMODE_SET(&icm0, 1);
		CFG_MACMODE_SET(&icm0, 1);
		CFG_WAITASYNCRD_SET(&icm2, 80);
		CFG_WAITASYNCRD_SET(&icm2, 80);
@@ -490,12 +531,15 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
		break;
		break;
	default:
	default:
		ENET_INTERFACE_MODE2_SET(&mc2, 2);
		ENET_INTERFACE_MODE2_SET(&mc2, 2);
		intf_ctl &= ~ENET_LHD_MODE;
		intf_ctl |= ENET_GHD_MODE;
		intf_ctl |= ENET_GHD_MODE;

		CFG_MACMODE_SET(&icm0, 2);
		CFG_WAITASYNCRD_SET(&icm2, 0);
		if (dev->of_node) {
		if (dev->of_node) {
			CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay);
			CFG_TXCLK_MUXSEL0_SET(&rgmii, pdata->tx_delay);
			CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay);
			CFG_RXCLK_MUXSEL0_SET(&rgmii, pdata->rx_delay);
		}
		}
		rgmii |= CFG_SPEED_1250;


		xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value);
		xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value);
		value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
		value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX;
@@ -503,7 +547,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
		break;
		break;
	}
	}


	mc2 |= FULL_DUPLEX2;
	mc2 |= FULL_DUPLEX2 | PAD_CRC;
	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
	xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2);
	xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);
	xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl);


@@ -522,6 +566,7 @@ static void xgene_gmac_init(struct xgene_enet_pdata *pdata)
	/* Rtype should be copied from FP */
	/* Rtype should be copied from FP */
	xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0);
	xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0);
	xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii);
	xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii);
	xgene_enet_configure_clock(pdata);


	/* Rx-Tx traffic resume */
	/* Rx-Tx traffic resume */
	xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0);
	xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0);
+1 −0
Original line number Original line Diff line number Diff line
@@ -181,6 +181,7 @@ enum xgene_enet_rm {
#define ENET_LHD_MODE			BIT(25)
#define ENET_LHD_MODE			BIT(25)
#define ENET_GHD_MODE			BIT(26)
#define ENET_GHD_MODE			BIT(26)
#define FULL_DUPLEX2			BIT(0)
#define FULL_DUPLEX2			BIT(0)
#define PAD_CRC				BIT(2)
#define SCAN_AUTO_INCR			BIT(5)
#define SCAN_AUTO_INCR			BIT(5)
#define TBYT_ADDR			0x38
#define TBYT_ADDR			0x38
#define TPKT_ADDR			0x39
#define TPKT_ADDR			0x39
+0 −1
Original line number Original line Diff line number Diff line
@@ -698,7 +698,6 @@ static int xgene_enet_open(struct net_device *ndev)
	else
	else
		schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF);
		schedule_delayed_work(&pdata->link_work, PHY_POLL_LINK_OFF);


	netif_carrier_off(ndev);
	netif_start_queue(ndev);
	netif_start_queue(ndev);


	return ret;
	return ret;