linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/8] Generic bitbanged MDIO library
@ 2007-08-28 20:11 Scott Wood
  2007-08-28 20:14 ` [PATCH v3 2/8] fs_enet: Whitespace cleanup Scott Wood
                   ` (32 more replies)
  0 siblings, 33 replies; 82+ messages in thread
From: Scott Wood @ 2007-08-28 20:11 UTC (permalink / raw)
  To: jgarzik; +Cc: netdev, linuxppc-dev

Previously, bitbanged MDIO was only supported in individual
hardware-specific drivers.  This code factors out the higher level
protocol implementation, reducing the hardware-specific portion to
functions setting direction, data, and clock.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
 drivers/net/phy/Kconfig        |    9 ++
 drivers/net/phy/Makefile       |    1 +
 drivers/net/phy/mdio-bitbang.c |  187 ++++++++++++++++++++++++++++++++++++++++
 include/linux/mdio-bitbang.h   |   42 +++++++++
 4 files changed, 239 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/phy/mdio-bitbang.c
 create mode 100644 include/linux/mdio-bitbang.h

diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index dd09011..72a98dd 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -76,4 +76,13 @@ config FIXED_MII_100_FDX
 	bool "Emulation for 100M Fdx fixed PHY behavior"
 	depends on FIXED_PHY
 
+config MDIO_BITBANG
+	tristate "Support for bitbanged MDIO buses"
+	help
+	  This module implements the MDIO bus protocol in software,
+	  for use by low level drivers that export the ability to
+	  drive the relevant pins.
+
+	  If in doubt, say N.
+
 endif # PHYLIB
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8885650..3d6cc7b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
 obj-$(CONFIG_BROADCOM_PHY)	+= broadcom.o
 obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
 obj-$(CONFIG_FIXED_PHY)		+= fixed.o
+obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
new file mode 100644
index 0000000..9bfc9ce
--- /dev/null
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -0,0 +1,187 @@
+/*
+ * Bitbanged MDIO support.
+ *
+ * Author: Scott Wood <scottwood@freescale.com>
+ * Copyright (c) 2007 Freescale Semiconductor
+ *
+ * Based on CPM2 MDIO code which is:
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ *  by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#define MDIO_READ 1
+#define MDIO_WRITE 0
+
+#define MDIO_SETUP_TIME 10
+#define MDIO_HOLD_TIME 10
+
+/* Minimum MDC period is 400 ns, plus some margin for error */
+#define MDIO_DELAY 250
+
+/* The PHY may take up to 300 ns to produce data, plus some margin
+ * for error.
+ */
+#define MDIO_READ_DELAY 350
+
+/* MDIO must already be configured as output. */
+static void mdio_bitbang_send_bit(struct mdio_bitbang_ctrl *ctrl, int val)
+{
+	const struct mdio_bitbang_ops *ops = ctrl->ops;
+
+	ops->set_mdio_data(ctrl, val);
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 1);
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 0);
+}
+
+/* MDIO must already be configured as input. */
+static int mdio_bitbang_get_bit(struct mdio_bitbang_ctrl *ctrl)
+{
+	const struct mdio_bitbang_ops *ops = ctrl->ops;
+
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 1);
+	ndelay(MDIO_READ_DELAY);
+	ops->set_mdc(ctrl, 0);
+
+	return ops->get_mdio_data(ctrl);
+}
+
+/* MDIO must already be configured as output. */
+static void mdio_bitbang_send_num(struct mdio_bitbang_ctrl *ctrl,
+                                  u16 val, int bits)
+{
+	int i;
+
+	for (i = bits - 1; i >= 0; i--)
+		mdio_bitbang_send_bit(ctrl, (val >> i) & 1);
+}
+
+/* MDIO must already be configured as input. */
+static u16 mdio_bitbang_get_num(struct mdio_bitbang_ctrl *ctrl, int bits)
+{
+	int i;
+	u16 ret = 0;
+
+	for (i = bits - 1; i >= 0; i--) {
+		ret <<= 1;
+		ret |= mdio_bitbang_get_bit(ctrl);
+	}
+
+	return ret;
+}
+
+/* Utility to send the preamble, address, and
+ * register (common to read and write).
+ */
+static void mdio_bitbang_cmd(struct mdio_bitbang_ctrl *ctrl,
+                             int read, u8 phy, u8 reg)
+{
+	const struct mdio_bitbang_ops *ops = ctrl->ops;
+	int i;
+
+	ops->set_mdio_dir(ctrl, 1);
+
+	/*
+	 * Send a 32 bit preamble ('1's) with an extra '1' bit for good
+	 * measure.  The IEEE spec says this is a PHY optional
+	 * requirement.  The AMD 79C874 requires one after power up and
+	 * one after a MII communications error.  This means that we are
+	 * doing more preambles than we need, but it is safer and will be
+	 * much more robust.
+	 */
+
+	for (i = 0; i < 32; i++)
+		mdio_bitbang_send_bit(ctrl, 1);
+
+	/* send the start bit (01) and the read opcode (10) or write (10) */
+	mdio_bitbang_send_bit(ctrl, 0);
+	mdio_bitbang_send_bit(ctrl, 1);
+	mdio_bitbang_send_bit(ctrl, read);
+	mdio_bitbang_send_bit(ctrl, !read);
+
+	mdio_bitbang_send_num(ctrl, phy, 5);
+	mdio_bitbang_send_num(ctrl, reg, 5);
+}
+
+
+static int mdio_bitbang_read(struct mii_bus *bus, int phy, int reg)
+{
+	struct mdio_bitbang_ctrl *ctrl = bus->priv;
+	int ret, i;
+
+	mdio_bitbang_cmd(ctrl, MDIO_READ, phy, reg);
+	ctrl->ops->set_mdio_dir(ctrl, 0);
+
+	/* check the turnaround bit: the PHY should be driving it to zero */
+	if (mdio_bitbang_get_bit(ctrl) != 0) {
+		/* PHY didn't drive TA low -- flush any bits it
+		 * may be trying to send.
+		 */
+		for (i = 0; i < 32; i++)
+			mdio_bitbang_get_bit(ctrl);
+
+		return 0xffff;
+	}
+
+	ret = mdio_bitbang_get_num(ctrl, 16);
+	mdio_bitbang_get_bit(ctrl);
+	return ret;
+}
+
+static int mdio_bitbang_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+	struct mdio_bitbang_ctrl *ctrl = bus->priv;
+
+	mdio_bitbang_cmd(ctrl, MDIO_WRITE, phy, reg);
+
+	/* send the turnaround (10) */
+	mdio_bitbang_send_bit(ctrl, 1);
+	mdio_bitbang_send_bit(ctrl, 0);
+
+	mdio_bitbang_send_num(ctrl, val, 16);
+
+	ctrl->ops->set_mdio_dir(ctrl, 0);
+	mdio_bitbang_get_bit(ctrl);
+	return 0;
+}
+
+struct mii_bus *alloc_mdio_bitbang(struct mdio_bitbang_ctrl *ctrl)
+{
+	struct mii_bus *bus;
+
+	bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+	if (!bus)
+		return NULL;
+
+	__module_get(ctrl->ops->owner);
+
+	bus->read = mdio_bitbang_read;
+	bus->write = mdio_bitbang_write;
+	bus->priv = ctrl;
+
+	return bus;
+}
+
+void free_mdio_bitbang(struct mii_bus *bus)
+{
+	struct mdio_bitbang_ctrl *ctrl = bus->priv;
+
+	module_put(ctrl->ops->owner);
+	kfree(bus);
+}
diff --git a/include/linux/mdio-bitbang.h b/include/linux/mdio-bitbang.h
new file mode 100644
index 0000000..63a11dd
--- /dev/null
+++ b/include/linux/mdio-bitbang.h
@@ -0,0 +1,42 @@
+#ifndef __LINUX_MDIO_BITBANG_H
+#define __LINUX_MDIO_BITBANG_H
+
+#include <linux/phy.h>
+#include <linux/module.h>
+
+struct mdio_bitbang_ctrl;
+
+struct mdio_bitbang_ops {
+	struct module *owner;
+
+	/* Set the Management Data Clock high if level is one,
+	 * low if level is zero.
+	 */
+	void (*set_mdc)(struct mdio_bitbang_ctrl *ctrl, int level);
+
+	/* Configure the Management Data I/O pin as an input if
+	 * "output" is zero, or an output if "output" is one.
+	 */
+	void (*set_mdio_dir)(struct mdio_bitbang_ctrl *ctrl, int output);
+
+	/* Set the Management Data I/O pin high if value is one,
+	 * low if "value" is zero.  This may only be called
+	 * when the MDIO pin is configured as an output.
+	 */
+	void (*set_mdio_data)(struct mdio_bitbang_ctrl *ctrl, int value);
+
+	/* Retrieve the state Management Data I/O pin. */
+	int (*get_mdio_data)(struct mdio_bitbang_ctrl *ctrl);
+};
+
+struct mdio_bitbang_ctrl {
+	const struct mdio_bitbang_ops *ops;
+};
+
+/* The returned bus is not yet registered with the phy layer. */
+struct mii_bus *alloc_mdio_bitbang(struct mdio_bitbang_ctrl *ctrl);
+
+/* The bus must already have been unregistered. */
+void free_mdio_bitbang(struct mii_bus *bus);
+
+#endif
-- 
1.5.0.3

