public inbox for linux-tegra@vger.kernel.org
 help / color / mirror / Atom feed
From: Michal Simek <michal.simek@amd.com>
To: Amit Kumar Mahapatra <amit.kumar-mahapatra@amd.com>,
	<broonie@kernel.org>, <miquel.raynal@bootlin.com>,
	<richard@nod.at>, <vigneshr@ti.com>, <jic23@kernel.org>,
	<tudor.ambarus@microchip.com>, <pratyush@kernel.org>,
	<sanju.mehta@amd.com>, <chin-ting_kuo@aspeedtech.com>,
	<clg@kaod.org>, <kdasu.kdev@gmail.com>, <f.fainelli@gmail.com>,
	<rjui@broadcom.com>, <sbranden@broadcom.com>,
	<eajames@linux.ibm.com>, <olteanv@gmail.com>, <han.xu@nxp.com>,
	<john.garry@huawei.com>, <shawnguo@kernel.org>,
	<s.hauer@pengutronix.de>, <narmstrong@baylibre.com>,
	<khilman@baylibre.com>, <matthias.bgg@gmail.com>,
	<haibo.chen@nxp.com>, <linus.walleij@linaro.org>,
	<daniel@zonque.org>, <haojian.zhuang@gmail.com>,
	<robert.jarzmik@free.fr>, <agross@kernel.org>,
	<bjorn.andersson@linaro.org>, <heiko@sntech.de>,
	<krzysztof.kozlowski@linaro.org>, <andi@etezian.org>,
	<mcoquelin.stm32@gmail.com>, <alexandre.torgue@foss.st.com>,
	<wens@csie.org>, <jernej.skrabec@gmail.com>,
	<samuel@sholland.org>, <masahisa.kojima@linaro.org>,
	<jaswinder.singh@linaro.org>, <rostedt@goodmis.org>,
	<mingo@redhat.com>, <l.stelmach@samsung.com>,
	<davem@davemloft.net>, <edumazet@google.com>, <kuba@kernel.org>,
	<pabeni@redhat.com>, <alex.aring@gmail.com>,
	<stefan@datenfreihafen.org>, <kvalo@kernel.org>,
	<thierry.reding@gmail.com>, <jonathanh@nvidia.com>,
	<skomatineni@nvidia.com>, <sumit.semwal@linaro.org>,
	<christian.koenig@amd.com>, <j.neuschaefer@gmx.net>,
	<vireshk@kernel.org>, <rmfrfs@gmail.com>, <johan@kernel.org>,
	<elder@kernel.org>, <gregkh@linuxfoundation.org>
Cc: <git@amd.com>, <linux-spi@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>, <joel@jms.id.au>,
	<andrew@aj.id.au>, <radu_nicolae.pirea@upb.ro>,
	<nicolas.ferre@microchip.com>, <alexandre.belloni@bootlin.com>,
	<claudiu.beznea@microchip.com>,
	<bcm-kernel-feedback-list@broadcom.com>,
	<fancer.lancer@gmail.com>, <kernel@pengutronix.de>,
	<festevam@gmail.com>, <linux-imx@nxp.com>, <jbrunet@baylibre.com>,
	<martin.blumenstingl@googlemail.com>, <avifishman70@gmail.com>,
	<tmaimon77@gmail.com>, <tali.perry1@gmail.com>,
	<venture@google.com>, <yuenn@google.com>,
	<benjaminfair@google.com>, <yogeshgaur.83@gmail.com>,
	<konrad.dybcio@somainline.org>, <alim.akhtar@samsung.com>,
	<ldewangan@nvidia.com>, <linux-aspeed@lists.ozlabs.org>,
	<openbmc@lists.ozlabs.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-rpi-kernel@lists.infradead.org>,
	<linux-amlogic@lists.infradead.org>,
	<linux-mediatek@lists.infradead.org>,
	<linux-arm-msm@vger.kernel.org>,
	<linux-rockchip@lists.infradead.org>,
	<linux-samsung-soc@vger.kernel.org>,
	<linux-stm32@st-md-mailman.stormreply.com>,
	<linux-sunxi@lists.linux.dev>, <linux-tegra@vger.kernel.org>,
	<netdev@vger.kernel.org>, <linux-wpan@vger.kernel.org>,
	<libertas-dev@lists.infradead.org>,
	<linux-wireless@vger.kernel.org>, <linux-mtd@lists.infradead.org>,
	<lars@metafoo.de>, <Michael.Hennerich@analog.com>,
	<linux-iio@vger.kernel.org>, <michael@walle.cc>,
	<palmer@dabbelt.com>, <linux-riscv@lists.infradead.org>,
	<linux-media@vger.kernel.org>, <dri-devel@lists.freedesktop.org>,
	<greybus-dev@lists.linaro.org>, <linux-staging@lists.linux.dev>,
	<amitrkcian2002@gmail.com>
