Merge branch 'master' of git://git.denx.de/u-boot-microblaze
authorWolfgang Denk <wd@denx.de>
Tue, 31 Jul 2012 20:01:08 +0000 (22:01 +0200)
committerWolfgang Denk <wd@denx.de>
Tue, 31 Jul 2012 20:01:08 +0000 (22:01 +0200)
* 'master' of git://git.denx.de/u-boot-microblaze:
  microblaze: Wire up SPI driver
  spi: microblaze: Adds driver for Xilinx SPI controller
  microblaze: intc: Clear interrupt code
  microblaze: Call serial multi initialization
  microblaze: Move __udelay implementation
  microblaze: Remove extern from board.c
  microblaze: Wire up dts configuration
  fdt: Add board specific dts inclusion
  microblaze: Move individual board linker scripts to common script in cpu tree.
  microblaze: Add gpio.h
  microblaze: Add missing undefs for UBI and UBIFS
  microblaze: Expand and correct configuration comments
  microblaze: Enable ubi support
  microblaze: Avoid compile error on systems without cfi flash
  microblaze: Remove wrong define CONFIG_SYS_FLASH_PROTECTION

Conflicts:
drivers/spi/Makefile

Signed-off-by: Wolfgang Denk <wd@denx.de>
17 files changed:
arch/microblaze/config.mk
arch/microblaze/cpu/interrupts.c
arch/microblaze/cpu/start.S
arch/microblaze/cpu/timer.c
arch/microblaze/cpu/u-boot.lds [moved from board/xilinx/microblaze-generic/u-boot.lds with 100% similarity]
arch/microblaze/include/asm/gpio.h [new file with mode: 0644]
arch/microblaze/include/asm/microblaze_intc.h
arch/microblaze/lib/Makefile
arch/microblaze/lib/board.c
arch/microblaze/lib/time.c
board/xilinx/dts/microblaze.dts [new file with mode: 0644]
board/xilinx/microblaze-generic/dts/microblaze.dts [new file with mode: 0644]
drivers/spi/Makefile
drivers/spi/xilinx_spi.c [new file with mode: 0644]
drivers/spi/xilinx_spi.h [new file with mode: 0644]
dts/Makefile
include/configs/microblaze-generic.h

index abea70b..aca79e2 100644 (file)
@@ -29,3 +29,5 @@ CROSS_COMPILE ?= mb-
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x80F00000
 
 PLATFORM_CPPFLAGS += -ffixed-r31 -D__microblaze__
+
+LDSCRIPT ?= $(SRCTREE)/$(CPUDIR)/u-boot.lds
index e7ca859..ee67082 100644 (file)
@@ -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");
-
-       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);
+       if (irq_no) {
+               puts("\nInterrupt-Information:\n\n"
+                     "Nr  Routine   Arg       Count\n"
+                     "-----------------------------\n");
+
+               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
index 9077f74..8a2f634 100644 (file)
@@ -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 */
index 1952804..cc6b897 100644 (file)
@@ -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/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h
new file mode 100644 (file)
index 0000000..883f4d4
--- /dev/null
@@ -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
+
index 4c385aa..6142b9c 100644 (file)
@@ -41,3 +41,6 @@ struct irq_action {
 
 void install_interrupt_handler (int irq, interrupt_handler_t * hdlr,
                                       void *arg);
+
+int interrupts_init(void);
+
index de0a7d3..7730695 100644 (file)
@@ -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))
index f3679d5..b80250a 100644 (file)
 #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) {
index da016a0..e69de29 100644 (file)
@@ -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 (file)
index 0000000..bf984b0
--- /dev/null
@@ -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 (file)
index 0000000..2033309
--- /dev/null
@@ -0,0 +1,7 @@
+/dts-v1/;
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       aliases {
+       } ;
+} ;
index c20f1f2..cd3f9fa 100644 (file)
@@ -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 (file)
index 0000000..e563c19
--- /dev/null
@@ -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 (file)
index 0000000..32610d2
--- /dev/null
@@ -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_ */
index 402dfe1..055b8ac 100644 (file)
@@ -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)
 
index 295d123..1266cf7 100644 (file)
 #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
 
 /* 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
 
 /*
  * 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
  *                                     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
                        - 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
 #  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 */
 # 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
 # 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