当前位置: 首页 > news >正文

OV5645 MIPI CSI-2 2-Lane配置分析:驱动与设备树的真实关系

问题背景

在调试基于Zynq UltraScale+ MPSoC的OV5645摄像头MIPI CSI-2接口时,发现设备树中配置了data-lanes = <1 2>,但驱动代码似乎并未使用此配置。本文分析了正点原子(Altik)和Xilinx官方两种OV5645驱动的2-lane配置机制。

硬件基础:OV5645的MIPI Lane配置

关键寄存器:0x300E (MIPI CONTROL 00)

OV5645通过寄存器0x300E控制MIPI物理层配置:

寄存器地址:0x300E
默认值:0x58Bit[7:5]: mipi_lane_mode001 (0x20): 1-lane模式010 (0x40): 2-lane模式  ← OV5645默认配置其他: Debug模式Bit[4]: MIPI TX PHY power down
Bit[3]: MIPI RX PHY power down  
Bit[2]: mipi_en (0=DVP, 1=MIPI)
Bit[1]: MIPI suspend
Bit[0]: Lane disable option

芯片上电默认值分析:

0x58 = 0101 1000
Bit[7:5] = 010 → 已经是2-lane模式
Bit[4] = 1   → TX PHY power down(待驱动启用)
Bit[3] = 1   → RX PHY power down
Bit[2] = 0   → DVP模式(待切换到MIPI)

驱动实现分析

正点原子(Altik)驱动

宏定义方式固定2-lane:

#define OV5645_2LANES 2
#define OV5645_IO_MIPI_CTRL00 0x300e

启动流配置:

static int __ov5645_start_stream(struct ov5645 *ov5645)
{// 启动时写入0x45ret = ov5645_write_reg(ov5645->client, OV5645_IO_MIPI_CTRL00,OV5645_REG_VALUE_08BIT, 0x45);return ov5645_write_reg(ov5645->client, OV5645_SYSTEM_CTRL0,OV5645_REG_VALUE_08BIT, OV5645_SYSTEM_CTRL0_START);
}

0x45寄存器值解析:

0x45 = 0100 0101
Bit[7:5] = 010 → 2-lane模式
Bit[4] = 0   → PHY正常工作
Bit[3] = 0   → PHY正常工作
Bit[2] = 1   → MIPI使能(关键:从DVP切换到MIPI)
Bit[1] = 0   → 不suspend
Bit[0] = 1   → Lane disable option

停止流配置:

static int __ov5645_stop_stream(struct ov5645 *ov5645)
{// 停止时写入0x40ov5645_write_reg(ov5645->client, OV5645_IO_MIPI_CTRL00,OV5645_REG_VALUE_08BIT, 0x40);return ov5645_write_reg(ov5645->client, OV5645_SYSTEM_CTRL0,OV5645_REG_VALUE_08BIT, OV5645_SYSTEM_CTRL0_STOP);
}

0x40寄存器值解析:

0x40 = 0100 0000
Bit[7:5] = 010 → 保持2-lane模式
Bit[2] = 0   → 禁用MIPI输出

V4L2 mbus配置(旧版API):

static int ov5645_g_mbus_config(struct v4l2_subdev *sd,struct v4l2_mbus_config *config)
{u32 val = 0;// 1 << (2 - 1) = 2 = 0b00000010 (Bit 1表示2-lane)val = 1 << (OV5645_2LANES - 1) |V4L2_MBUS_CSI2_CHANNEL_0 |V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;config->type = V4L2_MBUS_CSI2_DPHY;config->flags = val;return 0;
}

像素时钟计算包含lane数:

pixel_rate = (u32)link_freq / mode->bpp * 2 * OV5645_2LANES;

关键特点:

  • ❌ 未解析设备树endpoint
  • ❌ 未读取data-lanes配置
  • ✅ Hard-coded为2-lane
  • ✅ 使用固定寄存器值0x45/0x40

Xilinx官方驱动

Probe函数中解析设备树:

static int ov5645_probe(struct i2c_client *client)
{struct v4l2_fwnode_endpoint ep;// 解析endpointendpoint = of_graph_get_next_endpoint(dev->of_node, NULL);ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(endpoint), &ov5645->ep);// 验证总线类型if (ov5645->ep.bus_type != V4L2_MBUS_CSI2_DPHY) {dev_err(dev, "invalid bus type, must be CSI2\n");return -EINVAL;}// 注意:解析了ep但从未使用ep.bus.mipi_csi2.num_data_lanes!
}

