You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LS1028ARDB开发板FlexSPI时钟无法降至18MHz以下求助

LS1028 FlexSPI时钟无法降至18MHz以下的问题排查与解决需求

硬件连接与背景

使用LS1028ARDB开发板验证LS1028的FlexSPI与自定义设备的通信可行性,连接方式:

LS1028ARDB <--- QSPI port (managed by FlexSPI) <----> My device.

开发板QSPI端口引脚电压为1.8V,目标设备工作在3.3V,因此采用电压转换芯片,但这类芯片速度较慢,导致通信不可靠。测试不需要高速通信,仅需可靠通信,SPI频率越低越好。

时钟配置问题

无法将SPI时钟配置到18MHz以下:

  • 通过设备树的spi-max-frequency属性设置频率时,设为50MHz可正常生效(实际约48MHz,通过/sys/kernel/debug/clk/fspi_clk/clk_rate验证);
  • 设为10MHz、5MHz、1MHz等低于18MHz的值时,实际时钟仍维持在18MHz左右,且所有操作无报错。

所有时钟配置均由主线驱动管理,未修改驱动代码,仅添加设备树节点并编写了触发SPI操作的简易驱动。

相关代码片段

主线fsl-ls-1028a.dtsi中的fspi节点

fspi: spi@20c0000 {
    compatible = "nxp,lx2160a-fspi";
    #address-cells = <1>;
    #size-cells = <0>;
    reg = <0x0 0x20c0000 0x0 0x10000>,
          <0x0 0x20000000 0x0 0x10000000>;
    reg-names = "fspi_base", "fspi_mmap";
    interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
    clocks = <&fspi_clk>, <&fspi_clk>;
    clock-names = "fspi_en", "fspi";
    status = "disabled";
};

主线fsl-ls-1028a-rdb.dts中的修改

&fspi {
    status = "okay";

    pbspimem: pbspimem@0 {
        compatible = "pb,pb-spi-mem";
        #address-cells = <1>;
        #size-cells = <1>;
        spi-max-frequency = <5000000>;
        spi-rx-bus-width = <1>; /* 1 SPI Rx lines */
        spi-tx-bus-width = <1>; /* 1 SPI Tx line */
        reg = <0>;
    };
};

自定义简易SPI驱动

#include "linux/types.h"
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/spi/spi-mem.h>
#include <linux/dma-mapping.h>


static int pb_spi_mem_probe(struct spi_mem *spimem)
{
    int ret;
    uint8_t buf[64];
    memset(buf, 0, sizeof(buf));

    struct spi_mem_op op = SPI_MEM_OP(
        SPI_MEM_OP_CMD(0x80, 1),
        SPI_MEM_OP_ADDR(3, 0x000004, 1),
        SPI_MEM_OP_NO_DUMMY,
        SPI_MEM_OP_DATA_IN(4, buf, 1)
    );

    ret = spi_mem_exec_op(spimem, &op);

    if (ret) {
        pr_info("Cannot execute op\n");
    }

    return ret;
}

static int pb_spi_mem_remove(struct spi_mem *spimem)
{
    pr_info("%s\n", __func__);

    return 0;
}


static const struct spi_device_id spi_nor_dev_ids[] = {
    {"pb-spi-mem"},
    { } /* sentinel */
};
MODULE_DEVICE_TABLE(spi, spi_nor_dev_ids);

static const struct of_device_id pb_spi_mem_of_table[] = {
    { .compatible = "pb,pb-spi-mem" },
    { /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, pb_spi_mem_of_table);

static struct spi_mem_driver pb_spi_mem_driver = {
    .spidrv = {
        .driver = {
            .name = "pb-spi-mem-namer",
            .of_match_table = pb_spi_mem_of_table
        },
        .id_table = spi_nor_dev_ids
    },
    .probe = pb_spi_mem_probe,
    .remove = pb_spi_mem_remove
};

module_spi_mem_driver(pb_spi_mem_driver);

MODULE_LICENSE("GPL");

FlexSPI驱动相关代码片段

驱动底层调用nxp_fspi_exec_op函数,跟踪调用栈确认会执行以下代码:

static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi)
{
    unsigned long rate = spi->max_speed_hz;
    int ret;
    uint64_t size_kb;
    
    [...]

    nxp_fspi_clk_disable_unprep(f);

    ret = clk_set_rate(f->clk, rate);
    if (ret)
        return;

    ret = nxp_fspi_clk_prep_enable(f);
    if (ret)
        return;

    f->selected = spi->chip_select;
}

static int nxp_fspi_clk_prep_enable(struct nxp_fspi *f)
{
    int ret;

    if (is_acpi_node(f->dev->fwnode))
        return 0;

    ret = clk_prepare_enable(f->clk_en);
    if (ret)
        return ret;

    ret = clk_prepare_enable(f->clk);
    if (ret) {
        clk_disable_unprepare(f->clk_en);
        return ret;
    }

    return 0;
}

可见代码中调用了clk_set_rate(f->clk, rate),该函数在设置50MHz等高频时可正常生效,但无法将频率设置到18MHz以下。

需求

寻求将SPI时钟降至18MHz以下的方法,以满足低速可靠通信的测试需求。

内容的提问来源于stack exchange,提问作者bielu000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 01:37:06