Skip to content

Commit a82990c

Browse files
Sricharan Ramabadhranmiquelraynal
authored andcommitted
mtd: rawnand: qcom: Add read/read_start ops in exec_op path
READ/READ_START opcodes are not set in exec_op path. Fixing that here. While there, Steps to program the controller is common for erase/reset/read/program page. So use a common pattern and pull them under one function. Signed-off-by: Md Sadre Alam <quic_mdalam@quicinc.com> Signed-off-by: Sricharan Ramabadhran <quic_srichara@quicinc.com> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20230818145101.23825-4-quic_mdalam@quicinc.com
1 parent 318207f commit a82990c

File tree

1 file changed

+35
-59
lines changed

1 file changed

+35
-59
lines changed

drivers/mtd/nand/raw/qcom_nandc.c

Lines changed: 35 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -2541,9 +2541,11 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
25412541
return 0;
25422542
}
25432543

2544-
static int qcom_op_cmd_mapping(struct qcom_nand_controller *nandc, u8 opcode,
2544+
static int qcom_op_cmd_mapping(struct nand_chip *chip, u8 opcode,
25452545
struct qcom_op *q_op)
25462546
{
2547+
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
2548+
struct qcom_nand_host *host = to_qcom_nand_host(chip);
25472549
int cmd;
25482550

25492551
switch (opcode) {
@@ -2571,6 +2573,13 @@ static int qcom_op_cmd_mapping(struct qcom_nand_controller *nandc, u8 opcode,
25712573
q_op->flag = OP_PROGRAM_PAGE;
25722574
nandc->exec_opwrite = true;
25732575
break;
2576+
case NAND_CMD_READ0:
2577+
case NAND_CMD_READSTART:
2578+
if (host->use_ecc)
2579+
cmd = OP_PAGE_READ_WITH_ECC;
2580+
else
2581+
cmd = OP_PAGE_READ;
2582+
break;
25742583
default:
25752584
dev_err(nandc->dev, "Opcode not supported: %u\n", opcode);
25762585
return -EOPNOTSUPP;
@@ -2584,7 +2593,6 @@ static int qcom_parse_instructions(struct nand_chip *chip,
25842593
const struct nand_subop *subop,
25852594
struct qcom_op *q_op)
25862595
{
2587-
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
25882596
const struct nand_op_instr *instr = NULL;
25892597
unsigned int op_id;
25902598
int i, ret;
@@ -2597,7 +2605,7 @@ static int qcom_parse_instructions(struct nand_chip *chip,
25972605

25982606
switch (instr->type) {
25992607
case NAND_OP_CMD_INSTR:
2600-
ret = qcom_op_cmd_mapping(nandc, instr->ctx.cmd.opcode, q_op);
2608+
ret = qcom_op_cmd_mapping(chip, instr->ctx.cmd.opcode, q_op);
26012609
if (ret < 0)
26022610
return ret;
26032611

@@ -2791,13 +2799,25 @@ static int qcom_misc_cmd_type_exec(struct nand_chip *chip, const struct nand_sub
27912799
struct qcom_nand_host *host = to_qcom_nand_host(chip);
27922800
struct qcom_op q_op = {};
27932801
int ret;
2802+
int instrs = 1;
27942803

27952804
ret = qcom_parse_instructions(chip, subop, &q_op);
27962805
if (ret)
27972806
return ret;
27982807

2799-
if (q_op.flag == OP_PROGRAM_PAGE)
2808+
if (q_op.flag == OP_PROGRAM_PAGE) {
28002809
goto wait_rdy;
2810+
} else if (q_op.cmd_reg == OP_BLOCK_ERASE) {
2811+
q_op.cmd_reg |= PAGE_ACC | LAST_PAGE;
2812+
nandc_set_reg(chip, NAND_ADDR0, q_op.addr1_reg);
2813+
nandc_set_reg(chip, NAND_ADDR1, q_op.addr2_reg);
2814+
nandc_set_reg(chip, NAND_DEV0_CFG0,
2815+
host->cfg0_raw & ~(7 << CW_PER_PAGE));
2816+
nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw);
2817+
instrs = 3;
2818+
} else {
2819+
return 0;
2820+
}
28012821

28022822
nandc->buf_count = 0;
28032823
nandc->buf_start = 0;
@@ -2809,9 +2829,12 @@ static int qcom_misc_cmd_type_exec(struct nand_chip *chip, const struct nand_sub
28092829
nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg);
28102830
nandc_set_reg(chip, NAND_EXEC_CMD, 1);
28112831

2812-
write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
2813-
write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
2832+
write_reg_dma(nandc, NAND_FLASH_CMD, instrs, NAND_BAM_NEXT_SGL);
2833+
(q_op.cmd_reg == OP_BLOCK_ERASE) ? write_reg_dma(nandc, NAND_DEV0_CFG0,
2834+
2, NAND_BAM_NEXT_SGL) : read_reg_dma(nandc,
2835+
NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
28142836

2837+
write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
28152838
read_reg_dma(nandc, NAND_FLASH_STATUS, 1, NAND_BAM_NEXT_SGL);
28162839

28172840
ret = submit_descs(nandc);
@@ -2925,56 +2948,7 @@ static int qcom_param_page_type_exec(struct nand_chip *chip, const struct nand_
29252948
return ret;
29262949
}
29272950

2928-
static int qcom_erase_cmd_type_exec(struct nand_chip *chip, const struct nand_subop *subop)
2929-
{
2930-
struct qcom_nand_host *host = to_qcom_nand_host(chip);
2931-
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
2932-
struct qcom_op q_op = {};
2933-
int ret;
2934-
2935-
ret = qcom_parse_instructions(chip, subop, &q_op);
2936-
if (ret)
2937-
return ret;
2938-
2939-
q_op.cmd_reg |= PAGE_ACC | LAST_PAGE;
2940-
2941-
nandc->buf_count = 0;
2942-
nandc->buf_start = 0;
2943-
host->use_ecc = false;
2944-
clear_read_regs(nandc);
2945-
clear_bam_transaction(nandc);
2946-
2947-
nandc_set_reg(chip, NAND_FLASH_CMD, q_op.cmd_reg);
2948-
nandc_set_reg(chip, NAND_ADDR0, q_op.addr1_reg);
2949-
nandc_set_reg(chip, NAND_ADDR1, q_op.addr2_reg);
2950-
nandc_set_reg(chip, NAND_DEV0_CFG0,
2951-
host->cfg0_raw & ~(7 << CW_PER_PAGE));
2952-
nandc_set_reg(chip, NAND_DEV0_CFG1, host->cfg1_raw);
2953-
nandc_set_reg(chip, NAND_EXEC_CMD, 1);
2954-
2955-
write_reg_dma(nandc, NAND_FLASH_CMD, 3, NAND_BAM_NEXT_SGL);
2956-
write_reg_dma(nandc, NAND_DEV0_CFG0, 2, NAND_BAM_NEXT_SGL);
2957-
write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
2958-
2959-
ret = submit_descs(nandc);
2960-
if (ret) {
2961-
dev_err(nandc->dev, "failure in submitting erase descriptor\n");
2962-
goto err_out;
2963-
}
2964-
2965-
ret = qcom_wait_rdy_poll(chip, q_op.rdy_timeout_ms);
2966-
if (ret)
2967-
goto err_out;
2968-
2969-
err_out:
2970-
return ret;
2971-
}
2972-
29732951
static const struct nand_op_parser qcom_op_parser = NAND_OP_PARSER(
2974-
NAND_OP_PARSER_PATTERN(
2975-
qcom_misc_cmd_type_exec,
2976-
NAND_OP_PARSER_PAT_CMD_ELEM(false),
2977-
NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
29782952
NAND_OP_PARSER_PATTERN(
29792953
qcom_read_id_type_exec,
29802954
NAND_OP_PARSER_PAT_CMD_ELEM(false),
@@ -2991,10 +2965,10 @@ static const struct nand_op_parser qcom_op_parser = NAND_OP_PARSER(
29912965
NAND_OP_PARSER_PAT_WAITRDY_ELEM(true),
29922966
NAND_OP_PARSER_PAT_DATA_IN_ELEM(false, 512)),
29932967
NAND_OP_PARSER_PATTERN(
2994-
qcom_erase_cmd_type_exec,
2995-
NAND_OP_PARSER_PAT_CMD_ELEM(false),
2996-
NAND_OP_PARSER_PAT_ADDR_ELEM(false, MAX_ADDRESS_CYCLE),
2968+
qcom_misc_cmd_type_exec,
29972969
NAND_OP_PARSER_PAT_CMD_ELEM(false),
2970+
NAND_OP_PARSER_PAT_ADDR_ELEM(true, MAX_ADDRESS_CYCLE),
2971+
NAND_OP_PARSER_PAT_CMD_ELEM(true),
29982972
NAND_OP_PARSER_PAT_WAITRDY_ELEM(false)),
29992973
);
30002974

@@ -3015,7 +2989,9 @@ static int qcom_check_op(struct nand_chip *chip,
30152989
instr->ctx.cmd.opcode != NAND_CMD_ERASE1 &&
30162990
instr->ctx.cmd.opcode != NAND_CMD_ERASE2 &&
30172991
instr->ctx.cmd.opcode != NAND_CMD_STATUS &&
3018-
instr->ctx.cmd.opcode != NAND_CMD_PAGEPROG)
2992+
instr->ctx.cmd.opcode != NAND_CMD_PAGEPROG &&
2993+
instr->ctx.cmd.opcode != NAND_CMD_READ0 &&
2994+
instr->ctx.cmd.opcode != NAND_CMD_READSTART)
30192995
return -EOPNOTSUPP;
30202996
break;
30212997
default:

0 commit comments

Comments
 (0)