前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spi-mem: 为SPI存储器生态带来一些一致性

spi-mem: 为SPI存储器生态带来一些一致性

作者头像
zqb_all
发布2019-12-27 10:52:15
1.1K0
发布2019-12-27 10:52:15
举报
文章被收录于专栏:QB杂货铺QB杂货铺

在本文中,我们将介绍关于spi-mem Linux内核框架的工作,该框架将允许在SPI NOR设备和常规SPI设备以及SPI NAND设备上复用SPI控制器驱动程序。

从SPI到双线、四线、八线SPI

在过去,SPI是一个简单的协议,总线上的所有设备只共享3根信号线:

  • MISO: Master In Slave Out,主设备输入从设备输出线
  • MOSI: Master Out Slave In,主设备输出从设备输入线
  • SCLK: Serial Clock,时钟线

另外每个设备有一个独立信号线,用于选择我们想要通信的设备:

  • SS: Slave Select,从设备选择线 (有时也称为片选线CS,Chip Select)

但随后SPI存储出现了。它从较小且相对较慢的SPI NORs开始,如dataflash、EEPROMs和SRAMs,然后逐渐发展到较大的SPI NORs和SPI NANDs。像往常一样,当涉及到处理存储时,我们希望得到最佳性能表现。SPI总线的限制很快成为瓶颈,因此供应商决定添加更多的I/O线路,并使 MISO/MOSI 线可以双向通信。现在我们看到SPI控制器支持最多8路I/O。这就是业内所说的DualSPI QuadSPI和OctoSPI。

为了在主从设备的数据传输中用上所有的I/O线,必须有某种主从设备之间的协议,这样双方才能知道,何时可以在I/O线上收发数据,应该使用多少根I/O线等。这些由一组从设备预定义的操作规定了如何进行,主设备必须遵循这组操作的规定,进入特定的发送或接收状态。SPI存储器操作通常包括:

  • 1字节的操作码,表示将要进行从操作 (未来将很快会将出现2字节的操作码,请做好准备)
  • 0-N 字节的地址,其含义取决于操作码(可以是绝对内存地址,或其他含义)
  • 0-N 字节的哑字节,使得从设备有足够的时间来进入操作码请求的特定状态,同样,哑字节的数量时取决于操作码的
  • 0-N 字节的输入或输出数据,方向是取决于操作码

请注意,虽然这个协议倾向于被用于存储设备,但并没有什么能限制它只能用于存储设备,如果一些FPGA使用相同的协议来操作非存储设备,我也不会感到惊讶。

Linux SPI 生态

Linux支持双线SPI和四线SPI模式已经有一段时间了(v3.12), SPI设备驱动程序可以为每个SPI传输指定I/O通道的数量。使用这种方式,对SPI存储的操作可以被分为多次SPI传输,每次SPI传输使用预定义数量的I/O通道进行传输。

这种方式可以正常工作,直到一些IP供应商决定让它们的SPI控制器更加智能,嵌入某种高级接口,可以在单个的步骤中执行SPI存储器的操作,而不是使用分开的多次传输操作。(事实上,大多数SPI控制器甚至比这更加智能,可以允许你直接将SPI存储映射到CPU的地址空间,但让我们先把这种情况留待以后处理吧)。在这种情况下,我们需要赋予SPI控制器更多的控制权,这样它就可以决定具体该做什么,而不必从一组分散的SPI传输命令中,重建SPI存储器操作。

当时的决定是,将这些控制器专门用于一个任务,控制SPI NORs(当时这是唯一会用到双线和四线模式的情况),SPI NOR框架就是为此而创建的。

由于这个决定,我们现在在Linux中有一个SPI NOR框架用于连接SPI NOR控制器驱动和SPI NOR的逻辑代码(spi-nor 子系统),同时我们有常规的SPI控制器驱动,可以进行基础的SPI传输(spi 子系统)。然而,从硬件的角度看,能为SPI NOR提供特殊特性的SPI控制器,一般也拥有进行基本传输的能力,即可用于控制常规的SPI设备。不幸的是,基于当前的spi-nor 子系统和spi 子系统是分裂开来的情况,如果一个SPI控制器被spi-nor子系统的驱动支持了,它将无法被用于与spi子系统中的常规设备进行通信。

作为一个针对这个问题的部分的解决方案,->spi_flash_read()操作被添加到结构体 spi_controller中,这允许spi子系统中的常规spi控制器驱动提供一个较优的方式,来从SPI NOR存储中读取数据,这种方式被通用SPI NOR驱动m25p80所使用。然而,这个解决方案是部分的,因为它只优化了读取,并且仅限于SPI NORs。

在当前的架构中,我们有

  • SPI NOR框架,它包含与SPI NOR存储器通讯的协议。这个框架依赖于结构体spi_nor中列出的接口,这些接口的实现是:
  • 专用的SPI NOR控制器,支持专用于SPI NORs的高级SPI控制器
  • m25p80驱动,提供同样的接口,但基于常规SPI控制器驱动,可能具有->spi_flash_read()的优化

是什么促使我们提出SPI存储器接口?

