File Index
Files and directories
Sign in
FILE

spansion.c

File preview with syntax highlighting.

linux-6.19.14/drivers/mtd/spi-nor/spansion.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright (C) 2005, Intec Automation Inc.
   4 * Copyright (C) 2014, Freescale Semiconductor, Inc.
   5 */
   6
   7#include <linux/bitfield.h>
   8#include <linux/device.h>
   9#include <linux/errno.h>
  10#include <linux/mtd/spi-nor.h>
  11
  12#include "core.h"
  13
  14/* flash_info mfr_flag. Used to clear sticky prorietary SR bits. */
  15#define USE_CLSR	BIT(0)
  16#define USE_CLPEF	BIT(1)
  17
  18#define SPINOR_OP_CLSR		0x30	/* Clear status register 1 */
  19#define SPINOR_OP_CLPEF		0x82	/* Clear program/erase failure flags */
  20#define SPINOR_OP_CYPRESS_EX4B	0xB8	/* Exit 4-byte address mode */
  21#define SPINOR_OP_CYPRESS_DIE_ERASE		0x61	/* Chip (die) erase */
  22#define SPINOR_OP_RD_ANY_REG			0x65	/* Read any register */
  23#define SPINOR_OP_WR_ANY_REG			0x71	/* Write any register */
  24#define SPINOR_REG_CYPRESS_VREG			0x00800000
  25#define SPINOR_REG_CYPRESS_STR1			0x0
  26#define SPINOR_REG_CYPRESS_STR1V					\
  27	(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_STR1)
  28#define SPINOR_REG_CYPRESS_CFR1			0x2
  29#define SPINOR_REG_CYPRESS_CFR1_QUAD_EN		BIT(1)	/* Quad Enable */
  30#define SPINOR_REG_CYPRESS_CFR2			0x3
  31#define SPINOR_REG_CYPRESS_CFR2V					\
  32	(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR2)
  33#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK	GENMASK(3, 0)
  34#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24	0xb
  35#define SPINOR_REG_CYPRESS_CFR2_ADRBYT		BIT(7)
  36#define SPINOR_REG_CYPRESS_CFR3			0x4
  37#define SPINOR_REG_CYPRESS_CFR3_PGSZ		BIT(4) /* Page size. */
  38#define SPINOR_REG_CYPRESS_CFR5			0x6
  39#define SPINOR_REG_CYPRESS_CFR5_BIT6		BIT(6)
  40#define SPINOR_REG_CYPRESS_CFR5_DDR		BIT(1)
  41#define SPINOR_REG_CYPRESS_CFR5_OPI		BIT(0)
  42#define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN				\
  43	(SPINOR_REG_CYPRESS_CFR5_BIT6 |	SPINOR_REG_CYPRESS_CFR5_DDR |	\
  44	 SPINOR_REG_CYPRESS_CFR5_OPI)
  45#define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS	SPINOR_REG_CYPRESS_CFR5_BIT6
  46#define SPINOR_OP_CYPRESS_RD_FAST		0xee
  47#define SPINOR_REG_CYPRESS_ARCFN		0x00000006
  48
  49/* Cypress SPI NOR flash operations. */
  50#define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf)		\
  51	SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 0),		\
  52		   SPI_MEM_OP_ADDR(naddr, addr, 0),			\
  53		   SPI_MEM_OP_NO_DUMMY,					\
  54		   SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
  55
  56#define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, ndummy, buf)		\
  57	SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0),		\
  58		   SPI_MEM_OP_ADDR(naddr, addr, 0),			\
  59		   SPI_MEM_OP_DUMMY(ndummy, 0),				\
  60		   SPI_MEM_OP_DATA_IN(1, buf, 0))
  61
  62#define CYPRESS_NOR_EN4B_EX4B_OP(enable)				\
  63	SPI_MEM_OP(SPI_MEM_OP_CMD(enable ? SPINOR_OP_EN4B :		\
  64					   SPINOR_OP_CYPRESS_EX4B, 0),	\
  65		   SPI_MEM_OP_NO_ADDR,					\
  66		   SPI_MEM_OP_NO_DUMMY,					\
  67		   SPI_MEM_OP_NO_DATA)
  68
  69#define SPANSION_OP(opcode)						\
  70	SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0),				\
  71		   SPI_MEM_OP_NO_ADDR,					\
  72		   SPI_MEM_OP_NO_DUMMY,					\
  73		   SPI_MEM_OP_NO_DATA)
  74
  75/**
  76 * struct spansion_nor_params - Spansion private parameters.
  77 * @clsr:	Clear Status Register or Clear Program and Erase Failure Flag
  78 *		opcode.
  79 */
  80struct spansion_nor_params {
  81	u8 clsr;
  82};
  83
  84/**
  85 * spansion_nor_clear_sr() - Clear the Status Register.
  86 * @nor:	pointer to 'struct spi_nor'.
  87 */
  88static void spansion_nor_clear_sr(struct spi_nor *nor)
  89{
  90	const struct spansion_nor_params *priv_params = nor->params->priv;
  91	int ret;
  92
  93	if (nor->spimem) {
  94		struct spi_mem_op op = SPANSION_OP(priv_params->clsr);
  95
  96		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
  97
  98		ret = spi_mem_exec_op(nor->spimem, &op);
  99	} else {
 100		ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
 101						       NULL, 0);
 102	}
 103
 104	if (ret)
 105		dev_dbg(nor->dev, "error %d clearing SR\n", ret);
 106}
 107
 108static int cypress_nor_sr_ready_and_clear_reg(struct spi_nor *nor, u64 addr)
 109{
 110	struct spi_nor_flash_parameter *params = nor->params;
 111	struct spi_mem_op op =
 112		CYPRESS_NOR_RD_ANY_REG_OP(params->addr_mode_nbytes, addr,
 113					  0, nor->bouncebuf);
 114	int ret;
 115
 116	if (nor->reg_proto == SNOR_PROTO_8_8_8_DTR) {
 117		op.addr.nbytes = nor->addr_nbytes;
 118		op.dummy.nbytes = params->rdsr_dummy;
 119		op.data.nbytes = 2;
 120	}
 121
 122	ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 123	if (ret)
 124		return ret;
 125
 126	if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
 127		if (nor->bouncebuf[0] & SR_E_ERR)
 128			dev_err(nor->dev, "Erase Error occurred\n");
 129		else
 130			dev_err(nor->dev, "Programming Error occurred\n");
 131
 132		spansion_nor_clear_sr(nor);
 133
 134		ret = spi_nor_write_disable(nor);
 135		if (ret)
 136			return ret;
 137
 138		return -EIO;
 139	}
 140
 141	return !(nor->bouncebuf[0] & SR_WIP);
 142}
 143/**
 144 * cypress_nor_sr_ready_and_clear() - Query the Status Register of each die by
 145 * using Read Any Register command to see if the whole flash is ready for new
 146 * commands and clear it if there are any errors.
 147 * @nor:	pointer to 'struct spi_nor'.
 148 *
 149 * Return: 1 if ready, 0 if not ready, -errno on errors.
 150 */
 151static int cypress_nor_sr_ready_and_clear(struct spi_nor *nor)
 152{
 153	struct spi_nor_flash_parameter *params = nor->params;
 154	u64 addr;
 155	int ret;
 156	u8 i;
 157
 158	for (i = 0; i < params->n_dice; i++) {
 159		addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_STR1;
 160		ret = cypress_nor_sr_ready_and_clear_reg(nor, addr);
 161		if (ret < 0)
 162			return ret;
 163		else if (ret == 0)
 164			return 0;
 165	}
 166
 167	return 1;
 168}
 169
 170static int cypress_nor_set_memlat(struct spi_nor *nor, u64 addr)
 171{
 172	struct spi_mem_op op;
 173	u8 *buf = nor->bouncebuf;
 174	int ret;
 175	u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
 176
 177	op = (struct spi_mem_op)
 178		CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0, buf);
 179
 180	ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 181	if (ret)
 182		return ret;
 183
 184	/* Use 24 dummy cycles for memory array reads. */
 185	*buf &= ~SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK;
 186	*buf |= FIELD_PREP(SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK,
 187			   SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24);
 188	op = (struct spi_mem_op)
 189		CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1, buf);
 190
 191	ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
 192	if (ret)
 193		return ret;
 194
 195	nor->read_dummy = 24;
 196
 197	return 0;
 198}
 199
 200static int cypress_nor_set_octal_dtr_bits(struct spi_nor *nor, u64 addr)
 201{
 202	struct spi_mem_op op;
 203	u8 *buf = nor->bouncebuf;
 204
 205	/* Set the octal and DTR enable bits. */
 206	buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN;
 207	op = (struct spi_mem_op)
 208		CYPRESS_NOR_WR_ANY_REG_OP(nor->params->addr_mode_nbytes,
 209					  addr, 1, buf);
 210
 211	return spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
 212}
 213
 214static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
 215{
 216	const struct spi_nor_flash_parameter *params = nor->params;
 217	u8 *buf = nor->bouncebuf;
 218	u64 addr;
 219	int i, ret;
 220
 221	for (i = 0; i < params->n_dice; i++) {
 222		addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR2;
 223		ret = cypress_nor_set_memlat(nor, addr);
 224		if (ret)
 225			return ret;
 226
 227		addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR5;
 228		ret = cypress_nor_set_octal_dtr_bits(nor, addr);
 229		if (ret)
 230			return ret;
 231	}
 232
 233	/* Read flash ID to make sure the switch was successful. */
 234	ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf,
 235			      SNOR_PROTO_8_8_8_DTR);
 236	if (ret) {
 237		dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
 238		return ret;
 239	}
 240
 241	if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
 242		return -EINVAL;
 243
 244	return 0;
 245}
 246
 247static int cypress_nor_set_single_spi_bits(struct spi_nor *nor, u64 addr)
 248{
 249	struct spi_mem_op op;
 250	u8 *buf = nor->bouncebuf;
 251
 252	/*
 253	 * The register is 1-byte wide, but 1-byte transactions are not allowed
 254	 * in 8D-8D-8D mode. Since there is no register at the next location,
 255	 * just initialize the value to 0 and let the transaction go on.
 256	 */
 257	buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS;
 258	buf[1] = 0;
 259	op = (struct spi_mem_op)
 260		CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, addr, 2, buf);
 261	return spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
 262}
 263
 264static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
 265{
 266	const struct spi_nor_flash_parameter *params = nor->params;
 267	u8 *buf = nor->bouncebuf;
 268	u64 addr;
 269	int i, ret;
 270
 271	for (i = 0; i < params->n_dice; i++) {
 272		addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR5;
 273		ret = cypress_nor_set_single_spi_bits(nor, addr);
 274		if (ret)
 275			return ret;
 276	}
 277
 278	/* Read flash ID to make sure the switch was successful. */
 279	ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
 280	if (ret) {
 281		dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
 282		return ret;
 283	}
 284
 285	if (memcmp(buf, nor->info->id->bytes, nor->info->id->len))
 286		return -EINVAL;
 287
 288	return 0;
 289}
 290
 291static int cypress_nor_quad_enable_volatile_reg(struct spi_nor *nor, u64 addr)
 292{
 293	struct spi_mem_op op;
 294	u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
 295	u8 cfr1v_written;
 296	int ret;
 297
 298	op = (struct spi_mem_op)
 299		CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
 300					  nor->bouncebuf);
 301
 302	ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 303	if (ret)
 304		return ret;
 305
 306	if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR1_QUAD_EN)
 307		return 0;
 308
 309	/* Update the Quad Enable bit. */
 310	nor->bouncebuf[0] |= SPINOR_REG_CYPRESS_CFR1_QUAD_EN;
 311	op = (struct spi_mem_op)
 312		CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1,
 313					  nor->bouncebuf);
 314	ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
 315	if (ret)
 316		return ret;
 317
 318	cfr1v_written = nor->bouncebuf[0];
 319
 320	/* Read back and check it. */
 321	op = (struct spi_mem_op)
 322		CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
 323					  nor->bouncebuf);
 324	ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 325	if (ret)
 326		return ret;
 327
 328	if (nor->bouncebuf[0] != cfr1v_written) {
 329		dev_err(nor->dev, "CFR1: Read back test failed\n");
 330		return -EIO;
 331	}
 332
 333	return 0;
 334}
 335
 336/**
 337 * cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile
 338 *                                      register.
 339 * @nor:	pointer to a 'struct spi_nor'
 340 *
 341 * It is recommended to update volatile registers in the field application due
 342 * to a risk of the non-volatile registers corruption by power interrupt. This
 343 * function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable
 344 * bit in the CFR1 non-volatile in advance (typically by a Flash programmer
 345 * before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is
 346 * also set during Flash power-up.
 347 *
 348 * Return: 0 on success, -errno otherwise.
 349 */
 350static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
 351{
 352	struct spi_nor_flash_parameter *params = nor->params;
 353	u64 addr;
 354	u8 i;
 355	int ret;
 356
 357	for (i = 0; i < params->n_dice; i++) {
 358		addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR1;
 359		ret = cypress_nor_quad_enable_volatile_reg(nor, addr);
 360		if (ret)
 361			return ret;
 362	}
 363
 364	return 0;
 365}
 366
 367static int cypress_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
 368{
 369	int ret;
 370	struct spi_mem_op op = CYPRESS_NOR_EN4B_EX4B_OP(enable);
 371
 372	spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
 373
 374	ret = spi_mem_exec_op(nor->spimem, &op);
 375	if (ret)
 376		dev_dbg(nor->dev, "error %d setting 4-byte mode\n", ret);
 377
 378	return ret;
 379}
 380
 381/**
 382 * cypress_nor_determine_addr_mode_by_sr1() - Determine current address mode
 383 *                                            (3 or 4-byte) by querying status
 384 *                                            register 1 (SR1).
 385 * @nor:		pointer to a 'struct spi_nor'
 386 * @addr_mode:		ponter to a buffer where we return the determined
 387 *			address mode.
 388 *
 389 * This function tries to determine current address mode by comparing SR1 value
 390 * from RDSR1(no address), RDAR(3-byte address), and RDAR(4-byte address).
 391 *
 392 * Return: 0 on success, -errno otherwise.
 393 */
 394static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor,
 395						  u8 *addr_mode)
 396{
 397	struct spi_mem_op op =
 398		CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_STR1V, 0,
 399					  nor->bouncebuf);
 400	bool is3byte, is4byte;
 401	int ret;
 402
 403	ret = spi_nor_read_sr(nor, &nor->bouncebuf[1]);
 404	if (ret)
 405		return ret;
 406
 407	ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 408	if (ret)
 409		return ret;
 410
 411	is3byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
 412
 413	op = (struct spi_mem_op)
 414		CYPRESS_NOR_RD_ANY_REG_OP(4, SPINOR_REG_CYPRESS_STR1V, 0,
 415					  nor->bouncebuf);
 416	ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 417	if (ret)
 418		return ret;
 419
 420	is4byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
 421
 422	if (is3byte == is4byte)
 423		return -EIO;
 424	if (is3byte)
 425		*addr_mode = 3;
 426	else
 427		*addr_mode = 4;
 428
 429	return 0;
 430}
 431
 432/**
 433 * cypress_nor_set_addr_mode_nbytes() - Set the number of address bytes mode of
 434 *                                      current address mode.
 435 * @nor:		pointer to a 'struct spi_nor'
 436 *
 437 * Determine current address mode by reading SR1 with different methods, then
 438 * query CFR2V[7] to confirm. If determination is failed, force enter to 4-byte
 439 * address mode.
 440 *
 441 * Return: 0 on success, -errno otherwise.
 442 */
 443static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor)
 444{
 445	struct spi_mem_op op;
 446	u8 addr_mode;
 447	int ret;
 448
 449	/*
 450	 * Read SR1 by RDSR1 and RDAR(3- AND 4-byte addr). Use write enable
 451	 * that sets bit-1 in SR1.
 452	 */
 453	ret = spi_nor_write_enable(nor);
 454	if (ret)
 455		return ret;
 456	ret = cypress_nor_determine_addr_mode_by_sr1(nor, &addr_mode);
 457	if (ret) {
 458		ret = spi_nor_set_4byte_addr_mode(nor, true);
 459		if (ret)
 460			return ret;
 461		return spi_nor_write_disable(nor);
 462	}
 463	ret = spi_nor_write_disable(nor);
 464	if (ret)
 465		return ret;
 466
 467	/*
 468	 * Query CFR2V and make sure no contradiction between determined address
 469	 * mode and CFR2V[7].
 470	 */
 471	op = (struct spi_mem_op)
 472		CYPRESS_NOR_RD_ANY_REG_OP(addr_mode, SPINOR_REG_CYPRESS_CFR2V,
 473					  0, nor->bouncebuf);
 474	ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 475	if (ret)
 476		return ret;
 477
 478	if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR2_ADRBYT) {
 479		if (addr_mode != 4)
 480			return spi_nor_set_4byte_addr_mode(nor, true);
 481	} else {
 482		if (addr_mode != 3)
 483			return spi_nor_set_4byte_addr_mode(nor, true);
 484	}
 485
 486	nor->params->addr_nbytes = addr_mode;
 487	nor->params->addr_mode_nbytes = addr_mode;
 488
 489	return 0;
 490}
 491
 492/**
 493 * cypress_nor_get_page_size() - Get flash page size configuration.
 494 * @nor:	pointer to a 'struct spi_nor'
 495 *
 496 * The BFPT table advertises a 512B or 256B page size depending on part but the
 497 * page size is actually configurable (with the default being 256B). Read from
 498 * CFR3V[4] and set the correct size.
 499 *
 500 * Return: 0 on success, -errno otherwise.
 501 */
 502static int cypress_nor_get_page_size(struct spi_nor *nor)
 503{
 504	struct spi_mem_op op =
 505		CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
 506					  0, 0, nor->bouncebuf);
 507	struct spi_nor_flash_parameter *params = nor->params;
 508	int ret;
 509	u8 i;
 510
 511	/*
 512	 * Use the minimum common page size configuration. Programming 256-byte
 513	 * under 512-byte page size configuration is safe.
 514	 */
 515	params->page_size = 256;
 516	for (i = 0; i < params->n_dice; i++) {
 517		op.addr.val = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR3;
 518
 519		ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 520		if (ret)
 521			return ret;
 522
 523		if (!(nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3_PGSZ))
 524			return 0;
 525	}
 526
 527	params->page_size = 512;
 528
 529	return 0;
 530}
 531
 532static void cypress_nor_ecc_init(struct spi_nor *nor)
 533{
 534	/*
 535	 * Programming is supported only in 16-byte ECC data unit granularity.
 536	 * Byte-programming, bit-walking, or multiple program operations to the
 537	 * same ECC data unit without an erase are not allowed.
 538	 */
 539	nor->params->writesize = 16;
 540	nor->flags |= SNOR_F_ECC;
 541}
 542
 543static int
 544s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
 545			  const struct sfdp_parameter_header *bfpt_header,
 546			  const struct sfdp_bfpt *bfpt)
 547{
 548	struct spi_mem_op op;
 549	int ret;
 550
 551	/* Assign 4-byte address mode method that is not determined in BFPT */
 552	nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
 553
 554	ret = cypress_nor_set_addr_mode_nbytes(nor);
 555	if (ret)
 556		return ret;
 557
 558	/* Read Architecture Configuration Register (ARCFN) */
 559	op = (struct spi_mem_op)
 560		CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
 561					  SPINOR_REG_CYPRESS_ARCFN, 1,
 562					  nor->bouncebuf);
 563	ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
 564	if (ret)
 565		return ret;
 566
 567	/* ARCFN value must be 0 if uniform sector is selected  */
 568	if (nor->bouncebuf[0])
 569		return -ENODEV;
 570
 571	return 0;
 572}
 573
 574static int s25fs256t_post_sfdp_fixup(struct spi_nor *nor)
 575{
 576	struct spi_nor_flash_parameter *params = nor->params;
 577
 578	/*
 579	 * S25FS256T does not define the SCCR map, but we would like to use the
 580	 * same code base for both single and multi chip package devices, thus
 581	 * set the vreg_offset and n_dice to be able to do so.
 582	 */
 583	params->vreg_offset = devm_kmalloc(nor->dev, sizeof(u32), GFP_KERNEL);
 584	if (!params->vreg_offset)
 585		return -ENOMEM;
 586
 587	params->vreg_offset[0] = SPINOR_REG_CYPRESS_VREG;
 588	params->n_dice = 1;
 589
 590	/* PP_1_1_4_4B is supported but missing in 4BAIT. */
 591	params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
 592	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_1_1_4],
 593				SPINOR_OP_PP_1_1_4_4B,
 594				SNOR_PROTO_1_1_4);
 595
 596	return cypress_nor_get_page_size(nor);
 597}
 598
 599static int s25fs256t_late_init(struct spi_nor *nor)
 600{
 601	cypress_nor_ecc_init(nor);
 602
 603	return 0;
 604}
 605
 606static const struct spi_nor_fixups s25fs256t_fixups = {
 607	.post_bfpt = s25fs256t_post_bfpt_fixup,
 608	.post_sfdp = s25fs256t_post_sfdp_fixup,
 609	.late_init = s25fs256t_late_init,
 610};
 611
 612static int
 613s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
 614			const struct sfdp_parameter_header *bfpt_header,
 615			const struct sfdp_bfpt *bfpt)
 616{
 617	int ret;
 618
 619	/* Assign 4-byte address mode method that is not determined in BFPT */
 620	nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
 621
 622	ret = cypress_nor_set_addr_mode_nbytes(nor);
 623	if (ret)
 624		return ret;
 625
 626	/* Replace Quad Enable with volatile version */
 627	nor->params->quad_enable = cypress_nor_quad_enable_volatile;
 628
 629	return 0;
 630}
 631
 632static int s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
 633{
 634	struct spi_nor_flash_parameter *params = nor->params;
 635	struct spi_nor_erase_type *erase_type = params->erase_map.erase_type;
 636	unsigned int i;
 637
 638	if (!params->n_dice || !params->vreg_offset) {
 639		dev_err(nor->dev, "%s failed. The volatile register offset could not be retrieved from SFDP.\n",
 640			__func__);
 641		return -EOPNOTSUPP;
 642	}
 643
 644	/* The 2 Gb parts duplicate info and advertise 4 dice instead of 2. */
 645	if (params->size == SZ_256M)
 646		params->n_dice = 2;
 647
 648	/*
 649	 * In some parts, 3byte erase opcodes are advertised by 4BAIT.
 650	 * Convert them to 4byte erase opcodes.
 651	 */
 652	for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
 653		switch (erase_type[i].opcode) {
 654		case SPINOR_OP_SE:
 655			erase_type[i].opcode = SPINOR_OP_SE_4B;
 656			break;
 657		case SPINOR_OP_BE_4K:
 658			erase_type[i].opcode = SPINOR_OP_BE_4K_4B;
 659			break;
 660		default:
 661			break;
 662		}
 663	}
 664
 665	return cypress_nor_get_page_size(nor);
 666}
 667
 668static int s25hx_t_late_init(struct spi_nor *nor)
 669{
 670	struct spi_nor_flash_parameter *params = nor->params;
 671
 672	/* Fast Read 4B requires mode cycles */
 673	params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
 674	params->ready = cypress_nor_sr_ready_and_clear;
 675	cypress_nor_ecc_init(nor);
 676
 677	params->die_erase_opcode = SPINOR_OP_CYPRESS_DIE_ERASE;
 678	return 0;
 679}
 680
 681static const struct spi_nor_fixups s25hx_t_fixups = {
 682	.post_bfpt = s25hx_t_post_bfpt_fixup,
 683	.post_sfdp = s25hx_t_post_sfdp_fixup,
 684	.late_init = s25hx_t_late_init,
 685};
 686
 687/**
 688 * cypress_nor_set_octal_dtr() - Enable or disable octal DTR on Cypress flashes.
 689 * @nor:		pointer to a 'struct spi_nor'
 690 * @enable:              whether to enable or disable Octal DTR
 691 *
 692 * This also sets the memory access latency cycles to 24 to allow the flash to
 693 * run at up to 200MHz.
 694 *
 695 * Return: 0 on success, -errno otherwise.
 696 */
 697static int cypress_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
 698{
 699	return enable ? cypress_nor_octal_dtr_en(nor) :
 700			cypress_nor_octal_dtr_dis(nor);
 701}
 702
 703static int s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
 704{
 705	struct spi_nor_flash_parameter *params = nor->params;
 706
 707	if (!params->n_dice || !params->vreg_offset) {
 708		dev_err(nor->dev, "%s failed. The volatile register offset could not be retrieved from SFDP.\n",
 709			__func__);
 710		return -EOPNOTSUPP;
 711	}
 712
 713	/* The 2 Gb parts duplicate info and advertise 4 dice instead of 2. */
 714	if (params->size == SZ_256M)
 715		params->n_dice = 2;
 716
 717	/*
 718	 * On older versions of the flash the xSPI Profile 1.0 table has the
 719	 * 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE.
 720	 */
 721	if (params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0)
 722		params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode =
 723			SPINOR_OP_CYPRESS_RD_FAST;
 724
 725	/* This flash is also missing the 4-byte Page Program opcode bit. */
 726	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
 727				SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);
 728	/*
 729	 * Since xSPI Page Program opcode is backward compatible with
 730	 * Legacy SPI, use Legacy SPI opcode there as well.
 731	 */
 732	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
 733				SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
 734
 735	/*
 736	 * The xSPI Profile 1.0 table advertises the number of additional
 737	 * address bytes needed for Read Status Register command as 0 but the
 738	 * actual value for that is 4.
 739	 */
 740	params->rdsr_addr_nbytes = 4;
 741
 742	return cypress_nor_get_page_size(nor);
 743}
 744
 745static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
 746				   const struct sfdp_parameter_header *bfpt_header,
 747				   const struct sfdp_bfpt *bfpt)
 748{
 749	/* Assign 4-byte address mode method that is not determined in BFPT */
 750	nor->params->set_4byte_addr_mode = cypress_nor_set_4byte_addr_mode;
 751
 752	return cypress_nor_set_addr_mode_nbytes(nor);
 753}
 754
 755static int s28hx_t_late_init(struct spi_nor *nor)
 756{
 757	struct spi_nor_flash_parameter *params = nor->params;
 758
 759	params->set_octal_dtr = cypress_nor_set_octal_dtr;
 760	params->ready = cypress_nor_sr_ready_and_clear;
 761	cypress_nor_ecc_init(nor);
 762
 763	return 0;
 764}
 765
 766static const struct spi_nor_fixups s28hx_t_fixups = {
 767	.post_sfdp = s28hx_t_post_sfdp_fixup,
 768	.post_bfpt = s28hx_t_post_bfpt_fixup,
 769	.late_init = s28hx_t_late_init,
 770};
 771
 772static int
 773s25fs_s_nor_post_bfpt_fixups(struct spi_nor *nor,
 774			     const struct sfdp_parameter_header *bfpt_header,
 775			     const struct sfdp_bfpt *bfpt)
 776{
 777	/*
 778	 * The S25FS-S chip family reports 512-byte pages in BFPT but
 779	 * in reality the write buffer still wraps at the safe default
 780	 * of 256 bytes.  Overwrite the page size advertised by BFPT
 781	 * to get the writes working.
 782	 */
 783	nor->params->page_size = 256;
 784
 785	return 0;
 786}
 787
 788static void s25fs_s_nor_smpt_read_dummy(const struct spi_nor *nor,
 789					u8 *read_dummy)
 790{
 791	/*
 792	 * The configuration detection dwords in S25FS-S SMPT has 65h as
 793	 * command instruction and 'variable' as configuration detection command
 794	 * latency. Set 8 dummy cycles as it is factory default for 65h (read
 795	 * any register) op.
 796	 */
 797	*read_dummy = 8;
 798}
 799
 800static void s25fs_s_nor_smpt_map_id_dummy(const struct spi_nor *nor, u8 *map_id)
 801{
 802	/*
 803	 * The S25FS512S chip supports:
 804	 *   - Hybrid sector option which has physical set of eight 4-KB sectors
 805	 *     and one 224-KB sector at the top or bottom of address space with
 806	 *     all remaining sectors of 256-KB
 807	 *   - Uniform sector option which has uniform 256-KB sectors
 808	 *
 809	 * On the other hand, the datasheet rev.O Table 71 on page 153 JEDEC
 810	 * Sector Map Parameter Dword-6 Config. Detect-3 does use CR3NV[1] to
 811	 * discern 64-KB(CR3NV[1]=0) and 256-KB(CR3NV[1]=1) uniform sectors
 812	 * device configuration. And in section 7.5.5.1 Configuration Register 3
 813	 * Non-volatile (CR3NV) page 61, the CR3NV[1] is RFU Reserved for Future
 814	 * Use and set to 0, which means 64-KB uniform. Since the device does
 815	 * not support 64-KB uniform sectors in any configuration, parsing SMPT
 816	 * table cannot find a valid sector map entry and fails. Fix this up by
 817	 * setting SMPT by overwriting the CR3NV[1] value to 1, as the table
 818	 * expects.
 819	 */
 820	if (nor->params->size == SZ_64M)
 821		*map_id |= BIT(0);
 822}
 823
 824static const struct spi_nor_fixups s25fs_s_nor_fixups = {
 825	.post_bfpt = s25fs_s_nor_post_bfpt_fixups,
 826	.smpt_read_dummy = s25fs_s_nor_smpt_read_dummy,
 827	.smpt_map_id = s25fs_s_nor_smpt_map_id_dummy,
 828};
 829
 830static const struct flash_info spansion_nor_parts[] = {
 831	{
 832		.id = SNOR_ID(0x01, 0x02, 0x12),
 833		.name = "s25sl004a",
 834		.size = SZ_512K,
 835	}, {
 836		.id = SNOR_ID(0x01, 0x02, 0x13),
 837		.name = "s25sl008a",
 838		.size = SZ_1M,
 839	}, {
 840		.id = SNOR_ID(0x01, 0x02, 0x14),
 841		.name = "s25sl016a",
 842		.size = SZ_2M,
 843	}, {
 844		.id = SNOR_ID(0x01, 0x02, 0x15, 0x4d, 0x00),
 845		.name = "s25sl032p",
 846		.size = SZ_4M,
 847		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 848	}, {
 849		.id = SNOR_ID(0x01, 0x02, 0x15),
 850		.name = "s25sl032a",
 851		.size = SZ_4M,
 852	}, {
 853		.id = SNOR_ID(0x01, 0x02, 0x16, 0x4d, 0x00),
 854		.name = "s25sl064p",
 855		.size = SZ_8M,
 856		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 857	}, {
 858		.id = SNOR_ID(0x01, 0x02, 0x16),
 859		.name = "s25sl064a",
 860		.size = SZ_8M,
 861	}, {
 862		.id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x80),
 863		.name = "s25fl256s0",
 864		.size = SZ_32M,
 865		.sector_size = SZ_256K,
 866		.no_sfdp_flags = SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 867		.mfr_flags = USE_CLSR,
 868	}, {
 869		.id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x00, 0x81),
 870		.name = "s25fs256s0",
 871		.size = SZ_32M,
 872		.sector_size = SZ_256K,
 873		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 874		.mfr_flags = USE_CLSR,
 875	}, {
 876		.id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x01, 0x80),
 877		.name = "s25fl256s1",
 878		.size = SZ_32M,
 879		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 880		.mfr_flags = USE_CLSR,
 881	}, {
 882		.id = SNOR_ID(0x01, 0x02, 0x19, 0x4d, 0x01, 0x81),
 883		.name = "s25fs256s1",
 884		.size = SZ_32M,
 885		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 886		.mfr_flags = USE_CLSR,
 887	}, {
 888		.id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x80),
 889		.name = "s25fl512s",
 890		.size = SZ_64M,
 891		.sector_size = SZ_256K,
 892		.flags = SPI_NOR_HAS_LOCK,
 893		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 894		.mfr_flags = USE_CLSR,
 895	}, {
 896		.id = SNOR_ID(0x01, 0x02, 0x20, 0x4d, 0x00, 0x81),
 897		.name = "s25fs512s",
 898		.size = SZ_64M,
 899		.sector_size = SZ_256K,
 900		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 901		.mfr_flags = USE_CLSR,
 902		.fixups = &s25fs_s_nor_fixups,
 903	}, {
 904		.id = SNOR_ID(0x01, 0x20, 0x18, 0x03, 0x00),
 905		.name = "s25sl12800",
 906		.size = SZ_16M,
 907		.sector_size = SZ_256K,
 908	}, {
 909		.id = SNOR_ID(0x01, 0x20, 0x18, 0x03, 0x01),
 910		.name = "s25sl12801",
 911		.size = SZ_16M,
 912	}, {
 913		.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x00, 0x80),
 914		.name = "s25fl128s0",
 915		.size = SZ_16M,
 916		.sector_size = SZ_256K,
 917		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 918		.mfr_flags = USE_CLSR,
 919	}, {
 920		.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x00),
 921		.name = "s25fl129p0",
 922		.size = SZ_16M,
 923		.sector_size = SZ_256K,
 924		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 925		.mfr_flags = USE_CLSR,
 926	}, {
 927		.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x80),
 928		.name = "s25fl128s1",
 929		.size = SZ_16M,
 930		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 931		.mfr_flags = USE_CLSR,
 932	}, {
 933		.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01, 0x81),
 934		.name = "s25fs128s1",
 935		.size = SZ_16M,
 936		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 937		.mfr_flags = USE_CLSR,
 938		.fixups = &s25fs_s_nor_fixups,
 939	}, {
 940		.id = SNOR_ID(0x01, 0x20, 0x18, 0x4d, 0x01),
 941		.name = "s25fl129p1",
 942		.size = SZ_16M,
 943		.no_sfdp_flags = SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 944		.mfr_flags = USE_CLSR,
 945	}, {
 946		.id = SNOR_ID(0x01, 0x40, 0x13),
 947		.name = "s25fl204k",
 948		.size = SZ_512K,
 949		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
 950	}, {
 951		.id = SNOR_ID(0x01, 0x40, 0x14),
 952		.name = "s25fl208k",
 953		.size = SZ_1M,
 954		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ,
 955	}, {
 956		.id = SNOR_ID(0x01, 0x40, 0x15),
 957		.name = "s25fl116k",
 958		.size = SZ_2M,
 959		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 960	}, {
 961		.id = SNOR_ID(0x01, 0x40, 0x16),
 962		.name = "s25fl132k",
 963		.size = SZ_4M,
 964		.no_sfdp_flags = SECT_4K,
 965	}, {
 966		.id = SNOR_ID(0x01, 0x40, 0x17),
 967		.name = "s25fl164k",
 968		.size = SZ_8M,
 969		.no_sfdp_flags = SECT_4K,
 970	}, {
 971		.id = SNOR_ID(0x01, 0x60, 0x17),
 972		.name = "s25fl064l",
 973		.size = SZ_8M,
 974		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 975		.fixup_flags = SPI_NOR_4B_OPCODES,
 976	}, {
 977		.id = SNOR_ID(0x01, 0x60, 0x18),
 978		.name = "s25fl128l",
 979		.size = SZ_16M,
 980		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 981		.fixup_flags = SPI_NOR_4B_OPCODES,
 982	}, {
 983		.id = SNOR_ID(0x01, 0x60, 0x19),
 984		.name = "s25fl256l",
 985		.size = SZ_32M,
 986		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
 987		.fixup_flags = SPI_NOR_4B_OPCODES,
 988	}, {
 989		.id = SNOR_ID(0x04, 0x2c, 0xc2, 0x7f, 0x7f, 0x7f),
 990		.name = "cy15x104q",
 991		.size = SZ_512K,
 992		.sector_size = SZ_512K,
 993		.flags = SPI_NOR_NO_ERASE,
 994	}, {
 995		.id = SNOR_ID(0x34, 0x2a, 0x1a, 0x0f, 0x03, 0x90),
 996		.name = "s25hl512t",
 997		.mfr_flags = USE_CLPEF,
 998		.fixups = &s25hx_t_fixups
 999	}, {
1000		.id = SNOR_ID(0x34, 0x2a, 0x1b, 0x0f, 0x03, 0x90),
1001		.name = "s25hl01gt",
1002		.mfr_flags = USE_CLPEF,
1003		.fixups = &s25hx_t_fixups
1004	}, {
1005		.id = SNOR_ID(0x34, 0x2a, 0x1c, 0x0f, 0x00, 0x90),
1006		.name = "s25hl02gt",
1007		.mfr_flags = USE_CLPEF,
1008		.fixups = &s25hx_t_fixups
1009	}, {
1010		.id = SNOR_ID(0x34, 0x2b, 0x19, 0x0f, 0x08, 0x90),
1011		.name = "s25fs256t",
1012		.mfr_flags = USE_CLPEF,
1013		.fixups = &s25fs256t_fixups
1014	}, {
1015		.id = SNOR_ID(0x34, 0x2b, 0x1a, 0x0f, 0x03, 0x90),
1016		.name = "s25hs512t",
1017		.mfr_flags = USE_CLPEF,
1018		.fixups = &s25hx_t_fixups
1019	}, {
1020		.id = SNOR_ID(0x34, 0x2b, 0x1b, 0x0f, 0x03, 0x90),
1021		.name = "s25hs01gt",
1022		.mfr_flags = USE_CLPEF,
1023		.fixups = &s25hx_t_fixups
1024	}, {
1025		.id = SNOR_ID(0x34, 0x2b, 0x1c, 0x0f, 0x00, 0x90),
1026		.name = "s25hs02gt",
1027		.mfr_flags = USE_CLPEF,
1028		.fixups = &s25hx_t_fixups
1029	}, {
1030		/* S28HL256T */
1031		.id = SNOR_ID(0x34, 0x5a, 0x19),
1032		.mfr_flags = USE_CLPEF,
1033		.fixups = &s28hx_t_fixups,
1034	}, {
1035		.id = SNOR_ID(0x34, 0x5a, 0x1a),
1036		.name = "s28hl512t",
1037		.mfr_flags = USE_CLPEF,
1038		.fixups = &s28hx_t_fixups,
1039	}, {
1040		.id = SNOR_ID(0x34, 0x5a, 0x1b),
1041		.name = "s28hl01gt",
1042		.mfr_flags = USE_CLPEF,
1043		.fixups = &s28hx_t_fixups,
1044	}, {
1045		/* S28HL02GT */
1046		.id = SNOR_ID(0x34, 0x5a, 0x1c),
1047		.mfr_flags = USE_CLPEF,
1048		.fixups = &s28hx_t_fixups,
1049	}, {
1050		.id = SNOR_ID(0x34, 0x5b, 0x19),
1051		.mfr_flags = USE_CLPEF,
1052		.fixups = &s28hx_t_fixups,
1053	}, {
1054		.id = SNOR_ID(0x34, 0x5b, 0x1a),
1055		.name = "s28hs512t",
1056		.mfr_flags = USE_CLPEF,
1057		.fixups = &s28hx_t_fixups,
1058	}, {
1059		.id = SNOR_ID(0x34, 0x5b, 0x1b),
1060		.name = "s28hs01gt",
1061		.mfr_flags = USE_CLPEF,
1062		.fixups = &s28hx_t_fixups,
1063	}, {
1064		.id = SNOR_ID(0x34, 0x5b, 0x1c),
1065		.name = "s28hs02gt",
1066		.mfr_flags = USE_CLPEF,
1067		.fixups = &s28hx_t_fixups,
1068	}, {
1069		.id = SNOR_ID(0xef, 0x40, 0x13),
1070		.name = "s25fl004k",
1071		.size = SZ_512K,
1072		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
1073	}, {
1074		.id = SNOR_ID(0xef, 0x40, 0x14),
1075		.name = "s25fl008k",
1076		.size = SZ_1M,
1077		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
1078	}, {
1079		.id = SNOR_ID(0xef, 0x40, 0x15),
1080		.name = "s25fl016k",
1081		.size = SZ_2M,
1082		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
1083	}, {
1084		.id = SNOR_ID(0xef, 0x40, 0x17),
1085		.name = "s25fl064k",
1086		.size = SZ_8M,
1087		.no_sfdp_flags = SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ,
1088	}
1089};
1090
1091/**
1092 * spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the
1093 * flash is ready for new commands and clear it if there are any errors.
1094 * @nor:	pointer to 'struct spi_nor'.
1095 *
1096 * Return: 1 if ready, 0 if not ready, -errno on errors.
1097 */
1098static int spansion_nor_sr_ready_and_clear(struct spi_nor *nor)
1099{
1100	int ret;
1101
1102	ret = spi_nor_read_sr(nor, nor->bouncebuf);
1103	if (ret)
1104		return ret;
1105
1106	if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
1107		if (nor->bouncebuf[0] & SR_E_ERR)
1108			dev_err(nor->dev, "Erase Error occurred\n");
1109		else
1110			dev_err(nor->dev, "Programming Error occurred\n");
1111
1112		spansion_nor_clear_sr(nor);
1113
1114		/*
1115		 * WEL bit remains set to one when an erase or page program
1116		 * error occurs. Issue a Write Disable command to protect
1117		 * against inadvertent writes that can possibly corrupt the
1118		 * contents of the memory.
1119		 */
1120		ret = spi_nor_write_disable(nor);
1121		if (ret)
1122			return ret;
1123
1124		return -EIO;
1125	}
1126
1127	return !(nor->bouncebuf[0] & SR_WIP);
1128}
1129
1130static int spansion_nor_late_init(struct spi_nor *nor)
1131{
1132	struct spi_nor_flash_parameter *params = nor->params;
1133	struct spansion_nor_params *priv_params;
1134	u8 mfr_flags = nor->info->mfr_flags;
1135
1136	if (params->size > SZ_16M) {
1137		nor->flags |= SNOR_F_4B_OPCODES;
1138		/* No small sector erase for 4-byte command set */
1139		nor->erase_opcode = SPINOR_OP_SE;
1140		nor->mtd.erasesize = nor->info->sector_size ?:
1141			SPI_NOR_DEFAULT_SECTOR_SIZE;
1142	}
1143
1144	if (mfr_flags & (USE_CLSR | USE_CLPEF)) {
1145		priv_params = devm_kmalloc(nor->dev, sizeof(*priv_params),
1146					   GFP_KERNEL);
1147		if (!priv_params)
1148			return -ENOMEM;
1149
1150		if (mfr_flags & USE_CLSR)
1151			priv_params->clsr = SPINOR_OP_CLSR;
1152		else if (mfr_flags & USE_CLPEF)
1153			priv_params->clsr = SPINOR_OP_CLPEF;
1154
1155		params->priv = priv_params;
1156		params->ready = spansion_nor_sr_ready_and_clear;
1157	}
1158
1159	return 0;
1160}
1161
1162static const struct spi_nor_fixups spansion_nor_fixups = {
1163	.late_init = spansion_nor_late_init,
1164};
1165
1166const struct spi_nor_manufacturer spi_nor_spansion = {
1167	.name = "spansion",
1168	.parts = spansion_nor_parts,
1169	.nparts = ARRAY_SIZE(spansion_nor_parts),
1170	.fixups = &spansion_nor_fixups,
1171};
~/ Read-only file preview.