Skip to content

Commit 88fd4e4

Browse files
richard-bootlinmiquelraynal
authored andcommitted
mtd: rawnand: sunxi: Add support for H616 nand controller
The H616 nand controller has the same base as A10/A23, with some differences: - mdma is based on chained buffers - its ECC supports up to 80bit per 1024bytes - some registers layouts are a bit different, mainly due do the stronger ECC. - it uses USER_DATA_LEN registers along USER_DATA registers. - it needs a specific clock for ECC and MBUS. Introduce the basic support, with ECC and scrambling, but without DMA/MDMA. Tested on Whatsminer H616 board (with and without scrambling, ECC) Signed-off-by: Richard Genoud <richard.genoud@bootlin.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
1 parent 5ddfbc6 commit 88fd4e4

1 file changed

Lines changed: 177 additions & 8 deletions

File tree

drivers/mtd/nand/raw/sunxi_nand.c

Lines changed: 177 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,40 @@
4949
#define NFC_REG_A23_IO_DATA 0x0300
5050
#define NFC_REG_ECC_CTL 0x0034
5151
#define NFC_REG_ECC_ST 0x0038
52-
#define NFC_REG_DEBUG 0x003C
52+
#define NFC_REG_H6_PAT_FOUND 0x003C
5353
#define NFC_REG_A10_ECC_ERR_CNT 0x0040
54+
#define NFC_REG_H6_ECC_ERR_CNT 0x0050
5455
#define NFC_REG_ECC_ERR_CNT(nfc, x) ((nfc->caps->reg_ecc_err_cnt + (x)) & ~0x3)
56+
#define NFC_REG_H6_RDATA_CTL 0x0044
57+
#define NFC_REG_H6_RDATA_0 0x0048
58+
#define NFC_REG_H6_RDATA_1 0x004C
5559
#define NFC_REG_A10_USER_DATA 0x0050
60+
#define NFC_REG_H6_USER_DATA 0x0080
5661
#define NFC_REG_USER_DATA(nfc, x) (nfc->caps->reg_user_data + ((x) * 4))
62+
#define NFC_REG_H6_USER_DATA_LEN 0x0070
63+
/* A USER_DATA_LEN register can hold the length of 8 USER_DATA registers */
64+
#define NFC_REG_USER_DATA_LEN_CAPACITY 8
65+
#define NFC_REG_USER_DATA_LEN(nfc, step) \
66+
(nfc->caps->reg_user_data_len + \
67+
((step) / NFC_REG_USER_DATA_LEN_CAPACITY) * 4)
5768
#define NFC_REG_SPARE_AREA(nfc) (nfc->caps->reg_spare_area)
5869
#define NFC_REG_A10_SPARE_AREA 0x00A0
5970
#define NFC_REG_PAT_ID(nfc) (nfc->caps->reg_pat_id)
6071
#define NFC_REG_A10_PAT_ID 0x00A4
6172
#define NFC_REG_MDMA_ADDR 0x00C0
6273
#define NFC_REG_MDMA_CNT 0x00C4
74+
#define NFC_REG_H6_EFNAND_STATUS 0x0110
75+
#define NFC_REG_H6_SPARE_AREA 0x0114
76+
#define NFC_REG_H6_PAT_ID 0x0118
77+
#define NFC_REG_H6_DDR2_SPEC_CTL 0x011C
78+
#define NFC_REG_H6_NDMA_MODE_CTL 0x0120
79+
#define NFC_REG_H6_MDMA_DLBA_REG 0x0200
80+
#define NFC_REG_H6_MDMA_STA 0x0204
81+
#define NFC_REG_H6_MDMA_INT_MAS 0x0208
82+
#define NFC_REG_H6_MDMA_DESC_ADDR 0x020C
83+
#define NFC_REG_H6_MDMA_BUF_ADDR 0x0210
84+
#define NFC_REG_H6_MDMA_CNT 0x0214
85+
6386
#define NFC_RAM0_BASE 0x0400
6487
#define NFC_RAM1_BASE 0x0800
6588

