aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Guo <shawn.guo@linaro.org>2011-07-01 06:11:22 -0400
committerShawn Guo <shawn.guo@linaro.org>2011-07-26 21:30:50 -0400
commit0ca1e290b7c517300bf6cc4f14ebcedb5dfea5cc (patch)
treed66e2af8bd869ed6be022419354d2e6def93adc5
parent22698aa252e5e10f5b6d171bf82669deeab3bee1 (diff)
net/fec: gasket needs to be enabled for some i.mx
On the recent i.mx (mx25/50/53), there is a gasket inside fec controller which needs to be enabled no matter phy works in MII or RMII mode. The current code enables the gasket only when phy interface is RMII. It's broken when the driver works with a MII phy. The patch uses platform_device_id to distinguish the SoCs that have the gasket and enables it on these SoCs for both MII and RMII mode. Signed-off-by: Shawn Guo <shawn.guo@linaro.org> Reported-by: Troy Kisky <troy.kisky@boundarydevices.com> Cc: David S. Miller <davem@davemloft.net> Cc: Sascha Hauer <s.hauer@pengutronix.de> Acked-by: David S. Miller <davem@davemloft.net>
-rw-r--r--arch/arm/mach-imx/clock-imx25.c2
-rw-r--r--arch/arm/mach-imx/clock-imx27.c2
-rw-r--r--arch/arm/mach-imx/clock-imx35.c3
-rw-r--r--arch/arm/mach-mx5/clock-mx51-mx53.c6
-rw-r--r--arch/arm/plat-mxc/devices/platform-fec.c21
-rw-r--r--arch/arm/plat-mxc/include/mach/devices-common.h1
-rw-r--r--drivers/net/fec.c22
7 files changed, 40 insertions, 17 deletions
diff --git a/arch/arm/mach-imx/clock-imx25.c b/arch/arm/mach-imx/clock-imx25.c
index 006b30e4b4e7..13d61f34bd34 100644
--- a/arch/arm/mach-imx/clock-imx25.c
+++ b/arch/arm/mach-imx/clock-imx25.c
@@ -296,7 +296,7 @@ static struct clk_lookup lookups[] = {
296 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk) 296 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
297 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk) 297 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
298 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk) 298 _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
299 _REGISTER_CLOCK("fec.0", NULL, fec_clk) 299 _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
300 _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk) 300 _REGISTER_CLOCK("imxdi_rtc.0", NULL, dryice_clk)
301 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) 301 _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk)
302 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk) 302 _REGISTER_CLOCK("imx2-wdt.0", NULL, wdt_clk)
diff --git a/arch/arm/mach-imx/clock-imx27.c b/arch/arm/mach-imx/clock-imx27.c
index 8c9a681ebfc1..6912b821b37b 100644
--- a/arch/arm/mach-imx/clock-imx27.c
+++ b/arch/arm/mach-imx/clock-imx27.c
@@ -663,7 +663,7 @@ static struct clk_lookup lookups[] = {
663 _REGISTER_CLOCK(NULL, "brom", brom_clk) 663 _REGISTER_CLOCK(NULL, "brom", brom_clk)
664 _REGISTER_CLOCK(NULL, "emma", emma_clk) 664 _REGISTER_CLOCK(NULL, "emma", emma_clk)
665 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk) 665 _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk)
666 _REGISTER_CLOCK("fec.0", NULL, fec_clk) 666 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
667 _REGISTER_CLOCK(NULL, "emi", emi_clk) 667 _REGISTER_CLOCK(NULL, "emi", emi_clk)
668 _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk) 668 _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk)
669 _REGISTER_CLOCK(NULL, "ata", ata_clk) 669 _REGISTER_CLOCK(NULL, "ata", ata_clk)
diff --git a/arch/arm/mach-imx/clock-imx35.c b/arch/arm/mach-imx/clock-imx35.c
index b44cb065e629..7718101099b7 100644
--- a/arch/arm/mach-imx/clock-imx35.c
+++ b/arch/arm/mach-imx/clock-imx35.c
@@ -461,7 +461,8 @@ static struct clk_lookup lookups[] = {
461 _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk) 461 _REGISTER_CLOCK("sdhci-esdhc-imx.0", NULL, esdhc1_clk)
462 _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk) 462 _REGISTER_CLOCK("sdhci-esdhc-imx.1", NULL, esdhc2_clk)
463 _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk) 463 _REGISTER_CLOCK("sdhci-esdhc-imx.2", NULL, esdhc3_clk)
464 _REGISTER_CLOCK("fec.0", NULL, fec_clk) 464 /* i.mx35 has the i.mx27 type fec */
465 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
465 _REGISTER_CLOCK(NULL, "gpio", gpio1_clk) 466 _REGISTER_CLOCK(NULL, "gpio", gpio1_clk)
466 _REGISTER_CLOCK(NULL, "gpio", gpio2_clk) 467 _REGISTER_CLOCK(NULL, "gpio", gpio2_clk)
467 _REGISTER_CLOCK(NULL, "gpio", gpio3_clk) 468 _REGISTER_CLOCK(NULL, "gpio", gpio3_clk)
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index b8119e8fb519..76e450ba8589 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -1427,7 +1427,8 @@ static struct clk_lookup mx51_lookups[] = {
1427 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk) 1427 _REGISTER_CLOCK("imx21-uart.1", NULL, uart2_clk)
1428 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk) 1428 _REGISTER_CLOCK("imx21-uart.2", NULL, uart3_clk)
1429 _REGISTER_CLOCK(NULL, "gpt", gpt_clk) 1429 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
1430 _REGISTER_CLOCK("fec.0", NULL, fec_clk) 1430 /* i.mx51 has the i.mx27 type fec */
1431 _REGISTER_CLOCK("imx27-fec.0", NULL, fec_clk)
1431 _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk) 1432 _REGISTER_CLOCK("mxc_pwm.0", "pwm", pwm1_clk)
1432 _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk) 1433 _REGISTER_CLOCK("mxc_pwm.1", "pwm", pwm2_clk)
1433 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) 1434 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
@@ -1478,7 +1479,8 @@ static struct clk_lookup mx53_lookups[] = {
1478 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk) 1479 _REGISTER_CLOCK("imx21-uart.3", NULL, uart4_clk)
1479 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk) 1480 _REGISTER_CLOCK("imx21-uart.4", NULL, uart5_clk)
1480 _REGISTER_CLOCK(NULL, "gpt", gpt_clk) 1481 _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
1481 _REGISTER_CLOCK("fec.0", NULL, fec_clk) 1482 /* i.mx53 has the i.mx25 type fec */
1483 _REGISTER_CLOCK("imx25-fec.0", NULL, fec_clk)
1482 _REGISTER_CLOCK(NULL, "iim_clk", iim_clk) 1484 _REGISTER_CLOCK(NULL, "iim_clk", iim_clk)
1483 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) 1485 _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk)
1484 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) 1486 _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk)
diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
index 4fc6ffc2a13e..0bae44e890db 100644
--- a/arch/arm/plat-mxc/devices/platform-fec.c
+++ b/arch/arm/plat-mxc/devices/platform-fec.c
@@ -11,40 +11,45 @@
11#include <mach/hardware.h> 11#include <mach/hardware.h>
12#include <mach/devices-common.h> 12#include <mach/devices-common.h>
13 13
14#define imx_fec_data_entry_single(soc) \ 14#define imx_fec_data_entry_single(soc, _devid) \
15 { \ 15 { \
16 .devid = _devid, \
16 .iobase = soc ## _FEC_BASE_ADDR, \ 17 .iobase = soc ## _FEC_BASE_ADDR, \
17 .irq = soc ## _INT_FEC, \ 18 .irq = soc ## _INT_FEC, \
18 } 19 }
19 20
20#ifdef CONFIG_SOC_IMX25 21#ifdef CONFIG_SOC_IMX25
21const struct imx_fec_data imx25_fec_data __initconst = 22const struct imx_fec_data imx25_fec_data __initconst =
22 imx_fec_data_entry_single(MX25); 23 imx_fec_data_entry_single(MX25, "imx25-fec");
23#endif /* ifdef CONFIG_SOC_IMX25 */ 24#endif /* ifdef CONFIG_SOC_IMX25 */
24 25
25#ifdef CONFIG_SOC_IMX27 26#ifdef CONFIG_SOC_IMX27
26const struct imx_fec_data imx27_fec_data __initconst = 27const struct imx_fec_data imx27_fec_data __initconst =
27 imx_fec_data_entry_single(MX27); 28 imx_fec_data_entry_single(MX27, "imx27-fec");
28#endif /* ifdef CONFIG_SOC_IMX27 */ 29#endif /* ifdef CONFIG_SOC_IMX27 */
29 30
30#ifdef CONFIG_SOC_IMX35 31#ifdef CONFIG_SOC_IMX35
32/* i.mx35 has the i.mx27 type fec */
31const struct imx_fec_data imx35_fec_data __initconst = 33const struct imx_fec_data imx35_fec_data __initconst =
32 imx_fec_data_entry_single(MX35); 34 imx_fec_data_entry_single(MX35, "imx27-fec");
33#endif 35#endif
34 36
35#ifdef CONFIG_SOC_IMX50 37#ifdef CONFIG_SOC_IMX50
38/* i.mx50 has the i.mx25 type fec */
36const struct imx_fec_data imx50_fec_data __initconst = 39const struct imx_fec_data imx50_fec_data __initconst =
37 imx_fec_data_entry_single(MX50); 40 imx_fec_data_entry_single(MX50, "imx25-fec");
38#endif 41#endif
39 42
40#ifdef CONFIG_SOC_IMX51 43#ifdef CONFIG_SOC_IMX51
44/* i.mx51 has the i.mx27 type fec */
41const struct imx_fec_data imx51_fec_data __initconst = 45const struct imx_fec_data imx51_fec_data __initconst =
42 imx_fec_data_entry_single(MX51); 46 imx_fec_data_entry_single(MX51, "imx27-fec");
43#endif 47#endif
44 48
45#ifdef CONFIG_SOC_IMX53 49#ifdef CONFIG_SOC_IMX53
50/* i.mx53 has the i.mx25 type fec */
46const struct imx_fec_data imx53_fec_data __initconst = 51const struct imx_fec_data imx53_fec_data __initconst =
47 imx_fec_data_entry_single(MX53); 52 imx_fec_data_entry_single(MX53, "imx25-fec");
48#endif 53#endif
49 54
50struct platform_device *__init imx_add_fec( 55struct platform_device *__init imx_add_fec(
@@ -63,7 +68,7 @@ struct platform_device *__init imx_add_fec(
63 }, 68 },
64 }; 69 };
65 70
66 return imx_add_platform_device_dmamask("fec", 0, 71 return imx_add_platform_device_dmamask(data->devid, 0,
67 res, ARRAY_SIZE(res), 72 res, ARRAY_SIZE(res),
68 pdata, sizeof(*pdata), DMA_BIT_MASK(32)); 73 pdata, sizeof(*pdata), DMA_BIT_MASK(32));
69} 74}
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index bf93820ab61c..6ac24501426d 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -30,6 +30,7 @@ static inline struct platform_device *imx_add_platform_device(
30 30
31#include <linux/fec.h> 31#include <linux/fec.h>
32struct imx_fec_data { 32struct imx_fec_data {
33 const char *devid;
33 resource_size_t iobase; 34 resource_size_t iobase;
34 resource_size_t irq; 35 resource_size_t irq;
35}; 36};
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 5b631fe74738..ed137bbbcf61 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -66,17 +66,28 @@
66#define FEC_QUIRK_ENET_MAC (1 << 0) 66#define FEC_QUIRK_ENET_MAC (1 << 0)
67/* Controller needs driver to swap frame */ 67/* Controller needs driver to swap frame */
68#define FEC_QUIRK_SWAP_FRAME (1 << 1) 68#define FEC_QUIRK_SWAP_FRAME (1 << 1)
69/* Controller uses gasket */
70#define FEC_QUIRK_USE_GASKET (1 << 2)
69 71
70static struct platform_device_id fec_devtype[] = { 72static struct platform_device_id fec_devtype[] = {
71 { 73 {
74 /* keep it for coldfire */
72 .name = DRIVER_NAME, 75 .name = DRIVER_NAME,
73 .driver_data = 0, 76 .driver_data = 0,
74 }, { 77 }, {
78 .name = "imx25-fec",
79 .driver_data = FEC_QUIRK_USE_GASKET,
80 }, {
81 .name = "imx27-fec",
82 .driver_data = 0,
83 }, {
75 .name = "imx28-fec", 84 .name = "imx28-fec",
76 .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, 85 .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME,
77 }, 86 }, {
78 { } 87 /* sentinel */
88 }
79}; 89};
90MODULE_DEVICE_TABLE(platform, fec_devtype);
80 91
81static unsigned char macaddr[ETH_ALEN]; 92static unsigned char macaddr[ETH_ALEN];
82module_param_array(macaddr, byte, NULL, 0); 93module_param_array(macaddr, byte, NULL, 0);
@@ -427,7 +438,7 @@ fec_restart(struct net_device *ndev, int duplex)
427 438
428 } else { 439 } else {
429#ifdef FEC_MIIGSK_ENR 440#ifdef FEC_MIIGSK_ENR
430 if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) { 441 if (id_entry->driver_data & FEC_QUIRK_USE_GASKET) {
431 /* disable the gasket and wait */ 442 /* disable the gasket and wait */
432 writel(0, fep->hwp + FEC_MIIGSK_ENR); 443 writel(0, fep->hwp + FEC_MIIGSK_ENR);
433 while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4) 444 while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
@@ -436,8 +447,11 @@ fec_restart(struct net_device *ndev, int duplex)
436 /* 447 /*
437 * configure the gasket: 448 * configure the gasket:
438 * RMII, 50 MHz, no loopback, no echo 449 * RMII, 50 MHz, no loopback, no echo
450 * MII, 25 MHz, no loopback, no echo
439 */ 451 */
440 writel(1, fep->hwp + FEC_MIIGSK_CFGR); 452 writel((fep->phy_interface == PHY_INTERFACE_MODE_RMII) ?
453 1 : 0, fep->hwp + FEC_MIIGSK_CFGR);
454
441 455
442 /* re-enable the gasket */ 456 /* re-enable the gasket */
443 writel(2, fep->hwp + FEC_MIIGSK_ENR); 457 writel(2, fep->hwp + FEC_MIIGSK_ENR);