#define STMMAC_COAL_TIMER(x) (jiffies + usecs_to_jiffies(x))
-static int gmac_clk_enable(struct stmmac_priv *priv) {
- int phy_iface = -1;
-
- if ((priv->plat) && (priv->plat->bsp_priv)) {
- struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
- phy_iface = bsp_priv->phy_iface;
- } else {
- pr_err("%s:get PHY interface type failed!", __func__);
- }
-
- if (!priv->clk_enable) {
- if (phy_iface == PHY_INTERFACE_MODE_RMII) {
- clk_set_rate(priv->stmmac_clk, 50000000);
- clk_prepare_enable(priv->mac_clk_rx);
- clk_prepare_enable(priv->clk_mac_ref);
- clk_prepare_enable(priv->clk_mac_refout);
- }
-
- clk_prepare_enable(priv->aclk_mac);
- clk_prepare_enable(priv->pclk_mac);
- clk_prepare_enable(priv->mac_clk_tx);
-
- priv->clk_enable = true;
- }
-
- return 0;
-}
-
-static int gmac_clk_disable(struct stmmac_priv *priv) {
- int phy_iface = -1;
-
- if ((priv->plat) && (priv->plat->bsp_priv)) {
- struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
- phy_iface = bsp_priv->phy_iface;
- } else {
- pr_err("%s:get PHY interface type failed!", __func__);
- }
-
- if (priv->clk_enable) {
- if (phy_iface == PHY_INTERFACE_MODE_RMII) {
- clk_disable_unprepare(priv->mac_clk_rx);
- clk_disable_unprepare(priv->clk_mac_ref);
- clk_disable_unprepare(priv->clk_mac_refout);
- }
-
- clk_disable_unprepare(priv->aclk_mac);
- clk_disable_unprepare(priv->pclk_mac);
- clk_disable_unprepare(priv->mac_clk_tx);
-
- priv->clk_enable = false;
- }
-
- return 0;
-}
-
/**
* stmmac_verify_args - verify the driver parameters.
* Description: it verifies if some wrong parameter is passed to the driver.
}
}
+static int gPhyReg;
+
+static ssize_t show_phy_reg(struct device *dev,
+ struct device_attribute *attr, char *buf) {
+ int ret = snprintf(buf, PAGE_SIZE, "current phy reg = 0x%x\n", gPhyReg);
+ return ret;
+}
+
+static ssize_t set_phy_reg(struct device *dev,struct device_attribute *attr,
+ const char *buf, size_t count) {
+ int ovl;
+ int r = kstrtoint(buf, 0, &ovl);
+ if (r) printk("kstrtoint failed\n");
+ gPhyReg = ovl;
+ printk("%s----ovl=0x%x\n", __FUNCTION__, ovl);
+ return count;
+}
+
+static ssize_t show_phy_regValue(struct device *dev,
+ struct device_attribute *attr, char *buf) {
+ struct phy_device *phy_dev = dev_get_drvdata(dev);
+ int ret = 0;
+ int val;
+#if 0
+ val = phy_read(phy_dev, gPhyReg);
+ ret = snprintf(buf, PAGE_SIZE, "phy reg 0x%x = 0x%x\n", gPhyReg, val);
+#else
+ int i=0;
+
+ for (i=0; i<32; i++) {
+ printk("%d: 0x%x\n", i, phy_read(phy_dev, i));
+ }
+
+ val = phy_read(phy_dev, gPhyReg);
+ ret = snprintf(buf, PAGE_SIZE, "phy reg 0x%x = 0x%x\n", gPhyReg, val);
+#endif
+ return ret;
+}
+
+static ssize_t set_phy_regValue(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count) {
+ int ovl;
+ int ret;
+
+ struct phy_device *phy_dev = dev_get_drvdata(dev);
+ ret = kstrtoint(buf, 0, &ovl);
+ printk("%s----reg 0x%x: ovl=0x%x\n", __FUNCTION__, gPhyReg, ovl);
+ phy_write(phy_dev, gPhyReg, ovl);
+ return count;
+}
+
+static struct device_attribute phy_reg_attrs[] = {
+ __ATTR(phy_reg, S_IRUGO | S_IWUSR, show_phy_reg, set_phy_reg),
+ __ATTR(phy_regValue, S_IRUGO | S_IWUSR, show_phy_regValue, set_phy_regValue)
+};
+
+int gmac_create_sysfs(struct phy_device * phy_dev) {
+ int r;
+ int t;
+
+ dev_set_drvdata(&phy_dev->dev, phy_dev);
+ for (t = 0; t < ARRAY_SIZE(phy_reg_attrs); t++) {
+ r = device_create_file(&phy_dev->dev,&phy_reg_attrs[t]);
+ if (r) {
+ dev_err(&phy_dev->dev, "failed to create sysfs file\n");
+ return r;
+ }
+ }
+
+ return 0;
+}
+
/**
* stmmac_init_phy - PHY initialization
* @dev: net device structure
priv->phydev = phydev;
+ gmac_create_sysfs(phydev);
+
return 0;
}
struct stmmac_priv *priv = netdev_priv(dev);
int ret;
- clk_prepare_enable(priv->stmmac_clk);
- gmac_clk_enable(priv);
-
if ((priv->plat) && (priv->plat->bsp_priv)) {
struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
- if ((bsp_priv) && (bsp_priv->phy_power_on)) {
- bsp_priv->phy_power_on(priv->plat, 1);
+ if (bsp_priv) {
+ if (bsp_priv->phy_power_on) {
+ bsp_priv->phy_power_on(true);
+ }
+ if (bsp_priv->gmac_clk_enable) {
+ bsp_priv->gmac_clk_enable(true);
+ }
}
}
stmmac_check_ether_addr(priv);
- if (priv->pcs != STMMAC_PCS_SGMII && priv->pcs != STMMAC_PCS_TBI &&
- priv->pcs != STMMAC_PCS_RTBI && !priv->mdio_registered) {
- /* MDIO bus Registration */
- ret = stmmac_mdio_register(priv->dev);
- if (ret < 0) {
- pr_debug("%s: MDIO bus (id: %d) registration failed",
- __func__, priv->plat->bus_id);
- goto open_error;
- }
- priv->mdio_registered = true;
- }
if (priv->pcs != STMMAC_PCS_SGMII && priv->pcs != STMMAC_PCS_TBI &&
priv->pcs != STMMAC_PCS_RTBI) {
+ if(!priv->mdio_registered) {
+ /* MDIO bus Registration */
+ ret = stmmac_mdio_register(priv->dev);
+ if (ret < 0) {
+ pr_debug("%s: MDIO bus (id: %d) registration failed",
+ __func__, priv->plat->bus_id);
+ goto open_error;
+ }
+ priv->mdio_registered = true;
+ }
ret = stmmac_init_phy(dev);
if (ret) {
pr_err("%s: Cannot attach to PHY (error: %d)\n",
if (priv->phydev)
phy_disconnect(priv->phydev);
- clk_disable_unprepare(priv->stmmac_clk);
- gmac_clk_disable(priv);
+ if ((priv->plat) && (priv->plat->bsp_priv)) {
+ struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
+ if ((bsp_priv) && (bsp_priv->gmac_clk_enable)) {
+ bsp_priv->gmac_clk_enable(false);
+ }
+ }
return ret;
}
#ifdef CONFIG_GMAC_DEBUG_FS
stmmac_exit_fs();
#endif
- clk_disable_unprepare(priv->stmmac_clk);
- gmac_clk_disable(priv);
stmmac_release_ptp(priv);
if ((priv->plat) && (priv->plat->bsp_priv)) {
struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
- if ((bsp_priv) && (bsp_priv->phy_power_on)) {
- bsp_priv->phy_power_on(priv->plat, 0);
+ if (bsp_priv) {
+ if (bsp_priv->phy_power_on) {
+ bsp_priv->phy_power_on(false);
+ }
+ if (bsp_priv->gmac_clk_enable) {
+ bsp_priv->gmac_clk_enable(false);
+ }
}
}
}
priv->mdio_registered = false;
- priv->clk_enable = false;
-
- priv->mac_clk_rx = clk_get(priv->device,"mac_clk_rx");
- if (IS_ERR(priv->mac_clk_rx)) {
- pr_warn("%s: warning: cannot get mac_clk_rx clock\n", __func__);
- goto error_clk_get;
- }
-
- priv->mac_clk_tx = clk_get(priv->device,"mac_clk_tx");
- if (IS_ERR(priv->mac_clk_tx)) {
- pr_warn("%s: warning: cannot get mac_clk_tx clock\n", __func__);
- goto error_clk_get;
- }
-
- priv->clk_mac_ref = clk_get(priv->device,"clk_mac_ref");
- if (IS_ERR(priv->clk_mac_ref)) {
- pr_warn("%s: warning: cannot get clk_mac_ref clock\n", __func__);
- goto error_clk_get;
- }
-
- priv->clk_mac_refout = clk_get(priv->device,"clk_mac_refout");
- if (IS_ERR(priv->clk_mac_refout)) {
- pr_warn("%s: warning: cannot get clk_mac_refout clock\n", __func__);
- goto error_clk_get;
- }
-
- priv->aclk_mac = clk_get(priv->device,"aclk_mac");
- if (IS_ERR(priv->aclk_mac)) {
- pr_warn("%s: warning: cannot get aclk_mac clock\n", __func__);
- goto error_clk_get;
- }
-
- priv->pclk_mac = clk_get(priv->device,"pclk_mac");
- if (IS_ERR(priv->pclk_mac)) {
- pr_warn("%s: warning: cannot get pclk_mac clock\n", __func__);
- goto error_clk_get;
- }
-
- priv->clk_mac_pll = clk_get(priv->device,"clk_mac_pll");
- if (IS_ERR(priv->clk_mac_pll)) {
- pr_warn("%s: warning: cannot get clk_mac_pll clock\n", __func__);
- goto error_clk_get;
- }
-
- priv->gmac_clkin = clk_get(priv->device,"gmac_clkin");
- if (IS_ERR(priv->gmac_clkin)) {
- pr_warn("%s: warning: cannot get gmac_clkin clock\n", __func__);
- goto error_clk_get;
- }
-
- priv->stmmac_clk = clk_get(priv->device, "clk_mac");
+ priv->stmmac_clk = ((struct bsp_priv *)(priv->plat->bsp_priv))->clk_mac;
if (IS_ERR(priv->stmmac_clk)) {
pr_warn("%s: warning: cannot get CSR clock\n", __func__);
goto error_clk_get;
}
-#ifdef CONFIG_GMAC_CLK_IN
- clk_set_parent(priv->stmmac_clk, priv->gmac_clkin);
-#else
- clk_set_parent(priv->stmmac_clk, priv->clk_mac_pll);
-#endif
-
/* If a specific clk_csr value is passed from the platform
* this means that the CSR Clock Range selection cannot be
* changed at run-time and it is fixed. Viceversa the driver'll try to
priv->clk_csr = priv->plat->clk_csr;
stmmac_check_pcs_mode(priv);
-
+#if 0
+ if (priv->pcs != STMMAC_PCS_RGMII && priv->pcs != STMMAC_PCS_TBI &&
+ priv->pcs != STMMAC_PCS_RTBI) {
+ /* MDIO bus Registration */
+ ret = stmmac_mdio_register(ndev);
+ if (ret < 0) {
+ pr_debug("%s: MDIO bus (id: %d) registration failed",
+ __func__, priv->plat->bus_id);
+ goto error_mdio_register;
+ }
+ }
+#endif
return priv;
-
-/*error_mdio_register:
+#if 0
+error_mdio_register:
clk_put(priv->stmmac_clk);
- clk_put(priv->clk_mac);
- clk_put(priv->mac_clk_rx);
- clk_put(priv->mac_clk_tx);
- clk_put(priv->clk_mac_ref);
- clk_put(priv->clk_mac_refout);
- clk_put(priv->aclk_mac);
- clk_put(priv->pclk_mac);*/
+#endif
error_clk_get:
unregister_netdev(ndev);
error_netdev_register:
else {
stmmac_set_mac(priv->ioaddr, false);
/* Disable clock in case of PWM is off */
- clk_disable_unprepare(priv->stmmac_clk);
- gmac_clk_disable(priv);
+ if ((priv->plat) && (priv->plat->bsp_priv)) {
+ struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
+ if ((bsp_priv) && (bsp_priv->gmac_clk_enable)) {
+ bsp_priv->gmac_clk_enable(false);
+ }
+ }
+
}
spin_unlock_irqrestore(&priv->lock, flags);
return 0;
priv->hw->mac->pmt(priv->ioaddr, 0);
else {
/* enable the clk prevously disabled */
- clk_prepare_enable(priv->stmmac_clk);
- gmac_clk_enable(priv);
+ if ((priv->plat) && (priv->plat->bsp_priv)) {
+ struct bsp_priv * bsp_priv = priv->plat->bsp_priv;
+ if ((bsp_priv) && (bsp_priv->gmac_clk_enable)) {
+ bsp_priv->gmac_clk_enable(true);
+ }
+ }
}
netif_device_attach(ndev);
#define grf_readl(offset) readl_relaxed(RK_GRF_VIRT + offset)
#define grf_writel(v, offset) do { writel_relaxed(v, RK_GRF_VIRT + offset); dsb(); } while (0)
-// RK3288_GRF_SOC_CON1
+//RK3288_GRF_SOC_CON1
+//RK3128_GRF_MAC_CON1
#define GMAC_PHY_INTF_SEL_RGMII ((0x01C0 << 16) | (0x0040))
#define GMAC_PHY_INTF_SEL_RMII ((0x01C0 << 16) | (0x0100))
#define GMAC_FLOW_CTRL ((0x0200 << 16) | (0x0200))
#define GMAC_RMII_MODE ((0x4000 << 16) | (0x4000))
#define GMAC_RMII_MODE_CLR ((0x4000 << 16) | (0x0000))
-// RK3288_GRF_SOC_CON3
+//RK3288_GRF_SOC_CON3
+//RK3128_GRF_MAC_CON0
#define GMAC_TXCLK_DLY_ENABLE ((0x4000 << 16) | (0x4000))
#define GMAC_TXCLK_DLY_DISABLE ((0x4000 << 16) | (0x0000))
#define GMAC_RXCLK_DLY_ENABLE ((0x8000 << 16) | (0x8000))
#define GMAC_RXCLK_DLY_DISABLE ((0x8000 << 16) | (0x0000))
-#if 0
-#define GMAC_CLK_RX_DL_CFG ((0x3F80 << 16) | (0x0800))
-#define GMAC_CLK_TX_DL_CFG ((0x007F << 16) | (0x0040))
-#else
#define GMAC_CLK_RX_DL_CFG(val) ((0x3F80 << 16) | (val<<7)) // 7bit
#define GMAC_CLK_TX_DL_CFG(val) ((0x007F << 16) | (val)) // 7bit
+
+
+#if 0 //3288
+#define SET_RGMII { \
+ grf_writel(GMAC_PHY_INTF_SEL_RGMII, RK3288_GRF_SOC_CON1); \
+ grf_writel(GMAC_RMII_MODE_CLR, RK3288_GRF_SOC_CON1); \
+ grf_writel(GMAC_RXCLK_DLY_ENABLE, RK3288_GRF_SOC_CON3); \
+ grf_writel(GMAC_TXCLK_DLY_ENABLE, RK3288_GRF_SOC_CON3); \
+ grf_writel(GMAC_CLK_RX_DL_CFG(0x10), RK3288_GRF_SOC_CON3); \
+ grf_writel(GMAC_CLK_TX_DL_CFG(0x30), RK3288_GRF_SOC_CON3); \
+ grf_writel(0xffffffff,RK3288_GRF_GPIO3D_E); \
+ grf_writel(grf_readl(RK3288_GRF_GPIO4B_E) | 0x3<<2<<16 | 0x3<<2, RK3288_GRF_GPIO4B_E); \
+ grf_writel(0xffffffff,RK3288_GRF_GPIO4A_E); \
+ }
+
+#define SET_RMII { \
+ grf_writel(GMAC_PHY_INTF_SEL_RMII, RK3288_GRF_SOC_CON1); \
+ grf_writel(GMAC_RMII_MODE, RK3288_GRF_SOC_CON1); \
+ }
+
+#define SET_RGMII_10M { \
+ grf_writel(GMAC_CLK_2_5M, RK3288_GRF_SOC_CON1); \
+ }
+
+#define SET_RGMII_100M { \
+ grf_writel(GMAC_CLK_25M, RK3288_GRF_SOC_CON1); \
+ }
+
+#define SET_RGMII_1000M { \
+ grf_writel(GMAC_CLK_125M, RK3288_GRF_SOC_CON1); \
+ }
+
+#define SET_RMII_10M { \
+ grf_writel(GMAC_RMII_CLK_2_5M, RK3288_GRF_SOC_CON1); \
+ grf_writel(GMAC_SPEED_10M, RK3288_GRF_SOC_CON1); \
+ }
+
+#define SET_RMII_100M { \
+ grf_writel(GMAC_RMII_CLK_25M, RK3288_GRF_SOC_CON1); \
+ grf_writel(GMAC_SPEED_100M, RK3288_GRF_SOC_CON1); \
+ }
+#else //3128
+#define SET_RGMII { \
+ grf_writel(GMAC_PHY_INTF_SEL_RGMII, RK312X_GRF_MAC_CON1); \
+ grf_writel(GMAC_RMII_MODE_CLR, RK312X_GRF_MAC_CON1); \
+ grf_writel(GMAC_RXCLK_DLY_ENABLE, RK312X_GRF_MAC_CON0); \
+ grf_writel(GMAC_TXCLK_DLY_ENABLE, RK312X_GRF_MAC_CON0); \
+ grf_writel(GMAC_CLK_RX_DL_CFG(0x10), RK312X_GRF_MAC_CON0); \
+ grf_writel(GMAC_CLK_TX_DL_CFG(0x30), RK312X_GRF_MAC_CON0); \
+ }
+
+#define SET_RMII { \
+ grf_writel(GMAC_PHY_INTF_SEL_RMII, RK312X_GRF_MAC_CON1); \
+ grf_writel(GMAC_RMII_MODE, RK312X_GRF_MAC_CON1); \
+ }
+
+#define SET_RGMII_10M { \
+ grf_writel(GMAC_CLK_2_5M, RK312X_GRF_MAC_CON1); \
+ }
+
+#define SET_RGMII_100M { \
+ grf_writel(GMAC_CLK_25M, RK312X_GRF_MAC_CON1); \
+ }
+
+#define SET_RGMII_1000M { \
+ grf_writel(GMAC_CLK_125M, RK312X_GRF_MAC_CON1); \
+ }
+
+#define SET_RMII_10M { \
+ grf_writel(GMAC_RMII_CLK_2_5M, RK312X_GRF_MAC_CON1); \
+ grf_writel(GMAC_SPEED_10M, RK312X_GRF_MAC_CON1); \
+ }
+
+#define SET_RMII_100M { \
+ grf_writel(GMAC_RMII_CLK_25M, RK312X_GRF_MAC_CON1); \
+ grf_writel(GMAC_SPEED_100M, RK312X_GRF_MAC_CON1); \
+ }
+
#endif
+
struct bsp_priv g_bsp_priv;
-static int phy_power_on(struct plat_stmmacenet_data *plat, int enable)
+int gmac_clk_init(struct device *device)
{
- struct bsp_priv * bsp_priv;
- //int ret;
+ struct bsp_priv * bsp_priv = &g_bsp_priv;
- printk("%s: enable = %d \n", __func__, enable);
+ bsp_priv->clk_enable = false;
+
+ bsp_priv->mac_clk_rx = clk_get(device,"mac_clk_rx");
+ if (IS_ERR(bsp_priv->mac_clk_rx)) {
+ pr_warn("%s: warning: cannot get mac_clk_rx clock\n", __func__);
+ }
+
+ bsp_priv->mac_clk_tx = clk_get(device,"mac_clk_tx");
+ if (IS_ERR(bsp_priv->mac_clk_tx)) {
+ pr_warn("%s: warning: cannot get mac_clk_tx clock\n", __func__);
+ }
+
+ bsp_priv->clk_mac_ref = clk_get(device,"clk_mac_ref");
+ if (IS_ERR(bsp_priv->clk_mac_ref)) {
+ pr_warn("%s: warning: cannot get clk_mac_ref clock\n", __func__);
+ }
+
+ bsp_priv->clk_mac_refout = clk_get(device,"clk_mac_refout");
+ if (IS_ERR(bsp_priv->clk_mac_refout)) {
+ pr_warn("%s: warning: cannot get clk_mac_refout clock\n", __func__);
+ }
+
+ bsp_priv->aclk_mac = clk_get(device,"aclk_mac");
+ if (IS_ERR(bsp_priv->aclk_mac)) {
+ pr_warn("%s: warning: cannot get aclk_mac clock\n", __func__);
+ }
+
+ bsp_priv->pclk_mac = clk_get(device,"pclk_mac");
+ if (IS_ERR(bsp_priv->pclk_mac)) {
+ pr_warn("%s: warning: cannot get pclk_mac clock\n", __func__);
+ }
- if ((plat) && (plat->bsp_priv)) {
- bsp_priv = plat->bsp_priv;
+ bsp_priv->clk_mac_pll = clk_get(device,"clk_mac_pll");
+ if (IS_ERR(bsp_priv->clk_mac_pll)) {
+ pr_warn("%s: warning: cannot get clk_mac_pll clock\n", __func__);
+ }
+
+ bsp_priv->gmac_clkin = clk_get(device,"gmac_clkin");
+ if (IS_ERR(bsp_priv->gmac_clkin)) {
+ pr_warn("%s: warning: cannot get gmac_clkin clock\n", __func__);
+ }
+
+ bsp_priv->clk_mac = clk_get(device, "clk_mac");
+ if (IS_ERR(bsp_priv->clk_mac)) {
+ pr_warn("%s: warning: cannot get clk_mac clock\n", __func__);
+ }
+
+#ifdef CONFIG_GMAC_CLK_IN
+ clk_set_parent(bsp_priv->clk_mac, bsp_priv->gmac_clkin);
+#else
+ clk_set_parent(bsp_priv->clk_mac, bsp_priv->clk_mac_pll);
+#endif
+ return 0;
+}
+
+static int gmac_clk_enable(bool enable) {
+ int phy_iface = -1;
+ struct bsp_priv * bsp_priv = &g_bsp_priv;
+ phy_iface = bsp_priv->phy_iface;
+
+ if (enable) {
+ if (!bsp_priv->clk_enable) {
+ if (phy_iface == PHY_INTERFACE_MODE_RMII) {
+ if (!IS_ERR(bsp_priv->clk_mac))
+ clk_set_rate(bsp_priv->clk_mac, 50000000);
+
+ if (!IS_ERR(bsp_priv->mac_clk_rx))
+ clk_prepare_enable(bsp_priv->mac_clk_rx);
+
+ if (!IS_ERR(bsp_priv->clk_mac_ref))
+ clk_prepare_enable(bsp_priv->clk_mac_ref);
+
+ if (!IS_ERR(bsp_priv->clk_mac_refout))
+ clk_prepare_enable(bsp_priv->clk_mac_refout);
+ }
+
+ if (!IS_ERR(bsp_priv->aclk_mac))
+ clk_prepare_enable(bsp_priv->aclk_mac);
+
+ if (!IS_ERR(bsp_priv->pclk_mac))
+ clk_prepare_enable(bsp_priv->pclk_mac);
+
+ if (!IS_ERR(bsp_priv->mac_clk_tx))
+ clk_prepare_enable(bsp_priv->mac_clk_tx);
+
+ if (!IS_ERR(bsp_priv->clk_mac))
+ clk_prepare_enable(bsp_priv->clk_mac);
+
+
+ bsp_priv->clk_enable = true;
+ }
} else {
- pr_err("%s: ERROR: platform data or private data is NULL.\n", __FUNCTION__);
+ if (bsp_priv->clk_enable) {
+ if (phy_iface == PHY_INTERFACE_MODE_RMII) {
+ if (!IS_ERR(bsp_priv->mac_clk_rx))
+ clk_disable_unprepare(bsp_priv->mac_clk_rx);
+
+ if (!IS_ERR(bsp_priv->clk_mac_ref))
+ clk_disable_unprepare(bsp_priv->clk_mac_ref);
+
+ if (!IS_ERR(bsp_priv->clk_mac_refout))
+ clk_disable_unprepare(bsp_priv->clk_mac_refout);
+ }
+
+ if (!IS_ERR(bsp_priv->aclk_mac))
+ clk_disable_unprepare(bsp_priv->aclk_mac);
+
+ if (!IS_ERR(bsp_priv->pclk_mac))
+ clk_disable_unprepare(bsp_priv->pclk_mac);
+
+ if (!IS_ERR(bsp_priv->mac_clk_tx))
+ clk_disable_unprepare(bsp_priv->mac_clk_tx);
+
+ if (!IS_ERR(bsp_priv->clk_mac))
+ clk_disable_unprepare(bsp_priv->clk_mac);
+
+ bsp_priv->clk_enable = false;
+ }
+ }
+
+ return 0;
+}
+
+static int power_on_by_pmu(bool enable) {
+ struct bsp_priv * bsp_priv = &g_bsp_priv;
+ struct regulator * ldo;
+ char * ldostr = bsp_priv->pmu_regulator;
+ int ret;
+
+ if (ldostr == NULL) {
+ pr_err("%s: no ldo found\n", __func__);
return -1;
}
+ ldo = regulator_get(NULL, ldostr);
+ if (ldo == NULL) {
+ pr_err("\n%s get ldo %s failed\n", __func__, ldostr);
+ } else {
+ if (enable) {
+ if(!regulator_is_enabled(ldo)) {
+ regulator_set_voltage(ldo, 3300000, 3300000);
+ ret = regulator_enable(ldo);
+ if(ret != 0){
+ pr_err("%s: faild to enable %s\n", __func__, ldostr);
+ } else {
+ pr_info("turn on ldo done.\n");
+ }
+ } else {
+ pr_warn("%s is enabled before enable", ldostr);
+ }
+ } else {
+ if(regulator_is_enabled(ldo)) {
+ ret = regulator_disable(ldo);
+ if(ret != 0){
+ pr_err("%s: faild to disable %s\n", __func__, ldostr);
+ } else {
+ pr_info("turn off ldo done.\n");
+ }
+ } else {
+ pr_warn("%s is disabled before disable", ldostr);
+ }
+ }
+ regulator_put(ldo);
+ msleep(100);
+
+ if (enable) {
+ //reset
+ if (gpio_is_valid(bsp_priv->reset_io)) {
+ gpio_direction_output(bsp_priv->reset_io, bsp_priv->reset_io_level);
+ msleep(10);
+ gpio_direction_output(bsp_priv->reset_io, !bsp_priv->reset_io_level);
+ }
+
+ msleep(100);
+ } else {
+ //pull up reset
+ if (gpio_is_valid(bsp_priv->reset_io)) {
+ gpio_direction_output(bsp_priv->reset_io, !bsp_priv->reset_io_level);
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+static int power_on_by_gpio(bool enable) {
+ struct bsp_priv * bsp_priv = &g_bsp_priv;
if (enable) {
//power on
if (gpio_is_valid(bsp_priv->power_io)) {
- gpio_direction_output(bsp_priv->power_io, !bsp_priv->power_io_level);
- msleep(10);
gpio_direction_output(bsp_priv->power_io, bsp_priv->power_io_level);
- //gpio_set_value(bsp_priv->power_io, 1);
}
//reset
if (gpio_is_valid(bsp_priv->reset_io)) {
gpio_direction_output(bsp_priv->reset_io, bsp_priv->reset_io_level);
- //gpio_set_value(bsp_priv->reset_io, 0);
msleep(10);
gpio_direction_output(bsp_priv->reset_io, !bsp_priv->reset_io_level);
}
//power off
if (gpio_is_valid(bsp_priv->power_io)) {
gpio_direction_output(bsp_priv->power_io, !bsp_priv->power_io_level);
- //gpio_set_value(bsp_priv->power_io, 0);
+ }
+ //pull down reset
+ if (gpio_is_valid(bsp_priv->reset_io)) {
+ gpio_direction_output(bsp_priv->reset_io, !bsp_priv->reset_io_level);
}
}
return 0;
}
+static int phy_power_on(bool enable)
+{
+ struct bsp_priv *bsp_priv = &g_bsp_priv;
+ printk("%s: enable = %d \n", __func__, enable);
+
+ if (bsp_priv->power_ctrl_by_pmu) {
+ return power_on_by_pmu(enable);
+ } else {
+ return power_on_by_gpio(enable);
+ }
+}
+
int stmmc_pltfr_init(struct platform_device *pdev) {
int phy_iface;
int err;
//power
if (!gpio_is_valid(bsp_priv->power_io)) {
pr_err("%s: ERROR: Get power-gpio failed.\n", __func__);
- //return -EINVAL;
} else {
err = gpio_request(bsp_priv->power_io, "gmac_phy_power");
if (err) {
pr_err("%s: ERROR: Request gmac phy power pin failed.\n", __func__);
- //return -EINVAL;
}
}
if (!gpio_is_valid(bsp_priv->reset_io)) {
pr_err("%s: ERROR: Get reset-gpio failed.\n", __func__);
- //return -EINVAL;
} else {
err = gpio_request(bsp_priv->reset_io, "gmac_phy_reset");
if (err) {
pr_err("%s: ERROR: Request gmac phy reset pin failed.\n", __func__);
- //return -EINVAL;
}
}
//rmii or rgmii
if (phy_iface == PHY_INTERFACE_MODE_RGMII) {
pr_info("%s: init for RGMII\n", __func__);
- grf_writel(GMAC_PHY_INTF_SEL_RGMII, RK3288_GRF_SOC_CON1);
- grf_writel(GMAC_RMII_MODE_CLR, RK3288_GRF_SOC_CON1);
- grf_writel(GMAC_RXCLK_DLY_ENABLE, RK3288_GRF_SOC_CON3);
- grf_writel(GMAC_TXCLK_DLY_ENABLE, RK3288_GRF_SOC_CON3);
- grf_writel(GMAC_CLK_RX_DL_CFG(0x10), RK3288_GRF_SOC_CON3);
- grf_writel(GMAC_CLK_TX_DL_CFG(0x30), RK3288_GRF_SOC_CON3);
- grf_writel(0xffffffff,RK3288_GRF_GPIO3D_E);
- grf_writel(grf_readl(RK3288_GRF_GPIO4B_E) | 0x3<<2<<16 | 0x3<<2, RK3288_GRF_GPIO4B_E);
- grf_writel(0xffffffff,RK3288_GRF_GPIO4A_E);
-
+ SET_RGMII
} else if (phy_iface == PHY_INTERFACE_MODE_RMII) {
pr_info("%s: init for RMII\n", __func__);
- grf_writel(GMAC_PHY_INTF_SEL_RMII, RK3288_GRF_SOC_CON1);
- grf_writel(GMAC_RMII_MODE, RK3288_GRF_SOC_CON1);
+ SET_RMII
} else {
pr_err("%s: ERROR: NO interface defined!\n", __func__);
}
switch (speed) {
case 10: {
- grf_writel(GMAC_CLK_2_5M, RK3288_GRF_SOC_CON1);
+ SET_RGMII_10M
break;
}
case 100: {
- grf_writel(GMAC_CLK_25M, RK3288_GRF_SOC_CON1);
+ SET_RGMII_100M
break;
}
case 1000: {
- grf_writel(GMAC_CLK_125M, RK3288_GRF_SOC_CON1);
+ SET_RGMII_1000M
break;
}
default: {
pr_info("%s: fix speed for RMII\n", __func__);
switch (speed) {
case 10: {
- grf_writel(GMAC_RMII_CLK_2_5M, RK3288_GRF_SOC_CON1);
- grf_writel(GMAC_SPEED_10M, RK3288_GRF_SOC_CON1);
+ SET_RMII_10M
break;
}
case 100: {
- grf_writel(GMAC_RMII_CLK_25M, RK3288_GRF_SOC_CON1);
- grf_writel(GMAC_SPEED_100M, RK3288_GRF_SOC_CON1);
+ SET_RMII_100M
break;
}
default: {
*mac = of_get_mac_address(np);
plat->interface = of_get_phy_mode(np);
- //don't care about the return value of of_get_phy_mode(np)
+//don't care about the return value of of_get_phy_mode(np)
#ifdef CONFIG_GMAC_PHY_RMII
plat->interface = PHY_INTERFACE_MODE_RMII;
#else
g_bsp_priv.phy_iface = plat->interface;
g_bsp_priv.phy_power_on = phy_power_on;
+ g_bsp_priv.gmac_clk_enable = gmac_clk_enable;
plat->bsp_priv = &g_bsp_priv;
ret = stmmac_probe_config_dt(pdev, plat_dat, &mac);
if (ret) {
- pr_err("%s: ERROR: main dt probe failed", __func__);
+ pr_err("%s: main dt probe failed", __func__);
return ret;
}
} else {
return ret;
}
+ gmac_clk_init(&(pdev->dev));
+
priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr);
if (!priv) {
- pr_err("%s: ERROR: main driver probe failed", __func__);
+ pr_err("%s: main driver probe failed", __func__);
return -ENODEV;
}
+
/* Get MAC address if available (DT) */
if (mac)
memcpy(priv->dev->dev_addr, mac, ETH_ALEN);