HamsterBear F1C200s Linux v5.17.0 SPI总线适配(未完)

HamsterBear F1C200s Linux SPI总线适配

  • SoC - F1C200s

  • Kernel 版本 - v5.17.0


修改设备树文件

添加头文件

#include <dt-bindings/clock/suniv-ccu-f1c100s.h>
#include <dt-bindings/reset/suniv-ccu-f1c100s.h>

添加dma节点

                dma: dma-controller@1c02000 {
                        compatible = "allwinner,suniv-f1c100s-dma";
                        reg = <0x01c02000 0x1000>;
                        interrupts = <18>;
                        clocks  = <&ccu CLK_BUS_DMA>;
                        //clock-names = "ahb", "mod";
                        resets = <&ccu RST_BUS_DMA>;
                        status = "disabled";
                        #dma-cells = <1>;
                };

添加spi节点

                spi0: spi@1c05000 {
                        compatible = "allwinner,sun8i-h3-spi";
                        reg = <0x01c05000 0x1000>;
                        interrupts = <10>;
                        clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_BUS_SPI0>;
                        clock-names = "ahb", "mod";
                        dmas = <&dma 4>, <&dma 4>;
                        dma-names = "rx", "tx";
                        resets = <&ccu RST_BUS_SPI0>;
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
                };

                spi1: spi@1c06000 {
                        compatible = "allwinner,sun8i-h3-spi";
                        reg = <0x01c06000 0x1000>;
                        interrupts = <11>;
                        clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_BUS_SPI1>;
                        clock-names = "ahb", "mod";
                        dmas = <&dma 5>, <&dma 5>;
                        dma-names = "rx", "tx";
                        resets = <&ccu RST_BUS_SPI1>;
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
                };

pio下添加spi引脚组

                        spi0_pc_pins: spi0-pc-pins {
                                pins = "PC0", "PC1", "PC2", "PC3";
                                function = "spi0";
                        };


                        spi1_pa_pins: spi1-pa-pins {
                                pins = "PA0", "PA1", "PA2", "PA3";
                                function = "spi1";
                        };

引用dma节点

&dma {
        status = "okay";
};

引用spi节点,添加spi设备

&spi0 {
        pinctrl-names = "default";
        pinctrl-0 = <&spi0_pc_pins>;
        status = "okay";
        spi-max-frequency = <50000000>;
};

&spi1 {
        pinctrl-names = "default";
        pinctrl-0 = <&spi1_pa_pins>;
        status = "okay";
        spi-max-frequency = <50000000>;
};

开启内核驱动支持

对于suniv系列,还需要对spi dma驱动进行修改适配,过程放在文末。

  • arch/arm/boot/dts/suniv-f1c100s.dtsi

附上启动日志和截图

[    1.128780] fb_st7789v spi1.0: fbtft_property_value: buswidth = 8
[    1.135099] fb_st7789v spi1.0: fbtft_property_value: debug = 1
[    1.140988] fb_st7789v spi1.0: fbtft_property_value: rotate = 90
[    1.147087] fb_st7789v spi1.0: fbtft_property_value: fps = 60
[    1.153525] fb_st7789v spi1.0: fbtft_request_one_gpio: 'reset-gpios' = GPIO138
[    1.161072] fb_st7789v spi1.0: fbtft_request_one_gpio: 'dc-gpios' = GPIO139
[    1.615961] random: fast init done
[    1.648426] Console: switching to colour frame buffer device 35x30
[    1.657056] graphics fb0: fb_st7789v frame buffer, 280x240, 131 KiB video memory, 4 KiB buffer memory, fps=100, spi1.0 at 50 MHz

image

对于SUNIV所做的适配工作

新版本的内核中 SUN6I SPI 加入了DMA的支持,经尝试没有适配F1C200s,于是尝试适配。

相关驱动文件

  1. drivers/spi/spi-sun6i.c
  2. driver/dma/sun6i-dma.c

SUN6I SPI 的适配

spi 传输过程 通过对比xfer->len与sspi->fifo_depth判断,如果传输长度小于等于、FIFO深度,将直接使用FIFO,反之则使用DMA。

static bool sun6i_spi_can_dma(struct spi_master *master,
                              struct spi_device *spi,
                              struct spi_transfer *xfer)
{
        struct sun6i_spi *sspi = spi_master_get_devdata(master);

        /*
         * If the number of spi words to transfer is less or equal than
         * the fifo length we can just fill the fifo and wait for a single
         * irq, so don't bother setting up dma
         */
        return xfer->len > sspi->fifo_depth;
}


static int sun6i_spi_transfer_one(struct spi_master *master,
                                  struct spi_device *spi,
                                  struct spi_transfer *tfr)
{
	...
	bool use_dma;
	...
	use_dma = master->can_dma ? master->can_dma(master, spi, tfr) : false;
	...
}

可以修改强制使用FIFO

use_dma = master->can_dma ? master->can_dma(master, spi, tfr) : false;
use_dma = false;

F1C200s DMA 的适配

  1. 修改driver/dma/sun6i-dma.c

参考资料

posted @ 2022-04-20 15:30  IotaHydrae  阅读(524)  评论(0编辑  收藏  举报