LoginSignup
9
6

More than 3 years have passed since last update.

Ultra96 向け Debian GNU/Linux でAXI I/F のデータのビット幅を変更する

Last updated at Posted at 2019-05-27

はじめに

Zynq UltraScale+ MPSoC(ZynqMP) の PS-PL Interface は Fig.1 のように12本あります。そのうちの10本はデータのビット幅を 32bit、64bit、128bit から選択出来ます。

Fig.1 ZynqMP の PS-PL Interface

Fig.1 ZynqMP の PS-PL Interface


これら AXI I/Fのデータのビット幅の変更は、通常、PL 側をビルドするときに指定して、それに対応した FSBL(First Stage Boot Loader) を使ってブートすることで行われます。しかし、『Ultra96 向け Debian GNU/Linux (v2018.2版) ブートイメージの提供』(@Qiita)で紹介したような汎用の FSBL を使って Linux を起動してから Device Tree Overlay を使って PL 側のコンフィギュレーションを行うような場合には使えません。

この記事では、Device Tree を使って AXI I/F のデータのビット幅を変更する方法を紹介します。

Xilinx の AFI デバイスドライバ

実は、Xilinx が提供している Linux のディストリビューション(linux-xlnx)には、ZynqMP の AXI I/F のデータ幅を変更するデバイスドライバがすでに存在します。名前は xilinx-afi です。

ソースコードは drivers/fpga/xilinx-afi.c です。menu config などで、CONFIG_XILINX_AFI=y にすることで、このドライバが Linux Kernel に組み込まれます。 『Ultra96 向け Debian GNU/Linux (v2018.2版) ブートイメージの提供』(@Qiita)で紹介した Linux Kernel にはすでにこのデバイスドライバが組み込まれています。

xilinx-afi ドライバを使って AXI のデータ幅を設定するには、device tree で次のように指定します。

    afi0: afi0 {
        compatible = "xlnx,afi-fpga";
        config-afi = <0 0>, <1 0>;
    };

device tree にどのような記述をするかは、linux-xlnk の Documentation/devicetree/bindings/fpga/xlnx,afi-fpga.txt に説明があります。以下に引用します。

Xilinx ZynqMp AFI interface Manager
The Zynq UltraScale+ MPSoC Processing System core provides access from PL
masters to PS internal peripherals, and memory through AXI FIFO interface
(AFI) interfaces.
Required properties:
-compatible:        Should contain "xlnx,afi-fpga"
-config-afi:        Pairs of  <regid value >
The possible values of regid and values are
 regid:     Regids of the register to be written possible values
        0- AFIFM0_RDCTRL
        1- AFIFM0_WRCTRL
        2- AFIFM1_RDCTRL
        3- AFIFM1_WRCTRL
        4- AFIFM2_RDCTRL
        5- AFIFM2_WRCTRL
        6- AFIFM3_RDCTRL
        7- AFIFM3_WRCTRL
        8- AFIFM4_RDCTRL
        9- AFIFM4_WRCTRL
        10- AFIFM5_RDCTRL
        11- AFIFM5_WRCTRL
        12- AFIFM6_RDCTRL
        13- AFIFM6_WRCTRL
        14- AFIFS
        15- AFIFS_SS2
- value:    Array of values to be written.
        for FM0_RDCTRL(0) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM0_WRCTRL(1) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM1_RDCTRL(2) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM1_WRCTRL(3) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM2_RDCTRL(4) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM2_WRCTRL(5) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM3_RDCTRL(6) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM3_WRCTRL(7) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM4_RDCTRL(8) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM4_WRCTRL(9) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM5_RDCTRL(10) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM5_WRCTRL(11) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM6_RDCTRL(12) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for FM6_WRCTRL(13) the valid values-fabric width   2: 32-bit,1 : 64-bit ,0: 128-bit enabled
        for AFI_FA(14)
            dw_ss1_sel  bits (11:10)
            dw_ss0_sel  bits (9:8)
                0x0: 32-bit AXI data width),
                0x1: 64-bit AXI data width,
                0x2: 128-bit AXI data
        All other bits are 0 write ignored.
        for AFI_FA(15)  selects for ss2AXI data width valid values
                    0x000: 32-bit AXI data width),
                    0x100: 64-bit AXI data width,
                    0x200: 128-bit AXI data
Example:
afi0: afi0 {
    compatible = "xlnx,afi-fpga";
    config-afi = <0 2>, <1 1>, <2 1>;
};

Xilinx の AFI デバイスツリーのregid とレジスタの対応

前節の Documentation/devicetree/bindings/fpga/xlnx,afi-fpga.txt が分かりづらいのは、regid の説明です。これでは regid が何を意味するのかさっぱり分かりません。そこで Linux Kernel や Firmware のソースコードを追って調べてみました。その際に判明した、regid に対応する ZynqMP Register Module と AXI I/F を次の表に示します。

regid Name Register AXI I/F value
Module Register
0 AFIFM0_RDCTRL AFIFM0 RDCTRL S_AXI_HPC0_FPD 2'b10: 32-bit
2'b01: 64-bit
2'b00: 128-bit
1 AFIFM0_WRCTRL WRCTRL
2 AFIFM1_RDCTRL AFIFM1 RDCTRL S_AXI_HPC1_FPD
3 AFIFM1_WRCTRL WRCTRL
4 AFIFM2_RDCTRL AFIFM2 RDCTRL S_AXI_HP0_FPD
5 AFIFM2_WRCTRL WRCTRL
6 AFIFM3_RDCTRL AFIFM3 RDCTRL S_AXI_HP1_FPD
7 AFIFM3_WRCTRL WRCTRL
8 AFIFM4_RDCTRL AFIFM4 RDCTRL S_AXI_HP2_FPD
9 AFIFM4_WRCTRL WRCTRL
10 AFIFM5_RDCTRL AFIFM5 RDCTRL S_AXI_HP3_FPD
11 AFIFM5_WRCTRL WRCTRL
12 AFIFM6_RDCTRL AFIFM6 RDCTRL S_AXI_LPD
13 AFIFM6_WRCTRL WRCTRL
14 AFIFS FPD_SLCR afi_fs SS0=M_AXI_HPM0_FPD
SS1=M_AXI_HPM1_FPD
SS0_SEL bits[9:8]
SS1_SEL bits[11:10]
2'b00: 32-bit
2'b01: 64-bit
2'b10: 128-bit
15 AFIFS_SS2 LPD_SLCR afi_fs SS2=M_AXI_HPM0_LPD SS2_SEL bits[9:8]
2'b00: 32-bit
2'b01: 64-bit
2'b10: 128-bit

各レジスタの詳細は『Zynq UltraScale+ Devices Register Reference』を参照してください。この資料は以下の URL で示すページが見やすくて良いと思います。

次に device tree overlay を使ってPL のコンフィギュレーションと同時に S_AXI_HPC0_FPD と M_AXI_HPM0_FPD のビット幅を128bit に設定する例を示します。

/dts-v1/; /plugin/;
/ {
    fragment@0 {
        target-path = "/fpga-full";
        __overlay__ {
            firmware-name = "design_1_wrapper.bin";
        };
    };
    fragment@1 {
        target-path = "/amba_pl@0";
        __overlay__ {
            afi0 {
                compatible    = "xlnx,afi-fpga";
                config-afi    = <0 0>, <1 0>, <14 0x200>;
            };
        };
    };
};
9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6