Subject: Re: [PATCH v2 10/13] mtd: spi-nor: Add stacked memories support in spi-nor
Date: Mon, 23 Jan 2023 13:40:48 +0100	[thread overview]
Message-ID: <09534bb9-d9be-5433-5e7d-f9d40e30562e@amd.com> (raw)
In-Reply-To: <20230119185342.2093323-11-amit.kumar-mahapatra@amd.com>



On 1/19/23 19:53, Amit Kumar Mahapatra wrote:
> Each flash that is connected in stacked mode should have a separate
> parameter structure. So, the flash parameter member(*params) of the spi_nor
> structure is changed to an array (*params[2]). The array is used to store
> the parameters of each flash connected in stacked configuration.
> 
> The current implementation assumes that a maximum of two flashes are
> connected in stacked mode and both the flashes are of same make but can
> differ in sizes. So, except the sizes all other flash parameters of both
> the flashes are identical.
> 
> SPI-NOR is not aware of the chip_select values, for any incoming request
> SPI-NOR will decide the flash index with the help of individual flash size
> and the configuration type (single/stacked). SPI-NOR will pass on the flash
> index information to the SPI core & SPI driver by setting the appropriate
> bit in nor->spimem->spi->cs_index_mask. For example, if nth bit of
> nor->spimem->spi->cs_index_mask is set then the driver would
> assert/de-assert spi->chip_slect[n].
> 
> Signed-off-by: Amit Kumar Mahapatra <amit.kumar-mahapatra@amd.com>
> ---
>   drivers/mtd/spi-nor/core.c  | 282 +++++++++++++++++++++++++++++-------
>   drivers/mtd/spi-nor/core.h  |   4 +
>   drivers/mtd/spi-nor/otp.c   |   4 +-
>   include/linux/mtd/spi-nor.h |  12 +-
>   4 files changed, 246 insertions(+), 56 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
> index 8a4a54bf2d0e..bb7326dc8b70 100644
> --- a/drivers/mtd/spi-nor/core.c
> +++ b/drivers/mtd/spi-nor/core.c
> @@ -1441,13 +1441,18 @@ static int spi_nor_erase_multi_sectors(struct spi_nor *nor, u64 addr, u32 len)
>   static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>   {
>   	struct spi_nor *nor = mtd_to_spi_nor(mtd);
> -	u32 addr, len;
> +	struct spi_nor_flash_parameter *params;
> +	u32 addr, len, offset, cur_cs_num = 0;
>   	uint32_t rem;
>   	int ret;
> +	u64 sz;
>   
>   	dev_dbg(nor->dev, "at 0x%llx, len %lld\n", (long long)instr->addr,
>   			(long long)instr->len);
>   
> +	params = spi_nor_get_params(nor, 0);
> +	sz = params->size;
> +
>   	if (spi_nor_has_uniform_erase(nor)) {
>   		div_u64_rem(instr->len, mtd->erasesize, &rem);
>   		if (rem)
> @@ -1465,26 +1470,30 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>   	if (len == mtd->size && !(nor->flags & SNOR_F_NO_OP_CHIP_ERASE)) {
>   		unsigned long timeout;
>   
> -		ret = spi_nor_write_enable(nor);
> -		if (ret)
> -			goto erase_err;
> +		while (cur_cs_num < SNOR_FLASH_CNT_MAX && params) {
> +			nor->spimem->spi->cs_index_mask = 0x01 << cur_cs_num;
> +			ret = spi_nor_write_enable(nor);
> +			if (ret)
> +				goto erase_err;
>   
> -		ret = spi_nor_erase_chip(nor);
> -		if (ret)
> -			goto erase_err;
> +			ret = spi_nor_erase_chip(nor);
> +			if (ret)
> +				goto erase_err;
>   
> -		/*
> -		 * Scale the timeout linearly with the size of the flash, with
> -		 * a minimum calibrated to an old 2MB flash. We could try to
> -		 * pull these from CFI/SFDP, but these values should be good
> -		 * enough for now.
> -		 */
> -		timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES,
> -			      CHIP_ERASE_2MB_READY_WAIT_JIFFIES *
> -			      (unsigned long)(mtd->size / SZ_2M));
> -		ret = spi_nor_wait_till_ready_with_timeout(nor, timeout);
> -		if (ret)
> -			goto erase_err;
> +			/*
> +			 * Scale the timeout linearly with the size of the flash, with
> +			 * a minimum calibrated to an old 2MB flash. We could try to
> +			 * pull these from CFI/SFDP, but these values should be good
> +			 * enough for now.
> +			 */
> +			timeout = max(CHIP_ERASE_2MB_READY_WAIT_JIFFIES,
> +				      CHIP_ERASE_2MB_READY_WAIT_JIFFIES *
> +				      (unsigned long)(params->size / SZ_2M));
> +			ret = spi_nor_wait_till_ready_with_timeout(nor, timeout);
> +			if (ret)
> +				goto erase_err;
> +			cur_cs_num++;
> +		}
>   
>   	/* REVISIT in some cases we could speed up erasing large regions
>   	 * by using SPINOR_OP_SE instead of SPINOR_OP_BE_4K.  We may have set up
> @@ -1493,12 +1502,26 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>   
>   	/* "sector"-at-a-time erase */
>   	} else if (spi_nor_has_uniform_erase(nor)) {
> +		/* Determine the flash from which the operation need to start */
> +		while ((cur_cs_num < SNOR_FLASH_CNT_MAX) && (addr > sz - 1) && params) {
> +			cur_cs_num++;
> +			params = spi_nor_get_params(nor, cur_cs_num);
> +			sz += params->size;
> +		}
> +
>   		while (len) {
> +			nor->spimem->spi->cs_index_mask = 0x01 << cur_cs_num;
>   			ret = spi_nor_write_enable(nor);
>   			if (ret)
>   				goto erase_err;
>   
> -			ret = spi_nor_erase_sector(nor, addr);
> +			offset = addr;
> +			if (nor->flags & SNOR_F_HAS_STACKED) {
> +				params = spi_nor_get_params(nor, cur_cs_num);
> +				offset -= (sz - params->size);
> +			}
> +
> +			ret = spi_nor_erase_sector(nor, offset);
>   			if (ret)
>   				goto erase_err;
>   
> @@ -1508,13 +1531,45 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
>   
>   			addr += mtd->erasesize;
>   			len -= mtd->erasesize;
> +
> +			/*
> +			 * Flash cross over condition in stacked mode.
> +			 */
> +			if ((nor->flags & SNOR_F_HAS_STACKED) && (addr > sz - 1)) {
> +				cur_cs_num++;
> +				params = spi_nor_get_params(nor, cur_cs_num);
> +				sz += params->size;
> +			}
>   		}
>   
>   	/* erase multiple sectors */
>   	} else {
> -		ret = spi_nor_erase_multi_sectors(nor, addr, len);
> -		if (ret)
> -			goto erase_err;
> +		u64 erase_len = 0;
> +
> +		/* Determine the flash from which the operation need to start */
> +		while ((cur_cs_num < SNOR_FLASH_CNT_MAX) && (addr > sz - 1) && params) {
> +			cur_cs_num++;
> +			params = spi_nor_get_params(nor, cur_cs_num);
> +			sz += params->size;
> +		}
> +		/* perform multi sector erase onec per Flash*/
> +		while (len) {
> +			erase_len = (len > (sz - addr)) ? (sz - addr) : len;
> +			offset = addr;
> +			nor->spimem->spi->cs_index_mask = 0x01 << cur_cs_num;
> +			if (nor->flags & SNOR_F_HAS_STACKED) {
> +				params = spi_nor_get_params(nor, cur_cs_num);
> +				offset -= (sz - params->size);
> +			}
> +			ret = spi_nor_erase_multi_sectors(nor, offset, erase_len);
> +			if (ret)
> +				goto erase_err;
> +			len -= erase_len;
> +			addr += erase_len;
> +			cur_cs_num++;
> +			params = spi_nor_get_params(nor, cur_cs_num);
> +			sz += params->size;
> +		}
>   	}
>   
>   	ret = spi_nor_write_disable(nor);
> @@ -1713,7 +1768,10 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
>   			size_t *retlen, u_char *buf)
>   {
>   	struct spi_nor *nor = mtd_to_spi_nor(mtd);
> -	ssize_t ret;
> +	struct spi_nor_flash_parameter *params;
> +	ssize_t ret, read_len;
> +	u32 cur_cs_num = 0;
> +	u64 sz;
>   
>   	dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
>   
> @@ -1721,9 +1779,23 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
>   	if (ret)
>   		return ret;
>   
> +	params = spi_nor_get_params(nor, 0);
> +	sz = params->size;
> +
> +	/* Determine the flash from which the operation need to start */
> +	while ((cur_cs_num < SNOR_FLASH_CNT_MAX) && (from > sz - 1) && params) {
> +		cur_cs_num++;
> +		params = spi_nor_get_params(nor, cur_cs_num);
> +		sz += params->size;
> +	}
>   	while (len) {
>   		loff_t addr = from;
>   
> +		nor->spimem->spi->cs_index_mask = 0x01 << cur_cs_num;
> +		read_len = (len > (sz - addr)) ? (sz - addr) : len;
> +		params = spi_nor_get_params(nor, cur_cs_num);
> +		addr -= (sz - params->size);
> +
>   		addr = spi_nor_convert_addr(nor, addr);
>   
>   		ret = spi_nor_read_data(nor, addr, len, buf);
> @@ -1735,11 +1807,22 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
>   		if (ret < 0)
>   			goto read_err;
>   
> -		WARN_ON(ret > len);
> +		WARN_ON(ret > read_len);
>   		*retlen += ret;
>   		buf += ret;
>   		from += ret;
>   		len -= ret;
> +
> +		/*
> +		 * Flash cross over condition in stacked mode.
> +		 *
> +		 */
> +		if ((nor->flags & SNOR_F_HAS_STACKED) && (from > sz - 1)) {
> +			cur_cs_num++;
> +			params = spi_nor_get_params(nor, cur_cs_num);
> +			sz += params->size;
> +		}
> +
>   	}
>   	ret = 0;
>   
> @@ -1759,13 +1842,22 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
>   	struct spi_nor *nor = mtd_to_spi_nor(mtd);
>   	struct spi_nor_flash_parameter *params;
>   	size_t page_offset, page_remain, i;
> +	u32 page_size, cur_cs_num = 0;
>   	ssize_t ret;
> -	u32 page_size;
> +	u64 sz;
>   
>   	dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
>   
>   	params = spi_nor_get_params(nor, 0);
>   	page_size = params->page_size;
> +	sz = params->size;
> +
> +	/* Determine the flash from which the operation need to start */
> +	while ((cur_cs_num < SNOR_FLASH_CNT_MAX) && (to > sz - 1) && params) {
> +		cur_cs_num++;
> +		params = spi_nor_get_params(nor, cur_cs_num);
> +		sz += params->size;
> +	}
>   
>   	ret = spi_nor_lock_and_prep(nor);
>   	if (ret)
> @@ -1790,6 +1882,10 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
>   		/* the size of data remaining on the first page */
>   		page_remain = min_t(size_t, page_size - page_offset, len - i);
>   
> +		nor->spimem->spi->cs_index_mask = 0x01 << cur_cs_num;
> +		params = spi_nor_get_params(nor, cur_cs_num);
> +		addr -= (sz - params->size);
> +
>   		addr = spi_nor_convert_addr(nor, addr);
>   
>   		ret = spi_nor_write_enable(nor);
> @@ -1806,6 +1902,15 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
>   			goto write_err;
>   		*retlen += written;
>   		i += written;
> +
> +		/*
> +		 * Flash cross over condition in stacked mode.
> +		 */
> +		if ((nor->flags & SNOR_F_HAS_STACKED) && ((to + i) > sz - 1)) {
> +			cur_cs_num++;
> +			params = spi_nor_get_params(nor, cur_cs_num);
> +			sz += params->size;
> +		}
>   	}
>   
>   write_err:
> @@ -1918,8 +2023,6 @@ int spi_nor_hwcaps_pp2cmd(u32 hwcaps)
>   static int spi_nor_spimem_check_op(struct spi_nor *nor,
>   				   struct spi_mem_op *op)
>   {
> -	struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
> -
>   	/*
>   	 * First test with 4 address bytes. The opcode itself might
>   	 * be a 3B addressing opcode but we don't care, because
> @@ -1928,7 +2031,7 @@ static int spi_nor_spimem_check_op(struct spi_nor *nor,
>   	 */
>   	op->addr.nbytes = 4;
>   	if (!spi_mem_supports_op(nor->spimem, op)) {
> -		if (params->size > SZ_16M)
> +		if (nor->mtd.size > SZ_16M)
>   			return -EOPNOTSUPP;
>   
>   		/* If flash size <= 16MB, 3 address bytes are sufficient */
> @@ -2516,6 +2619,10 @@ static void spi_nor_init_fixup_flags(struct spi_nor *nor)
>   static void spi_nor_late_init_params(struct spi_nor *nor)
>   {
>   	struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
> +	struct device_node *np = spi_nor_get_flash_node(nor);
> +	u64 flash_size[SNOR_FLASH_CNT_MAX];
> +	u32 idx = 0, i = 0;
> +	int rc;
>   
>   	if (nor->manufacturer && nor->manufacturer->fixups &&
>   	    nor->manufacturer->fixups->late_init)
> @@ -2533,6 +2640,36 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
>   	 */
>   	if (nor->flags & SNOR_F_HAS_LOCK && !params->locking_ops)
>   		spi_nor_init_default_locking_ops(nor);
> +	/*
> +	 * The flashes that are connected in stacked mode should be of same make.
> +	 * Except the flash size all other properties are identical for all the
> +	 * flashes connected in stacked mode.
> +	 * The flashes that are connected in parallel mode should be identical.
> +	 */
> +	while (i < SNOR_FLASH_CNT_MAX) {
> +		rc = of_property_read_u64_index(np, "stacked-memories", idx, &flash_size[i]);
> +		if (rc == -EINVAL) {
> +			break;
> +		} else if (rc == -EOVERFLOW) {
> +			idx++;
> +		} else {
> +			idx++;
> +			i++;
> +			if (!(nor->flags & SNOR_F_HAS_STACKED))
> +				nor->flags |= SNOR_F_HAS_STACKED;
> +		}
> +	}
> +	if (nor->flags & SNOR_F_HAS_STACKED) {
> +		for (idx = 1; idx < SNOR_FLASH_CNT_MAX; idx++) {
> +			params = spi_nor_get_params(nor, idx);
> +			params = devm_kzalloc(nor->dev, sizeof(*params), GFP_KERNEL);
> +			if (params) {
> +				memcpy(params, spi_nor_get_params(nor, 0), sizeof(*params));
> +				params->size = flash_size[idx];
> +				spi_nor_set_params(nor, idx, params);
> +			}
> +		}
> +	}
>   }
>   
>   /**
> @@ -2741,22 +2878,36 @@ static int spi_nor_octal_dtr_enable(struct spi_nor *nor, bool enable)
>    */
>   static int spi_nor_quad_enable(struct spi_nor *nor)
>   {
> -	struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
> +	struct spi_nor_flash_parameter *params;
> +	int err, idx;
>   
> -	if (!params->quad_enable)
> -		return 0;
> +	for (idx = 0; idx < SNOR_FLASH_CNT_MAX; idx++) {
> +		params = spi_nor_get_params(nor, idx);
> +		if (params) {
> +			if (!params->quad_enable)
> +				return 0;
>   
> -	if (!(spi_nor_get_protocol_width(nor->read_proto) == 4 ||
> -	      spi_nor_get_protocol_width(nor->write_proto) == 4))
> -		return 0;
> +			if (!(spi_nor_get_protocol_width(nor->read_proto) == 4 ||
> +			      spi_nor_get_protocol_width(nor->write_proto) == 4))
> +				return 0;
> +			/*
> +			 * Set the appropriate CS index before
> +			 * issuing the command.
> +			 */
> +			nor->spimem->spi->cs_index_mask = 0x01 << idx;
>   
> -	return params->quad_enable(nor);
> +			err = params->quad_enable(nor);
> +			if (err)
> +				return err;
> +		}
> +	}
> +	return err;
>   }
>   
>   static int spi_nor_init(struct spi_nor *nor)
>   {
> -	struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
> -	int err;
> +	struct spi_nor_flash_parameter *params;
> +	int err, idx;
>   
>   	err = spi_nor_octal_dtr_enable(nor, true);
>   	if (err) {
> @@ -2797,9 +2948,19 @@ static int spi_nor_init(struct spi_nor *nor)
>   		 */
>   		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
>   			  "enabling reset hack; may not recover from unexpected reboots\n");
> -		err = params->set_4byte_addr_mode(nor, true);
> -		if (err && err != -ENOTSUPP)
> -			return err;
> +		for (idx = 0; idx < SNOR_FLASH_CNT_MAX; idx++) {
> +			params = spi_nor_get_params(nor, idx);
> +			if (params) {
> +				/*
> +				 * Select the appropriate CS index before
> +				 * issuing the command.
> +				 */
> +				nor->spimem->spi->cs_index_mask = 0x01 << idx;
> +				err = params->set_4byte_addr_mode(nor, true);
> +				if (err && err != -ENOTSUPP)
> +					return err;
> +			}
> +		}
>   	}
>   
>   	return 0;
> @@ -2915,19 +3076,31 @@ void spi_nor_restore(struct spi_nor *nor)
>   {
>   	struct spi_nor_flash_parameter *params;
>   	int ret;
> +	int idx;
>   
>   	/* restore the addressing mode */
>   	if (nor->addr_nbytes == 4 && !(nor->flags & SNOR_F_4B_OPCODES) &&
>   	    nor->flags & SNOR_F_BROKEN_RESET) {
> -		params = spi_nor_get_params(nor, 0);
> -		ret = params->set_4byte_addr_mode(nor, false);
> -		if (ret)
> -			/*
> -			 * Do not stop the execution in the hope that the flash
> -			 * will default to the 3-byte address mode after the
> -			 * software reset.
> -			 */
> -			dev_err(nor->dev, "Failed to exit 4-byte address mode, err = %d\n", ret);
> +		for (idx = 0; idx < SNOR_FLASH_CNT_MAX; idx++) {
> +			params = spi_nor_get_params(nor, idx);
> +			if (params) {
> +				/*
> +				 * Select the appropriate CS index before
> +				 * issuing the command.
> +				 */
> +				nor->spimem->spi->cs_index_mask = 0x01 << idx;
> +				ret = params->set_4byte_addr_mode(nor, false);
> +				if (ret)
> +					/*
> +					 * Do not stop the execution in the hope that the flash
> +					 * will default to the 3-byte address mode after the
> +					 * software reset.
> +					 */
> +					dev_err(nor->dev,
> +						"Failed to exit 4-byte address mode, err = %d\n",
> +						ret);
> +			}
> +		}
>   	}
>   
>   	if (nor->flags & SNOR_F_SOFT_RESET)
> @@ -2995,6 +3168,8 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
>   	struct spi_nor_flash_parameter *params = spi_nor_get_params(nor, 0);
>   	struct mtd_info *mtd = &nor->mtd;
>   	struct device *dev = nor->dev;
> +	u64 total_sz = 0;
> +	int idx;
>   
>   	spi_nor_set_mtd_locking_ops(nor);
>   	spi_nor_set_mtd_otp_ops(nor);
> @@ -3010,7 +3185,12 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
>   		mtd->_erase = spi_nor_erase;
>   	mtd->writesize = params->writesize;
>   	mtd->writebufsize = params->page_size;
> -	mtd->size = params->size;
> +	for (idx = 0; idx < SNOR_FLASH_CNT_MAX; idx++) {
> +		params = spi_nor_get_params(nor, idx);
> +		if (params)
> +			total_sz += params->size;
> +	}
> +	mtd->size = total_sz;
>   	mtd->_read = spi_nor_read;
>   	/* Might be already set by some SST flashes. */
>   	if (!mtd->_write)
> diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
> index f03b55cf7e6f..e94107cc465e 100644
> --- a/drivers/mtd/spi-nor/core.h
> +++ b/drivers/mtd/spi-nor/core.h
> @@ -11,6 +11,9 @@
>   
>   #define SPI_NOR_MAX_ID_LEN	6
>   
> +/* In single configuration enable CS0 */
> +#define SPI_NOR_ENABLE_CS0     BIT(0)
> +
>   /* Standard SPI NOR flash operations. */
>   #define SPI_NOR_READID_OP(naddr, ndummy, buf, len)			\
>   	SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 0),			\
> @@ -130,6 +133,7 @@ enum spi_nor_option_flags {
>   	SNOR_F_IO_MODE_EN_VOLATILE = BIT(11),
>   	SNOR_F_SOFT_RESET	= BIT(12),
>   	SNOR_F_SWP_IS_VOLATILE	= BIT(13),
> +	SNOR_F_HAS_STACKED      = BIT(14),
>   };
>   
>   struct spi_nor_read_command {
> diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c
> index a9c0844d55ef..b8c7e085a90d 100644
> --- a/drivers/mtd/spi-nor/otp.c
> +++ b/drivers/mtd/spi-nor/otp.c
> @@ -11,8 +11,8 @@
>   
>   #include "core.h"
>   
> -#define spi_nor_otp_region_len(nor) ((nor)->params->otp.org->len)
> -#define spi_nor_otp_n_regions(nor) ((nor)->params->otp.org->n_regions)
> +#define spi_nor_otp_region_len(nor) ((nor)->params[0]->otp.org->len)
> +#define spi_nor_otp_n_regions(nor) ((nor)->params[0]->otp.org->n_regions)

I think this should be also converted to static inline functions and use
spi_nor_get_params(nor, 0); instead of using arrays.
Can be done on the top of this series if it is the only one problem with it.

Thanks,
Michal

  reply	other threads:[~2023-01-23 12:41 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-19 18:53 [PATCH v2 00/13] spi: Add support for stacked/parallel memories Amit Kumar Mahapatra
2023-01-19 18:53 ` [PATCH v2 01/13] spi: Add APIs in spi core to set/get spi->chip_select and spi->cs_gpiod Amit Kumar Mahapatra
2023-01-23 12:44   ` Michal Simek
2023-01-19 18:53 ` [PATCH v2 02/13] spi: Replace all spi->chip_select and spi->cs_gpiod references with function call Amit Kumar Mahapatra
2023-01-20  9:47   ` Heiko Stübner
2023-01-23 12:46   ` Michal Simek
2023-01-23 13:10   ` Cédric Le Goater
2023-01-23 14:20   ` Dhruva Gole
2023-01-23 15:04   ` Serge Semin
2023-01-23 17:16   ` Patrice CHOTARD
2023-01-25  0:57   ` William Zhang
2023-02-01 15:15   ` Mark Brown
2023-01-19 18:53 ` [PATCH v2 03/13] net: " Amit Kumar Mahapatra
2023-01-23 12:46   ` Michal Simek
2023-01-19 18:53 ` [PATCH v2 04/13] iio: imu: " Amit Kumar Mahapatra
2023-01-21 16:52   ` Jonathan Cameron
2023-01-23 12:47   ` Michal Simek
2023-01-19 18:53 ` [PATCH v2 05/13] mtd: devices: " Amit Kumar Mahapatra
2023-01-23 12:47   ` Michal Simek
2023-01-19 18:53 ` [PATCH v2 06/13] staging: " Amit Kumar Mahapatra
2023-01-20 10:09   ` Greg KH
2023-01-23 12:47   ` Michal Simek
2023-01-19 18:53 ` [PATCH v2 07/13] platform/x86: serial-multi-instantiate: " Amit Kumar Mahapatra
2023-01-23 12:48   ` Michal Simek
2023-01-19 18:53 ` [PATCH v2 08/13] spi: Add stacked and parallel memories support in SPI core Amit Kumar Mahapatra
2023-01-19 18:53 ` [PATCH v2 09/13] mtd: spi-nor: Add APIs to set/get nor->params Amit Kumar Mahapatra
2023-01-19 18:53 ` [PATCH v2 10/13] mtd: spi-nor: Add stacked memories support in spi-nor Amit Kumar Mahapatra
2023-01-23 12:40   ` Michal Simek [this message]
2023-01-19 18:53 ` [PATCH v2 11/13] spi: spi-zynqmp-gqspi: Add stacked memories support in GQSPI driver Amit Kumar Mahapatra
2023-01-19 18:53 ` [PATCH v2 12/13] mtd: spi-nor: Add parallel memories support in spi-nor Amit Kumar Mahapatra
2023-01-19 18:53 ` [PATCH v2 13/13] spi: spi-zynqmp-gqspi: Add parallel memories support in GQSPI driver Amit Kumar Mahapatra
2023-02-01 16:57 ` (subset) [PATCH v2 00/13] spi: Add support for stacked/parallel memories Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=09534bb9-d9be-5433-5e7d-f9d40e30562e@amd.com \
    --to=michal.simek@amd.com \
    --cc=Michael.Hennerich@analog.com \
    --cc=agross@kernel.org \
    --cc=alex.aring@gmail.com \
    --cc=alexandre.belloni@bootlin.com \
    --cc=alexandre.torgue@foss.st.com \
    --cc=alim.akhtar@samsung.com \
    --cc=amit.kumar-mahapatra@amd.com \
    --cc=amitrkcian2002@gmail.com \
    --cc=andi@etezian.org \
    --cc=andrew@aj.id.au \
    --cc=avifishman70@gmail.com \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=benjaminfair@google.com \
    --cc=bjorn.andersson@linaro.org \
    --cc=broonie@kernel.org \
    --cc=chin-ting_kuo@aspeedtech.com \
    --cc=christian.koenig@amd.com \
    --cc=claudiu.beznea@microchip.com \
    --cc=clg@kaod.org \
    --cc=daniel@zonque.org \
    --cc=davem@davemloft.net \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=eajames@linux.ibm.com \
    --cc=edumazet@google.com \
    --cc=elder@kernel.org \
    --cc=f.fainelli@gmail.com \
    --cc=fancer.lancer@gmail.com \
    --cc=festevam@gmail.com \
    --cc=git@amd.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=greybus-dev@lists.linaro.org \
    --cc=haibo.chen@nxp.com \
    --cc=han.xu@nxp.com \
    --cc=haojian.zhuang@gmail.com \
    --cc=heiko@sntech.de \
    --cc=j.neuschaefer@gmx.net \
    --cc=jaswinder.singh@linaro.org \
    --cc=jbrunet@baylibre.com \
    --cc=jernej.skrabec@gmail.com \
    --cc=jic23@kernel.org \
    --cc=joel@jms.id.au \
    --cc=johan@kernel.org \
    --cc=john.garry@huawei.com \
    --cc=jonathanh@nvidia.com \
    --cc=kdasu.kdev@gmail.com \
    --cc=kernel@pengutronix.de \
    --cc=khilman@baylibre.com \
    --cc=konrad.dybcio@somainline.org \
    --cc=krzysztof.kozlowski@linaro.org \
    --cc=kuba@kernel.org \
    --cc=kvalo@kernel.org \
    --cc=l.stelmach@samsung.com \
    --cc=lars@metafoo.de \
    --cc=ldewangan@nvidia.com \
    --cc=libertas-dev@lists.infradead.org \
    --cc=linus.walleij@linaro.org \
    --cc=linux-amlogic@lists.infradead.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-aspeed@lists.ozlabs.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-imx@nxp.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linux-rockchip@lists.infradead.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=linux-spi@vger.kernel.org \
    --cc=linux-staging@lists.linux.dev \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=linux-sunxi@lists.linux.dev \
    --cc=linux-tegra@vger.kernel.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=linux-wpan@vger.kernel.org \
    --cc=martin.blumenstingl@googlemail.com \
    --cc=masahisa.kojima@linaro.org \
    --cc=matthias.bgg@gmail.com \
    --cc=mcoquelin.stm32@gmail.com \
    --cc=michael@walle.cc \
    --cc=mingo@redhat.com \
    --cc=miquel.raynal@bootlin.com \
    --cc=narmstrong@baylibre.com \
    --cc=netdev@vger.kernel.org \
    --cc=nicolas.ferre@microchip.com \
    --cc=olteanv@gmail.com \
    --cc=openbmc@lists.ozlabs.org \
    --cc=pabeni@redhat.com \
    --cc=palmer@dabbelt.com \
    --cc=pratyush@kernel.org \
    --cc=radu_nicolae.pirea@upb.ro \
    --cc=richard@nod.at \
    --cc=rjui@broadcom.com \
    --cc=rmfrfs@gmail.com \
    --cc=robert.jarzmik@free.fr \
    --cc=rostedt@goodmis.org \
    --cc=s.hauer@pengutronix.de \
    --cc=samuel@sholland.org \
    --cc=sanju.mehta@amd.com \
    --cc=sbranden@broadcom.com \
    --cc=shawnguo@kernel.org \
    --cc=skomatineni@nvidia.com \
    --cc=stefan@datenfreihafen.org \
    --cc=sumit.semwal@linaro.org \
    --cc=tali.perry1@gmail.com \
    --cc=thierry.reding@gmail.com \
    --cc=tmaimon77@gmail.com \
    --cc=tudor.ambarus@microchip.com \
    --cc=venture@google.com \
    --cc=vigneshr@ti.com \
    --cc=vireshk@kernel.org \
    --cc=wens@csie.org \
    --cc=yogeshgaur.83@gmail.com \
    --cc=yuenn@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox