From patchwork Wed Nov 3 05:29:20 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathew McBride X-Patchwork-Id: 1550121 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=traverse.com.au header.i=@traverse.com.au header.a=rsa-sha256 header.s=fm2 header.b=dfF7fYAh; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm1 header.b=KenXlzhu; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Hkb2Y6n3vz9sRK for ; Wed, 3 Nov 2021 16:30:29 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 7B01C834B5; Wed, 3 Nov 2021 06:30:20 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=traverse.com.au Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=traverse.com.au header.i=@traverse.com.au header.b="dfF7fYAh"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="KenXlzhu"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id F32428325E; Wed, 3 Nov 2021 06:30:16 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id DEF7F83325 for ; Wed, 3 Nov 2021 06:30:12 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=traverse.com.au Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=matt@traverse.com.au Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 20EE45C0130; Wed, 3 Nov 2021 01:30:12 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Wed, 03 Nov 2021 01:30:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=traverse.com.au; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=pwvF0B9dXs2S6 U8TdRD+OlnSIocpoMvb+a8ADsVvguU=; b=dfF7fYAhiIN8gDWTkT7egJoVelxE7 O8LfdhKN/CQ32DMGKKiHww8L/NDSeSfgUwfTYtwApnLynTrfyPUmj9H3u5dApv2c 0gKSVVBRmguqqNGonZFe3cjY+ytCoUVpuF72fwxkx3U7RH2fyVM4N6rNYJZG1FVV wM3m3aJk5dOMAVzNLXO0vrosQwrw7DOS2DBoduAO/YVfeh/FIBME0zYkZKBqaTVo zeEOQNKJHiQhAr2pn+j964nShI2NuEJNZG8j+AOug/4SMHzVDDt/W7fG3aWJbZ8+ WNVUYHO5gbjQiLhCevwypAz4I4YM45tTSfiaH8dj+xWtxhBxw5d2KWePg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=pwvF0B9dXs2S6U8TdRD+OlnSIocpoMvb+a8ADsVvguU=; b=KenXlzhu rc6zr69cj8duUFEONKW0/dDhrK//OcbqAVscUh4GrWb+EkEvWfSqsaYWN2MUxgb0 wYiY1AWSUINy+c8e9CRS6VKlU7PAOQx+K05ktmabuIjGi9btPpurXZiTdXmafNsR BOYzDoHFP4D3rmbdHCLwxAAer44ppJ97xeZnhXNsXff1hIzdEPM6pMILY+A9w7y2 dwkMj8mqRHAo7XsbnzQcfFuJSMIgByrXB6hCX9kgMTp05sxBP2a3lQ270RUAsJmO YZSJ1S9ITpLq4FicoN/k9fyad2kUjdZQvIN0u0u7bdVvZHTR7I9j/vX6kAaQG+Jv qgDgEbyhdOiP3Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvuddrtddugdekudcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepofgrthhhvgif ucfotgeurhhiuggvuceomhgrthhtsehtrhgrvhgvrhhsvgdrtghomhdrrghuqeenucggtf frrghtthgvrhhnpeekleevteelvdduheetgfdvfeelueekffeggeethedtteeljeeivedv gfehjeejheenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhroh hmpehmrghtthesthhrrghvvghrshgvrdgtohhmrdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 3 Nov 2021 01:30:10 -0400 (EDT) From: Mathew McBride To: u-boot@lists.denx.de, Priyanka Jain Cc: Mathew McBride Subject: [PATCH 1/2] board: traverse: add Ten64 board controller driver Date: Wed, 3 Nov 2021 05:29:20 +0000 Message-Id: <20211103052921.2718-2-matt@traverse.com.au> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20211103052921.2718-1-matt@traverse.com.au> References: <20211103052921.2718-1-matt@traverse.com.au> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Traverse Technologies Ten64 family boards use a microcontroller to control low level board functions like startup and reset, as well as holding details such as the board MAC address. Communication between the CPU and microcontroller is via I2C. To keep the driver structure clean between the Ten64 board file, DM_I2C, and a future utility command, this driver has been implemented as a misc uclass device. Signed-off-by: Mathew McBride --- board/traverse/common/Kconfig | 6 + board/traverse/common/Makefile | 1 + board/traverse/common/ten64-controller.h | 28 +++ board/traverse/common/ten64_controller.c | 238 +++++++++++++++++++++++ 4 files changed, 273 insertions(+) create mode 100644 board/traverse/common/Kconfig create mode 100644 board/traverse/common/Makefile create mode 100644 board/traverse/common/ten64-controller.h create mode 100644 board/traverse/common/ten64_controller.c diff --git a/board/traverse/common/Kconfig b/board/traverse/common/Kconfig new file mode 100644 index 0000000000..d34832bd0d --- /dev/null +++ b/board/traverse/common/Kconfig @@ -0,0 +1,6 @@ +config TEN64_CONTROLLER + bool "Enable Ten64 board controller driver" + depends on TARGET_TEN64 + help + Support for the board microcontroller on the Traverse + Ten64 family of boards. diff --git a/board/traverse/common/Makefile b/board/traverse/common/Makefile new file mode 100644 index 0000000000..d31e3535b9 --- /dev/null +++ b/board/traverse/common/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_TEN64_CONTROLLER) += ten64_controller.o diff --git a/board/traverse/common/ten64-controller.h b/board/traverse/common/ten64-controller.h new file mode 100644 index 0000000000..fed6af470d --- /dev/null +++ b/board/traverse/common/ten64-controller.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +#ifndef TEN64_CNTRL_H +#define TEN64_CNTRL_H + +/** + * struct t64uc_board_info - Board Information Structure + * @mac: Base MAC address + * @cpuId: Microcontroller unique serial number + * @fwversion_major: Microcontroller version number (Major) + * @fwversion_minor: Microcontroller version number (Minor) + * @fwversion_patch: Microcontroller version number (Patch) + */ +struct t64uc_board_info { + u8 mac[6]; + u32 cpuId[4]; + u8 fwversion_major; + u8 fwversion_minor; + u8 fwversion_patch; +} __packed; + +enum { + TEN64_CNTRL_GET_BOARD_INFO, + TEN64_CNTRL_10G_OFF, + TEN64_CNTRL_10G_ON, + TEN64_CNTRL_SET_NEXT_BOOTSRC +}; + +#endif diff --git a/board/traverse/common/ten64_controller.c b/board/traverse/common/ten64_controller.c new file mode 100644 index 0000000000..11e068f94f --- /dev/null +++ b/board/traverse/common/ten64_controller.c @@ -0,0 +1,238 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* Ten64 Board Microcontroller Driver + * Copyright 2021 Traverse Technologies Australia + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ten64-controller.h" + +/* Microcontroller command set and structure + * These should not be used outside this file + */ + +#define T64_UC_DATA_MAX_SIZE 128U +#define T64_UC_API_MSG_HEADER_SIZE 4U +#define T64_UC_API_HEADER_PREAMB 0xcabe + +#define TEN64_UC_CMD_SET_BOARD_MAC 0x10 +#define TEN64_UC_CMD_GET_BOARD_INFO 0x11 + +#define TEN64_UC_CMD_GET_STATE 0x20 +#define TEN64_UC_CMD_SET_RESET_BTN_HOLD_TIME 0x21 +#define TEN64_UC_CMD_ENABLE_RESET_BUTTON 0x22 +#define TEN64_UC_CMD_SET_NEXT_BOOTSRC 0x23 +#define TEN64_UC_CMD_ENABLE_10G 0x24 + +#define TEN64_UC_CMD_FWUP_GET_INFO 0xA0 +#define TEN64_UC_CMD_FWUP_INIT 0xA1 +#define TEN64_UC_CMD_FWUP_XFER 0xA2 +#define TEN64_UC_CMD_FWUP_CHECK 0xA3 +#define TEN64_UC_CMD_FWUPBOOT 0xA + +/** struct t64uc_message - Wire Format for microcontroller messages + * @preamb: Message preamble (always 0xcabe) + * @cmd: Command to invoke + * @len: Length of data + * @data: Command data, up to 128 bytes + */ +struct t64uc_message { + u16 preamb; + u8 cmd; + u8 len; + u8 data[T64_UC_DATA_MAX_SIZE]; +} __packed; + +#define T64_CTRL_IO_SET 1U +#define T64_CTRL_IO_CLEAR 2U +#define T64_CTRL_IO_TOGGLE 3U +#define T64_CTRL_IO_RESET 4U +#define T64_CTRL_IO_UNKNOWN 5U + +/** struct t64uc_board_10g_enable - Wrapper for 10G enable command + * @control: state to set the 10G retimer - either + * T64_CTRL_IO_CLEAR (0x02) for off or + * T64_CTRL_IO_SET (0x01) for on. + * + * This struct exists to simplify the wrapping of the + * command value into a microcontroller message and passing into + * functions. + */ +struct t64uc_board_10g_enable { + u8 control; +} __packed; + +/** ten64_controller_send_recv_command() - Wrapper function to + * send a command to the microcontroller. + * @uc_chip: the DM I2C chip handle for the microcontroller + * @uc_cmd: the microcontroller API command code + * @uc_cmd_data: pointer to the data struct for this command + * @uc_data_len: size of command data struct + * @return_data: place to store response from microcontroller, NULL if not expected + * @expected_return_len: expected size of microcontroller command response + * @return_message_wait: wait this long (in us) before reading the response + * + * Invoke a microcontroller command and receive a response. + * This function includes communicating with the microcontroller over + * I2C and encoding a message in the wire format. + * + * Return: 0 if successful, error code otherwise. + * Returns -EBADMSG if the microcontroller response could not be validated, + * other error codes may be passed from dm_i2c_xfer() + */ +static int ten64_controller_send_recv_command(struct udevice *ucdev, u8 uc_cmd, + void *uc_cmd_data, u8 cmd_data_len, + void *return_data, u8 expected_return_len, + u16 return_message_wait) +{ + int ret; + struct t64uc_message send, recv; + struct i2c_msg command_message, return_message; + struct dm_i2c_chip *chip = dev_get_parent_plat(ucdev); + + dev_dbg(ucdev, "%s sending cmd %02X len %d\n", __func__, uc_cmd, cmd_data_len); + + send.preamb = T64_UC_API_HEADER_PREAMB; + send.cmd = uc_cmd; + send.len = cmd_data_len; + if (uc_cmd_data && cmd_data_len > 0) + memcpy(send.data, uc_cmd_data, cmd_data_len); + + command_message.addr = chip->chip_addr; + command_message.len = T64_UC_API_MSG_HEADER_SIZE + send.len; + command_message.buf = (void *)&send; + command_message.flags = I2C_M_STOP; + + ret = dm_i2c_xfer(ucdev, &command_message, 1); + if (!return_data) + return ret; + + udelay(return_message_wait); + + return_message.addr = chip->chip_addr; + return_message.len = T64_UC_API_MSG_HEADER_SIZE + expected_return_len; + return_message.buf = (void *)&recv; + return_message.flags = I2C_M_RD; + + ret = dm_i2c_xfer(ucdev, &return_message, 1); + if (ret) + return ret; + + if (recv.preamb != T64_UC_API_HEADER_PREAMB) { + dev_err(ucdev, "%s: No preamble received in microcontroller response\n", + __func__); + return -EBADMSG; + } + if (recv.cmd != uc_cmd) { + dev_err(ucdev, "%s: command response mismatch, got %02X expecting %02X\n", + __func__, recv.cmd, uc_cmd); + return -EBADMSG; + } + if (recv.len != expected_return_len) { + dev_err(ucdev, "%s: received message has unexpected length, got %d expected %d\n", + __func__, recv.len, expected_return_len); + return -EBADMSG; + } + memcpy(return_data, recv.data, expected_return_len); + return ret; +} + +/** ten64_controller_send_command() - Send command to microcontroller without + * expecting a response (for example, invoking a control command) + * @uc_chip: the DM I2C chip handle for the microcontroller + * @uc_cmd: the microcontroller API command code + * @uc_cmd_data: pointer to the data struct for this command + * @uc_data_len: size of command data struct + */ +static int ten64_controller_send_command(struct udevice *ucdev, u8 uc_cmd, + void *uc_cmd_data, u8 cmd_data_len) +{ + return ten64_controller_send_recv_command(ucdev, uc_cmd, + uc_cmd_data, cmd_data_len, + NULL, 0, 0); +} + +/** ten64_controller_get_board_info() - Get board information from microcontroller + * @dev: The microcontroller device handle + * @out: Pointer to a t64uc_board_info struct that has been allocated by the caller + */ +static int ten64_controller_get_board_info(struct udevice *dev, struct t64uc_board_info *out) +{ + int ret; + + ret = ten64_controller_send_recv_command(dev, TEN64_UC_CMD_GET_BOARD_INFO, + NULL, 0, out, + sizeof(struct t64uc_board_info), + 10000); + if (ret) { + dev_err(dev, "%s unable to send board info command: %d\n", + __func__, ret); + return ret; + } + + return 0; +} + +/** + * ten64_controller_10g_enable_command() - Sends a 10G (Retimer) enable command + * to the microcontroller. + * @ucdev: The microcontroller udevice + * @value: The value flag for the 10G state + */ +static int ten64_controller_10g_enable_command(struct udevice *ucdev, u8 value) +{ + int ret; + struct t64uc_board_10g_enable enable_msg; + + enable_msg.control = value; + + ret = ten64_controller_send_command(ucdev, TEN64_UC_CMD_ENABLE_10G, + &enable_msg, sizeof(enable_msg)); + if (ret) { + dev_err(ucdev, "ERROR sending uC 10G Enable message: %d\n", ret); + return -1; + } + + return 0; +} + +int ten64_controller_call(struct udevice *dev, int msgid, void *tx_msg, int tx_size, + void *rx_msg, int rx_size) +{ + switch (msgid) { + case TEN64_CNTRL_GET_BOARD_INFO: + return ten64_controller_get_board_info(dev, (struct t64uc_board_info *)rx_msg); + case TEN64_CNTRL_10G_OFF: + return ten64_controller_10g_enable_command(dev, T64_CTRL_IO_CLEAR); + case TEN64_CNTRL_10G_ON: + return ten64_controller_10g_enable_command(dev, T64_CTRL_IO_SET); + default: + dev_err(dev, "%s: Unknown operation %d\n", __func__, msgid); + } + return -EINVAL; +} + +static struct misc_ops ten64_ctrl_ops = { + .call = ten64_controller_call +}; + +static const struct udevice_id ten64_controller_ids[] = { + {.compatible = "traverse,ten64-controller"}, + {} +}; + +U_BOOT_DRIVER(ten64_controller) = { + .name = "ten64-controller-i2c", + .id = UCLASS_MISC, + .of_match = ten64_controller_ids, + .ops = &ten64_ctrl_ops +}; From patchwork Wed Nov 3 05:29:21 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mathew McBride X-Patchwork-Id: 1550122 X-Patchwork-Delegate: priyanka.jain@nxp.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=traverse.com.au header.i=@traverse.com.au header.a=rsa-sha256 header.s=fm2 header.b=GquQoM2E; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.a=rsa-sha256 header.s=fm1 header.b=AvVrhkrA; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4Hkb2l1tMyz9sRK for ; Wed, 3 Nov 2021 16:30:39 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 63D4C835DA; Wed, 3 Nov 2021 06:30:25 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=traverse.com.au Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=traverse.com.au header.i=@traverse.com.au header.b="GquQoM2E"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="AvVrhkrA"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 86249834D0; Wed, 3 Nov 2021 06:30:22 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id B96CF83178 for ; Wed, 3 Nov 2021 06:30:15 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=traverse.com.au Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=matt@traverse.com.au Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id EC58B5C0130; Wed, 3 Nov 2021 01:30:14 -0400 (EDT) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Wed, 03 Nov 2021 01:30:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=traverse.com.au; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; s=fm2; bh=IZVpqSrwIE+GW QzfAqYHtyeDkzDslbwN9vsPXTUCmWw=; b=GquQoM2E9UK01c8RaKlWAJCPoe7WK 13SeX8i8rA/Q4pa//CIzWjB7YTO9o7EYp+v4MaFdIndnQqA1vJnUVYhqUYuViTD5 LPVM52au7NRmfvtlumt+8/Kg+LEtDYh0HcOXruRcES5ytxSSx6diNlc3wOaHeOAA 0L1LNOCxceveMU6UhMSaJLaJ1dnmQmzAl8wuiCdW1QQ6JNvDbDxIkJG3K9MquMZ9 EttWUFaqT3Zp6zpVF177Jt2MVpsYiWtnaDqDpYw4k2yDAZuEcmIV20/S6wQSZLyT fc1n9cpWR707vH5Hk9USA7zW+UYhY8SEUEco/Dm+XBZ4/RBQ3IdFWQF3Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=IZVpqSrwIE+GWQzfAqYHtyeDkzDslbwN9vsPXTUCmWw=; b=AvVrhkrA di7ZtOaFgl3MnVkBYU69LtaDG21vst0IHnPr9xJALAltCwg74nI67QpXVPtoMZDj uLN2ZReB4Ypse2Y3CiUtvsHQScrSvG3TmSu5LzEI2ExtU/uf3CnoRZ2AEESiTGCi OyJ1dO8ZHOblWvfAHgY6/OIwOro9ZXRaPBufd2WzFuc2+vgca77G+YG7oKGGmfNO lxn79VkyG9JXDqqfnjbL/TFSB5ypIP2z49N4pPOlQcFs/URlE+GP46wmhgNy9C4c YK3Tc5yja0KvMa3pRPFrVBsjsQkPEVMCxeHTQhHm4+/J801rxuxyz11J+flPZOan G1ghISWZNyAkUg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvuddrtddugdekvdcutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhgggfestdekredtredttdenucfhrhhomhepofgrthhhvgif ucfotgeurhhiuggvuceomhgrthhtsehtrhgrvhgvrhhsvgdrtghomhdrrghuqeenucggtf frrghtthgvrhhnpeekleevteelvdduheetgfdvfeelueekffeggeethedtteeljeeivedv gfehjeejheenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfhhroh hmpehmrghtthesthhrrghvvghrshgvrdgtohhmrdgruh X-ME-Proxy: Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 3 Nov 2021 01:30:12 -0400 (EDT) From: Mathew McBride To: u-boot@lists.denx.de, Priyanka Jain Cc: Mathew McBride Subject: [PATCH 2/2] board: traverse: add initial Ten64 support Date: Wed, 3 Nov 2021 05:29:21 +0000 Message-Id: <20211103052921.2718-3-matt@traverse.com.au> X-Mailer: git-send-email 2.30.1 In-Reply-To: <20211103052921.2718-1-matt@traverse.com.au> References: <20211103052921.2718-1-matt@traverse.com.au> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean The Ten64 is a networking-oriented MiniITX board using the NXP LS1088A SoC. This patch provides the bare minimum to support Ten64 boards under U-Boot for distroboot. Some related drivers have not yet been submitted and this basic support lacks some of the opinionated defaults provided by our firmware distribution. Signed-off-by: Mathew McBride --- arch/arm/Kconfig | 16 ++ arch/arm/dts/Makefile | 2 + arch/arm/dts/fsl-ls1088a-ten64.dts | 377 +++++++++++++++++++++++++ board/traverse/ten64/Kconfig | 17 ++ board/traverse/ten64/MAINTAINERS | 8 + board/traverse/ten64/Makefile | 6 + board/traverse/ten64/eth_ten64.c | 49 ++++ board/traverse/ten64/ten64.c | 433 +++++++++++++++++++++++++++++ configs/ten64_tfa_defconfig | 119 ++++++++ include/configs/ten64.h | 55 ++++ 10 files changed, 1082 insertions(+) create mode 100644 arch/arm/dts/fsl-ls1088a-ten64.dts create mode 100644 board/traverse/ten64/Kconfig create mode 100644 board/traverse/ten64/MAINTAINERS create mode 100644 board/traverse/ten64/Makefile create mode 100644 board/traverse/ten64/eth_ten64.c create mode 100644 board/traverse/ten64/ten64.c create mode 100644 configs/ten64_tfa_defconfig create mode 100644 include/configs/ten64.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index b4808d4c75..d732a5a676 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1758,6 +1758,21 @@ config TARGET_SL28 help Support for Kontron SMARC-sAL28 board. +config TARGET_TEN64 + bool "Support ten64" + select ARCH_LS1088A + select ARCH_MISC_INIT + select ARM64 + select ARMV8_MULTIENTRY + select ARCH_SUPPORT_TFABOOT + select BOARD_LATE_INIT + select SUPPORT_SPL + select FSL_DDR_INTERACTIVE if !SD_BOOT + select GPIO_EXTRA_HEADER + help + Support for Traverse Technologies Ten64 board, based + on NXP LS1088A. + config TARGET_COLIBRI_PXA270 bool "Support colibri_pxa270" select CPU_PXA @@ -2194,6 +2209,7 @@ source "board/socionext/developerbox/Kconfig" source "board/st/stv0991/Kconfig" source "board/tcl/sl50/Kconfig" source "board/toradex/colibri_pxa270/Kconfig" +source "board/traverse/ten64/Kconfig" source "board/variscite/dart_6ul/Kconfig" source "board/vscom/baltos/Kconfig" source "board/phytium/durian/Kconfig" diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index cc34da7bd8..2655707a43 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -478,6 +478,8 @@ dtb-$(CONFIG_TARGET_SL28) += fsl-ls1028a-kontron-sl28.dtb \ fsl-ls1028a-kontron-sl28-var3.dtb \ fsl-ls1028a-kontron-sl28-var4.dtb \ +dtb-$(CONFIG_TARGET_TEN64) += fsl-ls1088a-ten64.dtb + dtb-$(CONFIG_TARGET_DRAGONBOARD410C) += dragonboard410c.dtb dtb-$(CONFIG_TARGET_DRAGONBOARD820C) += dragonboard820c.dtb dtb-$(CONFIG_TARGET_STARQLTECHN) += starqltechn.dtb diff --git a/arch/arm/dts/fsl-ls1088a-ten64.dts b/arch/arm/dts/fsl-ls1088a-ten64.dts new file mode 100644 index 0000000000..43b669c642 --- /dev/null +++ b/arch/arm/dts/fsl-ls1088a-ten64.dts @@ -0,0 +1,377 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device Tree file for Travese Ten64 (LS1088) board + * Based on fsl-ls1088a-rdb.dts + * Copyright 2017-2020 NXP + * Copyright 2019-2021 Traverse Technologies + * + * Author: Mathew McBride + */ + +/dts-v1/; + +#include "fsl-ls1088a.dtsi" + +#include +#include + +/ { + model = "Traverse Ten64"; + compatible = "traverse,ten64", "fsl,ls1088a"; + + aliases { + spi0 = &qspi; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + buttons { + compatible = "gpio-keys"; + + /* Fired by system controller when + * external power off (e.g ATX Power Button) + * asserted + */ + powerdn { + label = "External Power Down"; + gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; + interrupts = <&gpio1 17 IRQ_TYPE_EDGE_FALLING>; + linux,code = ; + }; + + /* Rear Panel 'ADMIN' button (GPIO_H) */ + admin { + label = "ADMIN button"; + gpios = <&gpio3 8 GPIO_ACTIVE_HIGH>; + interrupts = <&gpio3 8 IRQ_TYPE_EDGE_RISING>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + sfp1down { + label = "ten64:green:sfp1:down"; + gpios = <&gpio3 11 GPIO_ACTIVE_HIGH>; + }; + + sfp2up { + label = "ten64:green:sfp2:up"; + gpios = <&gpio3 12 GPIO_ACTIVE_HIGH>; + }; + + admin { + label = "ten64:admin"; + gpios = <&sfpgpio 12 GPIO_ACTIVE_HIGH>; + }; + }; + + sfp_xg0: dpmac2-sfp { + compatible = "sff,sfp"; + i2c-bus = <&sfplower_i2c>; + tx-fault-gpios = <&sfpgpio 0 GPIO_ACTIVE_HIGH>; + tx-disable-gpios = <&sfpgpio 1 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&sfpgpio 2 GPIO_ACTIVE_LOW>; + los-gpios = <&sfpgpio 3 GPIO_ACTIVE_HIGH>; + maximum-power-milliwatt = <2000>; + }; + + sfp_xg1: dpmac1-sfp { + compatible = "sff,sfp"; + i2c-bus = <&sfpupper_i2c>; + tx-fault-gpios = <&sfpgpio 4 GPIO_ACTIVE_HIGH>; + tx-disable-gpios = <&sfpgpio 5 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&sfpgpio 6 GPIO_ACTIVE_LOW>; + los-gpios = <&sfpgpio 7 GPIO_ACTIVE_HIGH>; + maximum-power-milliwatt = <2000>; + }; +}; + +/* XG1 - Upper SFP */ +&dpmac1 { + sfp = <&sfp_xg1>; + phy-connection-type = "10gbase-r"; + managed = "in-band-status"; + status = "okay"; +}; + +/* XG0 - Lower SFP */ +&dpmac2 { + sfp = <&sfp_xg0>; + phy-connection-type = "10gbase-r"; + managed = "in-band-status"; + status = "okay"; +}; + +/* DPMAC3..6 is GE4 to GE8 */ +&dpmac3 { + phy-handle = <&mdio1_phy5>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + status = "okay"; +}; + +&dpmac4 { + phy-handle = <&mdio1_phy6>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + status = "okay"; +}; + +&dpmac5 { + phy-handle = <&mdio1_phy7>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + status = "okay"; +}; + +&dpmac6 { + phy-handle = <&mdio1_phy8>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + status = "okay"; +}; + +/* DPMAC7..10 is GE0 to GE3 */ +&dpmac7 { + phy-handle = <&mdio1_phy1>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + status = "okay"; +}; + +&dpmac8 { + phy-handle = <&mdio1_phy2>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + status = "okay"; +}; + +&dpmac9 { + phy-handle = <&mdio1_phy3>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + status = "okay"; +}; + +&dpmac10 { + phy-handle = <&mdio1_phy4>; + phy-connection-type = "qsgmii"; + managed = "in-band-status"; + status = "okay"; +}; + +&serial0 { + status = "okay"; +}; + +&serial1 { + status = "okay"; +}; + +&emdio1 { + status = "okay"; + + mdio1_phy5: ethernet-phy@c { + reg = <0xc>; + }; + + mdio1_phy6: ethernet-phy@d { + reg = <0xd>; + }; + + mdio1_phy7: ethernet-phy@e { + reg = <0xe>; + }; + + mdio1_phy8: ethernet-phy@f { + reg = <0xf>; + }; + + mdio1_phy1: ethernet-phy@1c { + reg = <0x1c>; + }; + + mdio1_phy2: ethernet-phy@1d { + reg = <0x1d>; + }; + + mdio1_phy3: ethernet-phy@1e { + reg = <0x1e>; + }; + + mdio1_phy4: ethernet-phy@1f { + reg = <0x1f>; + }; +}; + +&esdhc { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + sfpgpio: gpio@76 { + compatible = "ti,tca9539"; + reg = <0x76>; + #gpio-cells = <2>; + gpio-controller; + + admin_led_lower { + gpio-hog; + gpios = <13 GPIO_ACTIVE_HIGH>; + output-low; + }; + }; + + at97sc: tpm@29 { + compatible = "atmel,at97sc3204t"; + reg = <0x29>; + }; + + uc: board-controller@7e { + compatible = "traverse,ten64-controller"; + reg = <0x7e>; + }; +}; + +&i2c2 { + status = "okay"; + + rx8035: rtc@32 { + compatible = "epson,rx8035"; + reg = <0x32>; + }; +}; + +&i2c3 { + status = "okay"; + + i2c-switch@70 { + compatible = "nxp,pca9540"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + + sfpupper_i2c: i2c@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + }; + + sfplower_i2c: i2c@1 { + #address-cells = <1>; + #size-cells = <0>; + reg = <1>; + }; + }; +}; + +&qspi { + status = "okay"; + + en25s64: flash@0 { + compatible = "jedec,spi-nor"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0>; + spi-max-frequency = <20000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "bl2"; + reg = <0 0x100000>; + }; + + partition@100000 { + label = "bl3"; + reg = <0x100000 0x200000>; + }; + + partition@300000 { + label = "mcfirmware"; + reg = <0x300000 0x200000>; + }; + + partition@500000 { + label = "ubootenv"; + reg = <0x500000 0x80000>; + }; + + partition@580000 { + label = "dpl"; + reg = <0x580000 0x40000>; + }; + + partition@5C0000 { + label = "dpc"; + reg = <0x5C0000 0x40000>; + }; + + partition@600000 { + label = "devicetree"; + reg = <0x600000 0x40000>; + }; + }; + }; + + nand: flash@1 { + compatible = "spi-nand"; + #address-cells = <1>; + #size-cells = <1>; + reg = <1>; + spi-max-frequency = <20000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* reserved for future boot direct from NAND flash + * (this would use the same layout as the 8MiB NOR flash) + */ + partition@0 { + label = "nand-boot-reserved"; + reg = <0 0x800000>; + }; + + /* recovery / install environment */ + partition@800000 { + label = "recovery"; + reg = <0x800000 0x2000000>; + }; + + /* ubia (first OpenWrt) - a/b names to prevent confusion with ubi0/1/etc. */ + partition@2800000 { + label = "ubia"; + reg = <0x2800000 0x6C00000>; + }; + + /* ubib (second OpenWrt) */ + partition@9400000 { + label = "ubib"; + reg = <0x9400000 0x6C00000>; + }; + }; + }; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; +}; diff --git a/board/traverse/ten64/Kconfig b/board/traverse/ten64/Kconfig new file mode 100644 index 0000000000..ea8e3ea20d --- /dev/null +++ b/board/traverse/ten64/Kconfig @@ -0,0 +1,17 @@ +if TARGET_TEN64 + +config SYS_BOARD + default "ten64" + +config SYS_VENDOR + default "traverse" + +config SYS_SOC + default "fsl-layerscape" + +config SYS_CONFIG_NAME + default "ten64" + +endif + +source "board/traverse/common/Kconfig" diff --git a/board/traverse/ten64/MAINTAINERS b/board/traverse/ten64/MAINTAINERS new file mode 100644 index 0000000000..7b53e87938 --- /dev/null +++ b/board/traverse/ten64/MAINTAINERS @@ -0,0 +1,8 @@ +TEN64 BOARD +M: Mathew McBride +S: Maintained +F: arch/arm/dts/fsl-ls1088a-ten64.dts +F: board/traverse/ten64/ +F: board/traverse/common/ +F: include/configs/ten64.h +F: configs/ten64_tfa_defconfig diff --git a/board/traverse/ten64/Makefile b/board/traverse/ten64/Makefile new file mode 100644 index 0000000000..fd8d5cc87b --- /dev/null +++ b/board/traverse/ten64/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ + +obj-y += ten64.o +obj-y += eth_ten64.o + +CFLAGS_ten64.o += -DDEBUG diff --git a/board/traverse/ten64/eth_ten64.c b/board/traverse/ten64/eth_ten64.c new file mode 100644 index 0000000000..6be7cf0c5d --- /dev/null +++ b/board/traverse/ten64/eth_ten64.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2017 NXP + * Copyright 2019-2021 Traverse Technologies Australia + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_RESET_PHY_R) +void reset_phy(void) +{ + mc_env_boot(); +} +#endif /* CONFIG_RESET_PHY_R */ + +int board_phy_config(struct phy_device *phydev) +{ + /* These settings only apply to VSC8514 */ + if (phydev->phy_id == 0x70670) { + /* First, ensure LEDs are driven to rails (not tristate) + * This is in the extended page 0x0010 + */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1F, 0x0010); + phy_write(phydev, MDIO_DEVAD_NONE, 0x0E, 0x2000); + /* Restore to page 0 */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1F, 0x0000); + + /* Disable blink on the left LEDs, and make the activity LEDs blink faster */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0xC03); + + phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x3421); + } + + if (phydev->drv->config) + phydev->drv->config(phydev); + + return 0; +} diff --git a/board/traverse/ten64/ten64.c b/board/traverse/ten64/ten64.c new file mode 100644 index 0000000000..e21e6563dc --- /dev/null +++ b/board/traverse/ten64/ten64.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Traverse Ten64 Family board + * Copyright 2017-2018 NXP + * Copyright 2019-2021 Traverse Technologies + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../common/ten64-controller.h" + +#define I2C_RETIMER_ADDR 0x27 + +DECLARE_GLOBAL_DATA_PTR; + +static int ten64_read_board_info(struct t64uc_board_info *); +static void ten64_set_macaddrs_from_board_info(struct t64uc_board_info *); +static void ten64_board_retimer_ds110df410_init(void); + +int board_early_init_f(void) +{ + fsl_lsch3_early_init_f(); + return 0; +} + +static u32 ten64_get_board_rev(void) +{ + struct ccsr_gur *dcfg = (void *)CONFIG_SYS_FSL_GUTS_ADDR; + u32 board_rev_in = in_le32(&dcfg->gpporcr1); + return board_rev_in; +} + +int checkboard(void) +{ + enum boot_src src = get_boot_src(); + char boardmodel[32]; + struct t64uc_board_info boardinfo; + u32 board_rev = ten64_get_board_rev(); + + switch (board_rev) { + case 0xFF: + snprintf(boardmodel, 32, "1064-0201A (Alpha)"); + break; + case 0xFE: + snprintf(boardmodel, 32, "1064-0201B (Beta)"); + break; + case 0xFD: + snprintf(boardmodel, 32, "1064-0201C"); + break; + default: + snprintf(boardmodel, 32, "1064 Revision %X", (0xFF - board_rev)); + break; + } + + printf("Board: %s, boot from ", boardmodel); + if (src == BOOT_SOURCE_SD_MMC) + puts("SD card\n"); + else if (src == BOOT_SOURCE_QSPI_NOR) + puts("QSPI\n"); + else + printf("Unknown boot source %d\n", src); + + puts("Controller: "); + if (CONFIG_IS_ENABLED(TEN64_CONTROLLER)) { + /* Driver not compatible with alpha/beta board MCU firmware */ + if (board_rev <= 0xFD) { + if (ten64_read_board_info(&boardinfo)) { + puts("ERROR: unable to communicate\n"); + } else { + printf("firmware %d.%d.%d\n", + boardinfo.fwversion_major, + boardinfo.fwversion_minor, + boardinfo.fwversion_patch); + ten64_set_macaddrs_from_board_info(&boardinfo); + } + } else { + puts("not supported on this board revision\n"); + } + } else { + puts("driver not enabled (no MAC addresses or other information will be read)\n"); + } + + return 0; +} + +int board_init(void) +{ + init_final_memctl_regs(); + + if (CONFIG_IS_ENABLED(FSL_CAAM)) + sec_init(); + + return 0; +} + +int fsl_initdram(void) +{ + gd->ram_size = tfa_get_dram_size(); + + if (!gd->ram_size) + gd->ram_size = fsl_ddr_sdram_size(); + + return 0; +} + +void detail_board_ddr_info(void) +{ + puts("\nDDR "); + print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, ""); + print_ddr_info(0); +} + +#if CONFIG_IS_ENABLED(FSL_MC_ENET) +void board_quiesce_devices(void) +{ + fsl_mc_ldpaa_exit(gd->bd); +} + +void fdt_fixup_board_enet(void *fdt) +{ + int offset; + + offset = fdt_path_offset(fdt, "/fsl-mc"); + + if (offset < 0) + offset = fdt_path_offset(fdt, "/soc/fsl-mc"); + + if (offset < 0) { + printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", + __func__, offset); + return; + } + + if (get_mc_boot_status() == 0 && + (is_lazy_dpl_addr_valid() || get_dpl_apply_status() == 0)) + fdt_status_okay(fdt, offset); + else + fdt_status_fail(fdt, offset); +} +#endif + +/* Called after SoC board_late_init in fsl-layerscape/soc.c */ +int fsl_board_late_init(void) +{ + ten64_board_retimer_ds110df410_init(); + return 0; +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + int i; + u16 mc_memory_bank = 0; + + u64 *base; + u64 *size; + u64 mc_memory_base = 0; + u64 mc_memory_size = 0; + u16 total_memory_banks; + + debug("%s blob=0x%p\n", __func__, blob); + + ft_cpu_setup(blob, bd); + + fdt_fixup_mc_ddr(&mc_memory_base, &mc_memory_size); + + if (mc_memory_base != 0) + mc_memory_bank++; + + total_memory_banks = CONFIG_NR_DRAM_BANKS + mc_memory_bank; + + base = calloc(total_memory_banks, sizeof(u64)); + size = calloc(total_memory_banks, sizeof(u64)); + + /* fixup DT for the two GPP DDR banks */ + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + base[i] = gd->bd->bi_dram[i].start; + size[i] = gd->bd->bi_dram[i].size; + } + + if (CONFIG_IS_ENABLED(RESV_RAM)) { + /* reduce size if reserved memory is within this bank */ + if (gd->arch.resv_ram >= base[0] && + gd->arch.resv_ram < base[0] + size[0]) + size[0] = gd->arch.resv_ram - base[0]; + else if (gd->arch.resv_ram >= base[1] && + gd->arch.resv_ram < base[1] + size[1]) + size[1] = gd->arch.resv_ram - base[1]; + } + + if (mc_memory_base != 0) { + for (i = 0; i <= total_memory_banks; i++) { + if (base[i] == 0 && size[i] == 0) { + base[i] = mc_memory_base; + size[i] = mc_memory_size; + break; + } + } + } + + fdt_fixup_memory_banks(blob, base, size, total_memory_banks); + + fdt_fsl_mc_fixup_iommu_map_entry(blob); + + if (CONFIG_IS_ENABLED(FSL_MC_ENET)) + fdt_fixup_board_enet(blob); + + fdt_fixup_icid(blob); + + return 0; +} + +#if CONFIG_IS_ENABLED(TEN64_CONTROLLER) +#define MACADDRBITS(a, b) (u8)((a >> b) & 0xFF) + +/** Probe and return a udevice for the Ten64 board microcontroller. + * Optionally, return the I2C bus the microcontroller resides on + * @i2c_bus_out: return I2C bus device handle in this pointer + */ +static int ten64_get_micro_udevice(struct udevice **ucdev, struct udevice **i2c_bus_out) +{ + int ret; + struct udevice *i2cbus; + + ret = uclass_get_device_by_seq(UCLASS_I2C, 0, &i2cbus); + if (ret) { + printf("%s: Could not get I2C UCLASS", __func__); + return ret; + } + if (i2c_bus_out) + *i2c_bus_out = i2cbus; + + ret = dm_i2c_probe(i2cbus, 0x7E, DM_I2C_CHIP_RD_ADDRESS, ucdev); + if (ret) { + printf("%s: Could not get microcontroller device\n", __func__); + return ret; + } + return ret; +} + +static int ten64_read_board_info(struct t64uc_board_info *boardinfo) +{ + struct udevice *ucdev; + int ret; + + ret = ten64_get_micro_udevice(&ucdev, NULL); + if (ret) + return ret; + + ret = misc_call(ucdev, TEN64_CNTRL_GET_BOARD_INFO, NULL, 0, (void *)boardinfo, 0); + if (ret) + return ret; + + return 0; +} + +static void ten64_set_macaddrs_from_board_info(struct t64uc_board_info *boardinfo) +{ + char ethaddr[18]; + char enetvar[10]; + u8 intfidx, this_dpmac_num; + u64 macaddr = 0; + /* We will copy the MAC address returned from the + * uC (48 bits) into the u64 macaddr + */ + u8 *macaddr_bytes = (u8 *)&macaddr + 2; + + /** MAC addresses are allocated in order of the physical port numbers, + * DPMAC7->10 is "eth0" through "eth3" + * DPMAC3->6 is "eth4" through "eth7" + * DPMAC2 and 1 are "eth8" and "eth9" respectively + */ + int allocation_order[10] = {7, 8, 9, 10, 3, 4, 5, 6, 2, 1}; + + memcpy(macaddr_bytes, boardinfo->mac, 6); + /* MAC address bytes from uC are in big endian, + * convert to CPU + */ + macaddr = __be64_to_cpu(macaddr); + + for (intfidx = 0; intfidx < 10; intfidx++) { + snprintf(ethaddr, 18, "%02X:%02X:%02X:%02X:%02X:%02X", + MACADDRBITS(macaddr, 40), + MACADDRBITS(macaddr, 32), + MACADDRBITS(macaddr, 24), + MACADDRBITS(macaddr, 16), + MACADDRBITS(macaddr, 8), + MACADDRBITS(macaddr, 0)); + + this_dpmac_num = allocation_order[intfidx]; + printf("DPMAC%d: %s\n", this_dpmac_num, ethaddr); + snprintf(enetvar, 10, + (this_dpmac_num != 1) ? "eth%daddr" : "ethaddr", + this_dpmac_num - 1); + macaddr++; + + if (!env_get(enetvar)) + env_set(enetvar, ethaddr); + } +} + +/* The retimer (DS110DF410) is one of the devices without + * a RESET line, but a power switch is on the board + * allowing it to be reset via uC command + */ +static int board_cycle_retimer(struct udevice **retim_dev) +{ + int ret; + u8 loop; + struct udevice *uc_dev; + struct udevice *i2cbus; + + ret = ten64_get_micro_udevice(&uc_dev, &i2cbus); + if (ret) + return ret; + + ret = dm_i2c_probe(i2cbus, I2C_RETIMER_ADDR, 0, retim_dev); + if (ret == 0) { + puts("(retimer on, resetting...) "); + + ret = misc_call(uc_dev, TEN64_CNTRL_10G_OFF, NULL, 0, NULL, 0); + mdelay(1000); + } + + ret = misc_call(uc_dev, TEN64_CNTRL_10G_ON, NULL, 0, NULL, 0); + + // Wait for retimer to come back + for (loop = 0; loop < 5; loop++) { + ret = dm_i2c_probe(i2cbus, I2C_RETIMER_ADDR, 0, retim_dev); + if (ret == 0) + return 0; + mdelay(500); + } + + return -ENOSYS; +} +#endif /* CONFIG_IS_ENABLED(TEN64_CONTROLLER) */ + +/* ten64_board_retimer_ds110df410_init() - Configure the 10G retimer + * Adopted from the t102xqds board file + */ +static void ten64_board_retimer_ds110df410_init(void) +{ + u8 reg; + int ret; + struct udevice *retim_dev; + + puts("Retimer: "); + + ret = board_cycle_retimer(&retim_dev); + if (ret) { + puts("Retimer power on failed\n"); + return; + } + + /* Access to Control/Shared register */ + reg = 0x0; + + ret = dm_i2c_write(retim_dev, 0xff, ®, 1); + if (ret) { + printf("Error writing to retimer register (error %d)\n", ret); + return; + } + + /* Read device revision and ID */ + dm_i2c_read(retim_dev, 1, ®, 1); + if (reg == 0xF0) + puts("DS110DF410 found\n"); + else + printf("Unknown retimer 0x%xn\n", reg); + + /* Enable Broadcast */ + reg = 0x0c; + dm_i2c_write(retim_dev, 0xff, ®, 1); + + /* Perform a full reset (state, channel and clock) + * for all channels + * as the DS110DF410 does not have a RESET line + */ + dm_i2c_read(retim_dev, 0, ®, 1); + reg |= 0x7; + dm_i2c_write(retim_dev, 0, ®, 1); + + /* Set rate/subrate = 0 */ + reg = 0x6; + dm_i2c_write(retim_dev, 0x2F, ®, 1); + + /* Set data rate as 10.3125 Gbps */ + reg = 0x0; + dm_i2c_write(retim_dev, 0x60, ®, 1); + reg = 0xb2; + dm_i2c_write(retim_dev, 0x61, ®, 1); + reg = 0x90; + dm_i2c_write(retim_dev, 0x62, ®, 1); + reg = 0xb3; + dm_i2c_write(retim_dev, 0x63, ®, 1); + reg = 0xff; + dm_i2c_write(retim_dev, 0x64, ®, 1); + + /* Invert channel 2 (Lower SFP TX to CPU) due to the SFP being inverted */ + reg = 0x05; + dm_i2c_write(retim_dev, 0xFF, ®, 1); + dm_i2c_read(retim_dev, 0x1F, ®, 1); + reg |= 0x80; + dm_i2c_write(retim_dev, 0x1F, ®, 1); + + puts("OK\n"); +} diff --git a/configs/ten64_tfa_defconfig b/configs/ten64_tfa_defconfig new file mode 100644 index 0000000000..8d45b134fe --- /dev/null +++ b/configs/ten64_tfa_defconfig @@ -0,0 +1,119 @@ +CONFIG_ARM=y +CONFIG_TARGET_TEN64=y +CONFIG_SYS_TEXT_BASE=0x82000000 +CONFIG_QSPI_AHB_INIT=y +CONFIG_TFABOOT=y +CONFIG_ARMV8_SEC_FIRMWARE_SUPPORT=y +CONFIG_SEC_FIRMWARE_ARMV8_PSCI=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_NR_DRAM_BANKS=2 +# CONFIG_SYS_MALLOC_F is not set +CONFIG_FIT_VERBOSE=y +CONFIG_OF_BOARD_SETUP=y +CONFIG_OF_FDT_OVERLAY=y +CONFIG_OF_STDOUT_VIA_ALIAS=y +CONFIG_SYS_EXTRA_OPTIONS="SYS_FSL_DDR4" +CONFIG_USE_BOOTARGS=y +CONFIG_BOOTARGS="console=ttyS0,115200 root=/dev/ram0 earlycon=uart8250,mmio,0x21c0500 ramdisk_size=0x3000000 default_hugepagesz=2m hugepagesz=2m hugepages=256" +# CONFIG_USE_BOOTCOMMAND is not set +# CONFIG_DISPLAY_BOARDINFO is not set +CONFIG_DISPLAY_BOARDINFO_LATE=y +CONFIG_CMD_BOOTEFI_HELLO=y +CONFIG_CMD_BOOTEFI_SELFTEST=y +CONFIG_CMD_BOOTMENU=y +CONFIG_CMD_GPT=y +CONFIG_RANDOM_UUID=y +CONFIG_CMD_DM=y +CONFIG_CMD_GREPENV=y +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_I2C=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_UBI=y +CONFIG_CMD_UBIFS=y +CONFIG_CMD_USB=y +CONFIG_CMD_TIME=y +CONFIG_CMD_POWEROFF=y +CONFIG_CMD_WDT=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_FS_FAT=y +CONFIG_FAT_WRITE=y +CONFIG_MP=y +CONFIG_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="fsl-ls1088a-ten64" +CONFIG_EMC230X=y +CONFIG_ENV_IS_IN_MMC=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_OFFSET=0x500000 +CONFIG_ENV_SIZE=0x80000 +CONFIG_ENV_SECT_SIZE=0x80000 +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_DM=y +CONFIG_SCSI_AHCI=y +CONFIG_DM_MMC=y +CONFIG_FSL_ESDHC=y +CONFIG_CMD_FAN=y +CONFIG_FANCONTROL=y +CONFIG_DM_MTD=y +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_EON=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_SPI_FLASH_MTD=y +CONFIG_E1000=y +# CONFIG_ID_EEPROM is not set +CONFIG_MII=y +CONFIG_NVME=y +CONFIG_CMD_PCI=y +CONFIG_PCI=y +CONFIG_DM_PCA953X=y +CONFIG_DM_PCI=y +CONFIG_DM_PCI_COMPAT=y +CONFIG_PCIE_LAYERSCAPE_RC=y +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_FSL_DSPI=y +CONFIG_FSL_QSPI=y +CONFIG_UBI=y +CONFIG_USB=y +CONFIG_DM_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_DWC3=y +CONFIG_USB_DWC3=y +CONFIG_USB_GADGET=y +CONFIG_EFI_LOADER_BOUNCE_BUFFER=y +CONFIG_DM_I2C=y +CONFIG_DM_GPIO=y +CONFIG_ARM_SMCCC=y +CONFIG_MTD=y +CONFIG_MTD_SPI_NAND=y +CONFIG_CMD_MTD=y +CONFIG_LOGLEVEL=7 +CONFIG_MTDPARTS_DEFAULT="mtdparts=spi-nand0:8m(reserved),32m(recovery),108m(ubia),108m(ubib);nor1:1m(bl2),2m(bl3),2m(mcfirmware),512k(ubootenv),256k(dpl),256k(dpc),256k(devicetree)" +CONFIG_MPC8XXX_GPIO=y +CONFIG_GPIO_HOG=y +CONFIG_DM_RTC=y +CONFIG_RTC_RX8025=y +CONFIG_CMD_NVEDIT_EFI=y +CONFIG_CMD_EFIDEBUG=y +CONFIG_DM_ETH=y +CONFIG_PCI_INIT_R=y +CONFIG_PHYLIB=y +CONFIG_PHY_VITESSE=y +CONFIG_DM_MDIO=y +CONFIG_FSL_LS_MDIO=y +CONFIG_SYS_MALLOC_F=y +CONFIG_SYS_MALLOC_F_LEN=0x2000 +CONFIG_TPM=y +CONFIG_CMD_TPM=y +CONFIG_TPM_ATMEL_TWI=y +CONFIG_MISC=y +CONFIG_USB5744=y +CONFIG_TEN64_CONTROLLER=y +CONFIG_DM_SCSI=y +CONFIG_AHCI=y +CONFIG_AHCI_PCI=y +CONFIG_WDT=y +CONFIG_WDT_SP805=y diff --git a/include/configs/ten64.h b/include/configs/ten64.h new file mode 100644 index 0000000000..54e65f29f1 --- /dev/null +++ b/include/configs/ten64.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2017 NXP + * Copyright 2019-2021 Traverse Technologies + */ + +#ifndef __TEN64_H +#define __TEN64_H + +#include "ls1088a_common.h" + +#define CONFIG_SYS_CLK_FREQ 100000000 +#define COUNTER_FREQUENCY 25000000 /* 25MHz */ + +#define CONFIG_DIMM_SLOTS_PER_CTLR 1 + +#define CONFIG_SYS_LS_MC_BOOT_TIMEOUT_MS 5000 + +#define QSPI_NOR_BOOTCOMMAND "run distro_bootcmd" +#define SD_BOOTCOMMAND "run distro_bootcmd" + +#define QSPI_MC_INIT_CMD \ + "sf probe 0:0 && sf read 0x80000000 0x300000 0x200000 &&" \ + "sf read 0x80200000 0x5C0000 0x40000 &&" \ + "fsl_mc start mc 0x80000000 0x80200000 && " \ + "sf read 0x80300000 0x580000 0x40000 && fsl_mc lazyapply DPL 0x80300000\0" +#define SD_MC_INIT_CMD \ + "mmcinfo; fatload mmc 0 0x80000000 mcfirmware/mc_ls1088a.itb; "\ + "fatload mmc 0 0x80200000 dpaa2config/dpc.0x1D-0x0D.dtb; "\ + "fsl_mc start mc 0x80000000 0x80200000\0" + +#define BOOT_TARGET_DEVICES(func) \ + func(NVME, nvme, 0) \ + func(USB, usb, 0) \ + func(MMC, mmc, 0) \ + func(SCSI, scsi, 0) \ + func(DHCP, dhcp, 0) \ + func(PXE, pxe, 0) +#include + +#undef CONFIG_EXTRA_ENV_SETTINGS + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "BOARD=ten64\0" \ + "fdt_addr_r=0x90000000\0" \ + "fdt_high=0xa0000000\0" \ + "kernel_addr_r=0x81000000\0" \ + "load_addr=0xa0000000\0" \ + BOOTENV \ + "load_efi_dtb=mtd read devicetree $fdt_addr_r && fdt addr $fdt_addr_r && " \ + "fdt resize && fdt boardsetup\0" \ + "bootcmd_recovery=mtd read recovery 0xa0000000; mtd read dpl 0x80100000 && " \ + "fsl_mc apply DPL 0x80100000 && bootm 0xa0000000#ten64\0" + +#endif /* __TEN64_H */