Cadence QSPI调试

2.调试问题

2.1 uboot

2.1.1 dts解析报错

问题现象】

Uboot命令行执行sf probe提示error。 

(1)Invalid bus 0 (err=-19)

(2)Error: subnode with SPI flash config missing!

(3)fdtdec_get_addr_size_auto_noparent: fdtdec_get_addr_size_auto_parent: na=2, ns=2, fdtdec_get_addr_size_fixed: reg: (not enough data:

 expected >= 8 cells, got 4 cells)

【问题原因】

以上错误信息均由dts配置引起,包括qspi需要配置别名,qspi需要配置flash芯片子节点,地址配置需要按照指定的cell长度等,修复后的正确配置如下。

[uboot\arch\arm\dts\tsm_tx511.dtsi]

qspi: spi@f0d9e000 {

    compatible =  "cdns,qspi-nor";

    reg = <0x0 0xf0d9e000 0x0 0x1000>,

                  <0x0 0xe0000000 0x0 0x10000000>;

    num-cs = <4>;    

    cdns,fifo-depth = <256>;

    cdns,fifo-width = <4>;

};

[uboot\arch\arm\dts\tsm_tx511_fpga.dts]

aliases {

    spi0 = &qspi;

};

&qspi {

    status = "okay";

    flash@0 {

        compatible = "jedec,spi-nor";

        spi-max-frequency = <108000000>; /* Based on DC1 spec */

    };

};

2.1.2 ahb访问异常

【问题现象】

sf probe或者手动访问ahb触发异常。

=> md.l 0xe0000000 8                     

e0000000:"Synchronous Abort" handler, esr 0x96000006 
elr: 0000000001036a78 lr : 00000000010369d4 (reloc) 
elr: 000000003ffada78 lr : 000000003ffad9d4 
x0 : 0000000000000009 x1 : 0000000000000000 
x2 : 000000000000003a x3 : 00000000f0d8a000 
x4 : 00000000e0000000 x5 : 000000003f3fec88 
x6 : 000000003f3ff1e8 x7 : 000000003ffc15a0 
x8 : 0000000000000004 x9 : 0000000000000004 
x10: 0000000000000044 x11: 00000000000186a0 
x12: 000000000001869f x13: 0000000000000021 
x14: 0000000000000008 x15: 000000003f3fec88 
x16: 000000003ff99be8 x17: 0000000000000040 
x18: 000000003f3ffde0 x19: 0000000000000008 
x20: 00000000e0000000 x21: 00000000e0000000 
x22: 000000003ffc0e66 x23: 0000000000000008 
x24: 0000000000000004 x25: 000000003ffc0000 
x26: 0000000000000004 x27: 0000000000000004  
x28: 0000000000000000 x29: 000000003f3ff160                                      
Code: 12800000 17ffffce 7100137f 540001e1 (b9400081)   
Resetting CPU ...

【问题原因】

MMU表项配置OSPI的ahb地址少了个0,软件访问的AHB地址未找到物理地址,触发异常。

uboot\arch\arm\mach-tsm\cpu.c

 

2.1.3 32MB Flash读内容为0x0

【问题现象】

16MB的Flash读内容正常,但32MB的Flash读取内容为0x0。

=> sf read 0x8000000 0 0x1000

device 0 offset 0x0, size 0x1000

cadence_qspi_apb_chipselect : chipselect 0 decode 0

SF: 4096 bytes @ 0x0 Read: OK

=> md.b 0x8000000 10

08000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

=>

【问题原因】

大于16MB的Flash采用4 byte地址访问,此时需要改用4 byte模式下的Read指令。指令替换在spi_nor_scan()->spi_nor_set_4byte_opcodes()中执行。spi-nor-ids.c中的白名单数组配置中对于大于16MB的芯片需配上SPI_NOR_4B_OPCODES标志。

 

 白名单配置修改。

 

16MB Flash和32MB Flash Read指令对比,前者使用3 byte 模式的0x0b,后者使用4byte模式的0xc。

 

2.1.4 QSPI QE无法保存

【问题现象】

从QSPI FLASH启动,ATF阶段已经配置过QE使能位,到uboot或者内核阶段再读status寄存器,应该读到使能标志,但每次重启后,uboot/内核驱动调用quad_enable()之前读到的QE都为0。

【问题原因】

uboot/内核驱动在调用quad_enable()之前会调用write_sr(nor, 0)。这里虽然只写了status寄存器的一个byte,但是在SPI模式cs拉高后会清掉QE。该现象目前仅在gd25lq128出现,非普遍现象,非问题。

 

 

  2.2 kernel

2.2.1INDAC read死循环

【问题现象】

uboot驱动采用DAC模式访问,内核驱动采用INDAC模式访问。Uboot驱动采用轮询方式,内核驱动阶段采用中断方式,读写操作与中断有交互。正常读写流程发起后会等待中断调用complete()进行同步,以执行下一步处理。

出问题时中断未触发,且cpu反复读SRAM,但是CQSPI_REG_SDRAMLEVEL寄存器指示SRAM中始终有数据,一直未被读走,导致软件陷入死循环。

【问题原因】

中断配置,trigger address配置有误。

手册里ospi_int中断号为78,dts中原先配置interrupts = <0 78 0>,内核起来后体现为中断号110,边沿触发。实际上中断号应减去32,改为SPI中断开始的中断号,触发方式改为电平触发。

 

 修改后的中断配置,

qspi: spi@f0d9e000 {

interrupt-parent = <&gic>;

interrupts = <0 46 4>;

}

root@(none):/# cat /proc/interrupts | grep spi                                                                                   

           CPU0       CPU1                                                                                                                                                                                   
  9:          1          0     GIC-0  78 Level     f0d9e000.spi       

INDAC方式下CQSPI_REG_INDIRECTTRIGGER(1Ch)写入INDAC模式访问的基地址,该寄存器需配置为AHB的物理地址0xe0000000,这样当内核驱动读该地址时才会触发INDAC访问。否则如果AHB访问地址不在INDAC地址区间内,则该访问一直由DAC执行,由此导致INDAC模式使用的SRAM中数据未被取走。

2.2.2 OSPI 1-1-8模式读取内容错位

【问题现象】

1-1-1模式下发的Rd指令为0x0c,1-1-8模式下的Rd指令为0x8b。读到的数据为8Byte之后的内容,有错位。

 

 【问题原因】

类似问题2.1.3,内核驱动版本比较老,

spi_nor_scan()->spi_nor_set_4byte_opcodes()->spi_nor_convert_3to4_read()对1-1-8模式支持不全。从新内核版本移植1-1-8模式下4byte的指令之后,1-1-8读指令切换为SPINOR_OP_READ_1_1_8_4B(0x7c),后读数据内容ok,问题解决。

注意对于Giga芯片,并下发SPINOR_OP_EN4B命令进入4byte模式,而仅仅是使用4byte的读指令。

3. 代码流程

见uboot_sf_flow.emmx。

4.调试命令

4.1 uboot

(1) sf probe [[bus:]cs] [hz] [mode]

- init flash device on given SPI bus  and chip select                                                                                   

(2) sf read addr offset|partition len 

- read `len' bytes starting at `offset' or from start of mtd `partition'to memory at `addr'                                                            

(3) sf write addr offset|partition len      

- write `len' bytes from memory at `addr' to flash at `offset' or to start of mtd `partition'                                                            

(4) sf erase offset|partition [+]len        

- erase `len' bytes from `offset' or from start of mtd `partition' `+len' round up `len' to block size                                                        

(5) sf test offset len              

- run a very basic destructive test   

sf probe mode字段说明

mode字段定义 uboot/include/spi.h

 

示例:

1线模式

sf probe 0:0 1000000 0x3

8线模式

sf probe 0:0 1000000 0x8103

4线模式

sf probe 0:0 1000000 0x2103                                                        

4.2 kernel

4.2.1 mtd_debug

# mtd_debug                                                                                                                         

usage: mtd_debug info <device>                                                                                                      

       mtd_debug read <device> <offset> <len> <dest-filename>                                                                       

       mtd_debug write <device> <offset> <len> <source-filename>                                                                    

       mtd_debug erase <device> <offset> <len>

示例:

# mtd_debug erase /dev/mtd1 0 0x100000                                                                                              

Erased 1048576 bytes from address 0x00000000 in flash                                                                               

# mtd_debug read /dev/mtd1 0 0x5000 /tmp/rd_1.bin                                                                                      

Copied 20480 bytes from address 0x00000000 in flash to /tmp/rd_1.bin                                                                   

# hexdump -C /tmp/rd_1.bin                                                                                                               

00000000  ff ff ff ff ff ff ff ff  ff ff ff ff ff ff ff ff  |................|                                                      

*                                                                                                                                   

00005000                                                                                                                            

#

4.2.2 sysfs

(1) cat /sys/cdns_qspi/cqspidbg

dump寄存器或者驱动控制块

(2) echo readreg <offset> > /sys/cdns_qspi/cqspidbg

读寄存器

(3) echo writereg <offset> <value> > /sys/cdns_qspi/cqspidbg

写寄存器

(4) echo readid 0 > /sys/cdns_qspi/cqspidbg

读devid

(5) echo readstatus 0 > /sys/cdns_qspi/cqspidbg

读status/config/flag寄存器

(6) echo erase <offset> <length> > /sys/cdns_qspi/cqspidbg

擦除指定偏移和长度的sector区域                                                                                      

(7) echo readdata <offset> <length> > /sys/cdns_qspi/cqspidbg

从指定偏移位置读指定长度的内容到临时文件

(8) echo writedata <offset> <length> <pattern> > /sys/cdns_qspi/cqspidbg

向指定偏移位置写入指定长度的内容,具体内容由pattern决定   

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值