ethernet:gmac:
authorroger <cz@rock-chips.com>
Thu, 14 Aug 2014 06:51:23 +0000 (14:51 +0800)
committerroger <cz@rock-chips.com>
Thu, 14 Aug 2014 06:51:23 +0000 (14:51 +0800)
1. set interface type(rgmii/rmii) in dts
2. set clock input/output in dts
3. set tx/rx delay in dts

arch/arm/boot/dts/rk3128-box.dts
arch/arm/boot/dts/rk312x.dtsi
arch/arm/boot/dts/rk3288.dtsi
drivers/net/ethernet/rockchip/gmac/Kconfig
drivers/net/ethernet/rockchip/gmac/stmmac.h
drivers/net/ethernet/rockchip/gmac/stmmac_platform.c

index 29a3f617a439817f1c9461ad5ccd63f6d0ef0980..8f9a5976a3a183a39774e5cd5935e3d4310e62ad 100755 (executable)
        //pmu_enable_level = <1>; //1->HIGH, 0->LOW
        //power-gpio = <&gpio0 GPIO_A6 GPIO_ACTIVE_HIGH>;
        reset-gpio = <&gpio2 GPIO_D0 GPIO_ACTIVE_LOW>;
+       phy-mode = "rgmii";
+       clock_in_out = "input";
+       tx_delay = <0x30>;
+       rx_delay = <0x10>;
 };
 
 &codec {
index c099982ece381197f08ea349fc8a896962f14009..d0d71d75760722f5772cb0a47bdaf00090b5f553 100755 (executable)
                        "mac_clk_tx", "clk_mac_ref",
                        "clk_mac_refout",
                        "pclk_mac";
-               //phy-mode = "rmii";
                phy-mode = "rgmii";
                pinctrl-names = "default";
                pinctrl-0 = <&gmac_rxdv &gmac_txclk &gmac_crs &gmac_rxclk &gmac_mdio &gmac_txen &gmac_clk &gmac_rxer &gmac_rxd1 &gmac_rxd0 &gmac_txd1 &gmac_txd0 &gmac_rxd3 &gmac_rxd2 &gmac_txd2 &gmac_txd3 &gmac_col_gpio &gmac_mdc>;
index 0a8ebf289982cf02425ca1ead47b4e9fc3ed985f..b72636f5dc30776b4253fd0a6d26525366d74e22 100755 (executable)
                              "mac_clk_tx", "clk_mac_ref",
                              "clk_mac_refout", "aclk_mac",
                              "pclk_mac";
-               //phy-mode = "rmii";
                phy-mode = "rgmii";
                pinctrl-names = "default";
                pinctrl-0 = <&mac_clk &mac_txpins &mac_rxpins &mac_mdpins>;
index 93f4a86b8dce646f0791cbbd10175968b4ab2291..957a46bdbc1823c5243876fc3c5d3ecc2b8243ce 100755 (executable)
@@ -10,13 +10,6 @@ config RK_GMAC_ETH
          Rockchip 10/100/1000 Ethernet driver.
 
 if RK_GMAC_ETH
-config GMAC_CLK_IN
-       bool "Clock input from PHY"
-       default y
-
-config GMAC_PHY_RMII
-       bool "GMAC interface set to RMII"
-       default n
 
 config GMAC_DEBUG_FS
        bool "Enable monitoring via sysFS "
index 3800fa9945ecbd6ac83d71548fcf80a9cef0f2b6..ec6050bba7eb726b03cb0e34bb5f38957af57ad8 100755 (executable)
@@ -124,7 +124,10 @@ struct bsp_priv {
        int reset_io;
        int reset_io_level;
        int phy_iface;
+       bool clock_input;
        int chip;
+       int tx_delay;
+       int rx_delay;
 
        struct clk *clk_mac;
        struct clk *clk_mac_pll;
index 96f40ca801c5a7f4b5b75109ce861f65649c5c93..46b662ab23daa6321a0a8e65316c501db70c39f3 100755 (executable)
 #define GMAC_CLK_RX_DL_CFG(val) ((0x3F80 << 16) | (val<<7))        // 7bit
 #define GMAC_CLK_TX_DL_CFG(val) ((0x007F << 16) | (val))           // 7bit
 
-static void SET_RGMII(int type)
+static void SET_RGMII(int type, int tx_delay, int rx_delay)
 {
     if (type == RK3288_GMAC) {
         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(GMAC_CLK_RX_DL_CFG(rx_delay), RK3288_GRF_SOC_CON3);
+        grf_writel(GMAC_CLK_TX_DL_CFG(tx_delay), RK3288_GRF_SOC_CON3);
+        pr_info("tx delay=0x%x\nrx delay=0x%x\n", tx_delay, rx_delay);
+       //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);
     } else if (type == RK312X_GMAC) {
         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);
+        grf_writel(GMAC_CLK_RX_DL_CFG(rx_delay), RK312X_GRF_MAC_CON0);
+        grf_writel(GMAC_CLK_TX_DL_CFG(tx_delay), RK312X_GRF_MAC_CON0);
+        pr_info("tx delay=0x%x\nrx delay=0x%x\n", tx_delay, rx_delay);
     }
 }
 
@@ -195,13 +200,17 @@ int gmac_clk_init(struct device *device)
                pr_warn("%s: warning: cannot get clk_mac clock\n", __func__);
        }
 
