ZYNQ使用W25Q256问题笔记

在zynq使用w25q256出现问题,先把问题记录下来,暂时为解决。

我们使用环境 Linux-5.4.151,使用SPI FLASH启动,SPI FLASH :W25q256 (32MB)

内核启动 spi flash 报错,中间有添加打印调试信息

[    0.592838] Initialise system trusted keyrings
[    0.597462] workingset: timestamp_bits=30 max_order=18 bucket_order=0
[    0.610471] ntfs: driver 2.1.32 [Flags: R/W].
[    0.655821] Key type asymmetric registered
[    0.659917] Asymmetric key parser 'x509' registered
[    0.664882] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 250)
[    0.672269] io scheduler mq-deadline registered
[    0.676824] io scheduler kyber registered
[    0.682413] dma-pl330 f8003000.dmac: Loaded driver for PL330 DMAC-241330
[    0.689161] dma-pl330 f8003000.dmac:         DBUFF-128x8bytes Num_Chans-8 Num_Peri-4 Num_Events-16
[    0.754711] Serial: 8250/16550 driver, 5 ports, IRQ sharing disabled
[    0.762863] STMicroelectronics ASC driver initialized
[    0.777388] brd: module loaded
[    0.789431] loop: module loaded
[    0.793948] spi-nor spi0.0: flash:w25q256
[    0.798018] spi-nor spi0.0: flash id:ef-40-19-0-0-0
[    0.802895] spi-nor spi0.0: flash id len:3
[    0.807027] spi-nor spi0.0: flash sector size:65536
[    0.811896] spi-nor spi0.0: flash nsector size:512
[    0.816702] spi-nor spi0.0: flash page size:256
[    0.821227] spi-nor spi0.0: flash addr width:0
[    0.825689] spi-nor spi0.0: flash flags:97
[    0.829777] spi-nor spi0.0: flash:w25q256
[    0.833780] spi-nor spi0.0: flash id:ef-40-19-0-0-0
[    0.838669] spi-nor spi0.0: flash id len:3
[    0.842762] spi-nor spi0.0: flash sector size:65536
[    0.847657] spi-nor spi0.0: flash nsector size:512
[    0.852440] spi-nor spi0.0: flash page size:256
[    0.856992] spi-nor spi0.0: flash addr width:0
[    0.861433] spi-nor spi0.0: flash flags:97
[    0.865713] hwcaps:8 line:2816
[    0.868757] hwcaps:16 line:2816
[    0.871889] hwcaps:128 line:2816
[    0.875148] hwcaps:256 line:2816
[    0.878365] hwcaps:512 line:2816
[    0.881597] spi-nor spi0.0: share:66459 hw mask 8355839
[    0.886838] hwcaps:1 line:2816
[    0.889884] jjl 2810
[    0.892061] hwcaps:2 line:2816
[    0.895130] jjl 2810
[    0.897305] hwcaps:8 line:2816
[    0.900351] jjl 2810
[    0.902529] hwcaps:16 line:2816
[    0.905689] jjl 2810
[    0.907868] hwcaps:128 line:2816
[    0.911088] jjl 2810
[    0.913267] hwcaps:256 line:2816
[    0.916508] jjl 2810
[    0.918683] hwcaps:65536 line:2816
[    0.922076] jjl 2810
[    0.924286] spi-nor spi0.0: nor spi mem
[    0.928112] spi-nor spi0.0: share:0
[    0.931592] spi-nor spi0.0: can't select read settings supported by both the SPI controller and memory.
[    0.941012] spi-nor: probe of spi0.0 failed with error -22
[    0.946526] Xilinx QSPI Driver:700
[    0.950431] sdhci: Secure Digital Host Controller Interface driver
[    0.956648] sdhci: Copyright(c) Pierre Ossman
[    0.960998] Synopsys Designware Multimedia Card Interface Driver
[    0.967239] sdhci-pltfm: SDHCI platform and OF driver helper
[    0.999035] mmc0: SDHCI controller on e0100000.sdhci [e0100000.sdhci] using ADMA
[    1.006925] ledtrig-cpu: registered to indicate activity on CPUs
[    1.013462] fpga_manager fpga0: Xilinx Zynq FPGA Manager registered
[    1.020642] Registering SWP/SWPB emulation handler
[    1.026245] Loading compiled-in X.509 certificates
[    1.043940] UBI error: cannot open mtd 3, error -19
[    1.048934] hctosys: unable to open rtc device (rtc0)
[    1.054557] VFS: Cannot open root device "ubi0:rootfs" or unknown-block(0,0): error -19
[    1.062612] Please append a correct "root=" boot option; here are the available partitions:
[    1.071307] 0100           65536 ram0 
[    1.071311]  (driver?)
[    1.077483] 0101           65536 ram1 
[    1.077487]  (driver?)
[    1.083664] 0102           65536 ram2 
[    1.083667]  (driver?)
[    1.089821] 0103           65536 ram3 
[    1.089825]  (driver?)
[    1.095989] 0104           65536 ram4 
[    1.095993]  (driver?)
[    1.102174] 0105           65536 ram5 
[    1.102177]  (driver?)
[    1.108385] 0106           65536 ram6 
[    1.108389]  (driver?)
[    1.114583] 0107           65536 ram7 
[    1.114587]  (driver?)
[    1.120761] 0108           65536 ram8 
[    1.120764]  (driver?)
[    1.126965] 0109           65536 ram9 
[    1.126968]  (driver?)
[    1.133142] 010a           65536 ram10 
[    1.133145]  (driver?)
[    1.139485] 010b           65536 ram11 
[    1.139488]  (driver?)
[    1.145782] 010c           65536 ram12 
[    1.145785]  (driver?)
[    1.152051] 010d           65536 ram13 
[    1.152054]  (driver?)
[    1.158345] 010e           65536 ram14 
[    1.158349]  (driver?)
[    1.164588] 010f           65536 ram15 
[    1.164591]  (driver?)
[    1.170778] Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0)
[    1.179044] CPU1: stopping
[    1.181753] CPU: 1 PID: 0 Comm: swapper/1 Not tainted 5.4.151 #28
[    1.187839] Hardware name: Xilinx Zynq Platform

