Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7e9feb9 authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "mtd: msm_qpic_nand: Add support to read one codeword"

parents 732b0b1b ba507073
Loading
Loading
Loading
Loading
+67 −19
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@
#define MAX_DESC 16
#define SMEM_AARM_PARTITION_TABLE 9
#define SMEM_APPS 0
#define ONE_CODEWORD_SIZE 516

static bool enable_euclean;
static bool enable_perfstats;

@@ -1183,10 +1185,16 @@ static int msm_nand_validate_mtd_params(struct mtd_info *mtd, bool read,
			err = -EINVAL;
			goto out;
		}
		args->page_count = ops->len / (mtd->writesize + mtd->oobsize);
		if (ops->len <= ONE_CODEWORD_SIZE)
			args->page_count = 1;
		else
			args->page_count = ops->len /
				(mtd->writesize + mtd->oobsize);

	} else if (ops->mode == MTD_OPS_AUTO_OOB) {
		if (ops->datbuf && (ops->len % mtd->writesize) != 0) {
		if (ops->datbuf && (ops->len %
			((ops->len <= ONE_CODEWORD_SIZE) ?
			ONE_CODEWORD_SIZE : mtd->writesize)) != 0) {
			/* when ops->datbuf is NULL, ops->len can be ooblen */
			pr_err("unsupported data len %d for AUTO mode\n",
					ops->len);
@@ -1199,6 +1207,9 @@ static int msm_nand_validate_mtd_params(struct mtd_info *mtd, bool read,
			if ((args->page_count == 0) && (ops->ooblen))
				args->page_count = 1;
		} else if (ops->datbuf) {
			if (ops->len <= ONE_CODEWORD_SIZE)
				args->page_count = 1;
			else
				args->page_count = ops->len / mtd->writesize;
		}
	}
@@ -1245,12 +1256,20 @@ static void msm_nand_update_rw_reg_data(struct msm_nand_chip *chip,
					struct msm_nand_rw_params *args,
					struct msm_nand_rw_reg_data *data)
{
	/*
	 * While reading one codeword, CW_PER_PAGE bits of  QPIC_NAND_DEV0_CFG0
	 * should be set to 0, which implies 1 codeword per page. 'n' below,
	 * is used to configure cfg0 for reading one full page or one single
	 * codeword.
	 */
	int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1;

	if (args->read) {
		if (ops->mode != MTD_OPS_RAW) {
			data->cmd = MSM_NAND_CMD_PAGE_READ_ECC;
			data->cfg0 =
			(chip->cfg0 & ~(7U << CW_PER_PAGE)) |
			(((args->cwperpage-1) - args->start_sector)
			(((args->cwperpage-n) - args->start_sector)
			 << CW_PER_PAGE);
			data->cfg1 = chip->cfg1;
			data->ecc_bch_cfg = chip->ecc_bch_cfg;
@@ -1258,7 +1277,7 @@ static void msm_nand_update_rw_reg_data(struct msm_nand_chip *chip,
			data->cmd = MSM_NAND_CMD_PAGE_READ_ALL;
			data->cfg0 =
			(chip->cfg0_raw & ~(7U << CW_PER_PAGE)) |
			(((args->cwperpage-1) - args->start_sector)
			(((args->cwperpage-n) - args->start_sector)
			 << CW_PER_PAGE);
			data->cfg1 = chip->cfg1_raw;
			data->ecc_bch_cfg = chip->ecc_cfg_raw;
@@ -1302,6 +1321,11 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops,
	uint32_t offset, size, last_read;
	struct sps_command_element *curr_ce, *start_ce;
	uint32_t *flags_ptr, *num_ce_ptr;
	/*
	 * Variable to configure read_location register parameters
	 * while reading one codeword or one full page
	 */
	int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1;

	if (curr_cw == args->start_sector) {
		curr_ce = start_ce = &cmd_list->setup_desc.ce[0];
@@ -1394,10 +1418,15 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops,
	if (ops->mode == MTD_OPS_AUTO_OOB) {
		if (ops->datbuf) {
			offset = 0;
			if (ops->len <= ONE_CODEWORD_SIZE) {
				size = ONE_CODEWORD_SIZE;
				last_read = 1;
			} else {
				size = (curr_cw < (args->cwperpage - 1)) ? 516 :
					(512 - ((args->cwperpage - 1) << 2));
			last_read = (curr_cw < (args->cwperpage - 1)) ? 1 :
				(ops->oobbuf ? 0 : 1);
				last_read = (curr_cw < (args->cwperpage - 1)) ?
					1 : (ops->oobbuf ? 0 : 1);
			}
			rdata = (offset << 0) | (size << 16) |
				(last_read << 31);

@@ -1413,7 +1442,7 @@ static void msm_nand_prep_rw_cmd_desc(struct mtd_oob_ops *ops,
				curr_ce++;
			}
		}
		if (curr_cw == (args->cwperpage - 1) && ops->oobbuf) {
		if (curr_cw == (args->cwperpage - n) && ops->oobbuf) {
			offset = 512 - ((args->cwperpage - 1) << 2);
			size = (args->cwperpage) << 2;
			if (size > args->oob_len_cmd)
@@ -1471,6 +1500,11 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops,
	uint32_t sectordatasize, sectoroobsize;
	uint32_t sps_flags = 0;
	int err = 0;
	/*
	 * Variable to configure sectordatasize and sectoroobsize
	 * while reading one codeword or one full page.
	 */
	int n = (ops->len <= ONE_CODEWORD_SIZE) ? args->cwperpage : 1;

	if (args->read)
		data_pipe_handle = info->sps.data_prod.handle;
@@ -1479,7 +1513,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops,

	if (ops->mode == MTD_OPS_RAW) {
		if (ecc_parity_bytes && args->read) {
			if (curr_cw == (args->cwperpage - 1))
			if (curr_cw == (args->cwperpage - n))
				sps_flags |= SPS_IOVEC_FLAG_INT;

			/* read only ecc bytes */
@@ -1494,7 +1528,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops,
			sectordatasize = chip->cw_size;
			if (!args->read)
				sps_flags = SPS_IOVEC_FLAG_EOT;
			if (curr_cw == (args->cwperpage - 1))
			if (curr_cw == (args->cwperpage - n))
				sps_flags |= SPS_IOVEC_FLAG_INT;

			err = sps_transfer_one(data_pipe_handle,
@@ -1507,8 +1541,13 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops,
		}
	} else if (ops->mode == MTD_OPS_AUTO_OOB) {
		if (ops->datbuf) {
			sectordatasize = (curr_cw < (args->cwperpage - 1))
			? 516 : (512 - ((args->cwperpage - 1) << 2));
			if (ops->len <= ONE_CODEWORD_SIZE)
				sectordatasize = ONE_CODEWORD_SIZE;
			else
				sectordatasize =
					(curr_cw < (args->cwperpage - 1))
					? 516 :
					(512 - ((args->cwperpage - 1) << 2));

			if (!args->read) {
				sps_flags = SPS_IOVEC_FLAG_EOT;
@@ -1516,7 +1555,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops,
						ops->oobbuf)
					sps_flags = 0;
			}
			if ((curr_cw == (args->cwperpage - 1)) && !ops->oobbuf)
			if ((curr_cw == (args->cwperpage - n)) && !ops->oobbuf)
				sps_flags |= SPS_IOVEC_FLAG_INT;

			err = sps_transfer_one(data_pipe_handle,
@@ -1528,7 +1567,7 @@ static int msm_nand_submit_rw_data_desc(struct mtd_oob_ops *ops,
			args->data_dma_addr_curr += sectordatasize;
		}

		if (ops->oobbuf && (curr_cw == (args->cwperpage - 1))) {
		if (ops->oobbuf && (curr_cw == (args->cwperpage - n))) {
			sectoroobsize = args->cwperpage << 2;
			if (sectoroobsize > args->oob_len_data)
				sectoroobsize = args->oob_len_data;
@@ -2757,6 +2796,9 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
		data.addr0 = (rw_params.page << 16) | rw_params.oob_col;
		data.addr1 = (rw_params.page >> 16) & 0xff;

		if (ops->len <= ONE_CODEWORD_SIZE)
			cwperpage = 1;

		for (n = rw_params.start_sector; n < cwperpage; n++) {
			struct sps_command_element *curr_ce, *start_ce;

@@ -3054,6 +3096,9 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from,
	}
validate_mtd_params_failed:
	if (ops->mode != MTD_OPS_RAW)
		if (ops->len <= ONE_CODEWORD_SIZE)
			ops->retlen = ONE_CODEWORD_SIZE;
		else
			ops->retlen = mtd->writesize * pages_read;
	else
		ops->retlen = (mtd->writesize +  mtd->oobsize) * pages_read;
@@ -3127,8 +3172,11 @@ static int msm_nand_read_partial_page(struct mtd_info *mtd,
		ops->datbuf = no_copy ? actual_buf : bounce_buf;
		if (info->nand_chip.caps & MSM_NAND_CAP_PAGE_SCOPE_READ)
			err = msm_nand_read_pagescope(mtd, aligned_from, ops);
		else
		else {
			if ((len <= ONE_CODEWORD_SIZE) && (offset == 0))
				ops->len = ONE_CODEWORD_SIZE;
			err = msm_nand_read_oob(mtd, aligned_from, ops);
		}
		if (err == -EUCLEAN) {
			is_euclean = 1;
			err = 0;