^ permalink raw reply related	[flat|nested] 82+ messages in thread
* [PATCH 1/9] 8xx: Fix CONFIG_PIN_TLB.
@ 2007-09-05 19:27 Scott Wood
  2007-09-05 19:27 ` [PATCH 2/9] 8xx: Infrastructure code cleanup Scott Wood
  0 siblings, 1 reply; 82+ messages in thread
From: Scott Wood @ 2007-09-05 19:27 UTC (permalink / raw)
  To: galak; +Cc: linuxppc-dev

1. Only map 512K of the IMMR, rather than 8M, to avoid conflicting with
the default ioremap region.
2. The wrong register was being loaded into SPRN_MD_RPN.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
 arch/powerpc/kernel/head_8xx.S |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S
index 901be47..e40e122 100644
--- a/arch/powerpc/kernel/head_8xx.S
+++ b/arch/powerpc/kernel/head_8xx.S
@@ -695,7 +695,7 @@ initial_mmu:
 	mtspr	SPRN_MI_AP, r8
 	mtspr	SPRN_MD_AP, r8
 
-	/* Map another 8 MByte at the IMMR to get the processor
+	/* Map another 512 KByte at the IMMR to get the processor
 	 * internal registers (among other things).
 	 */
 #ifdef CONFIG_PIN_TLB
@@ -703,12 +703,12 @@ initial_mmu:
 	mtspr	SPRN_MD_CTR, r10
 #endif
 	mfspr	r9, 638			/* Get current IMMR */
-	andis.	r9, r9, 0xff80		/* Get 8Mbyte boundary */
+	andis.	r9, r9, 0xfff8		/* Get 512K boundary */
 
 	mr	r8, r9			/* Create vaddr for TLB */
 	ori	r8, r8, MD_EVALID	/* Mark it valid */
 	mtspr	SPRN_MD_EPN, r8
-	li	r8, MD_PS8MEG		/* Set 8M byte page */
+	li	r8, MD_PS512K		/* Set 512K byte page */
 	ori	r8, r8, MD_SVALID	/* Make it valid */
 	mtspr	SPRN_MD_TWC, r8
 	mr	r8, r9			/* Create paddr for TLB */
@@ -730,13 +730,13 @@ initial_mmu:
 	mtspr	SPRN_MD_TWC, r9
 	li	r11, MI_BOOTINIT	/* Create RPN for address 0 */
 	addis	r11, r11, 0x0080	/* Add 8M */
-	mtspr	SPRN_MD_RPN, r8
+	mtspr	SPRN_MD_RPN, r11
 
 	addis	r8, r8, 0x0080		/* Add 8M */
 	mtspr	SPRN_MD_EPN, r8
 	mtspr	SPRN_MD_TWC, r9
 	addis	r11, r11, 0x0080	/* Add 8M */
-	mtspr	SPRN_MD_RPN, r8
+	mtspr	SPRN_MD_RPN, r11
 #endif
 
 	/* Since the cache is enabled according to the information we
-- 
1.5.3

^ permalink raw reply related	[flat|nested] 82+ messages in thread

end of thread, other threads:[~2007-09-15  2:25 UTC | newest]

Thread overview: 82+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-28 20:11 [PATCH v3 1/8] Generic bitbanged MDIO library Scott Wood
2007-08-28 20:14 ` [PATCH v3 2/8] fs_enet: Whitespace cleanup Scott Wood
2007-08-28 20:14 ` [PATCH v3 3/8] fs_enet: Include linux/string.h from linux/fs_enet_pd.h Scott Wood
2007-08-28 20:14 ` [PATCH v3 4/8] fs_enet: Don't share the interrupt Scott Wood
2007-08-28 20:14 ` [PATCH v3 5/8] fs_enet: mac-fcc: Eliminate __fcc-* macros Scott Wood
2007-08-28 20:14 ` [PATCH v3 6/8] fs_enet: Align receive buffers Scott Wood
2007-08-28 20:14 ` [PATCH v3 7/8] fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set Scott Wood
2007-08-28 20:14 ` [PATCH v3 8/8] fs_enet: sparse fixes Scott Wood
2007-08-28 20:16 ` [PATCH 1/3] fsl_soc.c cleanup Scott Wood
2007-08-29  5:30   ` David Gibson
2007-09-11  5:35   ` Kumar Gala
2007-09-11 13:57     ` Scott Wood
2007-09-11 15:48       ` Kumar Gala
2007-09-11 15:51         ` Scott Wood
2007-09-11 16:22           ` Kumar Gala
2007-09-11 16:24             ` Scott Wood
2007-09-11 16:45               ` SOC registers/immr determination from device tree (was Re: [PATCH 1/3] fsl_soc.c cleanup) Kumar Gala
2007-09-11 17:03                 ` Scott Wood
2007-09-11 17:08                   ` Josh Boyer
2007-09-11 17:54                   ` Kumar Gala
2007-08-28 20:16 ` [PATCH 2/3] Introduce new CPM device bindings Scott Wood
2007-08-29  5:39   ` David Gibson
2007-08-29 13:58     ` Scott Wood
2007-08-30  0:55       ` David Gibson
2007-08-30  5:48         ` Scott Wood
2007-08-30  5:58           ` David Gibson
2007-08-30 14:10             ` Scott Wood
2007-08-31  2:48               ` David Gibson
2007-08-28 20:16 ` [PATCH 3/3] Add early debug console for CPM serial ports Scott Wood
2007-08-29  5:45   ` David Gibson
2007-08-29 14:02     ` Scott Wood
2007-08-29 19:58       ` Scott Wood
2007-08-30  0:58         ` David Gibson
2007-08-30  0:57       ` David Gibson
2007-08-28 20:16 ` [PATCH 1/4] ppc: Add clrbits8 and setbits8 Scott Wood
2007-08-28 20:16 ` [PATCH 2/4] cpm_uart: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set Scott Wood
2007-08-28 20:16 ` [PATCH 3/4] cpm_uart: sparse fixes Scott Wood
2007-08-28 20:16 ` [PATCH 4/4] cpm_uart: Issue STOP_TX command before initializing console Scott Wood
2007-08-28 20:17 ` [PATCH 1/9] 8xx: Fix CONFIG_PIN_TLB Scott Wood
2007-08-29 21:09   ` Vitaly Bordug
2007-08-28 20:17 ` [PATCH 2/9] 8xx: Infrastructure code cleanup Scott Wood
2007-09-13  7:11   ` David Gibson
2007-09-13  8:16     ` Vitaly Bordug
2007-09-14  4:09       ` David Gibson
2007-09-14  8:21         ` Vitaly Bordug
2007-09-15  2:25           ` David Gibson
2007-09-13 14:40     ` Scott Wood
2007-08-28 20:17 ` [PATCH 3/9] 8xx: Add pin and clock setting functions Scott Wood
2007-08-29 21:38   ` Vitaly Bordug
2007-08-31 20:44     ` Scott Wood
2007-09-05  7:39       ` Vitaly Bordug
2007-09-05 17:37         ` Scott Wood
2007-08-28 20:17 ` [PATCH 4/9] 8xx: Work around CPU15 erratum Scott Wood
2007-08-28 20:17 ` [PATCH 5/9] 8xx: Don't call non-existent Soft_emulate_8xx from SoftwareEmulation Scott Wood
2007-08-28 20:17 ` [PATCH 6/9] 8xx: Set initial memory limit John Traill
2007-08-28 20:19 ` Scott Wood
2007-08-28 20:19 ` [PATCH 7/9] 8xx: mpc885ads cleanup Scott Wood
2007-08-29 22:03   ` Vitaly Bordug
2007-08-28 20:19 ` [PATCH 8/9] 8xx: Embedded Planet EP88xC support Scott Wood
2007-08-28 20:19 ` [PATCH 9/9] 8xx: Adder 875 support Scott Wood
2007-08-28 20:19 ` [PATCH 1/9] cpm2: Infrastructure code cleanup Scott Wood
2007-08-28 20:19 ` [PATCH 2/9] cpm2: Fix off-by-one error in setbrg() Scott Wood
2007-08-29 22:09   ` Vitaly Bordug
2007-08-30 20:13     ` Scott Wood
2007-08-30 21:52       ` Vitaly Bordug
2007-08-28 20:19 ` [PATCH 3/9] cpm2: Add SCCs to cpm2_clk_setup(), and cpm2_smc_clk_setup() Scott Wood
2007-08-29 22:25   ` Vitaly Bordug
2007-08-30 20:15     ` Scott Wood
2007-09-04 20:43       ` Vitaly Bordug
2007-08-28 20:19 ` [PATCH 4/9] cpm2: Add cpm2_set_pin() Scott Wood
2007-09-04 20:51   ` Vitaly Bordug
2007-08-28 20:19 ` [PATCH 5/9] mpc82xx: Remove a bunch of cruft that duplicates generic functionality Scott Wood
2007-08-28 20:19 ` [PATCH 6/9] mpc82xx: Rename mpc82xx_ads to mpc8272_ads Scott Wood
2007-08-29  5:55   ` David Gibson
2007-08-28 20:19 ` [PATCH 7/9] mpc8272ads: Change references from 82xx_ADS to 8272_ADS Scott Wood
2007-08-28 20:19 ` [PATCH 8/9] mpc82xx: Update mpc8272ads, and factor out PCI and reset Scott Wood
2007-08-29 22:41   ` Kumar Gala
2007-08-30  5:56     ` Scott Wood
2007-08-30 14:56       ` Kumar Gala
2007-08-30 15:17         ` Scott Wood
2007-08-28 20:19 ` [PATCH 9/9] mpc82xx: Add pq2fads board support Scott Wood
  -- strict thread matches above, loose matches on Subject: below --
2007-09-05 19:27 [PATCH 1/9] 8xx: Fix CONFIG_PIN_TLB Scott Wood
2007-09-05 19:27 ` [PATCH 2/9] 8xx: Infrastructure code cleanup Scott Wood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).