[PATCH v5 5/7] spi: spi-qpic: add driver for QCOM SPI NAND flash Interface
Md Sadre Alam
quic_mdalam at quicinc.com
Mon May 20 08:25:58 PDT 2024
On 5/20/2024 6:13 PM, Miquel Raynal wrote:
> Hi,
>
>>>> +static int qcom_spi_io_op(struct qcom_nand_controller *snandc, const struct spi_mem_op *op)
>>>> +{
>>>> + int ret, val, opcode;
>>>> + bool copy = false, copy_ftr = false;
>>>> +
>>>> + ret = qcom_spi_send_cmdaddr(snandc, op);
>>>> + if (ret)
>>>> + return ret;
>>>> +
>>>> + snandc->buf_count = 0;
>>>> + snandc->buf_start = 0;
>>>> + qcom_clear_read_regs(snandc);
>>>> + qcom_clear_bam_transaction(snandc);
>>>> + opcode = op->cmd.opcode;
>>>> +
>>>> + switch (opcode) {
>>>> + case SPINAND_READID:
>>>> + snandc->buf_count = 4;
>>>> + qcom_read_reg_dma(snandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL);
>>>> + copy = true;
>>>> + break;
>>>> + case SPINAND_GET_FEATURE:
>>>> + snandc->buf_count = 4;
>>>> + qcom_read_reg_dma(snandc, NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL);
>>>> + copy_ftr = true;
>>>> + break;
>>>> + case SPINAND_SET_FEATURE:
>>>> + snandc->regs->flash_feature = *(u32 *)op->data.buf.out;
>>>> + qcom_write_reg_dma(snandc, &snandc->regs->flash_feature,
>>>> + NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL);
>>>> + break;
>>>> + default:
>>>> + return 0;
>>>
>>> No error state?
>> We can't return return error here , since this API is not for checking supported command.
>
> I no longer remember exactly where this is called, but if there are
> possible unhandled cases, I want an error to be returned.
Ok
>
>> We can return error only if we submitted the descriptor. That already we are handling.
>
> ...
>
>>>> --- a/include/linux/mtd/nand-qpic-common.h
>>>> +++ b/include/linux/mtd/nand-qpic-common.h
>>>> @@ -315,11 +315,56 @@ struct nandc_regs {
>>>> __le32 read_location_last1;
>>>> __le32 read_location_last2;
>>>> __le32 read_location_last3;
>>>> + __le32 spi_cfg;
>>>> + __le32 num_addr_cycle;
>>>> + __le32 busy_wait_cnt;
>>>> + __le32 flash_feature;
>>>> >> __le32 erased_cw_detect_cfg_clr;
>>>> __le32 erased_cw_detect_cfg_set;
>>>> };
>>>> >> +/*
>>>> + * ECC state struct
>>>> + * @corrected: ECC corrected
>>>> + * @bitflips: Max bit flip
>>>> + * @failed: ECC failed
>>>> + */
>>>> +struct qcom_ecc_stats {
>>>> + u32 corrected;
>>>> + u32 bitflips;
>>>> + u32 failed;
>>>> +};
>>>> +
>>>> +struct qpic_ecc {
>>>> + struct device *dev;
>>>> + const struct qpic_ecc_caps *caps;
>>>> + struct completion done;
>>>> + u32 sectors;
>>>> + u8 *eccdata;
>>>> + bool use_ecc;
>>>> + u32 ecc_modes;
>>>> + int ecc_bytes_hw;
>>>> + int spare_bytes;
>>>> + int bbm_size;
>>>> + int ecc_mode;
>>>> + int bytes;
>>>> + int steps;
>>>> + int step_size;
>>>> + int strength;
>>>> + int cw_size;
>>>> + int cw_data;
>>>> + u32 cfg0, cfg1;
>>>> + u32 cfg0_raw, cfg1_raw;
>>>> + u32 ecc_buf_cfg;
>>>> + u32 ecc_bch_cfg;
>>>> + u32 clrflashstatus;
>>>> + u32 clrreadstatus;
>>>> + bool bch_enabled;
>>>> +};
>>>> +
>>>> +struct qpic_ecc;
>>>> +
>>>> /*
>>>> * NAND controller data struct
>>>> *
>>>> @@ -329,6 +374,7 @@ struct nandc_regs {
>>>> *
>>>> * @core_clk: controller clock
>>>> * @aon_clk: another controller clock
>>>> + * @iomacro_clk: io macro clock
>>>> *
>>>> * @regs: a contiguous chunk of memory for DMA register
>>>> * writes. contains the register values to be
>>>> @@ -338,6 +384,7 @@ struct nandc_regs {
>>>> * initialized via DT match data
>>>> *
>>>> * @controller: base controller structure
>>>> + * @ctlr: spi controller structure
>>>> * @host_list: list containing all the chips attached to the
>>>> * controller
>>>> *
>>>> @@ -375,6 +422,7 @@ struct qcom_nand_controller {
>>>> >> struct clk *core_clk;
>>>> struct clk *aon_clk;
>>>> + struct clk *iomacro_clk;
>>>> >> struct nandc_regs *regs;
>>>> struct bam_transaction *bam_txn;
>>>> @@ -382,6 +430,7 @@ struct qcom_nand_controller {
>>>> const struct qcom_nandc_props *props;
>>>> >> struct nand_controller controller;
>>>> + struct spi_controller *ctlr;
>>>> struct list_head host_list;
>>>> >> union {
>>>> @@ -418,6 +467,21 @@ struct qcom_nand_controller {
>>>> >> u32 cmd1, vld;
>>>> bool exec_opwrite;
>>>> + struct qpic_ecc *ecc;
>>>> + struct qcom_ecc_stats ecc_stats;
>>>> + struct nand_ecc_engine ecc_eng;
>>>> + u8 *data_buf;
>>>> + u8 *oob_buf;
>>>> + u32 wlen;
>>>> + u32 addr1;
>>>> + u32 addr2;
>>>> + u32 cmd;
>>>> + u32 num_cw;
>>>> + u32 pagesize;
>>>> + bool oob_rw;
>>>> + bool page_rw;
>>>> + bool raw_rw;
>>>> + bool read_last_cw;
>>>> };
>>>
>>> If all these definitions are only used by the spi controller, I don't
>>> see why you want to put them in the common file.
>> We are using qcom_nand_controller{..} structure as common b/w raw nand
>> and spi nand. These all variables will be used by spi nand only , but
>> qcom_nand_controller structure is passed across all the SPI API, thats
>> why define these all variables inside qcom_nand_controller structure.
>> so that i can access directlty.
>
> Maybe you can move the spi-nand specific variables in a struct, and the
> raw NAND specific variables in another, and then use an enum in this
> structure. This way only the useful fields are available. Or maybe you
> can have two pointers and only populate the relevant one from the
> relevant driver with the fields that are missing. But this is a generic
> include, so don't put specific fields there just because it is
> convenient.
Ok , will do in next patch.
>
> Thanks,
> Miquèl
More information about the linux-mtd
mailing list