This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM335x and RMII TLK105, link not stable

Other Parts Discussed in Thread: TLK105

Hi all,

I am trying to get my enet up and running in Linux.  I am using the 6.0 dev kit. 

1) I have been able to configure the pinmux for both ETH0 and ETH1. 

2) Set the interface to use the external 50mhz clock. 

3) Change the interface to RMII mode. 

Despite all of this, the link keeps going up and down at 100mbs, and eventually defaults to 10mbs.  However, I can not ping anything, even at this speed.  I am at a loss as to where to look next.  question: I saw in the code calls to

 phy_register_fixup_for_uid(BBB_PHY_ID, BBB_PHY_MASK,beaglebone_phy_fixup);

do I need to do this for the TLK105?

Thanks!

Chuck

Here is my Pin Muxing code:

in the /arch/arm/mach-omap2/board-am335xevm.c file I added:

+/* Module pin mux for rmii1 */
+static struct pinmux_config rmii1_pin_mux[] = {
+       {"mii1_crs.rmii1_crs_dv", OMAP_MUX_MODE1 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"mii1_rxerr.rmii1_rxerr", OMAP_MUX_MODE1 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"mii1_txen.rmii1_txen", OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT},
+       {"mii1_txd1.rmii1_txd1", OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT},
+       {"mii1_txd0.rmii1_txd0", OMAP_MUX_MODE1 | AM33XX_PIN_OUTPUT},
+       {"mii1_rxd1.rmii1_rxd1", OMAP_MUX_MODE1 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"mii1_rxd0.rmii1_rxd0", OMAP_MUX_MODE1 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"rmii1_refclk.rmii1_refclk", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"mdio_data.mdio_data", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
+       {"mdio_clk.mdio_clk", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT_PULLUP},
+        {"mcasp0_axr1.gpio3_20", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT_PULLUP}, // FOR INTERRUPT
+       {NULL, 0},
+};

+/* Module pin mux for rmii2 */
+static struct pinmux_config rmii2_pin_mux[] = {
+       {"gpmc_wait0.rmii2_crs_dv", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"gpmc_wpn.rmii2_rxerr", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"gpmc_a0.rmii2_txen", OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT},
+       {"gpmc_a4.rmii2_txd1", OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT},
+       {"gpmc_a5.rmii2_txd0", OMAP_MUX_MODE3 | AM33XX_PIN_OUTPUT},
+       {"gpmc_a10.rmii2_rxd1", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"gpmc_a11.rmii2_rxd0", OMAP_MUX_MODE3 | AM33XX_PIN_INPUT_PULLDOWN},
+       {"mii1_col.rmii2_refclk", OMAP_MUX_MODE1 | AM33XX_PIN_INPUT_PULLDOWN},
+        {"mcasp0_ahclkx.gpio3_21", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT_PULLUP}, // FOR INTERRUPT
+       {NULL, 0},
 };
 

+static void rmii1_init(void)
+{
+       setup_pin_mux(rmii1_pin_mux);
+       return;
+}
+
+static void rmii2_init(void)
+{
+       setup_pin_mux(rmii2_pin_mux);
+       return;
+}

+void setup_enet (void)
+{
+/* Fillup global mac id */
+       am33xx_cpsw_macidfillup("0:1e", "0:00");
+        am33xx_cpsw_init(AM33XX_CPSW_MODE_RGMII, NULL, NULL);
+}

static void __init am335x_evm_init(void)
     am33xx_cpuidle_init();
        am33xx_mux_init(NULL);
     omap_serial_init();
+    rmii1_init();
+    rmii2_init();
+    setup_enet();
     am335x_rtc_init();

to setup the 50mhz clock as an input:

in /arch/arm/mach-omap2/control.h
@@ -372,7 +372,8 @@
 #define AM33XX_CONTROL_GMII_SEL_OFFSET 0x650
 #define AM33XX_RGMII_DISABLE_INT_DLY   (BIT(4) | BIT(5))
 #define AM33XX_MII_MODE_EN             0x0
-#define AM33XX_RMII_MODE_EN            ((1 << 0) | (1 << 2))
+// Chuck Kamas, added bits 6 and 7 set to have AM335x rx the 50mhz clock, not generate it
+#define AM33XX_RMII_MODE_EN            ((1 << 0) | (1 << 2) | (1<<6) | (1<<7))
 #define AM33XX_RGMII_MODE_EN           ((0x2 << 0) | (0x2 << 2) | \
                                        (AM33XX_RGMII_DISABLE_INT_DLY))

  • Hi Chuck,
     
    In your pinmux you should enable the receiver on MDIO_CLK:
     
     {"mdio_clk.mdio_clk", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP}
     
    This is necessary for MDIO_DATA input retiming.
     
  • Biser, thank you for answering my question, however, when I changed the clock from output to input, the second phy is no longer recognized.  I checked in the original board file and it too has the clock as an output only:

    {"mdio_clk.mdio_clk", OMAP_MUX_MODE0 | AM33XX_PIN_OUTPUT_PULLUP},

    Chuck

  • Hi Biser,

    Another thing I noticed, and I do not know if this is a symptom or distraction, is that the following message is printed during boot:

    [    0.808711] davinci_mdio davinci_mdio.0: phy[0]: device 0:00, driver unknown
    [    0.816121] davinci_mdio davinci_mdio.0: phy[1]: device 0:01, driver unknown

    Do I need to tell the davinvi mdio driver about the TLK105 phy?

    Chuck

  • The PHYs need to be initialized over MDIO.

  •  Biser,

    1) How does one init the Phys?

    2) why does the base demo code have the MDIO as an output, not an input as you suggest?

    Chuck

  • I think you may have misunderstood what Biser meant when he suggested you enable the MDIO clock input.

    He did not want you to change the pin from output to input.  This pin must be an output to generate a MDIO clock to the Ethernet PHY.

    The IO cell has the ability to turn off the input buffer and this control is unrelated to the output enable on output buffer.  He wants you to turn on the input buffer while the pin is operating as an output.  This is required because the clock source that is driven out the MDC pin to the Ethernet PHY is not connected to MDIO logic inside AM335x.  The internal MDIO logic gets its clock from the pin by looping the output back into the input.  Therefore, you must turn on the input buffer to get the clock back into Am335x.

    If you look at the register description for 'conf_mdc', you will see bit 5 is the input enable bit.  This bit must be set to '1' for the input to be enable which will loop back the MDIO clock back into the MDIO logic.

    Regards,
    Paul

  • Paul,

    OK, I understand now that the pin is used to route the clock internally at the same time as driving the external circuit.  So is the demo board file wrong then? It does not have bit 5 set.

    Even after this fix I still have the link going up and down.  In several other posts I see requests to dump the phy registers, how does one do that?

    Chuck

  • Chuck,

    Please take a look at the PHYUSERACCESS(n) registers. These registers provide a mechanism to read/write the PHY registers via MDIO.

  • DK,

    Thanks for the suggestion.  I am feeling a bit obtuse, I am assuming that you are talking about a C function called PHYUSERACCESS()?  Or is this a shell helper program?  Either way, could you be more specific in what you want me to do to dump the phy registers?

    Chuck

  • Sorry, the register name is MDIOUSERACCESS...refer to sections 14.4.4 and 14.4.5 of the TRM for instructions on how to use these registers to directly R/W from an attached PHY.

  • DK,

    Is there a bit of software already written that will do this?

    Chuck

  • Hi chuck,

    Can you post your TLK part of schematic here

    Rajeev

  • Rajeev

    4466.phy.pdf

    Here are the pages from the schematic.  The first two pages are the phys and the third is their connection to the am335x

    Thanks

    Chuck

  • Hi chuck,

     I am trying to recreate the problem you are facing.

    I will post the updates once i am done.

    Best Regards,

    Rajeev

  • Hi Rajeev,

    I was able to get UBOOT to TFTP over the ethernet.  So I am more confident that the hardware is working.
     I think it is a configuration issue with the RMII.  Do you have a board with an RMII interface to test on?

    Chuck

  • Woo Hoo!

    I found the problem!  I had a RGMII instead of a RMII in the following code:

    void setup_enet (void)
    {
    /* Fillup global mac id */
        am33xx_cpsw_macidfillup("0:1e", "0:00");
            am33xx_cpsw_init(AM33XX_CPSW_MODE_RMII, NULL, NULL);
    }

    Now iPerf works like a champ!  90MBS!

    THANK YOU.

    Chuck

  • Hi chuck,

     I do have a custom board, in which we are using TLK105 PHY.

    Best regards,

    Rajeev

       

  • Dear Chuck,

    I've got 3 questions on your TLK105 solution as I am using a AM335X board with a TLK105 as well.

    Which kernel version are you using ?

    Did you have to add the TLK105 PHY identifier somewhere to make it work ?

    What's the purpose of the interrupt line you configure and how do you combine that with the cpsw/phy driver ?

    Regards,

    Sebastian

  • Sebastian Wendt1 said:

    Which kernel version are you using ?

    From my first post, we are using SDK version 6.0, which is a 3.2 kernel.  However, all my modifications were in TI's SDK

    Sebastian Wendt1 said:

    Did you have to add the TLK105 PHY identifier somewhere to make it work ?

    No... But I did have to rework the init quite heavily as I outlined in the first post.... Are you having trouble following my logic?

    Sebastian Wendt1 said:

    What's the purpose of the interrupt line you configure and how do you combine that with the cpsw/phy driver ?

    The HW guy put it in because it was there.  I do not think that the Linux Driver uses it.... but I have not dug that deeply into the Linux Driver.

    Chuck

  • Found my problem - incorrect PHY IDs !