Use reset controller to reset mt7620 ethernet phy instead of directly
writing system control registers. The reset line of "ephy" is 24, so
the DTS resets properties have been updated to get the correct reset
signal.
Tested on HiWiFi HC5861.
Signed-off-by: Shiji Yang <[email protected]>
compatible = "mediatek,mt7620-gsw";
reg = <0x10110000 0x8000>;
- resets = <&sysc 23>;
- reset-names = "esw";
+ resets = <&sysc 24>;
+ reset-names = "ephy";
interrupt-parent = <&intc>;
interrupts = <17>;
compatible = "mediatek,mt7620-gsw";
reg = <0x10110000 0x8000>;
- resets = <&sysc 23>;
- reset-names = "esw";
+ resets = <&sysc 24>;
+ reset-names = "ephy";
interrupt-parent = <&intc>;
interrupts = <17>;
return IRQ_HANDLED;
}
+static void gsw_reset_ephy(struct mt7620_gsw *gsw)
+{
+ if (!gsw->rst_ephy)
+ return;
+
+ reset_control_assert(gsw->rst_ephy);
+ usleep_range(10, 20);
+ reset_control_deassert(gsw->rst_ephy);
+ usleep_range(10, 20);
+}
+
static void mt7620_ephy_init(struct mt7620_gsw *gsw)
{
u32 i;
mtk_switch_w32(gsw, mtk_switch_r32(gsw, GSW_REG_GPC1) |
(gsw->ephy_base << 16),
GSW_REG_GPC1);
- fe_reset(MT7620A_RESET_EPHY);
+ gsw_reset_ephy(gsw);
pr_info("gsw: ephy base address: %d\n", gsw->ephy_base);
}
gsw->irq = platform_get_irq(pdev, 0);
+ gsw->rst_ephy = devm_reset_control_get_exclusive(&pdev->dev, "ephy");
+ if (IS_ERR(gsw->rst_ephy)) {
+ dev_err(gsw->dev, "failed to get EPHY reset: %pe\n", gsw->rst_ephy);
+ gsw->rst_ephy = NULL;
+ }
+
platform_set_drvdata(pdev, gsw);
return 0;
*/
+#include <linux/reset.h>
+
#ifndef _RALINK_GSW_MT7620_H__
#define _RALINK_GSW_MT7620_H__
struct mt7620_gsw {
struct device *dev;
+ struct reset_control *rst_ephy;
void __iomem *base;
int irq;
bool ephy_disable;
#define NEXT_TX_DESP_IDX(X) (((X) + 1) & (ring->tx_ring_size - 1))
#define NEXT_RX_DESP_IDX(X) (((X) + 1) & (ring->rx_ring_size - 1))
-#define SYSC_REG_RSTCTRL 0x34
-
static int fe_msg_level = -1;
module_param_named(msg_level, fe_msg_level, int, 0);
MODULE_PARM_DESC(msg_level, "Message level (-1=defaults,0=none,...,16=all)");
spin_unlock(ð->page_lock);
}
-void fe_reset(u32 reset_bits)
-{
- u32 t;
-
- t = rt_sysc_r32(SYSC_REG_RSTCTRL);
- t |= reset_bits;
- rt_sysc_w32(t, SYSC_REG_RSTCTRL);
- usleep_range(10, 20);
-
- t &= ~reset_bits;
- rt_sysc_w32(t, SYSC_REG_RSTCTRL);
- usleep_range(10, 20);
-}
-
static void fe_reset_fe(struct fe_priv *priv)
{
if (!priv->resets)
#define MT7620A_FE_GDMA1_MAC_ADRL (MT7620A_GDMA_OFFSET + 0x0C)
#define MT7620A_FE_GDMA1_MAC_ADRH (MT7620A_GDMA_OFFSET + 0x10)
-#define MT7620A_RESET_EPHY BIT(24)
-
#define RT5350_TX_BASE_PTR0 (RT5350_PDMA_OFFSET + 0x00)
#define RT5350_TX_MAX_CNT0 (RT5350_PDMA_OFFSET + 0x04)
#define RT5350_TX_CTX_IDX0 (RT5350_PDMA_OFFSET + 0x08)
void fe_reg_w32(u32 val, enum fe_reg reg);
u32 fe_reg_r32(enum fe_reg reg);
-void fe_reset(u32 reset_bits);
-
static inline void *priv_netdev(struct fe_priv *priv)
{
return (char *)priv - ALIGN(sizeof(struct net_device), NETDEV_ALIGN);