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: 88fd4e4dea ("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>
This commit is contained in:
James Hilliard 2026-08-07 09:38:59 -06:00 committed by Miquel Raynal
parent 113f62225e
commit 9f2e033754

View File

@ -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[] = {