mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
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:
parent
113f62225e
commit
9f2e033754
|
|
@ -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[] = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user