mirror of
https://github.com/torvalds/linux.git
synced 2026-05-24 23:22:31 +02:00
mtd: rawnand: qcom: Add NAND controller support for SDX55
SDX55 uses QPIC version 2.0.0 IP for the NAND controller support. In this version, DEV_CMD_* registers are moved to operational state, hence CPU access in BAM mode is restricted. So, skip accessing these registers and also use a different config for reading ONFI parameters. Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20201126085705.48399-3-manivannan.sadhasivam@linaro.org
This commit is contained in:
parent
ce22be4307
commit
b1209582fb
|
|
@ -145,6 +145,7 @@
|
|||
#define OP_PAGE_READ 0x2
|
||||
#define OP_PAGE_READ_WITH_ECC 0x3
|
||||
#define OP_PAGE_READ_WITH_ECC_SPARE 0x4
|
||||
#define OP_PAGE_READ_ONFI_READ 0x5
|
||||
#define OP_PROGRAM_PAGE 0x6
|
||||
#define OP_PAGE_PROGRAM_WITH_ECC 0x7
|
||||
#define OP_PROGRAM_PAGE_SPARE 0x9
|
||||
|
|
@ -460,12 +461,14 @@ struct qcom_nand_host {
|
|||
* @ecc_modes - ecc mode for NAND
|
||||
* @is_bam - whether NAND controller is using BAM
|
||||
* @is_qpic - whether NAND CTRL is part of qpic IP
|
||||
* @qpic_v2 - flag to indicate QPIC IP version 2
|
||||
* @dev_cmd_reg_start - NAND_DEV_CMD_* registers starting offset
|
||||
*/
|
||||
struct qcom_nandc_props {
|
||||
u32 ecc_modes;
|
||||
bool is_bam;
|
||||
bool is_qpic;
|
||||
bool qpic_v2;
|
||||
u32 dev_cmd_reg_start;
|
||||
};
|
||||
|
||||
|
|
@ -1164,7 +1167,13 @@ static int nandc_param(struct qcom_nand_host *host)
|
|||
* in use. we configure the controller to perform a raw read of 512
|
||||
* bytes to read onfi params
|
||||
*/
|
||||
nandc_set_reg(nandc, NAND_FLASH_CMD, OP_PAGE_READ | PAGE_ACC | LAST_PAGE);
|
||||
if (nandc->props->qpic_v2)
|
||||
nandc_set_reg(nandc, NAND_FLASH_CMD, OP_PAGE_READ_ONFI_READ |
|
||||
PAGE_ACC | LAST_PAGE);
|
||||
else
|
||||
nandc_set_reg(nandc, NAND_FLASH_CMD, OP_PAGE_READ |
|
||||
PAGE_ACC | LAST_PAGE);
|
||||
|
||||
nandc_set_reg(nandc, NAND_ADDR0, 0);
|
||||
nandc_set_reg(nandc, NAND_ADDR1, 0);
|
||||
nandc_set_reg(nandc, NAND_DEV0_CFG0, 0 << CW_PER_PAGE
|
||||
|
|
@ -1180,21 +1189,28 @@ static int nandc_param(struct qcom_nand_host *host)
|
|||
| 1 << DEV0_CFG1_ECC_DISABLE);
|
||||
nandc_set_reg(nandc, NAND_EBI2_ECC_BUF_CFG, 1 << ECC_CFG_ECC_DISABLE);
|
||||
|
||||
/* configure CMD1 and VLD for ONFI param probing */
|
||||
nandc_set_reg(nandc, NAND_DEV_CMD_VLD,
|
||||
(nandc->vld & ~READ_START_VLD));
|
||||
nandc_set_reg(nandc, NAND_DEV_CMD1,
|
||||
(nandc->cmd1 & ~(0xFF << READ_ADDR))
|
||||
| NAND_CMD_PARAM << READ_ADDR);
|
||||
/* configure CMD1 and VLD for ONFI param probing in QPIC v1 */
|
||||
if (!nandc->props->qpic_v2) {
|
||||
nandc_set_reg(nandc, NAND_DEV_CMD_VLD,
|
||||
(nandc->vld & ~READ_START_VLD));
|
||||
nandc_set_reg(nandc, NAND_DEV_CMD1,
|
||||
(nandc->cmd1 & ~(0xFF << READ_ADDR))
|
||||
| NAND_CMD_PARAM << READ_ADDR);
|
||||
}
|
||||
|
||||
nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
|
||||
|
||||
nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1);
|
||||
nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld);
|
||||
if (!nandc->props->qpic_v2) {
|
||||
nandc_set_reg(nandc, NAND_DEV_CMD1_RESTORE, nandc->cmd1);
|
||||
nandc_set_reg(nandc, NAND_DEV_CMD_VLD_RESTORE, nandc->vld);
|
||||
}
|
||||
|
||||
nandc_set_read_loc(nandc, 0, 0, 512, 1);
|
||||
|
||||
write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
|
||||
write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
|
||||
if (!nandc->props->qpic_v2) {
|
||||
write_reg_dma(nandc, NAND_DEV_CMD_VLD, 1, 0);
|
||||
write_reg_dma(nandc, NAND_DEV_CMD1, 1, NAND_BAM_NEXT_SGL);
|
||||
}
|
||||
|
||||
nandc->buf_count = 512;
|
||||
memset(nandc->data_buffer, 0xff, nandc->buf_count);
|
||||
|
|
@ -1205,8 +1221,10 @@ static int nandc_param(struct qcom_nand_host *host)
|
|||
nandc->buf_count, 0);
|
||||
|
||||
/* restore CMD1 and VLD regs */
|
||||
write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1, 0);
|
||||
write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1, NAND_BAM_NEXT_SGL);
|
||||
if (!nandc->props->qpic_v2) {
|
||||
write_reg_dma(nandc, NAND_DEV_CMD1_RESTORE, 1, 0);
|
||||
write_reg_dma(nandc, NAND_DEV_CMD_VLD_RESTORE, 1, NAND_BAM_NEXT_SGL);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2772,8 +2790,10 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc)
|
|||
/* kill onenand */
|
||||
if (!nandc->props->is_qpic)
|
||||
nandc_write(nandc, SFLASHC_BURST_CFG, 0);
|
||||
nandc_write(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD),
|
||||
NAND_DEV_CMD_VLD_VAL);
|
||||
|
||||
if (!nandc->props->qpic_v2)
|
||||
nandc_write(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD_VLD),
|
||||
NAND_DEV_CMD_VLD_VAL);
|
||||
|
||||
/* enable ADM or BAM DMA */
|
||||
if (nandc->props->is_bam) {
|
||||
|
|
@ -2793,8 +2813,10 @@ static int qcom_nandc_setup(struct qcom_nand_controller *nandc)
|
|||
}
|
||||
|
||||
/* save the original values of these registers */
|
||||
nandc->cmd1 = nandc_read(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD1));
|
||||
nandc->vld = NAND_DEV_CMD_VLD_VAL;
|
||||
if (!nandc->props->qpic_v2) {
|
||||
nandc->cmd1 = nandc_read(nandc, dev_cmd_reg_addr(nandc, NAND_DEV_CMD1));
|
||||
nandc->vld = NAND_DEV_CMD_VLD_VAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -3052,6 +3074,14 @@ static const struct qcom_nandc_props ipq8074_nandc_props = {
|
|||
.dev_cmd_reg_start = 0x7000,
|
||||
};
|
||||
|
||||
static const struct qcom_nandc_props sdx55_nandc_props = {
|
||||
.ecc_modes = (ECC_BCH_4BIT | ECC_BCH_8BIT),
|
||||
.is_bam = true,
|
||||
.is_qpic = true,
|
||||
.qpic_v2 = true,
|
||||
.dev_cmd_reg_start = 0x7000,
|
||||
};
|
||||
|
||||
/*
|
||||
* data will hold a struct pointer containing more differences once we support
|
||||
* more controller variants
|
||||
|
|
@ -3073,6 +3103,10 @@ static const struct of_device_id qcom_nandc_of_match[] = {
|
|||
.compatible = "qcom,ipq8074-nand",
|
||||
.data = &ipq8074_nandc_props,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,sdx55-nand",
|
||||
.data = &sdx55_nandc_props,
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, qcom_nandc_of_match);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user