diff options
| -rw-r--r-- | arch/microblaze/config.mk | 2 | ||||
| -rw-r--r-- | arch/microblaze/cpu/interrupts.c | 86 | ||||
| -rw-r--r-- | arch/microblaze/cpu/start.S | 2 | ||||
| -rw-r--r-- | arch/microblaze/cpu/timer.c | 21 | ||||
| -rw-r--r-- | arch/microblaze/cpu/u-boot.lds (renamed from board/xilinx/microblaze-generic/u-boot.lds) | 0 | ||||
| -rw-r--r-- | arch/microblaze/include/asm/gpio.h | 41 | ||||
| -rw-r--r-- | arch/microblaze/include/asm/microblaze_intc.h | 3 | ||||
| -rw-r--r-- | arch/microblaze/lib/Makefile | 1 | ||||
| -rw-r--r-- | arch/microblaze/lib/board.c | 15 | ||||
| -rw-r--r-- | arch/microblaze/lib/time.c | 42 | ||||
| -rw-r--r-- | board/xilinx/dts/microblaze.dts | 1 | ||||
| -rw-r--r-- | board/xilinx/microblaze-generic/dts/microblaze.dts | 7 | ||||
| -rw-r--r-- | drivers/spi/Makefile | 2 | ||||
| -rw-r--r-- | drivers/spi/xilinx_spi.c | 214 | ||||
| -rw-r--r-- | drivers/spi/xilinx_spi.h | 135 | ||||
| -rw-r--r-- | dts/Makefile | 3 | ||||
| -rw-r--r-- | include/configs/microblaze-generic.h | 129 | 
17 files changed, 594 insertions, 110 deletions
| diff --git a/arch/microblaze/config.mk b/arch/microblaze/config.mk index abea70bb0..aca79e261 100644 --- a/arch/microblaze/config.mk +++ b/arch/microblaze/config.mk @@ -29,3 +29,5 @@ CROSS_COMPILE ?= mb-  CONFIG_STANDALONE_LOAD_ADDR ?= 0x80F00000  PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__ + +LDSCRIPT ?= $(SRCTREE)/$(CPUDIR)/u-boot.lds diff --git a/arch/microblaze/cpu/interrupts.c b/arch/microblaze/cpu/interrupts.c index e7ca859bf..ee6708218 100644 --- a/arch/microblaze/cpu/interrupts.c +++ b/arch/microblaze/cpu/interrupts.c @@ -26,6 +26,7 @@  #include <common.h>  #include <command.h> +#include <malloc.h>  #include <asm/microblaze_intc.h>  #include <asm/asm.h> @@ -48,20 +49,19 @@ int disable_interrupts (void)  	return (msr & 0x2) != 0;  } -#ifdef CONFIG_SYS_INTC_0 - -static struct irq_action vecs[CONFIG_SYS_INTC_0_NUM]; +static struct irq_action *vecs; +static u32 irq_no;  /* mapping structure to interrupt controller */ -microblaze_intc_t *intc = (microblaze_intc_t *) (CONFIG_SYS_INTC_0_ADDR); +microblaze_intc_t *intc;  /* default handler */ -void def_hdlr (void) +static void def_hdlr(void)  {  	puts ("def_hdlr\n");  } -void enable_one_interrupt (int irq) +static void enable_one_interrupt(int irq)  {  	int mask;  	int offset = 1; @@ -76,7 +76,7 @@ void enable_one_interrupt (int irq)  #endif  } -void disable_one_interrupt (int irq) +static void disable_one_interrupt(int irq)  {  	int mask;  	int offset = 1; @@ -96,7 +96,7 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg)  {  	struct irq_action *act;  	/* irq out of range */ -	if ((irq < 0) || (irq > CONFIG_SYS_INTC_0_NUM)) { +	if ((irq < 0) || (irq > irq_no)) {  		puts ("IRQ out of range\n");  		return;  	} @@ -114,7 +114,7 @@ void install_interrupt_handler (int irq, interrupt_handler_t * hdlr, void *arg)  }  /* initialization interrupt controller - hardware */ -void intc_init (void) +static void intc_init(void)  {  	intc->mer = 0;  	intc->ier = 0; @@ -127,18 +127,33 @@ void intc_init (void)  #endif  } -int interrupts_init (void) +int interrupts_init(void)  {  	int i; -	/* initialize irq list */ -	for (i = 0; i < CONFIG_SYS_INTC_0_NUM; i++) { -		vecs[i].handler = (interrupt_handler_t *) def_hdlr; -		vecs[i].arg = (void *)i; -		vecs[i].count = 0; + +#if defined(CONFIG_SYS_INTC_0_ADDR) && defined(CONFIG_SYS_INTC_0_NUM) +	intc = (microblaze_intc_t *) (CONFIG_SYS_INTC_0_ADDR); +	irq_no = CONFIG_SYS_INTC_0_NUM; +#endif +	if (irq_no) { +		vecs = calloc(1, sizeof(struct irq_action) * irq_no); +		if (vecs == NULL) { +			puts("Interrupt vector allocation failed\n"); +			return -1; +		} + +		/* initialize irq list */ +		for (i = 0; i < irq_no; i++) { +			vecs[i].handler = (interrupt_handler_t *) def_hdlr; +			vecs[i].arg = (void *)i; +			vecs[i].count = 0; +		} +		/* initialize intc controller */ +		intc_init(); +		enable_interrupts(); +	} else { +		puts("Undefined interrupt controller\n");  	} -	/* initialize intc controller */ -	intc_init (); -	enable_interrupts ();  	return 0;  } @@ -172,33 +187,30 @@ void interrupt_handler (void)  	printf ("Interrupt handler on %x line, r14 %x\n", irqs, value);  #endif  } -#endif  #if defined(CONFIG_CMD_IRQ) -#ifdef CONFIG_SYS_INTC_0 -int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) +int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, const char *argv[])  {  	int i;  	struct irq_action *act = vecs; -	puts ("\nInterrupt-Information:\n\n" -	      "Nr  Routine   Arg       Count\n" -	      "-----------------------------\n"); +	if (irq_no) { +		puts("\nInterrupt-Information:\n\n" +		      "Nr  Routine   Arg       Count\n" +		      "-----------------------------\n"); -	for (i = 0; i < CONFIG_SYS_INTC_0_NUM; i++) { -		if (act->handler != (interrupt_handler_t*) def_hdlr) { -			printf ("%02d  %08x  %08x  %d\n", i, -				(int)act->handler, (int)act->arg, act->count); +		for (i = 0; i < irq_no; i++) { +			if (act->handler != (interrupt_handler_t *) def_hdlr) { +				printf("%02d  %08x  %08x  %d\n", i, +					(int)act->handler, (int)act->arg, +								act->count); +			} +			act++;  		} -		act++; +		puts("\n"); +	} else { +		puts("Undefined interrupt controller\n");  	} -	puts ("\n"); -	return (0); -} -#else -int do_irqinfo (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) -{ -	puts ("Undefined interrupt controller\n"); +	return 0;  }  #endif -#endif diff --git a/arch/microblaze/cpu/start.S b/arch/microblaze/cpu/start.S index 9077f742c..8a2f634a9 100644 --- a/arch/microblaze/cpu/start.S +++ b/arch/microblaze/cpu/start.S @@ -108,7 +108,6 @@ _start:  	sh	r6, r0, r8  #endif -#ifdef CONFIG_SYS_INTC_0  	/* interrupt_handler */  	swi	r2, r0, 0x10	/* interrupt - imm opcode */  	swi	r3, r0, 0x14	/* interrupt - brai opcode */ @@ -120,7 +119,6 @@ _start:  	sh	r7, r0, r8  	rsubi	r8, r10, 0x16  	sh	r6, r0, r8 -#endif  	/* hardware exception */  	swi	r2, r0, 0x20	/* hardware exception - imm opcode */ diff --git a/arch/microblaze/cpu/timer.c b/arch/microblaze/cpu/timer.c index 1952804ea..cc6b897fb 100644 --- a/arch/microblaze/cpu/timer.c +++ b/arch/microblaze/cpu/timer.c @@ -40,7 +40,25 @@ ulong get_timer (ulong base)  }  #endif -#ifdef CONFIG_SYS_INTC_0 +#ifdef CONFIG_SYS_TIMER_0 +void __udelay(unsigned long usec) +{ +	int i; + +	i = get_timer(0); +	while ((get_timer(0) - i) < (usec / 1000)) +		; +} +#else +void __udelay(unsigned long usec) +{ +	unsigned int i; + +	for (i = 0; i < (usec * CONFIG_XILINX_CLOCK_FREQ / 10000000); i++) +		; +} +#endif +  #ifdef CONFIG_SYS_TIMER_0  microblaze_timer_t *tmr = (microblaze_timer_t *) (CONFIG_SYS_TIMER_0_ADDR); @@ -61,7 +79,6 @@ int timer_init (void)  	return 0;  }  #endif -#endif  /*   * This function is derived from PowerPC code (read timebase as long long). diff --git a/board/xilinx/microblaze-generic/u-boot.lds b/arch/microblaze/cpu/u-boot.lds index ee41145bb..ee41145bb 100644 --- a/board/xilinx/microblaze-generic/u-boot.lds +++ b/arch/microblaze/cpu/u-boot.lds diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h new file mode 100644 index 000000000..883f4d466 --- /dev/null +++ b/arch/microblaze/include/asm/gpio.h @@ -0,0 +1,41 @@ +#ifndef _ASM_MICROBLAZE_GPIO_H_ +#define _ASM_MICROBLAZE_GPIO_H_ + +#include <asm/io.h> + +static inline int gpio_request(unsigned gpio, const char *label) +{ +	return 0; +} + +static inline int gpio_free(unsigned gpio) +{ +	return 0; +} + +static inline int gpio_direction_input(unsigned gpio) +{ +	return 0; +} + +static inline int gpio_direction_output(unsigned gpio, int value) +{ +	return 0; +} + +static inline int gpio_get_value(unsigned gpio) +{ +	return 0; +} + +static inline int gpio_set_value(unsigned gpio, int value) +{ +	return 0; +} + +static inline int gpio_is_valid(int number) +{ +	return 0; +} +#endif + diff --git a/arch/microblaze/include/asm/microblaze_intc.h b/arch/microblaze/include/asm/microblaze_intc.h index 4c385aa24..6142b9c99 100644 --- a/arch/microblaze/include/asm/microblaze_intc.h +++ b/arch/microblaze/include/asm/microblaze_intc.h @@ -41,3 +41,6 @@ struct irq_action {  void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,  				       void *arg); + +int interrupts_init(void); + diff --git a/arch/microblaze/lib/Makefile b/arch/microblaze/lib/Makefile index de0a7d36c..7730695be 100644 --- a/arch/microblaze/lib/Makefile +++ b/arch/microblaze/lib/Makefile @@ -29,7 +29,6 @@ SOBJS-y	+=  COBJS-y	+= board.o  COBJS-y	+= bootm.o -COBJS-y	+= time.o  SRCS	:= $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)  OBJS	:= $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index f3679d536..b80250a6b 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -30,21 +30,16 @@  #include <version.h>  #include <watchdog.h>  #include <stdio_dev.h> +#include <serial.h>  #include <net.h>  #include <asm/processor.h> +#include <asm/microblaze_intc.h>  DECLARE_GLOBAL_DATA_PTR;  #ifdef CONFIG_SYS_GPIO_0  extern int gpio_init (void);  #endif -#ifdef CONFIG_SYS_INTC_0 -extern int interrupts_init (void); -#endif - -#if defined(CONFIG_CMD_NET) -extern int eth_init (bd_t * bis); -#endif  #ifdef CONFIG_SYS_TIMER_0  extern int timer_init (void);  #endif @@ -73,9 +68,7 @@ init_fnc_t *init_sequence[] = {  #ifdef CONFIG_SYS_GPIO_0  	gpio_init,  #endif -#ifdef CONFIG_SYS_INTC_0  	interrupts_init, -#endif  #ifdef CONFIG_SYS_TIMER_0  	timer_init,  #endif @@ -117,6 +110,10 @@ void board_init (void)  	 */  	mem_malloc_init (CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); +#ifdef CONFIG_SERIAL_MULTI +	serial_initialize(); +#endif +  	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {  		WATCHDOG_RESET ();  		if ((*init_fnc_ptr) () != 0) { diff --git a/arch/microblaze/lib/time.c b/arch/microblaze/lib/time.c index da016a001..e69de29bb 100644 --- a/arch/microblaze/lib/time.c +++ b/arch/microblaze/lib/time.c @@ -1,42 +0,0 @@ -/* - * (C) Copyright 2007 Michal Simek - * (C) Copyright 2004 Atmark Techno, Inc. - * - * Michal  SIMEK <monstr@monstr.eu> - * Yasushi SHOJI <yashi@atmark-techno.com> - * - * See file CREDITS for list of people who contributed to this - * project. - * - * 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; either version 2 of - * the License, or (at your option) any later version. - * - * 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., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include <common.h> - -#ifdef CONFIG_SYS_TIMER_0 -void __udelay (unsigned long usec) -{ -	int i; -	i = get_timer (0); -	while ((get_timer (0) - i) < (usec / 1000)) ; -} -#else -void __udelay (unsigned long usec) -{ -	unsigned int i; -	for (i = 0; i < (usec * CONFIG_XILINX_CLOCK_FREQ / 10000000); i++); -} -#endif diff --git a/board/xilinx/dts/microblaze.dts b/board/xilinx/dts/microblaze.dts new file mode 100644 index 000000000..bf984b0cf --- /dev/null +++ b/board/xilinx/dts/microblaze.dts @@ -0,0 +1 @@ +/include/ BOARD_DTS diff --git a/board/xilinx/microblaze-generic/dts/microblaze.dts b/board/xilinx/microblaze-generic/dts/microblaze.dts new file mode 100644 index 000000000..203330987 --- /dev/null +++ b/board/xilinx/microblaze-generic/dts/microblaze.dts @@ -0,0 +1,7 @@ +/dts-v1/; +/ { +	#address-cells = <1>; +	#size-cells = <1>; +	aliases { +	} ; +} ; diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index c20f1f2da..cd3f9fa85 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -44,6 +44,8 @@ COBJS-$(CONFIG_SOFT_SPI) += soft_spi.o  COBJS-$(CONFIG_SH_SPI) += sh_spi.o  COBJS-$(CONFIG_FSL_ESPI) += fsl_espi.o  COBJS-$(CONFIG_TEGRA_SPI) += tegra_spi.o +COBJS-$(CONFIG_TEGRA2_SPI) += tegra2_spi.o +COBJS-$(CONFIG_XILINX_SPI) += xilinx_spi.o  COBJS	:= $(COBJS-y)  SRCS	:= $(COBJS:.o=.c) diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c new file mode 100644 index 000000000..e563c1905 --- /dev/null +++ b/drivers/spi/xilinx_spi.c @@ -0,0 +1,214 @@ +/* + * Xilinx SPI driver + * + * supports 8 bit SPI transfers only, with or w/o FIFO + * + * based on bfin_spi.c, by way of altera_spi.c + * Copyright (c) 2005-2008 Analog Devices Inc. + * Copyright (c) 2010 Thomas Chou <thomas@wytron.com.tw> + * Copyright (c) 2010 Graeme Smecher <graeme.smecher@mail.mcgill.ca> + * Copyright (c) 2012 Stephan Linz <linz@li-pro.net> + * + * Licensed under the GPL-2 or later. + * + * [0]: http://www.xilinx.com/support/documentation + * + * [S]:	[0]/ip_documentation/xps_spi.pdf + *	[0]/ip_documentation/axi_spi_ds742.pdf + */ +#include <config.h> +#include <common.h> +#include <malloc.h> +#include <spi.h> + +#include "xilinx_spi.h" + +#ifndef CONFIG_SYS_XILINX_SPI_LIST +#define CONFIG_SYS_XILINX_SPI_LIST	{ CONFIG_SYS_SPI_BASE } +#endif + +#ifndef CONFIG_XILINX_SPI_IDLE_VAL +#define CONFIG_XILINX_SPI_IDLE_VAL	0xff +#endif + +#define XILSPI_SPICR_DFLT_ON		(SPICR_MANUAL_SS | \ +					 SPICR_MASTER_MODE | \ +					 SPICR_SPE) + +#define XILSPI_SPICR_DFLT_OFF		(SPICR_MASTER_INHIBIT | \ +					 SPICR_MANUAL_SS) + +#define XILSPI_MAX_XFER_BITS		8 + +static unsigned long xilinx_spi_base_list[] = CONFIG_SYS_XILINX_SPI_LIST; + +__attribute__((weak)) +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ +	return bus < ARRAY_SIZE(xilinx_spi_base_list) && cs < 32; +} + +__attribute__((weak)) +void spi_cs_activate(struct spi_slave *slave) +{ +	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); + +	writel(SPISSR_ACT(slave->cs), &xilspi->regs->spissr); +} + +__attribute__((weak)) +void spi_cs_deactivate(struct spi_slave *slave) +{ +	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); + +	writel(SPISSR_OFF, &xilspi->regs->spissr); +} + +void spi_init(void) +{ +	/* do nothing */ +} + +void spi_set_speed(struct spi_slave *slave, uint hz) +{ +	/* xilinx spi core does not support programmable speed */ +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, +				  unsigned int max_hz, unsigned int mode) +{ +	struct xilinx_spi_slave *xilspi; +	struct xilinx_spi_reg *regs; + +	if (!spi_cs_is_valid(bus, cs)) { +		printf("XILSPI error: %s: unsupported bus %d / cs %d\n", +				__func__, bus, cs); +		return NULL; +	} + +	xilspi = malloc(sizeof(*xilspi)); +	if (!xilspi) { +		printf("XILSPI error: %s: malloc of SPI structure failed\n", +				__func__); +		return NULL; +	} +	xilspi->slave.bus = bus; +	xilspi->slave.cs = cs; +	xilspi->regs = (struct xilinx_spi_reg *)xilinx_spi_base_list[bus]; +	xilspi->freq = max_hz; +	xilspi->mode = mode; +	debug("%s: bus:%i cs:%i base:%p mode:%x max_hz:%d\n", __func__, +		bus, cs, xilspi->regs, xilspi->mode, xilspi->freq); + +	return &xilspi->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ +	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); + +	free(xilspi); +} + +int spi_claim_bus(struct spi_slave *slave) +{ +	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); +	u32 spicr; + +	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); +	writel(SPISSR_OFF, &xilspi->regs->spissr); + +	spicr = XILSPI_SPICR_DFLT_ON; +	if (xilspi->mode & SPI_LSB_FIRST) +		spicr |= SPICR_LSB_FIRST; +	if (xilspi->mode & SPI_CPHA) +		spicr |= SPICR_CPHA; +	if (xilspi->mode & SPI_CPOL) +		spicr |= SPICR_CPOL; +	if (xilspi->mode & SPI_LOOP) +		spicr |= SPICR_LOOP; + +	writel(spicr, &xilspi->regs->spicr); +	return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ +	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); + +	debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); +	writel(SPISSR_OFF, &xilspi->regs->spissr); +	writel(XILSPI_SPICR_DFLT_OFF, &xilspi->regs->spicr); +} + +int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, +	     void *din, unsigned long flags) +{ +	struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); +	/* assume spi core configured to do 8 bit transfers */ +	unsigned int bytes = bitlen / XILSPI_MAX_XFER_BITS; +	const unsigned char *txp = dout; +	unsigned char *rxp = din; +	unsigned rxecount = 17;	/* max. 16 elements in FIFO, leftover 1 */ + +	debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__, +		slave->bus, slave->cs, bitlen, bytes, flags); +	if (bitlen == 0) +		goto done; + +	if (bitlen % XILSPI_MAX_XFER_BITS) { +		printf("XILSPI warning: %s: Not a multiple of %d bits\n", +				__func__, XILSPI_MAX_XFER_BITS); +		flags |= SPI_XFER_END; +		goto done; +	} + +	/* empty read buffer */ +	while (rxecount && !(readl(&xilspi->regs->spisr) & SPISR_RX_EMPTY)) { +		readl(&xilspi->regs->spidrr); +		rxecount--; +	} + +	if (!rxecount) { +		printf("XILSPI error: %s: Rx buffer not empty\n", __func__); +		return -1; +	} + +	if (flags & SPI_XFER_BEGIN) +		spi_cs_activate(slave); + +	while (bytes--) { +		unsigned timeout = /* at least 1usec or greater, leftover 1 */ +			xilspi->freq > XILSPI_MAX_XFER_BITS * 1000000 ? 2 : +			(XILSPI_MAX_XFER_BITS * 1000000 / xilspi->freq) + 1; + +		/* get Tx element from data out buffer and count up */ +		unsigned char d = txp ? *txp++ : CONFIG_XILINX_SPI_IDLE_VAL; +		debug("%s: tx:%x ", __func__, d); + +		/* write out and wait for processing (receive data) */ +		writel(d & SPIDTR_8BIT_MASK, &xilspi->regs->spidtr); +		while (timeout && readl(&xilspi->regs->spisr) +						& SPISR_RX_EMPTY) { +			timeout--; +			udelay(1); +		} + +		if (!timeout) { +			printf("XILSPI error: %s: Xfer timeout\n", __func__); +			return -1; +		} + +		/* read Rx element and push into data in buffer */ +		d = readl(&xilspi->regs->spidrr) & SPIDRR_8BIT_MASK; +		if (rxp) +			*rxp++ = d; +		debug("rx:%x\n", d); +	} + + done: +	if (flags & SPI_XFER_END) +		spi_cs_deactivate(slave); + +	return 0; +} diff --git a/drivers/spi/xilinx_spi.h b/drivers/spi/xilinx_spi.h new file mode 100644 index 000000000..32610d2a1 --- /dev/null +++ b/drivers/spi/xilinx_spi.h @@ -0,0 +1,135 @@ +/* + * Xilinx SPI driver + * + * XPS/AXI bus interface + * + * based on bfin_spi.c, by way of altera_spi.c + * Copyright (c) 2005-2008 Analog Devices Inc. + * Copyright (c) 2010 Thomas Chou <thomas@wytron.com.tw> + * Copyright (c) 2010 Graeme Smecher <graeme.smecher@mail.mcgill.ca> + * Copyright (c) 2012 Stephan Linz <linz@li-pro.net> + * + * Licensed under the GPL-2 or later. + * + * [0]: http://www.xilinx.com/support/documentation + * + * [S]:	[0]/ip_documentation/xps_spi.pdf + *	[0]/ip_documentation/axi_spi_ds742.pdf + */ +#ifndef _XILINX_SPI_ +#define _XILINX_SPI_ + +#include <asm/types.h> +#include <asm/io.h> + +/* + * Xilinx SPI Register Definition + * + * [1]:	[0]/ip_documentation/xps_spi.pdf + *	page 8, Register Descriptions + * [2]:	[0]/ip_documentation/axi_spi_ds742.pdf + *	page 7, Register Overview Table + */ +struct xilinx_spi_reg { +	u32 __space0__[7]; +	u32 dgier;	/* Device Global Interrupt Enable Register (DGIER) */ +	u32 ipisr;	/* IP Interrupt Status Register (IPISR) */ +	u32 __space1__; +	u32 ipier;	/* IP Interrupt Enable Register (IPIER) */ +	u32 __space2__[5]; +	u32 srr;	/* Softare Reset Register (SRR) */ +	u32 __space3__[7]; +	u32 spicr;	/* SPI Control Register (SPICR) */ +	u32 spisr;	/* SPI Status Register (SPISR) */ +	u32 spidtr;	/* SPI Data Transmit Register (SPIDTR) */ +	u32 spidrr;	/* SPI Data Receive Register (SPIDRR) */ +	u32 spissr;	/* SPI Slave Select Register (SPISSR) */ +	u32 spitfor;	/* SPI Transmit FIFO Occupancy Register (SPITFOR) */ +	u32 spirfor;	/* SPI Receive FIFO Occupancy Register (SPIRFOR) */ +}; + +/* Device Global Interrupt Enable Register (dgier), [1] p15, [2] p15 */ +#define DGIER_GIE		(1 << 31) + +/* IP Interrupt Status Register (ipisr), [1] p15, [2] p15 */ +#define IPISR_DRR_NOT_EMPTY	(1 << 8) +#define IPISR_SLAVE_SELECT	(1 << 7) +#define IPISR_TXF_HALF_EMPTY	(1 << 6) +#define IPISR_DRR_OVERRUN	(1 << 5) +#define IPISR_DRR_FULL		(1 << 4) +#define IPISR_DTR_UNDERRUN	(1 << 3) +#define IPISR_DTR_EMPTY		(1 << 2) +#define IPISR_SLAVE_MODF	(1 << 1) +#define IPISR_MODF		(1 << 0) + +/* IP Interrupt Enable Register (ipier), [1] p17, [2] p18 */ +#define IPIER_DRR_NOT_EMPTY	(1 << 8) +#define IPIER_SLAVE_SELECT	(1 << 7) +#define IPIER_TXF_HALF_EMPTY	(1 << 6) +#define IPIER_DRR_OVERRUN	(1 << 5) +#define IPIER_DRR_FULL		(1 << 4) +#define IPIER_DTR_UNDERRUN	(1 << 3) +#define IPIER_DTR_EMPTY		(1 << 2) +#define IPIER_SLAVE_MODF	(1 << 1) +#define IPIER_MODF		(1 << 0) + +/* Softare Reset Register (srr), [1] p9, [2] p8 */ +#define SRR_RESET_CODE		0x0000000A + +/* SPI Control Register (spicr), [1] p9, [2] p8 */ +#define SPICR_LSB_FIRST		(1 << 9) +#define SPICR_MASTER_INHIBIT	(1 << 8) +#define SPICR_MANUAL_SS		(1 << 7) +#define SPICR_RXFIFO_RESEST	(1 << 6) +#define SPICR_TXFIFO_RESEST	(1 << 5) +#define SPICR_CPHA		(1 << 4) +#define SPICR_CPOL		(1 << 3) +#define SPICR_MASTER_MODE	(1 << 2) +#define SPICR_SPE		(1 << 1) +#define SPICR_LOOP		(1 << 0) + +/* SPI Status Register (spisr), [1] p11, [2] p10 */ +#define SPISR_SLAVE_MODE_SELECT	(1 << 5) +#define SPISR_MODF		(1 << 4) +#define SPISR_TX_FULL		(1 << 3) +#define SPISR_TX_EMPTY		(1 << 2) +#define SPISR_RX_FULL		(1 << 1) +#define SPISR_RX_EMPTY		(1 << 0) + +/* SPI Data Transmit Register (spidtr), [1] p12, [2] p12 */ +#define SPIDTR_8BIT_MASK	(0xff << 0) +#define SPIDTR_16BIT_MASK	(0xffff << 0) +#define SPIDTR_32BIT_MASK	(0xffffffff << 0) + +/* SPI Data Receive Register (spidrr), [1] p12, [2] p12 */ +#define SPIDRR_8BIT_MASK	(0xff << 0) +#define SPIDRR_16BIT_MASK	(0xffff << 0) +#define SPIDRR_32BIT_MASK	(0xffffffff << 0) + +/* SPI Slave Select Register (spissr), [1] p13, [2] p13 */ +#define SPISSR_MASK(cs)		(1 << (cs)) +#define SPISSR_ACT(cs)		~SPISSR_MASK(cs) +#define SPISSR_OFF		~0UL + +/* SPI Transmit FIFO Occupancy Register (spitfor), [1] p13, [2] p14 */ +#define SPITFOR_OCYVAL_POS	0 +#define SPITFOR_OCYVAL_MASK	(0xf << SPITFOR_OCYVAL_POS) + +/* SPI Receive FIFO Occupancy Register (spirfor), [1] p14, [2] p14 */ +#define SPIRFOR_OCYVAL_POS	0 +#define SPIRFOR_OCYVAL_MASK	(0xf << SPIRFOR_OCYVAL_POS) + +struct xilinx_spi_slave { +	struct spi_slave slave; +	struct xilinx_spi_reg *regs; +	unsigned int freq; +	unsigned int mode; +}; + +static inline struct xilinx_spi_slave *to_xilinx_spi_slave( +					struct spi_slave *slave) +{ +	return container_of(slave, struct xilinx_spi_slave, slave); +} + +#endif /* _XILINX_SPI_ */ diff --git a/dts/Makefile b/dts/Makefile index 402dfe1dc..055b8ac59 100644 --- a/dts/Makefile +++ b/dts/Makefile @@ -36,7 +36,8 @@ $(error Your architecture does not have device tree support enabled. \  Please define CONFIG_ARCH_DEVICE_TREE))  # We preprocess the device tree file provide a useful define -DTS_CPPFLAGS := -DARCH_CPU_DTS=\"$(SRCTREE)/arch/$(ARCH)/dts/$(CONFIG_ARCH_DEVICE_TREE).dtsi\" +DTS_CPPFLAGS := -DARCH_CPU_DTS=\"$(SRCTREE)/arch/$(ARCH)/dts/$(CONFIG_ARCH_DEVICE_TREE).dtsi\" \ +		-DBOARD_DTS=\"$(SRCTREE)/board/$(VENDOR)/$(BOARD)/dts/$(DEVICE_TREE).dts\"  all:	$(obj).depend $(LIB) diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 295d123e5..1266cf72f 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -31,6 +31,28 @@  #define	CONFIG_MICROBLAZE	1  #define	MICROBLAZE_V5		1 +/* Open Firmware DTS */ +#define CONFIG_OF_CONTROL	1 +#define CONFIG_OF_EMBED		1 +#define CONFIG_DEFAULT_DEVICE_TREE microblaze + +/* linear and spi flash memory */ +#ifdef XILINX_FLASH_START +#define	FLASH +#undef	SPIFLASH +#undef	RAMENV	/* hold environment in flash */ +#else +#ifdef XILINX_SPI_FLASH_BASEADDR +#undef	FLASH +#define	SPIFLASH +#undef	RAMENV	/* hold environment in flash */ +#else +#undef	FLASH +#undef	SPIFLASH +#define	RAMENV	/* hold environment in RAM */ +#endif +#endif +  /* uart */  #ifdef XILINX_UARTLITE_BASEADDR  # define CONFIG_XILINX_UARTLITE @@ -88,7 +110,6 @@  /* interrupt controller */  #ifdef XILINX_INTC_BASEADDR -# define CONFIG_SYS_INTC_0		1  # define CONFIG_SYS_INTC_0_ADDR		XILINX_INTC_BASEADDR  # define CONFIG_SYS_INTC_0_NUM		XILINX_INTC_NUM_INTR_INPUTS  #endif @@ -113,15 +134,19 @@  /*   * memory layout - Example - * CONFIG_SYS_TEXT_BASE = 0x1200_0000; + * CONFIG_SYS_TEXT_BASE = 0x1200_0000;	defined in config.mk   * CONFIG_SYS_SRAM_BASE = 0x1000_0000; - * CONFIG_SYS_SRAM_SIZE = 0x0400_0000; + * CONFIG_SYS_SRAM_SIZE = 0x0400_0000;	64MB + * + * CONFIG_SYS_MONITOR_LEN = 0x40000 + * CONFIG_SYS_MALLOC_LEN = 3 * CONFIG_SYS_MONITOR_LEN = 0xC0000   *   * CONFIG_SYS_GBL_DATA_OFFSET = 0x1000_0000 + 0x0400_0000 - 0x1000 = 0x13FF_F000 - * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - 0x40000 = 0x13FB_F000 - * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - 0x40000 = 0x13F7_F000 + * CONFIG_SYS_MONITOR_BASE = 0x13FF_F000 - CONFIG_SYS_MONITOR_LEN = 0x13FB_F000 + * CONFIG_SYS_MALLOC_BASE = 0x13FB_F000 - CONFIG_SYS_MALLOC_LEN = 0x13EF_F000   *   * 0x1000_0000	CONFIG_SYS_SDRAM_BASE + *					MEMTEST_AREA	 64kB   *					FREE   * 0x1200_0000	CONFIG_SYS_TEXT_BASE   *		U-BOOT code @@ -129,9 +154,9 @@   *					FREE   *   *					STACK - * 0x13F7_F000	CONFIG_SYS_MALLOC_BASE - *					MALLOC_AREA	256kB	Alloc - * 0x11FB_F000	CONFIG_SYS_MONITOR_BASE + * 0x13EF_F000	CONFIG_SYS_MALLOC_BASE + *					MALLOC_AREA	768kB	Alloc + * 0x13FB_F000	CONFIG_SYS_MONITOR_BASE   *					MONITOR_CODE	256kB	Env   * 0x13FF_F000	CONFIG_SYS_GBL_DATA_OFFSET   *					GLOBAL_DATA	4kB	bd, gd @@ -157,15 +182,30 @@  			- CONFIG_SYS_MONITOR_LEN - GENERATED_BD_INFO_SIZE)  #define	CONFIG_SYS_MONITOR_END \  			(CONFIG_SYS_MONITOR_BASE + CONFIG_SYS_MONITOR_LEN) -#define	CONFIG_SYS_MALLOC_LEN		SIZE +#define	CONFIG_SYS_MALLOC_LEN		(SIZE * 3)  #define	CONFIG_SYS_MALLOC_BASE \  			(CONFIG_SYS_MONITOR_BASE - CONFIG_SYS_MALLOC_LEN)  /* stack */  #define	CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_MALLOC_BASE -/*#define	RAMENV */ -#define	FLASH +/* + * CFI flash memory layout - Example + * CONFIG_SYS_FLASH_BASE = 0x2200_0000; + * CONFIG_SYS_FLASH_SIZE = 0x0080_0000;	  8MB + * + * SECT_SIZE = 0x20000;			128kB is one sector + * CONFIG_ENV_SIZE = SECT_SIZE;		128kB environment store + * + * 0x2200_0000	CONFIG_SYS_FLASH_BASE + *					FREE		256kB + * 0x2204_0000	CONFIG_ENV_ADDR + *					ENV_AREA	128kB + * 0x2206_0000 + *					FREE + * 0x2280_0000	CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE + * + */  #ifdef FLASH  # define CONFIG_SYS_FLASH_BASE		XILINX_FLASH_START @@ -186,22 +226,51 @@  #  define CONFIG_ENV_SIZE	0x1000  #  define CONFIG_ENV_ADDR	(CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) -# else	/* !RAMENV */ +# else	/* FLASH && !RAMENV */  #  define CONFIG_ENV_IS_IN_FLASH	1  /* 128K(one sector) for env */  #  define CONFIG_ENV_SECT_SIZE	0x20000  #  define CONFIG_ENV_ADDR \  			(CONFIG_SYS_FLASH_BASE + (2 * CONFIG_ENV_SECT_SIZE))  #  define CONFIG_ENV_SIZE	0x20000 -# endif /* !RAMBOOT */ +# endif /* FLASH && !RAMBOOT */  #else /* !FLASH */ + +#ifdef SPIFLASH +# define CONFIG_SYS_NO_FLASH		1 +# define CONFIG_SYS_SPI_BASE		XILINX_SPI_FLASH_BASEADDR +# define CONFIG_XILINX_SPI		1 +# define CONFIG_SPI			1 +# define CONFIG_SPI_FLASH		1 +# define CONFIG_SPI_FLASH_STMICRO	1 +# define CONFIG_SF_DEFAULT_MODE		SPI_MODE_3 +# define CONFIG_SF_DEFAULT_SPEED	XILINX_SPI_FLASH_MAX_FREQ +# define CONFIG_SF_DEFAULT_CS		XILINX_SPI_FLASH_CS + +# ifdef	RAMENV +#  define CONFIG_ENV_IS_NOWHERE	1 +#  define CONFIG_ENV_SIZE	0x1000 +#  define CONFIG_ENV_ADDR	(CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) + +# else	/* SPIFLASH && !RAMENV */ +#  define CONFIG_ENV_IS_IN_SPI_FLASH	1 +#  define CONFIG_ENV_SPI_MODE		SPI_MODE_3 +#  define CONFIG_ENV_SPI_MAX_HZ		CONFIG_SF_DEFAULT_SPEED +#  define CONFIG_ENV_SPI_CS		CONFIG_SF_DEFAULT_CS +/* 128K(two sectors) for env */ +#  define CONFIG_ENV_SECT_SIZE	0x10000 +#  define CONFIG_ENV_SIZE	(2 * CONFIG_ENV_SECT_SIZE) +/* Warning: adjust the offset in respect of other flash content and size */ +#  define CONFIG_ENV_OFFSET	(128 * CONFIG_ENV_SECT_SIZE) /* at 8MB */ +# endif /* SPIFLASH && !RAMBOOT */ +#else /* !SPIFLASH */ +  /* ENV in RAM */  # define CONFIG_SYS_NO_FLASH	1  # define CONFIG_ENV_IS_NOWHERE	1  # define CONFIG_ENV_SIZE	0x1000  # define CONFIG_ENV_ADDR	(CONFIG_SYS_MONITOR_BASE - CONFIG_ENV_SIZE) -/* hardware flash protection */ -# define CONFIG_SYS_FLASH_PROTECTION +#endif /* !SPIFLASH */  #endif /* !FLASH */  /* system ace */ @@ -269,6 +338,17 @@  # define CONFIG_CMD_FLASH  # define CONFIG_CMD_IMLS  # define CONFIG_CMD_JFFS2 +# define CONFIG_CMD_UBI +# undef CONFIG_CMD_UBIFS + +# if !defined(RAMENV) +#  define CONFIG_CMD_SAVEENV +#  define CONFIG_CMD_SAVES +# endif + +#else +#if defined(SPIFLASH) +# define CONFIG_CMD_SF  # if !defined(RAMENV)  #  define CONFIG_CMD_SAVEENV @@ -278,10 +358,27 @@  # undef CONFIG_CMD_IMLS  # undef CONFIG_CMD_FLASH  # undef CONFIG_CMD_JFFS2 +# undef CONFIG_CMD_UBI +# undef CONFIG_CMD_UBIFS +#endif  #endif  #if defined(CONFIG_CMD_JFFS2) -/* JFFS2 partitions */ +# define CONFIG_MTD_PARTITIONS +#endif + +#if defined(CONFIG_CMD_UBIFS) +# define CONFIG_CMD_UBI +# define CONFIG_LZO +#endif + +#if defined(CONFIG_CMD_UBI) +# define CONFIG_MTD_PARTITIONS +# define CONFIG_RBTREE +#endif + +#if defined(CONFIG_MTD_PARTITIONS) +/* MTD partitions */  #define CONFIG_CMD_MTDPARTS	/* mtdparts command line support */  #define CONFIG_MTD_DEVICE	/* needed for mtdparts commands */  #define CONFIG_FLASH_CFI_MTD |