Last active
May 11, 2025 21:08
-
-
Save Noltari/4bd39c64ab33fbd9126375b1ef95c310 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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