Baseline update from LYNQ_SDK_ASR_T108_V05.03.01.00(kernel build error.)
Change-Id: I56fc72cd096e82c589920026553170e5cb9692eb
diff --git a/marvell/linux/drivers/net/ethernet/asr/emac_eth.c b/marvell/linux/drivers/net/ethernet/asr/emac_eth.c
old mode 100644
new mode 100755
index 5aed7ec..d407676
--- a/marvell/linux/drivers/net/ethernet/asr/emac_eth.c
+++ b/marvell/linux/drivers/net/ethernet/asr/emac_eth.c
@@ -39,6 +39,7 @@
#include <linux/cputype.h>
#include <linux/iopoll.h>
#include <linux/genalloc.h>
+#include <linux/regulator/consumer.h>
#ifdef CONFIG_DEBUG_FS
#include <linux/debugfs.h>
@@ -56,6 +57,7 @@
#define DRIVER_NAME "asr_emac"
+#define CLOSE_AIB_POWER_DOMAIN 1
#define AXI_PHYS_BASE 0xd4200000
#define AIB_GMAC_IO_REG 0xD401E804
@@ -131,6 +133,7 @@
static void emac_alloc_rx_desc_buffers(struct emac_priv *priv);
static int emac_phy_connect(struct net_device *dev);
+struct regulator *g_vcc3v3_gmac= NULL;
/* for falcon */
struct emac_regdata asr_emac_regdata_v1 = {
.support_dual_vol_power = 1,
@@ -836,7 +839,7 @@
writel(AKEY_ASFAR, apbc_asfar);
writel(AKEY_ASSAR, apbc_asfar + 4);
tmp = readl(aib_emac_io);
-
+priv->power_domain = 0;
/* 0= power down, only set power down when vol = 0 */
if (priv->power_domain) {
tmp &= ~(0x1 << 2); /* 3.3v */
@@ -1753,6 +1756,11 @@
{
struct net_device *ndev = priv->ndev;
int ret, val;
+#if CLOSE_AIB_POWER_DOMAIN
+ void __iomem *aib_emac_io;
+ void __iomem *apbc_asfar;
+ u32 tmp;
+#endif
#ifdef WAN_LAN_AUTO_ADAPT
u32 phy_id;
#endif
@@ -1763,6 +1771,20 @@
ret = emac_phy_connect(ndev);
if (ret) {
pr_err("%s phy_connet failed\n", __func__);
+#if CLOSE_AIB_POWER_DOMAIN
+ printk("===> enter emac_close_aib_power_domain\n");
+ aib_emac_io = ioremap(AIB_GMAC_IO_REG, 4);
+ apbc_asfar = ioremap(APBC_ASFAR, 8);
+ writel(AKEY_ASFAR, apbc_asfar);
+ writel(AKEY_ASSAR, apbc_asfar + 4);
+ writel(0x81, aib_emac_io);
+ writel(AKEY_ASFAR, apbc_asfar);
+ writel(AKEY_ASSAR, apbc_asfar + 4);
+ tmp = readl(aib_emac_io);
+ iounmap(apbc_asfar);
+ iounmap(aib_emac_io);
+ printk("===> exit emac_close_aib_power_domain = 0x%x\n", tmp);
+#endif
return ret;
}
@@ -3934,9 +3956,13 @@
emac_phy_interface_config(priv, phy_interface);
if (phy_interface != PHY_INTERFACE_MODE_RMII)
pinctrl_select_state(priv->pinctrl, priv->rgmii_pins);
-
- phydev = of_phy_connect(dev, np,
- &emac_adjust_link, 0, phy_interface);
+ phydev = phy_find_first(priv->mii);
+ if (!phydev) {
+ printk("%s: no PHY found\n", dev->name);
+ return -ENODEV;
+ }
+ phy_connect_direct(dev, phydev, emac_adjust_link, phy_interface); /* phy_start_machine */
+ //phydev = of_phy_connect(dev, np,&emac_adjust_link, 0, phy_interface);
if (IS_ERR_OR_NULL(phydev)) {
pr_err("Could not attach to PHY\n");
emac_power_down(priv);
@@ -4466,6 +4492,326 @@
}
#endif
+
+
+
+long g_PhyVersionNumber = 0;
+
+
+static ssize_t phy_version_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+
+ len = sprintf(buf, "phy_version = 0x%x\n", g_PhyVersionNumber);
+
+ return (ssize_t)len;
+}
+
+static ssize_t phy_version_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ int reg, val, devad = 0;
+
+ struct emac_priv *priv = dev_get_drvdata(dev);
+
+ sscanf(buf, "%d", &val);
+ if(val == 1)
+ {
+ devad = 0x1f;
+ reg = 0x113;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e);
+
+ }
+ g_PhyVersionNumber = val;
+
+ return size;
+}
+
+
+static ssize_t lpsd_sleep_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ int reg, val, devad = 0;
+ struct emac_priv *priv = dev_get_drvdata(dev);
+
+ devad = 0x3;
+ reg = 0x8700;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e);
+
+ len = sprintf(buf, "phy_version = 0x%x\n", val);
+
+ return (ssize_t)len;
+}
+
+static ssize_t lpsd_sleep_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ int reg, val, devad = 0;
+
+ struct emac_priv *priv = dev_get_drvdata(dev);
+
+ sscanf(buf, "%d", &val);
+ if(val == 1) //enter lpsd sleep mode
+ {
+ devad = 0x3;
+ reg = 0x8700;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e);
+
+ printk("lpsd sleep mode : reg3.8700 = 0x%x", val);
+ msleep(200);
+
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e, (val | BIT(0)));
+
+ }else
+ {
+
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e);
+
+ printk("lpsd sleep mode : reg3.8700 = 0x%x", val);
+ msleep(200);
+
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e, (val | ~BIT(0)));
+ }
+
+ return size;
+}
+
+
+static int mode_type = -1;
+static int enter_only_one = 0;
+
+
+static ssize_t gmac_master_or_slave_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ int val = 0;
+ int reg = 0;
+ int devad = 0;
+ int ret = 0;
+
+ struct emac_priv *priv = dev_get_drvdata(dev);
+
+ //read mode_type
+ ret = sscanf(buf, "%d", &mode_type);
+ if(ret < 1)
+ {
+ printk(KERN_ERR "Please enter the number 0-3 to enable the corresponding mode \n"
+ "Enter values in the non-0-3 range to get pattern description \n");
+ return size;
+ }
+
+ //Judgment model
+ if (mode_type < 0 || mode_type > 3) {
+ printk(KERN_DEBUG "Please enter the number range 0-3\n"
+ "0: Set the slave mode \n"
+ "1: Set the main mode \n"
+ "2: indicates setting SQI value view mode \n"
+ "3: Set the VCT value view mode \n"
+ "After the mode is set, the corresponding value can be obtained\n");
+ return ret ? ret : size;
+ }
+
+ //Set the Ethernet slave mode
+ if (mode_type == 0)
+ {
+ devad = 0x1;
+ reg = 0x834;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e);
+ msleep(200);
+
+ val &= ~BIT(14);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, val );
+
+ }
+ //Set the Ethernet master mode
+ else if (mode_type == 1)
+ {
+ devad = 0x1;
+ reg = 0x834;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e);
+ msleep(200);
+
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, val | BIT(14));
+
+
+ }
+
+ return size;
+}
+
+
+static ssize_t gmac_master_or_slave_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int len = 0;
+ int val = 0;
+ int reg = 0;
+ int devad = 0;
+ int ret = 0;
+ struct emac_priv *priv = dev_get_drvdata(dev);
+
+ if(enter_only_one == 1)
+ {
+ return 0;
+ }
+ enter_only_one = 1;
+
+ //Read the network master/slave
+ if (mode_type == 0 || mode_type == 1)
+ {
+ devad = 0x1;
+ reg = 0x834;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e) & BIT(14);
+ if(val)
+ memcpy(buf, "Master\n",7);
+ else
+ memcpy(buf, "Slave\n", 6);
+
+ printk(KERN_DEBUG "mode_type %d - gmac_master_or_slave is %s\n", mode_type, buf);
+
+ }
+
+ //Obtain the cable quality SQI value
+ else if(mode_type == 2)
+ {
+ devad = 0x1;
+ reg = 0x8B10;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0x0d, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0x0d, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0x0e);
+ sprintf(buf, "0x%x\n", val);
+ sprintf(buf, "SQI : 0x%x\n", val);
+ printk(KERN_DEBUG "mode_type %d - SQI is 0x%x", mode_type, val);
+
+ }
+
+ //Obtain short circuit, open circuit and normal connection of VCT
+ else if(mode_type == 3)
+ {
+ //--TDR Enable
+ devad = 0x1;
+ reg = 0x8B00;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, BIT(14));
+
+ msleep(200);
+
+ //--TDR Start
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, BIT(12) | BIT(14));
+
+ msleep(20);
+ //--Read VCT
+ devad = 0x1;
+ reg = 0x8B02;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0xe);
+
+ printk(KERN_DEBUG "Open status: %s - Short status: %s\n",
+ (val & BIT(1)) ? "Open" : "Normal", (val & BIT(0)) ? "Short" : "Normal");
+ sprintf(buf, "Open status: %s\nShort status: %s\n",
+ (val & BIT(1)) ? "Open" : "Normal", (val & BIT(0)) ? "Short" : "Normal");
+
+ reg = 0x8B01;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ val = mdiobus_read(priv->mii, priv->ndev->phydev->mdio.addr, 0xe);
+
+ sprintf(buf, "%sDistance status: 0x%x\n", buf, val);
+ printk(KERN_DEBUG "mode_type %d - Distance status is 0x%x\n", mode_type, val);
+
+ //--TDR Disable
+ devad = 0x1;
+ reg = 0x8B00;
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, reg);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xd, 0x4000 | devad);
+ mdiobus_write(priv->mii, priv->ndev->phydev->mdio.addr, 0xe, 0x0);
+
+
+ }
+ else{
+ sprintf(buf, "Please enter the number range 0-3\n"
+ "0: Set the slave mode \n"
+ "1: Set the main mode \n"
+ "2: indicates setting SQI value view mode \n"
+ "3: Set the VCT value view mode \n"
+ "After the mode is set, the corresponding value can be obtained\n");
+ printk(KERN_DEBUG "Please enter the number range 0-3\n"
+ "0: Set the slave mode \n"
+ "1: Set the main mode \n"
+ "2: indicates setting SQI value view mode \n"
+ "3: Set the VCT value view mode \n"
+ "After the mode is set, the corresponding value can be obtained\n");
+ }
+ enter_only_one = 0;
+
+ return strlen(buf);
+}
+
+
+
+static DEVICE_ATTR(lpsd_sleep, S_IRUGO | S_IWUSR, lpsd_sleep_show, lpsd_sleep_store);
+static DEVICE_ATTR(phy_version, S_IRUGO | S_IWUSR, phy_version_show, phy_version_store);
+static DEVICE_ATTR(gmac_master_or_slave, S_IRUGO | S_IWUSR, gmac_master_or_slave_show, gmac_master_or_slave_store);
+
+
+static struct attribute *ethrnet_opera_attrs[] = {
+ &dev_attr_lpsd_sleep.attr,
+ &dev_attr_phy_version.attr,
+ &dev_attr_gmac_master_or_slave.attr,
+ NULL,
+};
+
+static const struct attribute_group demo_attr_grp = {
+
+ .attrs = ethrnet_opera_attrs,
+
+};
+
static int emac_probe(struct platform_device *pdev)
{
struct emac_priv *priv;
@@ -4480,6 +4826,7 @@
struct dentry *emac_clk_tuning;
#endif
int ret;
+ struct regulator *vcc3v3_gmac;
ndev = alloc_etherdev(sizeof(struct emac_priv));
if (!ndev) {
@@ -4585,6 +4932,18 @@
priv->wolopts = 0;
}
+ vcc3v3_gmac = devm_regulator_get(dev, "vmmc");
+ if (!IS_ERR(vcc3v3_gmac))
+ {
+ if( regulator_set_voltage(vcc3v3_gmac, 1800000,1800000))
+ pr_err("fail to set regulator vcc3v3_gmac to 1.8v\n");
+
+ if (!regulator_is_enabled(vcc3v3_gmac) && regulator_enable(vcc3v3_gmac))
+ pr_err("fail to enable regulator vcc3v3_gmac\n");
+ }
+
+ g_vcc3v3_gmac = vcc3v3_gmac;
+
priv->pinctrl = devm_pinctrl_get(dev);
if (IS_ERR(priv->pinctrl))
dev_err(dev, "could not get pinctrl handle\n");
@@ -4755,6 +5114,11 @@
}
#endif
}
+
+ sysfs_create_group(&pdev->dev.kobj,&demo_attr_grp);
+
+
+ //device_create_file(&pdev->dev, &dev_attr_cable_sqi_value);
return 0;
err_mdio_deinit: