162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Applied Micro X-Gene SoC Ethernet v2 Driver
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2017, Applied Micro Circuits Corporation
662306a36Sopenharmony_ci * Author(s): Iyappan Subramanian <isubramanian@apm.com>
762306a36Sopenharmony_ci *	      Keyur Chudgar <kchudgar@apm.com>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "main.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_civoid xge_wr_csr(struct xge_pdata *pdata, u32 offset, u32 val)
1362306a36Sopenharmony_ci{
1462306a36Sopenharmony_ci	void __iomem *addr = pdata->resources.base_addr + offset;
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci	iowrite32(val, addr);
1762306a36Sopenharmony_ci}
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciu32 xge_rd_csr(struct xge_pdata *pdata, u32 offset)
2062306a36Sopenharmony_ci{
2162306a36Sopenharmony_ci	void __iomem *addr = pdata->resources.base_addr + offset;
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci	return ioread32(addr);
2462306a36Sopenharmony_ci}
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciint xge_port_reset(struct net_device *ndev)
2762306a36Sopenharmony_ci{
2862306a36Sopenharmony_ci	struct xge_pdata *pdata = netdev_priv(ndev);
2962306a36Sopenharmony_ci	struct device *dev = &pdata->pdev->dev;
3062306a36Sopenharmony_ci	u32 data, wait = 10;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	xge_wr_csr(pdata, ENET_CLKEN, 0x3);
3362306a36Sopenharmony_ci	xge_wr_csr(pdata, ENET_SRST, 0xf);
3462306a36Sopenharmony_ci	xge_wr_csr(pdata, ENET_SRST, 0);
3562306a36Sopenharmony_ci	xge_wr_csr(pdata, CFG_MEM_RAM_SHUTDOWN, 1);
3662306a36Sopenharmony_ci	xge_wr_csr(pdata, CFG_MEM_RAM_SHUTDOWN, 0);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	do {
3962306a36Sopenharmony_ci		usleep_range(100, 110);
4062306a36Sopenharmony_ci		data = xge_rd_csr(pdata, BLOCK_MEM_RDY);
4162306a36Sopenharmony_ci	} while (data != MEM_RDY && wait--);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci	if (data != MEM_RDY) {
4462306a36Sopenharmony_ci		dev_err(dev, "ECC init failed: %x\n", data);
4562306a36Sopenharmony_ci		return -ETIMEDOUT;
4662306a36Sopenharmony_ci	}
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	xge_wr_csr(pdata, ENET_SHIM, DEVM_ARAUX_COH | DEVM_AWAUX_COH);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	return 0;
5162306a36Sopenharmony_ci}
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic void xge_traffic_resume(struct net_device *ndev)
5462306a36Sopenharmony_ci{
5562306a36Sopenharmony_ci	struct xge_pdata *pdata = netdev_priv(ndev);
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	xge_wr_csr(pdata, CFG_FORCE_LINK_STATUS_EN, 1);
5862306a36Sopenharmony_ci	xge_wr_csr(pdata, FORCE_LINK_STATUS, 1);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	xge_wr_csr(pdata, CFG_LINK_AGGR_RESUME, 1);
6162306a36Sopenharmony_ci	xge_wr_csr(pdata, RX_DV_GATE_REG, 1);
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_civoid xge_port_init(struct net_device *ndev)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	struct xge_pdata *pdata = netdev_priv(ndev);
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	pdata->phy_speed = SPEED_1000;
6962306a36Sopenharmony_ci	xge_mac_init(pdata);
7062306a36Sopenharmony_ci	xge_traffic_resume(ndev);
7162306a36Sopenharmony_ci}
72