diff options
| author | Tom Rini <trini@ti.com> | 2013-11-11 09:40:34 -0500 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-11-11 09:40:34 -0500 | 
| commit | 60390d70be7336b2441f5f69bd4f5affa83d064d (patch) | |
| tree | 857824f8b7f5f7aaf2f5dac91eea94392818a7a0 | |
| parent | 85b8c5c4bf80025de4632ae6c9a8a606e51508a4 (diff) | |
| parent | a3e80904fb07cda792e636704e3b3950d1446af3 (diff) | |
| download | olio-uboot-2014.01-60390d70be7336b2441f5f69bd4f5affa83d064d.tar.xz olio-uboot-2014.01-60390d70be7336b2441f5f69bd4f5affa83d064d.zip | |
Merge branch 'master' of git://git.denx.de/u-boot-mips
25 files changed, 1256 insertions, 298 deletions
| diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/cpu/mips32/cache.S index 12f656cad..22bd844ea 100644 --- a/arch/mips/cpu/mips32/cache.S +++ b/arch/mips/cpu/mips32/cache.S @@ -20,15 +20,6 @@  #define RA		t9 -/* - * 16kB is the maximum size of instruction and data caches on MIPS 4K, - * 64kB is on 4KE, 24K, 5K, etc. Set bigger size for convenience. - * - * Note that the above size is the maximum size of primary cache. U-Boot - * doesn't have L2 cache support for now. - */ -#define MIPS_MAX_CACHE_SIZE	0x10000 -  #define INDEX_BASE	CKSEG0  	.macro	cache_op op addr @@ -126,12 +117,85 @@ LEAF(mips_init_dcache)   */  NESTED(mips_cache_reset, 0, ra)  	move	RA, ra -	li	t2, CONFIG_SYS_ICACHE_SIZE -	li	t3, CONFIG_SYS_DCACHE_SIZE + +#if !defined(CONFIG_SYS_ICACHE_SIZE) || !defined(CONFIG_SYS_DCACHE_SIZE) || \ +    !defined(CONFIG_SYS_CACHELINE_SIZE) +	/* read Config1 for use below */ +	mfc0	t5, CP0_CONFIG, 1 +#endif + +#ifdef CONFIG_SYS_CACHELINE_SIZE +	li	t7, CONFIG_SYS_CACHELINE_SIZE  	li	t8, CONFIG_SYS_CACHELINE_SIZE +#else +	/* Detect I-cache line size. */ +	srl	t8, t5, MIPS_CONF1_IL_SHIFT +	andi	t8, t8, (MIPS_CONF1_IL >> MIPS_CONF1_IL_SHIFT) +	beqz	t8, 1f +	li	t6, 2 +	sllv	t8, t6, t8 -	li	v0, MIPS_MAX_CACHE_SIZE +1:	/* Detect D-cache line size. */ +	srl	t7, t5, MIPS_CONF1_DL_SHIFT +	andi	t7, t7, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHIFT) +	beqz	t7, 1f +	li	t6, 2 +	sllv	t7, t6, t7 +1: +#endif +#ifdef CONFIG_SYS_ICACHE_SIZE +	li	t2, CONFIG_SYS_ICACHE_SIZE +#else +	/* Detect I-cache size. */ +	srl	t6, t5, MIPS_CONF1_IS_SHIFT +	andi	t6, t6, (MIPS_CONF1_IS >> MIPS_CONF1_IS_SHIFT) +	li	t4, 32 +	xori	t2, t6, 0x7 +	beqz	t2, 1f +	addi	t6, t6, 1 +	sllv	t4, t4, t6 +1:	/* At this point t4 == I-cache sets. */ +	mul	t2, t4, t8 +	srl	t6, t5, MIPS_CONF1_IA_SHIFT +	andi	t6, t6, (MIPS_CONF1_IA >> MIPS_CONF1_IA_SHIFT) +	addi	t6, t6, 1 +	/* At this point t6 == I-cache ways. */ +	mul	t2, t2, t6 +#endif + +#ifdef CONFIG_SYS_DCACHE_SIZE +	li	t3, CONFIG_SYS_DCACHE_SIZE +#else +	/* Detect D-cache size. */ +	srl	t6, t5, MIPS_CONF1_DS_SHIFT +	andi	t6, t6, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHIFT) +	li	t4, 32 +	xori	t3, t6, 0x7 +	beqz	t3, 1f +	addi	t6, t6, 1 +	sllv	t4, t4, t6 +1:	/* At this point t4 == I-cache sets. */ +	mul	t3, t4, t7 +	srl	t6, t5, MIPS_CONF1_DA_SHIFT +	andi	t6, t6, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHIFT) +	addi	t6, t6, 1 +	/* At this point t6 == I-cache ways. */ +	mul	t3, t3, t6 +#endif + +	/* Determine the largest L1 cache size */ +#if defined(CONFIG_SYS_ICACHE_SIZE) && defined(CONFIG_SYS_DCACHE_SIZE) +#if CONFIG_SYS_ICACHE_SIZE > CONFIG_SYS_DCACHE_SIZE +	li	v0, CONFIG_SYS_ICACHE_SIZE +#else +	li	v0, CONFIG_SYS_DCACHE_SIZE +#endif +#else +	move	v0, t2 +	sltu	t1, t2, t3 +	movn	v0, t3, t1 +#endif  	/*  	 * Now clear that much memory starting from zero.  	 */ @@ -163,7 +227,7 @@ NESTED(mips_cache_reset, 0, ra)  	 * then initialize D-cache.  	 */  	move	a1, t3 -	move	a2, t8 +	move	a2, t7  	PTR_LA	v1, mips_init_dcache  	jalr	v1 diff --git a/arch/mips/cpu/mips32/cpu.c b/arch/mips/cpu/mips32/cpu.c index 28d5c4568..278865b6f 100644 --- a/arch/mips/cpu/mips32/cpu.c +++ b/arch/mips/cpu/mips32/cpu.c @@ -34,28 +34,89 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	return 0;  } +#ifdef CONFIG_SYS_CACHELINE_SIZE + +static inline unsigned long icache_line_size(void) +{ +	return CONFIG_SYS_CACHELINE_SIZE; +} + +static inline unsigned long dcache_line_size(void) +{ +	return CONFIG_SYS_CACHELINE_SIZE; +} + +#else /* !CONFIG_SYS_CACHELINE_SIZE */ + +static inline unsigned long icache_line_size(void) +{ +	unsigned long conf1, il; +	conf1 = read_c0_config1(); +	il = (conf1 & MIPS_CONF1_IL) >> MIPS_CONF1_IL_SHIFT; +	if (!il) +		return 0; +	return 2 << il; +} + +static inline unsigned long dcache_line_size(void) +{ +	unsigned long conf1, dl; +	conf1 = read_c0_config1(); +	dl = (conf1 & MIPS_CONF1_DL) >> MIPS_CONF1_DL_SHIFT; +	if (!dl) +		return 0; +	return 2 << dl; +} + +#endif /* !CONFIG_SYS_CACHELINE_SIZE */ +  void flush_cache(ulong start_addr, ulong size)  { -	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; -	unsigned long addr = start_addr & ~(lsize - 1); -	unsigned long aend = (start_addr + size - 1) & ~(lsize - 1); +	unsigned long ilsize = icache_line_size(); +	unsigned long dlsize = dcache_line_size(); +	unsigned long addr, aend;  	/* aend will be miscalculated when size is zero, so we return here */  	if (size == 0)  		return; +	addr = start_addr & ~(dlsize - 1); +	aend = (start_addr + size - 1) & ~(dlsize - 1); + +	if (ilsize == dlsize) { +		/* flush I-cache & D-cache simultaneously */ +		while (1) { +			cache_op(HIT_WRITEBACK_INV_D, addr); +			cache_op(HIT_INVALIDATE_I, addr); +			if (addr == aend) +				break; +			addr += dlsize; +		} +		return; +	} + +	/* flush D-cache */  	while (1) {  		cache_op(HIT_WRITEBACK_INV_D, addr); +		if (addr == aend) +			break; +		addr += dlsize; +	} + +	/* flush I-cache */ +	addr = start_addr & ~(ilsize - 1); +	aend = (start_addr + size - 1) & ~(ilsize - 1); +	while (1) {  		cache_op(HIT_INVALIDATE_I, addr);  		if (addr == aend)  			break; -		addr += lsize; +		addr += ilsize;  	}  }  void flush_dcache_range(ulong start_addr, ulong stop)  { -	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; +	unsigned long lsize = dcache_line_size();  	unsigned long addr = start_addr & ~(lsize - 1);  	unsigned long aend = (stop - 1) & ~(lsize - 1); @@ -69,7 +130,7 @@ void flush_dcache_range(ulong start_addr, ulong stop)  void invalidate_dcache_range(ulong start_addr, ulong stop)  { -	unsigned long lsize = CONFIG_SYS_CACHELINE_SIZE; +	unsigned long lsize = dcache_line_size();  	unsigned long addr = start_addr & ~(lsize - 1);  	unsigned long aend = (stop - 1) & ~(lsize - 1); diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S index 70ad198cc..68e59b596 100644 --- a/arch/mips/cpu/mips32/start.S +++ b/arch/mips/cpu/mips32/start.S @@ -51,7 +51,7 @@ _start:  	 */  	.word CONFIG_SYS_XWAY_EBU_BOOTCFG  	.word 0x0 -#elif defined(CONFIG_QEMU_MALTA) +#elif defined(CONFIG_MALTA)  	/*  	 * Linux expects the Board ID here.  	 */ diff --git a/arch/mips/include/asm/malta.h b/arch/mips/include/asm/malta.h index d4d44a299..9b1100bc4 100644 --- a/arch/mips/include/asm/malta.h +++ b/arch/mips/include/asm/malta.h @@ -1,23 +1,60 @@  /*   * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2013 Imagination Technologies   * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. + * SPDX-License-Identifier:	GPL-2.0   */  #ifndef _MIPS_ASM_MALTA_H  #define _MIPS_ASM_MALTA_H -#define MALTA_IO_PORT_BASE	0x18000000 +#define MALTA_GT_BASE			0x1be00000 +#define MALTA_GT_PCIIO_BASE		0x18000000 +#define MALTA_GT_UART0_BASE		(MALTA_GT_PCIIO_BASE + 0x3f8) -#define MALTA_UART_BASE		(MALTA_IO_PORT_BASE + 0x3f8) +#define MALTA_MSC01_BIU_BASE		0x1bc80000 +#define MALTA_MSC01_PCI_BASE		0x1bd00000 +#define MALTA_MSC01_PBC_BASE		0x1bd40000 +#define MALTA_MSC01_IP1_BASE		0x1bc00000 +#define MALTA_MSC01_IP1_SIZE		0x00400000 +#define MALTA_MSC01_IP2_BASE1		0x10000000 +#define MALTA_MSC01_IP2_SIZE1		0x08000000 +#define MALTA_MSC01_IP2_BASE2		0x18000000 +#define MALTA_MSC01_IP2_SIZE2		0x04000000 +#define MALTA_MSC01_IP3_BASE		0x1c000000 +#define MALTA_MSC01_IP3_SIZE		0x04000000 +#define MALTA_MSC01_PCIMEM_BASE		0x10000000 +#define MALTA_MSC01_PCIMEM_SIZE		0x10000000 +#define MALTA_MSC01_PCIMEM_MAP		0x10000000 +#define MALTA_MSC01_PCIIO_BASE		0x1b000000 +#define MALTA_MSC01_PCIIO_SIZE		0x00800000 +#define MALTA_MSC01_PCIIO_MAP		0x00000000 +#define MALTA_MSC01_UART0_BASE		(MALTA_MSC01_PCIIO_BASE + 0x3f8) -#define MALTA_GT_BASE		0x1be00000 +#define MALTA_ASCIIWORD			0x1f000410 +#define MALTA_ASCIIPOS0			0x1f000418 +#define MALTA_ASCIIPOS1			0x1f000420 +#define MALTA_ASCIIPOS2			0x1f000428 +#define MALTA_ASCIIPOS3			0x1f000430 +#define MALTA_ASCIIPOS4			0x1f000438 +#define MALTA_ASCIIPOS5			0x1f000440 +#define MALTA_ASCIIPOS6			0x1f000448 +#define MALTA_ASCIIPOS7			0x1f000450 -#define MALTA_RESET_BASE	0x1f000500 -#define GORESET			0x42 +#define MALTA_RESET_BASE		0x1f000500 +#define GORESET				0x42 -#define MALTA_FLASH_BASE	0x1fc00000 +#define MALTA_FLASH_BASE		0x1fc00000 + +#define MALTA_REVISION			0x1fc00010 +#define MALTA_REVISION_CORID_SHF	10 +#define MALTA_REVISION_CORID_MSK	(0x3f << MALTA_REVISION_CORID_SHF) +#define MALTA_REVISION_CORID_CORE_LV		1 +#define MALTA_REVISION_CORID_CORE_FPGA6		14 + +#define PCI_CFG_PIIX4_PIRQRCA		0x60 +#define PCI_CFG_PIIX4_PIRQRCB		0x61 +#define PCI_CFG_PIIX4_PIRQRCC		0x62 +#define PCI_CFG_PIIX4_PIRQRCD		0x63  #endif /* _MIPS_ASM_MALTA_H */ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index be7e5c65e..3571e4fdf 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -494,11 +494,17 @@  #define MIPS_CONF1_PC		(_ULCAST_(1) <<  4)  #define MIPS_CONF1_MD		(_ULCAST_(1) <<  5)  #define MIPS_CONF1_C2		(_ULCAST_(1) <<  6) +#define MIPS_CONF1_DA_SHIFT	7  #define MIPS_CONF1_DA		(_ULCAST_(7) <<  7) +#define MIPS_CONF1_DL_SHIFT	10  #define MIPS_CONF1_DL		(_ULCAST_(7) << 10) +#define MIPS_CONF1_DS_SHIFT	13  #define MIPS_CONF1_DS		(_ULCAST_(7) << 13) +#define MIPS_CONF1_IA_SHIFT	16  #define MIPS_CONF1_IA		(_ULCAST_(7) << 16) +#define MIPS_CONF1_IL_SHIFT	19  #define MIPS_CONF1_IL		(_ULCAST_(7) << 19) +#define MIPS_CONF1_IS_SHIFT	22  #define MIPS_CONF1_IS		(_ULCAST_(7) << 22)  #define MIPS_CONF1_TLBS		(_ULCAST_(63)<< 25) diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index 66340ea47..1febf2986 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -17,10 +17,10 @@ DECLARE_GLOBAL_DATA_PTR;  #define	LINUX_MAX_ENVS		256  #define	LINUX_MAX_ARGS		256 -#if defined(CONFIG_QEMU_MALTA) -#define mips_boot_qemu_malta	1 +#if defined(CONFIG_MALTA) +#define mips_boot_malta		1  #else -#define mips_boot_qemu_malta	0 +#define mips_boot_malta		0  #endif  static int linux_argc; @@ -139,7 +139,7 @@ static void linux_env_set(const char *env_name, const char *env_val)  		strcpy(linux_env_p, env_name);  		linux_env_p += strlen(env_name); -		if (mips_boot_qemu_malta) { +		if (mips_boot_malta) {  			linux_env_p++;  			linux_env[++linux_env_idx] = linux_env_p;  		} else { @@ -196,7 +196,7 @@ static void boot_prep_linux(bootm_headers_t *images)  	if (cp)  		linux_env_set("eth1addr", cp); -	if (mips_boot_qemu_malta) +	if (mips_boot_malta)  		linux_env_set("modetty0", "38400n8r");  } @@ -210,7 +210,7 @@ static void boot_jump_linux(bootm_headers_t *images)  	bootstage_mark(BOOTSTAGE_ID_RUN_OS); -	if (mips_boot_qemu_malta) +	if (mips_boot_malta)  		linux_extra = gd->ram_size;  	/* we assume that the kernel is in place */ diff --git a/board/qemu-malta/Makefile b/board/imgtec/malta/Makefile index 5d727f6f5..19dd3a3c3 100644 --- a/board/qemu-malta/Makefile +++ b/board/imgtec/malta/Makefile @@ -5,5 +5,6 @@  # SPDX-License-Identifier:	GPL-2.0+  # -obj-y	= qemu-malta.o +obj-y	= malta.o  obj-y	+= lowlevel_init.o +obj-y	+= superio.o diff --git a/board/imgtec/malta/flash-malta-boot.tcl b/board/imgtec/malta/flash-malta-boot.tcl new file mode 100644 index 000000000..0eedf07ac --- /dev/null +++ b/board/imgtec/malta/flash-malta-boot.tcl @@ -0,0 +1,40 @@ +# +# Copyright (C) 2013 Imagination Technologies +# +# Programs a MIPS Malta boot flash with a flat binary image. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +proc flash-boot { binfile } { +  puts "flash monitor binary $binfile" +  config Coherent on +  config CoherencyDuringLoad on + +  if {[endian]=="big"} { +    puts "CPU in BE mode" +    flash device sharp_16x32_be; +  } else { +    puts "CPU in LE mode" +    flash device sharp_16x32; +  } + +  flash clear all; +  flash set 0xBE000000..0xBE0FFFFF +  flash erase sector 0xbe000000; +  flash erase sector 0xbe020000; +  flash erase sector 0xbe040000; +  flash erase sector 0xbe060000; +  flash erase sector 0xbe080000; +  flash erase sector 0xbe0a0000; +  flash erase sector 0xbe0c0000; +  flash erase sector 0xbe0e0000; +  puts "finished erasing boot flash"; + +  puts "programming flash, please be patient" +  load bin 0xbe000000 $binfile size4 + +  flash clear all +  config CoherencyDuringLoad off +  puts "finished programming boot flash"; +} diff --git a/board/imgtec/malta/lowlevel_init.S b/board/imgtec/malta/lowlevel_init.S new file mode 100644 index 000000000..ae09c27d0 --- /dev/null +++ b/board/imgtec/malta/lowlevel_init.S @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org> + * + * SPDX-License-Identifier:	GPL-2.0 + */ + +#include <config.h> +#include <gt64120.h> +#include <msc01.h> +#include <pci.h> + +#include <asm/addrspace.h> +#include <asm/regdef.h> +#include <asm/malta.h> +#include <asm/mipsregs.h> + +#ifdef CONFIG_SYS_BIG_ENDIAN +#define CPU_TO_GT32(_x)		((_x)) +#else +#define CPU_TO_GT32(_x) (					\ +	(((_x) & 0xff) << 24) | (((_x) & 0xff00) << 8) |	\ +	(((_x) & 0xff0000) >> 8) | (((_x) & 0xff000000) >> 24)) +#endif + +	.text +	.set noreorder +	.set mips32 + +	.globl	lowlevel_init +lowlevel_init: +	/* disable any L2 cache for now */ +	sync +	mfc0	t0, CP0_CONFIG, 2 +	ori	t0, t0, 0x1 << 12 +	mtc0	t0, CP0_CONFIG, 2 + +	/* detect the core card */ +	li	t0, KSEG1ADDR(MALTA_REVISION) +	lw	t0, 0(t0) +	srl	t0, t0, MALTA_REVISION_CORID_SHF +	andi	t0, t0, (MALTA_REVISION_CORID_MSK >> \ +			 MALTA_REVISION_CORID_SHF) + +	/* core cards using the gt64120 system controller */ +	li	t1, MALTA_REVISION_CORID_CORE_LV +	beq	t0, t1, _gt64120 + +	/* core cards using the MSC01 system controller */ +	 li	t1, MALTA_REVISION_CORID_CORE_FPGA6 +	beq	t0, t1, _msc01 +	 nop + +	/* unknown system controller */ +	b	. +	 nop + +	/* +	 * Load BAR registers of GT64120 as done by YAMON +	 * +	 * based on a patch sent by Antony Pavlov <antonynpavlov@gmail.com> +	 * to the barebox mailing list. +	 * The subject of the original patch: +	 *   'MIPS: qemu-malta: add YAMON-style GT64120 memory map' +	 * URL: +	 * http://www.mail-archive.com/barebox@lists.infradead.org/msg06128.html +	 * +	 * based on write_bootloader() in qemu.git/hw/mips_malta.c +	 * see GT64120 manual and qemu.git/hw/gt64xxx.c for details +	 */ +_gt64120: +	/* move GT64120 registers from 0x14000000 to 0x1be00000 */ +	li	t1, KSEG1ADDR(GT_DEF_BASE) +	li	t0, CPU_TO_GT32(0xdf000000) +	sw	t0, GT_ISD_OFS(t1) + +	/* setup MEM-to-PCI0 mapping */ +	li	t1, KSEG1ADDR(MALTA_GT_BASE) + +	/* setup PCI0 io window to 0x18000000-0x181fffff */ +	li	t0, CPU_TO_GT32(0xc0000000) +	sw	t0, GT_PCI0IOLD_OFS(t1) +	li	t0, CPU_TO_GT32(0x40000000) +	sw	t0, GT_PCI0IOHD_OFS(t1) + +	/* setup PCI0 mem windows */ +	li	t0, CPU_TO_GT32(0x80000000) +	sw	t0, GT_PCI0M0LD_OFS(t1) +	li	t0, CPU_TO_GT32(0x3f000000) +	sw	t0, GT_PCI0M0HD_OFS(t1) + +	li	t0, CPU_TO_GT32(0xc1000000) +	sw	t0, GT_PCI0M1LD_OFS(t1) +	li	t0, CPU_TO_GT32(0x5e000000) +	sw	t0, GT_PCI0M1HD_OFS(t1) + +	jr	ra +	 nop + +	/* +	 * +	 */ +_msc01: +	/* setup peripheral bus controller clock divide */ +	li	t0, KSEG1ADDR(MALTA_MSC01_PBC_BASE) +	li	t1, 0x1 << MSC01_PBC_CLKCFG_SHF +	sw	t1, MSC01_PBC_CLKCFG_OFS(t0) + +	/* tweak peripheral bus controller timings */ +	li	t1, (0x1 << MSC01_PBC_CS0TIM_CDT_SHF) | \ +		    (0x1 << MSC01_PBC_CS0TIM_CAT_SHF) +	sw	t1, MSC01_PBC_CS0TIM_OFS(t0) +	li	t1, (0x0 << MSC01_PBC_CS0RW_RDT_SHF) | \ +		    (0x2 << MSC01_PBC_CS0RW_RAT_SHF) | \ +		    (0x0 << MSC01_PBC_CS0RW_WDT_SHF) | \ +		    (0x2 << MSC01_PBC_CS0RW_WAT_SHF) +	sw	t1, MSC01_PBC_CS0RW_OFS(t0) +	lw	t1, MSC01_PBC_CS0CFG_OFS(t0) +	li	t2, MSC01_PBC_CS0CFG_DTYP_MSK +	and	t1, t2 +	ori	t1, (0x0 << MSC01_PBC_CS0CFG_ADM_SHF) | \ +		    (0x3 << MSC01_PBC_CS0CFG_WSIDLE_SHF) | \ +		    (0x10 << MSC01_PBC_CS0CFG_WS_SHF) +	sw	t1, MSC01_PBC_CS0CFG_OFS(t0) + +	/* setup basic address decode */ +	li	t0, KSEG1ADDR(MALTA_MSC01_BIU_BASE) +	li	t1, 0x0 +	li	t2, -CONFIG_SYS_MEM_SIZE +	sw	t1, MSC01_BIU_MCBAS1L_OFS(t0) +	sw	t2, MSC01_BIU_MCMSK1L_OFS(t0) +	sw	t1, MSC01_BIU_MCBAS2L_OFS(t0) +	sw	t2, MSC01_BIU_MCMSK2L_OFS(t0) + +	/* initialise IP1 - unused */ +	li	t1, MALTA_MSC01_IP1_BASE +	li	t2, -MALTA_MSC01_IP1_SIZE +	sw	t1, MSC01_BIU_IP1BAS1L_OFS(t0) +	sw	t2, MSC01_BIU_IP1MSK1L_OFS(t0) +	sw	t1, MSC01_BIU_IP1BAS2L_OFS(t0) +	sw	t2, MSC01_BIU_IP1MSK2L_OFS(t0) + +	/* initialise IP2 - PCI */ +	li	t1, MALTA_MSC01_IP2_BASE1 +	li	t2, -MALTA_MSC01_IP2_SIZE1 +	sw	t1, MSC01_BIU_IP2BAS1L_OFS(t0) +	sw	t2, MSC01_BIU_IP2MSK1L_OFS(t0) +	li	t1, MALTA_MSC01_IP2_BASE2 +	li	t2, -MALTA_MSC01_IP2_SIZE2 +	sw	t1, MSC01_BIU_IP2BAS2L_OFS(t0) +	sw	t2, MSC01_BIU_IP2MSK2L_OFS(t0) + +	/* initialise IP3 - peripheral bus controller */ +	li	t1, MALTA_MSC01_IP3_BASE +	li	t2, -MALTA_MSC01_IP3_SIZE +	sw	t1, MSC01_BIU_IP3BAS1L_OFS(t0) +	sw	t2, MSC01_BIU_IP3MSK1L_OFS(t0) +	sw	t1, MSC01_BIU_IP3BAS2L_OFS(t0) +	sw	t2, MSC01_BIU_IP3MSK2L_OFS(t0) + +	/* setup PCI memory */ +	li	t0, KSEG1ADDR(MALTA_MSC01_PCI_BASE) +	li	t1, MALTA_MSC01_PCIMEM_BASE +	li	t2, (-MALTA_MSC01_PCIMEM_SIZE) & MSC01_PCI_SC2PMMSKL_MSK_MSK +	li	t3, MALTA_MSC01_PCIMEM_MAP +	sw	t1, MSC01_PCI_SC2PMBASL_OFS(t0) +	sw	t2, MSC01_PCI_SC2PMMSKL_OFS(t0) +	sw	t3, MSC01_PCI_SC2PMMAPL_OFS(t0) + +	/* setup PCI I/O */ +	li	t1, MALTA_MSC01_PCIIO_BASE +	li	t2, (-MALTA_MSC01_PCIIO_SIZE) & MSC01_PCI_SC2PIOMSKL_MSK_MSK +	li	t3, MALTA_MSC01_PCIIO_MAP +	sw	t1, MSC01_PCI_SC2PIOBASL_OFS(t0) +	sw	t2, MSC01_PCI_SC2PIOMSKL_OFS(t0) +	sw	t3, MSC01_PCI_SC2PIOMAPL_OFS(t0) + +	/* setup PCI_BAR0 memory window */ +	li	t1, -CONFIG_SYS_MEM_SIZE +	sw	t1, MSC01_PCI_BAR0_OFS(t0) + +	/* setup PCI to SysCon/CPU translation */ +	sw	t1, MSC01_PCI_P2SCMSKL_OFS(t0) +	sw	zero, MSC01_PCI_P2SCMAPL_OFS(t0) + +	/* setup PCI vendor & device IDs */ +	li	t1, (PCI_VENDOR_ID_MIPS << MSC01_PCI_HEAD0_VENDORID_SHF) | \ +		    (PCI_DEVICE_ID_MIPS_MSC01 << MSC01_PCI_HEAD0_DEVICEID_SHF) +	sw	t1, MSC01_PCI_HEAD0_OFS(t0) + +	/* setup PCI subsystem vendor & device IDs */ +	sw	t1, MSC01_PCI_HEAD11_OFS(t0) + +	/* setup PCI class, revision */ +	li	t1, (PCI_CLASS_BRIDGE_HOST << MSC01_PCI_HEAD2_CLASS_SHF) | \ +		    (0x1 << MSC01_PCI_HEAD2_REV_SHF) +	sw	t1, MSC01_PCI_HEAD2_OFS(t0) + +	/* ensure a sane setup */ +	sw	zero, MSC01_PCI_HEAD3_OFS(t0) +	sw	zero, MSC01_PCI_HEAD4_OFS(t0) +	sw	zero, MSC01_PCI_HEAD5_OFS(t0) +	sw	zero, MSC01_PCI_HEAD6_OFS(t0) +	sw	zero, MSC01_PCI_HEAD7_OFS(t0) +	sw	zero, MSC01_PCI_HEAD8_OFS(t0) +	sw	zero, MSC01_PCI_HEAD9_OFS(t0) +	sw	zero, MSC01_PCI_HEAD10_OFS(t0) +	sw	zero, MSC01_PCI_HEAD12_OFS(t0) +	sw	zero, MSC01_PCI_HEAD13_OFS(t0) +	sw	zero, MSC01_PCI_HEAD14_OFS(t0) +	sw	zero, MSC01_PCI_HEAD15_OFS(t0) + +	/* setup PCI command register */ +	li	t1, (PCI_COMMAND_FAST_BACK | \ +		     PCI_COMMAND_SERR | \ +		     PCI_COMMAND_PARITY | \ +		     PCI_COMMAND_MASTER | \ +		     PCI_COMMAND_MEMORY) +	sw	t1, MSC01_PCI_HEAD1_OFS(t0) + +	/* setup PCI byte swapping */ +#ifdef CONFIG_SYS_BIG_ENDIAN +	li	t1, (0x1 << MSC01_PCI_SWAP_BAR0_BSWAP_SHF) | \ +		    (0x1 << MSC01_PCI_SWAP_IO_BSWAP_SHF) +	sw	t1, MSC01_PCI_SWAP_OFS(t0) +#else +	sw	zero, MSC01_PCI_SWAP_OFS(t0) +#endif + +	/* enable PCI host configuration cycles */ +	lw	t1, MSC01_PCI_CFG_OFS(t0) +	li	t2, MSC01_PCI_CFG_RA_MSK | \ +		    MSC01_PCI_CFG_G_MSK | \ +		    MSC01_PCI_CFG_EN_MSK +	or	t1, t1, t2 +	sw	t1, MSC01_PCI_CFG_OFS(t0) + +	jr	ra +	 nop diff --git a/board/imgtec/malta/malta.c b/board/imgtec/malta/malta.c new file mode 100644 index 000000000..a1a4c0186 --- /dev/null +++ b/board/imgtec/malta/malta.c @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org> + * Copyright (C) 2013 Imagination Technologies + * + * SPDX-License-Identifier:	GPL-2.0 + */ + +#include <common.h> +#include <netdev.h> +#include <pci.h> +#include <pci_gt64120.h> +#include <pci_msc01.h> +#include <rtc.h> +#include <serial.h> + +#include <asm/addrspace.h> +#include <asm/io.h> +#include <asm/malta.h> + +#include "superio.h" + +enum core_card { +	CORE_UNKNOWN, +	CORE_LV, +	CORE_FPGA6, +}; + +enum sys_con { +	SYSCON_UNKNOWN, +	SYSCON_GT64120, +	SYSCON_MSC01, +}; + +static void malta_lcd_puts(const char *str) +{ +	int i; +	void *reg = (void *)CKSEG1ADDR(MALTA_ASCIIPOS0); + +	/* print up to 8 characters of the string */ +	for (i = 0; i < min(strlen(str), 8); i++) { +		__raw_writel(str[i], reg); +		reg += MALTA_ASCIIPOS1 - MALTA_ASCIIPOS0; +	} + +	/* fill the rest of the display with spaces */ +	for (; i < 8; i++) { +		__raw_writel(' ', reg); +		reg += MALTA_ASCIIPOS1 - MALTA_ASCIIPOS0; +	} +} + +static enum core_card malta_core_card(void) +{ +	u32 corid, rev; + +	rev = __raw_readl(CKSEG1ADDR(MALTA_REVISION)); +	corid = (rev & MALTA_REVISION_CORID_MSK) >> MALTA_REVISION_CORID_SHF; + +	switch (corid) { +	case MALTA_REVISION_CORID_CORE_LV: +		return CORE_LV; + +	case MALTA_REVISION_CORID_CORE_FPGA6: +		return CORE_FPGA6; + +	default: +		return CORE_UNKNOWN; +	} +} + +static enum sys_con malta_sys_con(void) +{ +	switch (malta_core_card()) { +	case CORE_LV: +		return SYSCON_GT64120; + +	case CORE_FPGA6: +		return SYSCON_MSC01; + +	default: +		return SYSCON_UNKNOWN; +	} +} + +phys_size_t initdram(int board_type) +{ +	return CONFIG_SYS_MEM_SIZE; +} + +int checkboard(void) +{ +	enum core_card core; + +	malta_lcd_puts("U-boot"); +	puts("Board: MIPS Malta"); + +	core = malta_core_card(); +	switch (core) { +	case CORE_LV: +		puts(" CoreLV"); +		break; + +	case CORE_FPGA6: +		puts(" CoreFPGA6"); +		break; + +	default: +		puts(" CoreUnknown"); +	} + +	putc('\n'); +	return 0; +} + +int board_eth_init(bd_t *bis) +{ +	return pci_eth_init(bis); +} + +void _machine_restart(void) +{ +	void __iomem *reset_base; + +	reset_base = (void __iomem *)CKSEG1ADDR(MALTA_RESET_BASE); +	__raw_writel(GORESET, reset_base); +} + +int board_early_init_f(void) +{ +	void *io_base; + +	/* choose correct PCI I/O base */ +	switch (malta_sys_con()) { +	case SYSCON_GT64120: +		io_base = (void *)CKSEG1ADDR(MALTA_GT_PCIIO_BASE); +		break; + +	case SYSCON_MSC01: +		io_base = (void *)CKSEG1ADDR(MALTA_MSC01_PCIIO_BASE); +		break; + +	default: +		return -1; +	} + +	/* setup FDC37M817 super I/O controller */ +	malta_superio_init(io_base); + +	return 0; +} + +int misc_init_r(void) +{ +	rtc_reset(); + +	return 0; +} + +struct serial_device *default_serial_console(void) +{ +	switch (malta_sys_con()) { +	case SYSCON_GT64120: +		return &eserial1_device; + +	default: +	case SYSCON_MSC01: +		return &eserial2_device; +	} +} + +void pci_init_board(void) +{ +	pci_dev_t bdf; + +	switch (malta_sys_con()) { +	case SYSCON_GT64120: +		set_io_port_base(CKSEG1ADDR(MALTA_GT_PCIIO_BASE)); + +		gt64120_pci_init((void *)CKSEG1ADDR(MALTA_GT_BASE), +				 0x00000000, 0x00000000, CONFIG_SYS_MEM_SIZE, +				 0x10000000, 0x10000000, 128 * 1024 * 1024, +				 0x00000000, 0x00000000, 0x20000); +		break; + +	default: +	case SYSCON_MSC01: +		set_io_port_base(CKSEG1ADDR(MALTA_MSC01_PCIIO_BASE)); + +		msc01_pci_init((void *)CKSEG1ADDR(MALTA_MSC01_PCI_BASE), +			       0x00000000, 0x00000000, CONFIG_SYS_MEM_SIZE, +			       MALTA_MSC01_PCIMEM_MAP, +			       CKSEG1ADDR(MALTA_MSC01_PCIMEM_BASE), +			       MALTA_MSC01_PCIMEM_SIZE, MALTA_MSC01_PCIIO_MAP, +			       0x00000000, MALTA_MSC01_PCIIO_SIZE); +		break; +	} + +	bdf = pci_find_device(PCI_VENDOR_ID_INTEL, +			      PCI_DEVICE_ID_INTEL_82371AB_0, 0); +	if (bdf == -1) +		panic("Failed to find PIIX4 PCI bridge\n"); + +	/* setup PCI interrupt routing */ +	pci_write_config_byte(bdf, PCI_CFG_PIIX4_PIRQRCA, 10); +	pci_write_config_byte(bdf, PCI_CFG_PIIX4_PIRQRCB, 10); +	pci_write_config_byte(bdf, PCI_CFG_PIIX4_PIRQRCC, 11); +	pci_write_config_byte(bdf, PCI_CFG_PIIX4_PIRQRCD, 11); +} diff --git a/board/imgtec/malta/superio.c b/board/imgtec/malta/superio.c new file mode 100644 index 000000000..eaa14df39 --- /dev/null +++ b/board/imgtec/malta/superio.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * Setup code for the FDC37M817 super I/O controller + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> + +#define SIO_CONF_PORT		0x3f0 +#define SIO_DATA_PORT		0x3f1 + +enum sio_conf_key { +	SIOCONF_DEVNUM		= 0x07, +	SIOCONF_ACTIVATE	= 0x30, +	SIOCONF_ENTER_SETUP	= 0x55, +	SIOCONF_BASE_HIGH	= 0x60, +	SIOCONF_BASE_LOW	= 0x61, +	SIOCONF_PRIMARY_INT	= 0x70, +	SIOCONF_EXIT_SETUP	= 0xaa, +	SIOCONF_MODE		= 0xf0, +}; + +static struct { +	u8 key; +	u8 data; +} sio_config[] = { +	/* tty0 */ +	{ SIOCONF_DEVNUM,	0x04 }, +	{ SIOCONF_BASE_HIGH,	0x03 }, +	{ SIOCONF_BASE_LOW,	0xf8 }, +	{ SIOCONF_MODE,		0x02 }, +	{ SIOCONF_PRIMARY_INT,	0x04 }, +	{ SIOCONF_ACTIVATE,	0x01 }, + +	/* tty1 */ +	{ SIOCONF_DEVNUM,	0x05 }, +	{ SIOCONF_BASE_HIGH,	0x02 }, +	{ SIOCONF_BASE_LOW,	0xf8 }, +	{ SIOCONF_MODE,		0x02 }, +	{ SIOCONF_PRIMARY_INT,	0x03 }, +	{ SIOCONF_ACTIVATE,	0x01 }, +}; + +void malta_superio_init(void *io_base) +{ +	unsigned i; + +	/* enter config state */ +	writeb(SIOCONF_ENTER_SETUP, io_base + SIO_CONF_PORT); + +	/* configure peripherals */ +	for (i = 0; i < ARRAY_SIZE(sio_config); i++) { +		writeb(sio_config[i].key, io_base + SIO_CONF_PORT); +		writeb(sio_config[i].data, io_base + SIO_DATA_PORT); +	} + +	/* exit config state */ +	writeb(SIOCONF_EXIT_SETUP, io_base + SIO_CONF_PORT); +} diff --git a/board/imgtec/malta/superio.h b/board/imgtec/malta/superio.h new file mode 100644 index 000000000..1450da56d --- /dev/null +++ b/board/imgtec/malta/superio.h @@ -0,0 +1,15 @@ +/* + * Copyright (C) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * Setup code for the FDC37M817 super I/O controller + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __BOARD_MALTA_SUPERIO_H__ +#define __BOARD_MALTA_SUPERIO_H__ + +extern void malta_superio_init(void *io_base); + +#endif /* __BOARD_MALTA_SUPERIO_H__ */ diff --git a/board/qemu-malta/lowlevel_init.S b/board/qemu-malta/lowlevel_init.S deleted file mode 100644 index fa0b6a7d1..000000000 --- a/board/qemu-malta/lowlevel_init.S +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org> - * - * SPDX-License-Identifier:	GPL-2.0 - */ - -#include <config.h> -#include <gt64120.h> - -#include <asm/addrspace.h> -#include <asm/regdef.h> -#include <asm/malta.h> - -#ifdef CONFIG_SYS_BIG_ENDIAN -#define CPU_TO_GT32(_x)		((_x)) -#else -#define CPU_TO_GT32(_x) (					\ -	(((_x) & 0xff) << 24) | (((_x) & 0xff00) << 8) |	\ -	(((_x) & 0xff0000) >> 8) | (((_x) & 0xff000000) >> 24)) -#endif - -	.text -	.set noreorder -	.set mips32 - -	.globl	lowlevel_init -lowlevel_init: - -	/* -	 * Load BAR registers of GT64120 as done by YAMON -	 * -	 * based on a patch sent by Antony Pavlov <antonynpavlov@gmail.com> -	 * to the barebox mailing list. -	 * The subject of the original patch: -	 *   'MIPS: qemu-malta: add YAMON-style GT64120 memory map' -	 * URL: -	 * http://www.mail-archive.com/barebox@lists.infradead.org/msg06128.html -	 * -	 * based on write_bootloader() in qemu.git/hw/mips_malta.c -	 * see GT64120 manual and qemu.git/hw/gt64xxx.c for details -	 */ - -	/* move GT64120 registers from 0x14000000 to 0x1be00000 */ -	li	t1, KSEG1ADDR(GT_DEF_BASE) -	li	t0, CPU_TO_GT32(0xdf000000) -	sw	t0, GT_ISD_OFS(t1) - -	/* setup MEM-to-PCI0 mapping */ -	li	t1, KSEG1ADDR(MALTA_GT_BASE) - -	/* setup PCI0 io window to 0x18000000-0x181fffff */ -	li	t0, CPU_TO_GT32(0xc0000000) -	sw	t0, GT_PCI0IOLD_OFS(t1) -	li	t0, CPU_TO_GT32(0x40000000) -	sw	t0, GT_PCI0IOHD_OFS(t1) - -	/* setup PCI0 mem windows */ -	li	t0, CPU_TO_GT32(0x80000000) -	sw	t0, GT_PCI0M0LD_OFS(t1) -	li	t0, CPU_TO_GT32(0x3f000000) -	sw	t0, GT_PCI0M0HD_OFS(t1) - -	li	t0, CPU_TO_GT32(0xc1000000) -	sw	t0, GT_PCI0M1LD_OFS(t1) -	li	t0, CPU_TO_GT32(0x5e000000) -	sw	t0, GT_PCI0M1HD_OFS(t1) - -	jr	ra -	 nop diff --git a/board/qemu-malta/qemu-malta.c b/board/qemu-malta/qemu-malta.c deleted file mode 100644 index 7eddf1ce6..000000000 --- a/board/qemu-malta/qemu-malta.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2013 Gabor Juhos <juhosg@openwrt.org> - * - * SPDX-License-Identifier:	GPL-2.0 - */ - -#include <common.h> -#include <netdev.h> - -#include <asm/addrspace.h> -#include <asm/io.h> -#include <asm/malta.h> -#include <pci_gt64120.h> - -phys_size_t initdram(int board_type) -{ -	return CONFIG_SYS_MEM_SIZE; -} - -int checkboard(void) -{ -	puts("Board: MIPS Malta CoreLV (Qemu)\n"); -	return 0; -} - -int board_eth_init(bd_t *bis) -{ -	return pci_eth_init(bis); -} - -void _machine_restart(void) -{ -	void __iomem *reset_base; - -	reset_base = (void __iomem *)CKSEG1ADDR(MALTA_RESET_BASE); -	__raw_writel(GORESET, reset_base); -} - -void pci_init_board(void) -{ -	set_io_port_base(CKSEG1ADDR(MALTA_IO_PORT_BASE)); - -	gt64120_pci_init((void *)CKSEG1ADDR(MALTA_GT_BASE), -			 0x00000000, 0x00000000, CONFIG_SYS_MEM_SIZE, -			 0x10000000, 0x10000000, 128 * 1024 * 1024, -			 0x00000000, 0x00000000, 0x20000); -} diff --git a/boards.cfg b/boards.cfg index ce5b68606..7ee63ee3c 100644 --- a/boards.cfg +++ b/boards.cfg @@ -482,10 +482,10 @@ Active  m68k        mcf547x_8x     -           freescale       m548xevb  Active  m68k        mcf547x_8x     -           freescale       m548xevb            M5485GFE                             M5485EVB:SYS_BUSCLK=100000000,SYS_BOOTSZ=4,SYS_DRAMSZ=64                                                                          TsiChung Liew <Tsi-Chung.Liew@freescale.com>  Active  m68k        mcf547x_8x     -           freescale       m548xevb            M5485HFE                             M5485EVB:SYS_BUSCLK=100000000,SYS_BOOTSZ=2,SYS_DRAMSZ=64,SYS_NOR1SZ=16,SYS_VIDEO                                                  TsiChung Liew <Tsi-Chung.Liew@freescale.com>  Active  microblaze  microblaze     -           xilinx          microblaze-generic  microblaze-generic                   -                                                                                                                                 Michal Simek <monstr@monstr.eu> -Active  mips        mips32         -           -               qemu-malta          qemu_malta                           qemu-malta:MIPS32,SYS_BIG_ENDIAN                                                                                                  - -Active  mips        mips32         -           -               qemu-malta          qemu_maltael                         qemu-malta:MIPS32,SYS_LITTLE_ENDIAN                                                                                               -  Active  mips        mips32         -           -               qemu-mips           qemu_mips                            qemu-mips:SYS_BIG_ENDIAN                                                                                                          Vlad Lungu <vlad.lungu@windriver.com>  Active  mips        mips32         -           -               qemu-mips           qemu_mipsel                          qemu-mips:SYS_LITTLE_ENDIAN                                                                                                       - +Active  mips        mips32         -           imgtec          malta               malta                                malta:MIPS32,SYS_BIG_ENDIAN                                                                                                       Paul Burton <paul.burton@imgtec.com> +Active  mips        mips32         -           imgtec          malta               maltael                              malta:MIPS32,SYS_LITTLE_ENDIAN                                                                                                    Paul Burton <paul.burton@imgtec.com>  Active  mips        mips32         -           micronas        vct                 vct_platinum                         vct:VCT_PLATINUM                                                                                                                  -  Active  mips        mips32         -           micronas        vct                 vct_platinum_onenand                 vct:VCT_PLATINUM,VCT_ONENAND                                                                                                      -  Active  mips        mips32         -           micronas        vct                 vct_platinum_onenand_small           vct:VCT_PLATINUM,VCT_ONENAND,VCT_SMALL_IMAGE                                                                                      - diff --git a/doc/README.malta b/doc/README.malta new file mode 100644 index 000000000..a495d0245 --- /dev/null +++ b/doc/README.malta @@ -0,0 +1,16 @@ +MIPS Malta board + +How to flash using a MIPS Navigator Probe: + +  - Ensure that your Malta has jumper JP1 fitted. Without this jumper you will +    be unable to flash your Malta using a Navigator Probe. + +  - Connect Navigator Console to your probe and Malta as usual. + +  - Within Navigator Console run the following commands: + +      source /path/to/u-boot/board/malta/flash-malta-boot.tcl +      reset +      flash-boot /path/to/u-boot/u-boot.bin + +  - You should now be able to reboot your Malta to a U-boot shell. diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 283cb48b4..5b248bee4 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -89,39 +89,39 @@ static pcnet_priv_t *lp;  #define PCNET_RESET		0x14  #define PCNET_BDP		0x16 -static u16 pcnet_read_csr (struct eth_device *dev, int index) +static u16 pcnet_read_csr(struct eth_device *dev, int index)  { -	outw (index, dev->iobase + PCNET_RAP); -	return inw (dev->iobase + PCNET_RDP); +	outw(index, dev->iobase + PCNET_RAP); +	return inw(dev->iobase + PCNET_RDP);  } -static void pcnet_write_csr (struct eth_device *dev, int index, u16 val) +static void pcnet_write_csr(struct eth_device *dev, int index, u16 val)  { -	outw (index, dev->iobase + PCNET_RAP); -	outw (val, dev->iobase + PCNET_RDP); +	outw(index, dev->iobase + PCNET_RAP); +	outw(val, dev->iobase + PCNET_RDP);  } -static u16 pcnet_read_bcr (struct eth_device *dev, int index) +static u16 pcnet_read_bcr(struct eth_device *dev, int index)  { -	outw (index, dev->iobase + PCNET_RAP); -	return inw (dev->iobase + PCNET_BDP); +	outw(index, dev->iobase + PCNET_RAP); +	return inw(dev->iobase + PCNET_BDP);  } -static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val) +static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val)  { -	outw (index, dev->iobase + PCNET_RAP); -	outw (val, dev->iobase + PCNET_BDP); +	outw(index, dev->iobase + PCNET_RAP); +	outw(val, dev->iobase + PCNET_BDP);  } -static void pcnet_reset (struct eth_device *dev) +static void pcnet_reset(struct eth_device *dev)  { -	inw (dev->iobase + PCNET_RESET); +	inw(dev->iobase + PCNET_RESET);  } -static int pcnet_check (struct eth_device *dev) +static int pcnet_check(struct eth_device *dev)  { -	outw (88, dev->iobase + PCNET_RAP); -	return (inw (dev->iobase + PCNET_RAP) == 88); +	outw(88, dev->iobase + PCNET_RAP); +	return inw(dev->iobase + PCNET_RAP) == 88;  }  static int pcnet_init (struct eth_device *dev, bd_t * bis); @@ -139,63 +139,64 @@ static struct pci_device_id supported[] = {  }; -int pcnet_initialize (bd_t * bis) +int pcnet_initialize(bd_t *bis)  {  	pci_dev_t devbusfn;  	struct eth_device *dev;  	u16 command, status;  	int dev_nr = 0; -	PCNET_DEBUG1 ("\npcnet_initialize...\n"); +	PCNET_DEBUG1("\npcnet_initialize...\n");  	for (dev_nr = 0;; dev_nr++) {  		/*  		 * Find the PCnet PCI device(s).  		 */ -		if ((devbusfn = pci_find_devices (supported, dev_nr)) < 0) { +		devbusfn = pci_find_devices(supported, dev_nr); +		if (devbusfn < 0)  			break; -		}  		/*  		 * Allocate and pre-fill the device structure.  		 */ -		dev = (struct eth_device *) malloc (sizeof *dev); +		dev = (struct eth_device *)malloc(sizeof(*dev));  		if (!dev) {  			printf("pcnet: Can not allocate memory\n");  			break;  		}  		memset(dev, 0, sizeof(*dev)); -		dev->priv = (void *) devbusfn; -		sprintf (dev->name, "pcnet#%d", dev_nr); +		dev->priv = (void *)devbusfn; +		sprintf(dev->name, "pcnet#%d", dev_nr);  		/*  		 * Setup the PCI device.  		 */ -		pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, -				       (unsigned int *) &dev->iobase); -		dev->iobase=pci_io_to_phys (devbusfn, dev->iobase); +		pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, +				      (unsigned int *)&dev->iobase); +		dev->iobase = pci_io_to_phys(devbusfn, dev->iobase);  		dev->iobase &= ~0xf; -		PCNET_DEBUG1 ("%s: devbusfn=0x%x iobase=0x%x: ", -			      dev->name, devbusfn, dev->iobase); +		PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ", +			     dev->name, devbusfn, dev->iobase);  		command = PCI_COMMAND_IO | PCI_COMMAND_MASTER; -		pci_write_config_word (devbusfn, PCI_COMMAND, command); -		pci_read_config_word (devbusfn, PCI_COMMAND, &status); +		pci_write_config_word(devbusfn, PCI_COMMAND, command); +		pci_read_config_word(devbusfn, PCI_COMMAND, &status);  		if ((status & command) != command) { -			printf ("%s: Couldn't enable IO access or Bus Mastering\n", dev->name); -			free (dev); +			printf("%s: Couldn't enable IO access or Bus Mastering\n", +			       dev->name); +			free(dev);  			continue;  		} -		pci_write_config_byte (devbusfn, PCI_LATENCY_TIMER, 0x40); +		pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40);  		/*  		 * Probe the PCnet chip.  		 */ -		if (pcnet_probe (dev, bis, dev_nr) < 0) { -			free (dev); +		if (pcnet_probe(dev, bis, dev_nr) < 0) { +			free(dev);  			continue;  		} @@ -207,15 +208,15 @@ int pcnet_initialize (bd_t * bis)  		dev->send = pcnet_send;  		dev->recv = pcnet_recv; -		eth_register (dev); +		eth_register(dev);  	} -	udelay (10 * 1000); +	udelay(10 * 1000);  	return dev_nr;  } -static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr) +static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr)  {  	int chip_version;  	char *chipname; @@ -225,17 +226,17 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)  #endif  	/* Reset the PCnet controller */ -	pcnet_reset (dev); +	pcnet_reset(dev);  	/* Check if register access is working */ -	if (pcnet_read_csr (dev, 0) != 4 || !pcnet_check (dev)) { -		printf ("%s: CSR register access check failed\n", dev->name); +	if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) { +		printf("%s: CSR register access check failed\n", dev->name);  		return -1;  	}  	/* Identify the chip */  	chip_version = -		pcnet_read_csr (dev, 88) | (pcnet_read_csr (dev, 89) << 16); +		pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev, 89) << 16);  	if ((chip_version & 0xfff) != 0x003)  		return -1;  	chip_version = (chip_version >> 12) & 0xffff; @@ -254,12 +255,12 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)  		break;  #endif  	default: -		printf ("%s: PCnet version %#x not supported\n", -			dev->name, chip_version); +		printf("%s: PCnet version %#x not supported\n", +		       dev->name, chip_version);  		return -1;  	} -	PCNET_DEBUG1 ("AMD %s\n", chipname); +	PCNET_DEBUG1("AMD %s\n", chipname);  #ifdef PCNET_HAS_PROM  	/* @@ -270,7 +271,7 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)  	for (i = 0; i < 3; i++) {  		unsigned int val; -		val = pcnet_read_csr (dev, i + 12) & 0x0ffff; +		val = pcnet_read_csr(dev, i + 12) & 0x0ffff;  		/* There may be endianness issues here. */  		dev->enetaddr[2 * i] = val & 0x0ff;  		dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; @@ -280,35 +281,50 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr)  	return 0;  } -static int pcnet_init (struct eth_device *dev, bd_t * bis) +static int pcnet_init(struct eth_device *dev, bd_t *bis)  {  	int i, val;  	u32 addr; -	PCNET_DEBUG1 ("%s: pcnet_init...\n", dev->name); +	PCNET_DEBUG1("%s: pcnet_init...\n", dev->name);  	/* Switch pcnet to 32bit mode */ -	pcnet_write_bcr (dev, 20, 2); +	pcnet_write_bcr(dev, 20, 2);  #ifdef CONFIG_PN62  	/* Setup LED registers */ -	val = pcnet_read_bcr (dev, 2) | 0x1000; -	pcnet_write_bcr (dev, 2, val);	/* enable LEDPE */ -	pcnet_write_bcr (dev, 4, 0x5080);	/* 100MBit */ -	pcnet_write_bcr (dev, 5, 0x40c0);	/* LNKSE */ -	pcnet_write_bcr (dev, 6, 0x4090);	/* TX Activity */ -	pcnet_write_bcr (dev, 7, 0x4084);	/* RX Activity */ +	val = pcnet_read_bcr(dev, 2) | 0x1000; +	pcnet_write_bcr(dev, 2, val);	/* enable LEDPE */ +	pcnet_write_bcr(dev, 4, 0x5080);	/* 100MBit */ +	pcnet_write_bcr(dev, 5, 0x40c0);	/* LNKSE */ +	pcnet_write_bcr(dev, 6, 0x4090);	/* TX Activity */ +	pcnet_write_bcr(dev, 7, 0x4084);	/* RX Activity */  #endif  	/* Set/reset autoselect bit */ -	val = pcnet_read_bcr (dev, 2) & ~2; +	val = pcnet_read_bcr(dev, 2) & ~2;  	val |= 2; -	pcnet_write_bcr (dev, 2, val); +	pcnet_write_bcr(dev, 2, val);  	/* Enable auto negotiate, setup, disable fd */ -	val = pcnet_read_bcr (dev, 32) & ~0x98; +	val = pcnet_read_bcr(dev, 32) & ~0x98;  	val |= 0x20; -	pcnet_write_bcr (dev, 32, val); +	pcnet_write_bcr(dev, 32, val); + +	/* +	 * Enable NOUFLO on supported controllers, with the transmit +	 * start point set to the full packet. This will cause entire +	 * packets to be buffered by the ethernet controller before +	 * transmission, eliminating underflows which are common on +	 * slower devices. Controllers which do not support NOUFLO will +	 * simply be left with a larger transmit FIFO threshold. +	 */ +	val = pcnet_read_bcr(dev, 18); +	val |= 1 << 11; +	pcnet_write_bcr(dev, 18, val); +	val = pcnet_read_csr(dev, 80); +	val |= 0x3 << 10; +	pcnet_write_csr(dev, 80, val);  	/*  	 * We only maintain one structure because the drivers will never @@ -316,12 +332,12 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis)  	 * must be aligned on 16-byte boundaries.  	 */  	if (lp == NULL) { -		addr = (u32) malloc (sizeof (pcnet_priv_t) + 0x10); +		addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10);  		addr = (addr + 0xf) & ~0xf; -		lp = (pcnet_priv_t *) addr; +		lp = (pcnet_priv_t *)addr;  	} -	lp->init_block.mode = cpu_to_le16 (0x0000); +	lp->init_block.mode = cpu_to_le16(0x0000);  	lp->init_block.filter[0] = 0x00000000;  	lp->init_block.filter[1] = 0x00000000; @@ -330,9 +346,9 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis)  	 */  	lp->cur_rx = 0;  	for (i = 0; i < RX_RING_SIZE; i++) { -		lp->rx_ring[i].base = PCI_TO_MEM_LE (dev, lp->rx_buf[i]); -		lp->rx_ring[i].buf_length = cpu_to_le16 (-PKT_BUF_SZ); -		lp->rx_ring[i].status = cpu_to_le16 (0x8000); +		lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]); +		lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); +		lp->rx_ring[i].status = cpu_to_le16(0x8000);  		PCNET_DEBUG1  			("Rx%d: base=0x%x buf_length=0x%hx status=0x%hx\n", i,  			 lp->rx_ring[i].base, lp->rx_ring[i].buf_length, @@ -352,48 +368,49 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis)  	/*  	 * Setup Init Block.  	 */ -	PCNET_DEBUG1 ("Init block at 0x%p: MAC", &lp->init_block); +	PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->init_block);  	for (i = 0; i < 6; i++) {  		lp->init_block.phys_addr[i] = dev->enetaddr[i]; -		PCNET_DEBUG1 (" %02x", lp->init_block.phys_addr[i]); +		PCNET_DEBUG1(" %02x", lp->init_block.phys_addr[i]);  	} -	lp->init_block.tlen_rlen = cpu_to_le16 (TX_RING_LEN_BITS | -						RX_RING_LEN_BITS); -	lp->init_block.rx_ring = PCI_TO_MEM_LE (dev, lp->rx_ring); -	lp->init_block.tx_ring = PCI_TO_MEM_LE (dev, lp->tx_ring); +	lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | +					       RX_RING_LEN_BITS); +	lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring); +	lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring); +	flush_dcache_range((unsigned long)lp, (unsigned long)&lp->rx_buf); -	PCNET_DEBUG1 ("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", -		      lp->init_block.tlen_rlen, -		      lp->init_block.rx_ring, lp->init_block.tx_ring); +	PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", +		     lp->init_block.tlen_rlen, +		     lp->init_block.rx_ring, lp->init_block.tx_ring);  	/*  	 * Tell the controller where the Init Block is located.  	 */ -	addr = PCI_TO_MEM (dev, &lp->init_block); -	pcnet_write_csr (dev, 1, addr & 0xffff); -	pcnet_write_csr (dev, 2, (addr >> 16) & 0xffff); +	addr = PCI_TO_MEM(dev, &lp->init_block); +	pcnet_write_csr(dev, 1, addr & 0xffff); +	pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); -	pcnet_write_csr (dev, 4, 0x0915); -	pcnet_write_csr (dev, 0, 0x0001);	/* start */ +	pcnet_write_csr(dev, 4, 0x0915); +	pcnet_write_csr(dev, 0, 0x0001);	/* start */  	/* Wait for Init Done bit */  	for (i = 10000; i > 0; i--) { -		if (pcnet_read_csr (dev, 0) & 0x0100) +		if (pcnet_read_csr(dev, 0) & 0x0100)  			break; -		udelay (10); +		udelay(10);  	}  	if (i <= 0) { -		printf ("%s: TIMEOUT: controller init failed\n", dev->name); -		pcnet_reset (dev); +		printf("%s: TIMEOUT: controller init failed\n", dev->name); +		pcnet_reset(dev);  		return -1;  	}  	/*  	 * Finally start network controller operation.  	 */ -	pcnet_write_csr (dev, 0, 0x0002); +	pcnet_write_csr(dev, 0, 0x0002);  	return 0;  } @@ -403,20 +420,25 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len)  	int i, status;  	struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx]; -	PCNET_DEBUG2 ("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, -		      packet); +	PCNET_DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, +		     packet); + +	flush_dcache_range((unsigned long)packet, +			   (unsigned long)packet + pkt_len);  	/* Wait for completion by testing the OWN bit */  	for (i = 1000; i > 0; i--) { -		status = le16_to_cpu (entry->status); +		invalidate_dcache_range((unsigned long)entry, +					(unsigned long)entry + sizeof(*entry)); +		status = le16_to_cpu(entry->status);  		if ((status & 0x8000) == 0)  			break; -		udelay (100); -		PCNET_DEBUG2 ("."); +		udelay(100); +		PCNET_DEBUG2(".");  	}  	if (i <= 0) { -		printf ("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", -			dev->name, lp->cur_tx, status); +		printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", +		       dev->name, lp->cur_tx, status);  		pkt_len = 0;  		goto failure;  	} @@ -426,19 +448,21 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len)  	 * set the status with the "ownership" bits last.  	 */  	status = 0x8300; -	entry->length = le16_to_cpu (-pkt_len); +	entry->length = cpu_to_le16(-pkt_len);  	entry->misc = 0x00000000; -	entry->base = PCI_TO_MEM_LE (dev, packet); -	entry->status = le16_to_cpu (status); +	entry->base = PCI_TO_MEM_LE(dev, packet); +	entry->status = cpu_to_le16(status); +	flush_dcache_range((unsigned long)entry, +			   (unsigned long)entry + sizeof(*entry));  	/* Trigger an immediate send poll. */ -	pcnet_write_csr (dev, 0, 0x0008); +	pcnet_write_csr(dev, 0, 0x0008);        failure:  	if (++lp->cur_tx >= TX_RING_SIZE)  		lp->cur_tx = 0; -	PCNET_DEBUG2 ("done\n"); +	PCNET_DEBUG2("done\n");  	return pkt_len;  } @@ -450,43 +474,49 @@ static int pcnet_recv (struct eth_device *dev)  	while (1) {  		entry = &lp->rx_ring[lp->cur_rx]; +		invalidate_dcache_range((unsigned long)entry, +					(unsigned long)entry + sizeof(*entry));  		/*  		 * If we own the next entry, it's a new packet. Send it up.  		 */ -		if (((status = le16_to_cpu (entry->status)) & 0x8000) != 0) { +		status = le16_to_cpu(entry->status); +		if ((status & 0x8000) != 0)  			break; -		}  		status >>= 8;  		if (status != 0x03) {	/* There was an error. */ - -			printf ("%s: Rx%d", dev->name, lp->cur_rx); -			PCNET_DEBUG1 (" (status=0x%x)", status); +			printf("%s: Rx%d", dev->name, lp->cur_rx); +			PCNET_DEBUG1(" (status=0x%x)", status);  			if (status & 0x20) -				printf (" Frame"); +				printf(" Frame");  			if (status & 0x10) -				printf (" Overflow"); +				printf(" Overflow");  			if (status & 0x08) -				printf (" CRC"); +				printf(" CRC");  			if (status & 0x04) -				printf (" Fifo"); -			printf (" Error\n"); -			entry->status &= le16_to_cpu (0x03ff); +				printf(" Fifo"); +			printf(" Error\n"); +			entry->status &= le16_to_cpu(0x03ff);  		} else { - -			pkt_len = -				(le32_to_cpu (entry->msg_length) & 0xfff) - 4; +			pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4;  			if (pkt_len < 60) { -				printf ("%s: Rx%d: invalid packet length %d\n", dev->name, lp->cur_rx, pkt_len); +				printf("%s: Rx%d: invalid packet length %d\n", +				       dev->name, lp->cur_rx, pkt_len);  			} else { -				NetReceive (lp->rx_buf[lp->cur_rx], pkt_len); -				PCNET_DEBUG2 ("Rx%d: %d bytes from 0x%p\n", -					      lp->cur_rx, pkt_len, -					      lp->rx_buf[lp->cur_rx]); +				invalidate_dcache_range( +					(unsigned long)lp->rx_buf[lp->cur_rx], +					(unsigned long)lp->rx_buf[lp->cur_rx] + +					pkt_len); +				NetReceive(lp->rx_buf[lp->cur_rx], pkt_len); +				PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", +					     lp->cur_rx, pkt_len, +					     lp->rx_buf[lp->cur_rx]);  			}  		} -		entry->status |= cpu_to_le16 (0x8000); +		entry->status |= cpu_to_le16(0x8000); +		flush_dcache_range((unsigned long)entry, +				   (unsigned long)entry + sizeof(*entry));  		if (++lp->cur_rx >= RX_RING_SIZE)  			lp->cur_rx = 0; @@ -494,22 +524,21 @@ static int pcnet_recv (struct eth_device *dev)  	return pkt_len;  } -static void pcnet_halt (struct eth_device *dev) +static void pcnet_halt(struct eth_device *dev)  {  	int i; -	PCNET_DEBUG1 ("%s: pcnet_halt...\n", dev->name); +	PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name);  	/* Reset the PCnet controller */ -	pcnet_reset (dev); +	pcnet_reset(dev);  	/* Wait for Stop bit */  	for (i = 1000; i > 0; i--) { -		if (pcnet_read_csr (dev, 0) & 0x4) +		if (pcnet_read_csr(dev, 0) & 0x4)  			break; -		udelay (10); -	} -	if (i <= 0) { -		printf ("%s: TIMEOUT: controller reset failed\n", dev->name); +		udelay(10);  	} +	if (i <= 0) +		printf("%s: TIMEOUT: controller reset failed\n", dev->name);  } diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 99d51a6a9..6182a5904 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o  obj-$(CONFIG_PCI) += pci.o pci_auto.o  obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o  obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o +obj-$(CONFIG_PCI_MSC01) += pci_msc01.o  obj-$(CONFIG_FTPCI100) += pci_ftpci100.o  obj-$(CONFIG_IXP_PCI) += pci_ixp.o  obj-$(CONFIG_SH4_PCI) += pci_sh4.o diff --git a/drivers/pci/pci_msc01.c b/drivers/pci/pci_msc01.c new file mode 100644 index 000000000..284ffa09b --- /dev/null +++ b/drivers/pci/pci_msc01.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> +#include <msc01.h> +#include <pci.h> +#include <pci_msc01.h> +#include <asm/io.h> + +#define PCI_ACCESS_READ  0 +#define PCI_ACCESS_WRITE 1 + +struct msc01_pci_controller { +	struct pci_controller hose; +	void *base; +}; + +static inline struct msc01_pci_controller * +hose_to_msc01(struct pci_controller *hose) +{ +	return container_of(hose, struct msc01_pci_controller, hose); +} + +static int msc01_config_access(struct msc01_pci_controller *msc01, +			       unsigned char access_type, pci_dev_t bdf, +			       int where, u32 *data) +{ +	const u32 aborts = MSC01_PCI_INTSTAT_MA_MSK | MSC01_PCI_INTSTAT_TA_MSK; +	void *intstat = msc01->base + MSC01_PCI_INTSTAT_OFS; +	void *cfgdata = msc01->base + MSC01_PCI_CFGDATA_OFS; +	unsigned int bus = PCI_BUS(bdf); +	unsigned int dev = PCI_DEV(bdf); +	unsigned int devfn = PCI_DEV(bdf) << 3 | PCI_FUNC(bdf); + +	/* clear abort status */ +	__raw_writel(aborts, intstat); + +	/* setup address */ +	__raw_writel((bus << MSC01_PCI_CFGADDR_BNUM_SHF) | +		     (dev << MSC01_PCI_CFGADDR_DNUM_SHF) | +		     (devfn << MSC01_PCI_CFGADDR_FNUM_SHF) | +		     ((where / 4) << MSC01_PCI_CFGADDR_RNUM_SHF), +		     msc01->base + MSC01_PCI_CFGADDR_OFS); + +	/* perform access */ +	if (access_type == PCI_ACCESS_WRITE) +		__raw_writel(*data, cfgdata); +	else +		*data = __raw_readl(cfgdata); + +	/* check for aborts */ +	if (__raw_readl(intstat) & aborts) { +		/* clear abort status */ +		__raw_writel(aborts, intstat); +		return -1; +	} + +	return 0; +} + +static int msc01_read_config_dword(struct pci_controller *hose, pci_dev_t dev, +				   int where, u32 *value) +{ +	struct msc01_pci_controller *msc01 = hose_to_msc01(hose); + +	*value = 0xffffffff; +	return msc01_config_access(msc01, PCI_ACCESS_READ, dev, where, value); +} + +static int msc01_write_config_dword(struct pci_controller *hose, pci_dev_t dev, +				    int where, u32 value) +{ +	struct msc01_pci_controller *gt = hose_to_msc01(hose); +	u32 data = value; + +	return msc01_config_access(gt, PCI_ACCESS_WRITE, dev, where, &data); +} + +void msc01_pci_init(void *base, unsigned long sys_bus, unsigned long sys_phys, +		    unsigned long sys_size, unsigned long mem_bus, +		    unsigned long mem_phys, unsigned long mem_size, +		    unsigned long io_bus, unsigned long io_phys, +		    unsigned long io_size) +{ +	static struct msc01_pci_controller global_msc01; +	struct msc01_pci_controller *msc01; +	struct pci_controller *hose; + +	msc01 = &global_msc01; +	msc01->base = base; + +	hose = &msc01->hose; + +	hose->first_busno = 0; +	hose->last_busno = 0; + +	/* System memory space */ +	pci_set_region(&hose->regions[0], sys_bus, sys_phys, sys_size, +		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY); + +	/* PCI memory space */ +	pci_set_region(&hose->regions[1], mem_bus, mem_phys, mem_size, +		       PCI_REGION_MEM); + +	/* PCI I/O space */ +	pci_set_region(&hose->regions[2], io_bus, io_phys, io_size, +		       PCI_REGION_IO); + +	hose->region_count = 3; + +	pci_set_ops(hose, +		    pci_hose_read_config_byte_via_dword, +		    pci_hose_read_config_word_via_dword, +		    msc01_read_config_dword, +		    pci_hose_write_config_byte_via_dword, +		    pci_hose_write_config_word_via_dword, +		    msc01_write_config_dword); + +	pci_register_hose(hose); +	hose->last_busno = pci_hose_scan(hose); +} diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index 5f9d35959..f7cf1064f 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -15,7 +15,7 @@  #include <command.h>  #include <rtc.h> -#ifdef __I386__ +#if defined(__I386__) || defined(CONFIG_MALTA)  #include <asm/io.h>  #define in8(p) inb(p)  #define out8(p, v) outb(v, p) diff --git a/include/configs/qemu-malta.h b/include/configs/malta.h index 03514d165..4098e724f 100644 --- a/include/configs/qemu-malta.h +++ b/include/configs/malta.h @@ -4,8 +4,8 @@   * SPDX-License-Identifier:	GPL-2.0   */ -#ifndef _QEMU_MALTA_CONFIG_H -#define _QEMU_MALTA_CONFIG_H +#ifndef _MALTA_CONFIG_H +#define _MALTA_CONFIG_H  #include <asm/addrspace.h>  #include <asm/malta.h> @@ -13,12 +13,21 @@  /*   * System configuration   */ -#define CONFIG_QEMU_MALTA +#define CONFIG_MALTA + +#define CONFIG_MEMSIZE_IN_BYTES  #define CONFIG_PCI  #define CONFIG_PCI_GT64120 +#define CONFIG_PCI_MSC01  #define CONFIG_PCI_PNP  #define CONFIG_PCNET +#define CONFIG_PCNET_79C973 +#define PCNET_HAS_PROM + +#define CONFIG_MISC_INIT_R +#define CONFIG_RTC_MC146818 +#define CONFIG_SYS_ISA_IO_BASE_ADDRESS	0  /*   * CPU Configuration @@ -26,10 +35,6 @@  #define CONFIG_SYS_MHZ			250	/* arbitrary value */  #define CONFIG_SYS_MIPS_TIMER_FREQ	(CONFIG_SYS_MHZ * 1000000) -#define CONFIG_SYS_DCACHE_SIZE		16384	/* arbitrary value */ -#define CONFIG_SYS_ICACHE_SIZE		16384	/* arbitrary value */ -#define CONFIG_SYS_CACHELINE_SIZE	32	/* arbitrary value */ -  #define CONFIG_SWAP_IO_SPACE  /* @@ -54,9 +59,9 @@   * Console configuration   */  #if defined(CONFIG_SYS_LITTLE_ENDIAN) -#define CONFIG_SYS_PROMPT		"qemu-maltael # " +#define CONFIG_SYS_PROMPT		"maltael # "  #else -#define CONFIG_SYS_PROMPT		"qemu-malta # " +#define CONFIG_SYS_PROMPT		"malta # "  #endif  #define CONFIG_SYS_CBSIZE		256 @@ -76,16 +81,11 @@  #define CONFIG_SYS_NS16550_SERIAL  #define CONFIG_SYS_NS16550_REG_SIZE	1  #define CONFIG_SYS_NS16550_CLK		115200 -#define CONFIG_SYS_NS16550_COM1		CKSEG1ADDR(MALTA_UART_BASE) +#define CONFIG_SYS_NS16550_COM1		CKSEG1ADDR(MALTA_GT_UART0_BASE) +#define CONFIG_SYS_NS16550_COM2		CKSEG1ADDR(MALTA_MSC01_UART0_BASE)  #define CONFIG_CONS_INDEX		1  /* - * Environment - */ -#define CONFIG_ENV_IS_NOWHERE -#define CONFIG_ENV_SIZE			0x10000 - -/*   * Flash configuration   */  #define CONFIG_SYS_FLASH_BASE		(KSEG1 | MALTA_FLASH_BASE) @@ -96,6 +96,15 @@  #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE  /* + * Environment + */ +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_SECT_SIZE		0x20000 +#define CONFIG_ENV_SIZE			CONFIG_ENV_SECT_SIZE +#define CONFIG_ENV_ADDR \ +	(CONFIG_SYS_FLASH_BASE + (4 << 20) - CONFIG_ENV_SIZE) + +/*   * Commands   */  #include <config_cmd_default.h> @@ -105,9 +114,11 @@  #undef CONFIG_CMD_LOADS  #undef CONFIG_CMD_NFS +#define CONFIG_CMD_DATE +#define CONFIG_CMD_DHCP  #define CONFIG_CMD_PCI  #define CONFIG_CMD_PING  #define CONFIG_SYS_LONGHELP		/* verbose help, undef to save memory */ -#endif /* _QEMU_MALTA_CONFIG_H */ +#endif /* _MALTA_CONFIG_H */ diff --git a/include/msc01.h b/include/msc01.h new file mode 100644 index 000000000..37cf963f1 --- /dev/null +++ b/include/msc01.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __MSC01_H__ +#define __MSC01_H__ + +/* + * Bus Interface Unit + */ + +#define MSC01_BIU_IP1BAS1L_OFS		0x0208 +#define MSC01_BIU_IP1MSK1L_OFS		0x0218 +#define MSC01_BIU_IP1BAS2L_OFS		0x0248 +#define MSC01_BIU_IP1MSK2L_OFS		0x0258 +#define MSC01_BIU_IP2BAS1L_OFS		0x0288 +#define MSC01_BIU_IP2MSK1L_OFS		0x0298 +#define MSC01_BIU_IP2BAS2L_OFS		0x02c8 +#define MSC01_BIU_IP2MSK2L_OFS		0x02d8 +#define MSC01_BIU_IP3BAS1L_OFS		0x0308 +#define MSC01_BIU_IP3MSK1L_OFS		0x0318 +#define MSC01_BIU_IP3BAS2L_OFS		0x0348 +#define MSC01_BIU_IP3MSK2L_OFS		0x0358 +#define MSC01_BIU_MCBAS1L_OFS		0x0388 +#define MSC01_BIU_MCMSK1L_OFS		0x0398 +#define MSC01_BIU_MCBAS2L_OFS		0x03c8 +#define MSC01_BIU_MCMSK2L_OFS		0x03d8 + +/* + * PCI Bridge + */ + +#define MSC01_PCI_SC2PMBASL_OFS		0x0208 +#define MSC01_PCI_SC2PMMSKL_OFS		0x0218 +#define MSC01_PCI_SC2PMMAPL_OFS		0x0228 +#define MSC01_PCI_SC2PIOBASL_OFS	0x0248 +#define MSC01_PCI_SC2PIOMSKL_OFS	0x0258 +#define MSC01_PCI_SC2PIOMAPL_OFS	0x0268 +#define MSC01_PCI_P2SCMSKL_OFS		0x0308 +#define MSC01_PCI_P2SCMAPL_OFS		0x0318 +#define MSC01_PCI_INTSTAT_OFS		0x0608 +#define MSC01_PCI_CFGADDR_OFS		0x0610 +#define MSC01_PCI_CFGDATA_OFS		0x0618 +#define MSC01_PCI_HEAD0_OFS		0x2000 +#define MSC01_PCI_HEAD1_OFS		0x2008 +#define MSC01_PCI_HEAD2_OFS		0x2010 +#define MSC01_PCI_HEAD3_OFS		0x2018 +#define MSC01_PCI_HEAD4_OFS		0x2020 +#define MSC01_PCI_HEAD5_OFS		0x2028 +#define MSC01_PCI_HEAD6_OFS		0x2030 +#define MSC01_PCI_HEAD7_OFS		0x2038 +#define MSC01_PCI_HEAD8_OFS		0x2040 +#define MSC01_PCI_HEAD9_OFS		0x2048 +#define MSC01_PCI_HEAD10_OFS		0x2050 +#define MSC01_PCI_HEAD11_OFS		0x2058 +#define MSC01_PCI_HEAD12_OFS		0x2060 +#define MSC01_PCI_HEAD13_OFS		0x2068 +#define MSC01_PCI_HEAD14_OFS		0x2070 +#define MSC01_PCI_HEAD15_OFS		0x2078 +#define MSC01_PCI_BAR0_OFS		0x2220 +#define MSC01_PCI_CFG_OFS		0x2380 +#define MSC01_PCI_SWAP_OFS		0x2388 + +#define MSC01_PCI_SC2PMMSKL_MSK_MSK	0xff000000 +#define MSC01_PCI_SC2PIOMSKL_MSK_MSK	0xff000000 + +#define MSC01_PCI_INTSTAT_TA_SHF	6 +#define MSC01_PCI_INTSTAT_TA_MSK	(0x1 << MSC01_PCI_INTSTAT_TA_SHF) +#define MSC01_PCI_INTSTAT_MA_SHF	7 +#define MSC01_PCI_INTSTAT_MA_MSK	(0x1 << MSC01_PCI_INTSTAT_MA_SHF) + +#define MSC01_PCI_CFGADDR_BNUM_SHF	16 +#define MSC01_PCI_CFGADDR_BNUM_MSK	(0xff << MSC01_PCI_CFGADDR_BNUM_SHF) +#define MSC01_PCI_CFGADDR_DNUM_SHF	11 +#define MSC01_PCI_CFGADDR_DNUM_MSK	(0x1f << MSC01_PCI_CFGADDR_DNUM_SHF) +#define MSC01_PCI_CFGADDR_FNUM_SHF	8 +#define MSC01_PCI_CFGADDR_FNUM_MSK	(0x3 << MSC01_PCI_CFGADDR_FNUM_SHF) +#define MSC01_PCI_CFGADDR_RNUM_SHF	2 +#define MSC01_PCI_CFGADDR_RNUM_MSK	(0x3f << MSC01_PCI_CFGADDR_RNUM_SHF) + +#define MSC01_PCI_HEAD0_VENDORID_SHF	0 +#define MSC01_PCI_HEAD0_DEVICEID_SHF	16 + +#define MSC01_PCI_HEAD2_REV_SHF		0 +#define MSC01_PCI_HEAD2_CLASS_SHF	16 + +#define MSC01_PCI_CFG_EN_SHF		15 +#define MSC01_PCI_CFG_EN_MSK		(0x1 << MSC01_PCI_CFG_EN_SHF) +#define MSC01_PCI_CFG_G_SHF		16 +#define MSC01_PCI_CFG_G_MSK		(0x1 << MSC01_PCI_CFG_G_SHF) +#define MSC01_PCI_CFG_RA_SHF		17 +#define MSC01_PCI_CFG_RA_MSK		(0x1 << MSC01_PCI_CFG_RA_SHF) + +#define MSC01_PCI_SWAP_BAR0_BSWAP_SHF	0 +#define MSC01_PCI_SWAP_IO_BSWAP_SHF	18 + +/* + * Peripheral Bus Controller + */ + +#define MSC01_PBC_CLKCFG_OFS		0x0100 +#define MSC01_PBC_CS0CFG_OFS		0x0400 +#define MSC01_PBC_CS0TIM_OFS		0x0500 +#define MSC01_PBC_CS0RW_OFS		0x0600 + +#define MSC01_PBC_CLKCFG_SHF		0 +#define MSC01_PBC_CLKCFG_MSK		(0x1f << MSC01_PBC_CLKCFG_SHF) + +#define MSC01_PBC_CS0CFG_WS_SHF		0 +#define MSC01_PBC_CS0CFG_WS_MSK		(0x1f << MSC01_PBC_CS0CFG_WS_SHF) +#define MSC01_PBC_CS0CFG_WSIDLE_SHF	8 +#define MSC01_PBC_CS0CFG_WSIDLE_MSK	(0x1f << MSC01_PBC_CS0CFG_WSIDLE_SHF) +#define MSC01_PBC_CS0CFG_DTYP_SHF	16 +#define MSC01_PBC_CS0CFG_DTYP_MSK	(0x3 << MSC01_PBC_CS0CFG_DTYP_SHF) +#define MSC01_PBC_CS0CFG_ADM_SHF	20 +#define MSC01_PBC_CS0CFG_ADM_MSK	(0x1 << MSC01_PBC_CS0CFG_ADM_SHF) + +#define MSC01_PBC_CS0TIM_CAT_SHF	0 +#define MSC01_PBC_CS0TIM_CAT_MSK	(0x1f << MSC01_PBC_CS0TIM_CAT_SHF) +#define MSC01_PBC_CS0TIM_CDT_SHF	8 +#define MSC01_PBC_CS0TIM_CDT_MSK	(0x1f << MSC01_PBC_CS0TIM_CDT_SHF) + +#define MSC01_PBC_CS0RW_WAT_SHF		0 +#define MSC01_PBC_CS0RW_WAT_MSK		(0x1f << MSC01_PBC_CS0RW_WAT_SHF) +#define MSC01_PBC_CS0RW_WDT_SHF		8 +#define MSC01_PBC_CS0RW_WDT_MSK		(0x1f << MSC01_PBC_CS0RW_WDT_SHF) +#define MSC01_PBC_CS0RW_RAT_SHF		16 +#define MSC01_PBC_CS0RW_RAT_MSK		(0x1f << MSC01_PBC_CS0RW_RAT_SHF) +#define MSC01_PBC_CS0RW_RDT_SHF		24 +#define MSC01_PBC_CS0RW_RDT_MSK		(0x1f << MSC01_PBC_CS0RW_RDT_SHF) + +#endif /* __MSC01_H__ */ diff --git a/include/pci.h b/include/pci.h index d46247966..461f17c05 100644 --- a/include/pci.h +++ b/include/pci.h @@ -417,6 +417,8 @@  #include <pci_ids.h> +#ifndef __ASSEMBLY__ +  #ifdef CONFIG_SYS_PCI_64BIT  typedef u64 pci_addr_t;  typedef u64 pci_size_t; @@ -667,4 +669,6 @@ extern void pci_mpc824x_init (struct pci_controller *hose);  #ifdef CONFIG_MPC85xx  extern void pci_mpc85xx_init (struct pci_controller *hose);  #endif -#endif	/* _PCI_H */ + +#endif /* __ASSEMBLY__ */ +#endif /* _PCI_H */ diff --git a/include/pci_ids.h b/include/pci_ids.h index 2c6dfd404..6bab67744 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -2170,6 +2170,9 @@  #define PCI_DEVICE_ID_ENE_720		0x1421  #define PCI_DEVICE_ID_ENE_722		0x1422 +#define PCI_VENDOR_ID_MIPS		0x153f +#define PCI_DEVICE_ID_MIPS_MSC01	0x0001 +  #define PCI_SUBVENDOR_ID_PERLE          0x155f  #define PCI_SUBDEVICE_ID_PCI_RAS4       0xf001  #define PCI_SUBDEVICE_ID_PCI_RAS8       0xf010 diff --git a/include/pci_msc01.h b/include/pci_msc01.h new file mode 100644 index 000000000..54945a7a8 --- /dev/null +++ b/include/pci_msc01.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2013 Imagination Technologies + * Author: Paul Burton <paul.burton@imgtec.com> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#ifndef __PCI_MSC01_H__ +#define __PCI_MSC01_H__ + +extern void msc01_pci_init(void *base, unsigned long sys_bus, +			   unsigned long sys_phys, unsigned long sys_size, +			   unsigned long mem_bus, unsigned long mem_phys, +			   unsigned long mem_size, unsigned long io_bus, +			   unsigned long io_phys, unsigned long io_size); + +#endif /* __PCI_MSC01_H__ */ |