From patchwork Fri May 22 12:45:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pratyush Yadav X-Patchwork-Id: 1296243 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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=) Authentication-Results: ozlabs.org; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.a=rsa-sha256 header.s=ti-com-17Q1 header.b=aN9438NP; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 49T5qf0HrFz9sRW for ; Fri, 22 May 2020 22:47:41 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 6A70D81785; Fri, 22 May 2020 14:46:29 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=ti.com header.i=@ti.com header.b="aN9438NP"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 606578179A; Fri, 22 May 2020 14:45:46 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.2 Received: from lelv0142.ext.ti.com (lelv0142.ext.ti.com [198.47.23.249]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id D91D58168D for ; Fri, 22 May 2020 14:45:41 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=quarantine dis=none) header.from=ti.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=p.yadav@ti.com Received: from lelv0266.itg.ti.com ([10.180.67.225]) by lelv0142.ext.ti.com (8.15.2/8.15.2) with ESMTP id 04MCjeGT053932; Fri, 22 May 2020 07:45:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1590151540; bh=Bp6chnxx/T1wYHHNeb08jD7+b0r7tsEinER2URyoB5g=; h=From:To:CC:Subject:Date:In-Reply-To:References; b=aN9438NPnJtLlFU3mPDwDFbNmGVgi+jGv6AkNby+sy2PlXCvP6P0wURyMd0z5mUby UdmBS1nMvIUVsiV28UNsR/HqagGSsw7J/0ABm8w7LsNWgKQKN7O3A85vQ3JZV5HZtZ ZqS71Dt1jTW4itBF2INjp5fnMWmV8lMr1RUUSoHE= Received: from DLEE103.ent.ti.com (dlee103.ent.ti.com [157.170.170.33]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id 04MCjdZ4029795 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Fri, 22 May 2020 07:45:39 -0500 Received: from DLEE100.ent.ti.com (157.170.170.30) by DLEE103.ent.ti.com (157.170.170.33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3; Fri, 22 May 2020 07:45:39 -0500 Received: from lelv0327.itg.ti.com (10.180.67.183) by DLEE100.ent.ti.com (157.170.170.30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1979.3 via Frontend Transport; Fri, 22 May 2020 07:45:39 -0500 Received: from pratyush-OptiPlex-790.dhcp.ti.com (ileax41-snat.itg.ti.com [10.172.224.153]) by lelv0327.itg.ti.com (8.15.2/8.15.2) with ESMTP id 04MCjAoW091145; Fri, 22 May 2020 07:45:37 -0500 From: Pratyush Yadav To: Jagan Teki , Vignesh Raghavendra CC: Pratyush Yadav , , Sekhar Nori , Pragnesh Patel Subject: [PATCH v4 12/20] mtd: spi-nor-core: Parse xSPI Profile 1.0 table Date: Fri, 22 May 2020 18:15:01 +0530 Message-ID: <20200522124509.6901-13-p.yadav@ti.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200522124509.6901-1-p.yadav@ti.com> References: <20200522124509.6901-1-p.yadav@ti.com> MIME-Version: 1.0 X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.30rc1 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.102.2 at phobos.denx.de X-Virus-Status: Clean This table is indication that the flash is xSPI compliant and hence supports octal DTR mode. Extract information like the fast read opcode, the number of dummy cycles needed for a Read Status Register command, and the number of address bytes needed for a Read Status Register command. The default dummy cycles for a fast octal DTR read are set to 20. Since there is no simple way of determining the dummy cycles needed for the fast read command, flashes that use a different value should update it in their flash-specific hooks. Signed-off-by: Pratyush Yadav --- drivers/mtd/spi/spi-nor-core.c | 100 +++++++++++++++++++++++++++++++++ include/linux/mtd/spi-nor.h | 7 +++ 2 files changed, 107 insertions(+) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 2355283d30..2cb419c7ca 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -38,6 +39,8 @@ #define DEFAULT_READY_WAIT_JIFFIES (40UL * HZ) +#define ROUND_UP_TO(x, y) (((x) + (y) - 1) / (y) * (y)) + struct sfdp_parameter_header { u8 id_lsb; u8 minor; @@ -56,6 +59,7 @@ struct sfdp_parameter_header { #define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */ #define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */ #define SFDP_SST_ID 0x01bf /* Manufacturer specific Table */ +#define SFDP_PROFILE1_ID 0xff05 /* xSPI Profile 1.0 Table */ #define SFDP_SIGNATURE 0x50444653U #define SFDP_JESD216_MAJOR 1 @@ -153,6 +157,16 @@ struct sfdp_header { #define BFPT_DWORD18_CMD_EXT_RES (0x2UL << 29) /* Reserved */ #define BFPT_DWORD18_CMD_EXT_16B (0x3UL << 29) /* 16-bit opcode */ +/* xSPI Profile 1.0 table (from JESD216D.01). */ +#define PROFILE1_DWORD1_RD_FAST_CMD GENMASK(15, 8) +#define PROFILE1_DWORD1_RDSR_DUMMY BIT(28) +#define PROFILE1_DWORD1_RDSR_ADDR_BYTES BIT(29) +#define PROFILE1_DWORD4_DUMMY_200MHZ GENMASK(11, 7) +#define PROFILE1_DWORD5_DUMMY_166MHZ GENMASK(31, 27) +#define PROFILE1_DWORD5_DUMMY_133MHZ GENMASK(21, 17) +#define PROFILE1_DWORD5_DUMMY_100MHZ GENMASK(11, 7) +#define PROFILE1_DUMMY_DEFAULT 20 + struct sfdp_bfpt { u32 dwords[BFPT_DWORD_MAX]; }; @@ -2055,6 +2069,86 @@ static int spi_nor_parse_bfpt(struct spi_nor *nor, return spi_nor_post_bfpt_fixups(nor, bfpt_header, &bfpt, params); } +/** + * spi_nor_parse_profile1() - parse the xSPI Profile 1.0 table + * @nor: pointer to a 'struct spi_nor' + * @param_header: pointer to the 'struct sfdp_parameter_header' describing + * the 4-Byte Address Instruction Table length and version. + * @params: pointer to the 'struct spi_nor_flash_parameter' to be. + * + * Return: 0 on success, -errno otherwise. + */ +static int spi_nor_parse_profile1(struct spi_nor *nor, + const struct sfdp_parameter_header *profile1_header, + struct spi_nor_flash_parameter *params) +{ + u32 *table, opcode, addr; + size_t len; + int ret, i; + u8 dummy; + + len = profile1_header->length * sizeof(*table); + table = kmalloc(len, GFP_KERNEL); + if (!table) + return -ENOMEM; + + addr = SFDP_PARAM_HEADER_PTP(profile1_header); + ret = spi_nor_read_sfdp(nor, addr, len, table); + if (ret) + goto out; + + /* Fix endianness of the table DWORDs. */ + for (i = 0; i < profile1_header->length; i++) + table[i] = le32_to_cpu(table[i]); + + /* Get 8D-8D-8D fast read opcode and dummy cycles. */ + opcode = FIELD_GET(PROFILE1_DWORD1_RD_FAST_CMD, table[0]); + + /* + * We don't know what speed the controller is running at. Find the + * dummy cycles for the fastest frequency the flash can run at to be + * sure we are never short of dummy cycles. A value of 0 means the + * frequency is not supported. + * + * Default to PROFILE1_DUMMY_DEFAULT if we don't find anything, and let + * flashes set the correct value if needed in their fixup hooks. + */ + dummy = FIELD_GET(PROFILE1_DWORD4_DUMMY_200MHZ, table[3]); + if (!dummy) + dummy = FIELD_GET(PROFILE1_DWORD5_DUMMY_166MHZ, table[4]); + if (!dummy) + dummy = FIELD_GET(PROFILE1_DWORD5_DUMMY_133MHZ, table[4]); + if (!dummy) + dummy = FIELD_GET(PROFILE1_DWORD5_DUMMY_100MHZ, table[4]); + if (!dummy) + dummy = PROFILE1_DUMMY_DEFAULT; + + /* Round up to an even value to avoid tripping controllers up. */ + dummy = ROUND_UP_TO(dummy, 2); + + /* Update the fast read settings. */ + spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ_8_8_8_DTR], + 0, dummy, opcode, + SNOR_PROTO_8_8_8_DTR); + + /* + * Set the Read Status Register dummy cycles and dummy address bytes. + */ + if (table[0] & PROFILE1_DWORD1_RDSR_DUMMY) + params->rdsr_dummy = 8; + else + params->rdsr_dummy = 4; + + if (table[0] & PROFILE1_DWORD1_RDSR_ADDR_BYTES) + params->rdsr_addr_nbytes = 4; + else + params->rdsr_addr_nbytes = 0; + +out: + kfree(table); + return ret; +} + /** * spi_nor_parse_microchip_sfdp() - parse the Microchip manufacturer specific * SFDP table. @@ -2185,6 +2279,10 @@ static int spi_nor_parse_sfdp(struct spi_nor *nor, err = spi_nor_parse_microchip_sfdp(nor, param_header); break; + case SFDP_PROFILE1_ID: + err = spi_nor_parse_profile1(nor, param_header, params); + break; + default: break; } @@ -2857,6 +2955,8 @@ int spi_nor_scan(struct spi_nor *nor) if (ret) return ret; + nor->rdsr_dummy = params.rdsr_dummy; + nor->rdsr_addr_nbytes = params.rdsr_addr_nbytes; nor->name = mtd->name; nor->size = mtd->size; nor->erase_size = mtd->erasesize; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 9184534e82..f738c5eecc 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -391,6 +391,8 @@ enum spi_nor_pp_command_index { struct spi_nor_flash_parameter { u64 size; u32 page_size; + u8 rdsr_dummy; + u8 rdsr_addr_nbytes; struct spi_nor_hwcaps hwcaps; struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; @@ -443,6 +445,9 @@ struct flash_info; * @read_opcode: the read opcode * @read_dummy: the dummy needed by the read operation * @program_opcode: the program opcode + * @rdsr_dummy dummy cycles needed for Read Status Register command. + * @rdsr_addr_nbytes: dummy address bytes needed for Read Status Register + * command. * @bank_read_cmd: Bank read cmd * @bank_write_cmd: Bank write cmd * @bank_curr: Current flash bank @@ -483,6 +488,8 @@ struct spi_nor { u8 read_opcode; u8 read_dummy; u8 program_opcode; + u8 rdsr_dummy; + u8 rdsr_addr_nbytes; #ifdef CONFIG_SPI_FLASH_BAR u8 bank_read_cmd; u8 bank_write_cmd;