From: Mason Yang <masonccyang@mxic.com.tw> To: broonie@kernel.org, tudor.ambarus@microchip.com, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, boris.brezillon@collabora.com Cc: juliensu@mxic.com.tw, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, linux-spi@vger.kernel.org, Mason Yang <masonccyang@mxic.com.tw> Subject: [PATCH v2 2/5] mtd: spi-nor: sfdp: Add support for xSPI profile 1.0 table Date: Tue, 21 Apr 2020 14:39:44 +0800 [thread overview] Message-ID: <1587451187-6889-3-git-send-email-masonccyang@mxic.com.tw> (raw) In-Reply-To: <1587451187-6889-1-git-send-email-masonccyang@mxic.com.tw> xSPI(eXpanded Serial Peripheral Interface) is for Non Volatile Memory Devices supports Octal DTR mode. Extract information like: Read Fast command, the number of dummy cycles and address bytes for Read Status Register command. Read/Write volatile Register command for Configuration(CFG) Register 2. The dummy cycless used for various frequencies. Signed-off-by: Mason Yang <masonccyang@mxic.com.tw> --- drivers/mtd/spi-nor/core.h | 14 ++++++ drivers/mtd/spi-nor/sfdp.c | 106 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 6f2f6b2..2ea11fa 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -208,6 +208,12 @@ struct spi_nor_locking_ops { * e.g. different opcodes, specific address calculation, * page size, etc. * @locking_ops: SPI NOR locking methods. + * @dtr_read_cmd: xSPI Octal DTR Read Fast command. + * @rdsr_addr_nbytes: xSPI Octal address bytes for read status register. + * @rdsr_dummy_cycles: xSPI Octal dummy cycles for read status register. + * @rd_reg_cmd: xSPI Octal read volatile register command. + * @wr_reg_cmd: xSPI Octal write volatile register command. + * @dummy_cycles: xSPI Octal dummy cycles used for various frequencies. */ struct spi_nor_flash_parameter { u64 size; @@ -225,6 +231,14 @@ struct spi_nor_flash_parameter { int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps); const struct spi_nor_locking_ops *locking_ops; + + /* xSPI profile 1.0 parameter for Octal 8S-8S-8S/8D-8D-8D */ + u8 dtr_read_cmd; + u8 rdsr_addr_nbytes; + u8 rdsr_dummy_cycles; + u8 rd_reg_cmd; + u8 wr_reg_cmd; + u8 dummy_cycles; }; /** diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index f6038d3..26814a1 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <linux/sort.h> #include <linux/mtd/spi-nor.h> +#include <linux/bitfield.h> #include "core.h" @@ -19,6 +20,7 @@ #define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */ #define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */ #define SFDP_4BAIT_ID 0xff84 /* 4-byte Address Instruction Table */ +#define SFDP_XSPI_PF1_ID 0xff05 /* xSPI Profile 1.0 table. */ #define SFDP_SIGNATURE 0x50444653U #define SFDP_JESD216_MAJOR 1 @@ -26,6 +28,28 @@ #define SFDP_JESD216A_MINOR 5 #define SFDP_JESD216B_MINOR 6 +/* xSPI Profile 1.0 table (from JESD216D.01). */ +#define XSPI_PF1_DWORD1_RD_CMD GENMASK(15, 8) +#define XSPI_PF1_DWORD1_RDSR_ADDR_BYTES BIT(29) +#define XSPI_PF1_DWORD1_RDSR_DUMMY_CYCLES BIT(28) + +#define XSPI_PF1_DWORD2_RD_REG_CMD GENMASK(31, 24) +#define XSPI_PF1_DWORD2_WR_REG_CMD GENMASK(15, 8) + +#define XSPI_DWORD(x) ((x) - 1) +#define XSPI_DWORD_MAX 5 + +struct sfdp_xspi { + u32 dwords[XSPI_DWORD_MAX]; +}; + +struct xspi_dummy_cycles { + u16 speed_hz; /* Speed MHz */ + u8 dwords; /* Dwords index */ + u32 mask; /* Mask */ + u8 shift; /* Bit shift */ +}; + struct sfdp_header { u32 signature; /* Ox50444653U <=> "SFDP" */ u8 minor; @@ -1081,6 +1105,83 @@ static int spi_nor_parse_4bait(struct spi_nor *nor, } /** + * spi_nor_parse_xspi_pf1() - 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_xspi_pf1(struct spi_nor *nor, + const struct sfdp_parameter_header *header, + struct spi_nor_flash_parameter *params) +{ + struct sfdp_xspi pfile1; + u32 i, addr; + size_t len; + int ret; + static const struct xspi_dummy_cycles dummy[] = { + /* {MHz, Dwords index, Mask, Bit shift} */ + { 200, 4, GENMASK(11, 7), 7}, + { 166, 5, GENMASK(31, 27), 27}, + { 133, 5, GENMASK(21, 17), 17}, + { 100, 5, GENMASK(11, 7), 7}, + }; + + if (header->major != SFDP_JESD216_MAJOR || + header->length < XSPI_DWORD_MAX) + return -EINVAL; + + len = min_t(size_t, sizeof(pfile1), + header->length * sizeof(u32)); + + memset(&pfile1, 0, sizeof(pfile1)); + + addr = SFDP_PARAM_HEADER_PTP(header); + ret = spi_nor_read_sfdp(nor, addr, len, &pfile1); + if (ret) + goto out; + + /* Fix endianness of the xSPI 1.0 DWORDs. */ + le32_to_cpu_array(pfile1.dwords, XSPI_DWORD_MAX); + + /* Get 8D-8D-8D fast read opcode and dummy cycles. */ + params->dtr_read_cmd = FIELD_GET(XSPI_PF1_DWORD1_RD_CMD, + pfile1.dwords[XSPI_DWORD(1)]); + + if (pfile1.dwords[XSPI_DWORD(1)] & XSPI_PF1_DWORD1_RDSR_ADDR_BYTES) + params->rdsr_addr_nbytes = 4; + else + params->rdsr_addr_nbytes = 0; + + if (pfile1.dwords[XSPI_DWORD(1)] & XSPI_PF1_DWORD1_RDSR_DUMMY_CYCLES) + params->rdsr_dummy_cycles = 8; + else + params->rdsr_dummy_cycles = 4; + + params->rd_reg_cmd = FIELD_GET(XSPI_PF1_DWORD2_RD_REG_CMD, + pfile1.dwords[XSPI_DWORD(2)]); + params->wr_reg_cmd = FIELD_GET(XSPI_PF1_DWORD2_WR_REG_CMD, + pfile1.dwords[XSPI_DWORD(2)]); + + for (i = 0; i < ARRAY_SIZE(dummy); i++) { + if (params->octal_max_speed == dummy[i].speed_hz) { + params->dummy_cycles = + (dummy[i].mask & + pfile1.dwords[XSPI_DWORD(dummy[i].dwords)]) >> + dummy[i].shift; + break; + } + } + if (i == ARRAY_SIZE(dummy)) + params->dummy_cycles = 20; + +out: + return ret; +} + +/** * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. * @nor: pointer to a 'struct spi_nor' * @params: pointer to the 'struct spi_nor_flash_parameter' to be @@ -1171,7 +1272,6 @@ int spi_nor_parse_sfdp(struct spi_nor *nor, /* Parse optional parameter tables. */ for (i = 0; i < header.nph; i++) { param_header = ¶m_headers[i]; - switch (SFDP_PARAM_HEADER_ID(param_header)) { case SFDP_SECTOR_MAP_ID: err = spi_nor_parse_smpt(nor, param_header, params); @@ -1181,6 +1281,10 @@ int spi_nor_parse_sfdp(struct spi_nor *nor, err = spi_nor_parse_4bait(nor, param_header, params); break; + case SFDP_XSPI_PF1_ID: + err = spi_nor_parse_xspi_pf1(nor, param_header, params); + break; + default: break; } -- 1.9.1
WARNING: multiple messages have this Message-ID (diff)
From: Mason Yang <masonccyang@mxic.com.tw> To: broonie@kernel.org, tudor.ambarus@microchip.com, miquel.raynal@bootlin.com, richard@nod.at, vigneshr@ti.com, boris.brezillon@collabora.com Cc: juliensu@mxic.com.tw, Mason Yang <masonccyang@mxic.com.tw>, linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org Subject: [PATCH v2 2/5] mtd: spi-nor: sfdp: Add support for xSPI profile 1.0 table Date: Tue, 21 Apr 2020 14:39:44 +0800 [thread overview] Message-ID: <1587451187-6889-3-git-send-email-masonccyang@mxic.com.tw> (raw) In-Reply-To: <1587451187-6889-1-git-send-email-masonccyang@mxic.com.tw> xSPI(eXpanded Serial Peripheral Interface) is for Non Volatile Memory Devices supports Octal DTR mode. Extract information like: Read Fast command, the number of dummy cycles and address bytes for Read Status Register command. Read/Write volatile Register command for Configuration(CFG) Register 2. The dummy cycless used for various frequencies. Signed-off-by: Mason Yang <masonccyang@mxic.com.tw> --- drivers/mtd/spi-nor/core.h | 14 ++++++ drivers/mtd/spi-nor/sfdp.c | 106 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h index 6f2f6b2..2ea11fa 100644 --- a/drivers/mtd/spi-nor/core.h +++ b/drivers/mtd/spi-nor/core.h @@ -208,6 +208,12 @@ struct spi_nor_locking_ops { * e.g. different opcodes, specific address calculation, * page size, etc. * @locking_ops: SPI NOR locking methods. + * @dtr_read_cmd: xSPI Octal DTR Read Fast command. + * @rdsr_addr_nbytes: xSPI Octal address bytes for read status register. + * @rdsr_dummy_cycles: xSPI Octal dummy cycles for read status register. + * @rd_reg_cmd: xSPI Octal read volatile register command. + * @wr_reg_cmd: xSPI Octal write volatile register command. + * @dummy_cycles: xSPI Octal dummy cycles used for various frequencies. */ struct spi_nor_flash_parameter { u64 size; @@ -225,6 +231,14 @@ struct spi_nor_flash_parameter { int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps); const struct spi_nor_locking_ops *locking_ops; + + /* xSPI profile 1.0 parameter for Octal 8S-8S-8S/8D-8D-8D */ + u8 dtr_read_cmd; + u8 rdsr_addr_nbytes; + u8 rdsr_dummy_cycles; + u8 rd_reg_cmd; + u8 wr_reg_cmd; + u8 dummy_cycles; }; /** diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c index f6038d3..26814a1 100644 --- a/drivers/mtd/spi-nor/sfdp.c +++ b/drivers/mtd/spi-nor/sfdp.c @@ -7,6 +7,7 @@ #include <linux/slab.h> #include <linux/sort.h> #include <linux/mtd/spi-nor.h> +#include <linux/bitfield.h> #include "core.h" @@ -19,6 +20,7 @@ #define SFDP_BFPT_ID 0xff00 /* Basic Flash Parameter Table */ #define SFDP_SECTOR_MAP_ID 0xff81 /* Sector Map Table */ #define SFDP_4BAIT_ID 0xff84 /* 4-byte Address Instruction Table */ +#define SFDP_XSPI_PF1_ID 0xff05 /* xSPI Profile 1.0 table. */ #define SFDP_SIGNATURE 0x50444653U #define SFDP_JESD216_MAJOR 1 @@ -26,6 +28,28 @@ #define SFDP_JESD216A_MINOR 5 #define SFDP_JESD216B_MINOR 6 +/* xSPI Profile 1.0 table (from JESD216D.01). */ +#define XSPI_PF1_DWORD1_RD_CMD GENMASK(15, 8) +#define XSPI_PF1_DWORD1_RDSR_ADDR_BYTES BIT(29) +#define XSPI_PF1_DWORD1_RDSR_DUMMY_CYCLES BIT(28) + +#define XSPI_PF1_DWORD2_RD_REG_CMD GENMASK(31, 24) +#define XSPI_PF1_DWORD2_WR_REG_CMD GENMASK(15, 8) + +#define XSPI_DWORD(x) ((x) - 1) +#define XSPI_DWORD_MAX 5 + +struct sfdp_xspi { + u32 dwords[XSPI_DWORD_MAX]; +}; + +struct xspi_dummy_cycles { + u16 speed_hz; /* Speed MHz */ + u8 dwords; /* Dwords index */ + u32 mask; /* Mask */ + u8 shift; /* Bit shift */ +}; + struct sfdp_header { u32 signature; /* Ox50444653U <=> "SFDP" */ u8 minor; @@ -1081,6 +1105,83 @@ static int spi_nor_parse_4bait(struct spi_nor *nor, } /** + * spi_nor_parse_xspi_pf1() - 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_xspi_pf1(struct spi_nor *nor, + const struct sfdp_parameter_header *header, + struct spi_nor_flash_parameter *params) +{ + struct sfdp_xspi pfile1; + u32 i, addr; + size_t len; + int ret; + static const struct xspi_dummy_cycles dummy[] = { + /* {MHz, Dwords index, Mask, Bit shift} */ + { 200, 4, GENMASK(11, 7), 7}, + { 166, 5, GENMASK(31, 27), 27}, + { 133, 5, GENMASK(21, 17), 17}, + { 100, 5, GENMASK(11, 7), 7}, + }; + + if (header->major != SFDP_JESD216_MAJOR || + header->length < XSPI_DWORD_MAX) + return -EINVAL; + + len = min_t(size_t, sizeof(pfile1), + header->length * sizeof(u32)); + + memset(&pfile1, 0, sizeof(pfile1)); + + addr = SFDP_PARAM_HEADER_PTP(header); + ret = spi_nor_read_sfdp(nor, addr, len, &pfile1); + if (ret) + goto out; + + /* Fix endianness of the xSPI 1.0 DWORDs. */ + le32_to_cpu_array(pfile1.dwords, XSPI_DWORD_MAX); + + /* Get 8D-8D-8D fast read opcode and dummy cycles. */ + params->dtr_read_cmd = FIELD_GET(XSPI_PF1_DWORD1_RD_CMD, + pfile1.dwords[XSPI_DWORD(1)]); + + if (pfile1.dwords[XSPI_DWORD(1)] & XSPI_PF1_DWORD1_RDSR_ADDR_BYTES) + params->rdsr_addr_nbytes = 4; + else + params->rdsr_addr_nbytes = 0; + + if (pfile1.dwords[XSPI_DWORD(1)] & XSPI_PF1_DWORD1_RDSR_DUMMY_CYCLES) + params->rdsr_dummy_cycles = 8; + else + params->rdsr_dummy_cycles = 4; + + params->rd_reg_cmd = FIELD_GET(XSPI_PF1_DWORD2_RD_REG_CMD, + pfile1.dwords[XSPI_DWORD(2)]); + params->wr_reg_cmd = FIELD_GET(XSPI_PF1_DWORD2_WR_REG_CMD, + pfile1.dwords[XSPI_DWORD(2)]); + + for (i = 0; i < ARRAY_SIZE(dummy); i++) { + if (params->octal_max_speed == dummy[i].speed_hz) { + params->dummy_cycles = + (dummy[i].mask & + pfile1.dwords[XSPI_DWORD(dummy[i].dwords)]) >> + dummy[i].shift; + break; + } + } + if (i == ARRAY_SIZE(dummy)) + params->dummy_cycles = 20; + +out: + return ret; +} + +/** * spi_nor_parse_sfdp() - parse the Serial Flash Discoverable Parameters. * @nor: pointer to a 'struct spi_nor' * @params: pointer to the 'struct spi_nor_flash_parameter' to be @@ -1171,7 +1272,6 @@ int spi_nor_parse_sfdp(struct spi_nor *nor, /* Parse optional parameter tables. */ for (i = 0; i < header.nph; i++) { param_header = ¶m_headers[i]; - switch (SFDP_PARAM_HEADER_ID(param_header)) { case SFDP_SECTOR_MAP_ID: err = spi_nor_parse_smpt(nor, param_header, params); @@ -1181,6 +1281,10 @@ int spi_nor_parse_sfdp(struct spi_nor *nor, err = spi_nor_parse_4bait(nor, param_header, params); break; + case SFDP_XSPI_PF1_ID: + err = spi_nor_parse_xspi_pf1(nor, param_header, params); + break; + default: break; } -- 1.9.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/
next prev parent reply other threads:[~2020-04-21 7:08 UTC|newest] Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-04-21 6:39 [PATCH v2 0/5] mtd: spi-nor: Add support for Octal 8D-8D-8D mode Mason Yang 2020-04-21 6:39 ` Mason Yang 2020-04-21 6:39 ` [PATCH v2 1/5] " Mason Yang 2020-04-21 6:39 ` Mason Yang 2020-04-21 6:39 ` Mason Yang [this message] 2020-04-21 6:39 ` [PATCH v2 2/5] mtd: spi-nor: sfdp: Add support for xSPI profile 1.0 table Mason Yang 2020-04-21 6:39 ` [PATCH v2 3/5] mtd: spi-nor: Parse BFPT DWORD-18,19 and 20 for Octal 8D-8D-8D mode Mason Yang 2020-04-21 6:39 ` [PATCH v2 3/5] mtd: spi-nor: Parse BFPT DWORD-18, 19 " Mason Yang 2020-04-21 6:39 ` [PATCH v2 4/5] mtd: spi-nor: macronix: Add Octal 8D-8D-8D supports for Macronix mx25uw51245g Mason Yang 2020-04-21 6:39 ` Mason Yang 2020-04-21 6:39 ` [PATCH v2 5/5] spi: mxic: Patch for Octal 8D-8D-8D mode support Mason Yang 2020-04-21 6:39 ` Mason Yang 2020-04-24 15:41 ` kbuild test robot 2020-04-24 15:41 ` kbuild test robot 2020-04-24 15:41 ` kbuild test robot 2020-04-21 7:23 ` [PATCH v2 0/5] mtd: spi-nor: Add support for Octal 8D-8D-8D mode Boris Brezillon 2020-04-21 7:23 ` Boris Brezillon 2020-04-21 9:35 ` Vignesh Raghavendra 2020-04-21 9:35 ` Vignesh Raghavendra 2020-04-21 12:17 ` Boris Brezillon 2020-04-21 12:17 ` Boris Brezillon 2020-04-27 17:55 ` Pratyush Yadav 2020-04-27 17:55 ` Pratyush Yadav 2020-04-28 6:14 ` masonccyang 2020-04-28 6:14 ` masonccyang 2020-04-28 6:34 ` Boris Brezillon 2020-04-28 6:34 ` Boris Brezillon 2020-04-28 8:35 ` Pratyush Yadav 2020-04-28 8:35 ` Pratyush Yadav 2020-04-29 5:59 ` masonccyang 2020-04-29 5:59 ` masonccyang 2020-04-28 8:54 ` Pratyush Yadav 2020-04-28 8:54 ` Pratyush Yadav 2020-04-29 7:31 ` masonccyang 2020-04-29 7:31 ` masonccyang 2020-04-29 8:37 ` Boris Brezillon 2020-04-29 8:37 ` Boris Brezillon 2020-04-29 18:18 ` Pratyush Yadav 2020-04-29 18:18 ` Pratyush Yadav 2020-05-05 9:31 ` masonccyang 2020-05-05 9:31 ` masonccyang 2020-05-05 9:44 ` Boris Brezillon 2020-05-05 9:44 ` Boris Brezillon 2020-05-05 10:01 ` Boris Brezillon 2020-05-05 10:01 ` Boris Brezillon 2020-05-11 6:54 ` masonccyang 2020-05-11 6:54 ` masonccyang 2020-05-06 9:40 ` Pratyush Yadav 2020-05-06 9:40 ` Pratyush Yadav 2020-05-15 2:26 ` masonccyang 2020-05-15 2:26 ` masonccyang 2020-05-15 6:55 ` Pratyush Yadav 2020-05-15 6:55 ` Pratyush Yadav 2020-04-30 8:21 ` Vignesh Raghavendra 2020-04-30 8:21 ` Vignesh Raghavendra 2020-05-11 3:23 ` masonccyang 2020-05-11 3:23 ` masonccyang
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1587451187-6889-3-git-send-email-masonccyang@mxic.com.tw \ --to=masonccyang@mxic.com.tw \ --cc=boris.brezillon@collabora.com \ --cc=broonie@kernel.org \ --cc=juliensu@mxic.com.tw \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-mtd@lists.infradead.org \ --cc=linux-spi@vger.kernel.org \ --cc=miquel.raynal@bootlin.com \ --cc=richard@nod.at \ --cc=tudor.ambarus@microchip.com \ --cc=vigneshr@ti.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.