@@ -71,6 +94,7 @@
7194
#define NFC_BUS_WIDTH_16 (1 << 2)
7295
#define NFC_RB_SEL_MSK BIT(3)
7396
#define NFC_RB_SEL(x) ((x) << 3)
97+
/* CE_SEL BIT 27 is meant to be used for GPIO chipselect */
7498
#define NFC_CE_SEL_MSK GENMASK(26, 24)
7599
#define NFC_CE_SEL(x) ((x) << 24)
76100
#define NFC_CE_CTL BIT(6)
@@ -89,6 +113,9 @@
89113
#define NFC_STA BIT(4)
90114
#define NFC_NATCH_INT_FLAG BIT(5)
91115
#define NFC_RB_STATE(x) BIT(x + 8)
116+
#define NFC_RB_STATE_MSK GENMASK(11, 8)
117+
#define NDFC_RDATA_STA_1 BIT(12)
118+
#define NDFC_RDATA_STA_0 BIT(13)
92119

93120
/* define bit use in NFC_INT */
94121
#define NFC_B2R_INT_ENABLE BIT(0)
@@ -100,16 +127,23 @@
100127

101128
/* define bit use in NFC_TIMING_CTL */
102129
#define NFC_TIMING_CTL_EDO BIT(8)
130+
#define NFC_TIMING_CTL_E_EDO BIT(9)
103131

104132
/* define NFC_TIMING_CFG register layout */
105133
#define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD) \
106134
(((tWB) & 0x3) | (((tADL) & 0x3) << 2) | \
107135
(((tWHR) & 0x3) << 4) | (((tRHW) & 0x3) << 6) | \
108136
(((tCAD) & 0x7) << 8))
109137

138+
#define NFC_TIMING_CFG2(tCDQSS, tSC, tCLHZ, tCSS, tWC) \
139+
((((tCDQSS) & 0x1) << 11) | (((tSC) & 0x3) << 12) | \
140+
(((tCLHZ) & 0x3) << 14) | (((tCSS) & 0x3) << 16) | \
141+
(((tWC) & 0x3) << 18))
142+
110143
/* define bit use in NFC_CMD */
111144
#define NFC_CMD_LOW_BYTE_MSK GENMASK(7, 0)
112-
#define NFC_CMD_HIGH_BYTE_MSK GENMASK(15, 8)
145+
#define NFC_CMD_HIGH_BYTE_MSK GENMASK(15, 8) /* 15-10 reserved on H6 */
146+
#define NFC_CMD_ADR_NUM_MSK GENMASK(9, 8)
113147
#define NFC_CMD(x) (x)
114148
#define NFC_ADR_NUM_MSK GENMASK(18, 16)
115149
#define NFC_ADR_NUM(x) (((x) - 1) << 16)
@@ -122,6 +156,7 @@
122156
#define NFC_SEQ BIT(25)
123157
#define NFC_DATA_SWAP_METHOD BIT(26)
124158
#define NFC_ROW_AUTO_INC BIT(27)
159+
#define NFC_H6_SEND_RND_CMD2 BIT(27)
125160
#define NFC_SEND_CMD3 BIT(28)
126161
#define NFC_SEND_CMD4 BIT(29)
127162
#define NFC_CMD_TYPE_MSK GENMASK(31, 30)
@@ -133,6 +168,7 @@
133168
#define NFC_READ_CMD_MSK GENMASK(7, 0)
134169
#define NFC_RND_READ_CMD0_MSK GENMASK(15, 8)
135170
#define NFC_RND_READ_CMD1_MSK GENMASK(23, 16)
171+
#define NFC_RND_READ_CMD2_MSK GENMASK(31, 24)
136172

137173
/* define bit use in NFC_WCMD_SET */
138174
#define NFC_PROGRAM_CMD_MSK GENMASK(7, 0)
@@ -150,6 +186,9 @@
150186
#define NFC_RANDOM_DIRECTION(nfc) (nfc->caps->random_dir_mask)
151187
#define NFC_ECC_MODE_MSK(nfc) (nfc->caps->ecc_mode_mask)
152188
#define NFC_ECC_MODE(nfc, x) field_prep(NFC_ECC_MODE_MSK(nfc), (x))
189+
/* RANDOM_PAGE_SIZE: 0: ECC block size 1: page size */
190+
#define NFC_A23_RANDOM_PAGE_SIZE BIT(11)
191+
#define NFC_H6_RANDOM_PAGE_SIZE BIT(7)
153192
#define NFC_RANDOM_SEED_MSK GENMASK(30, 16)
154193
#define NFC_RANDOM_SEED(x) ((x) << 16)
155194

@@ -165,6 +204,9 @@
165204

