summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark F. Brown <mark.f.brown@intel.com>2011-09-07 18:06:24 -0400
committerPatrick Tjin <pattjin@google.com>2014-07-21 20:22:40 -0700
commit90847a8a794a6eedef1f61daab5a9e3afde33c5a (patch)
tree0da46a3a4531cc7a43d20acca98ce3ced107f741
parentaecaba3b298855b0ce93f94897a0e2b5269639a7 (diff)
downloadbootstub-90847a8a794a6eedef1f61daab5a9e3afde33c5a.tar.gz
SSP: Added SPI UART via SSP5
BZ: 114933 Merrifield uses SPI via SSP rather than a dedicated SPI peripheral Moved volatile definitions to types.h Based off code by Courtney A. Drant Change-Id: I3a8fbe364f2fcf860ac47f431b93868fb7b598d9 Signed-off-by: Mark F. Brown <mark.f.brown@intel.com> Signed-off-by: Courtney A. Drant <courtney.a.drant@intel.com> Reviewed-on: http://android.intel.com:8080/112531 Reviewed-by: Fourdan, Olivier <olivier.fourdan@intel.com> Tested-by: Fourdan, Olivier <olivier.fourdan@intel.com> Reviewed-by: Fert, Laurent <laurent.fert@intel.com> Reviewed-by: cactus <cactus@intel.com> Tested-by: cactus <cactus@intel.com>
-rw-r--r--Makefile5
-rw-r--r--bootstub.c34
-rw-r--r--bootstub.h6
-rw-r--r--sfi.c2
-rw-r--r--spi-uart.h3
-rw-r--r--ssp-uart.c77
-rw-r--r--ssp-uart.h32
-rw-r--r--types.h3
8 files changed, 154 insertions, 8 deletions
diff --git a/Makefile b/Makefile
index 1d0944a..8f3ed29 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-OBJ=bootstub.o spi-uart.o head.o sfi.o e820_bios.o
+OBJ=bootstub.o spi-uart.o head.o sfi.o e820_bios.o ssp-uart.o
CMDLINE_SIZE ?= 0x400
CFLAGS=-m32 -ffreestanding -Wall -DCMDLINE_SIZE=${CMDLINE_SIZE}
CC ?= gcc
@@ -20,6 +20,9 @@ bootstub.o:bootstub.c bootstub.h
spi-uart.o:spi-uart.c spi-uart.h
${CC} $(CFLAGS) -c spi-uart.c
+ssp-uart.o:ssp-uart.c ssp-uart.h
+ ${CC} $(CFLAGS) -c ssp-uart.c
+
sfi.o:sfi.c
${CC} $(CFLAGS) -c sfi.c
diff --git a/bootstub.c b/bootstub.c
index fb1d765..435910d 100644
--- a/bootstub.c
+++ b/bootstub.c
@@ -23,10 +23,9 @@
#include "bootstub.h"
#include "bootparam.h"
#include "spi-uart.h"
+#include "ssp-uart.h"
#include "sfi.h"
-#define bs_printk(x) { if (! *(int *)SPI_UART_SUPPRESSION) bs_spi_printk(x);}
-
extern int no_uart_used;
static void *memcpy(void *dest, const void *src, size_t count)
@@ -149,6 +148,10 @@ int mid_identify_cpu(void)
return MID_CPU_CHIP_CLOVERVIEW;
case VALLEYVIEW2_FAMILY:
return MID_CPU_CHIP_VALLEYVIEW2;
+ case TANGIER_FAMILY:
+ return MID_CPU_CHIP_TANGIER;
+ case ANNIEDALE_FAMILY:
+ return MID_CPU_CHIP_ANNIEDALE;
default:
return MID_CPU_CHIP_OTHER;
}
@@ -169,6 +172,16 @@ static void setup_spi(void)
bs_printk("CLV detected\n");
break;
+ case MID_CPU_CHIP_TANGIER:
+ *(int *)SPI_TYPE = SPI_2;
+ bs_printk("MRD detected\n");
+ break;
+
+ case MID_CPU_CHIP_ANNIEDALE:
+ *(int *)SPI_TYPE = SPI_2;
+ bs_printk("ANN detected\n");
+ break;
+
case MID_CPU_CHIP_VALLEYVIEW2:
case MID_CPU_CHIP_OTHER:
default:
@@ -186,3 +199,20 @@ int bootstub(void)
bs_printk("Jump to kernel 32bit entry ...\n");
return get_32bit_entry((unsigned char *)BZIMAGE_OFFSET);
}
+
+void bs_printk(const char *str)
+{
+ if (*(int *)SPI_UART_SUPPRESSION)
+ return;
+
+ switch (*(int *)SPI_TYPE) {
+
+ case SPI_1:
+ bs_spi_printk(str);
+ break;
+
+ case SPI_2:
+ bs_ssp_printk(str);
+ break;
+ }
+}
diff --git a/bootstub.h b/bootstub.h
index 8db1690..21b08bb 100644
--- a/bootstub.h
+++ b/bootstub.h
@@ -8,11 +8,15 @@
#define PENWELL_FAMILY 0x20670
#define CLOVERVIEW_FAMILY 0x30650
#define VALLEYVIEW2_FAMILY 0x30670
+#define TANGIER_FAMILY 0x406A0
+#define ANNIEDALE_FAMILY 0x506A0
#define MID_CPU_CHIP_LINCROFT 1
#define MID_CPU_CHIP_PENWELL 2
#define MID_CPU_CHIP_CLOVERVIEW 3
#define MID_CPU_CHIP_VALLEYVIEW2 4
+#define MID_CPU_CHIP_TANGIER 5
+#define MID_CPU_CHIP_ANNIEDALE 6
#define MID_CPU_CHIP_OTHER 0xFF
#define CMDLINE_OFFSET 0x1100000
@@ -22,6 +26,7 @@
#define SPI_TYPE (SPI_UART_SUPPRESSION + 4) /*0:SPI0 1:SPI1*/
#define SPI_0 0
#define SPI_1 1
+#define SPI_2 2
#define STACK_OFFSET 0x1101000
#define BZIMAGE_OFFSET 0x1102000
@@ -53,6 +58,7 @@
((u64)(limit & 0x0000ffff)))
int get_e820_by_bios(void *e820_buf);
int mid_identify_cpu(void);
+void bs_printk(const char *str);
#endif
#endif
diff --git a/sfi.c b/sfi.c
index 1b75c9e..f5e5656 100644
--- a/sfi.c
+++ b/sfi.c
@@ -23,8 +23,6 @@
#include "spi-uart.h"
#include "sfi.h"
-#define bs_printk(x) { if (!*(int *)SPI_UART_SUPPRESSION) bs_spi_printk(x); }
-
#define SFI_BASE_ADDR 0x000E0000
#define SFI_LENGTH 0x00020000
diff --git a/spi-uart.h b/spi-uart.h
index 21bedd1..69f0f17 100644
--- a/spi-uart.h
+++ b/spi-uart.h
@@ -5,9 +5,6 @@
#include "types.h"
-typedef volatile unsigned short vu16;
-typedef volatile unsigned int vu32;
-
#define MRST_REGBASE_SPI0 0xff128000
#define MRST_REGBASE_SPI1 0xff128400
#define MRST_REGBASE_SPI2 0xff128800
diff --git a/ssp-uart.c b/ssp-uart.c
new file mode 100644
index 0000000..7a379dc
--- /dev/null
+++ b/ssp-uart.c
@@ -0,0 +1,77 @@
+/*
+ * ssp-uart.c SPI via SSP
+ * Copyright (C) 2011, Mark F. Brown <mark.f.brown@intel.com> Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ */
+
+#include "ssp-uart.h"
+#include "bootstub.h"
+
+#define SSP_TIMEOUT 0xAFF
+#define SSP_SLAVE 0x02 /* Slave select */
+#define SSP_SSCR0 0x00C0008F
+#define SSP_SSCR1 0x10000000
+
+static int ssp_inited = 0;
+static volatile struct ssp_reg *pspi = 0;
+
+#define WRITE_DATA (2<<14)
+
+static void ssp_init()
+{
+ pspi = (struct ssp_reg*)TNG_SSP5_ADDR_BASE;
+ pspi->SSPx_SSFS = SSP_SLAVE;
+ pspi->SSPx_SSCR1 = SSP_SSCR1;
+ pspi->SSPx_SSCR0 = SSP_SSCR0;
+
+ ssp_inited = 1;
+}
+
+static void ssp_max3110_putc(char c)
+{
+ vu32 SSCR0 = 0;
+ vu32 i;
+
+ pspi = (struct ssp_reg*)TNG_SSP5_ADDR_BASE;
+ SSCR0 = (WRITE_DATA | c);
+ pspi->SSPx_SSDR = SSCR0;
+
+ for (i = 0; i < SSP_TIMEOUT; i++)
+ {
+ SSCR0 = pspi->SSPx_SSSR;
+ if ((SSCR0 & 0xF00) == 0) break;
+ }
+
+ SSCR0 = pspi->SSPx_SSDR;
+}
+
+void bs_ssp_printk(const char *str)
+{
+ if (!str)
+ return;
+
+ if (!ssp_inited)
+ {
+ ssp_init();
+ }
+
+ while (*str) {
+ if (*str == '\n')
+ ssp_max3110_putc('\r');
+
+ ssp_max3110_putc(*str++);
+ }
+}
diff --git a/ssp-uart.h b/ssp-uart.h
new file mode 100644
index 0000000..8ae6863
--- /dev/null
+++ b/ssp-uart.h
@@ -0,0 +1,32 @@
+#ifndef _SSP_UART
+#define _SSP_UART
+
+#include "types.h"
+
+#define TNG_SSP5_ADDR_BASE 0xFF189000
+
+struct ssp_reg {
+ vu32 SSPx_SSCR0; // 0x00
+ vu32 SSPx_SSCR1; // 0x04
+ vu32 SSPx_SSSR; // 0x08
+ vu32 SSPx_SSITR; // 0x0C
+ vu32 SSPx_SSDR; // 0x10
+ vu32 SSPx_DUMMY1; //0x14
+ vu32 SSPx_DUMMY2; //0x18
+ vu32 SSPx_DUMMY3; //0x1c
+ vu32 SSPx_DUMMY4; //0x20
+ vu32 SSPx_DUMMY5; //0x24
+ vu32 SSPx_SSTO; // 0x28
+ vu32 SSPx_SSPSP; // 0x2C
+ vu32 SSPx_SSTSA; // 0x30
+ vu32 SSPx_SSRSA; // 0x34
+ vu32 SSPx_SSTSS; // 0x38
+ vu32 SSPx_SSACD; // 0x3C
+ vu32 SSPx_SSCR2; // 0x40
+ vu32 SSPx_SSFS; // 0x44
+ vu32 SSPx_FRAME_CNT; // 0x48
+};
+
+extern void bs_ssp_printk(const char *str);
+
+#endif
diff --git a/types.h b/types.h
index b84de8e..5983418 100644
--- a/types.h
+++ b/types.h
@@ -17,4 +17,7 @@ typedef __u64 u64;
typedef unsigned int size_t;
+typedef volatile unsigned short vu16;
+typedef volatile unsigned int vu32;
+
#endif