在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 控制器进行打补丁