1c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
27ad269eaSRoger Chen /**
3d0ea5cbdSJesse Brandeburg * DOC: dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
47ad269eaSRoger Chen *
57ad269eaSRoger Chen * Copyright (C) 2014 Chen-Zhi (Roger Chen)
67ad269eaSRoger Chen *
77ad269eaSRoger Chen * Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>
87ad269eaSRoger Chen */
97ad269eaSRoger Chen
107ad269eaSRoger Chen #include <linux/stmmac.h>
117ad269eaSRoger Chen #include <linux/bitops.h>
127ad269eaSRoger Chen #include <linux/clk.h>
137ad269eaSRoger Chen #include <linux/phy.h>
147ad269eaSRoger Chen #include <linux/of_net.h>
15e0fb4013SJoachim Eastwood #include <linux/module.h>
163d40aed8SRob Herring #include <linux/of.h>
17e0fb4013SJoachim Eastwood #include <linux/platform_device.h>
187ad269eaSRoger Chen #include <linux/regulator/consumer.h>
197ad269eaSRoger Chen #include <linux/delay.h>
207ad269eaSRoger Chen #include <linux/mfd/syscon.h>
217ad269eaSRoger Chen #include <linux/regmap.h>
22aec3f415SPunit Agrawal #include <linux/pm_runtime.h>
237ad269eaSRoger Chen
24e0fb4013SJoachim Eastwood #include "stmmac_platform.h"
25e0fb4013SJoachim Eastwood
260fb98db1SHeiko Stübner struct rk_priv_data;
270fb98db1SHeiko Stübner struct rk_gmac_ops {
280fb98db1SHeiko Stübner void (*set_to_rgmii)(struct rk_priv_data *bsp_priv,
290fb98db1SHeiko Stübner int tx_delay, int rx_delay);
300fb98db1SHeiko Stübner void (*set_to_rmii)(struct rk_priv_data *bsp_priv);
310fb98db1SHeiko Stübner void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
320fb98db1SHeiko Stübner void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
332f2b60a0SDavid Wu void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input,
342f2b60a0SDavid Wu bool enable);
35fecd4d7eSDavid Wu void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
360546b224SJohn Keeping bool regs_valid;
373bb3d6b1SDavid Wu u32 regs[];
380fb98db1SHeiko Stübner };
390fb98db1SHeiko Stübner
40ea449f7fSSebastian Reichel static const char * const rk_clocks[] = {
41ea449f7fSSebastian Reichel "aclk_mac", "pclk_mac", "mac_clk_tx", "clk_mac_speed",
42ea449f7fSSebastian Reichel };
43ea449f7fSSebastian Reichel
44ea449f7fSSebastian Reichel static const char * const rk_rmii_clocks[] = {
45ea449f7fSSebastian Reichel "mac_clk_rx", "clk_mac_ref", "clk_mac_refout",
46ea449f7fSSebastian Reichel };
47ea449f7fSSebastian Reichel
48ea449f7fSSebastian Reichel enum rk_clocks_index {
49ea449f7fSSebastian Reichel RK_ACLK_MAC = 0,
50ea449f7fSSebastian Reichel RK_PCLK_MAC,
51ea449f7fSSebastian Reichel RK_MAC_CLK_TX,
52ea449f7fSSebastian Reichel RK_CLK_MAC_SPEED,
53ea449f7fSSebastian Reichel RK_MAC_CLK_RX,
54ea449f7fSSebastian Reichel RK_CLK_MAC_REF,
55ea449f7fSSebastian Reichel RK_CLK_MAC_REFOUT,
56ea449f7fSSebastian Reichel };
57ea449f7fSSebastian Reichel
587ad269eaSRoger Chen struct rk_priv_data {
597ad269eaSRoger Chen struct platform_device *pdev;
600c65b2b9SAndrew Lunn phy_interface_t phy_iface;
613bb3d6b1SDavid Wu int id;
622e12f536SRomain Perier struct regulator *regulator;
63229666c1SVincent Palatin bool suspended;
6492c2588fSJoachim Eastwood const struct rk_gmac_ops *ops;
657ad269eaSRoger Chen
667ad269eaSRoger Chen bool clk_enabled;
677ad269eaSRoger Chen bool clock_input;
68fecd4d7eSDavid Wu bool integrated_phy;
697ad269eaSRoger Chen
70ea449f7fSSebastian Reichel struct clk_bulk_data *clks;
71ea449f7fSSebastian Reichel int num_clks;
727ad269eaSRoger Chen struct clk *clk_mac;
73fecd4d7eSDavid Wu struct clk *clk_phy;
74fecd4d7eSDavid Wu
75fecd4d7eSDavid Wu struct reset_control *phy_reset;
767ad269eaSRoger Chen
777ad269eaSRoger Chen int tx_delay;
787ad269eaSRoger Chen int rx_delay;
797ad269eaSRoger Chen
807ad269eaSRoger Chen struct regmap *grf;
812f2b60a0SDavid Wu struct regmap *php_grf;
827ad269eaSRoger Chen };
837ad269eaSRoger Chen
847ad269eaSRoger Chen #define HIWORD_UPDATE(val, mask, shift) \
857ad269eaSRoger Chen ((val) << (shift) | (mask) << ((shift) + 16))
867ad269eaSRoger Chen
877ad269eaSRoger Chen #define GRF_BIT(nr) (BIT(nr) | BIT(nr+16))
887ad269eaSRoger Chen #define GRF_CLR_BIT(nr) (BIT(nr+16))
897ad269eaSRoger Chen
90eaf70ad1SWadim Egorov #define DELAY_ENABLE(soc, tx, rx) \
91eaf70ad1SWadim Egorov (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
92eaf70ad1SWadim Egorov ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
93eaf70ad1SWadim Egorov
9423c94d63SDavid Wu #define PX30_GRF_GMAC_CON1 0x0904
9523c94d63SDavid Wu
9623c94d63SDavid Wu /* PX30_GRF_GMAC_CON1 */
9723c94d63SDavid Wu #define PX30_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
9823c94d63SDavid Wu GRF_BIT(6))
9923c94d63SDavid Wu #define PX30_GMAC_SPEED_10M GRF_CLR_BIT(2)
10023c94d63SDavid Wu #define PX30_GMAC_SPEED_100M GRF_BIT(2)
10123c94d63SDavid Wu
px30_set_to_rmii(struct rk_priv_data * bsp_priv)10223c94d63SDavid Wu static void px30_set_to_rmii(struct rk_priv_data *bsp_priv)
10323c94d63SDavid Wu {
10423c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
10523c94d63SDavid Wu
10623c94d63SDavid Wu if (IS_ERR(bsp_priv->grf)) {
10723c94d63SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
10823c94d63SDavid Wu return;
10923c94d63SDavid Wu }
11023c94d63SDavid Wu
11123c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
11223c94d63SDavid Wu PX30_GMAC_PHY_INTF_SEL_RMII);
11323c94d63SDavid Wu }
11423c94d63SDavid Wu
px30_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)11523c94d63SDavid Wu static void px30_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
11623c94d63SDavid Wu {
117ea449f7fSSebastian Reichel struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
11823c94d63SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
11923c94d63SDavid Wu int ret;
12023c94d63SDavid Wu
121ea449f7fSSebastian Reichel if (!clk_mac_speed) {
12223c94d63SDavid Wu dev_err(dev, "%s: Missing clk_mac_speed clock\n", __func__);
12323c94d63SDavid Wu return;
12423c94d63SDavid Wu }
12523c94d63SDavid Wu
12623c94d63SDavid Wu if (speed == 10) {
12723c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
12823c94d63SDavid Wu PX30_GMAC_SPEED_10M);
12923c94d63SDavid Wu
130ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, 2500000);
13123c94d63SDavid Wu if (ret)
13223c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 2500000 failed: %d\n",
13323c94d63SDavid Wu __func__, ret);
13423c94d63SDavid Wu } else if (speed == 100) {
13523c94d63SDavid Wu regmap_write(bsp_priv->grf, PX30_GRF_GMAC_CON1,
13623c94d63SDavid Wu PX30_GMAC_SPEED_100M);
13723c94d63SDavid Wu
138ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, 25000000);
13923c94d63SDavid Wu if (ret)
14023c94d63SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate 25000000 failed: %d\n",
14123c94d63SDavid Wu __func__, ret);
14223c94d63SDavid Wu
14323c94d63SDavid Wu } else {
14423c94d63SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
14523c94d63SDavid Wu }
14623c94d63SDavid Wu }
14723c94d63SDavid Wu
14823c94d63SDavid Wu static const struct rk_gmac_ops px30_ops = {
14923c94d63SDavid Wu .set_to_rmii = px30_set_to_rmii,
15023c94d63SDavid Wu .set_rmii_speed = px30_set_rmii_speed,
15123c94d63SDavid Wu };
15223c94d63SDavid Wu
15305946876SDavid Wu #define RK3128_GRF_MAC_CON0 0x0168
15405946876SDavid Wu #define RK3128_GRF_MAC_CON1 0x016c
15505946876SDavid Wu
15605946876SDavid Wu /* RK3128_GRF_MAC_CON0 */
15705946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
15805946876SDavid Wu #define RK3128_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
15905946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
16005946876SDavid Wu #define RK3128_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
16105946876SDavid Wu #define RK3128_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
16205946876SDavid Wu #define RK3128_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
16305946876SDavid Wu
16405946876SDavid Wu /* RK3128_GRF_MAC_CON1 */
16505946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RGMII \
16605946876SDavid Wu (GRF_BIT(6) | GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
16705946876SDavid Wu #define RK3128_GMAC_PHY_INTF_SEL_RMII \
16805946876SDavid Wu (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | GRF_BIT(8))
16905946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL GRF_BIT(9)
17005946876SDavid Wu #define RK3128_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9)
17105946876SDavid Wu #define RK3128_GMAC_SPEED_10M GRF_CLR_BIT(10)
17205946876SDavid Wu #define RK3128_GMAC_SPEED_100M GRF_BIT(10)
17305946876SDavid Wu #define RK3128_GMAC_RMII_CLK_25M GRF_BIT(11)
17405946876SDavid Wu #define RK3128_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11)
17505946876SDavid Wu #define RK3128_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
17605946876SDavid Wu #define RK3128_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13))
17705946876SDavid Wu #define RK3128_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13))
17805946876SDavid Wu #define RK3128_GMAC_RMII_MODE GRF_BIT(14)
17905946876SDavid Wu #define RK3128_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14)
18005946876SDavid Wu
rk3128_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)18105946876SDavid Wu static void rk3128_set_to_rgmii(struct rk_priv_data *bsp_priv,
18205946876SDavid Wu int tx_delay, int rx_delay)
18305946876SDavid Wu {
18405946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
18505946876SDavid Wu
18605946876SDavid Wu if (IS_ERR(bsp_priv->grf)) {
18705946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n");
18805946876SDavid Wu return;
18905946876SDavid Wu }
19005946876SDavid Wu
19105946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
19205946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RGMII |
19305946876SDavid Wu RK3128_GMAC_RMII_MODE_CLR);
19405946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
19505946876SDavid Wu DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
19605946876SDavid Wu RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
19705946876SDavid Wu RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
19805946876SDavid Wu }
19905946876SDavid Wu
rk3128_set_to_rmii(struct rk_priv_data * bsp_priv)20005946876SDavid Wu static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
20105946876SDavid Wu {
20205946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
20305946876SDavid Wu
20405946876SDavid Wu if (IS_ERR(bsp_priv->grf)) {
20505946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n");
20605946876SDavid Wu return;
20705946876SDavid Wu }
20805946876SDavid Wu
20905946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
21005946876SDavid Wu RK3128_GMAC_PHY_INTF_SEL_RMII | RK3128_GMAC_RMII_MODE);
21105946876SDavid Wu }
21205946876SDavid Wu
rk3128_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)21305946876SDavid Wu static void rk3128_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
21405946876SDavid Wu {
21505946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
21605946876SDavid Wu
21705946876SDavid Wu if (IS_ERR(bsp_priv->grf)) {
21805946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n");
21905946876SDavid Wu return;
22005946876SDavid Wu }
22105946876SDavid Wu
22205946876SDavid Wu if (speed == 10)
22305946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22405946876SDavid Wu RK3128_GMAC_CLK_2_5M);
22505946876SDavid Wu else if (speed == 100)
22605946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
22705946876SDavid Wu RK3128_GMAC_CLK_25M);
22805946876SDavid Wu else if (speed == 1000)
22905946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
23005946876SDavid Wu RK3128_GMAC_CLK_125M);
23105946876SDavid Wu else
23205946876SDavid Wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
23305946876SDavid Wu }
23405946876SDavid Wu
rk3128_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)23505946876SDavid Wu static void rk3128_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
23605946876SDavid Wu {
23705946876SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
23805946876SDavid Wu
23905946876SDavid Wu if (IS_ERR(bsp_priv->grf)) {
24005946876SDavid Wu dev_err(dev, "Missing rockchip,grf property\n");
24105946876SDavid Wu return;
24205946876SDavid Wu }
24305946876SDavid Wu
24405946876SDavid Wu if (speed == 10) {
24505946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
24605946876SDavid Wu RK3128_GMAC_RMII_CLK_2_5M |
24705946876SDavid Wu RK3128_GMAC_SPEED_10M);
24805946876SDavid Wu } else if (speed == 100) {
24905946876SDavid Wu regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON1,
25005946876SDavid Wu RK3128_GMAC_RMII_CLK_25M |
25105946876SDavid Wu RK3128_GMAC_SPEED_100M);
25205946876SDavid Wu } else {
25305946876SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
25405946876SDavid Wu }
25505946876SDavid Wu }
25605946876SDavid Wu
25705946876SDavid Wu static const struct rk_gmac_ops rk3128_ops = {
25805946876SDavid Wu .set_to_rgmii = rk3128_set_to_rgmii,
25905946876SDavid Wu .set_to_rmii = rk3128_set_to_rmii,
26005946876SDavid Wu .set_rgmii_speed = rk3128_set_rgmii_speed,
26105946876SDavid Wu .set_rmii_speed = rk3128_set_rmii_speed,
26205946876SDavid Wu };
26305946876SDavid Wu
264e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON0 0x0900
265e7ffd812SXing Zheng #define RK3228_GRF_MAC_CON1 0x0904
266e7ffd812SXing Zheng
2676fa12c78SDavid Wu #define RK3228_GRF_CON_MUX 0x50
2686fa12c78SDavid Wu
269e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON0 */
270e7ffd812SXing Zheng #define RK3228_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
271e7ffd812SXing Zheng #define RK3228_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
272e7ffd812SXing Zheng
273e7ffd812SXing Zheng /* RK3228_GRF_MAC_CON1 */
274e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RGMII \
275e7ffd812SXing Zheng (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
276e7ffd812SXing Zheng #define RK3228_GMAC_PHY_INTF_SEL_RMII \
277e7ffd812SXing Zheng (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
278e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL GRF_BIT(3)
279e7ffd812SXing Zheng #define RK3228_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3)
280e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_10M GRF_CLR_BIT(2)
281e7ffd812SXing Zheng #define RK3228_GMAC_SPEED_100M GRF_BIT(2)
282e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_25M GRF_BIT(7)
283e7ffd812SXing Zheng #define RK3228_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7)
284e7ffd812SXing Zheng #define RK3228_GMAC_CLK_125M (GRF_CLR_BIT(8) | GRF_CLR_BIT(9))
285e7ffd812SXing Zheng #define RK3228_GMAC_CLK_25M (GRF_BIT(8) | GRF_BIT(9))
286e7ffd812SXing Zheng #define RK3228_GMAC_CLK_2_5M (GRF_CLR_BIT(8) | GRF_BIT(9))
287e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE GRF_BIT(10)
288e7ffd812SXing Zheng #define RK3228_GMAC_RMII_MODE_CLR GRF_CLR_BIT(10)
289e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0)
290e7ffd812SXing Zheng #define RK3228_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
291e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
292e7ffd812SXing Zheng #define RK3228_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
293e7ffd812SXing Zheng
2946fa12c78SDavid Wu /* RK3228_GRF_COM_MUX */
2956fa12c78SDavid Wu #define RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY GRF_BIT(15)
2966fa12c78SDavid Wu
rk3228_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)297e7ffd812SXing Zheng static void rk3228_set_to_rgmii(struct rk_priv_data *bsp_priv,
298e7ffd812SXing Zheng int tx_delay, int rx_delay)
299e7ffd812SXing Zheng {
300e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev;
301e7ffd812SXing Zheng
302e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) {
303e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n");
304e7ffd812SXing Zheng return;
305e7ffd812SXing Zheng }
306e7ffd812SXing Zheng
307e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
308e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RGMII |
309e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE_CLR |
310eaf70ad1SWadim Egorov DELAY_ENABLE(RK3228, tx_delay, rx_delay));
311e7ffd812SXing Zheng
312e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
313e7ffd812SXing Zheng RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
314e7ffd812SXing Zheng RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
315e7ffd812SXing Zheng }
316e7ffd812SXing Zheng
rk3228_set_to_rmii(struct rk_priv_data * bsp_priv)317e7ffd812SXing Zheng static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
318e7ffd812SXing Zheng {
319e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev;
320e7ffd812SXing Zheng
321e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) {
322e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n");
323e7ffd812SXing Zheng return;
324e7ffd812SXing Zheng }
325e7ffd812SXing Zheng
326e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
327e7ffd812SXing Zheng RK3228_GMAC_PHY_INTF_SEL_RMII |
328e7ffd812SXing Zheng RK3228_GMAC_RMII_MODE);
329e7ffd812SXing Zheng
330e7ffd812SXing Zheng /* set MAC to RMII mode */
331e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1, GRF_BIT(11));
332e7ffd812SXing Zheng }
333e7ffd812SXing Zheng
rk3228_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)334e7ffd812SXing Zheng static void rk3228_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
335e7ffd812SXing Zheng {
336e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev;
337e7ffd812SXing Zheng
338e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) {
339e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n");
340e7ffd812SXing Zheng return;
341e7ffd812SXing Zheng }
342e7ffd812SXing Zheng
343e7ffd812SXing Zheng if (speed == 10)
344e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
345e7ffd812SXing Zheng RK3228_GMAC_CLK_2_5M);
346e7ffd812SXing Zheng else if (speed == 100)
347e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
348e7ffd812SXing Zheng RK3228_GMAC_CLK_25M);
349e7ffd812SXing Zheng else if (speed == 1000)
350e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
351e7ffd812SXing Zheng RK3228_GMAC_CLK_125M);
352e7ffd812SXing Zheng else
353e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
354e7ffd812SXing Zheng }
355e7ffd812SXing Zheng
rk3228_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)356e7ffd812SXing Zheng static void rk3228_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
357e7ffd812SXing Zheng {
358e7ffd812SXing Zheng struct device *dev = &bsp_priv->pdev->dev;
359e7ffd812SXing Zheng
360e7ffd812SXing Zheng if (IS_ERR(bsp_priv->grf)) {
361e7ffd812SXing Zheng dev_err(dev, "Missing rockchip,grf property\n");
362e7ffd812SXing Zheng return;
363e7ffd812SXing Zheng }
364e7ffd812SXing Zheng
365e7ffd812SXing Zheng if (speed == 10)
366e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
367e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_2_5M |
368e7ffd812SXing Zheng RK3228_GMAC_SPEED_10M);
369e7ffd812SXing Zheng else if (speed == 100)
370e7ffd812SXing Zheng regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON1,
371e7ffd812SXing Zheng RK3228_GMAC_RMII_CLK_25M |
372e7ffd812SXing Zheng RK3228_GMAC_SPEED_100M);
373e7ffd812SXing Zheng else
374e7ffd812SXing Zheng dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
375e7ffd812SXing Zheng }
376e7ffd812SXing Zheng
rk3228_integrated_phy_powerup(struct rk_priv_data * priv)3776fa12c78SDavid Wu static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
3786fa12c78SDavid Wu {
3796fa12c78SDavid Wu regmap_write(priv->grf, RK3228_GRF_CON_MUX,
3806fa12c78SDavid Wu RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
3816fa12c78SDavid Wu }
3826fa12c78SDavid Wu
383e7ffd812SXing Zheng static const struct rk_gmac_ops rk3228_ops = {
384e7ffd812SXing Zheng .set_to_rgmii = rk3228_set_to_rgmii,
385e7ffd812SXing Zheng .set_to_rmii = rk3228_set_to_rmii,
386e7ffd812SXing Zheng .set_rgmii_speed = rk3228_set_rgmii_speed,
387e7ffd812SXing Zheng .set_rmii_speed = rk3228_set_rmii_speed,
3886fa12c78SDavid Wu .integrated_phy_powerup = rk3228_integrated_phy_powerup,
389e7ffd812SXing Zheng };
390e7ffd812SXing Zheng
3917ad269eaSRoger Chen #define RK3288_GRF_SOC_CON1 0x0248
3927ad269eaSRoger Chen #define RK3288_GRF_SOC_CON3 0x0250
3937ad269eaSRoger Chen
3947ad269eaSRoger Chen /*RK3288_GRF_SOC_CON1*/
3950fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(6) | GRF_CLR_BIT(7) | \
3960fb98db1SHeiko Stübner GRF_CLR_BIT(8))
3970fb98db1SHeiko Stübner #define RK3288_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(6) | GRF_CLR_BIT(7) | \
3980fb98db1SHeiko Stübner GRF_BIT(8))
3990fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL GRF_BIT(9)
4000fb98db1SHeiko Stübner #define RK3288_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(9)
4010fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_10M GRF_CLR_BIT(10)
4020fb98db1SHeiko Stübner #define RK3288_GMAC_SPEED_100M GRF_BIT(10)
4030fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_25M GRF_BIT(11)
4040fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(11)
4050fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_125M (GRF_CLR_BIT(12) | GRF_CLR_BIT(13))
4060fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_25M (GRF_BIT(12) | GRF_BIT(13))
4070fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_2_5M (GRF_CLR_BIT(12) | GRF_BIT(13))
4080fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE GRF_BIT(14)
4090fb98db1SHeiko Stübner #define RK3288_GMAC_RMII_MODE_CLR GRF_CLR_BIT(14)
4107ad269eaSRoger Chen
4117ad269eaSRoger Chen /*RK3288_GRF_SOC_CON3*/
4120fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
4130fb98db1SHeiko Stübner #define RK3288_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
4140fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
4150fb98db1SHeiko Stübner #define RK3288_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
4160fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
4170fb98db1SHeiko Stübner #define RK3288_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
4187ad269eaSRoger Chen
rk3288_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)4190fb98db1SHeiko Stübner static void rk3288_set_to_rgmii(struct rk_priv_data *bsp_priv,
4207ad269eaSRoger Chen int tx_delay, int rx_delay)
4217ad269eaSRoger Chen {
4227ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev;
4237ad269eaSRoger Chen
4247ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) {
425d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n");
4267ad269eaSRoger Chen return;
4277ad269eaSRoger Chen }
4287ad269eaSRoger Chen
4297ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4300fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RGMII |
4310fb98db1SHeiko Stübner RK3288_GMAC_RMII_MODE_CLR);
4327ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
433eaf70ad1SWadim Egorov DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
4340fb98db1SHeiko Stübner RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
4350fb98db1SHeiko Stübner RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
4367ad269eaSRoger Chen }
4377ad269eaSRoger Chen
rk3288_set_to_rmii(struct rk_priv_data * bsp_priv)4380fb98db1SHeiko Stübner static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
4397ad269eaSRoger Chen {
4407ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev;
4417ad269eaSRoger Chen
4427ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) {
443d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n");
4447ad269eaSRoger Chen return;
4457ad269eaSRoger Chen }
4467ad269eaSRoger Chen
4477ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4480fb98db1SHeiko Stübner RK3288_GMAC_PHY_INTF_SEL_RMII | RK3288_GMAC_RMII_MODE);
4497ad269eaSRoger Chen }
4507ad269eaSRoger Chen
rk3288_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)4510fb98db1SHeiko Stübner static void rk3288_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
4527ad269eaSRoger Chen {
4537ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev;
4547ad269eaSRoger Chen
4557ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) {
456d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n");
4577ad269eaSRoger Chen return;
4587ad269eaSRoger Chen }
4597ad269eaSRoger Chen
4607ad269eaSRoger Chen if (speed == 10)
4610fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4620fb98db1SHeiko Stübner RK3288_GMAC_CLK_2_5M);
4637ad269eaSRoger Chen else if (speed == 100)
4640fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4650fb98db1SHeiko Stübner RK3288_GMAC_CLK_25M);
4667ad269eaSRoger Chen else if (speed == 1000)
4670fb98db1SHeiko Stübner regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4680fb98db1SHeiko Stübner RK3288_GMAC_CLK_125M);
4697ad269eaSRoger Chen else
4707ad269eaSRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
4717ad269eaSRoger Chen }
4727ad269eaSRoger Chen
rk3288_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)4730fb98db1SHeiko Stübner static void rk3288_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
4747ad269eaSRoger Chen {
4757ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev;
4767ad269eaSRoger Chen
4777ad269eaSRoger Chen if (IS_ERR(bsp_priv->grf)) {
478d42202dcSRomain Perier dev_err(dev, "Missing rockchip,grf property\n");
4797ad269eaSRoger Chen return;
4807ad269eaSRoger Chen }
4817ad269eaSRoger Chen
4827ad269eaSRoger Chen if (speed == 10) {
4837ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4840fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_2_5M |
4850fb98db1SHeiko Stübner RK3288_GMAC_SPEED_10M);
4867ad269eaSRoger Chen } else if (speed == 100) {
4877ad269eaSRoger Chen regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON1,
4880fb98db1SHeiko Stübner RK3288_GMAC_RMII_CLK_25M |
4890fb98db1SHeiko Stübner RK3288_GMAC_SPEED_100M);
4907ad269eaSRoger Chen } else {
4917ad269eaSRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
4927ad269eaSRoger Chen }
4937ad269eaSRoger Chen }
4947ad269eaSRoger Chen
49592c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3288_ops = {
4960fb98db1SHeiko Stübner .set_to_rgmii = rk3288_set_to_rgmii,
4970fb98db1SHeiko Stübner .set_to_rmii = rk3288_set_to_rmii,
4980fb98db1SHeiko Stübner .set_rgmii_speed = rk3288_set_rgmii_speed,
4990fb98db1SHeiko Stübner .set_rmii_speed = rk3288_set_rmii_speed,
5000fb98db1SHeiko Stübner };
5010fb98db1SHeiko Stübner
502b4ac9456STobias Schramm #define RK3308_GRF_MAC_CON0 0x04a0
503b4ac9456STobias Schramm
504b4ac9456STobias Schramm /* RK3308_GRF_MAC_CON0 */
505b4ac9456STobias Schramm #define RK3308_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(2) | GRF_CLR_BIT(3) | \
506b4ac9456STobias Schramm GRF_BIT(4))
507b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL GRF_BIT(3)
508b4ac9456STobias Schramm #define RK3308_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3)
509b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_10M GRF_CLR_BIT(0)
510b4ac9456STobias Schramm #define RK3308_GMAC_SPEED_100M GRF_BIT(0)
511b4ac9456STobias Schramm
rk3308_set_to_rmii(struct rk_priv_data * bsp_priv)512b4ac9456STobias Schramm static void rk3308_set_to_rmii(struct rk_priv_data *bsp_priv)
513b4ac9456STobias Schramm {
514b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev;
515b4ac9456STobias Schramm
516b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) {
517b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n");
518b4ac9456STobias Schramm return;
519b4ac9456STobias Schramm }
520b4ac9456STobias Schramm
521b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
522b4ac9456STobias Schramm RK3308_GMAC_PHY_INTF_SEL_RMII);
523b4ac9456STobias Schramm }
524b4ac9456STobias Schramm
rk3308_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)525b4ac9456STobias Schramm static void rk3308_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
526b4ac9456STobias Schramm {
527b4ac9456STobias Schramm struct device *dev = &bsp_priv->pdev->dev;
528b4ac9456STobias Schramm
529b4ac9456STobias Schramm if (IS_ERR(bsp_priv->grf)) {
530b4ac9456STobias Schramm dev_err(dev, "Missing rockchip,grf property\n");
531b4ac9456STobias Schramm return;
532b4ac9456STobias Schramm }
533b4ac9456STobias Schramm
534b4ac9456STobias Schramm if (speed == 10) {
535b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
536b4ac9456STobias Schramm RK3308_GMAC_SPEED_10M);
537b4ac9456STobias Schramm } else if (speed == 100) {
538b4ac9456STobias Schramm regmap_write(bsp_priv->grf, RK3308_GRF_MAC_CON0,
539b4ac9456STobias Schramm RK3308_GMAC_SPEED_100M);
540b4ac9456STobias Schramm } else {
541b4ac9456STobias Schramm dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
542b4ac9456STobias Schramm }
543b4ac9456STobias Schramm }
544b4ac9456STobias Schramm
545b4ac9456STobias Schramm static const struct rk_gmac_ops rk3308_ops = {
546b4ac9456STobias Schramm .set_to_rmii = rk3308_set_to_rmii,
547b4ac9456STobias Schramm .set_rmii_speed = rk3308_set_rmii_speed,
548b4ac9456STobias Schramm };
549b4ac9456STobias Schramm
550d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON0 0x0900
551d4ff816eSdavid.wu #define RK3328_GRF_MAC_CON1 0x0904
5528bdf63bdSDavid Wu #define RK3328_GRF_MAC_CON2 0x0908
5538bdf63bdSDavid Wu #define RK3328_GRF_MACPHY_CON1 0xb04
554d4ff816eSdavid.wu
555d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON0 */
556d4ff816eSdavid.wu #define RK3328_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 7)
557d4ff816eSdavid.wu #define RK3328_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
558d4ff816eSdavid.wu
559d4ff816eSdavid.wu /* RK3328_GRF_MAC_CON1 */
560d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RGMII \
561d4ff816eSdavid.wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
562d4ff816eSdavid.wu #define RK3328_GMAC_PHY_INTF_SEL_RMII \
563d4ff816eSdavid.wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
564d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL GRF_BIT(3)
565d4ff816eSdavid.wu #define RK3328_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3)
566d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_10M GRF_CLR_BIT(2)
567d4ff816eSdavid.wu #define RK3328_GMAC_SPEED_100M GRF_BIT(2)
568d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_25M GRF_BIT(7)
569d4ff816eSdavid.wu #define RK3328_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7)
570d4ff816eSdavid.wu #define RK3328_GMAC_CLK_125M (GRF_CLR_BIT(11) | GRF_CLR_BIT(12))
571d4ff816eSdavid.wu #define RK3328_GMAC_CLK_25M (GRF_BIT(11) | GRF_BIT(12))
572d4ff816eSdavid.wu #define RK3328_GMAC_CLK_2_5M (GRF_CLR_BIT(11) | GRF_BIT(12))
573d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE GRF_BIT(9)
574d4ff816eSdavid.wu #define RK3328_GMAC_RMII_MODE_CLR GRF_CLR_BIT(9)
575d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0)
576d4ff816eSdavid.wu #define RK3328_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
577d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
578d4ff816eSdavid.wu #define RK3328_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(0)
579d4ff816eSdavid.wu
5808bdf63bdSDavid Wu /* RK3328_GRF_MACPHY_CON1 */
5818bdf63bdSDavid Wu #define RK3328_MACPHY_RMII_MODE GRF_BIT(9)
5828bdf63bdSDavid Wu
rk3328_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)583d4ff816eSdavid.wu static void rk3328_set_to_rgmii(struct rk_priv_data *bsp_priv,
584d4ff816eSdavid.wu int tx_delay, int rx_delay)
585d4ff816eSdavid.wu {
586d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev;
587d4ff816eSdavid.wu
588d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) {
589d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n");
590d4ff816eSdavid.wu return;
591d4ff816eSdavid.wu }
592d4ff816eSdavid.wu
593d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
594d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RGMII |
595d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE_CLR |
596d4ff816eSdavid.wu RK3328_GMAC_RXCLK_DLY_ENABLE |
597d4ff816eSdavid.wu RK3328_GMAC_TXCLK_DLY_ENABLE);
598d4ff816eSdavid.wu
599d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
600d4ff816eSdavid.wu RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
601d4ff816eSdavid.wu RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
602d4ff816eSdavid.wu }
603d4ff816eSdavid.wu
rk3328_set_to_rmii(struct rk_priv_data * bsp_priv)604d4ff816eSdavid.wu static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
605d4ff816eSdavid.wu {
606d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev;
6078bdf63bdSDavid Wu unsigned int reg;
608d4ff816eSdavid.wu
609d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) {
610d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n");
611d4ff816eSdavid.wu return;
612d4ff816eSdavid.wu }
613d4ff816eSdavid.wu
6148bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6158bdf63bdSDavid Wu RK3328_GRF_MAC_CON1;
6168bdf63bdSDavid Wu
6178bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg,
618d4ff816eSdavid.wu RK3328_GMAC_PHY_INTF_SEL_RMII |
619d4ff816eSdavid.wu RK3328_GMAC_RMII_MODE);
620d4ff816eSdavid.wu }
621d4ff816eSdavid.wu
rk3328_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)622d4ff816eSdavid.wu static void rk3328_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
623d4ff816eSdavid.wu {
624d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev;
625d4ff816eSdavid.wu
626d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) {
627d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n");
628d4ff816eSdavid.wu return;
629d4ff816eSdavid.wu }
630d4ff816eSdavid.wu
631d4ff816eSdavid.wu if (speed == 10)
632d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
633d4ff816eSdavid.wu RK3328_GMAC_CLK_2_5M);
634d4ff816eSdavid.wu else if (speed == 100)
635d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
636d4ff816eSdavid.wu RK3328_GMAC_CLK_25M);
637d4ff816eSdavid.wu else if (speed == 1000)
638d4ff816eSdavid.wu regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
639d4ff816eSdavid.wu RK3328_GMAC_CLK_125M);
640d4ff816eSdavid.wu else
641d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
642d4ff816eSdavid.wu }
643d4ff816eSdavid.wu
rk3328_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)644d4ff816eSdavid.wu static void rk3328_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
645d4ff816eSdavid.wu {
646d4ff816eSdavid.wu struct device *dev = &bsp_priv->pdev->dev;
6478bdf63bdSDavid Wu unsigned int reg;
648d4ff816eSdavid.wu
649d4ff816eSdavid.wu if (IS_ERR(bsp_priv->grf)) {
650d4ff816eSdavid.wu dev_err(dev, "Missing rockchip,grf property\n");
651d4ff816eSdavid.wu return;
652d4ff816eSdavid.wu }
653d4ff816eSdavid.wu
6548bdf63bdSDavid Wu reg = bsp_priv->integrated_phy ? RK3328_GRF_MAC_CON2 :
6558bdf63bdSDavid Wu RK3328_GRF_MAC_CON1;
6568bdf63bdSDavid Wu
657d4ff816eSdavid.wu if (speed == 10)
6588bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg,
659d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_2_5M |
660d4ff816eSdavid.wu RK3328_GMAC_SPEED_10M);
661d4ff816eSdavid.wu else if (speed == 100)
6628bdf63bdSDavid Wu regmap_write(bsp_priv->grf, reg,
663d4ff816eSdavid.wu RK3328_GMAC_RMII_CLK_25M |
664d4ff816eSdavid.wu RK3328_GMAC_SPEED_100M);
665d4ff816eSdavid.wu else
666d4ff816eSdavid.wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
667d4ff816eSdavid.wu }
668d4ff816eSdavid.wu
rk3328_integrated_phy_powerup(struct rk_priv_data * priv)6698bdf63bdSDavid Wu static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
6708bdf63bdSDavid Wu {
6718bdf63bdSDavid Wu regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
6728bdf63bdSDavid Wu RK3328_MACPHY_RMII_MODE);
6738bdf63bdSDavid Wu }
6748bdf63bdSDavid Wu
675d4ff816eSdavid.wu static const struct rk_gmac_ops rk3328_ops = {
676d4ff816eSdavid.wu .set_to_rgmii = rk3328_set_to_rgmii,
677d4ff816eSdavid.wu .set_to_rmii = rk3328_set_to_rmii,
678d4ff816eSdavid.wu .set_rgmii_speed = rk3328_set_rgmii_speed,
679d4ff816eSdavid.wu .set_rmii_speed = rk3328_set_rmii_speed,
6808bdf63bdSDavid Wu .integrated_phy_powerup = rk3328_integrated_phy_powerup,
681d4ff816eSdavid.wu };
682d4ff816eSdavid.wu
683ba289af8SRoger Chen #define RK3366_GRF_SOC_CON6 0x0418
684ba289af8SRoger Chen #define RK3366_GRF_SOC_CON7 0x041c
685ba289af8SRoger Chen
686ba289af8SRoger Chen /* RK3366_GRF_SOC_CON6 */
687ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \
688ba289af8SRoger Chen GRF_CLR_BIT(11))
689ba289af8SRoger Chen #define RK3366_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
690ba289af8SRoger Chen GRF_BIT(11))
691ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL GRF_BIT(8)
692ba289af8SRoger Chen #define RK3366_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8)
693ba289af8SRoger Chen #define RK3366_GMAC_SPEED_10M GRF_CLR_BIT(7)
694ba289af8SRoger Chen #define RK3366_GMAC_SPEED_100M GRF_BIT(7)
695ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_25M GRF_BIT(3)
696ba289af8SRoger Chen #define RK3366_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3)
697ba289af8SRoger Chen #define RK3366_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
698ba289af8SRoger Chen #define RK3366_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5))
699ba289af8SRoger Chen #define RK3366_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5))
700ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE GRF_BIT(6)
701ba289af8SRoger Chen #define RK3366_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6)
702ba289af8SRoger Chen
703ba289af8SRoger Chen /* RK3366_GRF_SOC_CON7 */
704ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7)
705ba289af8SRoger Chen #define RK3366_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7)
706ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
707ba289af8SRoger Chen #define RK3366_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
708ba289af8SRoger Chen #define RK3366_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
709ba289af8SRoger Chen #define RK3366_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
710ba289af8SRoger Chen
rk3366_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)711ba289af8SRoger Chen static void rk3366_set_to_rgmii(struct rk_priv_data *bsp_priv,
712ba289af8SRoger Chen int tx_delay, int rx_delay)
713ba289af8SRoger Chen {
714ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
715ba289af8SRoger Chen
716ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) {
717ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
718ba289af8SRoger Chen return;
719ba289af8SRoger Chen }
720ba289af8SRoger Chen
721ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
722ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RGMII |
723ba289af8SRoger Chen RK3366_GMAC_RMII_MODE_CLR);
724ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
725eaf70ad1SWadim Egorov DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
726ba289af8SRoger Chen RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
727ba289af8SRoger Chen RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
728ba289af8SRoger Chen }
729ba289af8SRoger Chen
rk3366_set_to_rmii(struct rk_priv_data * bsp_priv)730ba289af8SRoger Chen static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
731ba289af8SRoger Chen {
732ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
733ba289af8SRoger Chen
734ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) {
735ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
736ba289af8SRoger Chen return;
737ba289af8SRoger Chen }
738ba289af8SRoger Chen
739ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
740ba289af8SRoger Chen RK3366_GMAC_PHY_INTF_SEL_RMII | RK3366_GMAC_RMII_MODE);
741ba289af8SRoger Chen }
742ba289af8SRoger Chen
rk3366_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)743ba289af8SRoger Chen static void rk3366_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
744ba289af8SRoger Chen {
745ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
746ba289af8SRoger Chen
747ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) {
748ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
749ba289af8SRoger Chen return;
750ba289af8SRoger Chen }
751ba289af8SRoger Chen
752ba289af8SRoger Chen if (speed == 10)
753ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
754ba289af8SRoger Chen RK3366_GMAC_CLK_2_5M);
755ba289af8SRoger Chen else if (speed == 100)
756ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
757ba289af8SRoger Chen RK3366_GMAC_CLK_25M);
758ba289af8SRoger Chen else if (speed == 1000)
759ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
760ba289af8SRoger Chen RK3366_GMAC_CLK_125M);
761ba289af8SRoger Chen else
762ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
763ba289af8SRoger Chen }
764ba289af8SRoger Chen
rk3366_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)765ba289af8SRoger Chen static void rk3366_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
766ba289af8SRoger Chen {
767ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
768ba289af8SRoger Chen
769ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) {
770ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
771ba289af8SRoger Chen return;
772ba289af8SRoger Chen }
773ba289af8SRoger Chen
774ba289af8SRoger Chen if (speed == 10) {
775ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
776ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_2_5M |
777ba289af8SRoger Chen RK3366_GMAC_SPEED_10M);
778ba289af8SRoger Chen } else if (speed == 100) {
779ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON6,
780ba289af8SRoger Chen RK3366_GMAC_RMII_CLK_25M |
781ba289af8SRoger Chen RK3366_GMAC_SPEED_100M);
782ba289af8SRoger Chen } else {
783ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
784ba289af8SRoger Chen }
785ba289af8SRoger Chen }
786ba289af8SRoger Chen
787ba289af8SRoger Chen static const struct rk_gmac_ops rk3366_ops = {
788ba289af8SRoger Chen .set_to_rgmii = rk3366_set_to_rgmii,
789ba289af8SRoger Chen .set_to_rmii = rk3366_set_to_rmii,
790ba289af8SRoger Chen .set_rgmii_speed = rk3366_set_rgmii_speed,
791ba289af8SRoger Chen .set_rmii_speed = rk3366_set_rmii_speed,
792ba289af8SRoger Chen };
793ba289af8SRoger Chen
794df558854SHeiko Stübner #define RK3368_GRF_SOC_CON15 0x043c
795df558854SHeiko Stübner #define RK3368_GRF_SOC_CON16 0x0440
796df558854SHeiko Stübner
797df558854SHeiko Stübner /* RK3368_GRF_SOC_CON15 */
798df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \
799df558854SHeiko Stübner GRF_CLR_BIT(11))
800df558854SHeiko Stübner #define RK3368_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
801df558854SHeiko Stübner GRF_BIT(11))
802df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL GRF_BIT(8)
803df558854SHeiko Stübner #define RK3368_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8)
804df558854SHeiko Stübner #define RK3368_GMAC_SPEED_10M GRF_CLR_BIT(7)
805df558854SHeiko Stübner #define RK3368_GMAC_SPEED_100M GRF_BIT(7)
806df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_25M GRF_BIT(3)
807df558854SHeiko Stübner #define RK3368_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3)
808df558854SHeiko Stübner #define RK3368_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
809df558854SHeiko Stübner #define RK3368_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5))
810df558854SHeiko Stübner #define RK3368_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5))
811df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE GRF_BIT(6)
812df558854SHeiko Stübner #define RK3368_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6)
813df558854SHeiko Stübner
814df558854SHeiko Stübner /* RK3368_GRF_SOC_CON16 */
815df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7)
816df558854SHeiko Stübner #define RK3368_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7)
817df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
818df558854SHeiko Stübner #define RK3368_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
819df558854SHeiko Stübner #define RK3368_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
820df558854SHeiko Stübner #define RK3368_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
821df558854SHeiko Stübner
rk3368_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)822df558854SHeiko Stübner static void rk3368_set_to_rgmii(struct rk_priv_data *bsp_priv,
823df558854SHeiko Stübner int tx_delay, int rx_delay)
824df558854SHeiko Stübner {
825df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev;
826df558854SHeiko Stübner
827df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) {
828df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
829df558854SHeiko Stübner return;
830df558854SHeiko Stübner }
831df558854SHeiko Stübner
832df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
833df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RGMII |
834df558854SHeiko Stübner RK3368_GMAC_RMII_MODE_CLR);
835df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
836eaf70ad1SWadim Egorov DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
837df558854SHeiko Stübner RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
838df558854SHeiko Stübner RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
839df558854SHeiko Stübner }
840df558854SHeiko Stübner
rk3368_set_to_rmii(struct rk_priv_data * bsp_priv)841df558854SHeiko Stübner static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
842df558854SHeiko Stübner {
843df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev;
844df558854SHeiko Stübner
845df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) {
846df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
847df558854SHeiko Stübner return;
848df558854SHeiko Stübner }
849df558854SHeiko Stübner
850df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
851df558854SHeiko Stübner RK3368_GMAC_PHY_INTF_SEL_RMII | RK3368_GMAC_RMII_MODE);
852df558854SHeiko Stübner }
853df558854SHeiko Stübner
rk3368_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)854df558854SHeiko Stübner static void rk3368_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
855df558854SHeiko Stübner {
856df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev;
857df558854SHeiko Stübner
858df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) {
859df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
860df558854SHeiko Stübner return;
861df558854SHeiko Stübner }
862df558854SHeiko Stübner
863df558854SHeiko Stübner if (speed == 10)
864df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
865df558854SHeiko Stübner RK3368_GMAC_CLK_2_5M);
866df558854SHeiko Stübner else if (speed == 100)
867df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
868df558854SHeiko Stübner RK3368_GMAC_CLK_25M);
869df558854SHeiko Stübner else if (speed == 1000)
870df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
871df558854SHeiko Stübner RK3368_GMAC_CLK_125M);
872df558854SHeiko Stübner else
873df558854SHeiko Stübner dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
874df558854SHeiko Stübner }
875df558854SHeiko Stübner
rk3368_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)876df558854SHeiko Stübner static void rk3368_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
877df558854SHeiko Stübner {
878df558854SHeiko Stübner struct device *dev = &bsp_priv->pdev->dev;
879df558854SHeiko Stübner
880df558854SHeiko Stübner if (IS_ERR(bsp_priv->grf)) {
881df558854SHeiko Stübner dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
882df558854SHeiko Stübner return;
883df558854SHeiko Stübner }
884df558854SHeiko Stübner
885df558854SHeiko Stübner if (speed == 10) {
886df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
887df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_2_5M |
888df558854SHeiko Stübner RK3368_GMAC_SPEED_10M);
889df558854SHeiko Stübner } else if (speed == 100) {
890df558854SHeiko Stübner regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON15,
891df558854SHeiko Stübner RK3368_GMAC_RMII_CLK_25M |
892df558854SHeiko Stübner RK3368_GMAC_SPEED_100M);
893df558854SHeiko Stübner } else {
894df558854SHeiko Stübner dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
895df558854SHeiko Stübner }
896df558854SHeiko Stübner }
897df558854SHeiko Stübner
89892c2588fSJoachim Eastwood static const struct rk_gmac_ops rk3368_ops = {
899df558854SHeiko Stübner .set_to_rgmii = rk3368_set_to_rgmii,
900df558854SHeiko Stübner .set_to_rmii = rk3368_set_to_rmii,
901df558854SHeiko Stübner .set_rgmii_speed = rk3368_set_rgmii_speed,
902df558854SHeiko Stübner .set_rmii_speed = rk3368_set_rmii_speed,
903df558854SHeiko Stübner };
904df558854SHeiko Stübner
905ba289af8SRoger Chen #define RK3399_GRF_SOC_CON5 0xc214
906ba289af8SRoger Chen #define RK3399_GRF_SOC_CON6 0xc218
907ba289af8SRoger Chen
908ba289af8SRoger Chen /* RK3399_GRF_SOC_CON5 */
909ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RGMII (GRF_BIT(9) | GRF_CLR_BIT(10) | \
910ba289af8SRoger Chen GRF_CLR_BIT(11))
911ba289af8SRoger Chen #define RK3399_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(9) | GRF_CLR_BIT(10) | \
912ba289af8SRoger Chen GRF_BIT(11))
913ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL GRF_BIT(8)
914ba289af8SRoger Chen #define RK3399_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(8)
915ba289af8SRoger Chen #define RK3399_GMAC_SPEED_10M GRF_CLR_BIT(7)
916ba289af8SRoger Chen #define RK3399_GMAC_SPEED_100M GRF_BIT(7)
917ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_25M GRF_BIT(3)
918ba289af8SRoger Chen #define RK3399_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(3)
919ba289af8SRoger Chen #define RK3399_GMAC_CLK_125M (GRF_CLR_BIT(4) | GRF_CLR_BIT(5))
920ba289af8SRoger Chen #define RK3399_GMAC_CLK_25M (GRF_BIT(4) | GRF_BIT(5))
921ba289af8SRoger Chen #define RK3399_GMAC_CLK_2_5M (GRF_CLR_BIT(4) | GRF_BIT(5))
922ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE GRF_BIT(6)
923ba289af8SRoger Chen #define RK3399_GMAC_RMII_MODE_CLR GRF_CLR_BIT(6)
924ba289af8SRoger Chen
925ba289af8SRoger Chen /* RK3399_GRF_SOC_CON6 */
926ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7)
927ba289af8SRoger Chen #define RK3399_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7)
928ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
929ba289af8SRoger Chen #define RK3399_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
930ba289af8SRoger Chen #define RK3399_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
931ba289af8SRoger Chen #define RK3399_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
932ba289af8SRoger Chen
rk3399_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)933ba289af8SRoger Chen static void rk3399_set_to_rgmii(struct rk_priv_data *bsp_priv,
934ba289af8SRoger Chen int tx_delay, int rx_delay)
935ba289af8SRoger Chen {
936ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
937ba289af8SRoger Chen
938ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) {
939ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
940ba289af8SRoger Chen return;
941ba289af8SRoger Chen }
942ba289af8SRoger Chen
943ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
944ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RGMII |
945ba289af8SRoger Chen RK3399_GMAC_RMII_MODE_CLR);
946ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
947eaf70ad1SWadim Egorov DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
948ba289af8SRoger Chen RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
949ba289af8SRoger Chen RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
950ba289af8SRoger Chen }
951ba289af8SRoger Chen
rk3399_set_to_rmii(struct rk_priv_data * bsp_priv)952ba289af8SRoger Chen static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
953ba289af8SRoger Chen {
954ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
955ba289af8SRoger Chen
956ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) {
957ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
958ba289af8SRoger Chen return;
959ba289af8SRoger Chen }
960ba289af8SRoger Chen
961ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
962ba289af8SRoger Chen RK3399_GMAC_PHY_INTF_SEL_RMII | RK3399_GMAC_RMII_MODE);
963ba289af8SRoger Chen }
964ba289af8SRoger Chen
rk3399_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)965ba289af8SRoger Chen static void rk3399_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
966ba289af8SRoger Chen {
967ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
968ba289af8SRoger Chen
969ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) {
970ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
971ba289af8SRoger Chen return;
972ba289af8SRoger Chen }
973ba289af8SRoger Chen
974ba289af8SRoger Chen if (speed == 10)
975ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
976ba289af8SRoger Chen RK3399_GMAC_CLK_2_5M);
977ba289af8SRoger Chen else if (speed == 100)
978ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
979ba289af8SRoger Chen RK3399_GMAC_CLK_25M);
980ba289af8SRoger Chen else if (speed == 1000)
981ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
982ba289af8SRoger Chen RK3399_GMAC_CLK_125M);
983ba289af8SRoger Chen else
984ba289af8SRoger Chen dev_err(dev, "unknown speed value for RGMII! speed=%d", speed);
985ba289af8SRoger Chen }
986ba289af8SRoger Chen
rk3399_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)987ba289af8SRoger Chen static void rk3399_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
988ba289af8SRoger Chen {
989ba289af8SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
990ba289af8SRoger Chen
991ba289af8SRoger Chen if (IS_ERR(bsp_priv->grf)) {
992ba289af8SRoger Chen dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
993ba289af8SRoger Chen return;
994ba289af8SRoger Chen }
995ba289af8SRoger Chen
996ba289af8SRoger Chen if (speed == 10) {
997ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
998ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_2_5M |
999ba289af8SRoger Chen RK3399_GMAC_SPEED_10M);
1000ba289af8SRoger Chen } else if (speed == 100) {
1001ba289af8SRoger Chen regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON5,
1002ba289af8SRoger Chen RK3399_GMAC_RMII_CLK_25M |
1003ba289af8SRoger Chen RK3399_GMAC_SPEED_100M);
1004ba289af8SRoger Chen } else {
1005ba289af8SRoger Chen dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
1006ba289af8SRoger Chen }
1007ba289af8SRoger Chen }
1008ba289af8SRoger Chen
1009ba289af8SRoger Chen static const struct rk_gmac_ops rk3399_ops = {
1010ba289af8SRoger Chen .set_to_rgmii = rk3399_set_to_rgmii,
1011ba289af8SRoger Chen .set_to_rmii = rk3399_set_to_rmii,
1012ba289af8SRoger Chen .set_rgmii_speed = rk3399_set_rgmii_speed,
1013ba289af8SRoger Chen .set_rmii_speed = rk3399_set_rmii_speed,
1014ba289af8SRoger Chen };
1015ba289af8SRoger Chen
10163bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON0 0x0380
10173bb3d6b1SDavid Wu #define RK3568_GRF_GMAC0_CON1 0x0384
10183bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON0 0x0388
10193bb3d6b1SDavid Wu #define RK3568_GRF_GMAC1_CON1 0x038c
10203bb3d6b1SDavid Wu
10213bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
10223bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RGMII \
10233bb3d6b1SDavid Wu (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
10243bb3d6b1SDavid Wu #define RK3568_GMAC_PHY_INTF_SEL_RMII \
10253bb3d6b1SDavid Wu (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
10263bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL GRF_BIT(3)
10273bb3d6b1SDavid Wu #define RK3568_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3)
10283bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
10293bb3d6b1SDavid Wu #define RK3568_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
10303bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0)
10313bb3d6b1SDavid Wu #define RK3568_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
10323bb3d6b1SDavid Wu
10333bb3d6b1SDavid Wu /* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
10343bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
10353bb3d6b1SDavid Wu #define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
10363bb3d6b1SDavid Wu
rk3568_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)10373bb3d6b1SDavid Wu static void rk3568_set_to_rgmii(struct rk_priv_data *bsp_priv,
10383bb3d6b1SDavid Wu int tx_delay, int rx_delay)
10393bb3d6b1SDavid Wu {
10403bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
10413bb3d6b1SDavid Wu u32 con0, con1;
10423bb3d6b1SDavid Wu
10433bb3d6b1SDavid Wu if (IS_ERR(bsp_priv->grf)) {
10443bb3d6b1SDavid Wu dev_err(dev, "Missing rockchip,grf property\n");
10453bb3d6b1SDavid Wu return;
10463bb3d6b1SDavid Wu }
10473bb3d6b1SDavid Wu
10483bb3d6b1SDavid Wu con0 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON0 :
10493bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON0;
10503bb3d6b1SDavid Wu con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10513bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON1;
10523bb3d6b1SDavid Wu
10533bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con0,
10543bb3d6b1SDavid Wu RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
10553bb3d6b1SDavid Wu RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
10563bb3d6b1SDavid Wu
10573bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con1,
10583bb3d6b1SDavid Wu RK3568_GMAC_PHY_INTF_SEL_RGMII |
10593bb3d6b1SDavid Wu RK3568_GMAC_RXCLK_DLY_ENABLE |
10603bb3d6b1SDavid Wu RK3568_GMAC_TXCLK_DLY_ENABLE);
10613bb3d6b1SDavid Wu }
10623bb3d6b1SDavid Wu
rk3568_set_to_rmii(struct rk_priv_data * bsp_priv)10633bb3d6b1SDavid Wu static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
10643bb3d6b1SDavid Wu {
10653bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
10663bb3d6b1SDavid Wu u32 con1;
10673bb3d6b1SDavid Wu
10683bb3d6b1SDavid Wu if (IS_ERR(bsp_priv->grf)) {
10693bb3d6b1SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
10703bb3d6b1SDavid Wu return;
10713bb3d6b1SDavid Wu }
10723bb3d6b1SDavid Wu
10733bb3d6b1SDavid Wu con1 = (bsp_priv->id == 1) ? RK3568_GRF_GMAC1_CON1 :
10743bb3d6b1SDavid Wu RK3568_GRF_GMAC0_CON1;
10753bb3d6b1SDavid Wu regmap_write(bsp_priv->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
10763bb3d6b1SDavid Wu }
10773bb3d6b1SDavid Wu
rk3568_set_gmac_speed(struct rk_priv_data * bsp_priv,int speed)10783bb3d6b1SDavid Wu static void rk3568_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
10793bb3d6b1SDavid Wu {
1080ea449f7fSSebastian Reichel struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
10813bb3d6b1SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
10823bb3d6b1SDavid Wu unsigned long rate;
10833bb3d6b1SDavid Wu int ret;
10843bb3d6b1SDavid Wu
10853bb3d6b1SDavid Wu switch (speed) {
10863bb3d6b1SDavid Wu case 10:
10873bb3d6b1SDavid Wu rate = 2500000;
10883bb3d6b1SDavid Wu break;
10893bb3d6b1SDavid Wu case 100:
10903bb3d6b1SDavid Wu rate = 25000000;
10913bb3d6b1SDavid Wu break;
10923bb3d6b1SDavid Wu case 1000:
10933bb3d6b1SDavid Wu rate = 125000000;
10943bb3d6b1SDavid Wu break;
10953bb3d6b1SDavid Wu default:
10963bb3d6b1SDavid Wu dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
10973bb3d6b1SDavid Wu return;
10983bb3d6b1SDavid Wu }
10993bb3d6b1SDavid Wu
1100ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, rate);
11013bb3d6b1SDavid Wu if (ret)
11023bb3d6b1SDavid Wu dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
11033bb3d6b1SDavid Wu __func__, rate, ret);
11043bb3d6b1SDavid Wu }
11053bb3d6b1SDavid Wu
11063bb3d6b1SDavid Wu static const struct rk_gmac_ops rk3568_ops = {
11073bb3d6b1SDavid Wu .set_to_rgmii = rk3568_set_to_rgmii,
11083bb3d6b1SDavid Wu .set_to_rmii = rk3568_set_to_rmii,
11093bb3d6b1SDavid Wu .set_rgmii_speed = rk3568_set_gmac_speed,
11103bb3d6b1SDavid Wu .set_rmii_speed = rk3568_set_gmac_speed,
11110546b224SJohn Keeping .regs_valid = true,
11123bb3d6b1SDavid Wu .regs = {
11133bb3d6b1SDavid Wu 0xfe2a0000, /* gmac0 */
11143bb3d6b1SDavid Wu 0xfe010000, /* gmac1 */
11153bb3d6b1SDavid Wu 0x0, /* sentinel */
11163bb3d6b1SDavid Wu },
11173bb3d6b1SDavid Wu };
11183bb3d6b1SDavid Wu
1119*f9cc9997SDavid Wu /* VCCIO0_1_3_IOC */
1120*f9cc9997SDavid Wu #define RK3576_VCCIO0_1_3_IOC_CON2 0X6408
1121*f9cc9997SDavid Wu #define RK3576_VCCIO0_1_3_IOC_CON3 0X640c
1122*f9cc9997SDavid Wu #define RK3576_VCCIO0_1_3_IOC_CON4 0X6410
1123*f9cc9997SDavid Wu #define RK3576_VCCIO0_1_3_IOC_CON5 0X6414
1124*f9cc9997SDavid Wu
1125*f9cc9997SDavid Wu #define RK3576_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
1126*f9cc9997SDavid Wu #define RK3576_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
1127*f9cc9997SDavid Wu #define RK3576_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7)
1128*f9cc9997SDavid Wu #define RK3576_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7)
1129*f9cc9997SDavid Wu
1130*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
1131*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
1132*f9cc9997SDavid Wu
1133*f9cc9997SDavid Wu /* SDGMAC_GRF */
1134*f9cc9997SDavid Wu #define RK3576_GRF_GMAC_CON0 0X0020
1135*f9cc9997SDavid Wu #define RK3576_GRF_GMAC_CON1 0X0024
1136*f9cc9997SDavid Wu
1137*f9cc9997SDavid Wu #define RK3576_GMAC_RMII_MODE GRF_BIT(3)
1138*f9cc9997SDavid Wu #define RK3576_GMAC_RGMII_MODE GRF_CLR_BIT(3)
1139*f9cc9997SDavid Wu
1140*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_SELECT_IO GRF_BIT(7)
1141*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_SELECT_CRU GRF_CLR_BIT(7)
1142*f9cc9997SDavid Wu
1143*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RMII_DIV2 GRF_BIT(5)
1144*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RMII_DIV20 GRF_CLR_BIT(5)
1145*f9cc9997SDavid Wu
1146*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RGMII_DIV1 \
1147*f9cc9997SDavid Wu (GRF_CLR_BIT(6) | GRF_CLR_BIT(5))
1148*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RGMII_DIV5 \
1149*f9cc9997SDavid Wu (GRF_BIT(6) | GRF_BIT(5))
1150*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RGMII_DIV50 \
1151*f9cc9997SDavid Wu (GRF_BIT(6) | GRF_CLR_BIT(5))
1152*f9cc9997SDavid Wu
1153*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RMII_GATE GRF_BIT(4)
1154*f9cc9997SDavid Wu #define RK3576_GMAC_CLK_RMII_NOGATE GRF_CLR_BIT(4)
1155*f9cc9997SDavid Wu
rk3576_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)1156*f9cc9997SDavid Wu static void rk3576_set_to_rgmii(struct rk_priv_data *bsp_priv,
1157*f9cc9997SDavid Wu int tx_delay, int rx_delay)
1158*f9cc9997SDavid Wu {
1159*f9cc9997SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
1160*f9cc9997SDavid Wu unsigned int offset_con;
1161*f9cc9997SDavid Wu
1162*f9cc9997SDavid Wu if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
1163*f9cc9997SDavid Wu dev_err(dev, "Missing rockchip,grf or rockchip,php-grf property\n");
1164*f9cc9997SDavid Wu return;
1165*f9cc9997SDavid Wu }
1166*f9cc9997SDavid Wu
1167*f9cc9997SDavid Wu offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 :
1168*f9cc9997SDavid Wu RK3576_GRF_GMAC_CON0;
1169*f9cc9997SDavid Wu
1170*f9cc9997SDavid Wu regmap_write(bsp_priv->grf, offset_con, RK3576_GMAC_RGMII_MODE);
1171*f9cc9997SDavid Wu
1172*f9cc9997SDavid Wu offset_con = bsp_priv->id == 1 ? RK3576_VCCIO0_1_3_IOC_CON4 :
1173*f9cc9997SDavid Wu RK3576_VCCIO0_1_3_IOC_CON2;
1174*f9cc9997SDavid Wu
1175*f9cc9997SDavid Wu /* m0 && m1 delay enabled */
1176*f9cc9997SDavid Wu regmap_write(bsp_priv->php_grf, offset_con,
1177*f9cc9997SDavid Wu DELAY_ENABLE(RK3576, tx_delay, rx_delay));
1178*f9cc9997SDavid Wu regmap_write(bsp_priv->php_grf, offset_con + 0x4,
1179*f9cc9997SDavid Wu DELAY_ENABLE(RK3576, tx_delay, rx_delay));
1180*f9cc9997SDavid Wu
1181*f9cc9997SDavid Wu /* m0 && m1 delay value */
1182*f9cc9997SDavid Wu regmap_write(bsp_priv->php_grf, offset_con,
1183*f9cc9997SDavid Wu RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) |
1184*f9cc9997SDavid Wu RK3576_GMAC_CLK_RX_DL_CFG(rx_delay));
1185*f9cc9997SDavid Wu regmap_write(bsp_priv->php_grf, offset_con + 0x4,
1186*f9cc9997SDavid Wu RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) |
1187*f9cc9997SDavid Wu RK3576_GMAC_CLK_RX_DL_CFG(rx_delay));
1188*f9cc9997SDavid Wu }
1189*f9cc9997SDavid Wu
rk3576_set_to_rmii(struct rk_priv_data * bsp_priv)1190*f9cc9997SDavid Wu static void rk3576_set_to_rmii(struct rk_priv_data *bsp_priv)
1191*f9cc9997SDavid Wu {
1192*f9cc9997SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
1193*f9cc9997SDavid Wu unsigned int offset_con;
1194*f9cc9997SDavid Wu
1195*f9cc9997SDavid Wu if (IS_ERR(bsp_priv->grf)) {
1196*f9cc9997SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1197*f9cc9997SDavid Wu return;
1198*f9cc9997SDavid Wu }
1199*f9cc9997SDavid Wu
1200*f9cc9997SDavid Wu offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 :
1201*f9cc9997SDavid Wu RK3576_GRF_GMAC_CON0;
1202*f9cc9997SDavid Wu
1203*f9cc9997SDavid Wu regmap_write(bsp_priv->grf, offset_con, RK3576_GMAC_RMII_MODE);
1204*f9cc9997SDavid Wu }
1205*f9cc9997SDavid Wu
rk3576_set_gmac_speed(struct rk_priv_data * bsp_priv,int speed)1206*f9cc9997SDavid Wu static void rk3576_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
1207*f9cc9997SDavid Wu {
1208*f9cc9997SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
1209*f9cc9997SDavid Wu unsigned int val = 0, offset_con;
1210*f9cc9997SDavid Wu
1211*f9cc9997SDavid Wu switch (speed) {
1212*f9cc9997SDavid Wu case 10:
1213*f9cc9997SDavid Wu if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1214*f9cc9997SDavid Wu val = RK3576_GMAC_CLK_RMII_DIV20;
1215*f9cc9997SDavid Wu else
1216*f9cc9997SDavid Wu val = RK3576_GMAC_CLK_RGMII_DIV50;
1217*f9cc9997SDavid Wu break;
1218*f9cc9997SDavid Wu case 100:
1219*f9cc9997SDavid Wu if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
1220*f9cc9997SDavid Wu val = RK3576_GMAC_CLK_RMII_DIV2;
1221*f9cc9997SDavid Wu else
1222*f9cc9997SDavid Wu val = RK3576_GMAC_CLK_RGMII_DIV5;
1223*f9cc9997SDavid Wu break;
1224*f9cc9997SDavid Wu case 1000:
1225*f9cc9997SDavid Wu if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
1226*f9cc9997SDavid Wu val = RK3576_GMAC_CLK_RGMII_DIV1;
1227*f9cc9997SDavid Wu else
1228*f9cc9997SDavid Wu goto err;
1229*f9cc9997SDavid Wu break;
1230*f9cc9997SDavid Wu default:
1231*f9cc9997SDavid Wu goto err;
1232*f9cc9997SDavid Wu }
1233*f9cc9997SDavid Wu
1234*f9cc9997SDavid Wu offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 :
1235*f9cc9997SDavid Wu RK3576_GRF_GMAC_CON0;
1236*f9cc9997SDavid Wu
1237*f9cc9997SDavid Wu regmap_write(bsp_priv->grf, offset_con, val);
1238*f9cc9997SDavid Wu
1239*f9cc9997SDavid Wu return;
1240*f9cc9997SDavid Wu err:
1241*f9cc9997SDavid Wu dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
1242*f9cc9997SDavid Wu }
1243*f9cc9997SDavid Wu
rk3576_set_clock_selection(struct rk_priv_data * bsp_priv,bool input,bool enable)1244*f9cc9997SDavid Wu static void rk3576_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
1245*f9cc9997SDavid Wu bool enable)
1246*f9cc9997SDavid Wu {
1247*f9cc9997SDavid Wu unsigned int val = input ? RK3576_GMAC_CLK_SELECT_IO :
1248*f9cc9997SDavid Wu RK3576_GMAC_CLK_SELECT_CRU;
1249*f9cc9997SDavid Wu unsigned int offset_con;
1250*f9cc9997SDavid Wu
1251*f9cc9997SDavid Wu val |= enable ? RK3576_GMAC_CLK_RMII_NOGATE :
1252*f9cc9997SDavid Wu RK3576_GMAC_CLK_RMII_GATE;
1253*f9cc9997SDavid Wu
1254*f9cc9997SDavid Wu offset_con = bsp_priv->id == 1 ? RK3576_GRF_GMAC_CON1 :
1255*f9cc9997SDavid Wu RK3576_GRF_GMAC_CON0;
1256*f9cc9997SDavid Wu
1257*f9cc9997SDavid Wu regmap_write(bsp_priv->grf, offset_con, val);
1258*f9cc9997SDavid Wu }
1259*f9cc9997SDavid Wu
1260*f9cc9997SDavid Wu static const struct rk_gmac_ops rk3576_ops = {
1261*f9cc9997SDavid Wu .set_to_rgmii = rk3576_set_to_rgmii,
1262*f9cc9997SDavid Wu .set_to_rmii = rk3576_set_to_rmii,
1263*f9cc9997SDavid Wu .set_rgmii_speed = rk3576_set_gmac_speed,
1264*f9cc9997SDavid Wu .set_rmii_speed = rk3576_set_gmac_speed,
1265*f9cc9997SDavid Wu .set_clock_selection = rk3576_set_clock_selection,
1266*f9cc9997SDavid Wu .regs_valid = true,
1267*f9cc9997SDavid Wu .regs = {
1268*f9cc9997SDavid Wu 0x2a220000, /* gmac0 */
1269*f9cc9997SDavid Wu 0x2a230000, /* gmac1 */
1270*f9cc9997SDavid Wu 0x0, /* sentinel */
1271*f9cc9997SDavid Wu },
1272*f9cc9997SDavid Wu };
1273*f9cc9997SDavid Wu
12742f2b60a0SDavid Wu /* sys_grf */
12752f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON7 0X031c
12762f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON8 0X0320
12772f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON9 0X0324
12782f2b60a0SDavid Wu
12792f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 3)
12802f2b60a0SDavid Wu #define RK3588_GMAC_RXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 3)
12812f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 2)
12822f2b60a0SDavid Wu #define RK3588_GMAC_TXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 2)
12832f2b60a0SDavid Wu
12842f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8)
12852f2b60a0SDavid Wu #define RK3588_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0)
12862f2b60a0SDavid Wu
12872f2b60a0SDavid Wu /* php_grf */
12882f2b60a0SDavid Wu #define RK3588_GRF_GMAC_CON0 0X0008
12892f2b60a0SDavid Wu #define RK3588_GRF_CLK_CON1 0X0070
12902f2b60a0SDavid Wu
12912f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RGMII(id) \
12922f2b60a0SDavid Wu (GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
12932f2b60a0SDavid Wu #define RK3588_GMAC_PHY_INTF_SEL_RMII(id) \
12942f2b60a0SDavid Wu (GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
12952f2b60a0SDavid Wu
12962f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_MODE(id) GRF_BIT(5 * (id))
12972f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_MODE(id) GRF_CLR_BIT(5 * (id))
12982f2b60a0SDavid Wu
129978a60497SDetlev Casanova #define RK3588_GMAC_CLK_SELECT_CRU(id) GRF_BIT(5 * (id) + 4)
130078a60497SDetlev Casanova #define RK3588_GMAC_CLK_SELECT_IO(id) GRF_CLR_BIT(5 * (id) + 4)
13012f2b60a0SDavid Wu
13022f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV2(id) GRF_BIT(5 * (id) + 2)
13032f2b60a0SDavid Wu #define RK3588_GMA_CLK_RMII_DIV20(id) GRF_CLR_BIT(5 * (id) + 2)
13042f2b60a0SDavid Wu
13052f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV1(id) \
13062f2b60a0SDavid Wu (GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
13072f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV5(id) \
13082f2b60a0SDavid Wu (GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
13092f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RGMII_DIV50(id) \
13102f2b60a0SDavid Wu (GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
13112f2b60a0SDavid Wu
13122f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_GATE(id) GRF_BIT(5 * (id) + 1)
13132f2b60a0SDavid Wu #define RK3588_GMAC_CLK_RMII_NOGATE(id) GRF_CLR_BIT(5 * (id) + 1)
13142f2b60a0SDavid Wu
rk3588_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)13152f2b60a0SDavid Wu static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
13162f2b60a0SDavid Wu int tx_delay, int rx_delay)
13172f2b60a0SDavid Wu {
13182f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
13192f2b60a0SDavid Wu u32 offset_con, id = bsp_priv->id;
13202f2b60a0SDavid Wu
13212f2b60a0SDavid Wu if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
13222f2b60a0SDavid Wu dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n");
13232f2b60a0SDavid Wu return;
13242f2b60a0SDavid Wu }
13252f2b60a0SDavid Wu
13262f2b60a0SDavid Wu offset_con = bsp_priv->id == 1 ? RK3588_GRF_GMAC_CON9 :
13272f2b60a0SDavid Wu RK3588_GRF_GMAC_CON8;
13282f2b60a0SDavid Wu
13292f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
13302f2b60a0SDavid Wu RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
13312f2b60a0SDavid Wu
13322f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
13332f2b60a0SDavid Wu RK3588_GMAC_CLK_RGMII_MODE(id));
13342f2b60a0SDavid Wu
13352f2b60a0SDavid Wu regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7,
13362f2b60a0SDavid Wu RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
13372f2b60a0SDavid Wu RK3588_GMAC_TXCLK_DLY_ENABLE(id));
13382f2b60a0SDavid Wu
13392f2b60a0SDavid Wu regmap_write(bsp_priv->grf, offset_con,
13402f2b60a0SDavid Wu RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
13412f2b60a0SDavid Wu RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
13422f2b60a0SDavid Wu }
13432f2b60a0SDavid Wu
rk3588_set_to_rmii(struct rk_priv_data * bsp_priv)13442f2b60a0SDavid Wu static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv)
13452f2b60a0SDavid Wu {
13462f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
13472f2b60a0SDavid Wu
13482f2b60a0SDavid Wu if (IS_ERR(bsp_priv->php_grf)) {
13492f2b60a0SDavid Wu dev_err(dev, "%s: Missing rockchip,php_grf property\n", __func__);
13502f2b60a0SDavid Wu return;
13512f2b60a0SDavid Wu }
13522f2b60a0SDavid Wu
13532f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
13542f2b60a0SDavid Wu RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->id));
13552f2b60a0SDavid Wu
13562f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
13572f2b60a0SDavid Wu RK3588_GMAC_CLK_RMII_MODE(bsp_priv->id));
13582f2b60a0SDavid Wu }
13592f2b60a0SDavid Wu
rk3588_set_gmac_speed(struct rk_priv_data * bsp_priv,int speed)13602f2b60a0SDavid Wu static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
13612f2b60a0SDavid Wu {
13622f2b60a0SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
13632f2b60a0SDavid Wu unsigned int val = 0, id = bsp_priv->id;
13642f2b60a0SDavid Wu
13652f2b60a0SDavid Wu switch (speed) {
13662f2b60a0SDavid Wu case 10:
13672f2b60a0SDavid Wu if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
13682f2b60a0SDavid Wu val = RK3588_GMA_CLK_RMII_DIV20(id);
13692f2b60a0SDavid Wu else
13702f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV50(id);
13712f2b60a0SDavid Wu break;
13722f2b60a0SDavid Wu case 100:
13732f2b60a0SDavid Wu if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
13742f2b60a0SDavid Wu val = RK3588_GMA_CLK_RMII_DIV2(id);
13752f2b60a0SDavid Wu else
13762f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV5(id);
13772f2b60a0SDavid Wu break;
13782f2b60a0SDavid Wu case 1000:
13792f2b60a0SDavid Wu if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
13802f2b60a0SDavid Wu val = RK3588_GMAC_CLK_RGMII_DIV1(id);
13812f2b60a0SDavid Wu else
13822f2b60a0SDavid Wu goto err;
13832f2b60a0SDavid Wu break;
13842f2b60a0SDavid Wu default:
13852f2b60a0SDavid Wu goto err;
13862f2b60a0SDavid Wu }
13872f2b60a0SDavid Wu
13882f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
13892f2b60a0SDavid Wu
13902f2b60a0SDavid Wu return;
13912f2b60a0SDavid Wu err:
13922f2b60a0SDavid Wu dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
13932f2b60a0SDavid Wu }
13942f2b60a0SDavid Wu
rk3588_set_clock_selection(struct rk_priv_data * bsp_priv,bool input,bool enable)13952f2b60a0SDavid Wu static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
13962f2b60a0SDavid Wu bool enable)
13972f2b60a0SDavid Wu {
139878a60497SDetlev Casanova unsigned int val = input ? RK3588_GMAC_CLK_SELECT_IO(bsp_priv->id) :
139978a60497SDetlev Casanova RK3588_GMAC_CLK_SELECT_CRU(bsp_priv->id);
14002f2b60a0SDavid Wu
14012f2b60a0SDavid Wu val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->id) :
14022f2b60a0SDavid Wu RK3588_GMAC_CLK_RMII_GATE(bsp_priv->id);
14032f2b60a0SDavid Wu
14042f2b60a0SDavid Wu regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
14052f2b60a0SDavid Wu }
14062f2b60a0SDavid Wu
14072f2b60a0SDavid Wu static const struct rk_gmac_ops rk3588_ops = {
14082f2b60a0SDavid Wu .set_to_rgmii = rk3588_set_to_rgmii,
14092f2b60a0SDavid Wu .set_to_rmii = rk3588_set_to_rmii,
14102f2b60a0SDavid Wu .set_rgmii_speed = rk3588_set_gmac_speed,
14112f2b60a0SDavid Wu .set_rmii_speed = rk3588_set_gmac_speed,
14122f2b60a0SDavid Wu .set_clock_selection = rk3588_set_clock_selection,
141388619e77SBenjamin Gaignard .regs_valid = true,
141488619e77SBenjamin Gaignard .regs = {
141588619e77SBenjamin Gaignard 0xfe1b0000, /* gmac0 */
141688619e77SBenjamin Gaignard 0xfe1c0000, /* gmac1 */
141788619e77SBenjamin Gaignard 0x0, /* sentinel */
141888619e77SBenjamin Gaignard },
14192f2b60a0SDavid Wu };
14202f2b60a0SDavid Wu
142189c9c163SDavid Wu #define RV1108_GRF_GMAC_CON0 0X0900
142289c9c163SDavid Wu
142389c9c163SDavid Wu /* RV1108_GRF_GMAC_CON0 */
142489c9c163SDavid Wu #define RV1108_GMAC_PHY_INTF_SEL_RMII (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | \
142589c9c163SDavid Wu GRF_BIT(6))
142689c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL GRF_BIT(3)
142789c9c163SDavid Wu #define RV1108_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(3)
142889c9c163SDavid Wu #define RV1108_GMAC_SPEED_10M GRF_CLR_BIT(2)
142989c9c163SDavid Wu #define RV1108_GMAC_SPEED_100M GRF_BIT(2)
143089c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_25M GRF_BIT(7)
143189c9c163SDavid Wu #define RV1108_GMAC_RMII_CLK_2_5M GRF_CLR_BIT(7)
143289c9c163SDavid Wu
rv1108_set_to_rmii(struct rk_priv_data * bsp_priv)143389c9c163SDavid Wu static void rv1108_set_to_rmii(struct rk_priv_data *bsp_priv)
143489c9c163SDavid Wu {
143589c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
143689c9c163SDavid Wu
143789c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) {
143889c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
143989c9c163SDavid Wu return;
144089c9c163SDavid Wu }
144189c9c163SDavid Wu
144289c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
144389c9c163SDavid Wu RV1108_GMAC_PHY_INTF_SEL_RMII);
144489c9c163SDavid Wu }
144589c9c163SDavid Wu
rv1108_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)144689c9c163SDavid Wu static void rv1108_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
144789c9c163SDavid Wu {
144889c9c163SDavid Wu struct device *dev = &bsp_priv->pdev->dev;
144989c9c163SDavid Wu
145089c9c163SDavid Wu if (IS_ERR(bsp_priv->grf)) {
145189c9c163SDavid Wu dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
145289c9c163SDavid Wu return;
145389c9c163SDavid Wu }
145489c9c163SDavid Wu
145589c9c163SDavid Wu if (speed == 10) {
145689c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
145789c9c163SDavid Wu RV1108_GMAC_RMII_CLK_2_5M |
145889c9c163SDavid Wu RV1108_GMAC_SPEED_10M);
145989c9c163SDavid Wu } else if (speed == 100) {
146089c9c163SDavid Wu regmap_write(bsp_priv->grf, RV1108_GRF_GMAC_CON0,
146189c9c163SDavid Wu RV1108_GMAC_RMII_CLK_25M |
146289c9c163SDavid Wu RV1108_GMAC_SPEED_100M);
146389c9c163SDavid Wu } else {
146489c9c163SDavid Wu dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
146589c9c163SDavid Wu }
146689c9c163SDavid Wu }
146789c9c163SDavid Wu
146889c9c163SDavid Wu static const struct rk_gmac_ops rv1108_ops = {
146989c9c163SDavid Wu .set_to_rmii = rv1108_set_to_rmii,
147089c9c163SDavid Wu .set_rmii_speed = rv1108_set_rmii_speed,
147189c9c163SDavid Wu };
147289c9c163SDavid Wu
1473c931b060SAnand Moon #define RV1126_GRF_GMAC_CON0 0X0070
1474c931b060SAnand Moon #define RV1126_GRF_GMAC_CON1 0X0074
1475c931b060SAnand Moon #define RV1126_GRF_GMAC_CON2 0X0078
1476c931b060SAnand Moon
1477c931b060SAnand Moon /* RV1126_GRF_GMAC_CON0 */
1478c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RGMII \
1479c931b060SAnand Moon (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
1480c931b060SAnand Moon #define RV1126_GMAC_PHY_INTF_SEL_RMII \
1481c931b060SAnand Moon (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
1482c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL GRF_BIT(7)
1483c931b060SAnand Moon #define RV1126_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(7)
1484c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_ENABLE GRF_BIT(1)
1485c931b060SAnand Moon #define RV1126_GMAC_M0_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
1486c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_ENABLE GRF_BIT(0)
1487c931b060SAnand Moon #define RV1126_GMAC_M0_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
1488c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_ENABLE GRF_BIT(3)
1489c931b060SAnand Moon #define RV1126_GMAC_M1_RXCLK_DLY_DISABLE GRF_CLR_BIT(3)
1490c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_ENABLE GRF_BIT(2)
1491c931b060SAnand Moon #define RV1126_GMAC_M1_TXCLK_DLY_DISABLE GRF_CLR_BIT(2)
1492c931b060SAnand Moon
1493c931b060SAnand Moon /* RV1126_GRF_GMAC_CON1 */
1494c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
1495c931b060SAnand Moon #define RV1126_GMAC_M0_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
1496c931b060SAnand Moon /* RV1126_GRF_GMAC_CON2 */
1497c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
1498c931b060SAnand Moon #define RV1126_GMAC_M1_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
1499c931b060SAnand Moon
rv1126_set_to_rgmii(struct rk_priv_data * bsp_priv,int tx_delay,int rx_delay)1500c931b060SAnand Moon static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
1501c931b060SAnand Moon int tx_delay, int rx_delay)
1502c931b060SAnand Moon {
1503c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev;
1504c931b060SAnand Moon
1505c931b060SAnand Moon if (IS_ERR(bsp_priv->grf)) {
1506c931b060SAnand Moon dev_err(dev, "Missing rockchip,grf property\n");
1507c931b060SAnand Moon return;
1508c931b060SAnand Moon }
1509c931b060SAnand Moon
1510c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1511c931b060SAnand Moon RV1126_GMAC_PHY_INTF_SEL_RGMII |
1512c931b060SAnand Moon RV1126_GMAC_M0_RXCLK_DLY_ENABLE |
1513c931b060SAnand Moon RV1126_GMAC_M0_TXCLK_DLY_ENABLE |
1514c931b060SAnand Moon RV1126_GMAC_M1_RXCLK_DLY_ENABLE |
1515c931b060SAnand Moon RV1126_GMAC_M1_TXCLK_DLY_ENABLE);
1516c931b060SAnand Moon
1517c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1,
1518c931b060SAnand Moon RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) |
1519c931b060SAnand Moon RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay));
1520c931b060SAnand Moon
1521c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2,
1522c931b060SAnand Moon RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) |
1523c931b060SAnand Moon RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay));
1524c931b060SAnand Moon }
1525c931b060SAnand Moon
rv1126_set_to_rmii(struct rk_priv_data * bsp_priv)1526c931b060SAnand Moon static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
1527c931b060SAnand Moon {
1528c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev;
1529c931b060SAnand Moon
1530c931b060SAnand Moon if (IS_ERR(bsp_priv->grf)) {
1531c931b060SAnand Moon dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
1532c931b060SAnand Moon return;
1533c931b060SAnand Moon }
1534c931b060SAnand Moon
1535c931b060SAnand Moon regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
1536c931b060SAnand Moon RV1126_GMAC_PHY_INTF_SEL_RMII);
1537c931b060SAnand Moon }
1538c931b060SAnand Moon
rv1126_set_rgmii_speed(struct rk_priv_data * bsp_priv,int speed)1539c931b060SAnand Moon static void rv1126_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
1540c931b060SAnand Moon {
1541ea449f7fSSebastian Reichel struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
1542c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev;
1543c931b060SAnand Moon unsigned long rate;
1544c931b060SAnand Moon int ret;
1545c931b060SAnand Moon
1546c931b060SAnand Moon switch (speed) {
1547c931b060SAnand Moon case 10:
1548c931b060SAnand Moon rate = 2500000;
1549c931b060SAnand Moon break;
1550c931b060SAnand Moon case 100:
1551c931b060SAnand Moon rate = 25000000;
1552c931b060SAnand Moon break;
1553c931b060SAnand Moon case 1000:
1554c931b060SAnand Moon rate = 125000000;
1555c931b060SAnand Moon break;
1556c931b060SAnand Moon default:
1557c931b060SAnand Moon dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1558c931b060SAnand Moon return;
1559c931b060SAnand Moon }
1560c931b060SAnand Moon
1561ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, rate);
1562c931b060SAnand Moon if (ret)
1563c931b060SAnand Moon dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1564c931b060SAnand Moon __func__, rate, ret);
1565c931b060SAnand Moon }
1566c931b060SAnand Moon
rv1126_set_rmii_speed(struct rk_priv_data * bsp_priv,int speed)1567c931b060SAnand Moon static void rv1126_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
1568c931b060SAnand Moon {
1569ea449f7fSSebastian Reichel struct clk *clk_mac_speed = bsp_priv->clks[RK_CLK_MAC_SPEED].clk;
1570c931b060SAnand Moon struct device *dev = &bsp_priv->pdev->dev;
1571c931b060SAnand Moon unsigned long rate;
1572c931b060SAnand Moon int ret;
1573c931b060SAnand Moon
1574c931b060SAnand Moon switch (speed) {
1575c931b060SAnand Moon case 10:
1576c931b060SAnand Moon rate = 2500000;
1577c931b060SAnand Moon break;
1578c931b060SAnand Moon case 100:
1579c931b060SAnand Moon rate = 25000000;
1580c931b060SAnand Moon break;
1581c931b060SAnand Moon default:
1582c931b060SAnand Moon dev_err(dev, "unknown speed value for RGMII speed=%d", speed);
1583c931b060SAnand Moon return;
1584c931b060SAnand Moon }
1585c931b060SAnand Moon
1586ea449f7fSSebastian Reichel ret = clk_set_rate(clk_mac_speed, rate);
1587c931b060SAnand Moon if (ret)
1588c931b060SAnand Moon dev_err(dev, "%s: set clk_mac_speed rate %ld failed %d\n",
1589c931b060SAnand Moon __func__, rate, ret);
1590c931b060SAnand Moon }
1591c931b060SAnand Moon
1592c931b060SAnand Moon static const struct rk_gmac_ops rv1126_ops = {
1593c931b060SAnand Moon .set_to_rgmii = rv1126_set_to_rgmii,
1594c931b060SAnand Moon .set_to_rmii = rv1126_set_to_rmii,
1595c931b060SAnand Moon .set_rgmii_speed = rv1126_set_rgmii_speed,
1596c931b060SAnand Moon .set_rmii_speed = rv1126_set_rmii_speed,
1597c931b060SAnand Moon };
1598c931b060SAnand Moon
1599fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON0 0xb00
1600fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON1 0xb04
1601fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON2 0xb08
1602fecd4d7eSDavid Wu #define RK_GRF_MACPHY_CON3 0xb0c
1603fecd4d7eSDavid Wu
1604fecd4d7eSDavid Wu #define RK_MACPHY_ENABLE GRF_BIT(0)
1605fecd4d7eSDavid Wu #define RK_MACPHY_DISABLE GRF_CLR_BIT(0)
1606fecd4d7eSDavid Wu #define RK_MACPHY_CFG_CLK_50M GRF_BIT(14)
1607fecd4d7eSDavid Wu #define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7))
1608fecd4d7eSDavid Wu #define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0)
1609fecd4d7eSDavid Wu #define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0)
1610fecd4d7eSDavid Wu
rk_gmac_integrated_phy_powerup(struct rk_priv_data * priv)1611fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
16127ad269eaSRoger Chen {
1613fecd4d7eSDavid Wu if (priv->ops->integrated_phy_powerup)
1614fecd4d7eSDavid Wu priv->ops->integrated_phy_powerup(priv);
1615fecd4d7eSDavid Wu
1616fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
1617fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
1618fecd4d7eSDavid Wu
1619fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
1620fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
1621fecd4d7eSDavid Wu
1622fecd4d7eSDavid Wu if (priv->phy_reset) {
1623fecd4d7eSDavid Wu /* PHY needs to be disabled before trying to reset it */
1624fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1625fecd4d7eSDavid Wu if (priv->phy_reset)
1626fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset);
1627fecd4d7eSDavid Wu usleep_range(10, 20);
1628fecd4d7eSDavid Wu if (priv->phy_reset)
1629fecd4d7eSDavid Wu reset_control_deassert(priv->phy_reset);
1630fecd4d7eSDavid Wu usleep_range(10, 20);
1631fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
1632fecd4d7eSDavid Wu msleep(30);
1633fecd4d7eSDavid Wu }
1634fecd4d7eSDavid Wu }
1635fecd4d7eSDavid Wu
rk_gmac_integrated_phy_powerdown(struct rk_priv_data * priv)1636fecd4d7eSDavid Wu static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
1637fecd4d7eSDavid Wu {
1638fecd4d7eSDavid Wu regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
1639fecd4d7eSDavid Wu if (priv->phy_reset)
1640fecd4d7eSDavid Wu reset_control_assert(priv->phy_reset);
1641fecd4d7eSDavid Wu }
1642fecd4d7eSDavid Wu
rk_gmac_clk_init(struct plat_stmmacenet_data * plat)1643fecd4d7eSDavid Wu static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
1644fecd4d7eSDavid Wu {
1645fecd4d7eSDavid Wu struct rk_priv_data *bsp_priv = plat->bsp_priv;
16467ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev;
1647ea449f7fSSebastian Reichel int phy_iface = bsp_priv->phy_iface;
1648ea449f7fSSebastian Reichel int i, j, ret;
16497ad269eaSRoger Chen
16507ad269eaSRoger Chen bsp_priv->clk_enabled = false;
16517ad269eaSRoger Chen
1652ea449f7fSSebastian Reichel bsp_priv->num_clks = ARRAY_SIZE(rk_clocks);
1653ea449f7fSSebastian Reichel if (phy_iface == PHY_INTERFACE_MODE_RMII)
1654ea449f7fSSebastian Reichel bsp_priv->num_clks += ARRAY_SIZE(rk_rmii_clocks);
16557ad269eaSRoger Chen
1656ea449f7fSSebastian Reichel bsp_priv->clks = devm_kcalloc(dev, bsp_priv->num_clks,
1657ea449f7fSSebastian Reichel sizeof(*bsp_priv->clks), GFP_KERNEL);
1658ea449f7fSSebastian Reichel if (!bsp_priv->clks)
1659ea449f7fSSebastian Reichel return -ENOMEM;
16607ad269eaSRoger Chen
1661ea449f7fSSebastian Reichel for (i = 0; i < ARRAY_SIZE(rk_clocks); i++)
1662ea449f7fSSebastian Reichel bsp_priv->clks[i].id = rk_clocks[i];
16637ad269eaSRoger Chen
1664ea449f7fSSebastian Reichel if (phy_iface == PHY_INTERFACE_MODE_RMII) {
1665ea449f7fSSebastian Reichel for (j = 0; j < ARRAY_SIZE(rk_rmii_clocks); j++)
1666ea449f7fSSebastian Reichel bsp_priv->clks[i++].id = rk_rmii_clocks[j];
1667ea449f7fSSebastian Reichel }
16687ad269eaSRoger Chen
1669ea449f7fSSebastian Reichel ret = devm_clk_bulk_get_optional(dev, bsp_priv->num_clks,
1670ea449f7fSSebastian Reichel bsp_priv->clks);
1671ea449f7fSSebastian Reichel if (ret)
1672ea449f7fSSebastian Reichel return dev_err_probe(dev, ret, "Failed to get clocks\n");
1673ea449f7fSSebastian Reichel
1674ea449f7fSSebastian Reichel /* "stmmaceth" will be enabled by the core */
16757ad269eaSRoger Chen bsp_priv->clk_mac = devm_clk_get(dev, "stmmaceth");
1676ea449f7fSSebastian Reichel ret = PTR_ERR_OR_ZERO(bsp_priv->clk_mac);
1677ea449f7fSSebastian Reichel if (ret)
1678ea449f7fSSebastian Reichel return dev_err_probe(dev, ret, "Cannot get stmmaceth clock\n");
167923c94d63SDavid Wu
16807ad269eaSRoger Chen if (bsp_priv->clock_input) {
1681d42202dcSRomain Perier dev_info(dev, "clock input from PHY\n");
1682ea449f7fSSebastian Reichel } else if (phy_iface == PHY_INTERFACE_MODE_RMII) {
1683c48fa33cSHeiko Stübner clk_set_rate(bsp_priv->clk_mac, 50000000);
16847ad269eaSRoger Chen }
16857ad269eaSRoger Chen
1686fecd4d7eSDavid Wu if (plat->phy_node && bsp_priv->integrated_phy) {
1687fecd4d7eSDavid Wu bsp_priv->clk_phy = of_clk_get(plat->phy_node, 0);
1688ea449f7fSSebastian Reichel ret = PTR_ERR_OR_ZERO(bsp_priv->clk_phy);
1689ea449f7fSSebastian Reichel if (ret)
1690ea449f7fSSebastian Reichel return dev_err_probe(dev, ret, "Cannot get PHY clock\n");
1691fecd4d7eSDavid Wu clk_set_rate(bsp_priv->clk_phy, 50000000);
1692fecd4d7eSDavid Wu }
1693fecd4d7eSDavid Wu
16947ad269eaSRoger Chen return 0;
16957ad269eaSRoger Chen }
16967ad269eaSRoger Chen
gmac_clk_enable(struct rk_priv_data * bsp_priv,bool enable)16977ad269eaSRoger Chen static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
16987ad269eaSRoger Chen {
1699ea449f7fSSebastian Reichel int ret;
17007ad269eaSRoger Chen
17017ad269eaSRoger Chen if (enable) {
17027ad269eaSRoger Chen if (!bsp_priv->clk_enabled) {
1703ea449f7fSSebastian Reichel ret = clk_bulk_prepare_enable(bsp_priv->num_clks,
1704ea449f7fSSebastian Reichel bsp_priv->clks);
1705ea449f7fSSebastian Reichel if (ret)
1706ea449f7fSSebastian Reichel return ret;
17077ad269eaSRoger Chen
1708ea449f7fSSebastian Reichel ret = clk_prepare_enable(bsp_priv->clk_phy);
1709ea449f7fSSebastian Reichel if (ret)
1710ea449f7fSSebastian Reichel return ret;
171123c94d63SDavid Wu
17122f2b60a0SDavid Wu if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
17132f2b60a0SDavid Wu bsp_priv->ops->set_clock_selection(bsp_priv,
17142f2b60a0SDavid Wu bsp_priv->clock_input, true);
17152f2b60a0SDavid Wu
17167ad269eaSRoger Chen mdelay(5);
17177ad269eaSRoger Chen bsp_priv->clk_enabled = true;
17187ad269eaSRoger Chen }
17197ad269eaSRoger Chen } else {
17207ad269eaSRoger Chen if (bsp_priv->clk_enabled) {
1721ea449f7fSSebastian Reichel clk_bulk_disable_unprepare(bsp_priv->num_clks,
1722ea449f7fSSebastian Reichel bsp_priv->clks);
1723fecd4d7eSDavid Wu clk_disable_unprepare(bsp_priv->clk_phy);
1724fecd4d7eSDavid Wu
17252f2b60a0SDavid Wu if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
17262f2b60a0SDavid Wu bsp_priv->ops->set_clock_selection(bsp_priv,
17272f2b60a0SDavid Wu bsp_priv->clock_input, false);
1728ea449f7fSSebastian Reichel
17297ad269eaSRoger Chen bsp_priv->clk_enabled = false;
17307ad269eaSRoger Chen }
17317ad269eaSRoger Chen }
17327ad269eaSRoger Chen
17337ad269eaSRoger Chen return 0;
17347ad269eaSRoger Chen }
17357ad269eaSRoger Chen
phy_power_on(struct rk_priv_data * bsp_priv,bool enable)17367ad269eaSRoger Chen static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
17377ad269eaSRoger Chen {
17382e12f536SRomain Perier struct regulator *ldo = bsp_priv->regulator;
17397ad269eaSRoger Chen int ret;
17407ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev;
17417ad269eaSRoger Chen
17427ad269eaSRoger Chen if (enable) {
17437ad269eaSRoger Chen ret = regulator_enable(ldo);
17442e12f536SRomain Perier if (ret)
1745d42202dcSRomain Perier dev_err(dev, "fail to enable phy-supply\n");
17467ad269eaSRoger Chen } else {
17477ad269eaSRoger Chen ret = regulator_disable(ldo);
17482e12f536SRomain Perier if (ret)
1749d42202dcSRomain Perier dev_err(dev, "fail to disable phy-supply\n");
17507ad269eaSRoger Chen }
17517ad269eaSRoger Chen
17527ad269eaSRoger Chen return 0;
17537ad269eaSRoger Chen }
17547ad269eaSRoger Chen
rk_gmac_setup(struct platform_device * pdev,struct plat_stmmacenet_data * plat,const struct rk_gmac_ops * ops)17550fb98db1SHeiko Stübner static struct rk_priv_data *rk_gmac_setup(struct platform_device *pdev,
1756fecd4d7eSDavid Wu struct plat_stmmacenet_data *plat,
175792c2588fSJoachim Eastwood const struct rk_gmac_ops *ops)
17587ad269eaSRoger Chen {
17597ad269eaSRoger Chen struct rk_priv_data *bsp_priv;
17607ad269eaSRoger Chen struct device *dev = &pdev->dev;
17613bb3d6b1SDavid Wu struct resource *res;
17627ad269eaSRoger Chen int ret;
17637ad269eaSRoger Chen const char *strings = NULL;
17647ad269eaSRoger Chen int value;
17657ad269eaSRoger Chen
17667ad269eaSRoger Chen bsp_priv = devm_kzalloc(dev, sizeof(*bsp_priv), GFP_KERNEL);
17677ad269eaSRoger Chen if (!bsp_priv)
17687ad269eaSRoger Chen return ERR_PTR(-ENOMEM);
17697ad269eaSRoger Chen
17700c65b2b9SAndrew Lunn of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
17710fb98db1SHeiko Stübner bsp_priv->ops = ops;
17727ad269eaSRoger Chen
17733bb3d6b1SDavid Wu /* Some SoCs have multiple MAC controllers, which need
17743bb3d6b1SDavid Wu * to be distinguished.
17753bb3d6b1SDavid Wu */
17763bb3d6b1SDavid Wu res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
17770546b224SJohn Keeping if (res && ops->regs_valid) {
17783bb3d6b1SDavid Wu int i = 0;
17793bb3d6b1SDavid Wu
17803bb3d6b1SDavid Wu while (ops->regs[i]) {
17813bb3d6b1SDavid Wu if (ops->regs[i] == res->start) {
17823bb3d6b1SDavid Wu bsp_priv->id = i;
17833bb3d6b1SDavid Wu break;
17843bb3d6b1SDavid Wu }
17853bb3d6b1SDavid Wu i++;
17863bb3d6b1SDavid Wu }
17873bb3d6b1SDavid Wu }
17883bb3d6b1SDavid Wu
1789db219732SSebastian Reichel bsp_priv->regulator = devm_regulator_get(dev, "phy");
17902e12f536SRomain Perier if (IS_ERR(bsp_priv->regulator)) {
1791db219732SSebastian Reichel ret = PTR_ERR(bsp_priv->regulator);
1792db219732SSebastian Reichel dev_err_probe(dev, ret, "failed to get phy regulator\n");
1793db219732SSebastian Reichel return ERR_PTR(ret);
17947ad269eaSRoger Chen }
17957ad269eaSRoger Chen
17967ad269eaSRoger Chen ret = of_property_read_string(dev->of_node, "clock_in_out", &strings);
17977ad269eaSRoger Chen if (ret) {
1798d42202dcSRomain Perier dev_err(dev, "Can not read property: clock_in_out.\n");
17997ad269eaSRoger Chen bsp_priv->clock_input = true;
18007ad269eaSRoger Chen } else {
1801d42202dcSRomain Perier dev_info(dev, "clock input or output? (%s).\n",
1802d42202dcSRomain Perier strings);
18037ad269eaSRoger Chen if (!strcmp(strings, "input"))
18047ad269eaSRoger Chen bsp_priv->clock_input = true;
18057ad269eaSRoger Chen else
18067ad269eaSRoger Chen bsp_priv->clock_input = false;
18077ad269eaSRoger Chen }
18087ad269eaSRoger Chen
18097ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
18107ad269eaSRoger Chen if (ret) {
18117ad269eaSRoger Chen bsp_priv->tx_delay = 0x30;
1812d42202dcSRomain Perier dev_err(dev, "Can not read property: tx_delay.");
1813d42202dcSRomain Perier dev_err(dev, "set tx_delay to 0x%x\n",
1814d42202dcSRomain Perier bsp_priv->tx_delay);
18157ad269eaSRoger Chen } else {
1816d42202dcSRomain Perier dev_info(dev, "TX delay(0x%x).\n", value);
18177ad269eaSRoger Chen bsp_priv->tx_delay = value;
18187ad269eaSRoger Chen }
18197ad269eaSRoger Chen
18207ad269eaSRoger Chen ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
18217ad269eaSRoger Chen if (ret) {
18227ad269eaSRoger Chen bsp_priv->rx_delay = 0x10;
1823d42202dcSRomain Perier dev_err(dev, "Can not read property: rx_delay.");
1824d42202dcSRomain Perier dev_err(dev, "set rx_delay to 0x%x\n",
1825d42202dcSRomain Perier bsp_priv->rx_delay);
18267ad269eaSRoger Chen } else {
1827d42202dcSRomain Perier dev_info(dev, "RX delay(0x%x).\n", value);
18287ad269eaSRoger Chen bsp_priv->rx_delay = value;
18297ad269eaSRoger Chen }
18307ad269eaSRoger Chen
18317ad269eaSRoger Chen bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
18327ad269eaSRoger Chen "rockchip,grf");
18332f2b60a0SDavid Wu bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
18342f2b60a0SDavid Wu "rockchip,php-grf");
18357ad269eaSRoger Chen
1836fecd4d7eSDavid Wu if (plat->phy_node) {
1837fecd4d7eSDavid Wu bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
1838fecd4d7eSDavid Wu "phy-is-integrated");
1839fecd4d7eSDavid Wu if (bsp_priv->integrated_phy) {
1840fecd4d7eSDavid Wu bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
1841fecd4d7eSDavid Wu if (IS_ERR(bsp_priv->phy_reset)) {
1842fecd4d7eSDavid Wu dev_err(&pdev->dev, "No PHY reset control found.\n");
1843fecd4d7eSDavid Wu bsp_priv->phy_reset = NULL;
1844fecd4d7eSDavid Wu }
1845fecd4d7eSDavid Wu }
1846fecd4d7eSDavid Wu }
1847fecd4d7eSDavid Wu dev_info(dev, "integrated PHY? (%s).\n",
1848fecd4d7eSDavid Wu bsp_priv->integrated_phy ? "yes" : "no");
1849fecd4d7eSDavid Wu
1850fecd4d7eSDavid Wu bsp_priv->pdev = pdev;
185145383f52SRoger Chen
185245383f52SRoger Chen return bsp_priv;
185345383f52SRoger Chen }
185445383f52SRoger Chen
rk_gmac_check_ops(struct rk_priv_data * bsp_priv)185537c80d15SDavid Wu static int rk_gmac_check_ops(struct rk_priv_data *bsp_priv)
185637c80d15SDavid Wu {
185737c80d15SDavid Wu switch (bsp_priv->phy_iface) {
185837c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII:
185937c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_ID:
186037c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_RXID:
186137c80d15SDavid Wu case PHY_INTERFACE_MODE_RGMII_TXID:
186237c80d15SDavid Wu if (!bsp_priv->ops->set_to_rgmii)
186337c80d15SDavid Wu return -EINVAL;
186437c80d15SDavid Wu break;
186537c80d15SDavid Wu case PHY_INTERFACE_MODE_RMII:
186637c80d15SDavid Wu if (!bsp_priv->ops->set_to_rmii)
186737c80d15SDavid Wu return -EINVAL;
186837c80d15SDavid Wu break;
186937c80d15SDavid Wu default:
187037c80d15SDavid Wu dev_err(&bsp_priv->pdev->dev,
187137c80d15SDavid Wu "unsupported interface %d", bsp_priv->phy_iface);
187237c80d15SDavid Wu }
187337c80d15SDavid Wu return 0;
187437c80d15SDavid Wu }
187537c80d15SDavid Wu
rk_gmac_powerup(struct rk_priv_data * bsp_priv)187645383f52SRoger Chen static int rk_gmac_powerup(struct rk_priv_data *bsp_priv)
187745383f52SRoger Chen {
187845383f52SRoger Chen int ret;
187945383f52SRoger Chen struct device *dev = &bsp_priv->pdev->dev;
188045383f52SRoger Chen
188137c80d15SDavid Wu ret = rk_gmac_check_ops(bsp_priv);
188237c80d15SDavid Wu if (ret)
188337c80d15SDavid Wu return ret;
188437c80d15SDavid Wu
1885f217bfdeSHeiko Stübner ret = gmac_clk_enable(bsp_priv, true);
1886f217bfdeSHeiko Stübner if (ret)
1887f217bfdeSHeiko Stübner return ret;
1888f217bfdeSHeiko Stübner
18897ad269eaSRoger Chen /*rmii or rgmii*/
1890eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) {
1891eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII:
1892d42202dcSRomain Perier dev_info(dev, "init for RGMII\n");
18930fb98db1SHeiko Stübner bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay,
18940fb98db1SHeiko Stübner bsp_priv->rx_delay);
1895eaf70ad1SWadim Egorov break;
1896eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID:
1897eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_ID\n");
1898eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
1899eaf70ad1SWadim Egorov break;
1900eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID:
1901eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_RXID\n");
1902eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
1903eaf70ad1SWadim Egorov break;
1904eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID:
1905eaf70ad1SWadim Egorov dev_info(dev, "init for RGMII_TXID\n");
1906eaf70ad1SWadim Egorov bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
1907eaf70ad1SWadim Egorov break;
1908eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII:
1909d42202dcSRomain Perier dev_info(dev, "init for RMII\n");
19100fb98db1SHeiko Stübner bsp_priv->ops->set_to_rmii(bsp_priv);
1911eaf70ad1SWadim Egorov break;
1912eaf70ad1SWadim Egorov default:
1913d42202dcSRomain Perier dev_err(dev, "NO interface defined!\n");
19147ad269eaSRoger Chen }
19157ad269eaSRoger Chen
19167ad269eaSRoger Chen ret = phy_power_on(bsp_priv, true);
1917c69c29a1SAlexey Khoroshilov if (ret) {
1918c69c29a1SAlexey Khoroshilov gmac_clk_enable(bsp_priv, false);
19197ad269eaSRoger Chen return ret;
1920c69c29a1SAlexey Khoroshilov }
19217ad269eaSRoger Chen
1922aec3f415SPunit Agrawal pm_runtime_get_sync(dev);
1923aec3f415SPunit Agrawal
1924fecd4d7eSDavid Wu if (bsp_priv->integrated_phy)
1925fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerup(bsp_priv);
1926fecd4d7eSDavid Wu
19277ad269eaSRoger Chen return 0;
19287ad269eaSRoger Chen }
19297ad269eaSRoger Chen
rk_gmac_powerdown(struct rk_priv_data * gmac)1930229666c1SVincent Palatin static void rk_gmac_powerdown(struct rk_priv_data *gmac)
19317ad269eaSRoger Chen {
1932fecd4d7eSDavid Wu if (gmac->integrated_phy)
1933fecd4d7eSDavid Wu rk_gmac_integrated_phy_powerdown(gmac);
1934fecd4d7eSDavid Wu
1935aec3f415SPunit Agrawal pm_runtime_put_sync(&gmac->pdev->dev);
1936aec3f415SPunit Agrawal
19377ad269eaSRoger Chen phy_power_on(gmac, false);
19387ad269eaSRoger Chen gmac_clk_enable(gmac, false);
19397ad269eaSRoger Chen }
19407ad269eaSRoger Chen
rk_fix_speed(void * priv,unsigned int speed,unsigned int mode)19411fc04a0bSShenwei Wang static void rk_fix_speed(void *priv, unsigned int speed, unsigned int mode)
19427ad269eaSRoger Chen {
19437ad269eaSRoger Chen struct rk_priv_data *bsp_priv = priv;
19447ad269eaSRoger Chen struct device *dev = &bsp_priv->pdev->dev;
19457ad269eaSRoger Chen
1946eaf70ad1SWadim Egorov switch (bsp_priv->phy_iface) {
1947eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII:
1948eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_ID:
1949eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_RXID:
1950eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RGMII_TXID:
195137c80d15SDavid Wu if (bsp_priv->ops->set_rgmii_speed)
19520fb98db1SHeiko Stübner bsp_priv->ops->set_rgmii_speed(bsp_priv, speed);
1953eaf70ad1SWadim Egorov break;
1954eaf70ad1SWadim Egorov case PHY_INTERFACE_MODE_RMII:
195537c80d15SDavid Wu if (bsp_priv->ops->set_rmii_speed)
19560fb98db1SHeiko Stübner bsp_priv->ops->set_rmii_speed(bsp_priv, speed);
1957eaf70ad1SWadim Egorov break;
1958eaf70ad1SWadim Egorov default:
19597ad269eaSRoger Chen dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
19607ad269eaSRoger Chen }
1961eaf70ad1SWadim Egorov }
19627ad269eaSRoger Chen
rk_gmac_probe(struct platform_device * pdev)196327ffefd2SJoachim Eastwood static int rk_gmac_probe(struct platform_device *pdev)
196427ffefd2SJoachim Eastwood {
196527ffefd2SJoachim Eastwood struct plat_stmmacenet_data *plat_dat;
196627ffefd2SJoachim Eastwood struct stmmac_resources stmmac_res;
1967f529f182SJoachim Eastwood const struct rk_gmac_ops *data;
196827ffefd2SJoachim Eastwood int ret;
196927ffefd2SJoachim Eastwood
1970149adeddSJoachim Eastwood data = of_device_get_match_data(&pdev->dev);
1971149adeddSJoachim Eastwood if (!data) {
1972149adeddSJoachim Eastwood dev_err(&pdev->dev, "no of match data provided\n");
1973149adeddSJoachim Eastwood return -EINVAL;
1974149adeddSJoachim Eastwood }
1975149adeddSJoachim Eastwood
197627ffefd2SJoachim Eastwood ret = stmmac_get_platform_resources(pdev, &stmmac_res);
197727ffefd2SJoachim Eastwood if (ret)
197827ffefd2SJoachim Eastwood return ret;
197927ffefd2SJoachim Eastwood
19808eee20e1SJisheng Zhang plat_dat = devm_stmmac_probe_config_dt(pdev, stmmac_res.mac);
198127ffefd2SJoachim Eastwood if (IS_ERR(plat_dat))
198227ffefd2SJoachim Eastwood return PTR_ERR(plat_dat);
198327ffefd2SJoachim Eastwood
1984d6b06251SEzequiel Garcia /* If the stmmac is not already selected as gmac4,
1985d6b06251SEzequiel Garcia * then make sure we fallback to gmac.
1986d6b06251SEzequiel Garcia */
1987d6b06251SEzequiel Garcia if (!plat_dat->has_gmac4)
198827ffefd2SJoachim Eastwood plat_dat->has_gmac = true;
198927ffefd2SJoachim Eastwood plat_dat->fix_mac_speed = rk_fix_speed;
199027ffefd2SJoachim Eastwood
1991fecd4d7eSDavid Wu plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
19928eee20e1SJisheng Zhang if (IS_ERR(plat_dat->bsp_priv))
19938eee20e1SJisheng Zhang return PTR_ERR(plat_dat->bsp_priv);
199427ffefd2SJoachim Eastwood
1995fecd4d7eSDavid Wu ret = rk_gmac_clk_init(plat_dat);
1996fecd4d7eSDavid Wu if (ret)
19978eee20e1SJisheng Zhang return ret;
1998fecd4d7eSDavid Wu
199907a5e769SJoachim Eastwood ret = rk_gmac_powerup(plat_dat->bsp_priv);
200027ffefd2SJoachim Eastwood if (ret)
20018eee20e1SJisheng Zhang return ret;
200227ffefd2SJoachim Eastwood
20032d222656SJohan Hovold ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
20042d222656SJohan Hovold if (ret)
20052745529aSDavid S. Miller goto err_gmac_powerdown;
20062d222656SJohan Hovold
20072d222656SJohan Hovold return 0;
20082d222656SJohan Hovold
20092745529aSDavid S. Miller err_gmac_powerdown:
20102745529aSDavid S. Miller rk_gmac_powerdown(plat_dat->bsp_priv);
20112d222656SJohan Hovold
20122d222656SJohan Hovold return ret;
201327ffefd2SJoachim Eastwood }
201427ffefd2SJoachim Eastwood
rk_gmac_remove(struct platform_device * pdev)2015903cc461SUwe Kleine-König static void rk_gmac_remove(struct platform_device *pdev)
20160de8c4c9SJoachim Eastwood {
20170de8c4c9SJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
2018ff0011cfSUwe Kleine-König
2019ff0011cfSUwe Kleine-König stmmac_dvr_remove(&pdev->dev);
20200de8c4c9SJoachim Eastwood
20210de8c4c9SJoachim Eastwood rk_gmac_powerdown(bsp_priv);
20220de8c4c9SJoachim Eastwood }
20230de8c4c9SJoachim Eastwood
20245619468aSJoachim Eastwood #ifdef CONFIG_PM_SLEEP
rk_gmac_suspend(struct device * dev)20255619468aSJoachim Eastwood static int rk_gmac_suspend(struct device *dev)
20265619468aSJoachim Eastwood {
20275619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
20285619468aSJoachim Eastwood int ret = stmmac_suspend(dev);
20295619468aSJoachim Eastwood
20305619468aSJoachim Eastwood /* Keep the PHY up if we use Wake-on-Lan. */
20315619468aSJoachim Eastwood if (!device_may_wakeup(dev)) {
20325619468aSJoachim Eastwood rk_gmac_powerdown(bsp_priv);
20335619468aSJoachim Eastwood bsp_priv->suspended = true;
20345619468aSJoachim Eastwood }
20355619468aSJoachim Eastwood
20365619468aSJoachim Eastwood return ret;
20375619468aSJoachim Eastwood }
20385619468aSJoachim Eastwood
rk_gmac_resume(struct device * dev)20395619468aSJoachim Eastwood static int rk_gmac_resume(struct device *dev)
20405619468aSJoachim Eastwood {
20415619468aSJoachim Eastwood struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
20425619468aSJoachim Eastwood
20435619468aSJoachim Eastwood /* The PHY was up for Wake-on-Lan. */
20445619468aSJoachim Eastwood if (bsp_priv->suspended) {
20455619468aSJoachim Eastwood rk_gmac_powerup(bsp_priv);
20465619468aSJoachim Eastwood bsp_priv->suspended = false;
20475619468aSJoachim Eastwood }
20485619468aSJoachim Eastwood
20495619468aSJoachim Eastwood return stmmac_resume(dev);
20505619468aSJoachim Eastwood }
20515619468aSJoachim Eastwood #endif /* CONFIG_PM_SLEEP */
20525619468aSJoachim Eastwood
20535619468aSJoachim Eastwood static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
20545619468aSJoachim Eastwood
2055e0fb4013SJoachim Eastwood static const struct of_device_id rk_gmac_dwmac_match[] = {
205623c94d63SDavid Wu { .compatible = "rockchip,px30-gmac", .data = &px30_ops },
205705946876SDavid Wu { .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
2058e7ffd812SXing Zheng { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
2059f529f182SJoachim Eastwood { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
2060b4ac9456STobias Schramm { .compatible = "rockchip,rk3308-gmac", .data = &rk3308_ops },
2061d4ff816eSdavid.wu { .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
2062ba289af8SRoger Chen { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
2063f529f182SJoachim Eastwood { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
2064ba289af8SRoger Chen { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
20653bb3d6b1SDavid Wu { .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
2066*f9cc9997SDavid Wu { .compatible = "rockchip,rk3576-gmac", .data = &rk3576_ops },
20672f2b60a0SDavid Wu { .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops },
206889c9c163SDavid Wu { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
2069c931b060SAnand Moon { .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops },
2070e0fb4013SJoachim Eastwood { }
2071e0fb4013SJoachim Eastwood };
2072e0fb4013SJoachim Eastwood MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
2073e0fb4013SJoachim Eastwood
2074e0fb4013SJoachim Eastwood static struct platform_driver rk_gmac_dwmac_driver = {
207527ffefd2SJoachim Eastwood .probe = rk_gmac_probe,
2076903cc461SUwe Kleine-König .remove_new = rk_gmac_remove,
2077e0fb4013SJoachim Eastwood .driver = {
2078e0fb4013SJoachim Eastwood .name = "rk_gmac-dwmac",
20795619468aSJoachim Eastwood .pm = &rk_gmac_pm_ops,
2080e0fb4013SJoachim Eastwood .of_match_table = rk_gmac_dwmac_match,
2081e0fb4013SJoachim Eastwood },
2082e0fb4013SJoachim Eastwood };
2083e0fb4013SJoachim Eastwood module_platform_driver(rk_gmac_dwmac_driver);
2084e0fb4013SJoachim Eastwood
2085e0fb4013SJoachim Eastwood MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
2086e0fb4013SJoachim Eastwood MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
2087e0fb4013SJoachim Eastwood MODULE_LICENSE("GPL");
2088