diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index c37d5a280361..45ccbce91551 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -247,6 +247,8 @@ struct sunxi_nand_hw_ecc { /* Delay arrays contain internal NDFC clock cycles for field values 0 to 3. */ struct sunxi_nfc_timings { + /* Internal clock cycles used by T1-T4, T7 and T11. */ + u8 setup_cycles; s32 tWB[SUNXI_NFC_TIMING_STEPS]; s32 tADL[SUNXI_NFC_TIMING_STEPS]; s32 tWHR[SUNXI_NFC_TIMING_STEPS]; @@ -1741,12 +1743,21 @@ static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *nand, int page) } static const struct sunxi_nfc_timings sun4i_a10_nfc_timings = { + .setup_cycles = 1, .tWB = { 6, 12, 16, 20 }, .tADL = { 7, 15, 23, 31 }, .tWHR = { 7, 15, 23, 31 }, .tRHW = { 4, 8, 12, 20 }, }; +static const struct sunxi_nfc_timings sun50i_h616_nfc_timings = { + .setup_cycles = 2, + .tWB = { 28, 44, 60, 76 }, + .tADL = { 0, 12, 28, 44 }, + .tWHR = { 0, 12, 28, 44 }, + .tRHW = { 8, 24, 40, 56 }, +}; + static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration, u32 clk_period) { @@ -1781,20 +1792,28 @@ static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, return -ENOTSUPP; /* T1 <=> tCLS */ - if (timings->tCLS_min > min_clk_period) - min_clk_period = timings->tCLS_min; + if (timings->tCLS_min > + min_clk_period * nfc_timings->setup_cycles) + min_clk_period = DIV_ROUND_UP(timings->tCLS_min, + nfc_timings->setup_cycles); /* T2 <=> tCLH */ - if (timings->tCLH_min > min_clk_period) - min_clk_period = timings->tCLH_min; + if (timings->tCLH_min > + min_clk_period * nfc_timings->setup_cycles) + min_clk_period = DIV_ROUND_UP(timings->tCLH_min, + nfc_timings->setup_cycles); /* T3 <=> tCS */ - if (timings->tCS_min > min_clk_period) - min_clk_period = timings->tCS_min; + if (timings->tCS_min > + min_clk_period * nfc_timings->setup_cycles) + min_clk_period = DIV_ROUND_UP(timings->tCS_min, + nfc_timings->setup_cycles); /* T4 <=> tCH */ - if (timings->tCH_min > min_clk_period) - min_clk_period = timings->tCH_min; + if (timings->tCH_min > + min_clk_period * nfc_timings->setup_cycles) + min_clk_period = DIV_ROUND_UP(timings->tCH_min, + nfc_timings->setup_cycles); /* T5 <=> tWP */ if (timings->tWP_min > min_clk_period) @@ -1805,8 +1824,10 @@ static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, min_clk_period = timings->tWH_min; /* T7 <=> tALS */ - if (timings->tALS_min > min_clk_period) - min_clk_period = timings->tALS_min; + if (timings->tALS_min > + min_clk_period * nfc_timings->setup_cycles) + min_clk_period = DIV_ROUND_UP(timings->tALS_min, + nfc_timings->setup_cycles); /* T8 <=> tDS */ if (timings->tDS_min > min_clk_period) @@ -1821,8 +1842,10 @@ static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, min_clk_period = DIV_ROUND_UP(timings->tRR_min, 3); /* T11 <=> tALH */ - if (timings->tALH_min > min_clk_period) - min_clk_period = timings->tALH_min; + if (timings->tALH_min > + min_clk_period * nfc_timings->setup_cycles) + min_clk_period = DIV_ROUND_UP(timings->tALH_min, + nfc_timings->setup_cycles); /* T12 <=> tRP */ if (timings->tRP_min > min_clk_period) @@ -2758,7 +2781,7 @@ static const struct sunxi_nfc_caps sunxi_nfc_h616_caps = { .nuser_data_tab = ARRAY_SIZE(sunxi_user_data_len_h6), .max_ecc_steps = 32, .sram_size = 8192, - .timings = &sun4i_a10_nfc_timings, + .timings = &sun50i_h616_nfc_timings, }; static const struct of_device_id sunxi_nfc_ids[] = {