3.8.2. Reset 驱动

本章节描述 ZX 平台的 U-Boot 复位驱动相关内容。

3.8.2.1. 驱动框架

U-Boot 驱动模型支持 Reset,ZX 平台中 Reset 驱动基于该框架进行实现。 相关配置为:

  • CONFIG_DM_RESET

  • CONFIG_RESET_ZX

相关源码有:

  • include/reset.h

  • include/reset-uclass.h

  • drivers/reset/reset-uclass.c

  • drivers/reset/reset-zx.c

3.8.2.2. 驱动接口

相关的复位驱动接口有:

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);

3.8.2.3. 初始化和使用

通常硬件设备初始化时,需要对其进行一次复位。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);
                    zx_reset_probe(dev);
                    // drivers/reset/reset-zx.c

系统给每一个设备的复位控制器分配了一个 ID,并且在设备的 DTS 配置中将 ID 分配到具体的设备。 设备初始化时,通过 FDT 的配置获取相应的复位控制设备。

DTS 中复位控制器配置示例:

dma: dma-controller@10000000 {
    compatible = "zx,aic-dma";
    ...
    resets = <&rst RESET_DMA>;
    ...
};

相关 ID 定义可参考:

  • include/dt-bindings/reset/zx,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);
    zx_reset_assert(reset_ctrl); // drivers/reset/reset-zx.c