分析源码

在drivers/mtd/spi-nor/spi-nor.c中

static int spi_nor_default_setup(struct spi_nor *nor,
				 const struct spi_nor_hwcaps *hwcaps)
{
	struct spi_nor_flash_parameter *params = &nor->params;
	u32 ignored_mask, shared_mask;
	int err;

	/*
	 * Keep only the hardware capabilities supported by both the SPI
	 * controller and the SPI flash memory.
	 */
	shared_mask = hwcaps->mask & params->hwcaps.mask;
dev_err(nor->dev,"share:%d hw mask %d\n",shared_mask,hwcaps->mask);
	if (nor->spimem) {
		/*
		 * When called from spi_nor_probe(), all caps are set and we
		 * need to discard some of them based on what the SPI
		 * controller actually supports (using spi_mem_supports_op()).
		 */
		spi_nor_spimem_adjust_hwcaps(nor, &shared_mask);
		dev_err(nor->dev,"nor spi mem\n");
	} else {
		/*
		 * SPI n-n-n protocols are not supported when the SPI
		 * controller directly implements the spi_nor interface.
		 * Yet another reason to switch to spi-mem.
		 */
		ignored_mask = SNOR_HWCAPS_X_X_X;
		dev_err(nor->dev,"ig mask :%d\n",ignored_mask);
		if (shared_mask & ignored_mask) {
			dev_dbg(nor->dev,
				"SPI n-n-n protocols are not supported.\n");
			shared_mask &= ~ignored_mask;
		}
	}

	/* Select the (Fast) Read command. */
	err = spi_nor_select_read(nor, shared_mask);
	if (err) {
		dev_err(nor->dev,"share:%d\n",shared_mask);
		dev_err(nor->dev,
			"can't select read settings supported by both the SPI controller and memory.\n");
		return err;
	}

	/* Select the Page Program command. */
	err = spi_nor_select_pp(nor, shared_mask);
	if (err) {
		dev_err(nor->dev,
			"can't select write settings supported by both the SPI controller and memory.\n");
		return err;
	}

	/* Select the Sector Erase command. */
	err = spi_nor_select_erase(nor);
	if (err) {
		dev_err(nor->dev,
			"can't select erase settings supported by both the SPI controller and memory.\n");
		return err;
	}

	return 0;
}

发现是上述函数

spi_nor_spimem_adjust_hwcaps(nor, &shared_mask);

把shared_mask给置零

追踪函数

static int spi_nor_spimem_check_op(struct spi_nor *nor,
				   struct spi_mem_op *op)
{
	/*
	 * First test with 4 address bytes. The opcode itself might
	 * be a 3B addressing opcode but we don't care, because
	 * SPI controller implementation should not check the opcode,
	 * but just the sequence.
	 */
	op->addr.nbytes = 4;
	if (!spi_mem_supports_op(nor->spimem, op)) {
		if (nor->mtd.size > SZ_16M)
			return -ENOTSUPP;

		/* If flash size <= 16MB, 3 address bytes are sufficient */
		op->addr.nbytes = 3;
		if (!spi_mem_supports_op(nor->spimem, op))
			return -ENOTSUPP;
	}

	return 0;
}

函数spi_nor_spimem_check_op返回ENOTSUPP。w25q256是32M FLASH这里会检查spi控制器是否支持4字节地址spi_mem_supports_op,这个函数调用spi控制器中函数zynq_qspi_supports_op

位置drivers\spi\spi-zynq-qspi.c

static bool zynq_qspi_supports_op(struct spi_mem *mem,
				  const struct spi_mem_op *op)
{
	if (!spi_mem_default_supports_op(mem, op))
		return false;

	/*
	 * The number of address bytes should be equal to or less than 3 bytes.
	 */
	if (op->addr.nbytes > 3)
		return false;

	return true;
}

4字节地址,直接返回错误,看来需要对zynq spi 控制器进行打补丁

上一篇:Linux内核4.14版本——SPI NOR子系统(2)——spi-nor.c分析


下一篇:使用STM32进行Flash的读写