FILE
fmsh.c
File preview with syntax highlighting.
linux-6.19.14/drivers/mtd/nand/spi/fmsh.c
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2020-2021 Rockchip Electronics Co., Ltd. 4 * 5 * Author: Dingqiang Lin <jon.lin@rock-chips.com> 6 */ 7 8#include <linux/device.h> 9#include <linux/kernel.h> 10#include <linux/mtd/spinand.h> 11 12#define FM25S01BI3_STATUS_ECC_MASK (7 << 4) 13 #define FM25S01BI3_STATUS_ECC_NO_BITFLIPS (0 << 4) 14 #define FM25S01BI3_STATUS_ECC_1_3_BITFLIPS (1 << 4) 15 #define FM25S01BI3_STATUS_ECC_UNCOR_ERROR (2 << 4) 16 #define FM25S01BI3_STATUS_ECC_4_6_BITFLIPS (3 << 4) 17 #define FM25S01BI3_STATUS_ECC_7_8_BITFLIPS (5 << 4) 18 19#define SPINAND_MFR_FMSH 0xA1 20 21static SPINAND_OP_VARIANTS(read_cache_variants, 22 SPINAND_PAGE_READ_FROM_CACHE_1S_4S_4S_OP(0, 2, NULL, 0, 0), 23 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_4S_OP(0, 1, NULL, 0, 0), 24 SPINAND_PAGE_READ_FROM_CACHE_1S_2S_2S_OP(0, 1, NULL, 0, 0), 25 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_2S_OP(0, 1, NULL, 0, 0), 26 SPINAND_PAGE_READ_FROM_CACHE_FAST_1S_1S_1S_OP(0, 1, NULL, 0, 0), 27 SPINAND_PAGE_READ_FROM_CACHE_1S_1S_1S_OP(0, 1, NULL, 0, 0)); 28 29static SPINAND_OP_VARIANTS(write_cache_variants, 30 SPINAND_PROG_LOAD_1S_1S_4S_OP(true, 0, NULL, 0), 31 SPINAND_PROG_LOAD_1S_1S_1S_OP(true, 0, NULL, 0)); 32 33static SPINAND_OP_VARIANTS(update_cache_variants, 34 SPINAND_PROG_LOAD_1S_1S_4S_OP(false, 0, NULL, 0), 35 SPINAND_PROG_LOAD_1S_1S_1S_OP(false, 0, NULL, 0)); 36 37static int fm25s01a_ooblayout_ecc(struct mtd_info *mtd, int section, 38 struct mtd_oob_region *region) 39{ 40 return -ERANGE; 41} 42 43static int fm25s01a_ooblayout_free(struct mtd_info *mtd, int section, 44 struct mtd_oob_region *region) 45{ 46 if (section) 47 return -ERANGE; 48 49 region->offset = 2; 50 region->length = 62; 51 52 return 0; 53} 54 55static int fm25s01bi3_ecc_get_status(struct spinand_device *spinand, 56 u8 status) 57{ 58 switch (status & FM25S01BI3_STATUS_ECC_MASK) { 59 case FM25S01BI3_STATUS_ECC_NO_BITFLIPS: 60 return 0; 61 62 case FM25S01BI3_STATUS_ECC_UNCOR_ERROR: 63 return -EBADMSG; 64 65 case FM25S01BI3_STATUS_ECC_1_3_BITFLIPS: 66 return 3; 67 68 case FM25S01BI3_STATUS_ECC_4_6_BITFLIPS: 69 return 6; 70 71 case FM25S01BI3_STATUS_ECC_7_8_BITFLIPS: 72 return 8; 73 74 default: 75 break; 76 } 77 78 return -EINVAL; 79} 80 81static int fm25s01bi3_ooblayout_ecc(struct mtd_info *mtd, int section, 82 struct mtd_oob_region *region) 83{ 84 if (section) 85 return -ERANGE; 86 87 region->offset = 64; 88 region->length = 64; 89 90 return 0; 91} 92 93static int fm25s01bi3_ooblayout_free(struct mtd_info *mtd, int section, 94 struct mtd_oob_region *region) 95{ 96 if (section > 3) 97 return -ERANGE; 98 99 region->offset = (16 * section) + 4; 100 region->length = 12; 101 102 return 0; 103} 104 105static const struct mtd_ooblayout_ops fm25s01a_ooblayout = { 106 .ecc = fm25s01a_ooblayout_ecc, 107 .free = fm25s01a_ooblayout_free, 108}; 109 110static const struct mtd_ooblayout_ops fm25s01bi3_ooblayout = { 111 .ecc = fm25s01bi3_ooblayout_ecc, 112 .free = fm25s01bi3_ooblayout_free, 113}; 114 115static const struct spinand_info fmsh_spinand_table[] = { 116 SPINAND_INFO("FM25S01A", 117 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), 118 NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), 119 NAND_ECCREQ(1, 512), 120 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 121 &write_cache_variants, 122 &update_cache_variants), 123 0, 124 SPINAND_ECCINFO(&fm25s01a_ooblayout, NULL)), 125 SPINAND_INFO("FM25S01BI3", 126 SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xd4), 127 NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), 128 NAND_ECCREQ(8, 512), 129 SPINAND_INFO_OP_VARIANTS(&read_cache_variants, 130 &write_cache_variants, 131 &update_cache_variants), 132 SPINAND_HAS_QE_BIT, 133 SPINAND_ECCINFO(&fm25s01bi3_ooblayout, 134 fm25s01bi3_ecc_get_status)), 135}; 136 137static const struct spinand_manufacturer_ops fmsh_spinand_manuf_ops = { 138}; 139 140const struct spinand_manufacturer fmsh_spinand_manufacturer = { 141 .id = SPINAND_MFR_FMSH, 142 .name = "Fudan Micro", 143 .chips = fmsh_spinand_table, 144 .nchips = ARRAY_SIZE(fmsh_spinand_table), 145 .ops = &fmsh_spinand_manuf_ops, 146};
~/
Read-only file preview.