From patchwork Thu Jun 20 13:15:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dirk Eibach X-Patchwork-Id: 252923 X-Patchwork-Delegate: sr@denx.de 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 E2D4C2C02A8 for ; Thu, 20 Jun 2013 23:16:29 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4EA2B4A166; Thu, 20 Jun 2013 15:16:25 +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 lltAKmxE5xpq; Thu, 20 Jun 2013 15:16:25 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 72B3F4A17A; Thu, 20 Jun 2013 15:16:14 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4071C4A15A for ; Thu, 20 Jun 2013 15:16:03 +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 G17q8xm3jC-I for ; Thu, 20 Jun 2013 15:15:58 +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 smtprelay01.ispgateway.de (smtprelay01.ispgateway.de [80.67.31.35]) by theia.denx.de (Postfix) with ESMTP id 381C44A15C for ; Thu, 20 Jun 2013 15:15:47 +0200 (CEST) Received: from [217.6.197.18] (helo=bob3.gd.local) by smtprelay01.ispgateway.de with esmtpa (Exim 4.68) (envelope-from ) id 1UpeiJ-0004FI-8E; Thu, 20 Jun 2013 15:15:47 +0200 From: dirk.eibach@gdsys.cc To: u-boot@lists.denx.de, Stefan Roese Date: Thu, 20 Jun 2013 15:15:34 +0200 Message-Id: <1371734138-23316-3-git-send-email-dirk.eibach@gdsys.cc> X-Mailer: git-send-email 1.8.3 In-Reply-To: <1371734138-23316-1-git-send-email-dirk.eibach@gdsys.cc> References: <1371734138-23316-1-git-send-email-dirk.eibach@gdsys.cc> X-Df-Sender: ZGlyay5laWJhY2hAZ2RzeXMuY2M= Subject: [U-Boot] [PATCH v4 2/6] powerpc/ppc4xx: Add gdsys mclink interface 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 From: Dirk Eibach mclink is a serial interface for communication between gdsys FPGA. Signed-off-by: Dirk Eibach --- Changes in v4: None Changes in v3: - adapt to "powerpc/ppc4xx: Use generic accessor functions for gdsys FPGA" - squashed with "powerpc/ppc4xx: Increase timeout for gdsys mclink bus startup" Changes in v2: - update email account board/gdsys/common/mclink.c | 153 ++++++++++++++++++++++++++++++++++++++++++++ board/gdsys/common/mclink.h | 31 +++++++++ 2 files changed, 184 insertions(+) create mode 100644 board/gdsys/common/mclink.c create mode 100644 board/gdsys/common/mclink.h diff --git a/board/gdsys/common/mclink.c b/board/gdsys/common/mclink.c new file mode 100644 index 0000000..e0382a3 --- /dev/null +++ b/board/gdsys/common/mclink.c @@ -0,0 +1,153 @@ +/* + * (C) Copyright 2012 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#include + +enum { + MCINT_SLAVE_LINK_CHANGED_EV = 1 << 7, + MCINT_TX_ERROR_EV = 1 << 9, + MCINT_TX_BUFFER_FREE = 1 << 10, + MCINT_TX_PACKET_TRANSMITTED_EV = 1 << 11, + MCINT_RX_ERROR_EV = 1 << 13, + MCINT_RX_CONTENT_AVAILABLE = 1 << 14, + MCINT_RX_PACKET_RECEIVED_EV = 1 << 15, +}; + +int mclink_probe(void) +{ + unsigned int k; + int slaves = 0; + + for (k = 0; k < CONFIG_SYS_MCLINK_MAX; ++k) { + int timeout = 0; + unsigned int ctr = 0; + u16 mc_status; + + FPGA_GET_REG(k, mc_status, &mc_status); + + if (!(mc_status & (1 << 15))) + break; + + FPGA_SET_REG(k, mc_control, 0x8000); + + FPGA_GET_REG(k, mc_status, &mc_status); + while (!(mc_status & (1 << 14))) { + udelay(100); + if (ctr++ > 500) { + timeout = 1; + break; + } + FPGA_GET_REG(k, mc_status, &mc_status); + } + if (timeout) + break; + + printf("waited %d us for mclink %d to come up\n", ctr * 100, k); + + slaves++; + } + + return slaves; +} + +int mclink_send(u8 slave, u16 addr, u16 data) +{ + unsigned int ctr = 0; + u16 int_status; + u16 rx_cmd_status; + u16 rx_cmd; + + /* reset interrupt status */ + FPGA_GET_REG(0, mc_int, &int_status); + FPGA_SET_REG(0, mc_int, int_status); + + /* send */ + FPGA_SET_REG(0, mc_tx_address, addr); + FPGA_SET_REG(0, mc_tx_data, data); + FPGA_SET_REG(0, mc_tx_cmd, (slave & 0x03) << 14); + FPGA_SET_REG(0, mc_control, 0x8001); + + /* wait for reply */ + FPGA_GET_REG(0, mc_int, &int_status); + while (!(int_status & MCINT_RX_PACKET_RECEIVED_EV)) { + udelay(100); + if (ctr++ > 3) + return -ETIMEDOUT; + FPGA_GET_REG(0, mc_int, &int_status); + } + + FPGA_GET_REG(0, mc_rx_cmd_status, &rx_cmd_status); + rx_cmd = (rx_cmd_status >> 12) & 0x03; + if (rx_cmd != 0) + printf("mclink_send: received cmd %d, expected %d\n", rx_cmd, + 0); + + return 0; +} + +int mclink_receive(u8 slave, u16 addr, u16 *data) +{ + u16 rx_cmd_status; + u16 rx_cmd; + u16 int_status; + unsigned int ctr = 0; + + /* send read request */ + FPGA_SET_REG(0, mc_tx_address, addr); + FPGA_SET_REG(0, mc_tx_cmd, + ((slave & 0x03) << 14) | (1 << 12) | (1 << 0)); + FPGA_SET_REG(0, mc_control, 0x8001); + + + /* wait for reply */ + FPGA_GET_REG(0, mc_int, &int_status); + while (!(int_status & MCINT_RX_CONTENT_AVAILABLE)) { + udelay(100); + if (ctr++ > 3) + return -ETIMEDOUT; + FPGA_GET_REG(0, mc_int, &int_status); + } + + /* check reply */ + FPGA_GET_REG(0, mc_rx_cmd_status, &rx_cmd_status); + if ((rx_cmd_status >> 14) != slave) { + printf("mclink_receive: reply from slave %d, expected %d\n", + rx_cmd_status >> 14, slave); + return -EINVAL; + } + + rx_cmd = (rx_cmd_status >> 12) & 0x03; + if (rx_cmd != 1) { + printf("mclink_send: received cmd %d, expected %d\n", + rx_cmd, 1); + return -EIO; + } + + FPGA_GET_REG(0, mc_rx_data, data); + + return 0; +} diff --git a/board/gdsys/common/mclink.h b/board/gdsys/common/mclink.h new file mode 100644 index 0000000..47a62b4 --- /dev/null +++ b/board/gdsys/common/mclink.h @@ -0,0 +1,31 @@ +/* + * (C) Copyright 2012 + * Dirk Eibach, Guntermann & Drunck GmbH, dirk.eibach@gdsys.cc + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _MCLINK_H_ +#define _MCLINK_H_ + +int mclink_probe(void); +int mclink_send(u8 slave, u16 addr, u16 data); +int mclink_receive(u8 slave, u16 addr, u16 *data); + +#endif