From patchwork Mon Nov 25 10:30:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Baruch Siach X-Patchwork-Id: 1200332 X-Patchwork-Delegate: sr@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=tkos.co.il Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 47M3NF3Lz5z9sPj for ; Mon, 25 Nov 2019 21:35:57 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 2DE85C21E3B; Mon, 25 Nov 2019 10:33:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id B433FC21E73; Mon, 25 Nov 2019 10:31:07 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 03992C21CB6; Mon, 25 Nov 2019 10:31:03 +0000 (UTC) Received: from mx.tkos.co.il (guitar.tcltek.co.il [192.115.133.116]) by lists.denx.de (Postfix) with ESMTPS id A999EC21CB6 for ; Mon, 25 Nov 2019 10:31:02 +0000 (UTC) Received: from tarshish.tkos.co.il (unknown [10.0.8.2]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mx.tkos.co.il (Postfix) with ESMTPS id 602D34409B0; Mon, 25 Nov 2019 12:31:01 +0200 (IST) From: Baruch Siach To: u-boot@lists.denx.de, Stefan Roese Date: Mon, 25 Nov 2019 12:30:46 +0200 Message-Id: X-Mailer: git-send-email 2.24.0 In-Reply-To: References: MIME-Version: 1.0 Cc: Chris Packham , Baruch Siach , Dennis Gilmore Subject: [U-Boot] [PATCH 06/10] ARM: mvebu: clearfog: read basic TLV data X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 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" Read RAM die capacity from the EEPROM TLV. Follow the ONIE standard that defines the Vendor Extension entry type for vendor specific data. We have no Private Enterprise Number at the moment as the standard requires. Use the dummy all 0xff value for now. Signed-off-by: Baruch Siach Reviewed-by: Stefan Roese --- board/solidrun/clearfog/clearfog.c | 118 +++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index 8b6381194688..707afabb11a7 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,6 +17,14 @@ DECLARE_GLOBAL_DATA_PTR; +#define SR_TLV_CODE_RAM_DIE_SIZE 0x81 + +/* + * Some Clearfog variants have TLV on SOM and on carrier, with separate + * product name entries. + */ +static char tlv_product_name[2][32]; + /* * Those values and defines are taken from the Marvell U-Boot version * "u-boot-2013.01-15t1-clearfog" @@ -74,8 +83,117 @@ static struct mv_ddr_topology_map board_topology_map = { 0x3, /* clock enable mask */ }; +static void store_product_name(tlvinfo_tlv_t *tlv_entry) +{ + int len; + char *dest; + + if (strlen(tlv_product_name[0]) == 0) + dest = tlv_product_name[0]; + else if (strlen(tlv_product_name[1]) == 0) + dest = tlv_product_name[1]; + else + return; + + len = min_t(unsigned, tlv_entry->length, + sizeof(tlv_product_name[0])-1); + memcpy(dest, tlv_entry->value, len); +} + +static bool sr_product_is(const char *product) +{ + /* Allow prefix sub-string match */ + if (strncmp(tlv_product_name[0], product, strlen(product)) == 0) + return true; + if (strncmp(tlv_product_name[1], product, strlen(product)) == 0) + return true; + + return false; +} + +static void parse_tlv_vendor_ext(tlvinfo_tlv_t *tlv_entry) +{ + struct if_params *ifp = &board_topology_map.interface_params[0]; + u8 *val = tlv_entry->value; + uint32_t pen; /* IANA Private Enterprise Numbers */ + + if (tlv_entry->length < 5) /* 4 bytes PEN + at least 1 byte type */ + return; + + /* PEN is big endian */ + pen = (val[0] << 24) | (val[1] << 16) | (val[2] << 8) | val[3]; + /* Not a real PEN */ + if (pen != 0xffffffff) + return; + + switch (val[4]) { + case SR_TLV_CODE_RAM_DIE_SIZE: + if (tlv_entry->length != 6) + break; + switch (val[5]) { + case 4: + default: + ifp->memory_size = MV_DDR_DIE_CAP_4GBIT; + break; + case 8: + ifp->memory_size = MV_DDR_DIE_CAP_8GBIT; + break; + } + default: + break; + } +} + +static void parse_tlv_data(uint8_t *eeprom, tlvinfo_header_t *hdr, + tlvinfo_tlv_t *entry) +{ + unsigned tlv_offset, tlv_len; + + tlv_offset = sizeof(tlvinfo_header_t); + tlv_len = sizeof(tlvinfo_header_t) + be16_to_cpu(hdr->totallen); + while (tlv_offset < tlv_len) { + entry = (tlvinfo_tlv_t *) &eeprom[tlv_offset]; + + switch (entry->type) { + case TLV_CODE_PRODUCT_NAME: + store_product_name(entry); + break; + case TLV_CODE_VENDOR_EXT: + parse_tlv_vendor_ext(entry); + break; + default: + break; + } + + tlv_offset += sizeof(tlvinfo_tlv_t) + entry->length; + } +} + +static void read_tlv_data(void) +{ + uint8_t eeprom_data[TLV_TOTAL_LEN_MAX]; + tlvinfo_header_t *tlv_hdr; + tlvinfo_tlv_t *tlv_entry; + static bool ran_once; + int ret, i; + + if (ran_once) + return; + ran_once = true; + + for (i = 0; i < 2; i++) { + ret = read_tlvinfo_sys_eeprom_dev(eeprom_data, &tlv_hdr, + &tlv_entry, i); + if (ret < 0) + continue; + parse_tlv_data(eeprom_data, tlv_hdr, tlv_entry); + } +} + struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) { + read_tlv_data(); + /* Return the board topology as defined in the board code */ return &board_topology_map; }