我们之前已经看到,基于SPI NOR框架,SPI NOR存储器已经得到了适当的支持。但NORs 并非SPI总线上唯一的存储设备,SPI NANDs 正在变得越来越流行。

Peter Pan提出了一个遵循SPI NOR模型的,用于支持SPI NAND设备的框架: SPI控制器必须实现SPI NAND控制器接口才能控制SPI NAND。但是当我们更深入地参与到这个开发中时,我们很快意识到沿着这条路走会有多么麻烦,因为这意味着,如果SPI控制器想要同时控制两种设备,就必须同时实现SPI NOR和SPI NAND接口。当SPI NVRAM或任何其他类型的存储制造商决定采用SPI总线时,将会发生什么?再添加一个SPI控制器必须实现的接口?这听起来不是个好主意。

因此我们决定用另外的方式解决这个问题,尝试找出SPI NANDs和SPI NORs的共同点。SPI NORs和SPI NANDs 指令集不同,行为和约束也不同(主要是由于NOR和NAND本身的不同),但当与设备交互时,都遵循同样的SPI存储器操作语义,这也是高级控制器都在尝试优化的部分。

SPI 存储器层只是提供一种方式给SPI控制器驱动,用于传递高级SPI存储器操作,而不是让它们处理SPI传输细节并自行尝试优化它们。这同样简化了SPI存储器驱动,因为它们只需要按照SPI存储器规范发送SPI存储器操作指令,不需要关心复杂的、不断发展的、依赖具体存储器的接口。

有了这个新的架构,SPI NOR和SPI NAND都可以基于相同的SPI控制器驱动进行支持了。m25p80驱动将被修改成,使用spi-mem接口,取代具有局限性的->spi_flash_read()接口。目前,我们仍然有专用的SPI NOR控制器驱动,但最终目标是移除它们,并将它们移植为 drivers/spi 下的普通SPI控制器驱动。非常欢迎这方面的帮助和贡献。

SPI存储器API是什么样子的?

SPI存储器的API 由 include/linux/spi/spi-mem.h 描述。

希望使用SPI存储器API的SPI设备驱动程序,应该将自己声明为spi_mem_drivers,并实现->probe()和->remove()函数。

它们将被传入一个spi_mem对象,它只是一个围绕spi_device对象的简单包装,我们引入一个不同的对象的原因是,我们希望能够拓展spi_mem对象,并在需要时附加更多的信息(例如存储器类型,存储器组织方式和其他的高级SPI控制器可能需要的信息)。

当驱动想要执行SPI存储器操作时,它将填充spi_mem_op结构并调用spi_mem_exec_op()。另外,可以使用spi_mem_supports_op(),测试一个SPI控制器是否支持特定的存储器操作,使用spi_mem_adjust_op_size(),获取控制器支持的最大传输大小,并尝试拆分数据传输以避免超出限制。

现在让我们看下控制器端。一个希望优化SPI存储器操作的SPI控制器,可以实现spi_mem_ops接口,该接口包含三个直接对应用户API的方法:

  • ->exec_op():执行存储器操作,如果不支持则返回-ENOTSUPP。
  • ->supports_op(): 检查这个存储器操作是否支持。
  • ->adjust_op_size(): 调整存储器操作的数据传输大小,以符合对齐要求和最大FIFO大小的约束。

注意,当spi_mem_ops 没有实现时,core层将通过创建由多个SPI传输组成的SPI消息,来添加对该特性的通用支持,就像以前通用SPI NOR控制器驱动程序(名为m25p80)所做的那样。

如你所见,这些API非常直截了当,所以希望有更多的SPI存储器驱动能够转换为使用它,而不是手动创建包含多个SPI传输的SPI消息。

当前状态

一部分已经被贡献出去并合并,计划成为Linux 4.18的一部分:

下一步是什么?

先进的SPI控制器不仅能够优化SPI存储器操作的执行,它们可以进一步将所有存储器访问的复杂性隐藏起来,提供一个直接映射的IOMEM区域,对此区域的访问会自动在总线上触发SPI存储器操作,为你完成数据的收发,这样的行为就像一个连接在并行的内存总线上的内存。可以想象,这将允许更高的吞吐量和更少的用于SPI存储器操作管理的CPU时间,但这同时也是一个难以通过常规的方式进行支持的功能。我们已经在linux-mtd邮件列表上发布了一个支持这种直接映射功能的建议

如前所述,另一个具有挑战性的主题是,将所有的SPI NOR控制器驱动转换为基于SPI mem模型,以便所有的QSPI控制器都真正表现为SPI控制器而非SPI NOR控制器。这可能需要一些时间,因为目前在driver/mtd/spi-nor 下有10个驱动,我们只知道其中2个被转换为了SPI mem方法(fsl-quadspi和atmel-quadspi)。

本文地址 https://cloud.tencent.com/developer/article/1560552

译自 https://bootlin.com/blog/spi-mem-bringing-some-consistency-to-the-spi-memory-ecosystem/

原作者 Boris Brezillon

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-05-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 从SPI到双线、四线、八线SPI
  • Linux SPI 生态
  • 是什么促使我们提出SPI存储器接口?
  • SPI存储器API是什么样子的?
  • 当前状态
  • 下一步是什么?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档