9
0
Fork 0

Merge branch 'for-next/mips'

This commit is contained in:
Sascha Hauer 2016-03-11 10:49:49 +01:00
commit 7991fe1b8e
19 changed files with 510 additions and 12 deletions

View File

@ -6,6 +6,7 @@ config MIPS
select HAS_KALLSYMS
select HAVE_CONFIGURABLE_MEMORY_LAYOUT
select HAVE_CONFIGURABLE_TEXT_BASE
select HAS_DMA
default y
config SYS_SUPPORTS_BIG_ENDIAN

View File

@ -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

View File

@ -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

View File

@ -28,11 +28,13 @@ void of_add_memory_bank(struct device_node *node, bool dump, int r,
{
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);

View File

@ -9,6 +9,8 @@ CONFIG_NMON_USER_START_DELAY=0x5
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_EDIT=y
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_DRIVER_SPI_ATH79=y
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

View File

@ -3,6 +3,8 @@ CONFIG_BUILTIN_DTB_NAME="tplink-mr3020"
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

View File

@ -33,7 +33,7 @@
#clock-cells = <1>;
};
spi: spi@1f000000{
spi: spi@1f000000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "qca,ath79-spi";

View File

@ -1,6 +1,8 @@
/dts-v1/;
#include "ar9331.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
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 = <KEY_RESTART>;
};
};
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";

View File

@ -0,0 +1,6 @@
#ifndef _ASM_MIPS_CACHE_H
#define _ASM_MIPS_CACHE_H
void flush_cache_all(void);
#endif /* _ASM_MIPS_CACHE_H */

View File

@ -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 */

View File

@ -1,10 +1,12 @@
#ifndef _ASM_DMA_MAPPING_H
#define _ASM_DMA_MAPPING_H
#include <common.h>
#include <xfuncs.h>
#include <asm/addrspace.h>
#include <asm/types.h>
#include <malloc.h>
#include <asm/io.h>
static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
{
@ -12,16 +14,23 @@ static inline void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle)
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 */

View File

@ -14,6 +14,9 @@
#include <asm/types.h>
#include <asm/byteorder.h>
void dma_flush_range(unsigned long, unsigned long);
void dma_inv_range(unsigned long, unsigned long);
#define IO_SPACE_LIMIT 0
/*****************************************************************************/

View File

@ -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)

View File

@ -27,6 +27,8 @@
#include <asm-generic/memory_layout.h>
#include <generated/compile.h>
#include <generated/utsrelease.h>
#include <asm/addrspace.h>
#include <asm/cacheops.h>
.macro pbl_reg_writel val addr
.set push
@ -212,4 +214,135 @@ copy_loop_exit:
.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 */

View File

@ -6,6 +6,8 @@ obj-y += ashrdi3.o
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

View File

@ -10,10 +10,81 @@
#include <common.h>
#include <asm/io.h>
#include <asm/mipsregs.h>
#include <asm/cache.h>
#include <asm/cacheops.h>
#include <asm/cpu.h>
#include <asm/cpu-info.h>
#include <asm/bitops.h>
#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 = &current_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 @@ static void probe_pcache(void)
}
}
#define CONFIG_M (1 << 31)
#define CONFIG2_SS_OFFSET 8
#define CONFIG2_SL_OFFSET 4
#define CONFIG2_SA_OFFSET 0
@ -101,10 +171,10 @@ static void probe_scache(void)
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);

View File

@ -0,0 +1,57 @@
/*
* (C) Copyright 2015, 2016 Peter Mamonov <pmamonov@gmail.com>
*
* 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 <dma.h>
#include <asm/io.h>
#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);
}

12
arch/mips/lib/shutdown.c Normal file
View File

@ -0,0 +1,12 @@
/**
* This function is called by shutdown_barebox to get a clean
* memory/cache state.
*/
#include <init.h>
#include <asm/cache.h>
static void arch_shutdown(void)
{
flush_cache_all();
}
archshutdown_exitcall(arch_shutdown);

View File

@ -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 */