166205
#define NFC_ECC_ERR_CNT(b, x) (((x) >> (((b) % 4) * 8)) & 0xff)
167206

207+
#define NFC_USER_DATA_LEN_MSK(step) \
208+
(0xf << (((step) % NFC_REG_USER_DATA_LEN_CAPACITY) * 4))
209+
168210
#define NFC_DEFAULT_TIMEOUT_MS 1000
169211

170212
#define NFC_MAX_CS 7
@@ -235,9 +277,12 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
235277
* @has_mdma: Use mbus dma mode, otherwise general dma
236278
* through MBUS on A23/A33 needs extra configuration.
237279
* @has_ecc_block_512: If the ECC can handle 512B or only 1024B chuncks
280+
* @has_ecc_clk: If the controller needs an ECC clock.
281+
* @has_mbus_clk: If the controller needs a mbus clock.
238282
* @reg_io_data: I/O data register
239283
* @reg_ecc_err_cnt: ECC error counter register
240284
* @reg_user_data: User data register
285+
* @reg_user_data_len: User data length register
241286
* @reg_spare_area: Spare Area Register
242287
* @reg_pat_id: Pattern ID Register
243288
* @reg_pat_found: Data Pattern Status Register
@@ -249,14 +294,24 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand)
249294
* @dma_maxburst: DMA maxburst
250295
* @ecc_strengths: Available ECC strengths array
251296
* @nstrengths: Size of @ecc_strengths
297+
* @max_ecc_steps: Maximum supported steps for ECC, this is also the
298+
* number of user data registers
299+
* @user_data_len_tab: Table of lenghts supported by USER_DATA_LEN register
300+
* The table index is the value to set in NFC_USER_DATA_LEN
301+
* registers, and the corresponding value is the number of
302+
* bytes to write
303+
* @nuser_data_tab: Size of @user_data_len_tab
252304
* @sram_size: Size of the NAND controller SRAM
253305
*/
254306
struct sunxi_nfc_caps {
255307
bool has_mdma;
256308
bool has_ecc_block_512;
309+
bool has_ecc_clk;
310+
bool has_mbus_clk;
257311
unsigned int reg_io_data;
258312
unsigned int reg_ecc_err_cnt;
259313
unsigned int reg_user_data;
314+
unsigned int reg_user_data_len;
260315
unsigned int reg_spare_area;
261316
unsigned int reg_pat_id;
262317
unsigned int reg_pat_found;
@@ -268,6 +323,9 @@ struct sunxi_nfc_caps {
268323
unsigned int dma_maxburst;
269324
const u8 *ecc_strengths;
270325
unsigned int nstrengths;
326+
const u8 *user_data_len_tab;
327+
unsigned int nuser_data_tab;
328+
unsigned int max_ecc_steps;
271329
int sram_size;
272330
};
273331

@@ -279,6 +337,8 @@ struct sunxi_nfc_caps {
279337
* @regs: NAND controller registers
280338
* @ahb_clk: NAND controller AHB clock
281339
* @mod_clk: NAND controller mod clock
340+
* @ecc_clk: NAND controller ECC clock
341+
* @mbus_clk: NAND controller MBUS clock
282342
* @reset: NAND controller reset line
283343
* @assigned_cs: bitmask describing already assigned CS lines
284344
* @clk_rate: NAND controller current clock rate
@@ -294,6 +354,8 @@ struct sunxi_nfc {
294354
void __iomem *regs;
295355
struct clk *ahb_clk;
296356
struct clk *mod_clk;
357+
struct clk *ecc_clk;
358+
struct clk *mbus_clk;
297359
struct reset_control *reset;
298360
unsigned long assigned_cs;
299361
unsigned long clk_rate;
@@ -774,6 +836,53 @@ static void sunxi_nfc_hw_ecc_get_prot_oob_bytes(struct nand_chip *nand, u8 *oob,
774836
sunxi_nfc_randomize_bbm(nand, page, oob);
775837
}
776838

839+
/*
840+
* On H6/H6 the user_data length has to be set in specific registers
841+
* before writing.
842+
*/
843+
static void sunxi_nfc_reset_user_data_len(struct sunxi_nfc *nfc)
844+
{
845+
int loop_step = NFC_REG_USER_DATA_LEN_CAPACITY;
846+
847+
/* not all SoCs have this register */
848+
if (!nfc->caps->reg_user_data_len)
849+
return;
850+
851+
for (int i = 0; i < nfc->caps->max_ecc_steps; i += loop_step)
852+
writel(0, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, i));
853+
}
854+
855+
static void sunxi_nfc_set_user_data_len(struct sunxi_nfc *nfc,
856+
int len, int step)
857+
{
858+
bool found = false;
859+
u32 val;
860+
int i;
861+
862+
/* not all SoCs have this register */
863+
if (!nfc->caps->reg_user_data_len)
864+
return;
865+
866+
for (i = 0; i < nfc->caps->nuser_data_tab; i++) {
867+
if (len == nfc->caps->user_data_len_tab[i]) {
868+
found = true;
869+
break;
870+
}
871+
}
872+
873+
if (!found) {
874+
dev_warn(nfc->dev,
875+
"Unsupported length for user data reg: %d\n", len);
876+
return;
877+
}
878+
879+
val = readl(nfc->regs + NFC_REG_USER_DATA_LEN(nfc, step));
880+
881+
val &= ~NFC_USER_DATA_LEN_MSK(step);
882+
val |= field_prep(NFC_USER_DATA_LEN_MSK(step), i);
883+
writel(val, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, step));
884+
}
885+
777886
static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand,
778887
const u8 *oob, int step,
779888
bool bbm, int page)
@@ -868,6 +977,8 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand,
868977
if (ret)
869978
return ret;
870979

