@@ -37,10 +37,15 @@
#define MX93_GPR_ENET_QOS_INTF_SEL_RGMII (0x1 << 1)
#define MX93_GPR_ENET_QOS_CLK_GEN_EN (0x1 << 0)
+#define DMA_BUS_MODE 0x00001000
+#define DMA_BUS_MODE_SFT_RESET (0x1 << 0)
+#define RMII_RESET_SPEED (0x3 << 14)
+
struct imx_dwmac_ops {
u32 addr_width;
bool mac_rgmii_txclk_auto_adj;
+ int (*fix_soc_reset)(void *priv, void __iomem *ioaddr);
int (*set_intf_mode)(struct plat_stmmacenet_data *plat_dat);
};
@@ -207,6 +212,25 @@ static void imx_dwmac_fix_speed(void *priv, unsigned int speed)
dev_err(dwmac->dev, "failed to set tx rate %lu\n", rate);
}
+static int imx_dwmac_mx93_reset(void *priv, void __iomem *ioaddr)
+{
+ u32 value = readl(ioaddr + DMA_BUS_MODE);
+ struct plat_stmmacenet_data *plat_dat = priv;
+
+ /* DMA SW reset */
+ value |= DMA_BUS_MODE_SFT_RESET;
+ writel(value, ioaddr + DMA_BUS_MODE);
+
+ if (plat_dat->interface == PHY_INTERFACE_MODE_RMII) {
+ usleep_range(100, 200);
+ writel(RMII_RESET_SPEED, ioaddr + MAC_CTRL_REG);
+ }
+
+ return readl_poll_timeout(ioaddr + DMA_BUS_MODE, value,
+ !(value & DMA_BUS_MODE_SFT_RESET),
+ 10000, 1000000);
+}
+
static int
imx_dwmac_parse_dt(struct imx_priv_data *dwmac, struct device *dev)
{
@@ -305,6 +329,8 @@ static int imx_dwmac_probe(struct platform_device *pdev)
if (ret)
goto err_dwmac_init;
+ dwmac->plat_dat->fix_soc_reset = dwmac->ops->fix_soc_reset;
+
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
goto err_drv_probe;
@@ -338,6 +364,7 @@ static struct imx_dwmac_ops imx93_dwmac_data = {
.addr_width = 32,
.mac_rgmii_txclk_auto_adj = true,
.set_intf_mode = imx93_set_intf_mode,
+ .fix_soc_reset = imx_dwmac_mx93_reset,
};
static const struct of_device_id imx_dwmac_match[] = {