summaryrefslogtreecommitdiff
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/cpu/mips32/cache.S90
-rw-r--r--arch/mips/cpu/mips32/cpu.c73
-rw-r--r--arch/mips/cpu/mips32/start.S2
-rw-r--r--arch/mips/include/asm/malta.h62
-rw-r--r--arch/mips/include/asm/mipsregs.h6
-rw-r--r--arch/mips/lib/bootm.c16
6 files changed, 213 insertions, 36 deletions
diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/cpu/mips32/cache.S
index 12f656c..22bd844 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 28d5c45..278865b 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 70ad198..68e59b5 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 d4d44a2..9e7c045 100644
--- a/arch/mips/include/asm/malta.h
+++ b/arch/mips/include/asm/malta.h
@@ -1,23 +1,67 @@
/*
* 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 0x1e000000
+
+#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
+#define PCI_CFG_PIIX4_SERIRQC 0x64
+#define PCI_CFG_PIIX4_GENCFG 0xb0
+
+#define PCI_CFG_PIIX4_SERIRQC_EN (1 << 7)
+#define PCI_CFG_PIIX4_SERIRQC_CONT (1 << 6)
+
+#define PCI_CFG_PIIX4_GENCFG_SERIRQ (1 << 16)
#endif /* _MIPS_ASM_MALTA_H */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index be7e5c6..3571e4f 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 66340ea..71bb0d2 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,8 +196,10 @@ static void boot_prep_linux(bootm_headers_t *images)
if (cp)
linux_env_set("eth1addr", cp);
- if (mips_boot_qemu_malta)
- linux_env_set("modetty0", "38400n8r");
+ if (mips_boot_malta) {
+ sprintf(env_buf, "%un8r", gd->baudrate);
+ linux_env_set("modetty0", env_buf);
+ }
}
static void boot_jump_linux(bootm_headers_t *images)
@@ -210,7 +212,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 */