S32G3: Modifying RGMII TX clock from Linux

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

S32G3: Modifying RGMII TX clock from Linux

1,182件の閲覧回数
andopando
Contributor I

Hi,

 

We have a custom S32G399A board that uses PFE0 in RGMII mode to a gigabit transceiver (KSZ9131) wired to a RJ45 plug.

The hardware works fine when connected to a gigabit switch or router however when connected to a 100BASE-TX router the PFE0 TX clock does not get set to 25MHz and remains at 125MHz which is the speed for gigabit.

After some investigating I can see that the pfe0 tx clock comes from these two muxes:

EMAC0 mux

andopando_0-1733210657946.png

 

CGM2 Mux 1 with divider. Setting this divider to this value (5) is what we need the kernel (and SCMI I suppose) to be able to do.

andopando_1-1733210679156.png

 

The pfeng driver seems to think it is setting the clock to 25MHz

andopando_2-1733210843717.png

however probing the physical pfe0 tx pin shows the old 125MHz clock and there is no ethernet traffic passing through.

I believe SCMI running in BL31 (part of TF-A) is responsible for clock management.

 

I have tried patching the CGM2 part of the TF-A device tree to specify the 25MHz clock:

 

 

diff --git a/fdts/s32g.dtsi b/fdts/s32g.dtsi
index 14ba9729d..02cd393e4 100644
--- a/fdts/s32g.dtsi
+++ b/fdts/s32g.dtsi
@@ -604,12 +604,15 @@

assigned-clocks =
<&plat_clks S32G_CLK_MC_CGM2_MUX0>,
+ <&plat_clks S32G_CLK_MC_CGM2_MUX1>,
<&plat_clks S32G_CLK_PFE_PE>;
assigned-clock-rates =
<0>,
+ <25000000>,
<600000000>;
assigned-clock-parents =
- <&plat_clks S32G_CLK_ACCEL_PLL_PHI1>;
+ <&plat_clks S32G_CLK_ACCEL_PLL_PHI1>,
+ <&plat_clks S32GEN1_CLK_PERIPH_PLL_PHI5>;
};

pfe: pfe@46000000 {

 

 

And also this printout where the mux gets enabled to check when and how it's being set

 

 

diff --git a/drivers/nxp/s32/clk/enable_clk.c b/drivers/nxp/s32/clk/enable_clk.c
index a356da96c..24c1e59ec 100644
--- a/drivers/nxp/s32/clk/enable_clk.c
+++ b/drivers/nxp/s32/clk/enable_clk.c
@@ -762,7 +762,10 @@ static int enable_cgm_div(struct s32gen1_clk_obj *module,
return -EINVAL;
#endif
}
-
+ if(cgm_addr == (void*)MC_CGM2_BASE_ADDR){
+ NOTICE("\r\nEnabling CGM2 mux %d with div scaling %d\r\n",mux->index, dc);
+ NOTICE("\r\npfreq %lu div->freq %lu\r\n",pfreq, div->freq);
+ }
cgm_mux_div_config(cgm_addr, mux->index, dc - 1, div->index);
return 0;
}

 

 

The shell clearly outputs that the mux is being enabled with the divider set to 5 however this doesn't seem to work.

 

I have found a temporary workaround of just setting the PHI5 output of the peripheral pll to 25MHz via this patch which does work and enables 100Base tx communications

 

 

diff --git a/fdts/s32cc.dtsi b/fdts/s32cc.dtsi
index 15ee06089..d8177c12b 100644
--- a/fdts/s32cc.dtsi
+++ b/fdts/s32cc.dtsi
@@ -428,7 +428,7 @@
<S32GEN1_PERIPH_PLL_VCO_FREQ>, <100000000>,
<80000000>, <80000000>,
<125000000>, <200000000>,
- <125000000>, <100000000>;
+ <25000000>, <100000000>;
};

