From patchwork Mon Mar 26 11:34:47 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valentin Longchamp X-Patchwork-Id: 148726 X-Patchwork-Delegate: prafulla@marvell.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id DBD40B6EEA for ; Mon, 26 Mar 2012 23:27:34 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4516A28149; Mon, 26 Mar 2012 14:26:05 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VRCDp7VCwsYj; Mon, 26 Mar 2012 14:26:05 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 58C7D28196; Mon, 26 Mar 2012 14:22:26 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 899EB2812C for ; Mon, 26 Mar 2012 13:35:24 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id rhVdQV9GrsBL for ; Mon, 26 Mar 2012 13:35:13 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail.ch.keymile.com (mail.ch.keymile.com [193.17.201.103]) by theia.denx.de (Postfix) with SMTP id 86B912813D for ; Mon, 26 Mar 2012 13:34:57 +0200 (CEST) Received: from SRVCHBER1212.ch.keymile.net ([172.31.32.9]) by eSafe SMTP Relay 1332273563; Mon, 26 Mar 2012 13:34:55 +0100 Received: from chber1-10533x.ch.keymile.net ([172.31.40.3]) by SRVCHBER1212.ch.keymile.net with Microsoft SMTPSVC(6.0.3790.4675); Mon, 26 Mar 2012 13:34:53 +0200 From: Valentin Longchamp To: u-boot@lists.denx.de Date: Mon, 26 Mar 2012 13:34:47 +0200 Message-Id: <1332761689-16666-18-git-send-email-valentin.longchamp@keymile.com> X-Mailer: git-send-email 1.7.1 In-Reply-To: <1332761689-16666-1-git-send-email-valentin.longchamp@keymile.com> References: <1332761689-16666-1-git-send-email-valentin.longchamp@keymile.com> X-OriginalArrivalTime: 26 Mar 2012 11:34:53.0450 (UTC) FILETIME=[7653D6A0:01CD0B44] X-ESAFE-STATUS: [srvchber1306.keymile.net] Mail allowed X-Mailman-Approved-At: Mon, 26 Mar 2012 14:21:52 +0200 Cc: Valentin Longchamp , Holger Brunck , Gerlando Falauto , Prafulla@theia.denx.de Subject: [U-Boot] [PATCH v2 17/19] arm/km: correct init of 88e6352 switch in the reset_phy function X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de This is achieved thanks to the support read/write regs for the external 88e6352 switch. The functions for this are added into an own file managed_switch.c. This is compiled if the define CONFIG_KM_MANAGED_SW_ADDR was set in the board setup. This define specifies the phy address. Signed-off-by: Valentin Longchamp Signed-off-by: Holger Brunck cc: Gerlando Falauto cc: Prafulla Wadaskar --- board/keymile/common/common.h | 6 + board/keymile/km_arm/Makefile | 4 + board/keymile/km_arm/km_arm.c | 26 +++++- board/keymile/km_arm/managed_switch.c | 166 +++++++++++++++++++++++++++++++++ include/configs/km_kirkwood.h | 13 +++ 5 files changed, 214 insertions(+), 1 deletions(-) create mode 100644 board/keymile/km_arm/managed_switch.c diff --git a/board/keymile/common/common.h b/board/keymile/common/common.h index 6c1f640..49225b8 100644 --- a/board/keymile/common/common.h +++ b/board/keymile/common/common.h @@ -125,6 +125,12 @@ struct bfticu_iomap { int ethernet_present(void); int ivm_read_eeprom(void); + +int ext_switch_reg_write(const char *devname, u8 phy_addr, u8 port, + u8 reg, u16 data); +int ext_switch_reg_read(const char *devname, u8 phy_addr, u8 port, + u8 reg, u16 *data); + int set_km_env(void); int fdt_set_node_and_value(void *blob, char *nodename, diff --git a/board/keymile/km_arm/Makefile b/board/keymile/km_arm/Makefile index aa51255..06079e9 100644 --- a/board/keymile/km_arm/Makefile +++ b/board/keymile/km_arm/Makefile @@ -31,6 +31,10 @@ LIB = $(obj)lib$(BOARD).o COBJS := $(BOARD).o ../common/common.o ../common/ivm.o +ifdef CONFIG_KM_MANAGED_SW_ADDR +COBJS += managed_switch.o +endif + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) SOBJS := $(addprefix $(obj),$(SOBJS)) diff --git a/board/keymile/km_arm/km_arm.c b/board/keymile/km_arm/km_arm.c index 4b83439..f4be40f 100644 --- a/board/keymile/km_arm/km_arm.c +++ b/board/keymile/km_arm/km_arm.c @@ -9,6 +9,9 @@ * (C) Copyright 2010 * Heiko Schocher, DENX Software Engineering, hs@denx.de. * + * (C) Copyright 2011, 2012 + * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com + * * See file CREDITS for list of people who contributed to this * project. * @@ -36,6 +39,7 @@ #include #include #include +#include #include #include @@ -367,7 +371,27 @@ void reset_phy(void) /* reset the phy */ miiphy_reset(name, CONFIG_PHY_BASE_ADR); } -#elif !defined(CONFIG_KM_PIGGY4_88E6352) +#elif defined(CONFIG_KM_PIGGY4_88E6352) + +#if defined(CONFIG_KM_MANAGED_SW_ADDR) +void reset_phy(void) +{ + char *name = "egiga0"; + + if (miiphy_set_current_dev(name)) + return; + + /* enable autoneg on port 0 phy */ + ext_switch_reg_write(name, CONFIG_KM_MANAGED_SW_ADDR, 0, 0, 0x3300); + + /* egress broadcast franes on all macs, with forwarding */ + ext_switch_reg_write(name, CONFIG_KM_MANAGED_SW_ADDR, 16, 4, 0x000f); + ext_switch_reg_write(name, CONFIG_KM_MANAGED_SW_ADDR, 20, 4, 0x000f); + ext_switch_reg_write(name, CONFIG_KM_MANAGED_SW_ADDR, 21, 4, 0x000f); +} +#endif + +#else /* Configure and enable MV88E1118 PHY on the piggy*/ void reset_phy(void) { diff --git a/board/keymile/km_arm/managed_switch.c b/board/keymile/km_arm/managed_switch.c new file mode 100644 index 0000000..482c18d --- /dev/null +++ b/board/keymile/km_arm/managed_switch.c @@ -0,0 +1,166 @@ +/* + * (C) Copyright 2012 + * Valentin Lontgchamp, Keymile AG, valentin.longchamp@keymile.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ + +#include +#include +#include + +#define SMI_HDR ((0x8 | 0x1) << 12) +#define SMI_BUSY_MASK (0x8000) +#define SMIRD_OP (0x2 << 10) +#define SMIWR_OP (0x1 << 10) +#define SMI_MASK 0x1f +#define PORT_SHIFT 5 + +#define COMMAND_REG 0 +#define DATA_REG 1 + +static int ext_switch_wait_rdy(const char *devname, u8 phy_addr) +{ + u16 command; + u32 timeout = 100; + int ret; + + /* wait till the SMI is not busy */ + do { + /* read command register */ + ret = miiphy_read(devname, phy_addr, COMMAND_REG, &command); + if (ret < 0) { + printf("%s: Error reading command register\n", + __func__); + return ret; + } + if (timeout-- == 0) { + printf("Err..(%s) SMI busy timeout\n", __func__); + return -EFAULT; + } + } while (command & SMI_BUSY_MASK); + + return 0; +} + +int ext_switch_reg_read(const char *devname, u8 phy_addr, u8 port, + u8 reg, u16 *data) +{ + int ret; + u16 command; + + ret = ext_switch_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + command = SMI_HDR | SMIRD_OP | ((port&SMI_MASK) << PORT_SHIFT) | + (reg & SMI_MASK); + debug("%s: write to command: %#x\n", __func__, command); + ret = miiphy_write(devname, phy_addr, COMMAND_REG, command); + if (ret) + return ret; + + ret = ext_switch_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + ret = miiphy_read(devname, phy_addr, DATA_REG, data); + + return ret; +} + +int ext_switch_reg_write(const char *devname, u8 phy_addr, u8 port, + u8 reg, u16 data) +{ + int ret; + u16 value; + + ret = ext_switch_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + debug("%s: write to data: %#x\n", __func__, data); + ret = miiphy_write(devname, phy_addr, DATA_REG, data); + if (ret) + return ret; + + value = SMI_HDR | SMIWR_OP | ((port & SMI_MASK) << PORT_SHIFT) | + (reg & SMI_MASK); + debug("%s: write to command: %#x\n", __func__, value); + ret = miiphy_write(devname, phy_addr, COMMAND_REG, value); + if (ret) + return ret; + + ret = ext_switch_wait_rdy(devname, phy_addr); + if (ret) + return ret; + + return 0; +} + +int do_sw_reg_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char *name = "egiga0"; + u16 value = 0, phyaddr, reg, port; + int ret; + + if (argc < 4) + return cmd_usage(cmdtp); + + phyaddr = simple_strtoul(argv[1], NULL, 16); + port = simple_strtoul(argv[2], NULL, 10); + reg = simple_strtoul(argv[3], NULL, 10); + + ret = ext_switch_reg_read(name, phyaddr, port, reg, &value); + printf("%#x\n", value); + + return ret; +} + +U_BOOT_CMD( + sw_reg_read, 4, 1, do_sw_reg_read, + "read the switch registers", + " \n" + ); + +int do_sw_reg_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + char *name = "egiga0"; + u16 value = 0, phyaddr, reg, port; + int ret; + + if (argc < 5) + return cmd_usage(cmdtp); + + phyaddr = simple_strtoul(argv[1], NULL, 16); + port = simple_strtoul(argv[2], NULL, 10); + reg = simple_strtoul(argv[3], NULL, 10); + value = simple_strtoul(argv[4], NULL, 16); + + ret = ext_switch_reg_write(name, phyaddr, port, reg, value); + + return ret; +} + +U_BOOT_CMD( + sw_reg_write, 5, 1, do_sw_reg_write, + "write the the switch registers", + " \n" + ); + diff --git a/include/configs/km_kirkwood.h b/include/configs/km_kirkwood.h index fbe714b..059fdbc 100644 --- a/include/configs/km_kirkwood.h +++ b/include/configs/km_kirkwood.h @@ -58,6 +58,7 @@ #define CONFIG_KM_FPGA_CONFIG #define CONFIG_KM_PIGGY4_88E6352 +#define CONFIG_KM_MANAGED_SW_ADDR 0x10 /* KM_MGCOGE3UN */ #elif defined(CONFIG_KM_MGCOGE3UN) #define CONFIG_IDENT_STRING "\nKeymile COGE3UN" @@ -131,6 +132,18 @@ MVGBE_SET_GMII_SPEED_TO_1000 |\ MVGBE_SET_MII_SPEED_TO_100) +/* + * There is no phy on the eth interface, but an external switch + * For kmcoge5un it is completely unmanaged, so we disable an access to it + * For km_nusa, we an MDIO(MII) interface that can configure the switch trough + * an indirect access, so we do not disable the MII + */ +#ifndef CONFIG_KM_MANAGED_SW_ADDR +#undef CONFIG_MII +#undef CONFIG_CMD_MII +#undef CONFIG_RESET_PHY_R +#endif + #endif #ifdef CONFIG_KM_PIGGY4_88E6061