diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index fdf62e8..06a516d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -6,6 +6,7 @@ select HAS_KALLSYMS select HAVE_CONFIGURABLE_MEMORY_LAYOUT select HAVE_CONFIGURABLE_TEXT_BASE + select HAS_DMA default y config SYS_SUPPORTS_BIG_ENDIAN diff --git a/arch/mips/boards/black-swift/include/board/board_pbl_start.h b/arch/mips/boards/black-swift/include/board/board_pbl_start.h index 7394092..ee21a85 100644 --- a/arch/mips/boards/black-swift/include/board/board_pbl_start.h +++ b/arch/mips/boards/black-swift/include/board/board_pbl_start.h @@ -26,18 +26,32 @@ mips_barebox_10h - mips_disable_interrupts + hornet_mips24k_cp0_setup pbl_blt 0xbf000000 skip_pll_ram_config t8 + hornet_1_1_war + pbl_ar9331_pll pbl_ar9331_ddr2_config + /* Initialize caches... */ + mips_cache_reset + + /* ... and enable them */ + dcache_enable + skip_pll_ram_config: pbl_ar9331_uart_enable debug_ll_ar9331_init mips_nmon + /* + * It is amazing but we have to enable MDIO on GPIO + * to use GPIO27 for LED1. + */ + pbl_ar9331_mdio_gpio_enable + copy_to_link_location pbl_start .set pop diff --git a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h index d25f5aa..ef0d36d 100644 --- a/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h +++ b/arch/mips/boards/tplink-mr3020/include/board/board_pbl_start.h @@ -26,18 +26,32 @@ mips_barebox_10h - mips_disable_interrupts + hornet_mips24k_cp0_setup pbl_blt 0xbf000000 skip_pll_ram_config t8 + hornet_1_1_war + pbl_ar9331_pll pbl_ar9331_ddr1_config + /* Initialize caches... */ + mips_cache_reset + + /* ... and enable them */ + dcache_enable + skip_pll_ram_config: pbl_ar9331_uart_enable debug_ll_ar9331_init mips_nmon + /* + * It is amazing but we have to enable MDIO on GPIO + * to use GPIO26 for the "WPS" LED and GPIO27 for the "3G" LED. + */ + pbl_ar9331_mdio_gpio_enable + copy_to_link_location pbl_start .set pop diff --git a/arch/mips/boot/dtb.c b/arch/mips/boot/dtb.c index 23d8979..977c837 100644 --- a/arch/mips/boot/dtb.c +++ b/arch/mips/boot/dtb.c @@ -28,11 +28,13 @@ { static char str[12]; - sprintf(str, "kseg0_ram%d", r); - barebox_add_memory_bank(str, KSEG0 | base, size); - - sprintf(str, "kseg1_ram%d", r); - barebox_add_memory_bank(str, KSEG1 | base, size); + if (IS_ENABLED(CONFIG_MMU)) { + sprintf(str, "kseg0_ram%d", r); + barebox_add_memory_bank(str, KSEG0 | base, size); + } else { + sprintf(str, "kseg1_ram%d", r); + barebox_add_memory_bank(str, KSEG1 | base, size); + } if (dump) pr_info("%s: %s: 0x%llx@0x%llx\n", node->name, str, size, base); diff --git a/arch/mips/configs/black-swift_defconfig b/arch/mips/configs/black-swift_defconfig index 7444968..1a72cfb 100644 --- a/arch/mips/configs/black-swift_defconfig +++ b/arch/mips/configs/black-swift_defconfig @@ -9,6 +9,8 @@ CONFIG_NMON_HELP=y CONFIG_PBL_IMAGE=y CONFIG_IMAGE_COMPRESSION_XZKERN=y +CONFIG_MMU=y +CONFIG_TEXT_BASE=0x82000000 CONFIG_MALLOC_TLSF=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y @@ -32,6 +34,8 @@ CONFIG_CMD_MM=y CONFIG_CMD_CLK=y CONFIG_CMD_FLASH=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_LED=y CONFIG_CMD_SPI=y CONFIG_CMD_OF_NODE=y CONFIG_CMD_OF_PROPERTY=y @@ -42,5 +46,9 @@ CONFIG_MTD=y # CONFIG_MTD_OOB_DEVICE is not set CONFIG_MTD_M25P80=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_LED_GPIO_OF=y +CONFIG_KEYBOARD_GPIO=y CONFIG_DIGEST_SHA224_GENERIC=y CONFIG_DIGEST_SHA256_GENERIC=y diff --git a/arch/mips/configs/tplink-mr3020_defconfig b/arch/mips/configs/tplink-mr3020_defconfig index f2ba2da..93fb10d 100644 --- a/arch/mips/configs/tplink-mr3020_defconfig +++ b/arch/mips/configs/tplink-mr3020_defconfig @@ -3,6 +3,8 @@ CONFIG_MACH_MIPS_ATH79=y CONFIG_PBL_IMAGE=y CONFIG_IMAGE_COMPRESSION_XZKERN=y +CONFIG_MMU=y +CONFIG_TEXT_BASE=0x81000000 CONFIG_MALLOC_TLSF=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y diff --git a/arch/mips/dts/ar9331.dtsi b/arch/mips/dts/ar9331.dtsi index 99ede9e..efc0531 100644 --- a/arch/mips/dts/ar9331.dtsi +++ b/arch/mips/dts/ar9331.dtsi @@ -33,7 +33,7 @@ #clock-cells = <1>; }; - spi: spi@1f000000{ + spi: spi@1f000000 { #address-cells = <1>; #size-cells = <0>; compatible = "qca,ath79-spi"; diff --git a/arch/mips/dts/black-swift.dts b/arch/mips/dts/black-swift.dts index 270374d..d19c381 100644 --- a/arch/mips/dts/black-swift.dts +++ b/arch/mips/dts/black-swift.dts @@ -1,6 +1,8 @@ /dts-v1/; #include "ar9331.dtsi" +#include +#include / { model = "Black Swift"; @@ -13,12 +15,36 @@ aliases { spiflash = &spiflash; }; + + buttons { + compatible = "gpio-keys"; + + s1 { + label = "S1"; + gpios = <&gpio 11 GPIO_ACTIVE_LOW>; + linux,code = ; + }; + }; + + leds { + compatible = "gpio-leds"; + + s1 { + label = "LED1"; + gpios = <&gpio 27 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; }; &serial0 { status = "okay"; }; +&gpio { + status = "okay"; +}; + &spi { num-chipselects = <1>; status = "okay"; diff --git a/arch/mips/include/asm/cache.h b/arch/mips/include/asm/cache.h new file mode 100644 index 0000000..cceba0a --- /dev/null +++ b/arch/mips/include/asm/cache.h @@ -0,0 +1,6 @@ +#ifndef _ASM_MIPS_CACHE_H +#define _ASM_MIPS_CACHE_H + +void flush_cache_all(void); + +#endif /* _ASM_MIPS_CACHE_H */ diff --git a/arch/mips/include/asm/cacheops.h b/arch/mips/include/asm/cacheops.h new file mode 100644 index 0000000..3bc5852 --- /dev/null +++ b/arch/mips/include/asm/cacheops.h @@ -0,0 +1,36 @@ +/* + * Cache operations for the cache instruction. + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * (C) Copyright 1996, 97, 99, 2002, 03 Ralf Baechle + * (C) Copyright 1999 Silicon Graphics, Inc. + */ +#ifndef __ASM_CACHEOPS_H +#define __ASM_CACHEOPS_H + +/* + * Most cache ops are split into a 2 bit field identifying the cache, and a 3 + * bit field identifying the cache operation. + */ +#define Cache_I 0x00 +#define Cache_D 0x01 + +#define Index_Writeback_Inv 0x00 +#define Index_Store_Tag 0x08 +#define Hit_Invalidate 0x10 +#define Hit_Writeback_Inv 0x14 /* not with Cache_I though */ + +/* + * Cache Operations available on all MIPS processors with R4000-style caches + */ +#define Index_Invalidate_I (Cache_I | Index_Writeback_Inv) +#define Index_Writeback_Inv_D (Cache_D | Index_Writeback_Inv) +#define Index_Store_Tag_I (Cache_I | Index_Store_Tag) +#define Index_Store_Tag_D (Cache_D | Index_Store_Tag) +#define Hit_Invalidate_D (Cache_D | Hit_Invalidate) +#define Hit_Writeback_Inv_D (Cache_D | Hit_Writeback_Inv) + +#endif /* __ASM_CACHEOPS_H */ diff --git a/arch/mips/include/asm/dma-mapping.h b/arch/mips/include/asm/dma-mapping.h index 6395112..c71a087 100644 --- a/arch/mips/include/asm/dma-mapping.h +++ b/arch/mips/include/asm/dma-mapping.h @@ -1,10 +1,12 @@ #ifndef _ASM_DMA_MAPPING_H #define _ASM_DMA_MAPPING_H +#include #include #include #include #include +#include static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) { @@ -12,16 +14,23 @@ ret = xmemalign(PAGE_SIZE, size); + memset(ret, 0, size); + if (dma_handle) *dma_handle = CPHYSADDR(ret); + dma_flush_range((unsigned long)ret, (unsigned long)(ret + size)); + return (void *)CKSEG1ADDR(ret); } static inline void dma_free_coherent(void *vaddr, dma_addr_t dma_handle, size_t size) { - free(vaddr); + if (IS_ENABLED(CONFIG_MMU)) + free((void *)CKSEG0ADDR(vaddr)); + else + free(vaddr); } #endif /* _ASM_DMA_MAPPING_H */ diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index 4832be6..4bee591 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h @@ -14,6 +14,9 @@ #include #include +void dma_flush_range(unsigned long, unsigned long); +void dma_inv_range(unsigned long, unsigned long); + #define IO_SPACE_LIMIT 0 /*****************************************************************************/ diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index f923860..30262e6 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h @@ -409,6 +409,14 @@ #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_SHF 7 +#define MIPS_CONF1_DA (_ULCAST_(7) << 7) +#define MIPS_CONF1_DL_SHF 10 +#define MIPS_CONF1_DL (_ULCAST_(7) << 10) +#define MIPS_CONF1_DS_SHF 13 +#define MIPS_CONF1_DS (_ULCAST_(7) << 13) +#define MIPS_CONF1_IA_SHF 16 + #define MIPS_CONF1_DA (_ULCAST_(7) << 7) #define MIPS_CONF1_DL (_ULCAST_(7) << 10) #define MIPS_CONF1_DS (_ULCAST_(7) << 13) diff --git a/arch/mips/include/asm/pbl_macros.h b/arch/mips/include/asm/pbl_macros.h index dbe3410..37b150a 100644 --- a/arch/mips/include/asm/pbl_macros.h +++ b/arch/mips/include/asm/pbl_macros.h @@ -27,6 +27,8 @@ #include #include #include +#include +#include .macro pbl_reg_writel val addr .set push @@ -212,4 +214,135 @@ .set pop .endm +#ifndef CONFIG_SYS_MIPS_CACHE_MODE +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT +#endif + +#define INDEX_BASE CKSEG0 + + .macro f_fill64 dst, offset, val + LONG_S \val, (\offset + 0 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 1 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 2 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 3 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 4 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 5 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 6 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 7 * LONGSIZE)(\dst) +#if LONGSIZE == 4 + LONG_S \val, (\offset + 8 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 9 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 10 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 11 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 12 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 13 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 14 * LONGSIZE)(\dst) + LONG_S \val, (\offset + 15 * LONGSIZE)(\dst) +#endif + .endm + + .macro cache_loop curr, end, line_sz, op +10: cache \op, 0(\curr) + PTR_ADDU \curr, \curr, \line_sz + bne \curr, \end, 10b + .endm + + .macro l1_info sz, line_sz, off + .set push + .set noat + + mfc0 $1, CP0_CONFIG, 1 + + /* detect line size */ + srl \line_sz, $1, \off + MIPS_CONF1_DL_SHF - MIPS_CONF1_DA_SHF + andi \line_sz, \line_sz, (MIPS_CONF1_DL >> MIPS_CONF1_DL_SHF) + move \sz, zero + beqz \line_sz, 10f + li \sz, 2 + sllv \line_sz, \sz, \line_sz + + /* detect associativity */ + srl \sz, $1, \off + MIPS_CONF1_DA_SHF - MIPS_CONF1_DA_SHF + andi \sz, \sz, (MIPS_CONF1_DA >> MIPS_CONF1_DA_SHF) + addi \sz, \sz, 1 + + /* sz *= line_sz */ + mul \sz, \sz, \line_sz + + /* detect log32(sets) */ + srl $1, $1, \off + MIPS_CONF1_DS_SHF - MIPS_CONF1_DA_SHF + andi $1, $1, (MIPS_CONF1_DS >> MIPS_CONF1_DS_SHF) + addiu $1, $1, 1 + andi $1, $1, 0x7 + + /* sz <<= log32(sets) */ + sllv \sz, \sz, $1 + + /* sz *= 32 */ + li $1, 32 + mul \sz, \sz, $1 +10: + .set pop + .endm + +/* + * mips_cache_reset - low level initialisation of the primary caches + * + * This routine initialises the primary caches to ensure that they have good + * parity. It must be called by the ROM before any cached locations are used + * to prevent the possibility of data with bad parity being written to memory. + * + * To initialise the instruction cache it is essential that a source of data + * with good parity is available. This routine will initialise an area of + * memory starting at location zero to be used as a source of parity. + * + */ + .macro mips_cache_reset + + l1_info t2, t8, MIPS_CONF1_IA_SHF + l1_info t3, t9, MIPS_CONF1_DA_SHF + + /* + * The TagLo registers used depend upon the CPU implementation, but the + * architecture requires that it is safe for software to write to both + * TagLo selects 0 & 2 covering supported cases. + */ + mtc0 zero, CP0_TAGLO + mtc0 zero, CP0_TAGLO, 2 + + /* + * The caches are probably in an indeterminate state, so we force good + * parity into them by doing an invalidate for each line. + */ + + /* + * Initialize the I-cache first, + */ + blez t2, 1f + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, t2 + /* clear tag to invalidate */ + cache_loop t0, t1, t8, Index_Store_Tag_I + + /* + * then initialize D-cache. + */ +1: blez t3, 3f + PTR_LI t0, INDEX_BASE + PTR_ADDU t1, t0, t3 + /* clear all tags */ + cache_loop t0, t1, t9, Index_Store_Tag_D + +3: nop + + .endm + + .macro dcache_enable + mfc0 t0, CP0_CONFIG + ori t0, CONF_CM_CMASK + xori t0, CONF_CM_CMASK + ori t0, CONFIG_SYS_MIPS_CACHE_MODE + mtc0 t0, CP0_CONFIG + .endm + #endif /* __ASM_PBL_MACROS_H */ diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 02ee189..d25d096 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -6,6 +6,8 @@ obj-y += cpu-probe.o obj-y += traps.o obj-y += genex.o +obj-y += shutdown.o +obj-y += dma-default.o obj-$(CONFIG_MIPS_OPTIMIZED_STRING_FUNCTIONS) += memcpy.o obj-$(CONFIG_MIPS_OPTIMIZED_STRING_FUNCTIONS) += memset.o diff --git a/arch/mips/lib/c-r4k.c b/arch/mips/lib/c-r4k.c index 0a9dd0e..1502058 100644 --- a/arch/mips/lib/c-r4k.c +++ b/arch/mips/lib/c-r4k.c @@ -10,10 +10,81 @@ #include #include #include +#include +#include #include #include #include +#define cache_op(op,addr) \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noreorder \n" \ + " .set mips3\n\t \n" \ + " cache %0, %1 \n" \ + " .set pop \n" \ + : \ + : "i" (op), "R" (*(unsigned char *)(addr))) + +#define __BUILD_BLAST_CACHE_RANGE(pfx, desc, hitop) \ +static inline void blast_##pfx##cache##_range(unsigned long start, \ + unsigned long end) \ +{ \ + unsigned long lsize = current_cpu_data.desc.linesz; \ + unsigned long addr = start & ~(lsize - 1); \ + unsigned long aend = (end - 1) & ~(lsize - 1); \ + \ + if (current_cpu_data.desc.flags & MIPS_CACHE_NOT_PRESENT) \ + return; \ + \ + while (1) { \ + cache_op(hitop, addr); \ + if (addr == aend) \ + break; \ + addr += lsize; \ + } \ +} + +__BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D) +__BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D) + +void flush_cache_all(void) +{ + struct cpuinfo_mips *c = ¤t_cpu_data; + unsigned long lsize; + unsigned long addr; + unsigned long aend; + unsigned int icache_size, dcache_size; + + dcache_size = c->dcache.waysize * c->dcache.ways; + lsize = c->dcache.linesz; + aend = (KSEG0 + dcache_size - 1) & ~(lsize - 1); + for (addr = KSEG0; addr <= aend; addr += lsize) + cache_op(Index_Writeback_Inv_D, addr); + + icache_size = c->icache.waysize * c->icache.ways; + lsize = c->icache.linesz; + aend = (KSEG0 + icache_size - 1) & ~(lsize - 1); + for (addr = KSEG0; addr <= aend; addr += lsize) + cache_op(Index_Invalidate_I, addr); + + /* secondatory cache skipped */ +} + +void dma_flush_range(unsigned long start, unsigned long end) +{ + blast_dcache_range(start, end); + + /* secondatory cache skipped */ +} + +void dma_inv_range(unsigned long start, unsigned long end) +{ + blast_inv_dcache_range(start, end); + + /* secondatory cache skipped */ +} + void r4k_cache_init(void); static void probe_pcache(void) @@ -91,7 +162,6 @@ } } -#define CONFIG_M (1 << 31) #define CONFIG2_SS_OFFSET 8 #define CONFIG2_SL_OFFSET 4 #define CONFIG2_SA_OFFSET 0 @@ -101,10 +171,10 @@ unsigned int config2, config1, config = read_c0_config(); unsigned int ss, sl, sa; - if ((config & CONFIG_M) == 0) + if ((config & MIPS_CONF_M) == 0) goto noscache; config1 = read_c0_config1(); - if ((config1 & CONFIG_M) == 0) + if ((config1 & MIPS_CONF_M) == 0) goto noscache; config2 = read_c0_config2(); ss = 0xf & (config2 >> CONFIG2_SS_OFFSET); diff --git a/arch/mips/lib/dma-default.c b/arch/mips/lib/dma-default.c new file mode 100644 index 0000000..9b2fe7d --- /dev/null +++ b/arch/mips/lib/dma-default.c @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2015, 2016 Peter Mamonov + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include + +#if defined(CONFIG_CPU_MIPS32) || \ + defined(CONFIG_CPU_MIPS64) +static inline void __dma_sync_mips(unsigned long addr, size_t size, + enum dma_data_direction direction) +{ + switch (direction) { + case DMA_TO_DEVICE: + dma_flush_range(addr, addr + size); + break; + + case DMA_FROM_DEVICE: + dma_inv_range(addr, addr + size); + break; + + case DMA_BIDIRECTIONAL: + dma_flush_range(addr, addr + size); + break; + + default: + BUG(); + } +} +#else +static inline void __dma_sync_mips(void *addr, size_t size, + enum dma_data_direction direction) +{ +} +#endif + +void dma_sync_single_for_cpu(unsigned long address, size_t size, + enum dma_data_direction dir) +{ + __dma_sync_mips(address, size, dir); +} + +void dma_sync_single_for_device(unsigned long address, size_t size, + enum dma_data_direction dir) +{ + __dma_sync_mips(address, size, dir); +} diff --git a/arch/mips/lib/shutdown.c b/arch/mips/lib/shutdown.c new file mode 100644 index 0000000..973cd23 --- /dev/null +++ b/arch/mips/lib/shutdown.c @@ -0,0 +1,12 @@ +/** + * This function is called by shutdown_barebox to get a clean + * memory/cache state. + */ +#include +#include + +static void arch_shutdown(void) +{ + flush_cache_all(); +} +archshutdown_exitcall(arch_shutdown); diff --git a/arch/mips/mach-ath79/include/mach/pbl_macros.h b/arch/mips/mach-ath79/include/mach/pbl_macros.h index c00dd28..8f4d09a 100644 --- a/arch/mips/mach-ath79/include/mach/pbl_macros.h +++ b/arch/mips/mach-ath79/include/mach/pbl_macros.h @@ -179,4 +179,99 @@ | AR933X_GPIO_FUNC_RSRV15, GPIO_FUNC .endm +#define RESET_REG_BOOTSTRAP ((KSEG1 | AR71XX_RESET_BASE) \ + | AR933X_RESET_REG_BOOTSTRAP) + +.macro pbl_ar9331_mdio_gpio_enable + /* Bit 18 enables MDC and MDIO function on GPIO26 and GPIO28 */ + pbl_reg_set (1 << 18), RESET_REG_BOOTSTRAP +.endm + +.macro hornet_mips24k_cp0_setup + .set push + .set noreorder + + /* + * Clearing CP0 registers - This is generally required for the MIPS-24k + * core used by Atheros. + */ + mtc0 zero, CP0_INDEX + mtc0 zero, CP0_ENTRYLO0 + mtc0 zero, CP0_ENTRYLO1 + mtc0 zero, CP0_CONTEXT + mtc0 zero, CP0_PAGEMASK + mtc0 zero, CP0_WIRED + mtc0 zero, CP0_INFO + mtc0 zero, CP0_COUNT + mtc0 zero, CP0_ENTRYHI + mtc0 zero, CP0_COMPARE + + li t0, ST0_CU0 | ST0_ERL + mtc0 t0, CP0_STATUS + + mtc0 zero, CP0_CAUSE + mtc0 zero, CP0_EPC + + li t0, CONF_CM_UNCACHED + mtc0 t0, CP0_CONFIG + + mtc0 zero, CP0_LLADDR + mtc0 zero, CP0_WATCHLO + mtc0 zero, CP0_WATCHHI + mtc0 zero, CP0_XCONTEXT + mtc0 zero, CP0_FRAMEMASK + mtc0 zero, CP0_DIAGNOSTIC + mtc0 zero, CP0_DEBUG + mtc0 zero, CP0_DEPC + mtc0 zero, CP0_PERFORMANCE + mtc0 zero, CP0_ECC + mtc0 zero, CP0_CACHEERR + mtc0 zero, CP0_TAGLO + + .set pop +.endm + +.macro hornet_1_1_war + .set push + .set noreorder + +/* + * WAR: Hornet 1.1 currently need a reset once we boot to let the resetb has + * enough time to stable, so that trigger reset at 1st boot, system team + * is investigaing the issue, will remove in short + */ + + li t7, 0xbd000000 + lw t8, 0(t7) + li t9, 0x12345678 + + /* if value of 0xbd000000 != 0x12345678, go to do_reset */ + bne t8, t9, do_reset + nop + + li t9, 0xffffffff + sw t9, 0(t7) + b normal_path + nop + +do_reset: + /* put 0x12345678 into 0xbd000000 */ + sw t9, 0(t7) + + /* reset register 0x1806001c */ + li t7, 0xb806001c + lw t8, 0(t7) + /* bit24, fullchip reset */ + li t9, 0x1000000 + or t8, t8, t9 + sw t8, 0(t7) + +do_reset_loop: + b do_reset_loop + nop + +normal_path: + .set pop +.endm + #endif /* __ASM_MACH_ATH79_PBL_MACROS_H */