980+
sunxi_nfc_reset_user_data_len(nfc);
981+
sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, 0);
871982
sunxi_nfc_randomizer_config(nand, page, false);
872983
sunxi_nfc_randomizer_enable(nand);
873984
writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
@@ -978,6 +1089,8 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf
9781089
return ret;
9791090

9801091
sunxi_nfc_hw_ecc_enable(nand);
1092+
sunxi_nfc_reset_user_data_len(nfc);
1093+
sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, 0);
9811094
sunxi_nfc_randomizer_config(nand, page, false);
9821095
sunxi_nfc_randomizer_enable(nand);
9831096

@@ -1110,6 +1223,8 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand,
11101223

11111224
sunxi_nfc_randomizer_config(nand, page, false);
11121225
sunxi_nfc_randomizer_enable(nand);
1226+
sunxi_nfc_reset_user_data_len(nfc);
1227+
sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, 0);
11131228
sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, 0, bbm, page);
11141229

11151230
writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
@@ -1354,10 +1469,12 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand,
13541469
if (ret)
13551470
goto pio_fallback;
13561471

1472+
sunxi_nfc_reset_user_data_len(nfc);
13571473
for (i = 0; i < ecc->steps; i++) {
13581474
const u8 *oob = nand->oob_poi + (i * (ecc->bytes + USER_DATA_SZ));
13591475

13601476
sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, i, !i, page);
1477+
sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, i);
13611478
}
13621479

13631480
nand_prog_page_begin_op(nand, page, 0, NULL, 0);
@@ -2158,6 +2275,10 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
21582275
if (irq < 0)
21592276
return irq;
21602277

2278+
nfc->caps = of_device_get_match_data(dev);
2279+
if (!nfc->caps)
2280+
return -EINVAL;
2281+
21612282
nfc->ahb_clk = devm_clk_get_enabled(dev, "ahb");
21622283
if (IS_ERR(nfc->ahb_clk)) {
21632284
dev_err(dev, "failed to retrieve ahb clk\n");
@@ -2170,6 +2291,22 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
21702291
return PTR_ERR(nfc->mod_clk);
21712292
}
21722293

2294+
if (nfc->caps->has_ecc_clk) {
2295+
nfc->ecc_clk = devm_clk_get_enabled(dev, "ecc");
2296+
if (IS_ERR(nfc->ecc_clk)) {
2297+
dev_err(dev, "failed to retrieve ecc clk\n");
2298+
return PTR_ERR(nfc->ecc_clk);
2299+
}
2300+
}
2301+
2302+
if (nfc->caps->has_mbus_clk) {
2303+
nfc->mbus_clk = devm_clk_get_enabled(dev, "mbus");
2304+
if (IS_ERR(nfc->mbus_clk)) {
2305+
dev_err(dev, "failed to retrieve mbus clk\n");
2306+
return PTR_ERR(nfc->mbus_clk);
2307+
}
2308+
}
2309+
21732310
nfc->reset = devm_reset_control_get_optional_exclusive(dev, "ahb");
21742311
if (IS_ERR(nfc->reset))
21752312
return PTR_ERR(nfc->reset);
@@ -2180,12 +2317,6 @@ static int sunxi_nfc_probe(struct platform_device *pdev)
21802317
return ret;
21812318
}
21822319

