diff options
author | Mark F. Brown <mark.f.brown@intel.com> | 2011-09-07 18:06:24 -0400 |
---|---|---|
committer | Patrick Tjin <pattjin@google.com> | 2014-07-21 20:22:40 -0700 |
commit | 90847a8a794a6eedef1f61daab5a9e3afde33c5a (patch) | |
tree | 0da46a3a4531cc7a43d20acca98ce3ced107f741 | |
parent | aecaba3b298855b0ce93f94897a0e2b5269639a7 (diff) | |
download | bootstub-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-- | Makefile | 5 | ||||
-rw-r--r-- | bootstub.c | 34 | ||||
-rw-r--r-- | bootstub.h | 6 | ||||
-rw-r--r-- | sfi.c | 2 | ||||
-rw-r--r-- | spi-uart.h | 3 | ||||
-rw-r--r-- | ssp-uart.c | 77 | ||||
-rw-r--r-- | ssp-uart.h | 32 | ||||
-rw-r--r-- | types.h | 3 |
8 files changed, 154 insertions, 8 deletions
@@ -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 @@ -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; + } +} @@ -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 @@ -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 @@ -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 @@ -17,4 +17,7 @@ typedef __u64 u64; typedef unsigned int size_t; +typedef volatile unsigned short vu16; +typedef volatile unsigned int vu32; + #endif |