aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorValentine Barshak <vbarshak@ru.mvista.com>2008-04-21 20:46:46 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-04-25 02:08:07 -0400
commit0925ab5d385b6cd1c435c82bfc01898c81f3d062 (patch)
tree55a8cf446bc641a8c1c47a43426043b314d7e5fe /drivers
parentbe63c09afe9153be6ba4373d1b69848cf2b32268 (diff)
ibm_newemac: PowerPC 440GX EMAC PHY clock workaround
The PowerPC 440GX Taishan board fails to reset EMAC3 (reset timeout error) if there's no link. Because of that it fails to find PHY chip. The older ibm_emac driver had a workaround for that: the EMAC_CLK_INTERNAL/EMAC_CLK_EXTERNAL macros, which toggle the Ethernet Clock Select bit in the SDR0_MFR register. This patch does the same for "ibm,emac-440gx" compatible chips. The workaround forces clock on -all- EMACs, so we select clock under global emac_phy_map_lock. BenH: Made that #ifdef CONFIG_PPC_DCR_NATIVE for now as dcri_* stuff doesn't exist for MMIO type DCRs like Cell. Some future rework & improvements of the DCR infrastructure will make that cleaner but for now, this makes it work. Signed-off-by: Valentine Barshak <vbarshak@ru.mvista.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/ibm_newemac/core.c18
-rw-r--r--drivers/net/ibm_newemac/core.h8
2 files changed, 23 insertions, 3 deletions
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 7c66727359d4..4176dd6a2e83 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -43,6 +43,8 @@
43#include <asm/io.h> 43#include <asm/io.h>
44#include <asm/dma.h> 44#include <asm/dma.h>
45#include <asm/uaccess.h> 45#include <asm/uaccess.h>
46#include <asm/dcr.h>
47#include <asm/dcr-regs.h>
46 48
47#include "core.h" 49#include "core.h"
48 50
@@ -2333,6 +2335,11 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
2333 dev->phy.mdio_read = emac_mdio_read; 2335 dev->phy.mdio_read = emac_mdio_read;
2334 dev->phy.mdio_write = emac_mdio_write; 2336 dev->phy.mdio_write = emac_mdio_write;
2335 2337
2338 /* Enable internal clock source */
2339#ifdef CONFIG_PPC_DCR_NATIVE
2340 if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX))
2341 dcri_clrset(SDR0, SDR0_MFR, 0, SDR0_MFR_ECS);
2342#endif
2336 /* Configure EMAC with defaults so we can at least use MDIO 2343 /* Configure EMAC with defaults so we can at least use MDIO
2337 * This is needed mostly for 440GX 2344 * This is needed mostly for 440GX
2338 */ 2345 */
@@ -2365,6 +2372,12 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
2365 if (!emac_mii_phy_probe(&dev->phy, i)) 2372 if (!emac_mii_phy_probe(&dev->phy, i))
2366 break; 2373 break;
2367 } 2374 }
2375
2376 /* Enable external clock source */
2377#ifdef CONFIG_PPC_DCR_NATIVE
2378 if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX))
2379 dcri_clrset(SDR0, SDR0_MFR, SDR0_MFR_ECS, 0);
2380#endif
2368 mutex_unlock(&emac_phy_map_lock); 2381 mutex_unlock(&emac_phy_map_lock);
2369 if (i == 0x20) { 2382 if (i == 0x20) {
2370 printk(KERN_WARNING "%s: can't find PHY!\n", np->full_name); 2383 printk(KERN_WARNING "%s: can't find PHY!\n", np->full_name);
@@ -2490,8 +2503,11 @@ static int __devinit emac_init_config(struct emac_instance *dev)
2490 } 2503 }
2491 2504
2492 /* Check EMAC version */ 2505 /* Check EMAC version */
2493 if (of_device_is_compatible(np, "ibm,emac4")) 2506 if (of_device_is_compatible(np, "ibm,emac4")) {
2494 dev->features |= EMAC_FTR_EMAC4; 2507 dev->features |= EMAC_FTR_EMAC4;
2508 if (of_device_is_compatible(np, "ibm,emac-440gx"))
2509 dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX;
2510 }
2495 2511
2496 /* Fixup some feature bits based on the device tree */ 2512 /* Fixup some feature bits based on the device tree */
2497 if (of_get_property(np, "has-inverted-stacr-oc", NULL)) 2513 if (of_get_property(np, "has-inverted-stacr-oc", NULL))
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h
index 4e74d8287c65..96ec48266b4a 100644
--- a/drivers/net/ibm_newemac/core.h
+++ b/drivers/net/ibm_newemac/core.h
@@ -301,6 +301,10 @@ struct emac_instance {
301 * Set if we have new type STACR with STAOPC 301 * Set if we have new type STACR with STAOPC
302 */ 302 */
303#define EMAC_FTR_HAS_NEW_STACR 0x00000040 303#define EMAC_FTR_HAS_NEW_STACR 0x00000040
304/*
305 * Set if we need phy clock workaround for 440gx
306 */
307#define EMAC_FTR_440GX_PHY_CLK_FIX 0x00000080
304 308
305 309
306/* Right now, we don't quite handle the always/possible masks on the 310/* Right now, we don't quite handle the always/possible masks on the
@@ -312,8 +316,8 @@ enum {
312 316
313 EMAC_FTRS_POSSIBLE = 317 EMAC_FTRS_POSSIBLE =
314#ifdef CONFIG_IBM_NEW_EMAC_EMAC4 318#ifdef CONFIG_IBM_NEW_EMAC_EMAC4
315 EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR | 319 EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR |
316 EMAC_FTR_STACR_OC_INVERT | 320 EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX |
317#endif 321#endif
318#ifdef CONFIG_IBM_NEW_EMAC_TAH 322#ifdef CONFIG_IBM_NEW_EMAC_TAH
319 EMAC_FTR_HAS_TAH | 323 EMAC_FTR_HAS_TAH |