Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Richard Genoud and committed by
Miquel Raynal
88fd4e4d 5ddfbc68

+177 -8
+177 -8
drivers/mtd/nand/raw/sunxi_nand.c
··· 49 49 #define NFC_REG_A23_IO_DATA 0x0300 50 50 #define NFC_REG_ECC_CTL 0x0034 51 51 #define NFC_REG_ECC_ST 0x0038 52 - #define NFC_REG_DEBUG 0x003C 52 + #define NFC_REG_H6_PAT_FOUND 0x003C 53 53 #define NFC_REG_A10_ECC_ERR_CNT 0x0040 54 + #define NFC_REG_H6_ECC_ERR_CNT 0x0050 54 55 #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 55 59 #define NFC_REG_A10_USER_DATA 0x0050 60 + #define NFC_REG_H6_USER_DATA 0x0080 56 61 #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) 57 68 #define NFC_REG_SPARE_AREA(nfc) (nfc->caps->reg_spare_area) 58 69 #define NFC_REG_A10_SPARE_AREA 0x00A0 59 70 #define NFC_REG_PAT_ID(nfc) (nfc->caps->reg_pat_id) 60 71 #define NFC_REG_A10_PAT_ID 0x00A4 61 72 #define NFC_REG_MDMA_ADDR 0x00C0 62 73 #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 + 63 86 #define NFC_RAM0_BASE 0x0400 64 87 #define NFC_RAM1_BASE 0x0800 65 88 ··· 94 71 #define NFC_BUS_WIDTH_16 (1 << 2) 95 72 #define NFC_RB_SEL_MSK BIT(3) 96 73 #define NFC_RB_SEL(x) ((x) << 3) 74 + /* CE_SEL BIT 27 is meant to be used for GPIO chipselect */ 97 75 #define NFC_CE_SEL_MSK GENMASK(26, 24) 98 76 #define NFC_CE_SEL(x) ((x) << 24) 99 77 #define NFC_CE_CTL BIT(6) ··· 113 89 #define NFC_STA BIT(4) 114 90 #define NFC_NATCH_INT_FLAG BIT(5) 115 91 #define NFC_RB_STATE(x) BIT(x + 8) 92 + #define NFC_RB_STATE_MSK GENMASK(11, 8) 93 + #define NDFC_RDATA_STA_1 BIT(12) 94 + #define NDFC_RDATA_STA_0 BIT(13) 116 95 117 96 /* define bit use in NFC_INT */ 118 97 #define NFC_B2R_INT_ENABLE BIT(0) ··· 127 100 128 101 /* define bit use in NFC_TIMING_CTL */ 129 102 #define NFC_TIMING_CTL_EDO BIT(8) 103 + #define NFC_TIMING_CTL_E_EDO BIT(9) 130 104 131 105 /* define NFC_TIMING_CFG register layout */ 132 106 #define NFC_TIMING_CFG(tWB, tADL, tWHR, tRHW, tCAD) \ ··· 135 107 (((tWHR) & 0x3) << 4) | (((tRHW) & 0x3) << 6) | \ 136 108 (((tCAD) & 0x7) << 8)) 137 109 110 + #define NFC_TIMING_CFG2(tCDQSS, tSC, tCLHZ, tCSS, tWC) \ 111 + ((((tCDQSS) & 0x1) << 11) | (((tSC) & 0x3) << 12) | \ 112 + (((tCLHZ) & 0x3) << 14) | (((tCSS) & 0x3) << 16) | \ 113 + (((tWC) & 0x3) << 18)) 114 + 138 115 /* define bit use in NFC_CMD */ 139 116 #define NFC_CMD_LOW_BYTE_MSK GENMASK(7, 0) 140 - #define NFC_CMD_HIGH_BYTE_MSK GENMASK(15, 8) 117 + #define NFC_CMD_HIGH_BYTE_MSK GENMASK(15, 8) /* 15-10 reserved on H6 */ 118 + #define NFC_CMD_ADR_NUM_MSK GENMASK(9, 8) 141 119 #define NFC_CMD(x) (x) 142 120 #define NFC_ADR_NUM_MSK GENMASK(18, 16) 143 121 #define NFC_ADR_NUM(x) (((x) - 1) << 16) ··· 156 122 #define NFC_SEQ BIT(25) 157 123 #define NFC_DATA_SWAP_METHOD BIT(26) 158 124 #define NFC_ROW_AUTO_INC BIT(27) 125 + #define NFC_H6_SEND_RND_CMD2 BIT(27) 159 126 #define NFC_SEND_CMD3 BIT(28) 160 127 #define NFC_SEND_CMD4 BIT(29) 161 128 #define NFC_CMD_TYPE_MSK GENMASK(31, 30) ··· 168 133 #define NFC_READ_CMD_MSK GENMASK(7, 0) 169 134 #define NFC_RND_READ_CMD0_MSK GENMASK(15, 8) 170 135 #define NFC_RND_READ_CMD1_MSK GENMASK(23, 16) 136 + #define NFC_RND_READ_CMD2_MSK GENMASK(31, 24) 171 137 172 138 /* define bit use in NFC_WCMD_SET */ 173 139 #define NFC_PROGRAM_CMD_MSK GENMASK(7, 0) ··· 186 150 #define NFC_RANDOM_DIRECTION(nfc) (nfc->caps->random_dir_mask) 187 151 #define NFC_ECC_MODE_MSK(nfc) (nfc->caps->ecc_mode_mask) 188 152 #define NFC_ECC_MODE(nfc, x) field_prep(NFC_ECC_MODE_MSK(nfc), (x)) 153 + /* RANDOM_PAGE_SIZE: 0: ECC block size 1: page size */ 154 + #define NFC_A23_RANDOM_PAGE_SIZE BIT(11) 155 + #define NFC_H6_RANDOM_PAGE_SIZE BIT(7) 189 156 #define NFC_RANDOM_SEED_MSK GENMASK(30, 16) 190 157 #define NFC_RANDOM_SEED(x) ((x) << 16) 191 158 ··· 203 164 #define NFC_ECC_PAT_FOUND_MSK(nfc) (nfc->caps->pat_found_mask) 204 165 205 166 #define NFC_ECC_ERR_CNT(b, x) (((x) >> (((b) % 4) * 8)) & 0xff) 167 + 168 + #define NFC_USER_DATA_LEN_MSK(step) \ 169 + (0xf << (((step) % NFC_REG_USER_DATA_LEN_CAPACITY) * 4)) 206 170 207 171 #define NFC_DEFAULT_TIMEOUT_MS 1000 208 172 ··· 277 235 * @has_mdma: Use mbus dma mode, otherwise general dma 278 236 * through MBUS on A23/A33 needs extra configuration. 279 237 * @has_ecc_block_512: If the ECC can handle 512B or only 1024B chuncks 238 + * @has_ecc_clk: If the controller needs an ECC clock. 239 + * @has_mbus_clk: If the controller needs a mbus clock. 280 240 * @reg_io_data: I/O data register 281 241 * @reg_ecc_err_cnt: ECC error counter register 282 242 * @reg_user_data: User data register 243 + * @reg_user_data_len: User data length register 283 244 * @reg_spare_area: Spare Area Register 284 245 * @reg_pat_id: Pattern ID Register 285 246 * @reg_pat_found: Data Pattern Status Register ··· 294 249 * @dma_maxburst: DMA maxburst 295 250 * @ecc_strengths: Available ECC strengths array 296 251 * @nstrengths: Size of @ecc_strengths 252 + * @max_ecc_steps: Maximum supported steps for ECC, this is also the 253 + * number of user data registers 254 + * @user_data_len_tab: Table of lenghts supported by USER_DATA_LEN register 255 + * The table index is the value to set in NFC_USER_DATA_LEN 256 + * registers, and the corresponding value is the number of 257 + * bytes to write 258 + * @nuser_data_tab: Size of @user_data_len_tab 297 259 * @sram_size: Size of the NAND controller SRAM 298 260 */ 299 261 struct sunxi_nfc_caps { 300 262 bool has_mdma; 301 263 bool has_ecc_block_512; 264 + bool has_ecc_clk; 265 + bool has_mbus_clk; 302 266 unsigned int reg_io_data; 303 267 unsigned int reg_ecc_err_cnt; 304 268 unsigned int reg_user_data; 269 + unsigned int reg_user_data_len; 305 270 unsigned int reg_spare_area; 306 271 unsigned int reg_pat_id; 307 272 unsigned int reg_pat_found; ··· 323 268 unsigned int dma_maxburst; 324 269 const u8 *ecc_strengths; 325 270 unsigned int nstrengths; 271 + const u8 *user_data_len_tab; 272 + unsigned int nuser_data_tab; 273 + unsigned int max_ecc_steps; 326 274 int sram_size; 327 275 }; 328 276 ··· 337 279 * @regs: NAND controller registers 338 280 * @ahb_clk: NAND controller AHB clock 339 281 * @mod_clk: NAND controller mod clock 282 + * @ecc_clk: NAND controller ECC clock 283 + * @mbus_clk: NAND controller MBUS clock 340 284 * @reset: NAND controller reset line 341 285 * @assigned_cs: bitmask describing already assigned CS lines 342 286 * @clk_rate: NAND controller current clock rate ··· 354 294 void __iomem *regs; 355 295 struct clk *ahb_clk; 356 296 struct clk *mod_clk; 297 + struct clk *ecc_clk; 298 + struct clk *mbus_clk; 357 299 struct reset_control *reset; 358 300 unsigned long assigned_cs; 359 301 unsigned long clk_rate; ··· 836 774 sunxi_nfc_randomize_bbm(nand, page, oob); 837 775 } 838 776 777 + /* 778 + * On H6/H6 the user_data length has to be set in specific registers 779 + * before writing. 780 + */ 781 + static void sunxi_nfc_reset_user_data_len(struct sunxi_nfc *nfc) 782 + { 783 + int loop_step = NFC_REG_USER_DATA_LEN_CAPACITY; 784 + 785 + /* not all SoCs have this register */ 786 + if (!nfc->caps->reg_user_data_len) 787 + return; 788 + 789 + for (int i = 0; i < nfc->caps->max_ecc_steps; i += loop_step) 790 + writel(0, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, i)); 791 + } 792 + 793 + static void sunxi_nfc_set_user_data_len(struct sunxi_nfc *nfc, 794 + int len, int step) 795 + { 796 + bool found = false; 797 + u32 val; 798 + int i; 799 + 800 + /* not all SoCs have this register */ 801 + if (!nfc->caps->reg_user_data_len) 802 + return; 803 + 804 + for (i = 0; i < nfc->caps->nuser_data_tab; i++) { 805 + if (len == nfc->caps->user_data_len_tab[i]) { 806 + found = true; 807 + break; 808 + } 809 + } 810 + 811 + if (!found) { 812 + dev_warn(nfc->dev, 813 + "Unsupported length for user data reg: %d\n", len); 814 + return; 815 + } 816 + 817 + val = readl(nfc->regs + NFC_REG_USER_DATA_LEN(nfc, step)); 818 + 819 + val &= ~NFC_USER_DATA_LEN_MSK(step); 820 + val |= field_prep(NFC_USER_DATA_LEN_MSK(step), i); 821 + writel(val, nfc->regs + NFC_REG_USER_DATA_LEN(nfc, step)); 822 + } 823 + 839 824 static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand, 840 825 const u8 *oob, int step, 841 826 bool bbm, int page) ··· 977 868 if (ret) 978 869 return ret; 979 870 871 + sunxi_nfc_reset_user_data_len(nfc); 872 + sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, 0); 980 873 sunxi_nfc_randomizer_config(nand, page, false); 981 874 sunxi_nfc_randomizer_enable(nand); 982 875 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP, ··· 1089 978 return ret; 1090 979 1091 980 sunxi_nfc_hw_ecc_enable(nand); 981 + sunxi_nfc_reset_user_data_len(nfc); 982 + sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, 0); 1092 983 sunxi_nfc_randomizer_config(nand, page, false); 1093 984 sunxi_nfc_randomizer_enable(nand); 1094 985 ··· 1223 1110 1224 1111 sunxi_nfc_randomizer_config(nand, page, false); 1225 1112 sunxi_nfc_randomizer_enable(nand); 1113 + sunxi_nfc_reset_user_data_len(nfc); 1114 + sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, 0); 1226 1115 sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, 0, bbm, page); 1227 1116 1228 1117 writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | ··· 1469 1354 if (ret) 1470 1355 goto pio_fallback; 1471 1356 1357 + sunxi_nfc_reset_user_data_len(nfc); 1472 1358 for (i = 0; i < ecc->steps; i++) { 1473 1359 const u8 *oob = nand->oob_poi + (i * (ecc->bytes + USER_DATA_SZ)); 1474 1360 1475 1361 sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, i, !i, page); 1362 + sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, i); 1476 1363 } 1477 1364 1478 1365 nand_prog_page_begin_op(nand, page, 0, NULL, 0); ··· 2275 2158 if (irq < 0) 2276 2159 return irq; 2277 2160 2161 + nfc->caps = of_device_get_match_data(dev); 2162 + if (!nfc->caps) 2163 + return -EINVAL; 2164 + 2278 2165 nfc->ahb_clk = devm_clk_get_enabled(dev, "ahb"); 2279 2166 if (IS_ERR(nfc->ahb_clk)) { 2280 2167 dev_err(dev, "failed to retrieve ahb clk\n"); ··· 2291 2170 return PTR_ERR(nfc->mod_clk); 2292 2171 } 2293 2172 2173 + if (nfc->caps->has_ecc_clk) { 2174 + nfc->ecc_clk = devm_clk_get_enabled(dev, "ecc"); 2175 + if (IS_ERR(nfc->ecc_clk)) { 2176 + dev_err(dev, "failed to retrieve ecc clk\n"); 2177 + return PTR_ERR(nfc->ecc_clk); 2178 + } 2179 + } 2180 + 2181 + if (nfc->caps->has_mbus_clk) { 2182 + nfc->mbus_clk = devm_clk_get_enabled(dev, "mbus"); 2183 + if (IS_ERR(nfc->mbus_clk)) { 2184 + dev_err(dev, "failed to retrieve mbus clk\n"); 2185 + return PTR_ERR(nfc->mbus_clk); 2186 + } 2187 + } 2188 + 2294 2189 nfc->reset = devm_reset_control_get_optional_exclusive(dev, "ahb"); 2295 2190 if (IS_ERR(nfc->reset)) 2296 2191 return PTR_ERR(nfc->reset); ··· 2315 2178 if (ret) { 2316 2179 dev_err(dev, "reset err %d\n", ret); 2317 2180 return ret; 2318 - } 2319 - 2320 - nfc->caps = of_device_get_match_data(&pdev->dev); 2321 - if (!nfc->caps) { 2322 - ret = -EINVAL; 2323 - goto out_ahb_reset_reassert; 2324 2181 } 2325 2182 2326 2183 ret = sunxi_nfc_rst(nfc); ··· 2367 2236 16, 24, 28, 32, 40, 48, 56, 60, 64 2368 2237 }; 2369 2238 2239 + static const u8 sunxi_ecc_strengths_h6[] = { 2240 + 16, 24, 28, 32, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80 2241 + }; 2242 + 2243 + static const u8 sunxi_user_data_len_h6[] = { 2244 + 0, 4, 8, 12, 16, 20, 24, 28, 32 2245 + }; 2246 + 2370 2247 static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = { 2371 2248 .has_ecc_block_512 = true, 2372 2249 .reg_io_data = NFC_REG_A10_IO_DATA, ··· 2391 2252 .dma_maxburst = 4, 2392 2253 .ecc_strengths = sunxi_ecc_strengths_a10, 2393 2254 .nstrengths = ARRAY_SIZE(sunxi_ecc_strengths_a10), 2255 + .max_ecc_steps = 16, 2394 2256 .sram_size = 1024, 2395 2257 }; 2396 2258 ··· 2412 2272 .dma_maxburst = 8, 2413 2273 .ecc_strengths = sunxi_ecc_strengths_a10, 2414 2274 .nstrengths = ARRAY_SIZE(sunxi_ecc_strengths_a10), 2275 + .max_ecc_steps = 16, 2415 2276 .sram_size = 1024, 2277 + }; 2278 + 2279 + static const struct sunxi_nfc_caps sunxi_nfc_h616_caps = { 2280 + .has_ecc_clk = true, 2281 + .has_mbus_clk = true, 2282 + .reg_io_data = NFC_REG_A23_IO_DATA, 2283 + .reg_ecc_err_cnt = NFC_REG_H6_ECC_ERR_CNT, 2284 + .reg_user_data = NFC_REG_H6_USER_DATA, 2285 + .reg_user_data_len = NFC_REG_H6_USER_DATA_LEN, 2286 + .reg_spare_area = NFC_REG_H6_SPARE_AREA, 2287 + .reg_pat_id = NFC_REG_H6_PAT_ID, 2288 + .reg_pat_found = NFC_REG_H6_PAT_FOUND, 2289 + .random_en_mask = BIT(5), 2290 + .random_dir_mask = BIT(6), 2291 + .ecc_mode_mask = GENMASK(15, 8), 2292 + .ecc_err_mask = GENMASK(31, 0), 2293 + .pat_found_mask = GENMASK(31, 0), 2294 + .dma_maxburst = 8, 2295 + .ecc_strengths = sunxi_ecc_strengths_h6, 2296 + .nstrengths = ARRAY_SIZE(sunxi_ecc_strengths_h6), 2297 + .user_data_len_tab = sunxi_user_data_len_h6, 2298 + .nuser_data_tab = ARRAY_SIZE(sunxi_user_data_len_h6), 2299 + .max_ecc_steps = 32, 2300 + .sram_size = 8192, 2416 2301 }; 2417 2302 2418 2303 static const struct of_device_id sunxi_nfc_ids[] = { ··· 2448 2283 { 2449 2284 .compatible = "allwinner,sun8i-a23-nand-controller", 2450 2285 .data = &sunxi_nfc_a23_caps, 2286 + }, 2287 + { 2288 + .compatible = "allwinner,sun50i-h616-nand-controller", 2289 + .data = &sunxi_nfc_h616_caps, 2451 2290 }, 2452 2291 { /* sentinel */ } 2453 2292 };