-#ifdef CONFIG_GMAC_CLK_IN
-       clk_set_rate(bsp_priv->gmac_clkin, 50000000);
-       clk_set_parent(bsp_priv->clk_mac, bsp_priv->gmac_clkin);
-#else
-       clk_set_rate(bsp_priv->clk_mac_pll, 50000000);
-       clk_set_parent(bsp_priv->clk_mac, bsp_priv->clk_mac_pll);
-#endif
+       if (bsp_priv->clock_input) {
+               if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
+                       clk_set_rate(bsp_priv->gmac_clkin, 50000000);
+               }
+               clk_set_parent(bsp_priv->clk_mac, bsp_priv->gmac_clkin);
+       } else {
+               if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
+                       clk_set_rate(bsp_priv->clk_mac_pll, 50000000);
+               }
+               clk_set_parent(bsp_priv->clk_mac, bsp_priv->clk_mac_pll);
+       }
        return 0;
 }
 
@@ -402,22 +411,22 @@ int stmmc_pltfr_init(struct platform_device *pdev) {
        } 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__);
+                       pr_err("%s: ERROR: Request gmac phy power pin failed.\n", __func__);
                }
        }
 
        if (!gpio_is_valid(bsp_priv->reset_io)) {
-               //pr_err("%s: ERROR: Get reset-gpio failed.\n", __func__);
+               pr_err("%s: ERROR: Get reset-gpio failed.\n", __func__);
        } 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__);
+                       pr_err("%s: ERROR: Request gmac phy reset pin failed.\n", __func__);
                }
        }
 //rmii or rgmii
        if (phy_iface == PHY_INTERFACE_MODE_RGMII) {
                pr_info("%s: init for RGMII\n", __func__);
-               SET_RGMII(bsp_priv->chip);
+               SET_RGMII(bsp_priv->chip, bsp_priv->tx_delay, bsp_priv->rx_delay);
        } else if (phy_iface == PHY_INTERFACE_MODE_RMII) {
                pr_info("%s: init for RMII\n", __func__);
                SET_RMII(bsp_priv->chip);
@@ -496,12 +505,6 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
 
        *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)
-#ifdef CONFIG_GMAC_PHY_RMII
-       plat->interface = PHY_INTERFACE_MODE_RMII;
-#else
-       plat->interface = PHY_INTERFACE_MODE_RGMII;
-#endif
 
        plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
                                           sizeof(struct stmmac_mdio_bus_data),
@@ -519,6 +522,7 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
                g_bsp_priv.power_ctrl_by_pmu = true;
                strcpy(g_bsp_priv.pmu_regulator, strings);
        }
+
        ret = of_property_read_u32(np, "pmu_enable_level", &value);
        if (ret) {
                pr_err("%s: Can not read property: pmu_enable_level.\n", __func__);
@@ -529,6 +533,37 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
                g_bsp_priv.pmu_enable_level = value;
        }
 
+       ret = of_property_read_string(np, "clock_in_out", &strings);
+       if (ret) {
+               pr_err("%s: Can not read property: clock_in_out.\n", __func__);
+               g_bsp_priv.clock_input = true;
+       } else {
+               pr_info("%s: clock input or output? (%s).\n", __func__, strings);
+               if (!strcmp(strings, "input")) {
+                       g_bsp_priv.clock_input = true;
+               } else {
+                       g_bsp_priv.clock_input = false;
+               }
+       }
+
+       ret = of_property_read_u32(np, "tx_delay", &value);
+       if (ret) {
+               g_bsp_priv.tx_delay = 0x30;
+               pr_err("%s: Can not read property: tx_delay. set tx_delay to 0x%x\n", __func__, g_bsp_priv.tx_delay);
+       } else {
+               pr_info("%s: TX delay(0x%x).\n", __func__, value);
+               g_bsp_priv.tx_delay = value;
+       }
+
+       ret = of_property_read_u32(np, "rx_delay", &value);
+       if (ret) {
+               g_bsp_priv.rx_delay = 0x10;
+               pr_err("%s: Can not read property: rx_delay. set rx_delay to 0x%x\n", __func__, g_bsp_priv.rx_delay);
+       } else {
+               pr_info("%s: RX delay(0x%x).\n", __func__, value);
+               g_bsp_priv.rx_delay = value;
+       }
+
        g_bsp_priv.reset_io = 
                        of_get_named_gpio_flags(np, "reset-gpio", 0, &flags);
        g_bsp_priv.reset_io_level = (flags == GPIO_ACTIVE_HIGH) ? 1 : 0;