From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c | 1031 +++++++++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 857 insertions(+), 174 deletions(-)
diff --git a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index c6b6cae..8e1b354 100644
--- a/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/kernel/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -1,19 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/**
- * dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
+ * DOC: dwmac-rk.c - Rockchip RK3288 DWMAC specific glue layer
*
* Copyright (C) 2014 Chen-Zhi (Roger Chen)
*
* Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
#include <linux/stmmac.h>
@@ -24,6 +15,7 @@
#include <linux/of_net.h>
#include <linux/gpio.h>
#include <linux/module.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -47,12 +39,14 @@
void (*set_to_qsgmii)(struct rk_priv_data *bsp_priv);
void (*set_rgmii_speed)(struct rk_priv_data *bsp_priv, int speed);
void (*set_rmii_speed)(struct rk_priv_data *bsp_priv, int speed);
- void (*integrated_phy_powerup)(struct rk_priv_data *bsp_priv);
+ void (*set_clock_selection)(struct rk_priv_data *bsp_priv, bool input,
+ bool enable);
+ void (*integrated_phy_power)(struct rk_priv_data *bsp_priv, bool up);
};
struct rk_priv_data {
struct platform_device *pdev;
- int phy_iface;
+ phy_interface_t phy_iface;
int bus_id;
struct regulator *regulator;
bool suspended;
@@ -73,6 +67,7 @@
struct clk *pclk_mac;
struct clk *clk_phy;
struct clk *pclk_xpcs;
+ struct clk *clk_xpcs_eee;
struct reset_control *phy_reset;
@@ -80,7 +75,11 @@
int rx_delay;
struct regmap *grf;
+ struct regmap *php_grf;
struct regmap *xpcs;
+
+ unsigned char otp_data;
+ unsigned int bgs_increment;
};
/* XPCS */
@@ -212,8 +211,119 @@
#define GRF_CLR_BIT(nr) (BIT(nr+16))
#define DELAY_ENABLE(soc, tx, rx) \
- (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
- ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
+ ((((tx) >= 0) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \
+ (((rx) >= 0) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE))
+
+#define DELAY_ENABLE_BY_ID(soc, tx, rx, id) \
+ ((((tx) >= 0) ? soc##_GMAC_TXCLK_DLY_ENABLE(id) : soc##_GMAC_TXCLK_DLY_DISABLE(id)) | \
+ (((rx) >= 0) ? soc##_GMAC_RXCLK_DLY_ENABLE(id) : soc##_GMAC_RXCLK_DLY_DISABLE(id)))
+
+#define DELAY_VALUE(soc, tx, rx) \
+ ((((tx) >= 0) ? soc##_GMAC_CLK_TX_DL_CFG(tx) : 0) | \
+ (((rx) >= 0) ? soc##_GMAC_CLK_RX_DL_CFG(rx) : 0))
+
+#define GMAC_RGMII_CLK_DIV_BY_ID(soc, id, div) \
+ (soc##_GMAC##id##_CLK_RGMII_DIV##div)
+
+#define GMAC_RMII_CLK_DIV_BY_ID(soc, id, div) \
+ (soc##_GMAC##id##_CLK_RMII_DIV##div)
+
+/* Integrated EPHY */
+
+#define RK_GRF_MACPHY_CON0 0xb00
+#define RK_GRF_MACPHY_CON1 0xb04
+#define RK_GRF_MACPHY_CON2 0xb08
+#define RK_GRF_MACPHY_CON3 0xb0c
+
+#define RK_MACPHY_ENABLE GRF_BIT(0)
+#define RK_MACPHY_DISABLE GRF_CLR_BIT(0)
+#define RK_MACPHY_CFG_CLK_50M GRF_BIT(14)
+#define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7))
+#define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0)
+#define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0)
+
+static void rk_gmac_integrated_ephy_powerup(struct rk_priv_data *priv)
+{
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
+
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
+
+ if (priv->phy_reset) {
+ /* PHY needs to be disabled before trying to reset it */
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+ if (priv->phy_reset)
+ reset_control_assert(priv->phy_reset);
+ usleep_range(10, 20);
+ if (priv->phy_reset)
+ reset_control_deassert(priv->phy_reset);
+ usleep_range(10, 20);
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
+ msleep(30);
+ }
+}
+
+static void rk_gmac_integrated_ephy_powerdown(struct rk_priv_data *priv)
+{
+ regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
+ if (priv->phy_reset)
+ reset_control_assert(priv->phy_reset);
+}
+
+/* Integrated FEPHY */
+#define RK_FEPHY_SHUTDOWN GRF_BIT(1)
+#define RK_FEPHY_POWERUP GRF_CLR_BIT(1)
+#define RK_FEPHY_INTERNAL_RMII_SEL GRF_BIT(6)
+#define RK_FEPHY_24M_CLK_SEL (GRF_BIT(8) | GRF_BIT(9))
+#define RK_FEPHY_PHY_ID GRF_BIT(11)
+
+#define RK_FEPHY_BGS HIWORD_UPDATE(0x0, 0xf, 0)
+
+#define RK_FEPHY_BGS_MAX 7
+
+static void rk_gmac_integrated_fephy_power(struct rk_priv_data *priv,
+ unsigned int ctrl_offset,
+ unsigned int bgs_offset,
+ bool up)
+{
+ struct device *dev = &priv->pdev->dev;
+
+ if (IS_ERR(priv->grf) || !priv->phy_reset) {
+ dev_err(dev, "%s: Missing rockchip,grf or phy_reset property\n",
+ __func__);
+ return;
+ }
+
+ if (up) {
+ unsigned int bgs = priv->otp_data;
+
+ reset_control_assert(priv->phy_reset);
+ udelay(20);
+ regmap_write(priv->grf, ctrl_offset,
+ RK_FEPHY_POWERUP |
+ RK_FEPHY_INTERNAL_RMII_SEL |
+ RK_FEPHY_24M_CLK_SEL |
+ RK_FEPHY_PHY_ID);
+
+ if (bgs > (RK_FEPHY_BGS_MAX - priv->bgs_increment) &&
+ bgs <= RK_FEPHY_BGS_MAX) {
+ bgs = HIWORD_UPDATE(RK_FEPHY_BGS_MAX, 0xf, 0);
+ } else {
+ bgs += priv->bgs_increment;
+ bgs &= 0xf;
+ bgs = HIWORD_UPDATE(bgs, 0xf, 0);
+ }
+
+ regmap_write(priv->grf, bgs_offset, bgs);
+ usleep_range(10 * 1000, 12 * 1000);
+ reset_control_deassert(priv->phy_reset);
+ usleep_range(50 * 1000, 60 * 1000);
+ } else {
+ regmap_write(priv->grf, ctrl_offset,
+ RK_FEPHY_SHUTDOWN);
+ }
+}
#define PX30_GRF_GMAC_CON1 0x0904
@@ -306,12 +416,10 @@
regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON1,
RK1808_GMAC_PHY_INTF_SEL_RGMII |
- RK1808_GMAC_RXCLK_DLY_ENABLE |
- RK1808_GMAC_TXCLK_DLY_ENABLE);
+ DELAY_ENABLE(RK1808, tx_delay, rx_delay));
regmap_write(bsp_priv->grf, RK1808_GRF_GMAC_CON0,
- RK1808_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK1808_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK1808, tx_delay, rx_delay));
}
static void rk1808_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -439,8 +547,7 @@
RK3128_GMAC_RMII_MODE_CLR);
regmap_write(bsp_priv->grf, RK3128_GRF_MAC_CON0,
DELAY_ENABLE(RK3128, tx_delay, rx_delay) |
- RK3128_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK3128_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK3128, tx_delay, rx_delay));
}
static void rk3128_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -556,8 +663,7 @@
DELAY_ENABLE(RK3228, tx_delay, rx_delay));
regmap_write(bsp_priv->grf, RK3228_GRF_MAC_CON0,
- RK3228_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK3228_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK3128, tx_delay, rx_delay));
}
static void rk3228_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -620,10 +726,16 @@
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
}
-static void rk3228_integrated_phy_powerup(struct rk_priv_data *priv)
+static void rk3228_integrated_phy_power(struct rk_priv_data *priv, bool up)
{
- regmap_write(priv->grf, RK3228_GRF_CON_MUX,
- RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
+ if (up) {
+ regmap_write(priv->grf, RK3228_GRF_CON_MUX,
+ RK3228_GRF_CON_MUX_GMAC_INTEGRATED_PHY);
+
+ rk_gmac_integrated_ephy_powerup(priv);
+ } else {
+ rk_gmac_integrated_ephy_powerdown(priv);
+ }
}
static const struct rk_gmac_ops rk3228_ops = {
@@ -631,7 +743,7 @@
.set_to_rmii = rk3228_set_to_rmii,
.set_rgmii_speed = rk3228_set_rgmii_speed,
.set_rmii_speed = rk3228_set_rmii_speed,
- .integrated_phy_powerup = rk3228_integrated_phy_powerup,
+ .integrated_phy_power = rk3228_integrated_phy_power,
};
#define RK3288_GRF_SOC_CON1 0x0248
@@ -677,8 +789,7 @@
RK3288_GMAC_RMII_MODE_CLR);
regmap_write(bsp_priv->grf, RK3288_GRF_SOC_CON3,
DELAY_ENABLE(RK3288, tx_delay, rx_delay) |
- RK3288_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK3288_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK3288, tx_delay, rx_delay));
}
static void rk3288_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -849,12 +960,10 @@
regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON1,
RK3328_GMAC_PHY_INTF_SEL_RGMII |
RK3328_GMAC_RMII_MODE_CLR |
- RK3328_GMAC_RXCLK_DLY_ENABLE |
- RK3328_GMAC_TXCLK_DLY_ENABLE);
+ DELAY_ENABLE(RK3328, tx_delay, rx_delay));
regmap_write(bsp_priv->grf, RK3328_GRF_MAC_CON0,
- RK3328_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK3328_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK3328, tx_delay, rx_delay));
}
static void rk3328_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -922,10 +1031,16 @@
dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
}
-static void rk3328_integrated_phy_powerup(struct rk_priv_data *priv)
+static void rk3328_integrated_phy_power(struct rk_priv_data *priv, bool up)
{
- regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
- RK3328_MACPHY_RMII_MODE);
+ if (up) {
+ regmap_write(priv->grf, RK3328_GRF_MACPHY_CON1,
+ RK3328_MACPHY_RMII_MODE);
+
+ rk_gmac_integrated_ephy_powerup(priv);
+ } else {
+ rk_gmac_integrated_ephy_powerdown(priv);
+ }
}
static const struct rk_gmac_ops rk3328_ops = {
@@ -933,7 +1048,7 @@
.set_to_rmii = rk3328_set_to_rmii,
.set_rgmii_speed = rk3328_set_rgmii_speed,
.set_rmii_speed = rk3328_set_rmii_speed,
- .integrated_phy_powerup = rk3328_integrated_phy_powerup,
+ .integrated_phy_power = rk3328_integrated_phy_power,
};
#define RK3366_GRF_SOC_CON6 0x0418
@@ -979,8 +1094,7 @@
RK3366_GMAC_RMII_MODE_CLR);
regmap_write(bsp_priv->grf, RK3366_GRF_SOC_CON7,
DELAY_ENABLE(RK3366, tx_delay, rx_delay) |
- RK3366_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK3366_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK3366, tx_delay, rx_delay));
}
static void rk3366_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -1090,8 +1204,7 @@
RK3368_GMAC_RMII_MODE_CLR);
regmap_write(bsp_priv->grf, RK3368_GRF_SOC_CON16,
DELAY_ENABLE(RK3368, tx_delay, rx_delay) |
- RK3368_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK3368_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK3368, tx_delay, rx_delay));
}
static void rk3368_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -1201,8 +1314,7 @@
RK3399_GMAC_RMII_MODE_CLR);
regmap_write(bsp_priv->grf, RK3399_GRF_SOC_CON6,
DELAY_ENABLE(RK3399, tx_delay, rx_delay) |
- RK3399_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK3399_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK3399, tx_delay, rx_delay));
}
static void rk3399_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -1267,6 +1379,361 @@
.set_to_rmii = rk3399_set_to_rmii,
.set_rgmii_speed = rk3399_set_rgmii_speed,
.set_rmii_speed = rk3399_set_rmii_speed,
+};
+
+#define RK3528_VO_GRF_GMAC_CON 0X60018
+#define RK3528_VPU_GRF_GMAC_CON5 0X40018
+#define RK3528_VPU_GRF_GMAC_CON6 0X4001c
+
+#define RK3528_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15)
+#define RK3528_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15)
+#define RK3528_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14)
+#define RK3528_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14)
+
+#define RK3528_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8)
+#define RK3528_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0)
+
+#define RK3528_GMAC0_PHY_INTF_SEL_RMII GRF_BIT(1)
+#define RK3528_GMAC1_PHY_INTF_SEL_RGMII GRF_CLR_BIT(8)
+#define RK3528_GMAC1_PHY_INTF_SEL_RMII GRF_BIT(8)
+
+#define RK3528_GMAC1_CLK_SELET_CRU GRF_CLR_BIT(12)
+#define RK3528_GMAC1_CLK_SELET_IO GRF_BIT(12)
+
+#define RK3528_GMAC0_CLK_RMII_DIV2 GRF_BIT(3)
+#define RK3528_GMAC0_CLK_RMII_DIV20 GRF_CLR_BIT(3)
+#define RK3528_GMAC1_CLK_RMII_DIV2 GRF_BIT(10)
+#define RK3528_GMAC1_CLK_RMII_DIV20 GRF_CLR_BIT(10)
+
+#define RK3528_GMAC1_CLK_RGMII_DIV1 \
+ (GRF_CLR_BIT(11) | GRF_CLR_BIT(10))
+#define RK3528_GMAC1_CLK_RGMII_DIV5 \
+ (GRF_BIT(11) | GRF_BIT(10))
+#define RK3528_GMAC1_CLK_RGMII_DIV50 \
+ (GRF_BIT(11) | GRF_CLR_BIT(10))
+
+#define RK3528_GMAC0_CLK_RMII_GATE GRF_BIT(2)
+#define RK3528_GMAC0_CLK_RMII_NOGATE GRF_CLR_BIT(2)
+#define RK3528_GMAC1_CLK_RMII_GATE GRF_BIT(9)
+#define RK3528_GMAC1_CLK_RMII_NOGATE GRF_CLR_BIT(9)
+
+#define RK3528_VO_GRF_MACPHY_CON0 0X6001c
+#define RK3528_VO_GRF_MACPHY_CON1 0X60020
+
+static void rk3528_set_to_rgmii(struct rk_priv_data *bsp_priv,
+ int tx_delay, int rx_delay)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "Missing rockchip,grf property\n");
+ return;
+ }
+
+ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5,
+ RK3528_GMAC1_PHY_INTF_SEL_RGMII);
+
+ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5,
+ DELAY_ENABLE(RK3528, tx_delay, rx_delay));
+
+ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON6,
+ DELAY_VALUE(RK3528, tx_delay, rx_delay));
+}
+
+static void rk3528_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int id = bsp_priv->bus_id;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+ return;
+ }
+
+ if (id == 1)
+ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5,
+ RK3528_GMAC1_PHY_INTF_SEL_RMII);
+ else
+ regmap_write(bsp_priv->grf, RK3528_VO_GRF_GMAC_CON,
+ RK3528_GMAC0_PHY_INTF_SEL_RMII |
+ RK3528_GMAC0_CLK_RMII_DIV2);
+}
+
+static void rk3528_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int val = 0;
+
+ switch (speed) {
+ case 10:
+ val = RK3528_GMAC1_CLK_RGMII_DIV50;
+ break;
+ case 100:
+ val = RK3528_GMAC1_CLK_RGMII_DIV5;
+ break;
+ case 1000:
+ val = RK3528_GMAC1_CLK_RGMII_DIV1;
+ break;
+ default:
+ goto err;
+ }
+
+ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, val);
+ return;
+err:
+ dev_err(dev, "unknown RGMII speed value for GMAC speed=%d", speed);
+}
+
+static void rk3528_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int val, offset, id = bsp_priv->bus_id;
+
+ switch (speed) {
+ case 10:
+ val = (id == 1) ? RK3528_GMAC1_CLK_RMII_DIV20 :
+ RK3528_GMAC0_CLK_RMII_DIV20;
+ break;
+ case 100:
+ val = (id == 1) ? RK3528_GMAC1_CLK_RMII_DIV2 :
+ RK3528_GMAC0_CLK_RMII_DIV2;
+ break;
+ default:
+ goto err;
+ }
+
+ offset = (id == 1) ? RK3528_VPU_GRF_GMAC_CON5 : RK3528_VO_GRF_GMAC_CON;
+ regmap_write(bsp_priv->grf, offset, val);
+
+ return;
+err:
+ dev_err(dev, "unknown RMII speed value for GMAC speed=%d", speed);
+}
+
+static void rk3528_set_clock_selection(struct rk_priv_data *bsp_priv,
+ bool input, bool enable)
+{
+ unsigned int value, id = bsp_priv->bus_id;
+
+ if (id == 1) {
+ value = input ? RK3528_GMAC1_CLK_SELET_IO :
+ RK3528_GMAC1_CLK_SELET_CRU;
+ value |= enable ? RK3528_GMAC1_CLK_RMII_NOGATE :
+ RK3528_GMAC1_CLK_RMII_GATE;
+ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, value);
+ } else {
+ value = enable ? RK3528_GMAC0_CLK_RMII_NOGATE :
+ RK3528_GMAC0_CLK_RMII_GATE;
+ regmap_write(bsp_priv->grf, RK3528_VO_GRF_GMAC_CON, value);
+ }
+}
+
+static void rk3528_integrated_sphy_power(struct rk_priv_data *priv, bool up)
+{
+ rk_gmac_integrated_fephy_power(priv, RK3528_VO_GRF_MACPHY_CON0,
+ RK3528_VO_GRF_MACPHY_CON1, up);
+}
+
+static const struct rk_gmac_ops rk3528_ops = {
+ .set_to_rgmii = rk3528_set_to_rgmii,
+ .set_to_rmii = rk3528_set_to_rmii,
+ .set_rgmii_speed = rk3528_set_rgmii_speed,
+ .set_rmii_speed = rk3528_set_rmii_speed,
+ .set_clock_selection = rk3528_set_clock_selection,
+ .integrated_phy_power = rk3528_integrated_sphy_power,
+};
+
+/* sys_grf */
+#define RK3562_GRF_SYS_SOC_CON0 0X0400
+#define RK3562_GRF_SYS_SOC_CON1 0X0404
+
+#define RK3562_GMAC0_CLK_RMII_MODE GRF_BIT(5)
+#define RK3562_GMAC0_CLK_RGMII_MODE GRF_CLR_BIT(5)
+
+#define RK3562_GMAC0_CLK_RMII_GATE GRF_BIT(6)
+#define RK3562_GMAC0_CLK_RMII_NOGATE GRF_CLR_BIT(6)
+
+#define RK3562_GMAC0_CLK_RMII_DIV2 GRF_BIT(7)
+#define RK3562_GMAC0_CLK_RMII_DIV20 GRF_CLR_BIT(7)
+
+#define RK3562_GMAC0_CLK_RGMII_DIV1 \
+ (GRF_CLR_BIT(7) | GRF_CLR_BIT(8))
+#define RK3562_GMAC0_CLK_RGMII_DIV5 \
+ (GRF_BIT(7) | GRF_BIT(8))
+#define RK3562_GMAC0_CLK_RGMII_DIV50 \
+ (GRF_CLR_BIT(7) | GRF_BIT(8))
+
+#define RK3562_GMAC0_CLK_RMII_DIV2 GRF_BIT(7)
+#define RK3562_GMAC0_CLK_RMII_DIV20 GRF_CLR_BIT(7)
+
+#define RK3562_GMAC0_CLK_SELET_CRU GRF_CLR_BIT(9)
+#define RK3562_GMAC0_CLK_SELET_IO GRF_BIT(9)
+
+#define RK3562_GMAC1_CLK_RMII_GATE GRF_BIT(12)
+#define RK3562_GMAC1_CLK_RMII_NOGATE GRF_CLR_BIT(12)
+
+#define RK3562_GMAC1_CLK_RMII_DIV2 GRF_BIT(13)
+#define RK3562_GMAC1_CLK_RMII_DIV20 GRF_CLR_BIT(13)
+
+#define RK3562_GMAC1_RMII_SPEED100 GRF_BIT(11)
+#define RK3562_GMAC1_RMII_SPEED10 GRF_CLR_BIT(11)
+
+#define RK3562_GMAC1_CLK_SELET_CRU GRF_CLR_BIT(15)
+#define RK3562_GMAC1_CLK_SELET_IO GRF_BIT(15)
+
+/* ioc_grf */
+#define RK3562_GRF_IOC_GMAC_IOFUNC0_CON0 0X10400
+#define RK3562_GRF_IOC_GMAC_IOFUNC0_CON1 0X10404
+#define RK3562_GRF_IOC_GMAC_IOFUNC1_CON0 0X00400
+#define RK3562_GRF_IOC_GMAC_IOFUNC1_CON1 0X00404
+
+#define RK3562_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
+#define RK3562_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
+#define RK3562_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0)
+#define RK3562_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
+
+#define RK3562_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8)
+#define RK3562_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0)
+
+#define RK3562_GMAC0_IO_EXTCLK_SELET_CRU GRF_CLR_BIT(2)
+#define RK3562_GMAC0_IO_EXTCLK_SELET_IO GRF_BIT(2)
+
+#define RK3562_GMAC1_IO_EXTCLK_SELET_CRU GRF_CLR_BIT(3)
+#define RK3562_GMAC1_IO_EXTCLK_SELET_IO GRF_BIT(3)
+
+static void rk3562_set_to_rgmii(struct rk_priv_data *bsp_priv,
+ int tx_delay, int rx_delay)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
+ dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n");
+ return;
+ }
+
+ if (bsp_priv->bus_id > 0)
+ return;
+
+ regmap_write(bsp_priv->grf, RK3562_GRF_SYS_SOC_CON0,
+ RK3562_GMAC0_CLK_RGMII_MODE);
+
+ regmap_write(bsp_priv->php_grf, RK3562_GRF_IOC_GMAC_IOFUNC0_CON1,
+ DELAY_ENABLE(RK3562, tx_delay, rx_delay));
+ regmap_write(bsp_priv->php_grf, RK3562_GRF_IOC_GMAC_IOFUNC0_CON0,
+ DELAY_VALUE(RK3562, tx_delay, rx_delay));
+
+ regmap_write(bsp_priv->php_grf, RK3562_GRF_IOC_GMAC_IOFUNC1_CON1,
+ DELAY_ENABLE(RK3562, tx_delay, rx_delay));
+ regmap_write(bsp_priv->php_grf, RK3562_GRF_IOC_GMAC_IOFUNC1_CON0,
+ DELAY_VALUE(RK3562, tx_delay, rx_delay));
+}
+
+static void rk3562_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+ return;
+ }
+
+ if (!bsp_priv->bus_id)
+ regmap_write(bsp_priv->grf, RK3562_GRF_SYS_SOC_CON0,
+ RK3562_GMAC0_CLK_RMII_MODE);
+}
+
+static void rk3562_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int val = 0, offset, id = bsp_priv->bus_id;
+
+ switch (speed) {
+ case 10:
+ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
+ if (id > 0) {
+ val = GMAC_RMII_CLK_DIV_BY_ID(RK3562, 1, 20);
+ regmap_write(bsp_priv->grf, RK3562_GRF_SYS_SOC_CON0,
+ RK3562_GMAC1_RMII_SPEED10);
+ } else {
+ val = GMAC_RMII_CLK_DIV_BY_ID(RK3562, 0, 20);
+ }
+ } else {
+ val = GMAC_RGMII_CLK_DIV_BY_ID(RK3562, 0, 50);
+ }
+ break;
+ case 100:
+ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII) {
+ if (id > 0) {
+ val = GMAC_RMII_CLK_DIV_BY_ID(RK3562, 1, 2);
+ regmap_write(bsp_priv->grf, RK3562_GRF_SYS_SOC_CON0,
+ RK3562_GMAC1_RMII_SPEED100);
+ } else {
+ val = GMAC_RMII_CLK_DIV_BY_ID(RK3562, 0, 2);
+ }
+ } else {
+ val = GMAC_RGMII_CLK_DIV_BY_ID(RK3562, 0, 5);
+ }
+ break;
+ case 1000:
+ if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
+ val = GMAC_RGMII_CLK_DIV_BY_ID(RK3562, 0, 1);
+ else
+ goto err;
+ break;
+ default:
+ goto err;
+ }
+
+ offset = (bsp_priv->bus_id > 0) ? RK3562_GRF_SYS_SOC_CON1 :
+ RK3562_GRF_SYS_SOC_CON0;
+ regmap_write(bsp_priv->grf, offset, val);
+
+ return;
+err:
+ dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
+}
+
+static void rk3562_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
+ bool enable)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int value;
+
+ if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
+ dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n");
+ return;
+ }
+
+ if (!bsp_priv->bus_id) {
+ value = input ? RK3562_GMAC0_CLK_SELET_IO :
+ RK3562_GMAC0_CLK_SELET_CRU;
+ value |= enable ? RK3562_GMAC0_CLK_RMII_NOGATE :
+ RK3562_GMAC0_CLK_RMII_GATE;
+ regmap_write(bsp_priv->grf, RK3562_GRF_SYS_SOC_CON0, value);
+
+ value = input ? RK3562_GMAC0_IO_EXTCLK_SELET_IO :
+ RK3562_GMAC0_IO_EXTCLK_SELET_CRU;
+ regmap_write(bsp_priv->php_grf, RK3562_GRF_IOC_GMAC_IOFUNC0_CON1, value);
+ regmap_write(bsp_priv->php_grf, RK3562_GRF_IOC_GMAC_IOFUNC1_CON1, value);
+ } else {
+ value = input ? RK3562_GMAC1_CLK_SELET_IO :
+ RK3562_GMAC1_CLK_SELET_CRU;
+ value |= enable ? RK3562_GMAC1_CLK_RMII_NOGATE :
+ RK3562_GMAC1_CLK_RMII_GATE;
+ regmap_write(bsp_priv->grf, RK3562_GRF_SYS_SOC_CON1, value);
+
+ value = input ? RK3562_GMAC1_IO_EXTCLK_SELET_IO :
+ RK3562_GMAC1_IO_EXTCLK_SELET_CRU;
+ regmap_write(bsp_priv->php_grf, RK3562_GRF_IOC_GMAC_IOFUNC1_CON1, value);
+ }
+}
+
+static const struct rk_gmac_ops rk3562_ops = {
+ .set_to_rgmii = rk3562_set_to_rgmii,
+ .set_to_rmii = rk3562_set_to_rmii,
+ .set_rgmii_speed = rk3562_set_gmac_speed,
+ .set_rmii_speed = rk3562_set_gmac_speed,
+ .set_clock_selection = rk3562_set_clock_selection,
};
#define RK3568_GRF_GMAC0_CON0 0X0380
@@ -1349,12 +1816,10 @@
regmap_write(bsp_priv->grf, offset_con1,
RK3568_GMAC_PHY_INTF_SEL_RGMII |
- RK3568_GMAC_RXCLK_DLY_ENABLE |
- RK3568_GMAC_TXCLK_DLY_ENABLE);
+ DELAY_ENABLE(RK3568, tx_delay, rx_delay));
regmap_write(bsp_priv->grf, offset_con0,
- RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
- RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RK3568, tx_delay, rx_delay));
}
static void rk3568_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -1407,6 +1872,202 @@
.set_to_qsgmii = rk3568_set_to_qsgmii,
.set_rgmii_speed = rk3568_set_gmac_speed,
.set_rmii_speed = rk3568_set_gmac_speed,
+};
+
+/* sys_grf */
+#define RK3588_GRF_GMAC_CON7 0X031c
+#define RK3588_GRF_GMAC_CON8 0X0320
+#define RK3588_GRF_GMAC_CON9 0X0324
+
+#define RK3588_GMAC_RXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 3)
+#define RK3588_GMAC_RXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 3)
+#define RK3588_GMAC_TXCLK_DLY_ENABLE(id) GRF_BIT(2 * (id) + 2)
+#define RK3588_GMAC_TXCLK_DLY_DISABLE(id) GRF_CLR_BIT(2 * (id) + 2)
+
+#define RK3588_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8)
+#define RK3588_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0)
+
+/* php_grf */
+#define RK3588_GRF_GMAC_CON0 0X0008
+#define RK3588_GRF_CLK_CON1 0X0070
+
+#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id) \
+ (GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
+#define RK3588_GMAC_PHY_INTF_SEL_RMII(id) \
+ (GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
+
+#define RK3588_GMAC_CLK_RMII_MODE(id) GRF_BIT(5 * (id))
+#define RK3588_GMAC_CLK_RGMII_MODE(id) GRF_CLR_BIT(5 * (id))
+
+#define RK3588_GMAC_CLK_SELET_CRU(id) GRF_BIT(5 * (id) + 4)
+#define RK3588_GMAC_CLK_SELET_IO(id) GRF_CLR_BIT(5 * (id) + 4)
+
+#define RK3588_GMA_CLK_RMII_DIV2(id) GRF_BIT(5 * (id) + 2)
+#define RK3588_GMA_CLK_RMII_DIV20(id) GRF_CLR_BIT(5 * (id) + 2)
+
+#define RK3588_GMAC_CLK_RGMII_DIV1(id) \
+ (GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
+#define RK3588_GMAC_CLK_RGMII_DIV5(id) \
+ (GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
+#define RK3588_GMAC_CLK_RGMII_DIV50(id) \
+ (GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
+
+#define RK3588_GMAC_CLK_RMII_GATE(id) GRF_BIT(5 * (id) + 1)
+#define RK3588_GMAC_CLK_RMII_NOGATE(id) GRF_CLR_BIT(5 * (id) + 1)
+
+static void rk3588_set_to_rgmii(struct rk_priv_data *bsp_priv,
+ int tx_delay, int rx_delay)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+ u32 offset_con, id = bsp_priv->bus_id;
+
+ if (IS_ERR(bsp_priv->grf) || IS_ERR(bsp_priv->php_grf)) {
+ dev_err(dev, "Missing rockchip,grf or rockchip,php_grf property\n");
+ return;
+ }
+
+ offset_con = bsp_priv->bus_id == 1 ? RK3588_GRF_GMAC_CON9 :
+ RK3588_GRF_GMAC_CON8;
+
+ regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
+ RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
+
+ regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
+ RK3588_GMAC_CLK_RGMII_MODE(id));
+
+ regmap_write(bsp_priv->grf, RK3588_GRF_GMAC_CON7,
+ DELAY_ENABLE_BY_ID(RK3588, tx_delay, rx_delay, id));
+
+ regmap_write(bsp_priv->grf, offset_con,
+ DELAY_VALUE(RK3588, tx_delay, rx_delay));
+}
+
+static void rk3588_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->php_grf)) {
+ dev_err(dev, "%s: Missing rockchip,php_grf property\n", __func__);
+ return;
+ }
+
+ regmap_write(bsp_priv->php_grf, RK3588_GRF_GMAC_CON0,
+ RK3588_GMAC_PHY_INTF_SEL_RMII(bsp_priv->bus_id));
+
+ regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1,
+ RK3588_GMAC_CLK_RMII_MODE(bsp_priv->bus_id));
+}
+
+static void rk3588_set_gmac_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int val = 0, id = bsp_priv->bus_id;
+
+ switch (speed) {
+ case 10:
+ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
+ val = RK3588_GMA_CLK_RMII_DIV20(id);
+ else
+ val = RK3588_GMAC_CLK_RGMII_DIV50(id);
+ break;
+ case 100:
+ if (bsp_priv->phy_iface == PHY_INTERFACE_MODE_RMII)
+ val = RK3588_GMA_CLK_RMII_DIV2(id);
+ else
+ val = RK3588_GMAC_CLK_RGMII_DIV5(id);
+ break;
+ case 1000:
+ if (bsp_priv->phy_iface != PHY_INTERFACE_MODE_RMII)
+ val = RK3588_GMAC_CLK_RGMII_DIV1(id);
+ else
+ goto err;
+ break;
+ default:
+ goto err;
+ }
+
+ regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
+
+ return;
+err:
+ dev_err(dev, "unknown speed value for GMAC speed=%d", speed);
+}
+
+static void rk3588_set_clock_selection(struct rk_priv_data *bsp_priv, bool input,
+ bool enable)
+{
+ unsigned int val = input ? RK3588_GMAC_CLK_SELET_IO(bsp_priv->bus_id) :
+ RK3588_GMAC_CLK_SELET_CRU(bsp_priv->bus_id);
+
+ val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(bsp_priv->bus_id) :
+ RK3588_GMAC_CLK_RMII_GATE(bsp_priv->bus_id);
+
+ regmap_write(bsp_priv->php_grf, RK3588_GRF_CLK_CON1, val);
+}
+
+static const struct rk_gmac_ops rk3588_ops = {
+ .set_to_rgmii = rk3588_set_to_rgmii,
+ .set_to_rmii = rk3588_set_to_rmii,
+ .set_rgmii_speed = rk3588_set_gmac_speed,
+ .set_rmii_speed = rk3588_set_gmac_speed,
+ .set_clock_selection = rk3588_set_clock_selection,
+};
+
+#define RV1106_VOGRF_GMAC_CLK_CON 0X60004
+
+#define RV1106_VOGRF_MACPHY_RMII_MODE GRF_BIT(0)
+#define RV1106_VOGRF_GMAC_CLK_RMII_DIV2 GRF_BIT(2)
+#define RV1106_VOGRF_GMAC_CLK_RMII_DIV20 GRF_CLR_BIT(2)
+
+#define RV1106_VOGRF_MACPHY_CON0 0X60028
+#define RV1106_VOGRF_MACPHY_CON1 0X6002C
+
+static void rv1106_set_to_rmii(struct rk_priv_data *bsp_priv)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+ return;
+ }
+
+ regmap_write(bsp_priv->grf, RV1106_VOGRF_GMAC_CLK_CON,
+ RV1106_VOGRF_MACPHY_RMII_MODE |
+ RV1106_VOGRF_GMAC_CLK_RMII_DIV2);
+}
+
+static void rv1106_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed)
+{
+ struct device *dev = &bsp_priv->pdev->dev;
+ unsigned int val = 0;
+
+ if (IS_ERR(bsp_priv->grf)) {
+ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__);
+ return;
+ }
+
+ if (speed == 10) {
+ val = RV1106_VOGRF_GMAC_CLK_RMII_DIV20;
+ } else if (speed == 100) {
+ val = RV1106_VOGRF_GMAC_CLK_RMII_DIV2;
+ } else {
+ dev_err(dev, "unknown speed value for RMII! speed=%d", speed);
+ return;
+ }
+
+ regmap_write(bsp_priv->grf, RV1106_VOGRF_GMAC_CLK_CON, val);
+}
+
+static void rv1106_integrated_sphy_power(struct rk_priv_data *priv, bool up)
+{
+ rk_gmac_integrated_fephy_power(priv, RV1106_VOGRF_MACPHY_CON0,
+ RV1106_VOGRF_MACPHY_CON1, up);
+}
+
+static const struct rk_gmac_ops rv1106_ops = {
+ .set_to_rmii = rv1106_set_to_rmii,
+ .set_rmii_speed = rv1106_set_rmii_speed,
+ .integrated_phy_power = rv1106_integrated_sphy_power,
};
#define RV1108_GRF_GMAC_CON0 0X0900
@@ -1472,21 +2133,18 @@
(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
#define RV1126_GMAC_FLOW_CTRL GRF_BIT(7)
#define RV1126_GMAC_FLOW_CTRL_CLR GRF_CLR_BIT(7)
-#define RV1126_GMAC_M0_RXCLK_DLY_ENABLE GRF_BIT(1)
-#define RV1126_GMAC_M0_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
-#define RV1126_GMAC_M0_TXCLK_DLY_ENABLE GRF_BIT(0)
-#define RV1126_GMAC_M0_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
-#define RV1126_GMAC_M1_RXCLK_DLY_ENABLE GRF_BIT(3)
-#define RV1126_GMAC_M1_RXCLK_DLY_DISABLE GRF_CLR_BIT(3)
-#define RV1126_GMAC_M1_TXCLK_DLY_ENABLE GRF_BIT(2)
-#define RV1126_GMAC_M1_TXCLK_DLY_DISABLE GRF_CLR_BIT(2)
+#define RV1126_M0_GMAC_RXCLK_DLY_ENABLE GRF_BIT(1)
+#define RV1126_M0_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(1)
+#define RV1126_M0_GMAC_TXCLK_DLY_ENABLE GRF_BIT(0)
+#define RV1126_M0_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(0)
+#define RV1126_M1_GMAC_RXCLK_DLY_ENABLE GRF_BIT(3)
+#define RV1126_M1_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(3)
+#define RV1126_M1_GMAC_TXCLK_DLY_ENABLE GRF_BIT(2)
+#define RV1126_M1_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(2)
-/* RV1126_GRF_GMAC_CON1 */
-#define RV1126_GMAC_M0_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
-#define RV1126_GMAC_M0_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
-/* RV1126_GRF_GMAC_CON2 */
-#define RV1126_GMAC_M1_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
-#define RV1126_GMAC_M1_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
+/* RV1126_GRF_GMAC_CON1 && RV1126_GRF_GMAC_CON2 */
+#define RV1126_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
+#define RV1126_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
static void rv1126_set_to_rgmii(struct rk_priv_data *bsp_priv,
int tx_delay, int rx_delay)
@@ -1500,18 +2158,14 @@
regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON0,
RV1126_GMAC_PHY_INTF_SEL_RGMII |
- RV1126_GMAC_M0_RXCLK_DLY_ENABLE |
- RV1126_GMAC_M0_TXCLK_DLY_ENABLE |
- RV1126_GMAC_M1_RXCLK_DLY_ENABLE |
- RV1126_GMAC_M1_TXCLK_DLY_ENABLE);
+ DELAY_ENABLE(RV1126_M0, tx_delay, rx_delay) |
+ DELAY_ENABLE(RV1126_M1, tx_delay, rx_delay));
regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON1,
- RV1126_GMAC_M0_CLK_RX_DL_CFG(rx_delay) |
- RV1126_GMAC_M0_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RV1126, tx_delay, rx_delay));
regmap_write(bsp_priv->grf, RV1126_GRF_GMAC_CON2,
- RV1126_GMAC_M1_CLK_RX_DL_CFG(rx_delay) |
- RV1126_GMAC_M1_CLK_TX_DL_CFG(tx_delay));
+ DELAY_VALUE(RV1126, tx_delay, rx_delay));
}
static void rv1126_set_to_rmii(struct rk_priv_data *bsp_priv)
@@ -1585,50 +2239,6 @@
.set_rmii_speed = rv1126_set_rmii_speed,
};
-#define RK_GRF_MACPHY_CON0 0xb00
-#define RK_GRF_MACPHY_CON1 0xb04
-#define RK_GRF_MACPHY_CON2 0xb08
-#define RK_GRF_MACPHY_CON3 0xb0c
-
-#define RK_MACPHY_ENABLE GRF_BIT(0)
-#define RK_MACPHY_DISABLE GRF_CLR_BIT(0)
-#define RK_MACPHY_CFG_CLK_50M GRF_BIT(14)
-#define RK_GMAC2PHY_RMII_MODE (GRF_BIT(6) | GRF_CLR_BIT(7))
-#define RK_GRF_CON2_MACPHY_ID HIWORD_UPDATE(0x1234, 0xffff, 0)
-#define RK_GRF_CON3_MACPHY_ID HIWORD_UPDATE(0x35, 0x3f, 0)
-
-static void rk_gmac_integrated_phy_powerup(struct rk_priv_data *priv)
-{
- if (priv->ops->integrated_phy_powerup)
- priv->ops->integrated_phy_powerup(priv);
-
- regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_CFG_CLK_50M);
- regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_GMAC2PHY_RMII_MODE);
-
- regmap_write(priv->grf, RK_GRF_MACPHY_CON2, RK_GRF_CON2_MACPHY_ID);
- regmap_write(priv->grf, RK_GRF_MACPHY_CON3, RK_GRF_CON3_MACPHY_ID);
-
- if (priv->phy_reset) {
- /* PHY needs to be disabled before trying to reset it */
- regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
- if (priv->phy_reset)
- reset_control_assert(priv->phy_reset);
- usleep_range(10, 20);
- if (priv->phy_reset)
- reset_control_deassert(priv->phy_reset);
- usleep_range(10, 20);
- regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_ENABLE);
- msleep(30);
- }
-}
-
-static void rk_gmac_integrated_phy_powerdown(struct rk_priv_data *priv)
-{
- regmap_write(priv->grf, RK_GRF_MACPHY_CON0, RK_MACPHY_DISABLE);
- if (priv->phy_reset)
- reset_control_assert(priv->phy_reset);
-}
-
static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
{
struct rk_priv_data *bsp_priv = plat->bsp_priv;
@@ -1679,8 +2289,10 @@
bsp_priv->phy_iface == PHY_INTERFACE_MODE_QSGMII) {
bsp_priv->pclk_xpcs = devm_clk_get(dev, "pclk_xpcs");
if (IS_ERR(bsp_priv->pclk_xpcs))
- dev_err(dev, "cannot get clock %s\n",
- "pclk_xpcs");
+ dev_err(dev, "cannot get clock %s\n", "pclk_xpcs");
+ bsp_priv->clk_xpcs_eee = devm_clk_get(dev, "clk_xpcs_eee");
+ if (IS_ERR(bsp_priv->clk_xpcs_eee))
+ dev_err(dev, "cannot get clock %s\n", "clk_xpcs_eee");
}
bsp_priv->clk_mac_speed = devm_clk_get(dev, "clk_mac_speed");
@@ -1748,15 +2360,26 @@
if (!IS_ERR(bsp_priv->pclk_xpcs))
clk_prepare_enable(bsp_priv->pclk_xpcs);
+ if (!IS_ERR(bsp_priv->clk_xpcs_eee))
+ clk_prepare_enable(bsp_priv->clk_xpcs_eee);
+
+ if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
+ bsp_priv->ops->set_clock_selection(bsp_priv,
+ bsp_priv->clock_input, true);
+
/**
* if (!IS_ERR(bsp_priv->clk_mac))
* clk_prepare_enable(bsp_priv->clk_mac);
*/
- mdelay(5);
+ usleep_range(100, 200);
bsp_priv->clk_enabled = true;
}
} else {
if (bsp_priv->clk_enabled) {
+ if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
+ bsp_priv->ops->set_clock_selection(bsp_priv,
+ bsp_priv->clock_input, false);
+
if (phy_iface == PHY_INTERFACE_MODE_RMII) {
clk_disable_unprepare(bsp_priv->mac_clk_rx);
@@ -1776,6 +2399,8 @@
clk_disable_unprepare(bsp_priv->clk_mac_speed);
clk_disable_unprepare(bsp_priv->pclk_xpcs);
+
+ clk_disable_unprepare(bsp_priv->clk_xpcs_eee);
/**
* if (!IS_ERR(bsp_priv->clk_mac))
@@ -1824,7 +2449,7 @@
if (!bsp_priv)
return ERR_PTR(-ENOMEM);
- bsp_priv->phy_iface = of_get_phy_mode(dev->of_node);
+ of_get_phy_mode(dev->of_node, &bsp_priv->phy_iface);
bsp_priv->ops = ops;
bsp_priv->bus_id = plat->bus_id;
@@ -1853,7 +2478,7 @@
ret = of_property_read_u32(dev->of_node, "tx_delay", &value);
if (ret) {
- bsp_priv->tx_delay = 0x30;
+ bsp_priv->tx_delay = -1;
dev_err(dev, "Can not read property: tx_delay.");
dev_err(dev, "set tx_delay to 0x%x\n",
bsp_priv->tx_delay);
@@ -1864,7 +2489,7 @@
ret = of_property_read_u32(dev->of_node, "rx_delay", &value);
if (ret) {
- bsp_priv->rx_delay = 0x10;
+ bsp_priv->rx_delay = -1;
dev_err(dev, "Can not read property: rx_delay.");
dev_err(dev, "set rx_delay to 0x%x\n",
bsp_priv->rx_delay);
@@ -1875,6 +2500,8 @@
bsp_priv->grf = syscon_regmap_lookup_by_phandle(dev->of_node,
"rockchip,grf");
+ bsp_priv->php_grf = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "rockchip,php_grf");
bsp_priv->xpcs = syscon_regmap_lookup_by_phandle(dev->of_node,
"rockchip,xpcs");
if (!IS_ERR(bsp_priv->xpcs)) {
@@ -1892,10 +2519,45 @@
bsp_priv->integrated_phy = of_property_read_bool(plat->phy_node,
"phy-is-integrated");
if (bsp_priv->integrated_phy) {
+ unsigned char *efuse_buf;
+ struct nvmem_cell *cell;
+ size_t len;
+
bsp_priv->phy_reset = of_reset_control_get(plat->phy_node, NULL);
if (IS_ERR(bsp_priv->phy_reset)) {
dev_err(&pdev->dev, "No PHY reset control found.\n");
bsp_priv->phy_reset = NULL;
+ }
+
+ if (of_property_read_u32(plat->phy_node, "bgs,increment",
+ &bsp_priv->bgs_increment)) {
+ bsp_priv->bgs_increment = 0;
+ } else {
+ if (bsp_priv->bgs_increment > RK_FEPHY_BGS_MAX) {
+ dev_err(dev, "%s: error bgs increment: %d\n",
+ __func__, bsp_priv->bgs_increment);
+ bsp_priv->bgs_increment = RK_FEPHY_BGS_MAX;
+ }
+ }
+
+ /* Read bgs from OTP if it exists */
+ cell = nvmem_cell_get(dev, "bgs");
+ if (IS_ERR(cell)) {
+ if (PTR_ERR(cell) != -EPROBE_DEFER)
+ dev_info(dev, "failed to get bgs cell: %ld, use default\n",
+ PTR_ERR(cell));
+ else
+ return ERR_CAST(cell);
+ } else {
+ efuse_buf = nvmem_cell_read(cell, &len);
+ nvmem_cell_put(cell);
+ if (!IS_ERR(efuse_buf)) {
+ if (len == 1)
+ bsp_priv->otp_data = efuse_buf[0];
+ kfree(efuse_buf);
+ } else {
+ dev_err(dev, "failed to get efuse buf, use default\n");
+ }
}
}
}
@@ -1927,17 +2589,17 @@
case PHY_INTERFACE_MODE_RGMII_ID:
dev_info(dev, "init for RGMII_ID\n");
if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
- bsp_priv->ops->set_to_rgmii(bsp_priv, 0, 0);
+ bsp_priv->ops->set_to_rgmii(bsp_priv, -1, -1);
break;
case PHY_INTERFACE_MODE_RGMII_RXID:
dev_info(dev, "init for RGMII_RXID\n");
if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
- bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, 0);
+ bsp_priv->ops->set_to_rgmii(bsp_priv, bsp_priv->tx_delay, -1);
break;
case PHY_INTERFACE_MODE_RGMII_TXID:
dev_info(dev, "init for RGMII_TXID\n");
if (bsp_priv->ops && bsp_priv->ops->set_to_rgmii)
- bsp_priv->ops->set_to_rgmii(bsp_priv, 0, bsp_priv->rx_delay);
+ bsp_priv->ops->set_to_rgmii(bsp_priv, -1, bsp_priv->rx_delay);
break;
case PHY_INTERFACE_MODE_RMII:
dev_info(dev, "init for RMII\n");
@@ -1964,24 +2626,14 @@
return ret;
}
- pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
-
- if (bsp_priv->integrated_phy)
- rk_gmac_integrated_phy_powerup(bsp_priv);
return 0;
}
static void rk_gmac_powerdown(struct rk_priv_data *gmac)
{
- struct device *dev = &gmac->pdev->dev;
-
- if (gmac->integrated_phy)
- rk_gmac_integrated_phy_powerdown(gmac);
-
- pm_runtime_put_sync(dev);
- pm_runtime_disable(dev);
+ pm_runtime_put_sync(&gmac->pdev->dev);
rk_gmac_phy_power_on(gmac, false);
gmac_clk_enable(gmac, false);
@@ -2010,6 +2662,19 @@
default:
dev_err(dev, "unsupported interface %d", bsp_priv->phy_iface);
}
+}
+
+static int rk_integrated_phy_power(void *priv, bool up)
+{
+ struct rk_priv_data *bsp_priv = priv;
+
+ if (!bsp_priv->integrated_phy || !bsp_priv->ops ||
+ !bsp_priv->ops->integrated_phy_power)
+ return 0;
+
+ bsp_priv->ops->integrated_phy_power(bsp_priv, up);
+
+ return 0;
}
void dwmac_rk_set_rgmii_delayline(struct stmmac_priv *priv,
@@ -2046,28 +2711,20 @@
}
EXPORT_SYMBOL(dwmac_rk_get_phy_interface);
-void __weak rk_devinfo_get_eth_mac(u8 *mac)
-{
-}
-
static unsigned char macaddr[6];
extern ssize_t at24_mac_read(unsigned char* addr);
-void rk_get_eth_addr(void *priv, unsigned char *addr)
+static void rk_get_eth_addr(void *priv, unsigned char *addr)
{
struct rk_priv_data *bsp_priv = priv;
struct device *dev = &bsp_priv->pdev->dev;
- int i;
//unsigned char ethaddr[ETH_ALEN * MAX_ETH] = {0};
//int ret, id = bsp_priv->bus_id;
+ int i;
- //ben
- printk("nk-debug:enter rk_get_eth_addr.. \n");
-
- #if 0
- rk_devinfo_get_eth_mac(addr);
+#if 0
if (is_valid_ether_addr(addr))
goto out;
-
+
if (id < 0 || id >= MAX_ETH) {
dev_err(dev, "%s: Invalid ethernet bus id %d\n", __func__, id);
return;
@@ -2094,35 +2751,23 @@
} else {
memcpy(addr, ðaddr[id * ETH_ALEN], ETH_ALEN);
}
- #endif
-
- #if 0
- macaddr[0] = 0xee;
- macaddr[1] = 0x31;
- macaddr[2] = 0x32;
- macaddr[3] = 0x33;
- macaddr[4] = 0x34;
- macaddr[5] = 0x35;
-
- memcpy(addr, macaddr, 6);
- #endif
+#endif
#if 1
- if (at24_mac_read(macaddr) > 0) {
- printk("ben %s: at24_mac_read Success!! \n", __func__);
- memcpy(addr, macaddr, 6);
+ if (at24_mac_read(macaddr) > 0) {
+ printk("ben %s: at24_mac_read Success!! \n", __func__);
+ memcpy(addr, macaddr, 6);
- printk("Read the Ethernet MAC address from :");
- for (i = 0; i < 5; i++)
- printk("%2.2x:", addr[i]);
-
- printk("%2.2x\n", addr[i]);
- } else {
- printk("ben %s: at24_mac_read Failed!! \n", __func__);
- goto out;
- }
- #endif
-
+ printk("Read the Ethernet MAC address from :");
+ for (i = 0; i < 5; i++)
+ printk("%2.2x:", addr[i]);
+
+ printk("%2.2x\n", addr[i]);
+ } else {
+ printk("ben %s: at24_mac_read Failed!! \n", __func__);
+ goto out;
+ }
+ #endif
out:
dev_err(dev, "%s: mac address: %pM\n", __func__, addr);
}
@@ -2134,7 +2779,6 @@
const struct rk_gmac_ops *data;
int ret;
- printk("nk-debug:enter rk_gmac_probe 1.. \n");
data = of_device_get_match_data(&pdev->dev);
if (!data) {
dev_err(&pdev->dev, "no of match data provided\n");
@@ -2152,8 +2796,10 @@
if (!of_device_is_compatible(pdev->dev.of_node, "snps,dwmac-4.20a"))
plat_dat->has_gmac = true;
+ plat_dat->sph_disable = true;
plat_dat->fix_mac_speed = rk_fix_speed;
plat_dat->get_eth_addr = rk_get_eth_addr;
+ plat_dat->integrated_phy_power = rk_integrated_phy_power;
plat_dat->bsp_priv = rk_gmac_setup(pdev, plat_dat, data);
if (IS_ERR(plat_dat->bsp_priv)) {
@@ -2161,7 +2807,6 @@
goto err_remove_config_dt;
}
- printk("nk-debug:enter rk_gmac_probe 2.. \n");
ret = rk_gmac_clk_init(plat_dat);
if (ret)
goto err_remove_config_dt;
@@ -2231,19 +2876,57 @@
static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
static const struct of_device_id rk_gmac_dwmac_match[] = {
+#ifdef CONFIG_CPU_PX30
{ .compatible = "rockchip,px30-gmac", .data = &px30_ops },
+#endif
+#ifdef CONFIG_CPU_RK1808
{ .compatible = "rockchip,rk1808-gmac", .data = &rk1808_ops },
+#endif
+#ifdef CONFIG_CPU_RK312X
{ .compatible = "rockchip,rk3128-gmac", .data = &rk3128_ops },
+#endif
+#ifdef CONFIG_CPU_RK322X
{ .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
+#endif
+#ifdef CONFIG_CPU_RK3288
{ .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
+#endif
+#ifdef CONFIG_CPU_RK3308
{ .compatible = "rockchip,rk3308-mac", .data = &rk3308_ops },
+#endif
+#ifdef CONFIG_CPU_RK3328
{ .compatible = "rockchip,rk3328-gmac", .data = &rk3328_ops },
+#endif
+#ifdef CONFIG_CPU_RK3366
{ .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops },
+#endif
+#ifdef CONFIG_CPU_RK3368
{ .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops },
+#endif
+#ifdef CONFIG_CPU_RK3399
{ .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops },
+#endif
+#ifdef CONFIG_CPU_RK3528
+ { .compatible = "rockchip,rk3528-gmac", .data = &rk3528_ops },
+#endif
+#ifdef CONFIG_CPU_RK3562
+ { .compatible = "rockchip,rk3562-gmac", .data = &rk3562_ops },
+#endif
+#ifdef CONFIG_CPU_RK3568
{ .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops },
+#endif
+#ifdef CONFIG_CPU_RK3588
+ { .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops },
+#endif
+#ifdef CONFIG_CPU_RV1106
+ { .compatible = "rockchip,rv1106-gmac", .data = &rv1106_ops },
+#endif
+#ifdef CONFIG_CPU_RV1108
{ .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops },
+#endif
+#ifdef CONFIG_CPU_RV1126
{ .compatible = "rockchip,rv1126-gmac", .data = &rv1126_ops },
+#endif
{ }
};
MODULE_DEVICE_TABLE(of, rk_gmac_dwmac_match);
@@ -2258,7 +2941,7 @@
},
};
//module_platform_driver(rk_gmac_dwmac_driver);
- module_platform_driver1(rk_gmac_dwmac_driver);
+module_platform_driver1(rk_gmac_dwmac_driver);
MODULE_AUTHOR("Chen-Zhi (Roger Chen) <roger.chen@rock-chips.com>");
MODULE_DESCRIPTION("Rockchip RK3288 DWMAC specific glue layer");
--
Gitblit v1.6.2