From patchwork Wed Sep 21 16:07:50 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shawn Guo X-Patchwork-Id: 4225 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id D8CC023F6F for ; Wed, 21 Sep 2011 16:00:34 +0000 (UTC) Received: from mail-fx0-f52.google.com (mail-fx0-f52.google.com [209.85.161.52]) by fiordland.canonical.com (Postfix) with ESMTP id C9DE9A18AC3 for ; Wed, 21 Sep 2011 16:00:34 +0000 (UTC) Received: by fxe23 with SMTP id 23so2518680fxe.11 for ; Wed, 21 Sep 2011 09:00:34 -0700 (PDT) Received: by 10.223.63.8 with SMTP id z8mr1272083fah.84.1316620830118; Wed, 21 Sep 2011 09:00:30 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.152.18.198 with SMTP id y6cs131242lad; Wed, 21 Sep 2011 09:00:29 -0700 (PDT) Received: by 10.224.194.199 with SMTP id dz7mr792778qab.270.1316620828497; Wed, 21 Sep 2011 09:00:28 -0700 (PDT) Received: from ch1outboundpool.messaging.microsoft.com (ch1ehsobe005.messaging.microsoft.com. [216.32.181.185]) by mx.google.com with ESMTPS id fo10si4223414qab.42.2011.09.21.09.00.27 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 21 Sep 2011 09:00:28 -0700 (PDT) Received-SPF: neutral (google.com: 216.32.181.185 is neither permitted nor denied by best guess record for domain of shawn.guo@linaro.org) client-ip=216.32.181.185; Authentication-Results: mx.google.com; spf=neutral (google.com: 216.32.181.185 is neither permitted nor denied by best guess record for domain of shawn.guo@linaro.org) smtp.mail=shawn.guo@linaro.org Received: from mail160-ch1-R.bigfish.com (216.32.181.173) by CH1EHSOBE014.bigfish.com (10.43.70.64) with Microsoft SMTP Server id 14.1.225.22; Wed, 21 Sep 2011 16:00:27 +0000 Received: from mail160-ch1 (localhost.localdomain [127.0.0.1]) by mail160-ch1-R.bigfish.com (Postfix) with ESMTP id 66B8B8383CD; Wed, 21 Sep 2011 16:00:27 +0000 (UTC) X-SpamScore: -3 X-BigFish: VS-3(zcb8kz41c5Nzz1202hzz8275dhz2dh87h2a8h668h839h) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPVD:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-FB-DOMAIN-IP-MATCH: fail Received: from mail160-ch1 (localhost.localdomain [127.0.0.1]) by mail160-ch1 (MessageSwitch) id 1316620798255966_19937; Wed, 21 Sep 2011 15:59:58 +0000 (UTC) Received: from CH1EHSMHS023.bigfish.com (snatpool1.int.messaging.microsoft.com [10.43.68.245]) by mail160-ch1.bigfish.com (Postfix) with ESMTP id 09ECD15E81C6; Wed, 21 Sep 2011 15:58:34 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by CH1EHSMHS023.bigfish.com (10.43.70.23) with Microsoft SMTP Server (TLS) id 14.1.225.22; Wed, 21 Sep 2011 15:58:30 +0000 Received: from az33smr01.freescale.net (10.64.34.199) by 039-SN1MMR1-002.039d.mgd.msft.net (10.84.1.15) with Microsoft SMTP Server id 14.1.323.7; Wed, 21 Sep 2011 10:58:28 -0500 Received: from S2100-06.ap.freescale.net (S2100-06.ap.freescale.net [10.192.242.125]) by az33smr01.freescale.net (8.13.1/8.13.0) with ESMTP id p8LFwI54000611; Wed, 21 Sep 2011 10:58:26 -0500 (CDT) From: Shawn Guo To: "David S. Miller" CC: , , , Shawn Guo Subject: [PATCH v3 3/3] net/fec: add imx6q enet support Date: Thu, 22 Sep 2011 00:07:50 +0800 Message-ID: <1316621270-27805-4-git-send-email-shawn.guo@linaro.org> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1316621270-27805-1-git-send-email-shawn.guo@linaro.org> References: <1316621270-27805-1-git-send-email-shawn.guo@linaro.org> MIME-Version: 1.0 X-OriginatorOrg: sigmatel.com The imx6q enet is a derivative of imx28 enet controller. It fixed the frame endian issue found on imx28, and added 1 Gbps support. It also fixes a typo on vendor name in Kconfig. Signed-off-by: Shawn Guo --- drivers/net/ethernet/freescale/Kconfig | 9 ++--- drivers/net/ethernet/freescale/fec.c | 61 +++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig index 4dbe41f..1cf6716 100644 --- a/drivers/net/ethernet/freescale/Kconfig +++ b/drivers/net/ethernet/freescale/Kconfig @@ -7,7 +7,7 @@ config NET_VENDOR_FREESCALE default y depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \ M523x || M527x || M5272 || M528x || M520x || M532x || \ - IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC || \ + ARCH_MXC || ARCH_MXS || \ (PPC_MPC52xx && PPC_BESTCOMM) ---help--- If you have a network (Ethernet) card belonging to this class, say Y @@ -16,16 +16,15 @@ config NET_VENDOR_FREESCALE Note that the answer to this question doesn't directly affect the kernel: saying N will just cause the configurator to skip all - the questions about IBM devices. If you say Y, you will be asked for - your specific card in the following questions. + the questions about Freescale devices. If you say Y, you will be + asked for your specific card in the following questions. if NET_VENDOR_FREESCALE config FEC bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)" depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \ - IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC) - default IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC if ARM + ARCH_MXC || ARCH_MXS) select PHYLIB ---help--- Say Y here if you want to use the built-in 10/100 Fast ethernet diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 2bbe6a5..3101d05 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -18,7 +18,7 @@ * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be) * Copyright (c) 2004-2006 Macq Electronique SA. * - * Copyright (C) 2010 Freescale Semiconductor, Inc. + * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. */ #include @@ -72,6 +72,10 @@ #define FEC_QUIRK_SWAP_FRAME (1 << 1) /* Controller uses gasket */ #define FEC_QUIRK_USE_GASKET (1 << 2) +/* Controller has GBIT support */ +#define FEC_QUIRK_HAS_GBIT (1 << 3) +/* Controller's phy_speed bit field need to minus one */ +#define FEC_QUIRK_PHY_SPEED_MINUS_ONE (1 << 4) static struct platform_device_id fec_devtype[] = { { @@ -88,6 +92,10 @@ static struct platform_device_id fec_devtype[] = { .name = "imx28-fec", .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME, }, { + .name = "imx6q-fec", + .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT | + FEC_QUIRK_PHY_SPEED_MINUS_ONE, + }, { /* sentinel */ } }; @@ -97,12 +105,14 @@ enum imx_fec_type { IMX25_FEC = 1, /* runs on i.mx25/50/53 */ IMX27_FEC, /* runs on i.mx27/35/51 */ IMX28_FEC, + IMX6Q_FEC, }; static const struct of_device_id fec_dt_ids[] = { { .compatible = "fsl,imx25-fec", .data = &fec_devtype[IMX25_FEC], }, { .compatible = "fsl,imx27-fec", .data = &fec_devtype[IMX27_FEC], }, { .compatible = "fsl,imx28-fec", .data = &fec_devtype[IMX28_FEC], }, + { .compatible = "fsl,imx6q-fec", .data = &fec_devtype[IMX6Q_FEC], }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, fec_dt_ids); @@ -373,6 +383,7 @@ fec_restart(struct net_device *ndev, int duplex) int i; u32 temp_mac[2]; u32 rcntl = OPT_FRAME_SIZE | 0x04; + u32 ecntl = 0x2; /* ETHEREN */ /* Whack a reset. We should wait for this. */ writel(1, fep->hwp + FEC_ECNTRL); @@ -442,18 +453,23 @@ fec_restart(struct net_device *ndev, int duplex) /* Enable flow control and length check */ rcntl |= 0x40000000 | 0x00000020; - /* MII or RMII */ - if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) + /* RGMII, RMII or MII */ + if (fep->phy_interface == PHY_INTERFACE_MODE_RGMII) + rcntl |= (1 << 6); + else if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) rcntl |= (1 << 8); else rcntl &= ~(1 << 8); - /* 10M or 100M */ - if (fep->phy_dev && fep->phy_dev->speed == SPEED_100) - rcntl &= ~(1 << 9); - else - rcntl |= (1 << 9); - + /* 1G, 100M or 10M */ + if (fep->phy_dev) { + if (fep->phy_dev->speed == SPEED_1000) + ecntl |= (1 << 5); + else if (fep->phy_dev->speed == SPEED_100) + rcntl &= ~(1 << 9); + else + rcntl |= (1 << 9); + } } else { #ifdef FEC_MIIGSK_ENR if (id_entry->driver_data & FEC_QUIRK_USE_GASKET) { @@ -478,8 +494,15 @@ fec_restart(struct net_device *ndev, int duplex) } writel(rcntl, fep->hwp + FEC_R_CNTRL); + if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) { + /* enable ENET endian swap */ + ecntl |= (1 << 8); + /* enable ENET store and forward mode */ + writel(1 << 8, fep->hwp + FEC_X_WMRK); + } + /* And last, enable the transmit and receive processing */ - writel(2, fep->hwp + FEC_ECNTRL); + writel(ecntl, fep->hwp + FEC_ECNTRL); writel(0, fep->hwp + FEC_R_DES_ACTIVE); /* Enable interrupts we wish to service */ @@ -490,6 +513,8 @@ static void fec_stop(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); + const struct platform_device_id *id_entry = + platform_get_device_id(fep->pdev); /* We cannot expect a graceful transmit stop without link !!! */ if (fep->link) { @@ -504,6 +529,10 @@ fec_stop(struct net_device *ndev) udelay(10); writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); + + /* We have to keep ENET enabled to have MII interrupt stay working */ + if (id_entry->driver_data & FEC_QUIRK_ENET_MAC) + writel(2, fep->hwp + FEC_ECNTRL); } @@ -918,6 +947,8 @@ static int fec_enet_mdio_reset(struct mii_bus *bus) static int fec_enet_mii_probe(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); + const struct platform_device_id *id_entry = + platform_get_device_id(fep->pdev); struct phy_device *phy_dev = NULL; char mdio_bus_id[MII_BUS_ID_SIZE]; char phy_name[MII_BUS_ID_SIZE + 3]; @@ -949,14 +980,18 @@ static int fec_enet_mii_probe(struct net_device *ndev) snprintf(phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id); phy_dev = phy_connect(ndev, phy_name, &fec_enet_adjust_link, 0, - PHY_INTERFACE_MODE_MII); + fep->phy_interface); if (IS_ERR(phy_dev)) { printk(KERN_ERR "%s: could not attach to PHY\n", ndev->name); return PTR_ERR(phy_dev); } /* mask with MAC supported features */ - phy_dev->supported &= PHY_BASIC_FEATURES; + if (id_entry->driver_data & FEC_QUIRK_HAS_GBIT) + phy_dev->supported &= PHY_GBIT_FEATURES; + else + phy_dev->supported &= PHY_BASIC_FEATURES; + phy_dev->advertising = phy_dev->supported; fep->phy_dev = phy_dev; @@ -1008,6 +1043,8 @@ static int fec_enet_mii_init(struct platform_device *pdev) * Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed) */ fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), 5000000) << 1; + if (id_entry->driver_data & FEC_QUIRK_PHY_SPEED_MINUS_ONE) + fep->phy_speed--; writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); fep->mii_bus = mdiobus_alloc();