#define SPICC_SWAP_RO          BIT(14) /* RX FIFO Data Swap Read-Only */
 #define SPICC_SWAP_W1          BIT(15) /* RX FIFO Data Swap Write-Only */
 #define SPICC_DLYCTL_RO_MASK   GENMASK(20, 15) /* Delay Control Read-Only */
-#define SPICC_DLYCTL_W1_MASK   GENMASK(21, 16) /* Delay Control Write-Only */
+#define SPICC_MO_DELAY_MASK    GENMASK(17, 16) /* Master Output Delay */
+#define SPICC_MO_NO_DELAY      0
+#define SPICC_MO_DELAY_1_CYCLE 1
+#define SPICC_MO_DELAY_2_CYCLE 2
+#define SPICC_MO_DELAY_3_CYCLE 3
+#define SPICC_MI_DELAY_MASK    GENMASK(19, 18) /* Master Input Delay */
+#define SPICC_MI_NO_DELAY      0
+#define SPICC_MI_DELAY_1_CYCLE 1
+#define SPICC_MI_DELAY_2_CYCLE 2
+#define SPICC_MI_DELAY_3_CYCLE 3
+#define SPICC_MI_CAP_DELAY_MASK        GENMASK(21, 20) /* Master Capture Delay */
+#define SPICC_CAP_AHEAD_2_CYCLE        0
+#define SPICC_CAP_AHEAD_1_CYCLE        1
+#define SPICC_CAP_NO_DELAY     2
+#define SPICC_CAP_DELAY_1_CYCLE        3
 #define SPICC_FIFORST_RO_MASK  GENMASK(22, 21) /* FIFO Softreset Read-Only */
 #define SPICC_FIFORST_W1_MASK  GENMASK(23, 22) /* FIFO Softreset Write-Only */
 
        return IRQ_HANDLED;
 }
 
+static void meson_spicc_auto_io_delay(struct meson_spicc_device *spicc)
+{
+       u32 div, hz;
+       u32 mi_delay, cap_delay;
+       u32 conf;
+
+       if (spicc->data->has_enhance_clk_div) {
+               div = FIELD_GET(SPICC_ENH_DATARATE_MASK,
+                               readl_relaxed(spicc->base + SPICC_ENH_CTL0));
+               div++;
+               div <<= 1;
+       } else {
+               div = FIELD_GET(SPICC_DATARATE_MASK,
+                               readl_relaxed(spicc->base + SPICC_CONREG));
+               div += 2;
+               div = 1 << div;
+       }
+
+       mi_delay = SPICC_MI_NO_DELAY;
+       cap_delay = SPICC_CAP_AHEAD_2_CYCLE;
+       hz = clk_get_rate(spicc->clk);
+
+       if (hz >= 100000000)
+               cap_delay = SPICC_CAP_DELAY_1_CYCLE;
+       else if (hz >= 80000000)
+               cap_delay = SPICC_CAP_NO_DELAY;
+       else if (hz >= 40000000)
+               cap_delay = SPICC_CAP_AHEAD_1_CYCLE;
+       else if (div >= 16)
+               mi_delay = SPICC_MI_DELAY_3_CYCLE;
+       else if (div >= 8)
+               mi_delay = SPICC_MI_DELAY_2_CYCLE;
+       else if (div >= 6)
+               mi_delay = SPICC_MI_DELAY_1_CYCLE;
+
+       conf = readl_relaxed(spicc->base + SPICC_TESTREG);
+       conf &= ~(SPICC_MO_DELAY_MASK | SPICC_MI_DELAY_MASK
+                 | SPICC_MI_CAP_DELAY_MASK);
+       conf |= FIELD_PREP(SPICC_MI_DELAY_MASK, mi_delay);
+       conf |= FIELD_PREP(SPICC_MI_CAP_DELAY_MASK, cap_delay);
+       writel_relaxed(conf, spicc->base + SPICC_TESTREG);
+}
+
 static void meson_spicc_setup_xfer(struct meson_spicc_device *spicc,
                                   struct spi_transfer *xfer)
 {
                writel_relaxed(conf, spicc->base + SPICC_CONREG);
 
        clk_set_rate(spicc->clk, xfer->speed_hz);
+
+       meson_spicc_auto_io_delay(spicc);
 }
 
 static int meson_spicc_transfer_one(struct spi_master *master,