Stefan Reinauer has uploaded this change for review.

View Change

Add support for TerribleFire TF530 SPI controller

Change-Id: I109eec4dec89650bb80d3d1da905d33f65f60f5a
Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
---
M Makefile
M programmer.h
A tf530_spi.c
3 files changed, 188 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/44/54944/1
diff --git a/Makefile b/Makefile
index c486c12..0026898 100644
--- a/Makefile
+++ b/Makefile
@@ -138,6 +138,7 @@
ifeq ($(TARGET_OS), AmigaOS)
override CPPFLAGS += -m68000 -mcrt=clib2
override LIBS += -mcrt=clib2 -lamiga -lm -lunix
+override CONFIG_TF530_SPI = yes
# Bus Pirate, Serprog and PonyProg are not supported under AmigaOS (missing serial support).
ifeq ($(CONFIG_BUSPIRATE_SPI), yes)
UNSUPPORTED_FEATURES += CONFIG_BUSPIRATE_SPI=yes
@@ -1207,6 +1208,11 @@
PROGRAMMER_OBJS += jlink_spi.o
endif

+ifeq ($(CONFIG_TF530_SPI), yes)
+FEATURE_CFLAGS += -D'CONFIG_TF530_SPI=1'
+PROGRAMMER_OBJS += tf530_spi.o
+endif
+
ifeq ($(CONFIG_NI845X_SPI), yes)
FEATURE_CFLAGS += -D'CONFIG_NI845X_SPI=1'

diff --git a/programmer.h b/programmer.h
index 790fcc8..cbb5977 100644
--- a/programmer.h
+++ b/programmer.h
@@ -112,6 +112,9 @@
#if CONFIG_LINUX_SPI == 1
PROGRAMMER_LINUX_SPI,
#endif
+#if CONFIG_TF530_SPI == 1
+ PROGRAMMER_TF530_SPI,
+#endif
#if CONFIG_USBBLASTER_SPI == 1
PROGRAMMER_USBBLASTER_SPI,
#endif
@@ -559,6 +562,11 @@
int linux_spi_init(void);
#endif

+/* tf530_spi.c */
+#if CONFIG_TF530_SPI == 1
+int tf53x_spi_init(void);
+#endif
+
/* dediprog.c */
#if CONFIG_DEDIPROG == 1
int dediprog_init(void);
diff --git a/tf530_spi.c b/tf530_spi.c
new file mode 100644
index 0000000..76a7e43
--- /dev/null
+++ b/tf530_spi.c
@@ -0,0 +1,174 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2019 Steven J Leary
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if CONFIG_TF530_SPI == 1
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <ctype.h>
+#include "flash.h"
+#include "chipdrivers.h"
+#include "programmer.h"
+#include "spi.h"
+
+#include <exec/resident.h>
+#include <exec/errors.h>
+#include <exec/memory.h>
+#include <exec/lists.h>
+#include <exec/alerts.h>
+#include <exec/tasks.h>
+#include <exec/io.h>
+#include <exec/execbase.h>
+
+#include <libraries/expansion.h>
+
+#include <devices/trackdisk.h>
+#include <devices/timer.h>
+#include <devices/scsidisk.h>
+
+#include <dos/filehandler.h>
+
+#include <proto/exec.h>
+#include <proto/disk.h>
+#include <proto/expansion.h>
+
+struct TF53xSDRegs {
+ volatile uint8_t ctrl; // Control register
+ volatile uint8_t unused1; // padding
+ volatile uint8_t unused2; // padding
+ volatile uint8_t unused3; // padding
+ volatile uint8_t data; // data
+};
+
+static struct ConfigDev *cd = NULL;
+
+#define TF53x_CTRL_CS0 1
+#define TF53x_CTRL_CS1 2
+#define TF53x_CTRL_BUSY 4
+#define TF53x_CTRL_CS2 8
+
+static void spi_send_byte(struct TF53xSDRegs *port, uint8_t value)
+{
+ uint8_t busy = 0;
+
+ while (busy == 0) {
+ busy = port->ctrl & TF53x_CTRL_BUSY;
+ }
+
+ port->data = value;
+}
+
+inline uint8_t spi_recv_byte(struct TF53xSDRegs *port)
+{
+ uint8_t busy = 0;
+
+ while (busy == 0) {
+ busy = port->ctrl & TF53x_CTRL_BUSY;
+ }
+
+ return port->data;
+}
+
+static void spi_cs_unassert(struct TF53xSDRegs *port)
+{
+ uint8_t current = port->ctrl;
+ port->ctrl = current | TF53x_CTRL_CS0 | \
+ TF53x_CTRL_CS1 | TF53x_CTRL_CS2 | TF53x_CTRL_BUSY;
+}
+
+static void spi_cs_assert(struct TF53xSDRegs *port)
+{
+ uint8_t current = port->ctrl;
+ port->ctrl = current & (~TF53x_CTRL_CS2);
+}
+
+static int tf53x_spi_shutdown(void *data)
+{
+ return 0;
+}
+
+static int tf53x_spi_send_command(const struct flashctx *flash,
+ unsigned int writecnt,
+ unsigned int readcnt,
+ const unsigned char *txbuf,
+ unsigned char *rxbuf)
+{
+ struct TF53xSDRegs *port = cd->cd_BoardAddr;
+
+ spi_cs_assert(port);
+
+ for (unsigned int i = 0; i < writecnt; i++) {
+ spi_send_byte(port, txbuf[i]);
+ }
+
+ /* read the dummy byte and make sure
+ * the compiler doesnt optimize it away */
+ uint8_t volatile dummy = spi_recv_byte(port);
+ dummy;
+
+ for (unsigned int i = 0; i < readcnt; i++) {
+ rxbuf[i] = spi_recv_byte(port);
+ }
+
+ spi_cs_unassert(port);
+
+ return 0;
+}
+
+static const struct spi_master spi_master_tf53x = {
+ .features = SPI_MASTER_4BA,
+ .max_data_read = 256,
+ .max_data_write = 256,
+ .command = tf53x_spi_send_command,
+ .multicommand = default_spi_send_multicommand,
+ .read = default_spi_read,
+ .write_256 = default_spi_write_256,
+ .write_aai = default_spi_write_aai,
+};
+
+int tf53x_spi_init(void)
+{
+ struct Library *ExpansionBase = NULL;
+
+ if ((ExpansionBase = (struct Library *)
+ OpenLibrary((unsigned char *)"expansion.library", 0L)) == NULL) {
+ return 0;
+ }
+
+ if (cd = (struct ConfigDev *) FindConfigDev(cd, 0x13D8, 0x81)) {
+ msg_cinfo("\nTF530 SPI found in autoconfig chain.\n");
+ CloseLibrary(ExpansionBase);
+ } else {
+ msg_perr("\nTF530 SPI not found in autoconfig chain.\n");
+ CloseLibrary(ExpansionBase);
+ return -1;
+ }
+
+ if (register_shutdown(tf53x_spi_shutdown, NULL))
+ return 1;
+
+ register_spi_master(&spi_master_tf53x, NULL);
+
+ return 0;
+}
+
+#endif // CONFIG_TF530_SPI == 1

To view, visit change 54944. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I109eec4dec89650bb80d3d1da905d33f65f60f5a
Gerrit-Change-Number: 54944
Gerrit-PatchSet: 1
Gerrit-Owner: Stefan Reinauer <stefan.reinauer@coreboot.org>
Gerrit-MessageType: newchange