tg3: Set the MAC clock to the fastest speed during boot code load
authorNithin Sujir <nsujir@broadcom.com>
Fri, 3 Jan 2014 18:09:13 +0000 (10:09 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 4 Jan 2014 01:59:52 +0000 (20:59 -0500)
On the 5717, 5718 and 5719 devices, the bootcode runs slower when any
port doesn't have a link due to clock speed slowing down as part of the
link-aware feature. This leads to the driver timing out waiting for the
bootcode signature.

This patch overrides the clock policy to the highest frequency just before
reset and restores it after the bootcode is up.

Signed-off-by: Nithin Nayak Sujir <nsujir@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/broadcom/tg3.h

index c3b12de0b91853f9879fb756b0b031399ad239cb..7bc8449af262c0d1a28f2259e041d76a7c8fa97e 100644 (file)
@@ -8941,6 +8941,49 @@ static void tg3_restore_pci_state(struct tg3 *tp)
        }
 }
 
+static void tg3_override_clk(struct tg3 *tp)
+{
+       u32 val;
+
+       switch (tg3_asic_rev(tp)) {
+       case ASIC_REV_5717:
+               val = tr32(TG3_CPMU_CLCK_ORIDE_ENABLE);
+               tw32(TG3_CPMU_CLCK_ORIDE_ENABLE, val |
+                    TG3_CPMU_MAC_ORIDE_ENABLE);
+               break;
+
+       case ASIC_REV_5719:
+       case ASIC_REV_5720:
+               tw32(TG3_CPMU_CLCK_ORIDE, CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
+               break;
+
+       default:
+               return;
+       }
+}
+
+static void tg3_restore_clk(struct tg3 *tp)
+{
+       u32 val;
+
+       switch (tg3_asic_rev(tp)) {
+       case ASIC_REV_5717:
+               val = tr32(TG3_CPMU_CLCK_ORIDE_ENABLE);
+               tw32(TG3_CPMU_CLCK_ORIDE_ENABLE,
+                    val & ~TG3_CPMU_MAC_ORIDE_ENABLE);
+               break;
+
+       case ASIC_REV_5719:
+       case ASIC_REV_5720:
+               val = tr32(TG3_CPMU_CLCK_ORIDE);
+               tw32(TG3_CPMU_CLCK_ORIDE, val & ~CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
+               break;
+
+       default:
+               return;
+       }
+}
+
 /* tp->lock is held. */
 static int tg3_chip_reset(struct tg3 *tp)
 {
@@ -9029,6 +9072,13 @@ static int tg3_chip_reset(struct tg3 *tp)
                     tr32(GRC_VCPU_EXT_CTRL) & ~GRC_VCPU_EXT_CTRL_HALT_CPU);
        }
 
+       /* Set the clock to the highest frequency to avoid timeouts. With link
+        * aware mode, the clock speed could be slow and bootcode does not
+        * complete within the expected time. Override the clock to allow the
+        * bootcode to finish sooner and then restore it.
+        */
+       tg3_override_clk(tp);
+
        /* Manage gphy power for all CPMU absent PCIe devices. */
        if (tg3_flag(tp, 5705_PLUS) && !tg3_flag(tp, CPMU_PRESENT))
                val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
@@ -9167,10 +9217,7 @@ static int tg3_chip_reset(struct tg3 *tp)
                tw32(0x7c00, val | (1 << 25));
        }
 
-       if (tg3_asic_rev(tp) == ASIC_REV_5720) {
-               val = tr32(TG3_CPMU_CLCK_ORIDE);
-               tw32(TG3_CPMU_CLCK_ORIDE, val & ~CPMU_CLCK_ORIDE_MAC_ORIDE_EN);
-       }
+       tg3_restore_clk(tp);
 
        /* Reprobe ASF enable state.  */
        tg3_flag_clear(tp, ENABLE_ASF);
index e4da9d7834ce330ca895bbd2391776255f03bd4f..9e31eccc250bf70946b32a2225906b2b6f53aca1 100644 (file)
 #define TG3_CPMU_CLCK_ORIDE            0x00003624
 #define  CPMU_CLCK_ORIDE_MAC_ORIDE_EN   0x80000000
 
+#define TG3_CPMU_CLCK_ORIDE_ENABLE     0x00003628
+#define  TG3_CPMU_MAC_ORIDE_ENABLE      (1 << 13)
+
 #define TG3_CPMU_STATUS                        0x0000362c
 #define  TG3_CPMU_STATUS_FMSK_5717      0x20000000
 #define  TG3_CPMU_STATUS_FMSK_5719      0xc0000000