启动/停止流配置(与Altik完全相同):

static int ov5645_s_stream(struct v4l2_subdev *subdev, int enable)
{if (enable) {// 启动流ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x45);ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,OV5645_SYSTEM_CTRL0_START);} else {// 停止流ret = ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x40);ret = ov5645_write_reg(ov5645, OV5645_SYSTEM_CTRL0,OV5645_SYSTEM_CTRL0_STOP);}
}

断电时恢复默认值:

static int ov5645_set_power_off(struct device *dev)
{ov5645_write_reg(ov5645, OV5645_IO_MIPI_CTRL00, 0x58);// 其他断电操作...
}

关键特点:

  • ✅ 解析了设备树endpoint
  • ✅ 验证了总线类型
  • ❌ 但从未使用ep.bus.mipi_csi2.num_data_lanes
  • ✅ 使用相同的寄存器值0x45/0x40/0x58

对比:正确使用data-lanes的驱动(OV5640)

OV5640驱动展示了如何正确使用设备树的data-lanes配置:

struct ov5640_dev {struct v4l2_fwnode_endpoint ep;// ... 其他成员
};// 在时钟配置中使用num_data_lanes
static int ov5640_set_mipi_pclk(struct ov5640_dev *sensor)
{unsigned char num_lanes;// 从解析的endpoint读取lane数num_lanes = sensor->ep.bus.mipi_csi2.num_data_lanes;// 用于计算采样率sample_rate = (link_freq * mipi_div * num_lanes * 2) / 16;// ... 其他计算
}

设备树配置分析

典型设备树配置

&i2c1 {ov5645_cam: camera@3c {compatible = "ovti,ov5645";reg = <0x3c>;port {ov5645_ep: endpoint {data-lanes = <1 2>;                      // ← 声明使用lane1和lane2link-frequencies = /bits/64 <594000000>; // ← DDR速率:594 Mbpsremote-endpoint = <&mipi_csi_in>;};};};
};&mipi_csi2_rx_subsyst_0 {mipi_csi_port0: port@0 {mipi_csi_in: endpoint {data-lanes = <1 2>;                   // ← MIPI RX端也声明2-laneremote-endpoint = <&ov5645_ep>;};};
};

V4L2 Endpoint结构体

struct v4l2_fwnode_endpoint {enum v4l2_mbus_type bus_type;union {struct {unsigned int num_data_lanes;      // ← data-lanes数量unsigned int data_lanes[8];       // ← 每条lane的编号unsigned int clock_lane;// ... 其他成员} mipi_csi2;// ... 其他总线类型} bus;
};

关键结论

OV5645的2-Lane配置机制

配置层次配置方法是否必需实际作用
硬件默认芯片Reset值0x58-Bit[7:5]=010,默认2-lane
寄存器配置0x300E写入0x45/0x40✅ 必需Bit[2]控制MIPI使能
设备树data-lanesdata-lanes = <1 2>❌ 不必需驱动未读取此值
设备树link-frequencieslink-frequencies = <594000000>✅ 必需V4L2框架匹配验证

三个关键发现

  1. OV5645芯片硬件默认就是2-lane模式

    • Reset默认值0x58的Bit[7:5]=010
    • 驱动所有配置(0x45/0x40/0x58)的Bit[7:5]都保持为010
  2. 两种驱动都未使用设备树的data-lanes配置

    • Altik驱动:完全不解析endpoint
    • Xilinx驱动:解析endpoint但不使用num_data_lanes
    • 都通过hard-coded方式配置2-lane
  3. 寄存器0x300E的真正作用是控制MIPI使能

    • Bit[7:5]控制lane数(固定为010)
    • Bit[2]控制MIPI vs DVP切换(关键)
    • Bit[4:3]控制PHY电源
    • 0x45启动流:Bit[2]=1使能MIPI输出
    • 0x40停止流:Bit[2]=0禁用MIPI输出

实际影响

对于使用OV5645的开发者:

  1. 设备树中的data-lanes = <1 2>可以省略

    • OV5645驱动不会读取此配置
    • 芯片硬件固定工作在2-lane模式
    • 除非物理上只连接1根数据线
  2. 真正需要配置的是link-frequencies

    link-frequencies = /bits/64 <594000000>;  // DDR速率
    
    • 用于V4L2框架的link_freq控制匹配
    • 驱动中link_freq应设置为297MHz(594/2)
    • Vivado MIPI CSI-2 IP核的Line Rate应配置为594 Mbps
  3. 驱动移植注意事项

    • 如需支持1-lane模式,必须修改驱动代码
    • 需要从设备树读取ep.bus.mipi_csi2.num_data_lanes
    • 根据lane数动态配置0x300E的Bit[7:5]
    • 参考OV5640驱动的实现方式

改进建议

如果要让OV5645驱动支持动态lane配置,应参考OV5640驱动:

struct ov5645 {struct v4l2_fwnode_endpoint ep;unsigned int num_lanes;  // 新增成员// ... 其他成员
};static int ov5645_probe(struct i2c_client *client)
{// 解析endpointret = v4l2_fwnode_endpoint_parse(..., &ov5645->ep);// 读取并验证lane数num_lanes = ov5645->ep.bus.mipi_csi2.num_data_lanes;if (num_lanes != 1 && num_lanes != 2) {dev_err(dev, "invalid number of lanes: %u\n", num_lanes);return -EINVAL;}ov5645->num_lanes = num_lanes;// ... 其他初始化
}static int ov5645_start_stream(struct ov5645 *ov5645)
{u8 lane_mode;u8 reg_val;// 根据lane数配置寄存器lane_mode = (ov5645->num_lanes == 1) ? 0x20 : 0x40;  // Bit[7:5]reg_val = lane_mode | 0x05;  // 加上Bit[2]=1和Bit[0]=1ret = ov5645_write_reg(ov5645, 0x300E, reg_val);// ... 其他配置
}

参考资料

  • OV5645 Datasheet v2.01
  • Linux Kernel v6.6.40 - drivers/media/i2c/ov5645.c
  • Linux Kernel v6.6.40 - drivers/media/i2c/ov5640.c
  • Xilinx MIPI CSI-2 RX Subsystem v5.0/v6.0 文档

总结

OV5645的2-lane配置是通过硬件默认值和驱动hard-coded实现的,与设备树的data-lanes配置无关。这种实现方式简单直接,但缺乏灵活性。对于固定使用2-lane的场景,当前实现已足够;如需支持1-lane模式,则需要参考其他驱动进行改进。

http://www.dtcms.com/a/590017.html

相关文章:

  • 怎样注册网站卖东西发布html wordpress
  • template关键字
  • GradNorm
  • 企业做网站公司有哪些网站开发所需费用
  • 【TaskStackListener】Android 中用于监听和响应任务栈
  • 网站方案建设书怎么写国外最开放的浏览器是哪个
  • 【图像理解进阶】视频总结最新研究成果:从SOTA模型到实操落地(2025最新版)
  • 国内包装设计网站条形码生成器在线制作图片
  • 建设玩外汇平台网站wordpress 分类小工具
  • 数据结构---时空复杂度
  • 万维网站续费多少一年在免费空间上传网站为什么访问不了
  • win系统更新ios平台更新说明
  • WSL从C盘迁移到其他盘区,释放存储空间
  • Docker零基础入门
  • 上海网站搜索优化太原论坛2021
  • 【QT开发】Ubuntu搭建QT开发环境
  • 东莞做营销网站建设网站建设 php 企业网站
  • 递归动漫讲解咯
  • 男和男做的视频网站宿迁房产网签备案查询系统
  • 好用的Windows工具
  • 公司发布网站需要备案吗专业的建网站公司地址
  • C++ 从入门到进阶:核心知识与学习指南
  • 怎么获得免费网站首饰设计网站推荐
  • 做网站是买服务器还是买cdn微信页面
  • 网上书城网站开发自学网站开发软件开发
  • 门户网站广告的类型wordpress 修改字体
  • 混合式教学财务管理网站建设网站 设计案例
  • 搭建LNMP私有云存储
  • Zabbix监控K8S的PV卷
  • 电商网站开发视频中国最厉害的营销策划公司