[PATCH 13/16] fpga: machxo2: add optional additional flash areas to be erased

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <j.zink@xxxxxxxxxxxxxx>
---
 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




[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux