#define GMAC_HW_HASH_TB_SZ             GENMASK(25, 24)
 #define GMAC_HW_FEAT_AVSEL             BIT(20)
 #define GMAC_HW_TSOEN                  BIT(18)
+#define GMAC_HW_ADDR64                 GENMASK(15, 14)
 #define GMAC_HW_TXFIFOSIZE             GENMASK(10, 6)
 #define GMAC_HW_RXFIFOSIZE             GENMASK(4, 0)
 
 
 
 static void dwmac4_set_addr(struct dma_desc *p, dma_addr_t addr)
 {
-       p->des0 = cpu_to_le32(addr);
-       p->des1 = 0;
+       p->des0 = cpu_to_le32(lower_32_bits(addr));
+       p->des1 = cpu_to_le32(upper_32_bits(addr));
 }
 
 static void dwmac4_clear(struct dma_desc *p)
 
        value = value | (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
        writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
 
+       if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) && likely(dma_cfg->eame))
+               writel(upper_32_bits(dma_rx_phy),
+                      ioaddr + DMA_CHAN_RX_BASE_ADDR_HI(chan));
+
        writel(lower_32_bits(dma_rx_phy), ioaddr + DMA_CHAN_RX_BASE_ADDR(chan));
 }
 
 
        writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
 
+       if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT) && likely(dma_cfg->eame))
+               writel(upper_32_bits(dma_tx_phy),
+                      ioaddr + DMA_CHAN_TX_BASE_ADDR_HI(chan));
+
        writel(lower_32_bits(dma_tx_phy), ioaddr + DMA_CHAN_TX_BASE_ADDR(chan));
 }
 
        if (dma_cfg->aal)
                value |= DMA_SYS_BUS_AAL;
 
+       if (dma_cfg->eame)
+               value |= DMA_SYS_BUS_EAME;
+
        writel(value, ioaddr + DMA_SYS_BUS_MODE);
 }
 
        dma_cap->hash_tb_sz = (hw_cap & GMAC_HW_HASH_TB_SZ) >> 24;
        dma_cap->av = (hw_cap & GMAC_HW_FEAT_AVSEL) >> 20;
        dma_cap->tsoen = (hw_cap & GMAC_HW_TSOEN) >> 18;
+
+       dma_cap->addr64 = (hw_cap & GMAC_HW_ADDR64) >> 14;
+       switch (dma_cap->addr64) {
+       case 0:
+               dma_cap->addr64 = 32;
+               break;
+       case 1:
+               dma_cap->addr64 = 40;
+               break;
+       case 2:
+               dma_cap->addr64 = 48;
+               break;
+       default:
+               dma_cap->addr64 = 32;
+               break;
+       }
+
        /* RX and TX FIFO sizes are encoded as log2(n / 128). Undo that by
         * shifting and store the sizes in bytes.
         */
 
 #define DMA_SYS_BUS_MB                 BIT(14)
 #define DMA_AXI_1KBBE                  BIT(13)
 #define DMA_SYS_BUS_AAL                        BIT(12)
+#define DMA_SYS_BUS_EAME               BIT(11)
 #define DMA_AXI_BLEN256                        BIT(7)
 #define DMA_AXI_BLEN128                        BIT(6)
 #define DMA_AXI_BLEN64                 BIT(5)
 #define DMA_CHAN_CONTROL(x)            DMA_CHANX_BASE_ADDR(x)
 #define DMA_CHAN_TX_CONTROL(x)         (DMA_CHANX_BASE_ADDR(x) + 0x4)
 #define DMA_CHAN_RX_CONTROL(x)         (DMA_CHANX_BASE_ADDR(x) + 0x8)
+#define DMA_CHAN_TX_BASE_ADDR_HI(x)    (DMA_CHANX_BASE_ADDR(x) + 0x10)
 #define DMA_CHAN_TX_BASE_ADDR(x)       (DMA_CHANX_BASE_ADDR(x) + 0x14)
+#define DMA_CHAN_RX_BASE_ADDR_HI(x)    (DMA_CHANX_BASE_ADDR(x) + 0x18)
 #define DMA_CHAN_RX_BASE_ADDR(x)       (DMA_CHANX_BASE_ADDR(x) + 0x1c)
 #define DMA_CHAN_TX_END_ADDR(x)                (DMA_CHANX_BASE_ADDR(x) + 0x20)
 #define DMA_CHAN_RX_END_ADDR(x)                (DMA_CHANX_BASE_ADDR(x) + 0x28)