accelpll: accelpll@40040000 {

 

 

This isn't ideal since we might have other things reliant on the PHI5 clock that need a different frequency. The divider of CGM2 Mux 1 seems like an easier thing to modify.

 

I'm running at-f 2.5 from bsp39 and kernel 5.15 from bsp39 as well but tried 5.10 from bsp38 with no difference

 

タグ(1)
0 件の賞賛
返信
3 返答(返信)

1,154件の閲覧回数
alejandro_e
NXP TechSupport
NXP TechSupport

Hello @andopando,

Thanks a lot for the very detailed description of your problem. Can you share the changes you did to the device tree to enable the RGMII mode?

 

Best regards,

Alejandro 

0 件の賞賛
返信

1,143件の閲覧回数
andopando
Contributor I

Hi Alejandro,

Thanks for the quick reply!

I've attached a combined patch file of our changes of the DT's for AT-F 2.5 from bsp38.

I've also attached a patch file of the relevant patches we made to the kernel DT as well. This is for kernel 5.10-184 from bsp38

I've omitted some other changes unrelated to ethernet like can, spi to make the patch list shorter but it's still quite long, apologies.

 

One more thing I should mention is we have a bootloader that runs before anything else and it sets up some clocks as well but I believe only for the cores, qspi flash. 

0 件の賞賛
返信

1,094件の閲覧回数
alejandro_e
NXP TechSupport
NXP TechSupport

Hello @andopando,

Checking the internal documentation I was able to find the following, this is meant to use PFE_EMAC1 as RGMII but it can be translated to PFE_EMAC0:

In linux modify arch/arm64/boot/dts/freescale/s32g274a-rdb2.dtsi:

//
//// Comment out original nodes &gmac0_mdio and &pfe_netif1 ////
// 
// &gmac0_mdio {
//     /* AQR107 */
//     gmac_mdio_a_phy3: ethernet-phy@3 {
//         compatible = "ethernet-phy-ieee802.3-c45";
//         #address-cells = <1>;
//         #size-cells = <0>;
//         /*
//          * Warning: from board rev D it is subject
//          * for eth fixup: addr changed to 0x8
//          */
//         reg = <3>;
//     };
// };
//
// &pfe_netif1 {
//     phy-mode = "sgmii";
//     phy-handle = <&gmac_mdio_a_phy3>;
// };
//

//
//// Add these new nodes ////
//

&gmac0 {
    status = "disabled";
};

&gmac0_mdio {
    status = "disabled";
};

&pfe_mdio1 {
    status = "okay";
    /* KSZ9031 GMAC */
    pfe_mdio_a_phy1: ethernet-phy@1 {
        reg = <1>;
    };
};
&pfe {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&pfe2mdiob_pins>,
            <&pfe2rgmiib_pins>, <&pfe1mdioa_pins>, <&pfe1rgmiia_pins>;
};

&pfe_netif1 {
    status = "okay";
    phy-handle = <&pfe_mdio_a_phy1>;
    phy-mode = "rgmii-id";
};

&pinctrl {
    pfe1mdioa_pins: pfe1mdioa {
        pfe1mdioa_grp0 {
            pinmux = <S32CC_PINMUX(60, FUNC2)>;
            output-enable;
            slew-rate = <S32CC_FAST_SLEW_166MHZ>;
        };

        pfe1mdioa_grp1 {
            pinmux = <S32CC_PINMUX(61, FUNC2)>;
            output-enable;
            input-enable;
            slew-rate = <S32CC_FAST_SLEW_166MHZ>;
        };

        pfe1mdioa_grp2 {
            pinmux = <S32CC_PINMUX(857, FUNC2)>;
        };

    };

    pfe1rgmiia_pins: pfe1rgmiia {
        pfe1rgmiia_grp0 {
            pinmux = <S32CC_PINMUX(66, FUNC2)>;
            output-enable;
            slew-rate = <S32CC_FAST_SLEW_166MHZ>;
            bias-pull-up;
        };

        pfe1rgmiia_grp1 {
            pinmux = <S32CC_PINMUX(866, FUNC2)>,
                 <S32CC_PINMUX(859, FUNC2)>,
                 <S32CC_PINMUX(865, FUNC2)>,
                 <S32CC_PINMUX(861, FUNC2)>,
                 <S32CC_PINMUX(862, FUNC2)>,
                 <S32CC_PINMUX(863, FUNC2)>,
                 <S32CC_PINMUX(864, FUNC2)>;
        };

        pfe1rgmiia_grp2 {
            pinmux = <S32CC_PINMUX(67, FUNC2)>,
                 <S32CC_PINMUX(68, FUNC2)>,
                 <S32CC_PINMUX(69, FUNC2)>,
                 <S32CC_PINMUX(70, FUNC2)>,
                 <S32CC_PINMUX(71, FUNC3)>;
            output-enable;
            slew-rate = <S32CC_FAST_SLEW_166MHZ>;
        };

        pfe1rgmiia_grp3 {
            pinmux = <S32CC_PINMUX(72, FUNC0)>,
                 <S32CC_PINMUX(73, FUNC0)>,
                 <S32CC_PINMUX(74, FUNC0)>,
                 <S32CC_PINMUX(75, FUNC0)>,
                 <S32CC_PINMUX(76, FUNC0)>,
                 <S32CC_PINMUX(77, FUNC0)>;
            input-enable;
            slew-rate = <S32CC_FAST_SLEW_166MHZ>;
        };

    };
};

 

This changes above apply for BSP39 and onwards.

 

For BSP38 and earlier you need to to the following:

in u-boot (also meant for PFE_EMAC1):

setenv hwconfig "pcie0:mode=pcie,clock=ext;pcie1:mode=sgmii,clock=ext,fmhz=125,xpcs_mode=2G5"
setenv pfeng_mode 'enable,sgmii,rgmii,rgmii'
setenv s32cc_gmac_mode disable
saveenv

 In arch/arm64/boot/dts/freescale/s32g274a-rdb2.dtsi (also meant for PFE_EMAC2):

//// Comment out original nodes &gmac0_mdio and &pfe_netif1 ////
// &gmac0_mdio {
//     /* AQR107 */
//     gmac_mdio_a_phy3: ethernet-phy@3 {
//         compatible = "ethernet-phy-ieee802.3-c45";
//         #address-cells = <1>;
//         #size-cells = <0>;
//         /*
//          * Warning: from board rev D it is subject
//          * for eth fixup: addr changed to 0x8
//          */
//         reg = <3>;
//     };
// };

// &pfe_netif1 {
//     phy-mode = "sgmii";
//     phy-handle = <&gmac_mdio_a_phy3>;
// };


//// Add these new nodes ////
&gmac0 {
    status = "disabled";
};

&gmac0_mdio {
    status = "disabled";
};

&pfe_mdio1 {
    status = "okay";
    /* KSZ9031 GMAC */
    pfe_mdio_a_phy1: ethernet-phy@1 {
        reg = <1>;
    };
};

&pfe {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&pfe2mdiob_pins>,
            <&pfe2rgmiib_pins>, <&pfe1mdioa_pins>, <&pfe1rgmiia_pins>;
};

&pfe_netif1 {
    status = "okay";
    phy-handle = <&pfe_mdio_a_phy1>;
    phy-mode = "rgmii-id";
};

&pinctrl {
    pfe1mdioa_pins: pfe1mdioa {
        pfe1mdioa_grp0 {
            pinmux = <S32CC_PINMUX(60, FUNC2)>;
            output-enable;
            slew-rate = <S32CC_SLEW_208MHZ>;
        };

        pfe1mdioa_grp1 {
            pinmux = <S32CC_PINMUX(61, FUNC2)>;
            output-enable;
            input-enable;
            slew-rate = <S32CC_SLEW_208MHZ>;
        };

        pfe1mdioa_grp2 {
            pinmux = <S32CC_PINMUX(857, FUNC2)>;
        };

    };

    pfe1rgmiia_pins: pfe1rgmiia {
        pfe1rgmiia_grp0 {
            pinmux = <S32CC_PINMUX(66, FUNC2)>;
            output-enable;
            slew-rate = <S32CC_SLEW_208MHZ>;
            bias-pull-up;
        };

        pfe1rgmiia_grp1 {
            pinmux = <S32CC_PINMUX(866, FUNC2)>,
                 <S32CC_PINMUX(859, FUNC2)>,
                 <S32CC_PINMUX(865, FUNC2)>,
                 <S32CC_PINMUX(861, FUNC2)>,
                 <S32CC_PINMUX(862, FUNC2)>,
                 <S32CC_PINMUX(863, FUNC2)>,
                 <S32CC_PINMUX(864, FUNC2)>;
        };

        pfe1rgmiia_grp2 {
            pinmux = <S32CC_PINMUX(67, FUNC2)>,
                 <S32CC_PINMUX(68, FUNC2)>,
                 <S32CC_PINMUX(69, FUNC2)>,
                 <S32CC_PINMUX(70, FUNC2)>,
                 <S32CC_PINMUX(71, FUNC3)>;
            output-enable;
            slew-rate = <S32CC_SLEW_208MHZ>;
        };

        pfe1rgmiia_grp3 {
            pinmux = <S32CC_PINMUX(72, FUNC0)>,
                 <S32CC_PINMUX(73, FUNC0)>,
                 <S32CC_PINMUX(74, FUNC0)>,
                 <S32CC_PINMUX(75, FUNC0)>,
                 <S32CC_PINMUX(76, FUNC0)>,
                 <S32CC_PINMUX(77, FUNC0)>;
            input-enable;
            slew-rate = <S32CC_SLEW_208MHZ>;
        };

    };
};

 

 

To recompile the device tree you can use:

make -j ARCH=arm64 CROSS_COMPILE=<path-to-your-cross-compiler> dtbs

  and then just change the device tree file in the corresponding partition of your eMMC/SD card

 

Let me know the results after this change.

0 件の賞賛
返信