diff options
| author | James Hilliard <james.hilliard1@gmail.com> | 2026-08-07 09:38:59 -0600 |
|---|---|---|
| committer | Miquel Raynal <miquel.raynal@bootlin.com> | 2026-08-10 16:24:26 +0200 |
| commit | 9f2e033754c6c023150f184b4e72bbcc5d6eea13 (patch) | |
| tree | 5617df5efb972f1507cea41ea4204b6481da1e6d | |
| parent | 113f62225e98febabba0fee00afd29d4eaf65abb (diff) | |
mtd: rawnand: sunxi: group controller delay tables
The tWB and tRHW timing field encodings are controller properties, but
they currently live in standalone lookup tables.
Group them in a timing descriptor selected through the controller
capability data. Point every existing controller at the legacy values so
this is a pure preparation change.
Fixes: 88fd4e4deae8 ("mtd: rawnand: sunxi: Add support for H616 nand controller")
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
| -rw-r--r-- | drivers/mtd/nand/raw/sunxi_nand.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 6e22d82a77ea..4434221ad841 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -243,6 +243,14 @@ struct sunxi_nand_hw_ecc { u32 ecc_ctl; }; +#define SUNXI_NFC_TIMING_STEPS 4 + +/* Delay arrays contain internal NDFC clock cycles for field values 0 to 3. */ +struct sunxi_nfc_timings { + s32 tWB[SUNXI_NFC_TIMING_STEPS]; + s32 tRHW[SUNXI_NFC_TIMING_STEPS]; +}; + /** * struct sunxi_nand_chip - stores NAND chip device related information * @@ -314,6 +322,7 @@ struct sunxi_nfc_mdma_desc { * bytes to write * @nuser_data_tab: Size of @user_data_len_tab * @sram_size: Size of the NAND controller SRAM + * @timings: Controller timing characteristics */ struct sunxi_nfc_caps { bool has_mdma; @@ -341,6 +350,7 @@ struct sunxi_nfc_caps { unsigned int nuser_data_tab; unsigned int max_ecc_steps; int sram_size; + const struct sunxi_nfc_timings *timings; }; /** @@ -1728,8 +1738,10 @@ static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *nand, int page) return nand_prog_page_end_op(nand); } -static const s32 tWB_lut[] = {6, 12, 16, 20}; -static const s32 tRHW_lut[] = {4, 8, 12, 20}; +static const struct sunxi_nfc_timings sun4i_a10_nfc_timings = { + .tWB = { 6, 12, 16, 20 }, + .tRHW = { 4, 8, 12, 20 }, +}; static int _sunxi_nand_lookup_timing(const s32 *lut, int lut_size, u32 duration, u32 clk_period) @@ -1754,6 +1766,7 @@ static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, { struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); + const struct sunxi_nfc_timings *nfc_timings = nfc->caps->timings; const struct nand_sdr_timings *timings; u32 min_clk_period = 0; s32 tWB, tADL, tWHR, tRHW, tCAD; @@ -1824,8 +1837,10 @@ static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, min_clk_period = DIV_ROUND_UP(timings->tWC_min, 2); /* T16 - T19 + tCAD */ - if (timings->tWB_max > (min_clk_period * 20)) - min_clk_period = DIV_ROUND_UP(timings->tWB_max, 20); + if (timings->tWB_max > + (min_clk_period * nfc_timings->tWB[SUNXI_NFC_TIMING_STEPS - 1])) + min_clk_period = DIV_ROUND_UP(timings->tWB_max, + nfc_timings->tWB[SUNXI_NFC_TIMING_STEPS - 1]); if (timings->tADL_min > (min_clk_period * 32)) min_clk_period = DIV_ROUND_UP(timings->tADL_min, 32); @@ -1833,8 +1848,10 @@ static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, if (timings->tWHR_min > (min_clk_period * 32)) min_clk_period = DIV_ROUND_UP(timings->tWHR_min, 32); - if (timings->tRHW_min > (min_clk_period * 20)) - min_clk_period = DIV_ROUND_UP(timings->tRHW_min, 20); + if (timings->tRHW_min > + (min_clk_period * nfc_timings->tRHW[SUNXI_NFC_TIMING_STEPS - 1])) + min_clk_period = DIV_ROUND_UP(timings->tRHW_min, + nfc_timings->tRHW[SUNXI_NFC_TIMING_STEPS - 1]); /* * In non-EDO, tREA should be less than tRP to guarantee that the @@ -1850,7 +1867,7 @@ static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, if (timings->tREA_max > min_clk_period && !timings->tRLOH_min) min_clk_period = timings->tREA_max; - tWB = sunxi_nand_lookup_timing(tWB_lut, timings->tWB_max, + tWB = sunxi_nand_lookup_timing(nfc_timings->tWB, timings->tWB_max, min_clk_period); if (tWB < 0) { dev_err(nfc->dev, "unsupported tWB\n"); @@ -1869,7 +1886,7 @@ static int sunxi_nfc_setup_interface(struct nand_chip *nand, int csline, return -EINVAL; } - tRHW = sunxi_nand_lookup_timing(tRHW_lut, timings->tRHW_min, + tRHW = sunxi_nand_lookup_timing(nfc_timings->tRHW, timings->tRHW_min, min_clk_period); if (tRHW < 0) { dev_err(nfc->dev, "unsupported tRHW\n"); @@ -2682,6 +2699,7 @@ static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = { .nstrengths = ARRAY_SIZE(sunxi_ecc_strengths_a10), .max_ecc_steps = 16, .sram_size = 1024, + .timings = &sun4i_a10_nfc_timings, }; static const struct sunxi_nfc_caps sunxi_nfc_a23_caps = { @@ -2704,6 +2722,7 @@ static const struct sunxi_nfc_caps sunxi_nfc_a23_caps = { .nstrengths = ARRAY_SIZE(sunxi_ecc_strengths_a10), .max_ecc_steps = 16, .sram_size = 1024, + .timings = &sun4i_a10_nfc_timings, }; static const struct sunxi_nfc_caps sunxi_nfc_h616_caps = { @@ -2729,6 +2748,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, }; static const struct of_device_id sunxi_nfc_ids[] = { |