2183-
nfc->caps = of_device_get_match_data(&pdev->dev);
2184-
if (!nfc->caps) {
2185-
ret = -EINVAL;
2186-
goto out_ahb_reset_reassert;
2187-
}
2188-
21892320
ret = sunxi_nfc_rst(nfc);
21902321
if (ret)
21912322
goto out_ahb_reset_reassert;
@@ -2236,6 +2367,14 @@ static const u8 sunxi_ecc_strengths_a10[] = {
22362367
16, 24, 28, 32, 40, 48, 56, 60, 64
22372368
};
22382369

2370+
static const u8 sunxi_ecc_strengths_h6[] = {
2371+
16, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80
2372+
};
2373+
2374+
static const u8 sunxi_user_data_len_h6[] = {
2375+
0, 4, 8, 12, 16, 20, 24, 28, 32
2376+
};
2377+
22392378
static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = {
22402379
.has_ecc_block_512 = true,
22412380
.reg_io_data = NFC_REG_A10_IO_DATA,
@@ -2252,6 +2391,7 @@ static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = {
22522391
.dma_maxburst = 4,
22532392
.ecc_strengths = sunxi_ecc_strengths_a10,
22542393
.nstrengths = ARRAY_SIZE(sunxi_ecc_strengths_a10),
2394+
.max_ecc_steps = 16,
22552395
.sram_size = 1024,
22562396
};
22572397

@@ -2272,9 +2412,34 @@ static const struct sunxi_nfc_caps sunxi_nfc_a23_caps = {
22722412
.dma_maxburst = 8,
22732413
.ecc_strengths = sunxi_ecc_strengths_a10,
22742414
.nstrengths = ARRAY_SIZE(sunxi_ecc_strengths_a10),
2415+
.max_ecc_steps = 16,
22752416
.sram_size = 1024,
22762417
};
22772418

2419+
static const struct sunxi_nfc_caps sunxi_nfc_h616_caps = {
2420+
.has_ecc_clk = true,
2421+
.has_mbus_clk = true,
2422+
.reg_io_data = NFC_REG_A23_IO_DATA,
2423+
.reg_ecc_err_cnt = NFC_REG_H6_ECC_ERR_CNT,
2424+
.reg_user_data = NFC_REG_H6_USER_DATA,
2425+
.reg_user_data_len = NFC_REG_H6_USER_DATA_LEN,
2426+
.reg_spare_area = NFC_REG_H6_SPARE_AREA,
2427+
.reg_pat_id = NFC_REG_H6_PAT_ID,
2428+
.reg_pat_found = NFC_REG_H6_PAT_FOUND,
2429+
.random_en_mask = BIT(5),
2430+
.random_dir_mask = BIT(6),
2431+
.ecc_mode_mask = GENMASK(15, 8),
2432+
.ecc_err_mask = GENMASK(31, 0),
2433+
.pat_found_mask = GENMASK(31, 0),
2434+
.dma_maxburst = 8,
2435+
.ecc_strengths = sunxi_ecc_strengths_h6,
2436+
.nstrengths = ARRAY_SIZE(sunxi_ecc_strengths_h6),
2437+
.user_data_len_tab = sunxi_user_data_len_h6,
2438+
.nuser_data_tab = ARRAY_SIZE(sunxi_user_data_len_h6),
2439+
.max_ecc_steps = 32,
2440+
.sram_size = 8192,
2441+
};
2442+
22782443
static const struct of_device_id sunxi_nfc_ids[] = {
22792444
{
22802445
.compatible = "allwinner,sun4i-a10-nand",
@@ -2284,6 +2449,10 @@ static const struct of_device_id sunxi_nfc_ids[] = {
22842449
.compatible = "allwinner,sun8i-a23-nand-controller",
22852450
.data = &sunxi_nfc_a23_caps,
22862451
},
2452+
{
2453+
.compatible = "allwinner,sun50i-h616-nand-controller",
2454+
.data = &sunxi_nfc_h616_caps,
2455+
},
22872456
{ /* sentinel */ }
22882457
};
22892458
MODULE_DEVICE_TABLE(of, sunxi_nfc_ids);

0 commit comments

Comments
 (0)