diff options
107 files changed, 1684 insertions, 2084 deletions
@@ -3079,26 +3079,12 @@ CBFS (Coreboot Filesystem) support Define this option to include a destructive SPI flash test ('sf test'). - CONFIG_SPI_FLASH_BAR Ban/Extended Addr Reg - - Define this option to use the Bank addr/Extended addr - support on SPI flashes which has size > 16Mbytes. - CONFIG_SF_DUAL_FLASH Dual flash memories Define this option to use dual flash support where two flash memories can be connected with a given cs line. Currently Xilinx Zynq qspi supports these type of connections. - CONFIG_SPI_FLASH_MTD spi-flash MTD layer - - Define this option to use mtd support for spi flash layer, this - adapter is for translating mtd_read/mtd_write commands into - spi_flash_read/spi_flash_write commands. It is not intended to - use it within sf_cmd or the SPI flash subsystem. Such an adapter - is needed for subsystems like UBI which can only operate on top - of the MTD layer. - - SystemACE Support: CONFIG_SYSTEMACE diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index 0e11dcced5c..667f218bd80 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -47,9 +47,12 @@ #endif #define ARC_BCR_DC_BUILD 0x72 #define ARC_BCR_SLC 0xce -#define ARC_AUX_SLC_CONTROL 0x903 +#define ARC_AUX_SLC_CONFIG 0x901 +#define ARC_AUX_SLC_CTRL 0x903 #define ARC_AUX_SLC_FLUSH 0x904 #define ARC_AUX_SLC_INVALIDATE 0x905 +#define ARC_AUX_SLC_IVDL 0x910 +#define ARC_AUX_SLC_FLDL 0x912 #ifndef __ASSEMBLY__ /* Accessors for auxiliary registers */ diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 0b3ebd9f585..432606a4335 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -29,12 +29,7 @@ #ifndef __ASSEMBLY__ -#ifdef CONFIG_ISA_ARCV2 -void slc_enable(void); -void slc_disable(void); -void slc_flush(void); -void slc_invalidate(void); -#endif +void cache_init(void); #endif /* __ASSEMBLY__ */ diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c index d185a50bd31..04d9d9cce57 100644 --- a/arch/arc/lib/bootm.c +++ b/arch/arc/lib/bootm.c @@ -53,6 +53,9 @@ static void boot_prep_linux(bootm_headers_t *images) hang(); } +__weak void smp_set_core_boot_addr(unsigned long addr, int corenr) {} +__weak void smp_kick_all_cpus(void) {} + /* Subcommand: GO */ static void boot_jump_linux(bootm_headers_t *images, int flag) { @@ -80,6 +83,9 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) r2 = (unsigned int)getenv("bootargs"); } + smp_set_core_boot_addr((unsigned long)kernel_entry, -1); + smp_kick_all_cpus(); + if (!fake) kernel_entry(r0, 0, r2); } diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index e369e5a8569..ed8e8e74e2a 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -5,9 +5,13 @@ */ #include <config.h> +#include <linux/compiler.h> +#include <linux/kernel.h> #include <asm/arcregs.h> #include <asm/cache.h> +#define CACHE_LINE_MASK (~(CONFIG_SYS_CACHELINE_SIZE - 1)) + /* Bit values in IC_CTRL */ #define IC_CTRL_CACHE_DISABLE (1 << 0) @@ -18,60 +22,186 @@ #define CACHE_VER_NUM_MASK 0xF #define SLC_CTRL_SB (1 << 2) +#define OP_INV 0x1 +#define OP_FLUSH 0x2 +#define OP_INV_IC 0x3 + +#ifdef CONFIG_ISA_ARCV2 +/* + * By default that variable will fall into .bss section. + * But .bss section is not relocated and so it will be initilized before + * relocation but will be used after being zeroed. + */ +int slc_line_sz __section(".data"); +int slc_exists __section(".data"); + +static unsigned int __before_slc_op(const int op) +{ + unsigned int reg = reg; + + if (op == OP_INV) { + /* + * IM is set by default and implies Flush-n-inv + * Clear it here for vanilla inv + */ + reg = read_aux_reg(ARC_AUX_SLC_CTRL); + write_aux_reg(ARC_AUX_SLC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH); + } + + return reg; +} + +static void __after_slc_op(const int op, unsigned int reg) +{ + if (op & OP_FLUSH) /* flush / flush-n-inv both wait */ + while (read_aux_reg(ARC_AUX_SLC_CTRL) & + DC_CTRL_FLUSH_STATUS) + ; + + /* Switch back to default Invalidate mode */ + if (op == OP_INV) + write_aux_reg(ARC_AUX_SLC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH); +} + +static inline void __slc_line_loop(unsigned long paddr, unsigned long sz, + const int op) +{ + unsigned int aux_cmd; + int num_lines; + +#define SLC_LINE_MASK (~(slc_line_sz - 1)) + + aux_cmd = op & OP_INV ? ARC_AUX_SLC_IVDL : ARC_AUX_SLC_FLDL; + + sz += paddr & ~SLC_LINE_MASK; + paddr &= SLC_LINE_MASK; + + num_lines = DIV_ROUND_UP(sz, slc_line_sz); + + while (num_lines-- > 0) { + write_aux_reg(aux_cmd, paddr); + paddr += slc_line_sz; + } +} + +static inline void __slc_entire_op(const int cacheop) +{ + int aux; + unsigned int ctrl_reg = __before_slc_op(cacheop); + + if (cacheop & OP_INV) /* Inv or flush-n-inv use same cmd reg */ + aux = ARC_AUX_SLC_INVALIDATE; + else + aux = ARC_AUX_SLC_FLUSH; + + write_aux_reg(aux, 0x1); + + __after_slc_op(cacheop, ctrl_reg); +} + +static inline void __slc_line_op(unsigned long paddr, unsigned long sz, + const int cacheop) +{ + unsigned int ctrl_reg = __before_slc_op(cacheop); + __slc_line_loop(paddr, sz, cacheop); + __after_slc_op(cacheop, ctrl_reg); +} +#else +#define __slc_entire_op(cacheop) +#define __slc_line_op(paddr, sz, cacheop) +#endif + +static inline int icache_exists(void) +{ + /* Check if Instruction Cache is available */ + if (read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK) + return 1; + else + return 0; +} + +static inline int dcache_exists(void) +{ + /* Check if Data Cache is available */ + if (read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK) + return 1; + else + return 0; +} + +void cache_init(void) +{ +#ifdef CONFIG_ISA_ARCV2 + /* Check if System-Level Cache (SLC) is available */ + if (read_aux_reg(ARC_BCR_SLC) & CACHE_VER_NUM_MASK) { +#define LSIZE_OFFSET 4 +#define LSIZE_MASK 3 + if (read_aux_reg(ARC_AUX_SLC_CONFIG) & + (LSIZE_MASK << LSIZE_OFFSET)) + slc_line_sz = 64; + else + slc_line_sz = 128; + slc_exists = 1; + } else { + slc_exists = 0; + } +#endif +} + int icache_status(void) { - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) + if (!icache_exists()) return 0; - return (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) != - IC_CTRL_CACHE_DISABLE; + if (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE) + return 0; + else + return 1; } void icache_enable(void) { - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) - return; - - write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) & - ~IC_CTRL_CACHE_DISABLE); + if (icache_exists()) + write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) & + ~IC_CTRL_CACHE_DISABLE); } void icache_disable(void) { - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) - return; - - write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) | - IC_CTRL_CACHE_DISABLE); + if (icache_exists()) + write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) | + IC_CTRL_CACHE_DISABLE); } +#ifndef CONFIG_SYS_DCACHE_OFF void invalidate_icache_all(void) { - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_IC_BUILD) & CACHE_VER_NUM_MASK)) - return; - /* Any write to IC_IVIC register triggers invalidation of entire I$ */ - write_aux_reg(ARC_AUX_IC_IVIC, 1); + if (icache_status()) { + write_aux_reg(ARC_AUX_IC_IVIC, 1); + read_aux_reg(ARC_AUX_IC_CTRL); /* blocks */ + } } +#else +void invalidate_icache_all(void) +{ +} +#endif int dcache_status(void) { - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + if (!dcache_exists()) return 0; - return (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) != - DC_CTRL_CACHE_DISABLE; + if (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE) + return 0; + else + return 1; } void dcache_enable(void) { - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + if (!dcache_exists()) return; write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) & @@ -80,139 +210,144 @@ void dcache_enable(void) void dcache_disable(void) { - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) + if (!dcache_exists()) return; write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) | DC_CTRL_CACHE_DISABLE); } -void flush_dcache_all(void) -{ - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) - return; - - /* Do flush of entire cache */ - write_aux_reg(ARC_AUX_DC_FLSH, 1); - - /* Wait flush end */ - while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS) - ; -} - #ifndef CONFIG_SYS_DCACHE_OFF -static void dcache_flush_line(unsigned addr) +/* + * Common Helper for Line Operations on {I,D}-Cache + */ +static inline void __cache_line_loop(unsigned long paddr, unsigned long sz, + const int cacheop) { + unsigned int aux_cmd; #if (CONFIG_ARC_MMU_VER == 3) - write_aux_reg(ARC_AUX_DC_PTAG, addr); + unsigned int aux_tag; #endif - write_aux_reg(ARC_AUX_DC_FLDL, addr); + int num_lines; - /* Wait flush end */ - while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS) - ; - -#ifndef CONFIG_SYS_ICACHE_OFF - /* - * Invalidate I$ for addresses range just flushed from D$. - * If we try to execute data flushed above it will be valid/correct - */ + if (cacheop == OP_INV_IC) { + aux_cmd = ARC_AUX_IC_IVIL; #if (CONFIG_ARC_MMU_VER == 3) - write_aux_reg(ARC_AUX_IC_PTAG, addr); + aux_tag = ARC_AUX_IC_PTAG; #endif - write_aux_reg(ARC_AUX_IC_IVIL, addr); -#endif /* CONFIG_SYS_ICACHE_OFF */ -} -#endif /* CONFIG_SYS_DCACHE_OFF */ - -void flush_dcache_range(unsigned long start, unsigned long end) -{ -#ifndef CONFIG_SYS_DCACHE_OFF - unsigned int addr; + } else { + /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */ + aux_cmd = cacheop & OP_INV ? ARC_AUX_DC_IVDL : ARC_AUX_DC_FLDL; +#if (CONFIG_ARC_MMU_VER == 3) + aux_tag = ARC_AUX_DC_PTAG; +#endif + } - start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); - end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); + sz += paddr & ~CACHE_LINE_MASK; + paddr &= CACHE_LINE_MASK; - for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) - dcache_flush_line(addr); -#endif /* CONFIG_SYS_DCACHE_OFF */ -} + num_lines = DIV_ROUND_UP(sz, CONFIG_SYS_CACHELINE_SIZE); -void invalidate_dcache_range(unsigned long start, unsigned long end) -{ -#ifndef CONFIG_SYS_DCACHE_OFF - unsigned int addr; - - start = start & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); - end = end & (~(CONFIG_SYS_CACHELINE_SIZE - 1)); - - for (addr = start; addr <= end; addr += CONFIG_SYS_CACHELINE_SIZE) { + while (num_lines-- > 0) { #if (CONFIG_ARC_MMU_VER == 3) - write_aux_reg(ARC_AUX_DC_PTAG, addr); + write_aux_reg(aux_tag, paddr); #endif - write_aux_reg(ARC_AUX_DC_IVDL, addr); + write_aux_reg(aux_cmd, paddr); + paddr += CONFIG_SYS_CACHELINE_SIZE; } -#endif /* CONFIG_SYS_DCACHE_OFF */ } -void invalidate_dcache_all(void) +static unsigned int __before_dc_op(const int op) { - /* If no cache in CPU exit immediately */ - if (!(read_aux_reg(ARC_BCR_DC_BUILD) & CACHE_VER_NUM_MASK)) - return; + unsigned int reg; + + if (op == OP_INV) { + /* + * IM is set by default and implies Flush-n-inv + * Clear it here for vanilla inv + */ + reg = read_aux_reg(ARC_AUX_DC_CTRL); + write_aux_reg(ARC_AUX_DC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH); + } - /* Write 1 to DC_IVDC register triggers invalidation of entire D$ */ - write_aux_reg(ARC_AUX_DC_IVDC, 1); + return reg; } -void flush_cache(unsigned long start, unsigned long size) +static void __after_dc_op(const int op, unsigned int reg) { - flush_dcache_range(start, start + size); + if (op & OP_FLUSH) /* flush / flush-n-inv both wait */ + while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS) + ; + + /* Switch back to default Invalidate mode */ + if (op == OP_INV) + write_aux_reg(ARC_AUX_DC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH); } -#ifdef CONFIG_ISA_ARCV2 -void slc_enable(void) +static inline void __dc_entire_op(const int cacheop) { - /* If SLC ver = 0, no SLC present in CPU */ - if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) - return; + int aux; + unsigned int ctrl_reg = __before_dc_op(cacheop); - write_aux_reg(ARC_AUX_SLC_CONTROL, - read_aux_reg(ARC_AUX_SLC_CONTROL) & ~1); -} + if (cacheop & OP_INV) /* Inv or flush-n-inv use same cmd reg */ + aux = ARC_AUX_DC_IVDC; + else + aux = ARC_AUX_DC_FLSH; -void slc_disable(void) -{ - /* If SLC ver = 0, no SLC present in CPU */ - if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) - return; + write_aux_reg(aux, 0x1); - write_aux_reg(ARC_AUX_SLC_CONTROL, - read_aux_reg(ARC_AUX_SLC_CONTROL) | 1); + __after_dc_op(cacheop, ctrl_reg); } -void slc_flush(void) +static inline void __dc_line_op(unsigned long paddr, unsigned long sz, + const int cacheop) { - /* If SLC ver = 0, no SLC present in CPU */ - if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) - return; + unsigned int ctrl_reg = __before_dc_op(cacheop); + __cache_line_loop(paddr, sz, cacheop); + __after_dc_op(cacheop, ctrl_reg); +} +#else +#define __dc_entire_op(cacheop) +#define __dc_line_op(paddr, sz, cacheop) +#endif /* !CONFIG_SYS_DCACHE_OFF */ - write_aux_reg(ARC_AUX_SLC_FLUSH, 1); +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ + __dc_line_op(start, end - start, OP_INV); +#ifdef CONFIG_ISA_ARCV2 + if (slc_exists) + __slc_line_op(start, end - start, OP_INV); +#endif +} - /* Wait flush end */ - while (read_aux_reg(ARC_AUX_SLC_CONTROL) & SLC_CTRL_SB) - ; +void flush_dcache_range(unsigned long start, unsigned long end) +{ + __dc_line_op(start, end - start, OP_FLUSH); +#ifdef CONFIG_ISA_ARCV2 + if (slc_exists) + __slc_line_op(start, end - start, OP_FLUSH); +#endif } -void slc_invalidate(void) +void flush_cache(unsigned long start, unsigned long size) { - /* If SLC ver = 0, no SLC present in CPU */ - if (!(read_aux_reg(ARC_BCR_SLC) & 0xff)) - return; + flush_dcache_range(start, start + size); +} - write_aux_reg(ARC_AUX_SLC_INVALIDATE, 1); +void invalidate_dcache_all(void) +{ + __dc_entire_op(OP_INV); +#ifdef CONFIG_ISA_ARCV2 + if (slc_exists) + __slc_entire_op(OP_INV); +#endif } -#endif /* CONFIG_ISA_ARCV2 */ +void flush_dcache_all(void) +{ + __dc_entire_op(OP_FLUSH); +#ifdef CONFIG_ISA_ARCV2 + if (slc_exists) + __slc_entire_op(OP_FLUSH); +#endif +} diff --git a/arch/arc/lib/cpu.c b/arch/arc/lib/cpu.c index 3c930bcbebd..4e4dd74db3d 100644 --- a/arch/arc/lib/cpu.c +++ b/arch/arc/lib/cpu.c @@ -23,6 +23,8 @@ int arch_cpu_init(void) gd->cpu_clk = CONFIG_SYS_CLK_FREQ; gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + cache_init(); + return 0; } diff --git a/arch/arc/lib/init_helpers.c b/arch/arc/lib/init_helpers.c index 25690ee16e0..dbc8d68ffb2 100644 --- a/arch/arc/lib/init_helpers.c +++ b/arch/arc/lib/init_helpers.c @@ -10,16 +10,8 @@ DECLARE_GLOBAL_DATA_PTR; int init_cache_f_r(void) { -#ifndef CONFIG_SYS_ICACHE_OFF - icache_enable(); - /* Make sure no stale entries persist from before we disabled cache */ - invalidate_icache_all(); -#endif - #ifndef CONFIG_SYS_DCACHE_OFF - dcache_enable(); - /* Make sure no stale entries persist from before we disabled cache */ - invalidate_dcache_all(); + flush_dcache_all(); #endif return 0; } diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S index e1ef19cb889..26a59341893 100644 --- a/arch/arc/lib/start.S +++ b/arch/arc/lib/start.S @@ -13,18 +13,46 @@ ENTRY(_start) /* Setup interrupt vector base that matches "__text_start" */ sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] - /* Setup stack- and frame-pointers */ - mov %sp, CONFIG_SYS_INIT_SP_ADDR - mov %fp, %sp + ; Disable/enable I-cache according to configuration + lr r5, [ARC_BCR_IC_BUILD] + breq r5, 0, 1f ; I$ doesn't exist + lr r5, [ARC_AUX_IC_CTRL] +#ifndef CONFIG_SYS_ICACHE_OFF + bclr r5, r5, 0 ; 0 - Enable, 1 is Disable +#else + bset r5, r5, 0 ; I$ exists, but is not used +#endif + sr r5, [ARC_AUX_IC_CTRL] + +1: + ; Disable/enable D-cache according to configuration + lr r5, [ARC_BCR_DC_BUILD] + breq r5, 0, 1f ; D$ doesn't exist + lr r5, [ARC_AUX_DC_CTRL] + bclr r5, r5, 6 ; Invalidate (discard w/o wback) +#ifndef CONFIG_SYS_DCACHE_OFF + bclr r5, r5, 0 ; Enable (+Inv) +#else + bset r5, r5, 0 ; Disable (+Inv) +#endif + sr r5, [ARC_AUX_DC_CTRL] - /* Unconditionally disable caches */ +1: #ifdef CONFIG_ISA_ARCV2 - bl slc_flush - bl slc_disable + ; Disable System-Level Cache (SLC) + lr r5, [ARC_BCR_SLC] + breq r5, 0, 1f ; SLC doesn't exist + lr r5, [ARC_AUX_SLC_CTRL] + bclr r5, r5, 6 ; Invalidate (discard w/o wback) + bclr r5, r5, 0 ; Enable (+Inv) + sr r5, [ARC_AUX_SLC_CTRL] + +1: #endif - bl flush_dcache_all - bl dcache_disable - bl icache_disable + + /* Setup stack- and frame-pointers */ + mov %sp, CONFIG_SYS_INIT_SP_ADDR + mov %fp, %sp /* Allocate and zero GD, update SP */ mov %r0, %sp diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 08292353336..9908b430d62 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -589,10 +589,6 @@ config TARGET_TBS2910 bool "Support tbs2910" select CPU_V7 -config TARGET_TQMA6 - bool "TQ Systems TQMa6 board" - select CPU_V7 - config TARGET_OT1200 bool "Bachmann OT1200" select CPU_V7 @@ -670,7 +666,11 @@ config ARCH_ZYNQ bool "Xilinx Zynq Platform" select CPU_V7 select SUPPORT_SPL + select OF_CONTROL + select SPL_DISABLE_OF_CONTROL select DM + select DM_SPI + select DM_SPI_FLASH config TARGET_XILINX_ZYNQMP bool "Support Xilinx ZynqMP Platform" @@ -972,7 +972,6 @@ source "board/ti/ti816x/Kconfig" source "board/timll/devkit3250/Kconfig" source "board/toradex/colibri_pxa270/Kconfig" source "board/toradex/colibri_vf/Kconfig" -source "board/tqc/tqma6/Kconfig" source "board/trizepsiv/Kconfig" source "board/ttcontrol/vision2/Kconfig" source "board/udoo/Kconfig" diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig index 1282be3418c..10908c4c4a2 100644 --- a/arch/arm/cpu/armv7/mx6/Kconfig +++ b/arch/arm/cpu/armv7/mx6/Kconfig @@ -33,11 +33,16 @@ config TARGET_SECOMX6 bool "Support secomx6 boards" select CPU_V7 +config TARGET_TQMA6 + bool "TQ Systems TQMa6 board" + select CPU_V7 + endchoice config SYS_SOC default "mx6" source "board/seco/Kconfig" +source "board/tqc/tqma6/Kconfig" endif diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index b21bd03a8aa..29de6243dc9 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -62,6 +62,7 @@ u32 get_cpu_rev(void) struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; u32 reg = readl(&anatop->digprog_sololite); u32 type = ((reg >> 16) & 0xff); + u32 major; if (type != MXC_CPU_MX6SL) { reg = readl(&anatop->digprog); @@ -79,8 +80,9 @@ u32 get_cpu_rev(void) } } + major = ((reg >> 8) & 0xff); reg &= 0xff; /* mx6 silicon revision */ - return (type << 12) | (reg + 0x10); + return (type << 12) | (reg + (0x10 * (major + 1))); } /* diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 03443629bcd..5f39aa07cfb 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -45,11 +45,11 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUNXI_GPIO_INPUT); #endif #if defined(CONFIG_MACH_SUN8I) - sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0_TX); - sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0_RX); + sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUN8I_GPF_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUN8I_GPF_UART0); #else - sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF_UART0_TX); - sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF_UART0_RX); + sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF_UART0); #endif sunxi_gpio_set_pull(SUNXI_GPF(4), 1); #elif CONFIG_CONS_INDEX == 1 && (defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)) @@ -64,6 +64,10 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPH(20), SUN6I_GPH_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPH(21), SUN6I_GPH_UART0); sunxi_gpio_set_pull(SUNXI_GPH(21), SUNXI_GPIO_PULL_UP); +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_A33) + sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN8I_A33_GPB_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN8I_A33_GPB_UART0); + sunxi_gpio_set_pull(SUNXI_GPB(1), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN9I) sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0); diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/cpu/armv7/sunxi/rsb.c index f115a9cac41..6fd11f15298 100644 --- a/arch/arm/cpu/armv7/sunxi/rsb.c +++ b/arch/arm/cpu/armv7/sunxi/rsb.c @@ -60,11 +60,12 @@ int rsb_init(void) struct sunxi_rsb_reg * const rsb = (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; - rsb_cfg_io(); - /* Enable RSB and PIO clk, and de-assert their resets */ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB); + /* Setup external pins */ + rsb_cfg_io(); + writel(RSB_CTRL_SOFT_RST, &rsb->ctrl); rsb_set_clk(); diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 9c735c672ab..bbca94f1a08 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -128,7 +128,8 @@ dtb-$(CONFIG_MACH_SUN8I_A23) += \ dtb-$(CONFIG_MACH_SUN8I_A33) += \ sun8i-a33-et-q8-v1.6.dtb \ sun8i-a33-ga10h-v1.1.dtb \ - sun8i-a33-ippo-q8h-v1.2-lcd1024x600.dtb + sun8i-a33-ippo-q8h-v1.2-lcd1024x600.dtb \ + sun8i-a33-sinlinx-sina33.dtb dtb-$(CONFIG_MACH_SUN9I) += \ sun9i-a80-optimus.dtb \ sun9i-a80-cubieboard4.dtb diff --git a/arch/arm/dts/sun8i-a23-a33.dtsi b/arch/arm/dts/sun8i-a23-a33.dtsi index faea94e45ee..7abd0ae3143 100644 --- a/arch/arm/dts/sun8i-a23-a33.dtsi +++ b/arch/arm/dts/sun8i-a23-a33.dtsi @@ -366,6 +366,16 @@ allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; }; + mmc2_8bit_pins: mmc2_8bit { + allwinner,pins = "PC5", "PC6", "PC8", + "PC9", "PC10", "PC11", + "PC12", "PC13", "PC14", + "PC15"; + allwinner,function = "mmc2"; + allwinner,drive = <SUN4I_PINCTRL_30_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + i2c0_pins_a: i2c0@0 { allwinner,pins = "PH2", "PH3"; allwinner,function = "i2c0"; diff --git a/arch/arm/dts/sun8i-a33-sinlinx-sina33.dts b/arch/arm/dts/sun8i-a33-sinlinx-sina33.dts new file mode 100644 index 00000000000..5788c29cb56 --- /dev/null +++ b/arch/arm/dts/sun8i-a33-sinlinx-sina33.dts @@ -0,0 +1,129 @@ +/* + * Copyright 2015 Chen-Yu Tsai + * + * Chen-Yu Tsai <wens@csie.org> + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file 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 file 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. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-a33.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/pinctrl/sun4i-a10.h> + +/ { + model = "Sinlinx SinA33"; + compatible = "sinlinx,sina33", "allwinner,sun8i-a33"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&lradc { + vref-supply = <®_vcc3v0>; + status = "okay"; + + button@200 { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + channel = <0>; + voltage = <191011>; + }; + + button@400 { + label = "Volume Down"; + linux,code = <KEY_VOLUMEDOWN>; + channel = <0>; + voltage = <391304>; + }; + + button@600 { + label = "Home"; + linux,code = <KEY_HOME>; + channel = <0>; + voltage = <600000>; + }; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_sina33>; + vmmc-supply = <®_vcc3v0>; + bus-width = <4>; + cd-gpios = <&pio 1 4 GPIO_ACTIVE_HIGH>; /* PB4 */ + cd-inverted; + status = "okay"; +}; + +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_pins>; + vmmc-supply = <®_vcc3v0>; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&mmc2_8bit_pins { + /* eMMC is missing pull-ups */ + allwinner,pull = <SUN4I_PINCTRL_PULL_UP>; +}; + +&pio { + mmc0_cd_pin_sina33: mmc0_cd_pin@0 { + allwinner,pins = "PB4"; + allwinner,function = "gpio_in"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_PULL_UP>; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_b>; + status = "okay"; +}; diff --git a/arch/arm/dts/sun8i-a33.dtsi b/arch/arm/dts/sun8i-a33.dtsi index 9b43bc6e792..85ee08098b7 100644 --- a/arch/arm/dts/sun8i-a33.dtsi +++ b/arch/arm/dts/sun8i-a33.dtsi @@ -86,4 +86,12 @@ compatible = "allwinner,sun8i-a33-pinctrl"; interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; + + uart0_pins_b: uart0@1 { + allwinner,pins = "PB0", "PB1"; + allwinner,function = "uart0"; + allwinner,drive = <SUN4I_PINCTRL_10_MA>; + allwinner,pull = <SUN4I_PINCTRL_NO_PULL>; + }; + }; diff --git a/arch/arm/dts/uniphier-ph1-ld4-ref.dts b/arch/arm/dts/uniphier-ph1-ld4-ref.dts index d972c0230ec..25e487ae511 100644 --- a/arch/arm/dts/uniphier-ph1-ld4-ref.dts +++ b/arch/arm/dts/uniphier-ph1-ld4-ref.dts @@ -5,7 +5,7 @@ * Copyright (C) 2015 Socionext Inc. * Author: Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ /dts-v1/; diff --git a/arch/arm/dts/uniphier-ph1-ld4.dtsi b/arch/arm/dts/uniphier-ph1-ld4.dtsi index c2008383c1b..39d7b240190 100644 --- a/arch/arm/dts/uniphier-ph1-ld4.dtsi +++ b/arch/arm/dts/uniphier-ph1-ld4.dtsi @@ -1,11 +1,9 @@ /* * Device Tree Source for UniPhier PH1-LD4 SoC * - * Copyright (C) 2014-2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ /include/ "skeleton.dtsi" @@ -24,11 +22,26 @@ }; }; + clocks { + arm_timer_clk: arm_timer_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + interrupt-parent = <&intc>; + + extbus: extbus { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + }; uart0: serial@54006800 { compatible = "socionext,uniphier-uart"; @@ -94,6 +107,12 @@ status = "disabled"; }; + system-bus-controller-misc@59800000 { + compatible = "socionext,uniphier-system-bus-controller-misc", + "syscon"; + reg = <0x59800000 0x2000>; + }; + usb0: usb@5a800100 { compatible = "socionext,uniphier-ehci", "generic-ehci"; status = "disabled"; @@ -112,6 +131,28 @@ reg = <0x5a820100 0x100>; }; + timer@60000200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0x60000200 0x20>; + interrupts = <1 11 0x104>; + clocks = <&arm_timer_clk>; + }; + + timer@60000600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x60000600 0x20>; + interrupts = <1 13 0x104>; + clocks = <&arm_timer_clk>; + }; + + intc: interrupt-controller@60001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x60001000 0x1000>, + <0x60000100 0x100>; + }; + nand: nand@68000000 { compatible = "denali,denali-nand-dt"; reg = <0x68000000 0x20>, <0x68100000 0x1000>; diff --git a/arch/arm/dts/uniphier-ph1-pro4-ref.dts b/arch/arm/dts/uniphier-ph1-pro4-ref.dts index f6d03e3e26c..b4b7f61e5c9 100644 --- a/arch/arm/dts/uniphier-ph1-pro4-ref.dts +++ b/arch/arm/dts/uniphier-ph1-pro4-ref.dts @@ -5,7 +5,7 @@ * Copyright (C) 2015 Socionext Inc. * Author: Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ /dts-v1/; diff --git a/arch/arm/dts/uniphier-ph1-pro4.dtsi b/arch/arm/dts/uniphier-ph1-pro4.dtsi index 8195266db3c..f06906c7fa8 100644 --- a/arch/arm/dts/uniphier-ph1-pro4.dtsi +++ b/arch/arm/dts/uniphier-ph1-pro4.dtsi @@ -1,11 +1,9 @@ /* * Device Tree Source for UniPhier PH1-Pro4 SoC * - * Copyright (C) 2014-2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ /include/ "skeleton.dtsi" @@ -16,6 +14,7 @@ cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "socionext,uniphier-smp"; cpu@0 { device_type = "cpu"; @@ -30,11 +29,26 @@ }; }; + clocks { + arm_timer_clk: arm_timer_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + interrupt-parent = <&intc>; + + extbus: extbus { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + }; uart0: serial@54006800 { compatible = "socionext,uniphier-uart"; @@ -120,6 +134,12 @@ status = "ok"; }; + system-bus-controller-misc@59800000 { + compatible = "socionext,uniphier-system-bus-controller-misc", + "syscon"; + reg = <0x59800000 0x2000>; + }; + usb2: usb@5a800100 { compatible = "socionext,uniphier-ehci", "generic-ehci"; status = "disabled"; @@ -144,6 +164,28 @@ reg = <0x65c00000 0x100>; }; + timer@60000200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0x60000200 0x20>; + interrupts = <1 11 0x304>; + clocks = <&arm_timer_clk>; + }; + + timer@60000600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x60000600 0x20>; + interrupts = <1 13 0x304>; + clocks = <&arm_timer_clk>; + }; + + intc: interrupt-controller@60001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x60001000 0x1000>, + <0x60000100 0x100>; + }; + nand: nand@68000000 { compatible = "denali,denali-nand-dt"; reg = <0x68000000 0x20>, <0x68100000 0x1000>; diff --git a/arch/arm/dts/uniphier-ph1-sld3-ref.dts b/arch/arm/dts/uniphier-ph1-sld3-ref.dts index d9616f68a08..9dc929671ea 100644 --- a/arch/arm/dts/uniphier-ph1-sld3-ref.dts +++ b/arch/arm/dts/uniphier-ph1-sld3-ref.dts @@ -5,7 +5,7 @@ * Copyright (C) 2015 Socionext Inc. * Author: Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ /dts-v1/; diff --git a/arch/arm/dts/uniphier-ph1-sld3.dtsi b/arch/arm/dts/uniphier-ph1-sld3.dtsi index 44b19897b3b..2fa42a600f1 100644 --- a/arch/arm/dts/uniphier-ph1-sld3.dtsi +++ b/arch/arm/dts/uniphier-ph1-sld3.dtsi @@ -1,11 +1,9 @@ /* * Device Tree Source for UniPhier PH1-sLD3 SoC * - * Copyright (C) 2014-2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ /include/ "skeleton.dtsi" @@ -16,6 +14,7 @@ cpus { #address-cells = <1>; #size-cells = <0>; + enable-method = "socionext,uniphier-smp"; cpu@0 { device_type = "cpu"; @@ -30,11 +29,48 @@ }; }; + clocks { + arm_timer_clk: arm_timer_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + interrupt-parent = <&intc>; + + extbus: extbus { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + }; + + timer@20000200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0x20000200 0x20>; + interrupts = <1 11 0x304>; + clocks = <&arm_timer_clk>; + }; + + timer@20000600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x20000600 0x20>; + interrupts = <1 13 0x304>; + clocks = <&arm_timer_clk>; + }; + + intc: interrupt-controller@20001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x20001000 0x1000>, + <0x20000100 0x100>; + }; uart0: serial@54006800 { compatible = "socionext,uniphier-uart"; @@ -93,6 +129,12 @@ status = "disabled"; }; + system-bus-controller-misc@59800000 { + compatible = "socionext,uniphier-system-bus-controller-misc", + "syscon"; + reg = <0x59800000 0x2000>; + }; + usb0: usb@5a800100 { compatible = "socionext,uniphier-ehci", "generic-ehci"; status = "disabled"; diff --git a/arch/arm/dts/uniphier-ph1-sld8-ref.dts b/arch/arm/dts/uniphier-ph1-sld8-ref.dts index 69e9bfa9ba0..2d1359c30e5 100644 --- a/arch/arm/dts/uniphier-ph1-sld8-ref.dts +++ b/arch/arm/dts/uniphier-ph1-sld8-ref.dts @@ -5,7 +5,7 @@ * Copyright (C) 2015 Socionext Inc. * Author: Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ /dts-v1/; diff --git a/arch/arm/dts/uniphier-ph1-sld8.dtsi b/arch/arm/dts/uniphier-ph1-sld8.dtsi index d9f61c22319..15df50f2eaa 100644 --- a/arch/arm/dts/uniphier-ph1-sld8.dtsi +++ b/arch/arm/dts/uniphier-ph1-sld8.dtsi @@ -1,11 +1,9 @@ /* * Device Tree Source for UniPhier PH1-sLD8 SoC * - * Copyright (C) 2014-2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ /include/ "skeleton.dtsi" @@ -24,11 +22,26 @@ }; }; + clocks { + arm_timer_clk: arm_timer_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <50000000>; + }; + }; + soc { compatible = "simple-bus"; #address-cells = <1>; #size-cells = <1>; ranges; + interrupt-parent = <&intc>; + + extbus: extbus { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + }; uart0: serial@54006800 { compatible = "socionext,uniphier-uart"; @@ -94,6 +107,12 @@ status = "disabled"; }; + system-bus-controller-misc@59800000 { + compatible = "socionext,uniphier-system-bus-controller-misc", + "syscon"; + reg = <0x59800000 0x2000>; + }; + usb0: usb@5a800100 { compatible = "socionext,uniphier-ehci", "generic-ehci"; status = "disabled"; @@ -112,6 +131,28 @@ reg = <0x5a820100 0x100>; }; + timer@60000200 { + compatible = "arm,cortex-a9-global-timer"; + reg = <0x60000200 0x20>; + interrupts = <1 11 0x104>; + clocks = <&arm_timer_clk>; + }; + + timer@60000600 { + compatible = "arm,cortex-a9-twd-timer"; + reg = <0x60000600 0x20>; + interrupts = <1 13 0x104>; + clocks = <&arm_timer_clk>; + }; + + intc: interrupt-controller@60001000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x60001000 0x1000>, + <0x60000100 0x100>; + }; + nand: nand@68000000 { compatible = "denali,denali-nand-dt"; reg = <0x68000000 0x20>, <0x68100000 0x1000>; diff --git a/arch/arm/dts/uniphier-ref-daughter.dtsi b/arch/arm/dts/uniphier-ref-daughter.dtsi index aca9f58b250..84b2206ad4a 100644 --- a/arch/arm/dts/uniphier-ref-daughter.dtsi +++ b/arch/arm/dts/uniphier-ref-daughter.dtsi @@ -1,11 +1,9 @@ /* * Device Tree Source for UniPhier Reference Daughter Board * - * Copyright (C) 2014-2015 Panasonic Corporation - * Copyright (C) 2015 Socionext Inc. - * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ X11 */ &i2c0 { diff --git a/arch/arm/dts/zynq-7000.dtsi b/arch/arm/dts/zynq-7000.dtsi index 2d076f194e0..920715989e9 100644 --- a/arch/arm/dts/zynq-7000.dtsi +++ b/arch/arm/dts/zynq-7000.dtsi @@ -109,6 +109,32 @@ interrupts = <0 50 4>; }; + spi0: spi@e0006000 { + compatible = "xlnx,zynq-spi"; + reg = <0xe0006000 0x1000>; + status = "disabled"; + interrupt-parent = <&intc>; + interrupts = <0 26 4>; + clocks = <&clkc 25>, <&clkc 34>; + clock-names = "ref_clk", "pclk"; + spi-max-frequency = <166666700>; + #address-cells = <1>; + #size-cells = <0>; + }; + + spi1: spi@e0007000 { + compatible = "xlnx,zynq-spi"; + reg = <0xe0007000 0x1000>; + status = "disabled"; + interrupt-parent = <&intc>; + interrupts = <0 49 4>; + clocks = <&clkc 26>, <&clkc 35>; + clock-names = "ref_clk", "pclk"; + spi-max-frequency = <166666700>; + #address-cells = <1>; + #size-cells = <0>; + }; + gem0: ethernet@e000b000 { compatible = "cdns,gem"; reg = <0xe000b000 0x4000>; diff --git a/arch/arm/dts/zynq-zc770-xm010.dts b/arch/arm/dts/zynq-zc770-xm010.dts index 5e661749772..bf107e308a6 100644 --- a/arch/arm/dts/zynq-zc770-xm010.dts +++ b/arch/arm/dts/zynq-zc770-xm010.dts @@ -14,6 +14,7 @@ aliases { serial0 = &uart1; + spi1 = &spi1; }; memory { @@ -21,3 +22,7 @@ reg = <0 0x40000000>; }; }; + +&spi1 { + status = "okay"; +}; diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c index e5229904539..c12556addfc 100644 --- a/arch/arm/imx-common/timer.c +++ b/arch/arm/imx-common/timer.c @@ -44,8 +44,8 @@ static inline int gpt_has_clk_source_osc(void) { #if defined(CONFIG_MX6) if (((is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) && - (is_soc_rev(CHIP_REV_1_0) > 0)) || is_cpu_type(MXC_CPU_MX6DL) || - is_cpu_type(MXC_CPU_MX6SOLO) || is_cpu_type(MXC_CPU_MX6SX)) + (soc_rev() > CHIP_REV_1_0)) || is_cpu_type(MXC_CPU_MX6DL) || + is_cpu_type(MXC_CPU_MX6SOLO) || is_cpu_type(MXC_CPU_MX6SX)) return 1; return 0; diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h index f059d0f664b..5f0e1e63467 100644 --- a/arch/arm/include/asm/arch-mx5/imx-regs.h +++ b/arch/arm/include/asm/arch-mx5/imx-regs.h @@ -9,6 +9,8 @@ #define ARCH_MXC +#define CONFIG_SYS_CACHELINE_SIZE 64 + #if defined(CONFIG_MX51) #define IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */ #define IPU_SOC_BASE_ADDR 0x40000000 diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 0d38d450daa..35a324cd532 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -312,6 +312,7 @@ #define CHIP_REV_1_0 0x10 #define CHIP_REV_1_2 0x12 #define CHIP_REV_1_5 0x15 +#define CHIP_REV_2_0 0x20 #ifndef CONFIG_MX6SX #define IRAM_SIZE 0x00040000 #else diff --git a/arch/arm/include/asm/arch-mx6/sys_proto.h b/arch/arm/include/asm/arch-mx6/sys_proto.h index c5832912b42..28c77a498ea 100644 --- a/arch/arm/include/asm/arch-mx6/sys_proto.h +++ b/arch/arm/include/asm/arch-mx6/sys_proto.h @@ -12,7 +12,7 @@ #include "../arch-imx/cpu.h" #define soc_rev() (get_cpu_rev() & 0xFF) -#define is_soc_rev(rev) (soc_rev() - rev) +#define is_soc_rev(rev) (soc_rev() == rev) u32 get_nr_cpus(void); u32 get_cpu_rev(void); @@ -20,7 +20,7 @@ u32 get_cpu_speed_grade_hz(void); u32 get_cpu_temp_grade(int *minc, int *maxc); /* returns MXC_CPU_ value */ -#define cpu_type(rev) (((rev) >> 12)&0xff) +#define cpu_type(rev) (((rev) >> 12) & 0xff) /* both macros return/take MXC_CPU_ constants */ #define get_cpu_type() (cpu_type(get_cpu_rev())) @@ -30,6 +30,10 @@ const char *get_imx_type(u32 imxtype); unsigned imx_ddr_size(void); void set_chipselect_size(int const); +#define is_mx6dqp() ((is_cpu_type(MXC_CPU_MX6Q) || \ + is_cpu_type(MXC_CPU_MX6D)) && \ + (soc_rev() >= CHIP_REV_2_0)) + /* * Initializes on-chip ethernet controllers. * to override, implement board_eth_init() diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 496295d3573..8e67b3bcb87 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -156,6 +156,7 @@ enum sunxi_gpio_number { #define SUN4I_GPB_UART0 2 #define SUN5I_GPB_UART0 2 #define SUN8I_GPB_UART2 2 +#define SUN8I_A33_GPB_UART0 3 #define SUNXI_GPC_SDC2 3 #define SUN6I_GPC_SDC3 4 diff --git a/arch/arm/mach-uniphier/cpu_info.c b/arch/arm/mach-uniphier/cpu_info.c index c4ba6d249eb..5d9ed84be4e 100644 --- a/arch/arm/mach-uniphier/cpu_info.c +++ b/arch/arm/mach-uniphier/cpu_info.c @@ -34,6 +34,15 @@ int print_cpuinfo(void) case 0x29: puts("PH1-sLD8 (MN2WS0270)"); break; + case 0x2A: + puts("PH1-Pro5 (MN2WS0300)"); + break; + case 0x2E: + puts("ProXstream2 (MN2WS0310)"); + break; + case 0x2F: + puts("PH1-LD6b (MN2WS0320)"); + break; default: printf("Unknown Processor ID (0x%x)\n", revision); return -1; diff --git a/board/solidrun/mx6cuboxi/mx6cuboxi.c b/board/solidrun/mx6cuboxi/mx6cuboxi.c index d15c726a01e..9b1ecf0457d 100644 --- a/board/solidrun/mx6cuboxi/mx6cuboxi.c +++ b/board/solidrun/mx6cuboxi/mx6cuboxi.c @@ -536,7 +536,7 @@ static const struct mx6_mmdc_calibration mx6dl_1g_mmcd_calib = { .p0_mpdgctrl0 = 0x023C0224, .p0_mpdgctrl1 = 0x02000220, .p1_mpdgctrl0 = 0x02200220, - .p1_mpdgctrl1 = 0x02000220, + .p1_mpdgctrl1 = 0x02040208, .p0_mprddlctl = 0x44444846, .p1_mprddlctl = 0x4042463C, .p0_mpwrdlctl = 0x32343032, @@ -627,7 +627,7 @@ static void spl_dram_init(int width) else if (is_cpu_type(MXC_CPU_MX6Q)) mx6_dram_cfg(&sysinfo, &mx6q_2g_mmcd_calib, &mem_ddr_4g); else if (is_cpu_type(MXC_CPU_MX6DL)) - mx6_dram_cfg(&sysinfo, &mx6q_1g_mmcd_calib, &mem_ddr_2g); + mx6_dram_cfg(&sysinfo, &mx6dl_1g_mmcd_calib, &mem_ddr_2g); else if (is_cpu_type(MXC_CPU_MX6SOLO)) mx6_dram_cfg(&sysinfo, &mx6dl_512m_mmcd_calib, &mem_ddr_2g); } diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index 7a420555593..1f12a646e48 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -162,6 +162,12 @@ M: Siarhei Siamashka <siarhei.siamashka@gmail.com> S: Maintained F: configs/MSI_Primo81_defconfig +SINLINX SINA33 BOARD +M: Chen-Yu Tsai <wens@csie.org> +S: Maintained +F: configs/Sinlinx_SinA33_defconfig +W: http://linux-sunxi.org/Sinlinx_SinA33 + TZX-Q8-713B7 BOARD M: Paul Kocialkowski <contact@paulk.fr> S: Maintained diff --git a/board/synopsys/axs101/MAINTAINERS b/board/synopsys/axs101/MAINTAINERS index 481bbcc2076..79fff8eb3e2 100644 --- a/board/synopsys/axs101/MAINTAINERS +++ b/board/synopsys/axs101/MAINTAINERS @@ -4,3 +4,4 @@ S: Maintained F: board/synopsys/axs101/ F: include/configs/axs101.h F: configs/axs101_defconfig +F: configs/axs103_defconfig diff --git a/board/synopsys/axs101/axs101.c b/board/synopsys/axs101/axs101.c index 8c16410944d..d4280f743ad 100644 --- a/board/synopsys/axs101/axs101.c +++ b/board/synopsys/axs101/axs101.c @@ -56,3 +56,33 @@ int board_early_init_f(void) return 0; } + +#ifdef CONFIG_ISA_ARCV2 +#define RESET_VECTOR_ADDR 0x0 + +void smp_set_core_boot_addr(unsigned long addr, int corenr) +{ + /* All cores have reset vector pointing to 0 */ + writel(addr, (void __iomem *)RESET_VECTOR_ADDR); + + /* Make sure other cores see written value in memory */ + flush_dcache_range(RESET_VECTOR_ADDR, RESET_VECTOR_ADDR + sizeof(int)); +} + +void smp_kick_all_cpus(void) +{ +/* CPU start CREG */ +#define AXC003_CREG_CPU_START 0xF0001400 + +/* Bits positions in CPU start CREG */ +#define BITS_START 0 +#define BITS_POLARITY 8 +#define BITS_CORE_SEL 9 +#define BITS_MULTICORE 12 + +#define CMD (1 << BITS_MULTICORE) | (1 << BITS_CORE_SEL) | \ + (1 << BITS_POLARITY) | (1 << BITS_START) + + writel(CMD, (void __iomem *)AXC003_CREG_CPU_START); +} +#endif diff --git a/board/tqc/tqma6/Kconfig b/board/tqc/tqma6/Kconfig index f8b3d1fd404..b56237d1875 100644 --- a/board/tqc/tqma6/Kconfig +++ b/board/tqc/tqma6/Kconfig @@ -12,4 +12,62 @@ config SYS_SOC config SYS_CONFIG_NAME default "tqma6" +choice + prompt "TQMa6 SoC variant" + default TQMA6Q + help + select the TQMa6 module variant. The variants differing in the used + i.MX6 CPU type and DRAM + +config TQMA6Q + bool "TQMa6Q / TQMa6D" + select MX6Q + help + select TQMa6Q / TQMa6D with i.MX6Q/D and 1GiB DRAM + +config TQMA6S + bool "TQMa6S" + select MX6S + help + select TQMa6S with i.MX6S and 512 MiB DRAM + +endchoice + +choice + prompt "TQMa6 boot configuration" + default TQMA6X_MMC_BOOT + help + Configure boot device. This is also used to implement environment + location. + +config TQMA6X_MMC_BOOT + bool "MMC / SD Boot" + help + Boot from eMMC / SD Card + +config TQMA6X_SPI_BOOT + bool "SPI NOR Boot" + help + Boot from on board SPI NOR flash + +endchoice + +choice + prompt "TQMa6 base board variant" + default MBA6 + help + Select base board for TQMa6 + +config MBA6 + bool "TQMa6 on MBa6 Starterkit" + help + Select the MBa6 starterkit. This features a GigE Phy, USB, SD-Card + etc. + +endchoice + +config IMX_CONFIG + default "board/tqc/tqma6/tqma6q.cfg" if TQMA6Q + default "board/tqc/tqma6/tqma6s.cfg" if TQMA6S + endif diff --git a/common/Kconfig b/common/Kconfig index 2976cd78ddd..40cd69ed708 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -311,6 +311,11 @@ config CMD_NAND help NAND support. +config CMD_SF + bool "sf" + help + SPI Flash support + config CMD_SPI bool "sspi" help diff --git a/configs/Sinlinx_SinA33_defconfig b/configs/Sinlinx_SinA33_defconfig new file mode 100644 index 00000000000..e9e62da101d --- /dev/null +++ b/configs/Sinlinx_SinA33_defconfig @@ -0,0 +1,16 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +CONFIG_MACH_SUN8I_A33=y +CONFIG_DRAM_CLK=552 +CONFIG_DRAM_ZQ=15291 +CONFIG_DEFAULT_DEVICE_TREE="sun8i-a33-sinlinx-sina33" +# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set +CONFIG_SPL=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +CONFIG_DM_ETH=y +CONFIG_DM_SERIAL=y +CONFIG_AXP221_ALDO1_VOLT=3000 +CONFIG_USB=y +CONFIG_DM_USB=y diff --git a/configs/alt_defconfig b/configs/alt_defconfig index f4fea7f2c30..d994d78592e 100644 --- a/configs/alt_defconfig +++ b/configs/alt_defconfig @@ -17,4 +17,5 @@ CONFIG_TARGET_ALT=y # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_MISC is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y CONFIG_SH_SDHI=y diff --git a/configs/am43xx_evm_defconfig b/configs/am43xx_evm_defconfig index 407d67c4768..65efa9d9a30 100644 --- a/configs/am43xx_evm_defconfig +++ b/configs/am43xx_evm_defconfig @@ -5,4 +5,5 @@ CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1,NAND" # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set +CONFIG_SPI_FLASH_BAR=y CONFIG_SPI_FLASH=y diff --git a/configs/bg0900_defconfig b/configs/bg0900_defconfig index 8e0fac85267..a29ad01bd4b 100644 --- a/configs/bg0900_defconfig +++ b/configs/bg0900_defconfig @@ -4,3 +4,4 @@ CONFIG_SPL=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/dra7xx_evm_defconfig b/configs/dra7xx_evm_defconfig index 1a0e01fe9a7..463a7e264e8 100644 --- a/configs/dra7xx_evm_defconfig +++ b/configs/dra7xx_evm_defconfig @@ -8,3 +8,4 @@ CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=1" # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_NFS is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/gose_defconfig b/configs/gose_defconfig index bece0aa6a34..72aee1cd9c7 100644 --- a/configs/gose_defconfig +++ b/configs/gose_defconfig @@ -17,4 +17,5 @@ CONFIG_TARGET_GOSE=y # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_MISC is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y CONFIG_SH_SDHI=y diff --git a/configs/koelsch_defconfig b/configs/koelsch_defconfig index 13c8310b265..df49a71b966 100644 --- a/configs/koelsch_defconfig +++ b/configs/koelsch_defconfig @@ -17,4 +17,5 @@ CONFIG_TARGET_KOELSCH=y # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_MISC is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y CONFIG_SH_SDHI=y diff --git a/configs/lager_defconfig b/configs/lager_defconfig index 3805fcb5ce6..6b86f00eaab 100644 --- a/configs/lager_defconfig +++ b/configs/lager_defconfig @@ -17,4 +17,5 @@ CONFIG_TARGET_LAGER=y # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_MISC is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y CONFIG_SH_SDHI=y diff --git a/configs/maxbcm_defconfig b/configs/maxbcm_defconfig index c5b3b670248..b0b0d6c72c6 100644 --- a/configs/maxbcm_defconfig +++ b/configs/maxbcm_defconfig @@ -5,3 +5,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig index e355ba51080..e6e4db5c486 100644 --- a/configs/mx6sxsabresd_defconfig +++ b/configs/mx6sxsabresd_defconfig @@ -5,3 +5,4 @@ CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sxsabresd/imximage.cfg,M # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig index 650201a17d7..a71511c4107 100644 --- a/configs/ph1_ld4_defconfig +++ b/configs/ph1_ld4_defconfig @@ -7,10 +7,6 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-ld4-ref" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_HUSH_PARSER=y -CONFIG_AUTOBOOT_KEYED=y -CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n" -CONFIG_AUTOBOOT_DELAY_STR="d" -CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_CMD_XIMG is not set # CONFIG_CMD_ENV_EXISTS is not set CONFIG_CMD_NAND=y diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig index 7d8d9cc61a0..d02712eb573 100644 --- a/configs/ph1_pro4_defconfig +++ b/configs/ph1_pro4_defconfig @@ -6,10 +6,6 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-pro4-ref" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_HUSH_PARSER=y -CONFIG_AUTOBOOT_KEYED=y -CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n" -CONFIG_AUTOBOOT_DELAY_STR="d" -CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_CMD_XIMG is not set # CONFIG_CMD_ENV_EXISTS is not set CONFIG_CMD_NAND=y diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig index 90c44ac857c..ee4cebcef38 100644 --- a/configs/ph1_sld8_defconfig +++ b/configs/ph1_sld8_defconfig @@ -7,10 +7,6 @@ CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-sld8-ref" CONFIG_FIT=y CONFIG_FIT_VERBOSE=y CONFIG_HUSH_PARSER=y -CONFIG_AUTOBOOT_KEYED=y -CONFIG_AUTOBOOT_PROMPT="Press SPACE to abort autoboot in %d seconds\n" -CONFIG_AUTOBOOT_DELAY_STR="d" -CONFIG_AUTOBOOT_STOP_STR=" " # CONFIG_CMD_XIMG is not set # CONFIG_CMD_ENV_EXISTS is not set CONFIG_CMD_NAND=y diff --git a/configs/porter_defconfig b/configs/porter_defconfig index 15f3434de87..dc8b5caaf18 100644 --- a/configs/porter_defconfig +++ b/configs/porter_defconfig @@ -17,4 +17,5 @@ CONFIG_TARGET_PORTER=y # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_MISC is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y CONFIG_SH_SDHI=y diff --git a/configs/silk_defconfig b/configs/silk_defconfig index 20c85fd6e64..e4e4ebc6d9f 100644 --- a/configs/silk_defconfig +++ b/configs/silk_defconfig @@ -17,4 +17,5 @@ CONFIG_TARGET_SILK=y # CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_MISC is not set CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y CONFIG_SH_SDHI=y diff --git a/configs/tbs2910_defconfig b/configs/tbs2910_defconfig index bb140265979..f0e5106e8c1 100644 --- a/configs/tbs2910_defconfig +++ b/configs/tbs2910_defconfig @@ -3,3 +3,5 @@ CONFIG_TARGET_TBS2910=y CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q2g.cfg,MX6Q" # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set +CONFIG_DM=y +CONFIG_DM_THERMAL=y diff --git a/configs/tqma6q_mba6_mmc_defconfig b/configs/tqma6q_mba6_mmc_defconfig index ceb3386ac51..c590354aa84 100644 --- a/configs/tqma6q_mba6_mmc_defconfig +++ b/configs/tqma6q_mba6_mmc_defconfig @@ -1,6 +1,6 @@ CONFIG_ARM=y +CONFIG_ARCH_MX6=y CONFIG_TARGET_TQMA6=y -CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/tqc/tqma6/tqma6q.cfg,MX6Q,MBA6,TQMA6X_MMC_BOOT" # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set CONFIG_SPI_FLASH=y diff --git a/configs/tqma6q_mba6_spi_defconfig b/configs/tqma6q_mba6_spi_defconfig index e413ef4b101..7de3f995287 100644 --- a/configs/tqma6q_mba6_spi_defconfig +++ b/configs/tqma6q_mba6_spi_defconfig @@ -1,6 +1,7 @@ CONFIG_ARM=y +CONFIG_ARCH_MX6=y CONFIG_TARGET_TQMA6=y -CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/tqc/tqma6/tqma6q.cfg,MX6Q,MBA6,TQMA6X_SPI_BOOT" +CONFIG_TQMA6X_SPI_BOOT=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set CONFIG_SPI_FLASH=y diff --git a/configs/tqma6s_mba6_mmc_defconfig b/configs/tqma6s_mba6_mmc_defconfig index 6c37b4f0b1a..7bf15d174e1 100644 --- a/configs/tqma6s_mba6_mmc_defconfig +++ b/configs/tqma6s_mba6_mmc_defconfig @@ -1,6 +1,7 @@ CONFIG_ARM=y +CONFIG_ARCH_MX6=y CONFIG_TARGET_TQMA6=y -CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/tqc/tqma6/tqma6s.cfg,MX6S,MBA6,TQMA6X_MMC_BOOT" +CONFIG_TQMA6S=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set CONFIG_SPI_FLASH=y diff --git a/configs/tqma6s_mba6_spi_defconfig b/configs/tqma6s_mba6_spi_defconfig index af7853ff86a..ff38d0b914a 100644 --- a/configs/tqma6s_mba6_spi_defconfig +++ b/configs/tqma6s_mba6_spi_defconfig @@ -1,6 +1,8 @@ CONFIG_ARM=y +CONFIG_ARCH_MX6=y CONFIG_TARGET_TQMA6=y -CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/tqc/tqma6/tqma6s.cfg,MX6S,MBA6,TQMA6X_SPI_BOOT" +CONFIG_TQMA6S=y +CONFIG_TQMA6X_SPI_BOOT=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set CONFIG_SPI_FLASH=y diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig index 533cdb5bb66..c878924c70d 100644 --- a/configs/zynq_microzed_defconfig +++ b/configs/zynq_microzed_defconfig @@ -10,5 +10,3 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_DISABLE_OF_CONTROL=y diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig index 2e405081827..5dde452cc39 100644 --- a/configs/zynq_zc702_defconfig +++ b/configs/zynq_zc702_defconfig @@ -10,4 +10,3 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y diff --git a/configs/zynq_zc706_defconfig b/configs/zynq_zc706_defconfig index 7c3713eb238..0f96d16c080 100644 --- a/configs/zynq_zc706_defconfig +++ b/configs/zynq_zc706_defconfig @@ -10,4 +10,3 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig index 41c04bb74fd..525c538b983 100644 --- a/configs/zynq_zc70x_defconfig +++ b/configs/zynq_zc70x_defconfig @@ -10,5 +10,3 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_DISABLE_OF_CONTROL=y diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig index 73b585474fa..f1fc2830360 100644 --- a/configs/zynq_zc770_xm010_defconfig +++ b/configs/zynq_zc770_xm010_defconfig @@ -11,6 +11,4 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010" # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_DISABLE_OF_CONTROL=y CONFIG_SPI_FLASH=y diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig index 0d5c77ee413..73ed13d9be8 100644 --- a/configs/zynq_zc770_xm012_defconfig +++ b/configs/zynq_zc770_xm012_defconfig @@ -9,5 +9,3 @@ CONFIG_FIT_VERBOSE=y CONFIG_FIT_SIGNATURE=y CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012" # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_DISABLE_OF_CONTROL=y diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig index 8d320a16e1d..211a41d91a5 100644 --- a/configs/zynq_zc770_xm013_defconfig +++ b/configs/zynq_zc770_xm013_defconfig @@ -11,5 +11,3 @@ CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013" # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_DISABLE_OF_CONTROL=y diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig index 9f378492b9f..f3c63f9560b 100644 --- a/configs/zynq_zed_defconfig +++ b/configs/zynq_zed_defconfig @@ -10,5 +10,3 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_DISABLE_OF_CONTROL=y diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig index e25573bc4a8..0c6117d68e7 100644 --- a/configs/zynq_zybo_defconfig +++ b/configs/zynq_zybo_defconfig @@ -10,5 +10,3 @@ CONFIG_FIT_SIGNATURE=y # CONFIG_CMD_IMLS is not set # CONFIG_CMD_FLASH is not set # CONFIG_CMD_SETEXPR is not set -CONFIG_OF_CONTROL=y -CONFIG_SPL_DISABLE_OF_CONTROL=y diff --git a/doc/device-tree-bindings/spi/spi-zynq.txt b/doc/device-tree-bindings/spi/spi-zynq.txt new file mode 100644 index 00000000000..f397a36d680 --- /dev/null +++ b/doc/device-tree-bindings/spi/spi-zynq.txt @@ -0,0 +1,29 @@ +Zynq SPI controller Device Tree Bindings +---------------------------------------- + +Required properties: +- compatible : Should be "xlnx,spi-zynq". +- reg : Physical base address and size of SPI registers map. +- status : Status will be disabled in dtsi and enabled in required dts. +- interrupt-parent : Must be core interrupt controller. +- interrupts : Property with a value describing the interrupt + number. +- clocks : Clock phandles (see clock bindings for details). +- clock-names : List of input clock names - "ref_clk", "pclk" + (See clock bindings for details). +- spi-max-frequency : Maximum SPI clocking speed of device in Hz + +Example: + + spi@e0006000 { + compatible = "xlnx,zynq-spi"; + reg = <0xe0006000 0x1000>; + status = "disabled"; + interrupt-parent = <&intc>; + interrupts = <0 26 4>; + clocks = <&clkc 25>, <&clkc 34>; + clock-names = "ref_clk", "pclk"; + spi-max-frequency = <166666700>; + #address-cells = <1>; + #size-cells = <0>; + } ; diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig index 40a7981bd53..4f0c0402143 100644 --- a/drivers/mtd/spi/Kconfig +++ b/drivers/mtd/spi/Kconfig @@ -1,11 +1,4 @@ -config SPI_FLASH - bool "Enable SPI Flash support" - help - Enable the legacy SPI flash support. This will include basic - standard support for things like probing, read / write, and - erasing through the MTD layer. - - If unsure, say N +menu "SPI Flash Support" config DM_SPI_FLASH bool "Enable Driver Model for SPI flash" @@ -31,3 +24,49 @@ config SPI_FLASH_SANDBOX bus (see CONFIG_SANDBOX_SPI) and SPI traffic will be routed to this device. Typically the contents of the emulated SPI flash device is stored in a file on the host filesystem. + +config SPI_FLASH + bool "Legacy SPI Flash Interface support" + help + Enable the legacy SPI flash support. This will include basic + standard support for things like probing, read / write, and + erasing through cmd_sf interface. + + If unsure, say N + +config SPI_FLASH_BAR + bool "SPI flash Bank/Extended address register support" + depends on SPI_FLASH + help + Enable the SPI flash Bank/Extended address register support. + Bank/Extended address registers are used to access the flash + which has size > 16MiB in 3-byte addressing. + +config SPI_FLASH_DATAFLASH + bool "AT45xxx DataFlash support" + depends on SPI_FLASH && DM_SPI_FLASH + help + Enable the access for SPI-flash-based AT45xxx DataFlash chips. + DataFlash is a kind of SPI flash. Most AT45 chips have two buffers + in each chip, which may be used for double buffered I/O; but this + driver doesn't (yet) use these for any kind of i/o overlap or prefetching. + + Sometimes DataFlash is packaged in MMC-format cards, although the + MMC stack can't (yet?) distinguish between MMC and DataFlash + protocols during enumeration. + + If unsure, say N + +config SPI_FLASH_MTD + bool "SPI Flash MTD support" + depends on SPI_FLASH + help + Enable the MTD support for spi flash layer, this adapter is for + translating mtd_read/mtd_write commands into spi_flash_read/write + commands. It is not intended to use it within sf_cmd or the SPI + flash subsystem. Such an adapter is needed for subsystems like + UBI which can only operate on top of the MTD layer. + + If unsure, say N + +endmenu # menu "SPI Flash Support" diff --git a/drivers/mtd/spi/Makefile b/drivers/mtd/spi/Makefile index ed46648aa37..ff48b25f6f3 100644 --- a/drivers/mtd/spi/Makefile +++ b/drivers/mtd/spi/Makefile @@ -15,9 +15,9 @@ endif #ifndef CONFIG_DM_SPI obj-$(CONFIG_SPI_FLASH) += sf_probe.o #endif -obj-$(CONFIG_SF_DATAFLASH) += sf_dataflash.o obj-$(CONFIG_CMD_SF) += sf.o obj-$(CONFIG_SPI_FLASH) += sf_ops.o sf_params.o +obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o obj-$(CONFIG_SPI_FLASH_SANDBOX) += sandbox.o obj-$(CONFIG_SPI_M95XXX) += eeprom_m95xxx.o diff --git a/drivers/mtd/spi/sf_dataflash.c b/drivers/mtd/spi/sf_dataflash.c index d287db8b4ce..3111f4fd12e 100644 --- a/drivers/mtd/spi/sf_dataflash.c +++ b/drivers/mtd/spi/sf_dataflash.c @@ -19,16 +19,6 @@ #include "sf_internal.h" -/* - * DataFlash is a kind of SPI flash. Most AT45 chips have two buffers in - * each chip, which may be used for double buffered I/O; but this driver - * doesn't (yet) use these for any kind of i/o overlap or prefetching. - * - * Sometimes DataFlash is packaged in MMC-format cards, although the - * MMC stack can't (yet?) distinguish between MMC and DataFlash - * protocols during enumeration. - */ - /* reads can bypass the buffers */ #define OP_READ_CONTINUOUS 0xE8 #define OP_READ_PAGE 0xD2 diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index 81eea8ce9db..9fb555707cd 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -31,9 +31,9 @@ enum spi_read_cmds { }; /* Normal - Extended - Full command set */ -#define RD_NORM (ARRAY_SLOW | ARRAY_FAST) -#define RD_EXTN (RD_NORM | DUAL_OUTPUT_FAST | DUAL_IO_FAST) -#define RD_FULL (RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST) +#define RD_NORM (ARRAY_SLOW | ARRAY_FAST) +#define RD_EXTN (RD_NORM | DUAL_OUTPUT_FAST | DUAL_IO_FAST) +#define RD_FULL (RD_EXTN | QUAD_OUTPUT_FAST | QUAD_IO_FAST) /* sf param flags */ enum { @@ -67,12 +67,12 @@ enum { #define CMD_WRITE_STATUS 0x01 #define CMD_PAGE_PROGRAM 0x02 #define CMD_WRITE_DISABLE 0x04 -#define CMD_READ_STATUS 0x05 +#define CMD_READ_STATUS 0x05 #define CMD_QUAD_PAGE_PROGRAM 0x32 #define CMD_READ_STATUS1 0x35 #define CMD_WRITE_ENABLE 0x06 -#define CMD_READ_CONFIG 0x35 -#define CMD_FLAG_STATUS 0x70 +#define CMD_READ_CONFIG 0x35 +#define CMD_FLAG_STATUS 0x70 /* Read commands */ #define CMD_READ_ARRAY_SLOW 0x03 @@ -99,13 +99,13 @@ enum { /* Flash timeout values */ #define SPI_FLASH_PROG_TIMEOUT (2 * CONFIG_SYS_HZ) -#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ) +#define SPI_FLASH_PAGE_ERASE_TIMEOUT (5 * CONFIG_SYS_HZ) #define SPI_FLASH_SECTOR_ERASE_TIMEOUT (10 * CONFIG_SYS_HZ) /* SST specific */ #ifdef CONFIG_SPI_FLASH_SST # define CMD_SST_BP 0x02 /* Byte Program */ -# define CMD_SST_AAI_WP 0xAD /* Auto Address Incr Word Program */ +# define CMD_SST_AAI_WP 0xAD /* Auto Address Incr Word Program */ int sst_write_wp(struct spi_flash *flash, u32 offset, size_t len, const void *buf); @@ -121,7 +121,7 @@ int sst_write_bp(struct spi_flash *flash, u32 offset, size_t len, * @ext_jedec: Device ext_jedec ID * @sector_size: Isn't necessarily a sector size from vendor, * the size listed here is what works with CMD_ERASE_64K - * @nr_sectors: No.of sectors on this device + * @nr_sectors: No.of sectors on this device * @e_rd_cmd: Enum list for read commands * @flags: Important param, for flash specific behaviour */ diff --git a/drivers/mtd/spi/sf_params.c b/drivers/mtd/spi/sf_params.c index c12e8c6fe7e..4a4a3afc925 100644 --- a/drivers/mtd/spi/sf_params.c +++ b/drivers/mtd/spi/sf_params.c @@ -100,7 +100,7 @@ const struct spi_flash_params spi_flash_params_table[] = { {"SST25WF010", 0xbf2502, 0x0, 64 * 1024, 2, RD_NORM, SECT_4K | SST_WR}, {"SST25WF020", 0xbf2503, 0x0, 64 * 1024, 4, RD_NORM, SECT_4K | SST_WR}, {"SST25WF040", 0xbf2504, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K | SST_WR}, - {"SST25WF040B", 0x621613, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K | SST_WR}, + {"SST25WF040B", 0x621613, 0x0, 64 * 1024, 8, RD_NORM, SECT_4K}, {"SST25WF080", 0xbf2505, 0x0, 64 * 1024, 16, RD_NORM, SECT_4K | SST_WR}, #endif #ifdef CONFIG_SPI_FLASH_WINBOND /* WINBOND */ diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 357a33511ff..c84a7b74d6c 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -1,3 +1,5 @@ +menu "SPI Support" + config DM_SPI bool "Enable Driver Model for SPI drivers" depends on DM @@ -11,6 +13,51 @@ config DM_SPI typically use driver-private data instead of extending the spi_slave structure. +if DM_SPI + +config CADENCE_QSPI + bool "Cadence QSPI driver" + help + Enable the Cadence Quad-SPI (QSPI) driver. This driver can be + used to access the SPI NOR flash on platforms embedding this + Cadence IP core. + +config DESIGNWARE_SPI + bool "Designware SPI driver" + help + Enable the Designware SPI driver. This driver can be used to + access the SPI NOR flash on platforms embedding this Designware + IP core. + +config EXYNOS_SPI + bool "Samsung Exynos SPI driver" + help + Enable the Samsung Exynos SPI driver. This driver can be used to + access the SPI NOR flash on platforms embedding this Samsung + Exynos IP core. + +config FSL_DSPI + bool "Freescale DSPI driver" + help + Enable the Freescale DSPI driver. This driver can be used to + access the SPI NOR flash and SPI Data flash on platforms embedding + this Freescale DSPI IP core. LS102xA and Colibri VF50/VF61 platforms + use this driver. + +config FSL_QSPI + bool "Freescale QSPI driver" + help + Enable the Freescale Quad-SPI (QSPI) driver. This driver can be + used to access the SPI NOR flash on platforms embedding this + Freescale IP core. + +config ICH_SPI + bool "Intel ICH SPI driver" + help + Enable the Intel ICH SPI driver. This driver can be used to + access the SPI NOR flash on platforms embedding this Intel + ICH IP core. + config SANDBOX_SPI bool "Sandbox SPI driver" depends on SANDBOX && DM @@ -34,20 +81,61 @@ config SANDBOX_SPI spi-max-frequency = <40000000>; sandbox,filename = "spi.bin"; }; - }; + }; -config DESIGNWARE_SPI - bool "Designware SPI driver" - depends on DM_SPI +config TEGRA114_SPI + bool "nVidia Tegra114 SPI driver" help - Enable the Designware SPI driver. This driver can be used to - access the SPI NOR flash on platforms embedding this Designware + Enable the nVidia Tegra114 SPI driver. This driver can be used to + access the SPI NOR flash on platforms embedding this nVidia Tegra114 IP core. -config CADENCE_QSPI - bool "Cadence QSPI driver" - depends on DM_SPI + This controller is different than the older SoCs SPI controller and + also register interface get changed with this controller. + +config TEGRA20_SFLASH + bool "nVidia Tegra20 Serial Flash controller driver" help - Enable the Cadence Quad-SPI (QSPI) driver. This driver can be - used to access the SPI NOR flash on platforms embedding this - Cadence IP core. + Enable the nVidia Tegra20 Serial Flash controller driver. This driver + can be used to access the SPI NOR flash on platforms embedding this + nVidia Tegra20 IP core. + +config TEGRA20_SLINK + bool "nVidia Tegra20/Tegra30 SLINK driver" + help + Enable the nVidia Tegra20/Tegra30 SLINK driver. This driver can + be used to access the SPI NOR flash on platforms embedding this + nVidia Tegra20/Tegra30 IP cores. + +config XILINX_SPI + bool "Xilinx SPI driver" + help + Enable the Xilinx SPI driver from the Xilinx EDK. This SPI + controller support 8 bit SPI transfers only, with or w/o FIFO. + For more info on Xilinx SPI Register Definitions and Overview + see driver file - drivers/spi/xilinx_spi.c + +config ZYNQ_SPI + bool "Zynq SPI driver" + depends on ARCH_ZYNQ || TARGET_XILINX_ZYNQMP + help + Enable the Zynq SPI driver. This driver can be used to + access the SPI NOR flash on platforms embedding this Zynq + SPI IP core. + +endif # if DM_SPI + +config FSL_ESPI + bool "Freescale eSPI driver" + help + Enable the Freescale eSPI driver. This driver can be used to + access the SPI interface and SPI NOR flash on platforms embedding + this Freescale eSPI IP core. + +config TI_QSPI + bool "TI QSPI driver" + help + Enable the TI Quad-SPI (QSPI) driver for DRA7xx and AM43xx evms. + This driver support spi flash single, quad and memory reads. + +endmenu # menu "SPI Support" diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index e288692f268..ee88aa162bc 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -15,9 +15,7 @@ obj-y += spi.o obj-$(CONFIG_SOFT_SPI) += soft_spi_legacy.o endif -obj-$(CONFIG_EP93XX_SPI) += ep93xx_spi.o obj-$(CONFIG_ALTERA_SPI) += altera_spi.o -obj-$(CONFIG_ANDES_SPI) += andes_spi.o obj-$(CONFIG_ARMADA100_SPI) += armada100_spi.o obj-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o @@ -28,8 +26,11 @@ obj-$(CONFIG_CF_SPI) += cf_spi.o obj-$(CONFIG_CF_QSPI) += cf_qspi.o obj-$(CONFIG_DAVINCI_SPI) += davinci_spi.o obj-$(CONFIG_DESIGNWARE_SPI) += designware_spi.o +obj-$(CONFIG_EP93XX_SPI) += ep93xx_spi.o obj-$(CONFIG_EXYNOS_SPI) += exynos_spi.o -obj-$(CONFIG_FTSSP010_SPI) += ftssp010_spi.o +obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o +obj-$(CONFIG_FSL_ESPI) += fsl_espi.o +obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o obj-$(CONFIG_ICH_SPI) += ich.o obj-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o obj-$(CONFIG_LPC32XX_SSP) += lpc32xx_ssp.o @@ -37,17 +38,13 @@ obj-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o obj-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o obj-$(CONFIG_MXC_SPI) += mxc_spi.o obj-$(CONFIG_MXS_SPI) += mxs_spi.o -obj-$(CONFIG_OC_TINY_SPI) += oc_tiny_spi.o obj-$(CONFIG_OMAP3_SPI) += omap3_spi.o obj-$(CONFIG_SANDBOX_SPI) += sandbox_spi.o obj-$(CONFIG_SH_SPI) += sh_spi.o obj-$(CONFIG_SH_QSPI) += sh_qspi.o -obj-$(CONFIG_FSL_ESPI) += fsl_espi.o +obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o obj-$(CONFIG_TEGRA20_SFLASH) += tegra20_sflash.o obj-$(CONFIG_TEGRA20_SLINK) += tegra20_slink.o -obj-$(CONFIG_TEGRA114_SPI) += tegra114_spi.o obj-$(CONFIG_TI_QSPI) += ti_qspi.o obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o obj-$(CONFIG_ZYNQ_SPI) += zynq_spi.o -obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o -obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o diff --git a/drivers/spi/andes_spi.c b/drivers/spi/andes_spi.c deleted file mode 100644 index 82aed75ca18..00000000000 --- a/drivers/spi/andes_spi.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Driver of Andes SPI Controller - * - * (C) Copyright 2011 Andes Technology - * Macpaul Lin <macpaul@andestech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <malloc.h> -#include <spi.h> - -#include <asm/io.h> -#include "andes_spi.h" - -void spi_init(void) -{ - /* do nothing */ -} - -static void andes_spi_spit_en(struct andes_spi_slave *ds) -{ - unsigned int dcr = readl(&ds->regs->dcr); - - debug("%s: dcr: %x, write value: %x\n", - __func__, dcr, (dcr | ANDES_SPI_DCR_SPIT)); - - writel((dcr | ANDES_SPI_DCR_SPIT), &ds->regs->dcr); -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct andes_spi_slave *ds; - - if (!spi_cs_is_valid(bus, cs)) - return NULL; - - ds = spi_alloc_slave(struct andes_spi_slave, bus, cs); - if (!ds) - return NULL; - - ds->regs = (struct andes_spi_regs *)CONFIG_SYS_SPI_BASE; - - /* - * The hardware of andes_spi will set its frequency according - * to APB/AHB bus clock. Hence the hardware doesn't allow changing of - * requency and so the user requested speed is always ignored. - */ - ds->freq = max_hz; - - return &ds->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct andes_spi_slave *ds = to_andes_spi(slave); - - free(ds); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct andes_spi_slave *ds = to_andes_spi(slave); - unsigned int apb; - unsigned int baud; - - /* Enable the SPI hardware */ - writel(ANDES_SPI_CR_SPIRST, &ds->regs->cr); - udelay(1000); - - /* setup format */ - baud = ((CONFIG_SYS_CLK_FREQ / CONFIG_SYS_SPI_CLK / 2) - 1) & 0xFF; - - /* - * SPI_CLK = AHB bus clock / ((BAUD + 1)*2) - * BAUD = AHB bus clock / SPI_CLK / 2) - 1 - */ - apb = (readl(&ds->regs->apb) & 0xffffff00) | baud; - writel(apb, &ds->regs->apb); - - /* no interrupts */ - writel(0, &ds->regs->ie); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - struct andes_spi_slave *ds = to_andes_spi(slave); - - /* Disable the SPI hardware */ - writel(ANDES_SPI_CR_SPIRST, &ds->regs->cr); -} - -static int andes_spi_read(struct spi_slave *slave, unsigned int len, - u8 *rxp, unsigned long flags) -{ - struct andes_spi_slave *ds = to_andes_spi(slave); - unsigned int i, left; - unsigned int data; - - debug("%s: slave: %x, len: %d, rxp: %x, flags: %d\n", - __func__, slave, len, rxp, flags); - - debug("%s: data: ", __func__); - while (len > 0) { - left = min(len, 4); - data = readl(&ds->regs->data); - - debug(" "); - for (i = 0; i < left; i++) { - debug("%02x ", data & 0xff); - *rxp++ = data; - data >>= 8; - len--; - } - } - debug("\n"); - - return 0; -} - -static int andes_spi_write(struct spi_slave *slave, unsigned int wlen, - unsigned int rlen, const u8 *txp, unsigned long flags) -{ - struct andes_spi_slave *ds = to_andes_spi(slave); - unsigned int data; - unsigned int i, left; - unsigned int spit_enabled = 0; - - debug("%s: slave: %x, wlen: %d, rlen: %d, txp: %x, flags: %x\n", - __func__, slave, wlen, rlen, txp, flags); - - /* The value of wlen and rlen wrote to register must minus 1 */ - if (rlen == 0) /* write only */ - writel(ANDES_SPI_DCR_MODE_WO | ANDES_SPI_DCR_WCNT(wlen-1) | - ANDES_SPI_DCR_RCNT(0), &ds->regs->dcr); - else /* write then read */ - writel(ANDES_SPI_DCR_MODE_WR | ANDES_SPI_DCR_WCNT(wlen-1) | - ANDES_SPI_DCR_RCNT(rlen-1), &ds->regs->dcr); - - /* wait till SPIBSY is cleared */ - while (readl(&ds->regs->st) & ANDES_SPI_ST_SPIBSY) - ; - - /* data write process */ - debug("%s: txp: ", __func__); - while (wlen > 0) { - /* clear the data */ - data = 0; - - /* data are usually be read 32bits once a time */ - left = min(wlen, 4); - - for (i = 0; i < left; i++) { - debug("%x ", *txp); - data |= *txp++ << (i * 8); - wlen--; - } - debug("\n"); - - debug("data: %08x\n", data); - debug("streg before write: %08x\n", readl(&ds->regs->st)); - /* wait till TXFULL is deasserted */ - while (readl(&ds->regs->st) & ANDES_SPI_ST_TXFEL) - ; - writel(data, &ds->regs->data); - debug("streg after write: %08x\n", readl(&ds->regs->st)); - - - if (spit_enabled == 0) { - /* enable SPIT bit - trigger the tx and rx progress */ - andes_spi_spit_en(ds); - spit_enabled = 1; - } - - } - debug("\n"); - - return 0; -} - -/* - * spi_xfer: - * Since andes_spi doesn't support independent command transaction, - * that is, write and than read must be operated in continuous - * execution, there is no need to set dcr and trigger spit again in - * RX process. - */ -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - unsigned int len; - static int op_nextime; - static u8 tmp_cmd[5]; - static int tmp_wlen; - unsigned int i; - - if (bitlen == 0) - /* Finish any previously submitted transfers */ - goto out; - - if (bitlen % 8) { - /* Errors always terminate an ongoing transfer */ - flags |= SPI_XFER_END; - goto out; - } - - len = bitlen / 8; - - debug("%s: slave: %08x, bitlen: %d, dout: " - "%08x, din: %08x, flags: %d, len: %d\n", - __func__, slave, bitlen, dout, din, flags, len); - - /* - * Important: - * andes_spi's hardware doesn't support 2 data channel. The read - * and write cmd/data share the same register (data register). - * - * If a command has write and read transaction, you cannot do write - * this time and then do read on next time. - * - * A command writes first with a read response must indicating - * the read length in write operation. Hence the write action must - * be stored temporary and wait until the next read action has been - * arrived. Then we flush the write and read action out together. - */ - if (!dout) { - if (op_nextime == 1) { - /* flags should be SPI_XFER_END, value is 2 */ - op_nextime = 0; - andes_spi_write(slave, tmp_wlen, len, tmp_cmd, flags); - } - return andes_spi_read(slave, len, din, flags); - } else if (!din) { - if (flags == SPI_XFER_BEGIN) { - /* store the write command and do operation next time */ - op_nextime = 1; - memset(tmp_cmd, 0, sizeof(tmp_cmd)); - memcpy(tmp_cmd, dout, len); - - debug("%s: tmp_cmd: ", __func__); - for (i = 0; i < len; i++) - debug("%x ", *(tmp_cmd + i)); - debug("\n"); - - tmp_wlen = len; - } else { - /* - * flags should be (SPI_XFER_BEGIN | SPI_XFER_END), - * the value is 3. - */ - if (op_nextime == 1) { - /* flags should be SPI_XFER_END, value is 2 */ - op_nextime = 0; - /* flags 3 implies write only */ - andes_spi_write(slave, tmp_wlen, 0, tmp_cmd, 3); - } - - debug("flags: %x\n", flags); - return andes_spi_write(slave, len, 0, dout, flags); - } - } - -out: - return 0; -} - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - return bus == 0 && cs == 0; -} - -void spi_cs_activate(struct spi_slave *slave) -{ - /* do nothing */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - /* do nothing */ -} diff --git a/drivers/spi/andes_spi.h b/drivers/spi/andes_spi.h deleted file mode 100644 index b7d294599a1..00000000000 --- a/drivers/spi/andes_spi.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Register definitions for the Andes SPI Controller - * - * (C) Copyright 2011 Andes Technology - * Macpaul Lin <macpaul@andestech.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef __ANDES_SPI_H -#define __ANDES_SPI_H - -struct andes_spi_regs { - unsigned int apb; /* 0x00 - APB SPI interface setting */ - unsigned int pio; /* 0x04 - PIO reg */ - unsigned int cr; /* 0x08 - SPI Control reg */ - unsigned int st; /* 0x0c - SPI Status reg */ - unsigned int ie; /* 0x10 - Interrupt Enable reg */ - unsigned int ist; /* 0x14 - Interrupt Status reg */ - unsigned int dcr; /* 0x18 - data control reg */ - unsigned int data; /* 0x1c - data register */ - unsigned int ahb; /* 0x20 - AHB SPI interface setting */ - unsigned int ver; /* 0x3c - SPI version reg */ -}; - -#define BIT(x) (1 << (x)) - -/* 0x00 - APB SPI interface setting register */ -#define ANDES_SPI_APB_BAUD(x) (((x) & 0xff) < 0) -#define ANDES_SPI_APB_CSHT(x) (((x) & 0xf) < 16) -#define ANDES_SPI_APB_SPNTS BIT(20) /* 0: normal, 1: delay */ -#define ANDES_SPI_APB_CPHA BIT(24) /* 0: Sampling at odd edges */ -#define ANDES_SPI_APB_CPOL BIT(25) /* 0: SCK low, 1: SCK high */ -#define ANDES_SPI_APB_MSSL BIT(26) /* 0: SPI Master, 1: slave */ - -/* 0x04 - PIO register */ -#define ANDES_SPI_PIO_MISO BIT(0) /* input value of pin MISO */ -#define ANDES_SPI_PIO_MOSI BIT(1) /* I/O value of pin MOSI */ -#define ANDES_SPI_PIO_SCK BIT(2) /* I/O value of pin SCK */ -#define ANDES_SPI_PIO_CS BIT(3) /* I/O value of pin CS */ -#define ANDES_SPI_PIO_PIOE BIT(4) /* Programming IO Enable */ - -/* 0x08 - SPI Control register */ -#define ANDES_SPI_CR_SPIRST BIT(0) /* SPI mode reset */ -#define ANDES_SPI_CR_RXFRST BIT(1) /* RxFIFO reset */ -#define ANDES_SPI_CR_TXFRST BIT(2) /* TxFIFO reset */ -#define ANDES_SPI_CR_RXFTH(x) (((x) & 0x1f) << 10) /* RxFIFO Threshold */ -#define ANDES_SPI_CR_TXFTH(x) (((x) & 0x1f) << 18) /* TxFIFO Threshold */ - -/* 0x0c - SPI Status register */ -#define ANDES_SPI_ST_SPIBSY BIT(0) /* SPI Transfer is active */ -#define ANDES_SPI_ST_RXFEM BIT(8) /* RxFIFO Empty Flag */ -#define ANDES_SPI_ST_RXFEL BIT(9) /* RxFIFO Full Flag */ -#define ANDES_SPI_ST_RXFVE(x) (((x) >> 10) & 0x1f) -#define ANDES_SPI_ST_TXFEM BIT(16) /* TxFIFO Empty Flag */ -#define ANDES_SPI_ST_TXFEL BIT(7) /* TxFIFO Full Flag */ -#define ANDES_SPI_ST_TXFVE(x) (((x) >> 18) & 0x1f) - -/* 0x10 - Interrupt Enable register */ -#define ANDES_SPI_IE_RXFORIE BIT(0) /* RxFIFO overrun intr */ -#define ANDES_SPI_IE_TXFURIE BIT(1) /* TxFOFO underrun intr */ -#define ANDES_SPI_IE_RXFTHIE BIT(2) /* RxFIFO threshold intr */ -#define ANDES_SPI_IE_TXFTHIE BIT(3) /* TxFIFO threshold intr */ -#define ANDES_SPI_IE_SPIEIE BIT(4) /* SPI transmit END intr */ -#define ANDES_SPI_IE_SPCFIE BIT(5) /* AHB/APB TxReq conflict */ - -/* 0x14 - Interrupt Status Register */ -#define ANDES_SPI_IST_RXFORI BIT(0) /* has RxFIFO overrun */ -#define ANDES_SPI_IST_TXFURI BIT(1) /* has TxFOFO underrun */ -#define ANDES_SPI_IST_RXFTHI BIT(2) /* has RxFIFO threshold */ -#define ANDES_SPI_IST_TXFTHI BIT(3) /* has TxFIFO threshold */ -#define ANDES_SPI_IST_SPIEI BIT(4) /* has SPI transmit END */ -#define ANDES_SPI_IST_SPCFI BIT(5) /* has AHB/APB TxReq conflict */ - -/* 0x18 - Data Control Register */ -#define ANDES_SPI_DCR_RCNT(x) (((x) & 0x3ff) << 0) -#define ANDES_SPI_DCR_DYCNT(x) (((x) & 0x7) << 12) -#define ANDES_SPI_DCR_WCNT(x) (((x) & 0x3ff) << 16) -#define ANDES_SPI_DCR_TRAMODE(x) (((x) & 0x7) << 28) -#define ANDES_SPI_DCR_SPIT BIT(31) /* SPI bus trigger */ - -#define ANDES_SPI_DCR_MODE_WRCON ANDES_SPI_DCR_TRAMODE(0) /* w/r at the same time */ -#define ANDES_SPI_DCR_MODE_WO ANDES_SPI_DCR_TRAMODE(1) /* write only */ -#define ANDES_SPI_DCR_MODE_RO ANDES_SPI_DCR_TRAMODE(2) /* read only */ -#define ANDES_SPI_DCR_MODE_WR ANDES_SPI_DCR_TRAMODE(3) /* write, read */ -#define ANDES_SPI_DCR_MODE_RW ANDES_SPI_DCR_TRAMODE(4) /* read, write */ -#define ANDES_SPI_DCR_MODE_WDR ANDES_SPI_DCR_TRAMODE(5) /* write, dummy, read */ -#define ANDES_SPI_DCR_MODE_RDW ANDES_SPI_DCR_TRAMODE(6) /* read, dummy, write */ -#define ANDES_SPI_DCR_MODE_RECEIVE ANDES_SPI_DCR_TRAMODE(7) /* receive */ - -/* 0x20 - AHB SPI interface setting register */ -#define ANDES_SPI_AHB_BAUD(x) (((x) & 0xff) < 0) -#define ANDES_SPI_AHB_CSHT(x) (((x) & 0xf) < 16) -#define ANDES_SPI_AHB_SPNTS BIT(20) /* 0: normal, 1: delay */ -#define ANDES_SPI_AHB_CPHA BIT(24) /* 0: Sampling at odd edges */ -#define ANDES_SPI_AHB_CPOL BIT(25) /* 0: SCK low, 1: SCK high */ -#define ANDES_SPI_AHB_MSSL BIT(26) /* only Master mode */ - -/* 0x3c - Version Register - (Year V.MAJOR.MINOR) */ -#define ANDES_SPI_VER_MINOR(x) (((x) >> 0) & 0xf) -#define ANDES_SPI_VER_MAJOR(x) (((x) >> 8) & 0xf) -#define ANDES_SPI_VER_YEAR(x) (((x) >> 16) & 0xf) - -struct andes_spi_slave { - struct spi_slave slave; - struct andes_spi_regs *regs; - unsigned int freq; -}; - -static inline struct andes_spi_slave *to_andes_spi(struct spi_slave *slave) -{ - return container_of(slave, struct andes_spi_slave, slave); -} - -#endif /* __ANDES_SPI_H */ diff --git a/drivers/spi/cf_qspi.c b/drivers/spi/cf_qspi.c index 834c5bd259d..e57e63eb47a 100644 --- a/drivers/spi/cf_qspi.c +++ b/drivers/spi/cf_qspi.c @@ -19,7 +19,6 @@ DECLARE_GLOBAL_DATA_PTR; -#define clamp(x, low, high) (min(max(low, x), high)) #define to_cf_qspi_slave(s) container_of(s, struct cf_qspi_slave, slave) struct cf_qspi_slave { @@ -120,7 +119,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, dev->qmr = 2u; else /* Get the closest baud rate */ dev->qmr = clamp(((gd->bus_clk >> 2) + max_hz - 1)/max_hz, - 2u, 255u); + 2lu, 255lu); /* Map mode to QMR[CPOL] and QMR[CPHA] */ if (mode & SPI_CPOL) diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index bf18362baaf..0a036ccb009 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -8,116 +8,122 @@ * * SPDX-License-Identifier: GPL-2.0+ */ + #include <common.h> #include <spi.h> #include <malloc.h> #include <asm/io.h> #include <asm/arch/hardware.h> -#include "davinci_spi.h" -void spi_init() -{ - /* do nothing */ -} +#define BIT(x) (1 << (x)) -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) -{ - struct davinci_spi_slave *ds; +/* SPIGCR0 */ +#define SPIGCR0_SPIENA_MASK 0x1 +#define SPIGCR0_SPIRST_MASK 0x0 - if (!spi_cs_is_valid(bus, cs)) - return NULL; +/* SPIGCR0 */ +#define SPIGCR1_CLKMOD_MASK BIT(1) +#define SPIGCR1_MASTER_MASK BIT(0) +#define SPIGCR1_SPIENA_MASK BIT(24) - ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs); - if (!ds) - return NULL; +/* SPIPC0 */ +#define SPIPC0_DIFUN_MASK BIT(11) /* SIMO */ +#define SPIPC0_DOFUN_MASK BIT(10) /* SOMI */ +#define SPIPC0_CLKFUN_MASK BIT(9) /* CLK */ +#define SPIPC0_EN0FUN_MASK BIT(0) - switch (bus) { - case SPI0_BUS: - ds->regs = (struct davinci_spi_regs *)SPI0_BASE; - break; -#ifdef CONFIG_SYS_SPI1 - case SPI1_BUS: - ds->regs = (struct davinci_spi_regs *)SPI1_BASE; - break; -#endif -#ifdef CONFIG_SYS_SPI2 - case SPI2_BUS: - ds->regs = (struct davinci_spi_regs *)SPI2_BASE; - break; -#endif - default: /* Invalid bus number */ - return NULL; - } +/* SPIFMT0 */ +#define SPIFMT_SHIFTDIR_SHIFT 20 +#define SPIFMT_POLARITY_SHIFT 17 +#define SPIFMT_PHASE_SHIFT 16 +#define SPIFMT_PRESCALE_SHIFT 8 - ds->freq = max_hz; +/* SPIDAT1 */ +#define SPIDAT1_CSHOLD_SHIFT 28 +#define SPIDAT1_CSNR_SHIFT 16 - return &ds->slave; -} +/* SPIDELAY */ +#define SPI_C2TDELAY_SHIFT 24 +#define SPI_T2CDELAY_SHIFT 16 -void spi_free_slave(struct spi_slave *slave) -{ - struct davinci_spi_slave *ds = to_davinci_spi(slave); +/* SPIBUF */ +#define SPIBUF_RXEMPTY_MASK BIT(31) +#define SPIBUF_TXFULL_MASK BIT(29) - free(ds); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct davinci_spi_slave *ds = to_davinci_spi(slave); - unsigned int scalar; - - /* Enable the SPI hardware */ - writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); - udelay(1000); - writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0); +/* SPIDEF */ +#define SPIDEF_CSDEF0_MASK BIT(0) - /* Set master mode, powered up and not activated */ - writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1); - - /* CS, CLK, SIMO and SOMI are functional pins */ - writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK | - SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0); - - /* setup format */ - scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF; - - /* - * Use following format: - * character length = 8, - * clock signal delayed by half clk cycle, - * clock low in idle state - Mode 0, - * MSB shifted out first - */ - writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) | - (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0); - - /* - * Including a minor delay. No science here. Should be good even with - * no delay - */ - writel((50 << SPI_C2TDELAY_SHIFT) | - (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay); - - /* default chip select register */ - writel(SPIDEF_CSDEF0_MASK, &ds->regs->def); - - /* no interrupts */ - writel(0, &ds->regs->int0); - writel(0, &ds->regs->lvl); +#define SPI0_BUS 0 +#define SPI0_BASE CONFIG_SYS_SPI_BASE +/* + * Define default SPI0_NUM_CS as 1 for existing platforms that uses this + * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS + * if more than one CS is supported and by defining CONFIG_SYS_SPI0. + */ +#ifndef CONFIG_SYS_SPI0 +#define SPI0_NUM_CS 1 +#else +#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS +#endif - /* enable SPI */ - writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1); +/* + * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and + * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus + */ +#ifdef CONFIG_SYS_SPI1 +#define SPI1_BUS 1 +#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS +#define SPI1_BASE CONFIG_SYS_SPI1_BASE +#endif - return 0; -} +/* + * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and + * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus + */ +#ifdef CONFIG_SYS_SPI2 +#define SPI2_BUS 2 +#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS +#define SPI2_BASE CONFIG_SYS_SPI2_BASE +#endif -void spi_release_bus(struct spi_slave *slave) +/* davinci spi register set */ +struct davinci_spi_regs { + dv_reg gcr0; /* 0x00 */ + dv_reg gcr1; /* 0x04 */ + dv_reg int0; /* 0x08 */ + dv_reg lvl; /* 0x0c */ + dv_reg flg; /* 0x10 */ + dv_reg pc0; /* 0x14 */ + dv_reg pc1; /* 0x18 */ + dv_reg pc2; /* 0x1c */ + dv_reg pc3; /* 0x20 */ + dv_reg pc4; /* 0x24 */ + dv_reg pc5; /* 0x28 */ + dv_reg rsvd[3]; + dv_reg dat0; /* 0x38 */ + dv_reg dat1; /* 0x3c */ + dv_reg buf; /* 0x40 */ + dv_reg emu; /* 0x44 */ + dv_reg delay; /* 0x48 */ + dv_reg def; /* 0x4c */ + dv_reg fmt0; /* 0x50 */ + dv_reg fmt1; /* 0x54 */ + dv_reg fmt2; /* 0x58 */ + dv_reg fmt3; /* 0x5c */ + dv_reg intvec0; /* 0x60 */ + dv_reg intvec1; /* 0x64 */ +}; + +/* davinci spi slave */ +struct davinci_spi_slave { + struct spi_slave slave; + struct davinci_spi_regs *regs; + unsigned int freq; +}; + +static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave) { - struct davinci_spi_slave *ds = to_davinci_spi(slave); - - /* Disable the SPI hardware */ - writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); + return container_of(slave, struct davinci_spi_slave, slave); } /* @@ -235,6 +241,149 @@ static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len, } #endif +int spi_cs_is_valid(unsigned int bus, unsigned int cs) +{ + int ret = 0; + + switch (bus) { + case SPI0_BUS: + if (cs < SPI0_NUM_CS) + ret = 1; + break; +#ifdef CONFIG_SYS_SPI1 + case SPI1_BUS: + if (cs < SPI1_NUM_CS) + ret = 1; + break; +#endif +#ifdef CONFIG_SYS_SPI2 + case SPI2_BUS: + if (cs < SPI2_NUM_CS) + ret = 1; + break; +#endif + default: + /* Invalid bus number. Do nothing */ + break; + } + return ret; +} + +void spi_cs_activate(struct spi_slave *slave) +{ + /* do nothing */ +} + +void spi_cs_deactivate(struct spi_slave *slave) +{ + /* do nothing */ +} + +void spi_init(void) +{ + /* do nothing */ +} + +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, + unsigned int max_hz, unsigned int mode) +{ + struct davinci_spi_slave *ds; + + if (!spi_cs_is_valid(bus, cs)) + return NULL; + + ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs); + if (!ds) + return NULL; + + switch (bus) { + case SPI0_BUS: + ds->regs = (struct davinci_spi_regs *)SPI0_BASE; + break; +#ifdef CONFIG_SYS_SPI1 + case SPI1_BUS: + ds->regs = (struct davinci_spi_regs *)SPI1_BASE; + break; +#endif +#ifdef CONFIG_SYS_SPI2 + case SPI2_BUS: + ds->regs = (struct davinci_spi_regs *)SPI2_BASE; + break; +#endif + default: /* Invalid bus number */ + return NULL; + } + + ds->freq = max_hz; + + return &ds->slave; +} + +void spi_free_slave(struct spi_slave *slave) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + + free(ds); +} + +int spi_claim_bus(struct spi_slave *slave) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + unsigned int scalar; + + /* Enable the SPI hardware */ + writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); + udelay(1000); + writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0); + + /* Set master mode, powered up and not activated */ + writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1); + + /* CS, CLK, SIMO and SOMI are functional pins */ + writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK | + SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0); + + /* setup format */ + scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF; + + /* + * Use following format: + * character length = 8, + * clock signal delayed by half clk cycle, + * clock low in idle state - Mode 0, + * MSB shifted out first + */ + writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) | + (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0); + + /* + * Including a minor delay. No science here. Should be good even with + * no delay + */ + writel((50 << SPI_C2TDELAY_SHIFT) | + (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay); + + /* default chip select register */ + writel(SPIDEF_CSDEF0_MASK, &ds->regs->def); + + /* no interrupts */ + writel(0, &ds->regs->int0); + writel(0, &ds->regs->lvl); + + /* enable SPI */ + writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1); + + return 0; +} + +void spi_release_bus(struct spi_slave *slave) +{ + struct davinci_spi_slave *ds = to_davinci_spi(slave); + + /* Disable the SPI hardware */ + writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0); +} + int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, void *din, unsigned long flags) { @@ -278,41 +427,3 @@ out: } return 0; } - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - int ret = 0; - - switch (bus) { - case SPI0_BUS: - if (cs < SPI0_NUM_CS) - ret = 1; - break; -#ifdef CONFIG_SYS_SPI1 - case SPI1_BUS: - if (cs < SPI1_NUM_CS) - ret = 1; - break; -#endif -#ifdef CONFIG_SYS_SPI2 - case SPI2_BUS: - if (cs < SPI2_NUM_CS) - ret = 1; - break; -#endif - default: - /* Invalid bus number. Do nothing */ - break; - } - return ret; -} - -void spi_cs_activate(struct spi_slave *slave) -{ - /* do nothing */ -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - /* do nothing */ -} diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h deleted file mode 100644 index d4612d3527e..00000000000 --- a/drivers/spi/davinci_spi.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ - * - * Register definitions for the DaVinci SPI Controller - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _DAVINCI_SPI_H_ -#define _DAVINCI_SPI_H_ - -struct davinci_spi_regs { - dv_reg gcr0; /* 0x00 */ - dv_reg gcr1; /* 0x04 */ - dv_reg int0; /* 0x08 */ - dv_reg lvl; /* 0x0c */ - dv_reg flg; /* 0x10 */ - dv_reg pc0; /* 0x14 */ - dv_reg pc1; /* 0x18 */ - dv_reg pc2; /* 0x1c */ - dv_reg pc3; /* 0x20 */ - dv_reg pc4; /* 0x24 */ - dv_reg pc5; /* 0x28 */ - dv_reg rsvd[3]; - dv_reg dat0; /* 0x38 */ - dv_reg dat1; /* 0x3c */ - dv_reg buf; /* 0x40 */ - dv_reg emu; /* 0x44 */ - dv_reg delay; /* 0x48 */ - dv_reg def; /* 0x4c */ - dv_reg fmt0; /* 0x50 */ - dv_reg fmt1; /* 0x54 */ - dv_reg fmt2; /* 0x58 */ - dv_reg fmt3; /* 0x5c */ - dv_reg intvec0; /* 0x60 */ - dv_reg intvec1; /* 0x64 */ -}; - -#define BIT(x) (1 << (x)) - -/* SPIGCR0 */ -#define SPIGCR0_SPIENA_MASK 0x1 -#define SPIGCR0_SPIRST_MASK 0x0 - -/* SPIGCR0 */ -#define SPIGCR1_CLKMOD_MASK BIT(1) -#define SPIGCR1_MASTER_MASK BIT(0) -#define SPIGCR1_SPIENA_MASK BIT(24) - -/* SPIPC0 */ -#define SPIPC0_DIFUN_MASK BIT(11) /* SIMO */ -#define SPIPC0_DOFUN_MASK BIT(10) /* SOMI */ -#define SPIPC0_CLKFUN_MASK BIT(9) /* CLK */ -#define SPIPC0_EN0FUN_MASK BIT(0) - -/* SPIFMT0 */ -#define SPIFMT_SHIFTDIR_SHIFT 20 -#define SPIFMT_POLARITY_SHIFT 17 -#define SPIFMT_PHASE_SHIFT 16 -#define SPIFMT_PRESCALE_SHIFT 8 - -/* SPIDAT1 */ -#define SPIDAT1_CSHOLD_SHIFT 28 -#define SPIDAT1_CSNR_SHIFT 16 - -/* SPIDELAY */ -#define SPI_C2TDELAY_SHIFT 24 -#define SPI_T2CDELAY_SHIFT 16 - -/* SPIBUF */ -#define SPIBUF_RXEMPTY_MASK BIT(31) -#define SPIBUF_TXFULL_MASK BIT(29) - -/* SPIDEF */ -#define SPIDEF_CSDEF0_MASK BIT(0) - -#define SPI0_BUS 0 -#define SPI0_BASE CONFIG_SYS_SPI_BASE -/* - * Define default SPI0_NUM_CS as 1 for existing platforms that uses this - * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS - * if more than one CS is supported and by defining CONFIG_SYS_SPI0. - */ -#ifndef CONFIG_SYS_SPI0 -#define SPI0_NUM_CS 1 -#else -#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS -#endif - -/* - * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and - * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus - */ -#ifdef CONFIG_SYS_SPI1 -#define SPI1_BUS 1 -#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS -#define SPI1_BASE CONFIG_SYS_SPI1_BASE -#endif - -/* - * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and - * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus - */ -#ifdef CONFIG_SYS_SPI2 -#define SPI2_BUS 2 -#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS -#define SPI2_BASE CONFIG_SYS_SPI2_BASE -#endif - -struct davinci_spi_slave { - struct spi_slave slave; - struct davinci_spi_regs *regs; - unsigned int freq; -}; - -static inline struct davinci_spi_slave *to_davinci_spi(struct spi_slave *slave) -{ - return container_of(slave, struct davinci_spi_slave, slave); -} - -#endif /* _DAVINCI_SPI_H_ */ diff --git a/drivers/spi/ftssp010_spi.c b/drivers/spi/ftssp010_spi.c deleted file mode 100644 index c7d64804780..00000000000 --- a/drivers/spi/ftssp010_spi.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * (C) Copyright 2013 - * Faraday Technology Corporation. <http://www.faraday-tech.com/tw/> - * Kuo-Jung Su <dantesu@gmail.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/compat.h> -#include <asm/io.h> -#include <malloc.h> -#include <spi.h> - -#ifndef CONFIG_FTSSP010_BASE_LIST -#define CONFIG_FTSSP010_BASE_LIST { CONFIG_FTSSP010_BASE } -#endif - -#ifndef CONFIG_FTSSP010_GPIO_BASE -#define CONFIG_FTSSP010_GPIO_BASE 0 -#endif - -#ifndef CONFIG_FTSSP010_GPIO_LIST -#define CONFIG_FTSSP010_GPIO_LIST { CONFIG_FTSSP010_GPIO_BASE } -#endif - -#ifndef CONFIG_FTSSP010_CLOCK -#define CONFIG_FTSSP010_CLOCK clk_get_rate("SSP"); -#endif - -#ifndef CONFIG_FTSSP010_TIMEOUT -#define CONFIG_FTSSP010_TIMEOUT 100 -#endif - -/* FTSSP010 chip registers */ -struct ftssp010_regs { - uint32_t cr[3];/* control register */ - uint32_t sr; /* status register */ - uint32_t icr; /* interrupt control register */ - uint32_t isr; /* interrupt status register */ - uint32_t dr; /* data register */ - uint32_t rsvd[17]; - uint32_t revr; /* revision register */ - uint32_t fear; /* feature register */ -}; - -/* Control Register 0 */ -#define CR0_FFMT_MASK (7 << 12) -#define CR0_FFMT_SSP (0 << 12) -#define CR0_FFMT_SPI (1 << 12) -#define CR0_FFMT_MICROWIRE (2 << 12) -#define CR0_FFMT_I2S (3 << 12) -#define CR0_FFMT_AC97 (4 << 12) -#define CR0_FLASH (1 << 11) -#define CR0_FSDIST(x) (((x) & 0x03) << 8) -#define CR0_LOOP (1 << 7) /* loopback mode */ -#define CR0_LSB (1 << 6) /* LSB */ -#define CR0_FSPO (1 << 5) /* fs atcive low (I2S only) */ -#define CR0_FSJUSTIFY (1 << 4) -#define CR0_OPM_SLAVE (0 << 2) -#define CR0_OPM_MASTER (3 << 2) -#define CR0_OPM_I2S_MSST (3 << 2) /* master stereo mode */ -#define CR0_OPM_I2S_MSMO (2 << 2) /* master mono mode */ -#define CR0_OPM_I2S_SLST (1 << 2) /* slave stereo mode */ -#define CR0_OPM_I2S_SLMO (0 << 2) /* slave mono mode */ -#define CR0_SCLKPO (1 << 1) /* clock polarity */ -#define CR0_SCLKPH (1 << 0) /* clock phase */ - -/* Control Register 1 */ -#define CR1_PDL(x) (((x) & 0xff) << 24) /* padding length */ -#define CR1_SDL(x) ((((x) - 1) & 0x1f) << 16) /* data length */ -#define CR1_DIV(x) (((x) - 1) & 0xffff) /* clock divider */ - -/* Control Register 2 */ -#define CR2_CS(x) (((x) & 3) << 10) /* CS/FS select */ -#define CR2_FS (1 << 9) /* CS/FS signal level */ -#define CR2_TXEN (1 << 8) /* tx enable */ -#define CR2_RXEN (1 << 7) /* rx enable */ -#define CR2_RESET (1 << 6) /* chip reset */ -#define CR2_TXFC (1 << 3) /* tx fifo Clear */ -#define CR2_RXFC (1 << 2) /* rx fifo Clear */ -#define CR2_TXDOE (1 << 1) /* tx data output enable */ -#define CR2_EN (1 << 0) /* chip enable */ - -/* Status Register */ -#define SR_RFF (1 << 0) /* rx fifo full */ -#define SR_TFNF (1 << 1) /* tx fifo not full */ -#define SR_BUSY (1 << 2) /* chip busy */ -#define SR_RFVE(reg) (((reg) >> 4) & 0x1f) /* rx fifo valid entries */ -#define SR_TFVE(reg) (((reg) >> 12) & 0x1f) /* tx fifo valid entries */ - -/* Feature Register */ -#define FEAR_BITS(reg) ((((reg) >> 0) & 0xff) + 1) /* data width */ -#define FEAR_RFSZ(reg) ((((reg) >> 8) & 0xff) + 1) /* rx fifo size */ -#define FEAR_TFSZ(reg) ((((reg) >> 16) & 0xff) + 1) /* tx fifo size */ -#define FEAR_AC97 (1 << 24) -#define FEAR_I2S (1 << 25) -#define FEAR_SPI_MWR (1 << 26) -#define FEAR_SSP (1 << 27) -#define FEAR_SPDIF (1 << 28) - -/* FTGPIO010 chip registers */ -struct ftgpio010_regs { - uint32_t out; /* 0x00: Data Output */ - uint32_t in; /* 0x04: Data Input */ - uint32_t dir; /* 0x08: Direction */ - uint32_t bypass; /* 0x0c: Bypass */ - uint32_t set; /* 0x10: Data Set */ - uint32_t clr; /* 0x14: Data Clear */ - uint32_t pull_up; /* 0x18: Pull-Up Enabled */ - uint32_t pull_st; /* 0x1c: Pull State (0=pull-down, 1=pull-up) */ -}; - -struct ftssp010_gpio { - struct ftgpio010_regs *regs; - uint32_t pin; -}; - -struct ftssp010_spi { - struct spi_slave slave; - struct ftssp010_gpio gpio; - struct ftssp010_regs *regs; - uint32_t fifo; - uint32_t mode; - uint32_t div; - uint32_t clk; - uint32_t speed; - uint32_t revision; -}; - -static inline struct ftssp010_spi *to_ftssp010_spi(struct spi_slave *slave) -{ - return container_of(slave, struct ftssp010_spi, slave); -} - -static int get_spi_chip(int bus, struct ftssp010_spi *chip) -{ - uint32_t fear, base[] = CONFIG_FTSSP010_BASE_LIST; - - if (bus >= ARRAY_SIZE(base) || !base[bus]) - return -1; - - chip->regs = (struct ftssp010_regs *)base[bus]; - - chip->revision = readl(&chip->regs->revr); - - fear = readl(&chip->regs->fear); - chip->fifo = min_t(uint32_t, FEAR_TFSZ(fear), FEAR_RFSZ(fear)); - - return 0; -} - -static int get_spi_gpio(int bus, struct ftssp010_gpio *chip) -{ - uint32_t base[] = CONFIG_FTSSP010_GPIO_LIST; - - if (bus >= ARRAY_SIZE(base) || !base[bus]) - return -1; - - chip->regs = (struct ftgpio010_regs *)(base[bus] & 0xfff00000); - chip->pin = base[bus] & 0x1f; - - /* make it an output pin */ - setbits_le32(&chip->regs->dir, 1 << chip->pin); - - return 0; -} - -static int ftssp010_wait(struct ftssp010_spi *chip) -{ - struct ftssp010_regs *regs = chip->regs; - ulong t; - - /* wait until device idle */ - for (t = get_timer(0); get_timer(t) < CONFIG_FTSSP010_TIMEOUT; ) { - if (!(readl(®s->sr) & SR_BUSY)) - return 0; - } - - puts("ftspi010: busy timeout\n"); - - return -1; -} - -static int ftssp010_wait_tx(struct ftssp010_spi *chip) -{ - struct ftssp010_regs *regs = chip->regs; - ulong t; - - /* wait until tx fifo not full */ - for (t = get_timer(0); get_timer(t) < CONFIG_FTSSP010_TIMEOUT; ) { - if (readl(®s->sr) & SR_TFNF) - return 0; - } - - puts("ftssp010: tx timeout\n"); - - return -1; -} - -static int ftssp010_wait_rx(struct ftssp010_spi *chip) -{ - struct ftssp010_regs *regs = chip->regs; - ulong t; - - /* wait until rx fifo not empty */ - for (t = get_timer(0); get_timer(t) < CONFIG_FTSSP010_TIMEOUT; ) { - if (SR_RFVE(readl(®s->sr))) - return 0; - } - - puts("ftssp010: rx timeout\n"); - - return -1; -} - -static int ftssp010_spi_work_transfer_v2(struct ftssp010_spi *chip, - const void *tx_buf, void *rx_buf, int len, uint flags) -{ - struct ftssp010_regs *regs = chip->regs; - const uint8_t *txb = tx_buf; - uint8_t *rxb = rx_buf; - - while (len > 0) { - int i, depth = min(chip->fifo >> 2, len); - uint32_t xmsk = 0; - - if (tx_buf) { - for (i = 0; i < depth; ++i) { - ftssp010_wait_tx(chip); - writel(*txb++, ®s->dr); - } - xmsk |= CR2_TXEN | CR2_TXDOE; - if ((readl(®s->cr[2]) & xmsk) != xmsk) - setbits_le32(®s->cr[2], xmsk); - } - if (rx_buf) { - xmsk |= CR2_RXEN; - if ((readl(®s->cr[2]) & xmsk) != xmsk) - setbits_le32(®s->cr[2], xmsk); - for (i = 0; i < depth; ++i) { - ftssp010_wait_rx(chip); - *rxb++ = (uint8_t)readl(®s->dr); - } - } - - len -= depth; - } - - return 0; -} - -static int ftssp010_spi_work_transfer_v1(struct ftssp010_spi *chip, - const void *tx_buf, void *rx_buf, int len, uint flags) -{ - struct ftssp010_regs *regs = chip->regs; - const uint8_t *txb = tx_buf; - uint8_t *rxb = rx_buf; - - while (len > 0) { - int i, depth = min(chip->fifo >> 2, len); - uint32_t tmp; - - for (i = 0; i < depth; ++i) { - ftssp010_wait_tx(chip); - writel(txb ? (*txb++) : 0, ®s->dr); - } - for (i = 0; i < depth; ++i) { - ftssp010_wait_rx(chip); - tmp = readl(®s->dr); - if (rxb) - *rxb++ = (uint8_t)tmp; - } - - len -= depth; - } - - return 0; -} - -static void ftssp010_cs_set(struct ftssp010_spi *chip, int high) -{ - struct ftssp010_regs *regs = chip->regs; - struct ftssp010_gpio *gpio = &chip->gpio; - uint32_t mask; - - /* cs pull high/low */ - if (chip->revision >= 0x11900) { - mask = CR2_CS(chip->slave.cs) | (high ? CR2_FS : 0); - writel(mask, ®s->cr[2]); - } else if (gpio->regs) { - mask = 1 << gpio->pin; - if (high) - writel(mask, &gpio->regs->set); - else - writel(mask, &gpio->regs->clr); - } - - /* extra delay for signal propagation */ - udelay_masked(1); -} - -/* - * Determine if a SPI chipselect is valid. - * This function is provided by the board if the low-level SPI driver - * needs it to determine if a given chipselect is actually valid. - * - * Returns: 1 if bus:cs identifies a valid chip on this board, 0 - * otherwise. - */ -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - struct ftssp010_spi chip; - - if (get_spi_chip(bus, &chip)) - return 0; - - if (!cs) - return 1; - else if ((cs < 4) && (chip.revision >= 0x11900)) - return 1; - - return 0; -} - -/* - * Activate a SPI chipselect. - * This function is provided by the board code when using a driver - * that can't control its chipselects automatically (e.g. - * common/soft_spi.c). When called, it should activate the chip select - * to the device identified by "slave". - */ -void spi_cs_activate(struct spi_slave *slave) -{ - struct ftssp010_spi *chip = to_ftssp010_spi(slave); - struct ftssp010_regs *regs = chip->regs; - - /* cs pull */ - if (chip->mode & SPI_CS_HIGH) - ftssp010_cs_set(chip, 1); - else - ftssp010_cs_set(chip, 0); - - /* chip enable + fifo clear */ - setbits_le32(®s->cr[2], CR2_EN | CR2_TXFC | CR2_RXFC); -} - -/* - * Deactivate a SPI chipselect. - * This function is provided by the board code when using a driver - * that can't control its chipselects automatically (e.g. - * common/soft_spi.c). When called, it should deactivate the chip - * select to the device identified by "slave". - */ -void spi_cs_deactivate(struct spi_slave *slave) -{ - struct ftssp010_spi *chip = to_ftssp010_spi(slave); - - /* wait until chip idle */ - ftssp010_wait(chip); - - /* cs pull */ - if (chip->mode & SPI_CS_HIGH) - ftssp010_cs_set(chip, 0); - else - ftssp010_cs_set(chip, 1); -} - -void spi_init(void) -{ - /* nothing to do */ -} - -struct spi_slave *spi_setup_slave(uint bus, uint cs, uint max_hz, uint mode) -{ - struct ftssp010_spi *chip; - - if (mode & SPI_3WIRE) { - puts("ftssp010: can't do 3-wire\n"); - return NULL; - } - - if (mode & SPI_SLAVE) { - puts("ftssp010: can't do slave mode\n"); - return NULL; - } - - if (mode & SPI_PREAMBLE) { - puts("ftssp010: can't skip preamble bytes\n"); - return NULL; - } - - if (!spi_cs_is_valid(bus, cs)) { - puts("ftssp010: invalid (bus, cs)\n"); - return NULL; - } - - chip = spi_alloc_slave(struct ftssp010_spi, bus, cs); - if (!chip) - return NULL; - - if (get_spi_chip(bus, chip)) - goto free_out; - - if (chip->revision < 0x11900 && get_spi_gpio(bus, &chip->gpio)) { - puts("ftssp010: Before revision 1.19.0, its clock & cs are\n" - "controlled by tx engine which is not synced with rx engine,\n" - "so the clock & cs might be shutdown before rx engine\n" - "finishs its jobs.\n" - "If possible, please add a dedicated gpio for it.\n"); - } - - chip->mode = mode; - chip->clk = CONFIG_FTSSP010_CLOCK; - chip->div = 2; - if (max_hz) { - while (chip->div < 0xffff) { - if ((chip->clk / (2 * chip->div)) <= max_hz) - break; - chip->div += 1; - } - } - chip->speed = chip->clk / (2 * chip->div); - - return &chip->slave; - -free_out: - free(chip); - return NULL; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct ftssp010_spi *chip = to_ftssp010_spi(slave); - - free(chip); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct ftssp010_spi *chip = to_ftssp010_spi(slave); - struct ftssp010_regs *regs = chip->regs; - - writel(CR1_SDL(8) | CR1_DIV(chip->div), ®s->cr[1]); - - if (chip->revision >= 0x11900) { - writel(CR0_OPM_MASTER | CR0_FFMT_SPI | CR0_FSPO | CR0_FLASH, - ®s->cr[0]); - writel(CR2_TXFC | CR2_RXFC, - ®s->cr[2]); - } else { - writel(CR0_OPM_MASTER | CR0_FFMT_SPI | CR0_FSPO, - ®s->cr[0]); - writel(CR2_TXFC | CR2_RXFC | CR2_EN | CR2_TXDOE, - ®s->cr[2]); - } - - if (chip->mode & SPI_LOOP) - setbits_le32(®s->cr[0], CR0_LOOP); - - if (chip->mode & SPI_CPOL) - setbits_le32(®s->cr[0], CR0_SCLKPO); - - if (chip->mode & SPI_CPHA) - setbits_le32(®s->cr[0], CR0_SCLKPH); - - spi_cs_deactivate(slave); - - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - struct ftssp010_spi *chip = to_ftssp010_spi(slave); - struct ftssp010_regs *regs = chip->regs; - - writel(0, ®s->cr[2]); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, - const void *dout, void *din, unsigned long flags) -{ - struct ftssp010_spi *chip = to_ftssp010_spi(slave); - uint32_t len = bitlen >> 3; - - if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); - - if (chip->revision >= 0x11900) - ftssp010_spi_work_transfer_v2(chip, dout, din, len, flags); - else - ftssp010_spi_work_transfer_v1(chip, dout, din, len, flags); - - if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); - - return 0; -} diff --git a/drivers/spi/oc_tiny_spi.c b/drivers/spi/oc_tiny_spi.c deleted file mode 100644 index 4de5d008aaf..00000000000 --- a/drivers/spi/oc_tiny_spi.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Opencore tiny_spi driver - * - * http://opencores.org/project,tiny_spi - * - * based on bfin_spi.c - * Copyright (c) 2005-2008 Analog Devices Inc. - * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <malloc.h> -#include <spi.h> -#include <asm/gpio.h> - -#define TINY_SPI_STATUS_TXE 0x1 -#define TINY_SPI_STATUS_TXR 0x2 - -struct tiny_spi_regs { - unsigned rxdata; /* Rx data reg */ - unsigned txdata; /* Tx data reg */ - unsigned status; /* Status reg */ - unsigned control; /* Control reg */ - unsigned baud; /* Baud reg */ -}; - -struct tiny_spi_host { - uint base; - uint freq; - uint baudwidth; -}; -static const struct tiny_spi_host tiny_spi_host_list[] = - CONFIG_SYS_TINY_SPI_LIST; - -struct tiny_spi_slave { - struct spi_slave slave; - const struct tiny_spi_host *host; - uint mode; - uint baud; - uint flg; -}; -#define to_tiny_spi_slave(s) container_of(s, struct tiny_spi_slave, slave) - -int spi_cs_is_valid(unsigned int bus, unsigned int cs) -{ - return bus < ARRAY_SIZE(tiny_spi_host_list) && gpio_is_valid(cs); -} - -void spi_cs_activate(struct spi_slave *slave) -{ - struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave); - unsigned int cs = slave->cs; - - gpio_set_value(cs, tiny_spi->flg); - debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs)); -} - -void spi_cs_deactivate(struct spi_slave *slave) -{ - struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave); - unsigned int cs = slave->cs; - - gpio_set_value(cs, !tiny_spi->flg); - debug("%s: SPI_CS_GPIO:%x\n", __func__, gpio_get_value(cs)); -} - -void spi_set_speed(struct spi_slave *slave, uint hz) -{ - struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave); - const struct tiny_spi_host *host = tiny_spi->host; - - tiny_spi->baud = min(DIV_ROUND_UP(host->freq, hz * 2), - (1 << host->baudwidth)) - 1; - debug("%s: speed %u actual %u\n", __func__, hz, - host->freq / ((tiny_spi->baud + 1) * 2)); -} - -void spi_init(void) -{ -} - -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int hz, unsigned int mode) -{ - struct tiny_spi_slave *tiny_spi; - - if (!spi_cs_is_valid(bus, cs) || gpio_request(cs, "tiny_spi")) - return NULL; - - tiny_spi = spi_alloc_slave(struct tiny_spi_slave, bus, cs); - if (!tiny_spi) - return NULL; - - tiny_spi->host = &tiny_spi_host_list[bus]; - tiny_spi->mode = mode & (SPI_CPOL | SPI_CPHA); - tiny_spi->flg = mode & SPI_CS_HIGH ? 1 : 0; - spi_set_speed(&tiny_spi->slave, hz); - - debug("%s: bus:%i cs:%i base:%lx\n", __func__, - bus, cs, tiny_spi->host->base); - return &tiny_spi->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave); - - gpio_free(slave->cs); - free(tiny_spi); -} - -int spi_claim_bus(struct spi_slave *slave) -{ - struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave); - struct tiny_spi_regs *regs = (void *)tiny_spi->host->base; - - debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); - gpio_direction_output(slave->cs, !tiny_spi->flg); - writel(tiny_spi->mode, ®s->control); - writel(tiny_spi->baud, ®s->baud); - return 0; -} - -void spi_release_bus(struct spi_slave *slave) -{ - debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); -} - -#ifndef CONFIG_TINY_SPI_IDLE_VAL -# define CONFIG_TINY_SPI_IDLE_VAL 0xff -#endif - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) -{ - struct tiny_spi_slave *tiny_spi = to_tiny_spi_slave(slave); - struct tiny_spi_regs *regs = (void *)tiny_spi->host->base; - const u8 *txp = dout; - u8 *rxp = din; - uint bytes = bitlen / 8; - uint i; - - 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; - - /* assume to do 8 bits transfers */ - if (bitlen % 8) { - flags |= SPI_XFER_END; - goto done; - } - - if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); - - /* we need to tighten the transfer loop */ - if (txp && rxp) { - writeb(*txp++, ®s->txdata); - if (bytes > 1) { - writeb(*txp++, ®s->txdata); - for (i = 2; i < bytes; i++) { - u8 rx, tx = *txp++; - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXR)) - ; - rx = readb(®s->txdata); - writeb(tx, ®s->txdata); - *rxp++ = rx; - } - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXR)) - ; - *rxp++ = readb(®s->txdata); - } - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXE)) - ; - *rxp++ = readb(®s->rxdata); - } else if (rxp) { - writeb(CONFIG_TINY_SPI_IDLE_VAL, ®s->txdata); - if (bytes > 1) { - writeb(CONFIG_TINY_SPI_IDLE_VAL, - ®s->txdata); - for (i = 2; i < bytes; i++) { - u8 rx; - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXR)) - ; - rx = readb(®s->txdata); - writeb(CONFIG_TINY_SPI_IDLE_VAL, - ®s->txdata); - *rxp++ = rx; - } - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXR)) - ; - *rxp++ = readb(®s->txdata); - } - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXE)) - ; - *rxp++ = readb(®s->rxdata); - } else if (txp) { - writeb(*txp++, ®s->txdata); - if (bytes > 1) { - writeb(*txp++, ®s->txdata); - for (i = 2; i < bytes; i++) { - u8 tx = *txp++; - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXR)) - ; - writeb(tx, ®s->txdata); - } - } - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXE)) - ; - } else { - writeb(CONFIG_TINY_SPI_IDLE_VAL, ®s->txdata); - if (bytes > 1) { - writeb(CONFIG_TINY_SPI_IDLE_VAL, - ®s->txdata); - for (i = 2; i < bytes; i++) { - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXR)) - ; - writeb(CONFIG_TINY_SPI_IDLE_VAL, - ®s->txdata); - } - } - while (!(readb(®s->status) & - TINY_SPI_STATUS_TXE)) - ; - } - - done: - if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); - - return 0; -} diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c index 56d99d17c7d..6c21acda576 100644 --- a/drivers/spi/xilinx_spi.c +++ b/drivers/spi/xilinx_spi.c @@ -1,149 +1,175 @@ /* * Xilinx SPI driver * - * supports 8 bit SPI transfers only, with or w/o FIFO + * 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> + * Based on bfin_spi.c, by way of altera_spi.c + * Copyright (c) 2015 Jagan Teki <jteki@openedev.com> * Copyright (c) 2012 Stephan Linz <linz@li-pro.net> + * Copyright (c) 2010 Graeme Smecher <graeme.smecher@mail.mcgill.ca> + * Copyright (c) 2010 Thomas Chou <thomas@wytron.com.tw> + * Copyright (c) 2005-2008 Analog Devices Inc. * * SPDX-License-Identifier: GPL-2.0+ - * - * [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 <dm.h> +#include <errno.h> #include <malloc.h> #include <spi.h> +#include <asm/io.h> -#include "xilinx_spi.h" +/* + * [0]: http://www.xilinx.com/support/documentation + * + * Xilinx SPI Register Definitions + * [1]: [0]/ip_documentation/xps_spi.pdf + * page 8, Register Descriptions + * [2]: [0]/ip_documentation/axi_spi_ds742.pdf + * page 7, Register Overview Table + */ -#ifndef CONFIG_SYS_XILINX_SPI_LIST -#define CONFIG_SYS_XILINX_SPI_LIST { CONFIG_SYS_SPI_BASE } -#endif +/* 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 Software Reset Register (ssr) */ +#define SPISSR_RESET_VALUE 0x0a + +#define XILSPI_MAX_XFER_BITS 8 +#define XILSPI_SPICR_DFLT_ON (SPICR_MANUAL_SS | SPICR_MASTER_MODE | \ + SPICR_SPE) +#define XILSPI_SPICR_DFLT_OFF (SPICR_MASTER_INHIBIT | SPICR_MANUAL_SS) #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) +#ifndef CONFIG_SYS_XILINX_SPI_LIST +#define CONFIG_SYS_XILINX_SPI_LIST { CONFIG_SYS_SPI_BASE } +#endif -#define XILSPI_MAX_XFER_BITS 8 +/* xilinx spi register set */ +struct xilinx_spi_regs { + 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) */ +}; + +/* xilinx spi priv */ +struct xilinx_spi_priv { + struct xilinx_spi_regs *regs; + unsigned int freq; + unsigned int mode; +}; 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) +static int xilinx_spi_probe(struct udevice *bus) { - return bus < ARRAY_SIZE(xilinx_spi_base_list) && cs < 32; -} + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; -__attribute__((weak)) -void spi_cs_activate(struct spi_slave *slave) -{ - struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); + priv->regs = (struct xilinx_spi_regs *)xilinx_spi_base_list[bus->seq]; - writel(SPISSR_ACT(slave->cs), &xilspi->regs->spissr); -} + writel(SPISSR_RESET_VALUE, ®s->srr); -__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); + return 0; } -void spi_init(void) +static void spi_cs_activate(struct udevice *dev, uint cs) { - /* do nothing */ -} + struct udevice *bus = dev_get_parent(dev); + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; -void spi_set_speed(struct spi_slave *slave, uint hz) -{ - /* xilinx spi core does not support programmable speed */ + writel(SPISSR_ACT(cs), ®s->spissr); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) +static void spi_cs_deactivate(struct udevice *dev) { - struct xilinx_spi_slave *xilspi; - - if (!spi_cs_is_valid(bus, cs)) { - printf("XILSPI error: %s: unsupported bus %d / cs %d\n", - __func__, bus, cs); - return NULL; - } - - xilspi = spi_alloc_slave(struct xilinx_spi_slave, bus, cs); - if (!xilspi) { - printf("XILSPI error: %s: malloc of SPI structure failed\n", - __func__); - return NULL; - } - 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); + struct udevice *bus = dev_get_parent(dev); + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; - writel(SPISSR_RESET_VALUE, &xilspi->regs->srr); - - return &xilspi->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); - - free(xilspi); + writel(SPISSR_OFF, ®s->spissr); } -int spi_claim_bus(struct spi_slave *slave) +static int xilinx_spi_claim_bus(struct udevice *dev) { - struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); - u32 spicr; + struct udevice *bus = dev_get_parent(dev); + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; - debug("%s: bus:%i cs:%i\n", __func__, slave->bus, slave->cs); - writel(SPISSR_OFF, &xilspi->regs->spissr); + writel(SPISSR_OFF, ®s->spissr); + writel(XILSPI_SPICR_DFLT_ON, ®s->spicr); - 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) +static int xilinx_spi_release_bus(struct udevice *dev) { - struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); + struct udevice *bus = dev_get_parent(dev); + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; + + writel(SPISSR_OFF, ®s->spissr); + writel(XILSPI_SPICR_DFLT_OFF, ®s->spicr); - 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); + return 0; } -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) +static int xilinx_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) { - struct xilinx_spi_slave *xilspi = to_xilinx_spi_slave(slave); + struct udevice *bus = dev_get_parent(dev); + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); /* assume spi core configured to do 8 bit transfers */ unsigned int bytes = bitlen / XILSPI_MAX_XFER_BITS; const unsigned char *txp = dout; @@ -151,65 +177,125 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, unsigned rxecount = 17; /* max. 16 elements in FIFO, leftover 1 */ unsigned global_timeout; - debug("%s: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", __func__, - slave->bus, slave->cs, bitlen, bytes, flags); + debug("spi_xfer: bus:%i cs:%i bitlen:%i bytes:%i flags:%lx\n", + bus->seq, slave_plat->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); + printf("XILSPI warning: Not a multiple of %d bits\n", + 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); + while (rxecount && !(readl(®s->spisr) & SPISR_RX_EMPTY)) { + readl(®s->spidrr); rxecount--; } if (!rxecount) { - printf("XILSPI error: %s: Rx buffer not empty\n", __func__); + printf("XILSPI error: Rx buffer not empty\n"); return -1; } if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); + spi_cs_activate(dev, slave_plat->cs); /* at least 1usec or greater, leftover 1 */ - global_timeout = xilspi->freq > XILSPI_MAX_XFER_BITS * 1000000 ? 2 : - (XILSPI_MAX_XFER_BITS * 1000000 / xilspi->freq) + 1; + global_timeout = priv->freq > XILSPI_MAX_XFER_BITS * 1000000 ? 2 : + (XILSPI_MAX_XFER_BITS * 1000000 / priv->freq) + 1; while (bytes--) { unsigned timeout = global_timeout; /* 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); + debug("spi_xfer: tx:%x ", d); /* write out and wait for processing (receive data) */ - writel(d & SPIDTR_8BIT_MASK, &xilspi->regs->spidtr); - while (timeout && readl(&xilspi->regs->spisr) + writel(d & SPIDTR_8BIT_MASK, ®s->spidtr); + while (timeout && readl(®s->spisr) & SPISR_RX_EMPTY) { timeout--; udelay(1); } if (!timeout) { - printf("XILSPI error: %s: Xfer timeout\n", __func__); + printf("XILSPI error: Xfer timeout\n"); return -1; } /* read Rx element and push into data in buffer */ - d = readl(&xilspi->regs->spidrr) & SPIDRR_8BIT_MASK; + d = readl(®s->spidrr) & SPIDRR_8BIT_MASK; if (rxp) *rxp++ = d; - debug("rx:%x\n", d); + debug("spi_xfer: rx:%x\n", d); } done: if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); + spi_cs_deactivate(dev); return 0; } + +static int xilinx_spi_set_speed(struct udevice *bus, uint speed) +{ + struct xilinx_spi_priv *priv = dev_get_priv(bus); + + priv->freq = speed; + + debug("xilinx_spi_set_speed: regs=%p, mode=%d\n", priv->regs, + priv->freq); + + return 0; +} + +static int xilinx_spi_set_mode(struct udevice *bus, uint mode) +{ + struct xilinx_spi_priv *priv = dev_get_priv(bus); + struct xilinx_spi_regs *regs = priv->regs; + uint32_t spicr; + + spicr = readl(®s->spicr); + if (priv->mode & SPI_LSB_FIRST) + spicr |= SPICR_LSB_FIRST; + if (priv->mode & SPI_CPHA) + spicr |= SPICR_CPHA; + if (priv->mode & SPI_CPOL) + spicr |= SPICR_CPOL; + if (priv->mode & SPI_LOOP) + spicr |= SPICR_LOOP; + + writel(spicr, ®s->spicr); + priv->mode = mode; + + debug("xilinx_spi_set_mode: regs=%p, mode=%d\n", priv->regs, + priv->mode); + + return 0; +} + +static const struct dm_spi_ops xilinx_spi_ops = { + .claim_bus = xilinx_spi_claim_bus, + .release_bus = xilinx_spi_release_bus, + .xfer = xilinx_spi_xfer, + .set_speed = xilinx_spi_set_speed, + .set_mode = xilinx_spi_set_mode, +}; + +static const struct udevice_id xilinx_spi_ids[] = { + { .compatible = "xlnx,xilinx-spi" }, + { } +}; + +U_BOOT_DRIVER(xilinx_spi) = { + .name = "xilinx_spi", + .id = UCLASS_SPI, + .of_match = xilinx_spi_ids, + .ops = &xilinx_spi_ops, + .priv_auto_alloc_size = sizeof(struct xilinx_spi_priv), + .probe = xilinx_spi_probe, +}; diff --git a/drivers/spi/xilinx_spi.h b/drivers/spi/xilinx_spi.h deleted file mode 100644 index ce7d82c3944..00000000000 --- a/drivers/spi/xilinx_spi.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * 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> - * - * SPDX-License-Identifier: GPL-2.0+ - * - * [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) - -/* SPI Software Reset Register (ssr) */ -#define SPISSR_RESET_VALUE 0x0a - -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/drivers/spi/zynq_spi.c b/drivers/spi/zynq_spi.c index e9129da79d9..c5c3e1044fd 100644 --- a/drivers/spi/zynq_spi.c +++ b/drivers/spi/zynq_spi.c @@ -1,5 +1,6 @@ /* * (C) Copyright 2013 Inc. + * (C) Copyright 2015 Jagan Teki <jteki@openedev.com> * * Xilinx Zynq PS SPI controller driver (master mode only) * @@ -8,11 +9,16 @@ #include <config.h> #include <common.h> +#include <dm.h> +#include <errno.h> #include <malloc.h> #include <spi.h> +#include <fdtdec.h> #include <asm/io.h> #include <asm/arch/hardware.h> +DECLARE_GLOBAL_DATA_PTR; + /* zynq spi register bit masks ZYNQ_SPI_<REG>_<BIT>_MASK */ #define ZYNQ_SPI_CR_MSA_MASK (1 << 15) /* Manual start enb */ #define ZYNQ_SPI_CR_MCS_MASK (1 << 14) /* Manual chip select */ @@ -44,180 +50,141 @@ struct zynq_spi_regs { u32 rxdr; /* 0x20 */ }; -/* zynq spi slave */ -struct zynq_spi_slave { - struct spi_slave slave; - struct zynq_spi_regs *base; + +/* zynq spi platform data */ +struct zynq_spi_platdata { + struct zynq_spi_regs *regs; + u32 frequency; /* input frequency */ + u32 speed_hz; +}; + +/* zynq spi priv */ +struct zynq_spi_priv { + struct zynq_spi_regs *regs; u8 mode; u8 fifo_depth; - u32 speed_hz; - u32 input_hz; - u32 req_hz; + u32 freq; /* required frequency */ }; -static inline struct zynq_spi_slave *to_zynq_spi_slave(struct spi_slave *slave) +static int zynq_spi_ofdata_to_platdata(struct udevice *bus) { - return container_of(slave, struct zynq_spi_slave, slave); -} + struct zynq_spi_platdata *plat = bus->platdata; + const void *blob = gd->fdt_blob; + int node = bus->of_offset; -static inline struct zynq_spi_regs *get_zynq_spi_base(int dev) -{ - if (dev) - return (struct zynq_spi_regs *)ZYNQ_SPI_BASEADDR1; - else - return (struct zynq_spi_regs *)ZYNQ_SPI_BASEADDR0; + plat->regs = (struct zynq_spi_regs *)fdtdec_get_addr(blob, node, "reg"); + + /* FIXME: Use 250MHz as a suitable default */ + plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", + 250000000); + plat->speed_hz = plat->frequency / 2; + + debug("zynq_spi_ofdata_to_platdata: regs=%p max-frequency=%d\n", + plat->regs, plat->frequency); + + return 0; } -static void zynq_spi_init_hw(struct zynq_spi_slave *zslave) +static void zynq_spi_init_hw(struct zynq_spi_priv *priv) { + struct zynq_spi_regs *regs = priv->regs; u32 confr; /* Disable SPI */ - writel(~ZYNQ_SPI_ENR_SPI_EN_MASK, &zslave->base->enr); + writel(~ZYNQ_SPI_ENR_SPI_EN_MASK, ®s->enr); /* Disable Interrupts */ - writel(ZYNQ_SPI_IXR_ALL_MASK, &zslave->base->idr); + writel(ZYNQ_SPI_IXR_ALL_MASK, ®s->idr); /* Clear RX FIFO */ - while (readl(&zslave->base->isr) & + while (readl(®s->isr) & ZYNQ_SPI_IXR_RXNEMPTY_MASK) - readl(&zslave->base->rxdr); + readl(®s->rxdr); /* Clear Interrupts */ - writel(ZYNQ_SPI_IXR_ALL_MASK, &zslave->base->isr); + writel(ZYNQ_SPI_IXR_ALL_MASK, ®s->isr); /* Manual slave select and Auto start */ confr = ZYNQ_SPI_CR_MCS_MASK | ZYNQ_SPI_CR_CS_MASK | ZYNQ_SPI_CR_MSTREN_MASK; confr &= ~ZYNQ_SPI_CR_MSA_MASK; - writel(confr, &zslave->base->cr); + writel(confr, ®s->cr); /* Enable SPI */ - writel(ZYNQ_SPI_ENR_SPI_EN_MASK, &zslave->base->enr); + writel(ZYNQ_SPI_ENR_SPI_EN_MASK, ®s->enr); } -int spi_cs_is_valid(unsigned int bus, unsigned int cs) +static int zynq_spi_probe(struct udevice *bus) { - /* 2 bus with 3 chipselect */ - return bus < 2 && cs < 3; + struct zynq_spi_platdata *plat = dev_get_platdata(bus); + struct zynq_spi_priv *priv = dev_get_priv(bus); + + priv->regs = plat->regs; + priv->fifo_depth = ZYNQ_SPI_FIFO_DEPTH; + + /* init the zynq spi hw */ + zynq_spi_init_hw(priv); + + return 0; } -void spi_cs_activate(struct spi_slave *slave) +static void spi_cs_activate(struct udevice *dev, uint cs) { - struct zynq_spi_slave *zslave = to_zynq_spi_slave(slave); + struct udevice *bus = dev->parent; + struct zynq_spi_priv *priv = dev_get_priv(bus); + struct zynq_spi_regs *regs = priv->regs; u32 cr; - debug("spi_cs_activate: 0x%08x\n", (u32)slave); - - clrbits_le32(&zslave->base->cr, ZYNQ_SPI_CR_CS_MASK); - cr = readl(&zslave->base->cr); + clrbits_le32(®s->cr, ZYNQ_SPI_CR_CS_MASK); + cr = readl(®s->cr); /* * CS cal logic: CS[13:10] * xxx0 - cs0 * xx01 - cs1 * x011 - cs2 */ - cr |= (~(0x1 << slave->cs) << 10) & ZYNQ_SPI_CR_CS_MASK; - writel(cr, &zslave->base->cr); + cr |= (~(0x1 << cs) << 10) & ZYNQ_SPI_CR_CS_MASK; + writel(cr, ®s->cr); } -void spi_cs_deactivate(struct spi_slave *slave) +static void spi_cs_deactivate(struct udevice *dev) { - struct zynq_spi_slave *zslave = to_zynq_spi_slave(slave); - - debug("spi_cs_deactivate: 0x%08x\n", (u32)slave); + struct udevice *bus = dev->parent; + struct zynq_spi_priv *priv = dev_get_priv(bus); + struct zynq_spi_regs *regs = priv->regs; - setbits_le32(&zslave->base->cr, ZYNQ_SPI_CR_CS_MASK); -} - -void spi_init() -{ - /* nothing to do */ + setbits_le32(®s->cr, ZYNQ_SPI_CR_CS_MASK); } -struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, - unsigned int max_hz, unsigned int mode) +static int zynq_spi_claim_bus(struct udevice *dev) { - struct zynq_spi_slave *zslave; + struct udevice *bus = dev->parent; + struct zynq_spi_priv *priv = dev_get_priv(bus); + struct zynq_spi_regs *regs = priv->regs; - if (!spi_cs_is_valid(bus, cs)) - return NULL; + writel(ZYNQ_SPI_ENR_SPI_EN_MASK, ®s->enr); - zslave = spi_alloc_slave(struct zynq_spi_slave, bus, cs); - if (!zslave) { - printf("SPI_error: Fail to allocate zynq_spi_slave\n"); - return NULL; - } - - zslave->base = get_zynq_spi_base(bus); - zslave->mode = mode; - zslave->fifo_depth = ZYNQ_SPI_FIFO_DEPTH; - zslave->input_hz = 166666700; - zslave->speed_hz = zslave->input_hz / 2; - zslave->req_hz = max_hz; - - /* init the zynq spi hw */ - zynq_spi_init_hw(zslave); - - return &zslave->slave; -} - -void spi_free_slave(struct spi_slave *slave) -{ - struct zynq_spi_slave *zslave = to_zynq_spi_slave(slave); - - debug("spi_free_slave: 0x%08x\n", (u32)slave); - free(zslave); + return 0; } -int spi_claim_bus(struct spi_slave *slave) +static int zynq_spi_release_bus(struct udevice *dev) { - struct zynq_spi_slave *zslave = to_zynq_spi_slave(slave); - u32 confr = 0; - u8 baud_rate_val = 0; + struct udevice *bus = dev->parent; + struct zynq_spi_priv *priv = dev_get_priv(bus); + struct zynq_spi_regs *regs = priv->regs; - writel(~ZYNQ_SPI_ENR_SPI_EN_MASK, &zslave->base->enr); - - /* Set the SPI Clock phase and polarities */ - confr = readl(&zslave->base->cr); - confr &= ~(ZYNQ_SPI_CR_CPHA_MASK | ZYNQ_SPI_CR_CPOL_MASK); - if (zslave->mode & SPI_CPHA) - confr |= ZYNQ_SPI_CR_CPHA_MASK; - if (zslave->mode & SPI_CPOL) - confr |= ZYNQ_SPI_CR_CPOL_MASK; - - /* Set the clock frequency */ - if (zslave->req_hz == 0) { - /* Set baudrate x8, if the req_hz is 0 */ - baud_rate_val = 0x2; - } else if (zslave->speed_hz != zslave->req_hz) { - while ((baud_rate_val < 8) && - ((zslave->input_hz / - (2 << baud_rate_val)) > zslave->req_hz)) - baud_rate_val++; - zslave->speed_hz = zslave->req_hz / (2 << baud_rate_val); - } - confr &= ~ZYNQ_SPI_CR_BRD_MASK; - confr |= (baud_rate_val << 3); - writel(confr, &zslave->base->cr); - - writel(ZYNQ_SPI_ENR_SPI_EN_MASK, &zslave->base->enr); + writel(~ZYNQ_SPI_ENR_SPI_EN_MASK, ®s->enr); return 0; } -void spi_release_bus(struct spi_slave *slave) +static int zynq_spi_xfer(struct udevice *dev, unsigned int bitlen, + const void *dout, void *din, unsigned long flags) { - struct zynq_spi_slave *zslave = to_zynq_spi_slave(slave); - - debug("spi_release_bus: 0x%08x\n", (u32)slave); - writel(~ZYNQ_SPI_ENR_SPI_EN_MASK, &zslave->base->enr); -} - -int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, - void *din, unsigned long flags) -{ - struct zynq_spi_slave *zslave = to_zynq_spi_slave(slave); + struct udevice *bus = dev->parent; + struct zynq_spi_priv *priv = dev_get_priv(bus); + struct zynq_spi_regs *regs = priv->regs; + struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); u32 len = bitlen / 8; u32 tx_len = len, rx_len = len, tx_tvl; const u8 *tx_buf = dout; @@ -225,7 +192,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, u32 ts, status; debug("spi_xfer: bus:%i cs:%i bitlen:%i len:%i flags:%lx\n", - slave->bus, slave->cs, bitlen, len, flags); + bus->seq, slave_plat->cs, bitlen, len, flags); if (bitlen % 8) { debug("spi_xfer: Non byte aligned SPI transfer\n"); @@ -233,45 +200,126 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, } if (flags & SPI_XFER_BEGIN) - spi_cs_activate(slave); + spi_cs_activate(dev, slave_plat->cs); while (rx_len > 0) { /* Write the data into TX FIFO - tx threshold is fifo_depth */ tx_tvl = 0; - while ((tx_tvl < zslave->fifo_depth) && tx_len) { + while ((tx_tvl < priv->fifo_depth) && tx_len) { if (tx_buf) buf = *tx_buf++; else buf = 0; - writel(buf, &zslave->base->txdr); + writel(buf, ®s->txdr); tx_len--; tx_tvl++; } /* Check TX FIFO completion */ ts = get_timer(0); - status = readl(&zslave->base->isr); + status = readl(®s->isr); while (!(status & ZYNQ_SPI_IXR_TXOW_MASK)) { if (get_timer(ts) > CONFIG_SYS_ZYNQ_SPI_WAIT) { printf("spi_xfer: Timeout! TX FIFO not full\n"); return -1; } - status = readl(&zslave->base->isr); + status = readl(®s->isr); } /* Read the data from RX FIFO */ - status = readl(&zslave->base->isr); + status = readl(®s->isr); while (status & ZYNQ_SPI_IXR_RXNEMPTY_MASK) { - buf = readl(&zslave->base->rxdr); + buf = readl(®s->rxdr); if (rx_buf) *rx_buf++ = buf; - status = readl(&zslave->base->isr); + status = readl(®s->isr); rx_len--; } } if (flags & SPI_XFER_END) - spi_cs_deactivate(slave); + spi_cs_deactivate(dev); return 0; } + +static int zynq_spi_set_speed(struct udevice *bus, uint speed) +{ + struct zynq_spi_platdata *plat = bus->platdata; + struct zynq_spi_priv *priv = dev_get_priv(bus); + struct zynq_spi_regs *regs = priv->regs; + uint32_t confr; + u8 baud_rate_val = 0; + + if (speed > plat->frequency) + speed = plat->frequency; + + /* Set the clock frequency */ + confr = readl(®s->cr); + if (speed == 0) { + /* Set baudrate x8, if the freq is 0 */ + baud_rate_val = 0x2; + } else if (plat->speed_hz != speed) { + while ((baud_rate_val < 8) && + ((plat->frequency / + (2 << baud_rate_val)) > speed)) + baud_rate_val++; + plat->speed_hz = speed / (2 << baud_rate_val); + } + confr &= ~ZYNQ_SPI_CR_BRD_MASK; + confr |= (baud_rate_val << 3); + + writel(confr, ®s->cr); + priv->freq = speed; + + debug("zynq_spi_set_speed: regs=%p, mode=%d\n", priv->regs, priv->freq); + + return 0; +} + +static int zynq_spi_set_mode(struct udevice *bus, uint mode) +{ + struct zynq_spi_priv *priv = dev_get_priv(bus); + struct zynq_spi_regs *regs = priv->regs; + uint32_t confr; + + /* Set the SPI Clock phase and polarities */ + confr = readl(®s->cr); + confr &= ~(ZYNQ_SPI_CR_CPHA_MASK | ZYNQ_SPI_CR_CPOL_MASK); + + if (priv->mode & SPI_CPHA) + confr |= ZYNQ_SPI_CR_CPHA_MASK; + if (priv->mode & SPI_CPOL) + confr |= ZYNQ_SPI_CR_CPOL_MASK; + + writel(confr, ®s->cr); + priv->mode = mode; + + debug("zynq_spi_set_mode: regs=%p, mode=%d\n", priv->regs, priv->mode); + + return 0; +} + +static const struct dm_spi_ops zynq_spi_ops = { + .claim_bus = zynq_spi_claim_bus, + .release_bus = zynq_spi_release_bus, + .xfer = zynq_spi_xfer, + .set_speed = zynq_spi_set_speed, + .set_mode = zynq_spi_set_mode, +}; + +static const struct udevice_id zynq_spi_ids[] = { + { .compatible = "xlnx,zynq-spi" }, + { } +}; + +U_BOOT_DRIVER(zynq_spi) = { + .name = "zynq_spi", + .id = UCLASS_SPI, + .of_match = zynq_spi_ids, + .ops = &zynq_spi_ops, + .ofdata_to_platdata = zynq_spi_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct zynq_spi_platdata), + .priv_auto_alloc_size = sizeof(struct zynq_spi_priv), + .probe = zynq_spi_probe, +}; diff --git a/include/configs/alt.h b/include/configs/alt.h index 524da4280d0..6d2c242b950 100644 --- a/include/configs/alt.h +++ b/include/configs/alt.h @@ -41,7 +41,6 @@ /* FLASH */ #define CONFIG_SPI -#define CONFIG_SPI_FLASH_BAR #define CONFIG_SH_QSPI #define CONFIG_SPI_FLASH_SPANSION #define CONFIG_SPI_FLASH_QUAD diff --git a/include/configs/am43xx_evm.h b/include/configs/am43xx_evm.h index 466ded7ddfb..33e534a7658 100644 --- a/include/configs/am43xx_evm.h +++ b/include/configs/am43xx_evm.h @@ -204,7 +204,6 @@ #define CONFIG_CMD_SF #define CONFIG_CMD_SPI #define CONFIG_TI_SPI_MMAP -#define CONFIG_SPI_FLASH_BAR #define CONFIG_QSPI_SEL_GPIO 48 #define CONFIG_SF_DEFAULT_SPEED 48000000 #define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3 diff --git a/include/configs/bg0900.h b/include/configs/bg0900.h index 76c1c6a0945..c45c8c2389c 100644 --- a/include/configs/bg0900.h +++ b/include/configs/bg0900.h @@ -49,7 +49,6 @@ /* SPI FLASH */ #ifdef CONFIG_CMD_SF -#define CONFIG_SPI_FLASH_BAR #define CONFIG_SPI_FLASH_STMICRO #define CONFIG_SF_DEFAULT_BUS 2 #define CONFIG_SF_DEFAULT_CS 0 diff --git a/include/configs/colibri_vf.h b/include/configs/colibri_vf.h index aff2810a051..f2f8e2ee4d0 100644 --- a/include/configs/colibri_vf.h +++ b/include/configs/colibri_vf.h @@ -179,7 +179,7 @@ #define CONFIG_SYS_PROMPT_HUSH_PS2 "> " #define CONFIG_SYS_PROMPT "Colibri VFxx # " #undef CONFIG_AUTO_COMPLETE -#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */ +#define CONFIG_SYS_CBSIZE 1024 /* Console I/O Buffer Size */ #define CONFIG_SYS_PBSIZE \ (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16) #define CONFIG_SYS_MAXARGS 16 /* max number of command args */ diff --git a/include/configs/dra7xx_evm.h b/include/configs/dra7xx_evm.h index 914e1cf0697..d84427d1d8b 100644 --- a/include/configs/dra7xx_evm.h +++ b/include/configs/dra7xx_evm.h @@ -125,7 +125,6 @@ #define CONFIG_SPI_FLASH_SPANSION #define CONFIG_CMD_SF #define CONFIG_CMD_SPI -#define CONFIG_SPI_FLASH_BAR #define CONFIG_TI_SPI_MMAP #define CONFIG_SF_DEFAULT_SPEED 48000000 #define CONFIG_DEFAULT_SPI_MODE SPI_MODE_3 diff --git a/include/configs/gose.h b/include/configs/gose.h index f088649afd7..c08e73ac691 100644 --- a/include/configs/gose.h +++ b/include/configs/gose.h @@ -44,7 +44,6 @@ #define CONFIG_SYS_NO_FLASH #define CONFIG_SPI #define CONFIG_SH_QSPI -#define CONFIG_SPI_FLASH_BAR #define CONFIG_SPI_FLASH_SPANSION /* SH Ether */ diff --git a/include/configs/koelsch.h b/include/configs/koelsch.h index ff948f963c1..c905cc2dc2e 100644 --- a/include/configs/koelsch.h +++ b/include/configs/koelsch.h @@ -44,7 +44,6 @@ #define CONFIG_SYS_NO_FLASH #define CONFIG_SPI #define CONFIG_SH_QSPI -#define CONFIG_SPI_FLASH_BAR #define CONFIG_SPI_FLASH_SPANSION /* SH Ether */ diff --git a/include/configs/lager.h b/include/configs/lager.h index 546863ea485..1450e8f53fa 100644 --- a/include/configs/lager.h +++ b/include/configs/lager.h @@ -42,7 +42,6 @@ /* SPI */ #define CONFIG_SPI -#define CONFIG_SPI_FLASH_BAR #define CONFIG_SH_QSPI #define CONFIG_SPI_FLASH_SPANSION #define CONFIG_SYS_NO_FLASH diff --git a/include/configs/ls1021aqds.h b/include/configs/ls1021aqds.h index 46c609af893..8a5a707d3b1 100644 --- a/include/configs/ls1021aqds.h +++ b/include/configs/ls1021aqds.h @@ -423,7 +423,7 @@ unsigned long get_board_ddr_clk(void); #if defined(CONFIG_FSL_DSPI) || defined(CONFIG_FSL_QSPI) #define CONFIG_CMD_SF #define CONFIG_DM_SPI_FLASH -#define CONFIG_SF_DATAFLASH +#define CONFIG_SPI_FLASH_DATAFLASH #endif #endif diff --git a/include/configs/maxbcm.h b/include/configs/maxbcm.h index 0839d39a396..4826044857d 100644 --- a/include/configs/maxbcm.h +++ b/include/configs/maxbcm.h @@ -43,7 +43,6 @@ #define CONFIG_SF_DEFAULT_MODE SPI_MODE_3 #define CONFIG_SPI_FLASH_STMICRO #define CONFIG_SPI_FLASH_SPANSION -#define CONFIG_SPI_FLASH_BAR /* Environment in SPI NOR flash */ #define CONFIG_ENV_IS_IN_SPI_FLASH diff --git a/include/configs/mx6_common.h b/include/configs/mx6_common.h index 2ef3201de18..86d7b167775 100644 --- a/include/configs/mx6_common.h +++ b/include/configs/mx6_common.h @@ -86,7 +86,7 @@ #define CONFIG_CMD_FAT /* Miscellaneous configurable options */ -#define CONFIG_SYS_NO_FLASH +#undef CONFIG_CMD_IMLS #define CONFIG_SYS_LONGHELP #define CONFIG_SYS_HUSH_PARSER #define CONFIG_CMDLINE_EDITING diff --git a/include/configs/mx6cuboxi.h b/include/configs/mx6cuboxi.h index 3f99512bce8..3d5bba75d38 100644 --- a/include/configs/mx6cuboxi.h +++ b/include/configs/mx6cuboxi.h @@ -186,14 +186,6 @@ "fi; " \ "else run netboot; fi" -/* Miscellaneous configurable options */ -#define CONFIG_SYS_LONGHELP -#define CONFIG_SYS_HUSH_PARSER -#define CONFIG_AUTO_COMPLETE -#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE - -#define CONFIG_CMDLINE_EDITING - /* Physical Memory Map */ #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_SYS_SDRAM_BASE MMDC0_ARB_BASE_ADDR diff --git a/include/configs/mx6sxsabresd.h b/include/configs/mx6sxsabresd.h index 19f9e4438c5..2b278a8ab4a 100644 --- a/include/configs/mx6sxsabresd.h +++ b/include/configs/mx6sxsabresd.h @@ -189,7 +189,6 @@ #ifdef CONFIG_FSL_QSPI #define CONFIG_CMD_SF -#define CONFIG_SPI_FLASH_BAR #define CONFIG_SPI_FLASH_SPANSION #define CONFIG_SPI_FLASH_STMICRO #define CONFIG_SYS_FSL_QSPI_LE diff --git a/include/configs/novena.h b/include/configs/novena.h index 1dc9d83c2cb..d9b7250cad7 100644 --- a/include/configs/novena.h +++ b/include/configs/novena.h @@ -24,6 +24,7 @@ #define CONFIG_CMD_DHCP #define CONFIG_CMD_EEPROM #define CONFIG_CMD_I2C +#define CONFIG_FAT_WRITE #define CONFIG_CMD_FUSE #define CONFIG_CMD_MII #define CONFIG_CMD_PCI diff --git a/include/configs/porter.h b/include/configs/porter.h index 93673490fb4..59b14e90610 100644 --- a/include/configs/porter.h +++ b/include/configs/porter.h @@ -42,7 +42,6 @@ /* FLASH */ #define CONFIG_SPI -#define CONFIG_SPI_FLASH_BAR #define CONFIG_SH_QSPI #define CONFIG_SPI_FLASH_SPANSION #define CONFIG_SPI_FLASH_QUAD diff --git a/include/configs/silk.h b/include/configs/silk.h index b105f5af316..cd839aa63fa 100644 --- a/include/configs/silk.h +++ b/include/configs/silk.h @@ -42,7 +42,6 @@ /* FLASH */ #define CONFIG_SPI -#define CONFIG_SPI_FLASH_BAR #define CONFIG_SH_QSPI #define CONFIG_SPI_FLASH_SPANSION #define CONFIG_SPI_FLASH_QUAD diff --git a/include/configs/tbs2910.h b/include/configs/tbs2910.h index e1c993783bb..42e58218074 100644 --- a/include/configs/tbs2910.h +++ b/include/configs/tbs2910.h @@ -21,6 +21,8 @@ #define CONFIG_SYS_PROMPT "Matrix U-Boot> " #define CONFIG_SYS_HZ 1000 +#define CONFIG_IMX6_THERMAL + /* Physical Memory Map */ #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_SYS_SDRAM_BASE MMDC0_ARB_BASE_ADDR @@ -49,6 +51,10 @@ #define CONFIG_CONSOLE_MUX #define CONFIG_CONS_INDEX 1 +#define CONFIG_PRE_CONSOLE_BUFFER +#define CONFIG_PRE_CON_BUF_SZ 4096 +#define CONFIG_PRE_CON_BUF_ADDR 0x7C000000 + /* *** Command definition *** */ #define CONFIG_CMD_BMODE #define CONFIG_CMD_MEMTEST diff --git a/include/configs/tqma6.h b/include/configs/tqma6.h index 78a8e399c68..e0c4ada711d 100644 --- a/include/configs/tqma6.h +++ b/include/configs/tqma6.h @@ -9,6 +9,7 @@ #ifndef __CONFIG_H #define __CONFIG_H +#include <linux/kconfig.h> /* SPL */ /* #if defined(CONFIG_SPL_BUILD) */ diff --git a/include/spi.h b/include/spi.h index f4b93e6a139..18362364cf0 100644 --- a/include/spi.h +++ b/include/spi.h @@ -54,7 +54,7 @@ /* Header byte that marks the start of the message */ #define SPI_PREAMBLE_END_BYTE 0xec -#define SPI_DEFAULT_WORDLEN 8 +#define SPI_DEFAULT_WORDLEN 8 #ifdef CONFIG_DM_SPI /* TODO(sjg@chromium.org): Remove this and use max_hz from struct spi_slave */ diff --git a/include/spi_flash.h b/include/spi_flash.h index f2814ef41a0..3b2d555c77b 100644 --- a/include/spi_flash.h +++ b/include/spi_flash.h @@ -37,13 +37,15 @@ struct spi_slave; * struct spi_flash - SPI flash structure * * @spi: SPI slave + * @dev: SPI flash device + * @flags: Indication of spi flash flags * @name: Name of SPI flash - * @dual_flash: Indicates dual flash memories - dual stacked, parallel + * @dual_flash: Indicates dual flash memories - dual stacked, parallel * @shift: Flash shift useful in dual parallel * @size: Total flash size * @page_size: Write (page) size * @sector_size: Sector size - * @erase_size: Erase size + * @erase_size: Erase size * @bank_read_cmd: Bank read cmd * @bank_write_cmd: Bank write cmd * @bank_curr: Current flash bank @@ -51,8 +53,8 @@ struct spi_slave; * @erase_cmd: Erase cmd 4K, 32K, 64K * @read_cmd: Read cmd - Array Fast, Extn read and quad read. * @write_cmd: Write cmd - page and quad program. - * @dummy_byte: Dummy cycles for read operation. - * @memory_map: Address of read-only SPI flash access + * @dummy_byte: Dummy cycles for read operation. + * @memory_map: Address of read-only SPI flash access * @read: Flash read ops: Read len bytes at offset into buf * Supported cmds: Fast Array Read * @write: Flash write ops: Write len bytes from buf into offset |