Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save Noltari/4bd39c64ab33fbd9126375b1ef95c310 to your computer and use it in GitHub Desktop.

Select an option

Save Noltari/4bd39c64ab33fbd9126375b1ef95c310 to your computer and use it in GitHub Desktop.
diff -uprN openwrt-6.12/drivers/mtd/nand/raw/brcmnand/brcmnand.c openwrt-legacy-exec_op/drivers/mtd/nand/raw/brcmnand/brcmnand.c
--- openwrt-6.12/drivers/mtd/nand/raw/brcmnand/brcmnand.c 2025-05-10 10:08:43.434026960 +0200
+++ openwrt-legacy-exec_op/drivers/mtd/nand/raw/brcmnand/brcmnand.c 2025-05-11 23:02:25.170601490 +0200
@@ -2490,14 +2490,115 @@ static int brcmnand_op_is_reset(const st
return 0;
}
+static int brcmnand_exec_instructions(struct nand_chip *chip,
+ const struct nand_operation *op)
+{
+ struct brcmnand_host *host = nand_get_controller_data(chip);
+ unsigned int i;
+ int ret = 0;
+
+ for (i = 0; i < op->ninstrs; i++) {
+ ret = brcmnand_exec_instr(host, i, op);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static int brcmnand_exec_instructions_legacy(struct nand_chip *chip,
+ const struct nand_operation *op)
+{
+ struct mtd_info *mtd = nand_to_mtd(chip);
+ struct brcmnand_host *host = nand_get_controller_data(chip);
+ struct brcmnand_controller *ctrl = host->ctrl;
+ const struct nand_op_instr *instr;
+ unsigned int i, j;
+ int cmd = CMD_NULL;
+ int ret = 0;
+
+ for (i = 0; i < op->ninstrs; i++) {
+ instr = &op->instrs[i];
+
+ if (instr->type == NAND_OP_CMD_INSTR) {
+ if (instr->ctx.cmd.opcode == NAND_CMD_READID)
+ cmd = CMD_DEVICE_ID_READ;
+ else if (instr->ctx.cmd.opcode == NAND_CMD_READOOB)
+ cmd = CMD_SPARE_AREA_READ;
+ else if (instr->ctx.cmd.opcode == NAND_CMD_ERASE1)
+ cmd = CMD_BLOCK_ERASE;
+ else
+ cmd = CMD_NULL;
+
+ if (cmd == CMD_NULL) {
+ dev_err(ctrl->dev, "unsupported cmd=%d\n",
+ instr->ctx.cmd.opcode);
+ ret = -ENOTSUPP;
+ break;
+ }
+ } else if (instr->type == NAND_OP_ADDR_INSTR) {
+ u64 addr = 0;
+
+ if (instr->ctx.addr.naddrs > 8) {
+ dev_err(ctrl->dev, "unsupported naddrs=%u\n",
+ instr->ctx.addr.naddrs);
+ ret = -ENOTSUPP;
+ break;
+ }
+
+ for (j = 0; j < instr->ctx.addr.naddrs; j++)
+ addr |= (instr->ctx.addr.addrs[j]) << (j << 3);
+
+ brcmnand_set_cmd_addr(mtd, addr);
+ brcmnand_send_cmd(host, cmd);
+ brcmnand_waitfunc(chip);
+ } else if (instr->type == NAND_OP_DATA_IN_INSTR) {
+ u8 *in = instr->ctx.data.buf.in;
+
+ if (cmd == CMD_DEVICE_ID_READ) {
+ u32 val;
+
+ if (instr->ctx.data.len > 8) {
+ dev_err(ctrl->dev, "unsupported len=%u\n",
+ instr->ctx.data.len);
+ ret = -ENOTSUPP;
+ break;
+ }
+
+ for (j = 0; j < instr->ctx.data.len; j++)
+ {
+ if (j == 0)
+ val = brcmnand_read_reg(ctrl, BRCMNAND_ID);
+ else if (j == 4)
+ val = brcmnand_read_reg(ctrl, BRCMNAND_ID_EXT);
+
+ in[j] = (val >> (24 - ((j % 4) << 3))) & 0xff;
+ }
+ } else if (cmd == CMD_SPARE_AREA_READ) {
+ for (j = 0; j < instr->ctx.data.len; j++)
+ in[j] = oob_reg_read(ctrl, j);
+ }
+
+ cmd = CMD_NULL;
+ } else if (instr->type == NAND_OP_WAITRDY_INSTR) {
+ ret = bcmnand_ctrl_poll_status(host, NAND_CTRL_RDY, NAND_CTRL_RDY, 0);
+ } else {
+ dev_err(ctrl->dev, "unsupported instruction type: %d\n", instr->type);
+ ret = -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
static int brcmnand_exec_op(struct nand_chip *chip,
const struct nand_operation *op,
bool check_only)
{
struct brcmnand_host *host = nand_get_controller_data(chip);
+ struct brcmnand_controller *ctrl = host->ctrl;
struct mtd_info *mtd = nand_to_mtd(chip);
u8 *status;
- unsigned int i;
int ret = 0;
if (check_only)
@@ -2525,11 +2626,10 @@ static int brcmnand_exec_op(struct nand_
if (op->deassert_wp)
brcmnand_wp(mtd, 0);
- for (i = 0; i < op->ninstrs; i++) {
- ret = brcmnand_exec_instr(host, i, op);
- if (ret)
- break;
- }
+ if (ctrl->nand_version >= 0x500)
+ brcmnand_exec_instructions(chip, op);
+ else
+ brcmnand_exec_instructions_legacy(chip, op);
if (op->deassert_wp)
brcmnand_wp(mtd, 1);
typedef struct NandCtrlRegs {
uint32 NandRevision; /* 00: NAND Revision */
uint32 NandCmdStart; /* 04: Nand Flash Command Start */
#define NCMD_MASK 0x1f000000
#define NCMD_LOW_LEVEL_OP 0x10000000
#define NCMD_PARAM_CHG_COL 0x0f000000
#define NCMD_PARAM_READ 0x0e000000
#define NCMD_BLK_LOCK_STS 0x0d000000
#define NCMD_BLK_UNLOCK 0x0c000000
#define NCMD_BLK_LOCK_DOWN 0x0b000000
#define NCMD_BLK_LOCK 0x0a000000
#define NCMD_FLASH_RESET 0x09000000
#define NCMD_BLOCK_ERASE 0x08000000
#define NCMD_DEV_ID_READ 0x07000000
#define NCMD_COPY_BACK 0x06000000
#define NCMD_PROGRAM_SPARE 0x05000000
#define NCMD_PROGRAM_PAGE 0x04000000
#define NCMD_STS_READ 0x03000000
#define NCMD_SPARE_READ 0x02000000
#define NCMD_PAGE_READ 0x01000000
uint32 NandCmdExtAddr; /* 08: Nand Flash Command Extended Address */
uint32 NandCmdAddr; /* 0C: Nand Flash Command Address */
uint32 NandCmdEndAddr; /* 10: Nand Flash Command End Address */
uint32 NandNandBootConfig; /* 14: Nand Flash Boot Config */
#define NBC_CS_LOCK 0x80000000
#define NBC_AUTO_DEV_ID_CFG 0x40000000
#define NBC_WR_PROT_BLK0 0x10000000
#define NBC_EBI_CS7_USES_NAND (1<<15)
#define NBC_EBI_CS6_USES_NAND (1<<14)
#define NBC_EBI_CS5_USES_NAND (1<<13)
#define NBC_EBI_CS4_USES_NAND (1<<12)
#define NBC_EBI_CS3_USES_NAND (1<<11)
#define NBC_EBI_CS2_USES_NAND (1<<10)
#define NBC_EBI_CS1_USES_NAND (1<< 9)
#define NBC_EBI_CS0_USES_NAND (1<< 8)
#define NBC_EBC_CS7_SEL (1<< 7)
#define NBC_EBC_CS6_SEL (1<< 6)
#define NBC_EBC_CS5_SEL (1<< 5)
#define NBC_EBC_CS4_SEL (1<< 4)
#define NBC_EBC_CS3_SEL (1<< 3)
#define NBC_EBC_CS2_SEL (1<< 2)
#define NBC_EBC_CS1_SEL (1<< 1)
#define NBC_EBC_CS0_SEL (1<< 0)
uint32 NandCsNandXor; /* 18: Nand Flash EBI CS Address XOR with */
/* 1FC0 Control */
uint32 NandReserved1; // 1C
uint32 NandSpareAreaReadOfs0; /* 20: Nand Flash Spare Area Read Bytes 0-3 */
uint32 NandSpareAreaReadOfs4; /* 24: Nand Flash Spare Area Read Bytes 4-7 */
uint32 NandSpareAreaReadOfs8; /* 28: Nand Flash Spare Area Read Bytes 8-11 */
uint32 NandSpareAreaReadOfsC; /* 2C: Nand Flash Spare Area Read Bytes 12-15*/
uint32 NandSpareAreaWriteOfs0; /* 30: Nand Flash Spare Area Write Bytes 0-3 */
uint32 NandSpareAreaWriteOfs4; /* 34: Nand Flash Spare Area Write Bytes 4-7 */
uint32 NandSpareAreaWriteOfs8; /* 38: Nand Flash Spare Area Write Bytes 8-11*/
uint32 NandSpareAreaWriteOfsC; /* 3C: Nand Flash Spare Area Write Bytes12-15*/
uint32 NandAccControl; /* 40: Nand Flash Access Control */
#define NAC_RD_ECC_EN 0x80000000
#define NAC_WR_ECC_EN 0x40000000
#define NAC_RD_ECC_BLK0_EN 0x20000000
#define NAC_FAST_PGM_RDIN 0x10000000
#define NAC_RD_ERASED_ECC_EN 0x08000000
#define NAC_PARTIAL_PAGE_EN 0x04000000
#define NAC_WR_PREEMPT_EN 0x02000000
#define NAC_PAGE_HIT_EN 0x01000000
#define NAC_ECC_LVL_0_SHIFT 20
#define NAC_ECC_LVL_0_MASK 0x00f00000
#define NAC_ECC_LVL_SHIFT 16
#define NAC_ECC_LVL_MASK 0x000f0000
#define NAC_ECC_LVL_DISABLE 0
#define NAC_ECC_LVL_BCH_1 1
#define NAC_ECC_LVL_BCH_2 2
#define NAC_ECC_LVL_BCH_3 3
#define NAC_ECC_LVL_BCH_4 4
#define NAC_ECC_LVL_BCH_5 5
#define NAC_ECC_LVL_BCH_6 6
#define NAC_ECC_LVL_BCH_7 7
#define NAC_ECC_LVL_BCH_8 8
#define NAC_ECC_LVL_BCH_9 9
#define NAC_ECC_LVL_BCH_10 10
#define NAC_ECC_LVL_BCH_11 11
#define NAC_ECC_LVL_BCH_12 12
#define NAC_ECC_LVL_RESVD_1 13
#define NAC_ECC_LVL_RESVD_2 14
#define NAC_ECC_LVL_HAMMING 15
#define NAC_SPARE_SZ_0_SHIFT 8
#define NAC_SPARE_SZ_0_MASK 0x00003f00
#define NAC_SPARE_SZ_SHIFT 0
#define NAC_SPARE_SZ_MASK 0x0000003f
uint32 NandReserved2; // 44
uint32 NandConfig; /* 48: Nand Flash Config */
#define NC_CONFIG_LOCK 0x80000000
#define NC_BLK_SIZE_MASK 0x70000000
#define NC_BLK_SIZE_2048K 0x60000000
#define NC_BLK_SIZE_1024K 0x50000000
#define NC_BLK_SIZE_512K 0x30000000
#define NC_BLK_SIZE_128K 0x10000000
#define NC_BLK_SIZE_16K 0x00000000
#define NC_BLK_SIZE_8K 0x20000000
#define NC_BLK_SIZE_256K 0x40000000
#define NC_DEV_SIZE_MASK 0x0f000000
#define NC_DEV_SIZE_SHIFT 24
#define NC_DEV_WIDTH_MASK 0x00800000
#define NC_DEV_WIDTH_16 0x00800000
#define NC_DEV_WIDTH_8 0x00000000
#define NC_PG_SIZE_MASK 0x00300000
#define NC_PG_SIZE_8K 0x00300000
#define NC_PG_SIZE_4K 0x00200000
#define NC_PG_SIZE_2K 0x00100000
#define NC_PG_SIZE_512B 0x00000000
#define NC_FUL_ADDR_MASK 0x00070000
#define NC_FUL_ADDR_SHIFT 16
#define NC_BLK_ADDR_MASK 0x00000700
#define NC_BLK_ADDR_SHIFT 8
uint32 NandReserved3; // 4C
uint32 NandTiming1; /* 50: Nand Flash Timing Parameters 1 */
#define NT_TREH_MASK 0x000f0000
#define NT_TREH_SHIFT 16
#define NT_TRP_MASK 0x00f00000
#define NT_TRP_SHIFT 20
uint32 NandTiming2; /* 54: Nand Flash Timing Parameters 2 */
#define NT_TREAD_MASK 0x0000000f
#define NT_TREAD_SHIFT 0
uint32 NandSemaphore; /* 58: Semaphore */
uint32 NandReserved4; // 5C
uint32 NandFlashDeviceId; /* 60: Nand Flash Device ID */
uint32 NandFlashDeviceIdExt; /* 64: Nand Flash Extended Device ID */
uint32 NandBlockLockStatus; /* 68: Nand Flash Block Lock Status */
uint32 NandIntfcStatus; /* 6C: Nand Flash Interface Status */
#define NIS_CTLR_READY 0x80000000
#define NIS_FLASH_READY 0x40000000
#define NIS_CACHE_VALID 0x20000000
#define NIS_SPARE_VALID 0x10000000
#define NIS_FLASH_STS_MASK 0x000000ff
#define NIS_WRITE_PROTECT 0x00000080
#define NIS_DEV_READY 0x00000040
#define NIS_PGM_ERASE_ERROR 0x00000001
uint32 NandEccCorrExtAddr; /* 70: ECC Correctable Error Extended Address*/
uint32 NandEccCorrAddr; /* 74: ECC Correctable Error Address */
uint32 NandEccUncExtAddr; /* 78: ECC Uncorrectable Error Extended Addr */
uint32 NandEccUncAddr; /* 7C: ECC Uncorrectable Error Address */
uint32 NandReadErrorCount; /* 80: Read Error Count */
uint32 NandCorrStatThreshold; /* 84: Correctable Error Reporting Threshold */
uint32 NandOnfiStatus; /* 88: ONFI Status */
uint32 NandOnfiDebugData; /* 8C: ONFI Debug Data */
uint32 NandFlashReadExtAddr; /* 90: Flash Read Data Extended Address */
uint32 NandFlashReadAddr; /* 94: Flash Read Data Address */
uint32 NandProgramPageExtAddr; /* 98: Page Program Extended Address */
uint32 NandProgramPageAddr; /* 9C: Page Program Address */
uint32 NandCopyBackExtAddr; /* A0: Copy Back Extended Address */
uint32 NandCopyBackAddr; /* A4: Copy Back Address */
uint32 NandBlockEraseExtAddr; /* A8: Block Erase Extended Address */
uint32 NandBlockEraseAddr; /* AC: Block Erase Address */
uint32 NandInvReadExtAddr; /* B0: Flash Invalid Data Extended Address */
uint32 NandInvReadAddr; /* B4: Flash Invalid Data Address */
uint32 NandReserved5[2]; // B8
uint32 NandBlkWrProtect; /* C0: Block Write Protect Enable and Size */
/* for EBI_CS0b */
uint32 NandReserved6[3]; // C4
uint32 NandAccControlCs1; /* D0: Nand Flash Access Control */
uint32 NandConfigCs1; /* D4: Nand Flash Config */
uint32 NandTiming1Cs1; /* D8: Nand Flash Timing Parameters 1 */
uint32 NandTiming2Cs1; /* DC: Nand Flash Timing Parameters 2 */
uint32 NandAccControlCs2; /* E0: Nand Flash Access Control */
uint32 NandConfigCs2; /* E4: Nand Flash Config */
uint32 NandTiming1Cs2; /* E8: Nand Flash Timing Parameters 1 */
uint32 NandTiming2Cs2; /* EC: Nand Flash Timing Parameters 2 */
uint32 NandReserved7[16]; // F0
uint32 NandSpareAreaReadOfs10; /* 130: Nand Flash Spare Area Read Bytes 16-19 */
uint32 NandSpareAreaReadOfs14; /* 134: Nand Flash Spare Area Read Bytes 20-23 */
uint32 NandSpareAreaReadOfs18; /* 138: Nand Flash Spare Area Read Bytes 24-27 */
uint32 NandSpareAreaReadOfs1C; /* 13C: Nand Flash Spare Area Read Bytes 28-31 */
uint32 NandReserved8[14]; // 140
uint32 NandLlOpNand; /* 178: Flash Low Level Operation */
uint32 NandLlRdData; /* 17C: Nand Flash Low Level Read Data */
} NandCtrlRegs;
/* BRCMNAND v3.3-v4.0 */
static const u16 brcmnand_regs_v33[] = {
[BRCMNAND_CMD_START] = 0x04,
[BRCMNAND_CMD_EXT_ADDRESS] = 0x08,
[BRCMNAND_CMD_ADDRESS] = 0x0c,
[BRCMNAND_INTFC_STATUS] = 0x6c,
[BRCMNAND_CS_SELECT] = 0x14,
[BRCMNAND_CS_XOR] = 0x18,
[BRCMNAND_LL_OP] = 0xec,
[BRCMNAND_CS0_BASE] = 0x40,
[BRCMNAND_CS1_BASE] = 0xbc,
[BRCMNAND_CORR_THRESHOLD] = 0x84,
[BRCMNAND_CORR_THRESHOLD_EXT] = 0,
[BRCMNAND_UNCORR_COUNT] = 0,
[BRCMNAND_CORR_COUNT] = 0,
[BRCMNAND_CORR_EXT_ADDR] = 0x70,
[BRCMNAND_CORR_ADDR] = 0x74,
[BRCMNAND_UNCORR_EXT_ADDR] = 0x78,
[BRCMNAND_UNCORR_ADDR] = 0x7c,
[BRCMNAND_SEMAPHORE] = 0x58,
[BRCMNAND_ID] = 0x60,
[BRCMNAND_ID_EXT] = 0x64,
[BRCMNAND_LL_RDATA] = 0xf0,
[BRCMNAND_OOB_READ_BASE] = 0x20,
[BRCMNAND_OOB_READ_10_BASE] = 0xdc,
[BRCMNAND_OOB_WRITE_BASE] = 0x30,
[BRCMNAND_OOB_WRITE_10_BASE] = 0,
[BRCMNAND_FC_BASE] = 0x200,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment