[PATCH 13/16] fpga: machxo2: add optional additional flash areas to be erased
From: Johannes Zink <hidden>
Date: 2022-08-25 14:20:40
Also in:
linux-fpga
Subsystem:
fpga manager framework, the rest · Maintainers:
Moritz Fischer, Xu Yilun, Linus Torvalds
This patch allows additional flash areas to be erased, i.e. not only the configuration flash, but also sram, feature row and UFM (user flash memory) can be erased. Signed-off-by: Johannes Zink <redacted> --- drivers/fpga/machxo2-common.c | 40 +++++++++++++++++++++++++++++------ drivers/fpga/machxo2-common.h | 1 + 2 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/drivers/fpga/machxo2-common.c b/drivers/fpga/machxo2-common.c
index 71f886a60cba..d93c304cceb9 100644
--- a/drivers/fpga/machxo2-common.c
+++ b/drivers/fpga/machxo2-common.c@@ -10,10 +10,13 @@ #include <linux/delay.h> #include <linux/bitfield.h> +#include <linux/byteorder/generic.h> +#include <asm-generic/unaligned.h> #include <linux/fpga/fpga-mgr.h> #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/property.h> #include "machxo2-common.h" #define MACHXO2_LOW_DELAY_USEC 5
@@ -41,6 +44,16 @@ #define MACHXO2_ERR_EESDMEOF 7 /* SDM EOF */ #define MACHXO2_FAIL BIT(13) +/* + * second byte ('operand') of ISC_ERASE can be ORed with the + * following bitmasks to not only erase configuration flash, + * but also SRAM, Feature Row or UFM, respectively. See MachXO2 + * Programming and Configuration Usage Guide + */ +#define ISC_ERASE_SRAM BIT(16) +#define ISC_ERASE_FEATURE_ROW BIT(17) +#define ISC_ERASE_UFM BIT(19) + static inline u8 get_err(u32 status) {
@@ -90,13 +103,13 @@ static int machxo2_wait_until_not_busy(struct machxo2_common_priv *priv) static int machxo2_cleanup(struct fpga_manager *mgr) { struct machxo2_common_priv *priv = mgr->priv; - u8 erase[] = ISC_ERASE; u8 refresh[] = LSC_REFRESH; struct machxo2_cmd cmd = {}; int ret; - cmd.cmd = erase; - cmd.cmd_len = sizeof(erase); + cmd.cmd = (u8 *)&priv->erase_cmd; + cmd.cmd_len = sizeof(priv->erase_cmd); + ret = priv->write_commands(priv, &cmd, 1); if (ret) goto fail;
@@ -143,7 +156,6 @@ static int machxo2_write_init(struct fpga_manager *mgr, { struct machxo2_common_priv *priv = mgr->priv; u8 enable[] = ISC_ENABLE; - u8 erase[] = ISC_ERASE; u8 initaddr[] = LSC_INITADDRESS; struct machxo2_cmd cmd[2] = {}; u32 status;
@@ -162,8 +174,9 @@ static int machxo2_write_init(struct fpga_manager *mgr, cmd[0].cmd_len = sizeof(enable); cmd[0].delay_us = MACHXO2_LOW_DELAY_USEC; - cmd[1].cmd = erase; - cmd[1].cmd_len = sizeof(erase); + cmd[1].cmd = (u8 *)&priv->erase_cmd; + cmd[1].cmd_len = sizeof(priv->erase_cmd); + ret = priv->write_commands(priv, cmd, 2); if (ret) goto fail;
@@ -302,6 +315,21 @@ static const struct fpga_manager_ops machxo2_ops = { int machxo2_common_init(struct machxo2_common_priv *priv, struct device *dev) { struct fpga_manager *mgr; + u8 erase[] = ISC_ERASE; + u32 erase_cmd; + + erase_cmd = get_unaligned_be32(erase); + + if (device_property_read_bool(dev, "lattice,erase-sram")) + erase_cmd |= ISC_ERASE_SRAM; + + if (device_property_read_bool(dev, "lattice,erase-feature-row")) + erase_cmd |= ISC_ERASE_FEATURE_ROW; + + if (device_property_read_bool(dev, "lattice,erase-userflash")) + erase_cmd |= ISC_ERASE_UFM; + + priv->erase_cmd = cpu_to_be32(erase_cmd); priv->dev = dev;
diff --git a/drivers/fpga/machxo2-common.h b/drivers/fpga/machxo2-common.h
index a16060602a3f..1b54154f91b1 100644
--- a/drivers/fpga/machxo2-common.h
+++ b/drivers/fpga/machxo2-common.h@@ -31,6 +31,7 @@ struct machxo2_common_priv { struct machxo2_cmd *cmds, size_t cmd_count); int (*get_status)(struct machxo2_common_priv *priv, u32 *status); struct device *dev; + __be32 erase_cmd; }; int machxo2_common_init(struct machxo2_common_priv *priv, struct device *dev);
--
2.30.2