Reset
4 Dec 2024
Read time: 2 minute(s)
本章节描述 ArtInChip 平台的 U-Boot 复位驱动相关内容。
驱动框架
U-Boot 驱动模型支持 Reset,ArtInChip 平台中 Reset 驱动基于该框架进行实现。 相关配置为:
-
CONFIG_DM_RESET
-
CONFIG_RESET_ARTINCHIP
相关源码有:
-
include/reset.h
-
include/reset-uclass.h
-
drivers/reset/reset-uclass.c
-
drivers/reset/reset-artinchip.c
驱动接口
相关的复位驱动接口有:
int reset_get_by_index(struct udevice *dev, int index,
struct reset_ctl *reset_ctl);
int reset_get_by_name(struct udevice *dev, const char *name,
struct reset_ctl *reset_ctl);
int reset_get_by_index_nodev(ofnode node, int index,
struct reset_ctl *reset_ctl);
int reset_get_bulk(struct udevice *dev, struct reset_ctl_bulk *bulk);
int reset_request(struct reset_ctl *reset_ctl);
int reset_free(struct reset_ctl *reset_ctl);
int reset_assert(struct reset_ctl *reset_ctl);
int reset_deassert(struct reset_ctl *reset_ctl);
初始化和使用
通常硬件设备初始化时,需要对其进行一次复位。Reset 驱动的 probe
在复位控制器第一次被获取时触发。
reset_get_by_index(); // drivers/reset/reset-uclass.c
|-> reset_get_by_index_tail(ret, dev_ofnode(dev), &args, "resets",
| index > 0, reset_ctl);
|-> uclass_get_device_by_ofnode(UCLASS_RESET, args->node, &dev_reset);
|-> uclass_find_device_by_ofnode(id, node, &dev);
|-> uclass_get_device_tail(dev, ret, devp);
|-> device_probe(dev); // drivers/core/device.c
|-> drv->probe(dev);
artinchip_reset_probe(dev);
// drivers/reset/reset-artinchip.c
系统给每一个设备的复位控制器分配了一个 ID,并且在设备的 DTS 配置中将 ID 分配到具体的设备。 设备初始化时,通过 FDT 的配置获取相应的复位控制设备。
DTS 中复位控制器配置示例:
dma: dma-controller@10000000 {
compatible = "artinchip,aic-dma";
...
resets = <&rst RESET_DMA>;
...
};
相关 ID 定义可参考:
- include/dt-bindings/reset/artinchip,aic-reset.h
获取复位控制器的流程:
reset_get_by_index(dev, index, reset_ctl); // drivers/reset/reset-uclass.c
| // 此处 index 是 DTS 中配置给该设备的第几个复位控制设备
|
|-> reset_get_by_index_tail();
|-> uclass_get_device_by_ofnode(UCLASS_RESET, args->node, &dev_reset);
|-> resetof_xlate_default(reset_ctl, args);
|-> reset_ctl->id = args->args[0]; // 获取到具体的复位控制器 ID
需要对设备进行复位时,通过 reset_ctl->id
进行访问和设置硬件。
reset_assert(reset_ctl); // drivers/reset/reset-uclass.c
|-> ops->rst_assert(reset_ctl);
artinchip_reset_assert(reset_ctrl); // drivers/reset/reset-artinchip.c