mirror of
https://github.com/u-boot/u-boot.git
synced 2025-01-21 10:14:05 +08:00
Merge branch 'master' of git://git.denx.de/u-boot-mips
This commit is contained in:
commit
d7d0003112
58
api/api.c
58
api/api.c
@ -52,7 +52,7 @@ static int API_getc(va_list ap)
|
||||
{
|
||||
int *c;
|
||||
|
||||
if ((c = (int *)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((c = (int *)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
*c = getc();
|
||||
@ -68,7 +68,7 @@ static int API_tstc(va_list ap)
|
||||
{
|
||||
int *t;
|
||||
|
||||
if ((t = (int *)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((t = (int *)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
*t = tstc();
|
||||
@ -84,7 +84,7 @@ static int API_putc(va_list ap)
|
||||
{
|
||||
char *c;
|
||||
|
||||
if ((c = (char *)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((c = (char *)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
putc(*c);
|
||||
@ -100,7 +100,7 @@ static int API_puts(va_list ap)
|
||||
{
|
||||
char *s;
|
||||
|
||||
if ((s = (char *)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((s = (char *)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
puts(s);
|
||||
@ -132,7 +132,7 @@ static int API_get_sys_info(va_list ap)
|
||||
{
|
||||
struct sys_info *si;
|
||||
|
||||
si = (struct sys_info *)va_arg(ap, u_int32_t);
|
||||
si = (struct sys_info *)va_arg(ap, uintptr_t);
|
||||
if (si == NULL)
|
||||
return API_ENOMEM;
|
||||
|
||||
@ -148,7 +148,7 @@ static int API_udelay(va_list ap)
|
||||
{
|
||||
unsigned long *d;
|
||||
|
||||
if ((d = (unsigned long *)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((d = (unsigned long *)va_arg(ap, unsigned long)) == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
udelay(*d);
|
||||
@ -164,11 +164,11 @@ static int API_get_timer(va_list ap)
|
||||
{
|
||||
unsigned long *base, *cur;
|
||||
|
||||
cur = (unsigned long *)va_arg(ap, u_int32_t);
|
||||
cur = (unsigned long *)va_arg(ap, unsigned long);
|
||||
if (cur == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
base = (unsigned long *)va_arg(ap, u_int32_t);
|
||||
base = (unsigned long *)va_arg(ap, unsigned long);
|
||||
if (base == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
@ -199,7 +199,7 @@ static int API_dev_enum(va_list ap)
|
||||
struct device_info *di;
|
||||
|
||||
/* arg is ptr to the device_info struct we are going to fill out */
|
||||
di = (struct device_info *)va_arg(ap, u_int32_t);
|
||||
di = (struct device_info *)va_arg(ap, uintptr_t);
|
||||
if (di == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
@ -233,7 +233,7 @@ static int API_dev_open(va_list ap)
|
||||
int err = 0;
|
||||
|
||||
/* arg is ptr to the device_info struct */
|
||||
di = (struct device_info *)va_arg(ap, u_int32_t);
|
||||
di = (struct device_info *)va_arg(ap, uintptr_t);
|
||||
if (di == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
@ -265,7 +265,7 @@ static int API_dev_close(va_list ap)
|
||||
int err = 0;
|
||||
|
||||
/* arg is ptr to the device_info struct */
|
||||
di = (struct device_info *)va_arg(ap, u_int32_t);
|
||||
di = (struct device_info *)va_arg(ap, uintptr_t);
|
||||
if (di == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
@ -319,7 +319,7 @@ static int API_dev_write(va_list ap)
|
||||
int err = 0;
|
||||
|
||||
/* 1. arg is ptr to the device_info struct */
|
||||
di = (struct device_info *)va_arg(ap, u_int32_t);
|
||||
di = (struct device_info *)va_arg(ap, uintptr_t);
|
||||
if (di == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
@ -329,12 +329,12 @@ static int API_dev_write(va_list ap)
|
||||
return API_ENODEV;
|
||||
|
||||
/* 2. arg is ptr to buffer from where to get data to write */
|
||||
buf = (void *)va_arg(ap, u_int32_t);
|
||||
buf = (void *)va_arg(ap, uintptr_t);
|
||||
if (buf == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
/* 3. arg is length of buffer */
|
||||
len = (int *)va_arg(ap, u_int32_t);
|
||||
len = (int *)va_arg(ap, uintptr_t);
|
||||
if (len == NULL)
|
||||
return API_EINVAL;
|
||||
if (*len <= 0)
|
||||
@ -387,7 +387,7 @@ static int API_dev_read(va_list ap)
|
||||
int *len_net, *act_len_net;
|
||||
|
||||
/* 1. arg is ptr to the device_info struct */
|
||||
di = (struct device_info *)va_arg(ap, u_int32_t);
|
||||
di = (struct device_info *)va_arg(ap, uintptr_t);
|
||||
if (di == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
@ -397,23 +397,23 @@ static int API_dev_read(va_list ap)
|
||||
return API_ENODEV;
|
||||
|
||||
/* 2. arg is ptr to buffer from where to put the read data */
|
||||
buf = (void *)va_arg(ap, u_int32_t);
|
||||
buf = (void *)va_arg(ap, uintptr_t);
|
||||
if (buf == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
if (di->type & DEV_TYP_STOR) {
|
||||
/* 3. arg - ptr to var with # of blocks to read */
|
||||
len_stor = (lbasize_t *)va_arg(ap, u_int32_t);
|
||||
len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
|
||||
if (!len_stor)
|
||||
return API_EINVAL;
|
||||
if (*len_stor <= 0)
|
||||
return API_EINVAL;
|
||||
|
||||
/* 4. arg - ptr to var with start block */
|
||||
start = (lbastart_t *)va_arg(ap, u_int32_t);
|
||||
start = (lbastart_t *)va_arg(ap, uintptr_t);
|
||||
|
||||
/* 5. arg - ptr to var where to put the len actually read */
|
||||
act_len_stor = (lbasize_t *)va_arg(ap, u_int32_t);
|
||||
act_len_stor = (lbasize_t *)va_arg(ap, uintptr_t);
|
||||
if (!act_len_stor)
|
||||
return API_EINVAL;
|
||||
|
||||
@ -422,14 +422,14 @@ static int API_dev_read(va_list ap)
|
||||
} else if (di->type & DEV_TYP_NET) {
|
||||
|
||||
/* 3. arg points to the var with length of packet to read */
|
||||
len_net = (int *)va_arg(ap, u_int32_t);
|
||||
len_net = (int *)va_arg(ap, uintptr_t);
|
||||
if (!len_net)
|
||||
return API_EINVAL;
|
||||
if (*len_net <= 0)
|
||||
return API_EINVAL;
|
||||
|
||||
/* 4. - ptr to var where to put the len actually read */
|
||||
act_len_net = (int *)va_arg(ap, u_int32_t);
|
||||
act_len_net = (int *)va_arg(ap, uintptr_t);
|
||||
if (!act_len_net)
|
||||
return API_EINVAL;
|
||||
|
||||
@ -453,9 +453,9 @@ static int API_env_get(va_list ap)
|
||||
{
|
||||
char *name, **value;
|
||||
|
||||
if ((name = (char *)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((name = (char *)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
if ((value = (char **)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((value = (char **)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
*value = getenv(name);
|
||||
@ -476,9 +476,9 @@ static int API_env_set(va_list ap)
|
||||
{
|
||||
char *name, *value;
|
||||
|
||||
if ((name = (char *)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((name = (char *)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
if ((value = (char *)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((value = (char *)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
setenv(name, value);
|
||||
@ -498,9 +498,9 @@ static int API_env_enum(va_list ap)
|
||||
int i, n;
|
||||
char *last, **next;
|
||||
|
||||
last = (char *)va_arg(ap, u_int32_t);
|
||||
last = (char *)va_arg(ap, unsigned long);
|
||||
|
||||
if ((next = (char **)va_arg(ap, u_int32_t)) == NULL)
|
||||
if ((next = (char **)va_arg(ap, uintptr_t)) == NULL)
|
||||
return API_EINVAL;
|
||||
|
||||
if (last == NULL)
|
||||
@ -662,14 +662,14 @@ void api_init(void)
|
||||
}
|
||||
|
||||
setenv_hex("api_address", (unsigned long)sig);
|
||||
debugf("API sig @ 0x%08x\n", sig);
|
||||
debugf("API sig @ 0x%lX\n", (unsigned long)sig);
|
||||
memcpy(sig->magic, API_SIG_MAGIC, 8);
|
||||
sig->version = API_SIG_VERSION;
|
||||
sig->syscall = &syscall;
|
||||
sig->checksum = 0;
|
||||
sig->checksum = crc32(0, (unsigned char *)sig,
|
||||
sizeof(struct api_signature));
|
||||
debugf("syscall entry: 0x%08x\n", sig->syscall);
|
||||
debugf("syscall entry: 0x%lX\n", (unsigned long)sig->syscall);
|
||||
}
|
||||
|
||||
void platform_set_mr(struct sys_info *si, unsigned long start, unsigned long size,
|
||||
|
@ -5,8 +5,8 @@ config SYS_ARCH
|
||||
default "mips"
|
||||
|
||||
config SYS_CPU
|
||||
default "mips32" if CPU_MIPS32_R1 || CPU_MIPS32_R2
|
||||
default "mips64" if CPU_MIPS64_R1 || CPU_MIPS64_R2
|
||||
default "mips32" if CPU_MIPS32
|
||||
default "mips64" if CPU_MIPS64
|
||||
|
||||
choice
|
||||
prompt "Target select"
|
||||
@ -28,6 +28,7 @@ config TARGET_MALTA
|
||||
select SUPPORTS_LITTLE_ENDIAN
|
||||
select SUPPORTS_CPU_MIPS32_R1
|
||||
select SUPPORTS_CPU_MIPS32_R2
|
||||
select SUPPORTS_CPU_MIPS32_R6
|
||||
select SWAP_IO_SPACE
|
||||
select MIPS_L1_CACHE_SHIFT_6
|
||||
|
||||
@ -55,6 +56,11 @@ config TARGET_PB1X00
|
||||
select SYS_MIPS_CACHE_INIT_RAM_LOAD
|
||||
select MIPS_TUNE_4KC
|
||||
|
||||
config ARCH_ATH79
|
||||
bool "Support QCA/Atheros ath79"
|
||||
select OF_CONTROL
|
||||
select DM
|
||||
|
||||
config MACH_PIC32
|
||||
bool "Support Microchip PIC32"
|
||||
select OF_CONTROL
|
||||
@ -67,6 +73,7 @@ source "board/imgtec/malta/Kconfig"
|
||||
source "board/micronas/vct/Kconfig"
|
||||
source "board/pb1x00/Kconfig"
|
||||
source "board/qemu-mips/Kconfig"
|
||||
source "arch/mips/mach-ath79/Kconfig"
|
||||
source "arch/mips/mach-pic32/Kconfig"
|
||||
|
||||
if MIPS
|
||||
@ -98,7 +105,7 @@ config CPU_MIPS32_R1
|
||||
depends on SUPPORTS_CPU_MIPS32_R1
|
||||
select 32BIT
|
||||
help
|
||||
Choose this option to build an U-Boot for release 1 or later of the
|
||||
Choose this option to build an U-Boot for release 1 through 5 of the
|
||||
MIPS32 architecture.
|
||||
|
||||
config CPU_MIPS32_R2
|
||||
@ -106,7 +113,15 @@ config CPU_MIPS32_R2
|
||||
depends on SUPPORTS_CPU_MIPS32_R2
|
||||
select 32BIT
|
||||
help
|
||||
Choose this option to build an U-Boot for release 2 or later of the
|
||||
Choose this option to build an U-Boot for release 2 through 5 of the
|
||||
MIPS32 architecture.
|
||||
|
||||
config CPU_MIPS32_R6
|
||||
bool "MIPS32 Release 6"
|
||||
depends on SUPPORTS_CPU_MIPS32_R6
|
||||
select 32BIT
|
||||
help
|
||||
Choose this option to build an U-Boot for release 6 or later of the
|
||||
MIPS32 architecture.
|
||||
|
||||
config CPU_MIPS64_R1
|
||||
@ -114,7 +129,7 @@ config CPU_MIPS64_R1
|
||||
depends on SUPPORTS_CPU_MIPS64_R1
|
||||
select 64BIT
|
||||
help
|
||||
Choose this option to build a kernel for release 1 or later of the
|
||||
Choose this option to build a kernel for release 1 through 5 of the
|
||||
MIPS64 architecture.
|
||||
|
||||
config CPU_MIPS64_R2
|
||||
@ -122,7 +137,15 @@ config CPU_MIPS64_R2
|
||||
depends on SUPPORTS_CPU_MIPS64_R2
|
||||
select 64BIT
|
||||
help
|
||||
Choose this option to build a kernel for release 2 or later of the
|
||||
Choose this option to build a kernel for release 2 through 5 of the
|
||||
MIPS64 architecture.
|
||||
|
||||
config CPU_MIPS64_R6
|
||||
bool "MIPS64 Release 6"
|
||||
depends on SUPPORTS_CPU_MIPS64_R6
|
||||
select 64BIT
|
||||
help
|
||||
Choose this option to build a kernel for release 6 or later of the
|
||||
MIPS64 architecture.
|
||||
|
||||
endchoice
|
||||
@ -169,19 +192,25 @@ config SUPPORTS_CPU_MIPS32_R1
|
||||
config SUPPORTS_CPU_MIPS32_R2
|
||||
bool
|
||||
|
||||
config SUPPORTS_CPU_MIPS32_R6
|
||||
bool
|
||||
|
||||
config SUPPORTS_CPU_MIPS64_R1
|
||||
bool
|
||||
|
||||
config SUPPORTS_CPU_MIPS64_R2
|
||||
bool
|
||||
|
||||
config SUPPORTS_CPU_MIPS64_R6
|
||||
bool
|
||||
|
||||
config CPU_MIPS32
|
||||
bool
|
||||
default y if CPU_MIPS32_R1 || CPU_MIPS32_R2
|
||||
default y if CPU_MIPS32_R1 || CPU_MIPS32_R2 || CPU_MIPS32_R6
|
||||
|
||||
config CPU_MIPS64
|
||||
bool
|
||||
default y if CPU_MIPS64_R1 || CPU_MIPS64_R2
|
||||
default y if CPU_MIPS64_R1 || CPU_MIPS64_R2 || CPU_MIPS64_R6
|
||||
|
||||
config MIPS_TUNE_4KC
|
||||
bool
|
||||
@ -192,6 +221,9 @@ config MIPS_TUNE_14KC
|
||||
config MIPS_TUNE_24KC
|
||||
bool
|
||||
|
||||
config MIPS_TUNE_74KC
|
||||
bool
|
||||
|
||||
config 32BIT
|
||||
bool
|
||||
|
||||
|
@ -8,6 +8,7 @@ libs-y += arch/mips/cpu/
|
||||
libs-y += arch/mips/lib/
|
||||
|
||||
machine-$(CONFIG_SOC_AU1X00) += au1x00
|
||||
machine-$(CONFIG_ARCH_ATH79) += ath79
|
||||
machine-$(CONFIG_MACH_PIC32) += pic32
|
||||
|
||||
machdirs := $(patsubst %,arch/mips/mach-%/,$(machine-y))
|
||||
@ -18,13 +19,16 @@ PLATFORM_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs))
|
||||
# Optimize for MIPS architectures
|
||||
arch-$(CONFIG_CPU_MIPS32_R1) += -march=mips32 -Wa,-mips32
|
||||
arch-$(CONFIG_CPU_MIPS32_R2) += -march=mips32r2 -Wa,-mips32r2
|
||||
arch-$(CONFIG_CPU_MIPS32_R6) += -march=mips32r6 -Wa,-mips32r6
|
||||
arch-$(CONFIG_CPU_MIPS64_R1) += -march=mips64 -Wa,-mips64
|
||||
arch-$(CONFIG_CPU_MIPS64_R2) += -march=mips64r2 -Wa,-mips64r2
|
||||
arch-$(CONFIG_CPU_MIPS64_R6) += -march=mips64r6 -Wa,-mips64r6
|
||||
|
||||
# Allow extra optimization for specific CPUs/SoCs
|
||||
tune-$(CONFIG_MIPS_TUNE_4KC) += -mtune=4kc
|
||||
tune-$(CONFIG_MIPS_TUNE_14KC) += -mtune=14kc
|
||||
tune-$(CONFIG_MIPS_TUNE_24KC) += -mtune=24kc
|
||||
tune-$(CONFIG_MIPS_TUNE_74KC) += -mtune=74kc
|
||||
|
||||
# Include default header files
|
||||
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <netdev.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/reboot.h>
|
||||
|
@ -164,12 +164,14 @@ reset:
|
||||
li t0, -16
|
||||
PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
|
||||
and sp, t1, t0 # force 16 byte alignment
|
||||
PTR_SUB sp, sp, GD_SIZE # reserve space for gd
|
||||
PTR_SUBU \
|
||||
sp, sp, GD_SIZE # reserve space for gd
|
||||
and sp, sp, t0 # force 16 byte alignment
|
||||
move k0, sp # save gd pointer
|
||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||
li t2, CONFIG_SYS_MALLOC_F_LEN
|
||||
PTR_SUB sp, sp, t2 # reserve space for early malloc
|
||||
PTR_SUBU \
|
||||
sp, sp, t2 # reserve space for early malloc
|
||||
and sp, sp, t0 # force 16 byte alignment
|
||||
#endif
|
||||
move fp, sp
|
||||
@ -179,7 +181,7 @@ reset:
|
||||
1:
|
||||
PTR_S zero, 0(t0)
|
||||
blt t0, t1, 1b
|
||||
PTR_ADDI t0, PTRSIZE
|
||||
PTR_ADDIU t0, PTRSIZE
|
||||
|
||||
#ifdef CONFIG_SYS_MALLOC_F_LEN
|
||||
PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
|
||||
@ -237,7 +239,7 @@ ENTRY(relocate_code)
|
||||
move a0, s2 # a0 <-- destination address
|
||||
|
||||
/* Jump to where we've relocated ourselves */
|
||||
PTR_ADDI t0, s2, in_ram - _start
|
||||
PTR_ADDIU t0, s2, in_ram - _start
|
||||
jr t0
|
||||
nop
|
||||
|
||||
@ -257,7 +259,7 @@ in_ram:
|
||||
PTR_L t3, -(1 * PTRSIZE)(t0) # t3 <-- num_got_entries
|
||||
PTR_L t8, -(2 * PTRSIZE)(t0) # t8 <-- _GLOBAL_OFFSET_TABLE_
|
||||
PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_
|
||||
PTR_ADDI t8, t8, 2 * PTRSIZE # skipping first two entries
|
||||
PTR_ADDIU t8, t8, 2 * PTRSIZE # skipping first two entries
|
||||
PTR_LI t2, 2
|
||||
1:
|
||||
PTR_L t1, 0(t8)
|
||||
@ -265,16 +267,16 @@ in_ram:
|
||||
PTR_ADD t1, s1
|
||||
PTR_S t1, 0(t8)
|
||||
2:
|
||||
PTR_ADDI t2, 1
|
||||
PTR_ADDIU t2, 1
|
||||
blt t2, t3, 1b
|
||||
PTR_ADDI t8, PTRSIZE
|
||||
PTR_ADDIU t8, PTRSIZE
|
||||
|
||||
/* Update dynamic relocations */
|
||||
PTR_L t1, -(4 * PTRSIZE)(t0) # t1 <-- __rel_dyn_start
|
||||
PTR_L t2, -(5 * PTRSIZE)(t0) # t2 <-- __rel_dyn_end
|
||||
|
||||
b 2f # skip first reserved entry
|
||||
PTR_ADDI t1, 2 * PTRSIZE
|
||||
PTR_ADDIU t1, 2 * PTRSIZE
|
||||
|
||||
1:
|
||||
lw t8, -4(t1) # t8 <-- relocation info
|
||||
@ -293,7 +295,7 @@ in_ram:
|
||||
|
||||
2:
|
||||
blt t1, t2, 1b
|
||||
PTR_ADDI t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes
|
||||
PTR_ADDIU t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes
|
||||
|
||||
/*
|
||||
* Clear BSS
|
||||
@ -307,7 +309,7 @@ in_ram:
|
||||
1:
|
||||
PTR_S zero, 0(t1)
|
||||
blt t1, t2, 1b
|
||||
PTR_ADDI t1, PTRSIZE
|
||||
PTR_ADDIU t1, PTRSIZE
|
||||
|
||||
move a0, s0 # a0 <-- gd
|
||||
move a1, s2
|
||||
|
@ -2,7 +2,10 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
dtb-$(CONFIG_TARGET_AP121) += ap121.dtb
|
||||
dtb-$(CONFIG_TARGET_AP143) += ap143.dtb
|
||||
dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb
|
||||
dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
|
||||
|
||||
targets += $(dtb-y)
|
||||
|
||||
|
43
arch/mips/dts/ap121.dts
Normal file
43
arch/mips/dts/ap121.dts
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "ar933x.dtsi"
|
||||
|
||||
/ {
|
||||
model = "AP121 Reference Board";
|
||||
compatible = "qca,ap121", "qca,ar933x";
|
||||
|
||||
aliases {
|
||||
spi0 = &spi0;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
};
|
||||
|
||||
&xtal {
|
||||
clock-frequency = <25000000>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
spi-max-frequency = <25000000>;
|
||||
status = "okay";
|
||||
spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-flash";
|
||||
memory-map = <0x9f000000 0x00800000>;
|
||||
spi-max-frequency = <25000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
43
arch/mips/dts/ap143.dts
Normal file
43
arch/mips/dts/ap143.dts
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "qca953x.dtsi"
|
||||
|
||||
/ {
|
||||
model = "AP143 Reference Board";
|
||||
compatible = "qca,ap143", "qca,qca953x";
|
||||
|
||||
aliases {
|
||||
spi0 = &spi0;
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
};
|
||||
|
||||
&xtal {
|
||||
clock-frequency = <25000000>;
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
spi-max-frequency = <25000000>;
|
||||
status = "okay";
|
||||
spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-flash";
|
||||
memory-map = <0x9f000000 0x00800000>;
|
||||
spi-max-frequency = <25000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
115
arch/mips/dts/ar933x.dtsi
Normal file
115
arch/mips/dts/ar933x.dtsi
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "qca,ar933x";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "mips,mips24Kc";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
xtal: xtal {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "xtal";
|
||||
};
|
||||
};
|
||||
|
||||
pinctrl {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "qca,ar933x-pinctrl";
|
||||
ranges;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x18040000 0x100>;
|
||||
};
|
||||
|
||||
ahb {
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
apb {
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ehci0: ehci@1b000100 {
|
||||
compatible = "generic-ehci";
|
||||
reg = <0x1b000100 0x100>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart0: uart@18020000 {
|
||||
compatible = "qca,ar9330-uart";
|
||||
reg = <0x18020000 0x20>;
|
||||
interrupts = <128 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gmac0: eth@0x19000000 {
|
||||
compatible = "qca,ag7240-mac";
|
||||
reg = <0x19000000 0x200>;
|
||||
phy = <&phy0>;
|
||||
phy-mode = "rmii";
|
||||
|
||||
status = "disabled";
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
gmac1: eth@0x1a000000 {
|
||||
compatible = "qca,ag7240-mac";
|
||||
reg = <0x1a000000 0x200>;
|
||||
phy = <&phy0>;
|
||||
phy-mode = "rgmii";
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
spi0: spi@1f000000 {
|
||||
compatible = "qca,ar7100-spi";
|
||||
reg = <0x1f000000 0x10>;
|
||||
interrupts = <129 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
status = "disabled";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
112
arch/mips/dts/ar934x.dtsi
Normal file
112
arch/mips/dts/ar934x.dtsi
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "qca,ar934x";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "mips,mips74Kc";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
xtal: xtal {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "xtal";
|
||||
};
|
||||
};
|
||||
|
||||
ahb {
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
apb {
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
ehci0: ehci@1b000100 {
|
||||
compatible = "generic-ehci";
|
||||
reg = <0x1b000100 0x100>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
uart0: uart@18020000 {
|
||||
compatible = "ns16550";
|
||||
reg = <0x18020000 0x20>;
|
||||
reg-shift = <2>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
gmac0: eth@0x19000000 {
|
||||
compatible = "qca,ag934x-mac";
|
||||
reg = <0x19000000 0x200>;
|
||||
phy = <&phy0>;
|
||||
phy-mode = "rgmii";
|
||||
|
||||
status = "disabled";
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
gmac1: eth@0x1a000000 {
|
||||
compatible = "qca,ag934x-mac";
|
||||
reg = <0x1a000000 0x200>;
|
||||
phy = <&phy1>;
|
||||
phy-mode = "rgmii";
|
||||
|
||||
status = "disabled";
|
||||
|
||||
mdio {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
phy1: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
spi0: spi@1f000000 {
|
||||
compatible = "qca,ar7100-spi";
|
||||
reg = <0x1f000000 0x10>;
|
||||
|
||||
status = "disabled";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
84
arch/mips/dts/qca953x.dtsi
Normal file
84
arch/mips/dts/qca953x.dtsi
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <dt-bindings/interrupt-controller/irq.h>
|
||||
#include "skeleton.dtsi"
|
||||
|
||||
/ {
|
||||
compatible = "qca,qca953x";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
cpus {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
cpu@0 {
|
||||
device_type = "cpu";
|
||||
compatible = "mips,mips24Kc";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
clocks {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
ranges;
|
||||
|
||||
xtal: xtal {
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-output-names = "xtal";
|
||||
};
|
||||
};
|
||||
|
||||
pinctrl {
|
||||
u-boot,dm-pre-reloc;
|
||||
compatible = "qca,qca953x-pinctrl";
|
||||
ranges;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0x18040000 0x100>;
|
||||
};
|
||||
|
||||
ahb {
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
apb {
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
uart0: uart@18020000 {
|
||||
compatible = "ns16550";
|
||||
reg = <0x18020000 0x20>;
|
||||
reg-shift = <2>;
|
||||
clock-frequency = <25000000>;
|
||||
interrupts = <128 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
spi0: spi@1f000000 {
|
||||
compatible = "qca,ar7100-spi";
|
||||
reg = <0x1f000000 0x10>;
|
||||
interrupts = <129 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
status = "disabled";
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
||||
};
|
||||
};
|
53
arch/mips/dts/tplink_wdr4300.dts
Normal file
53
arch/mips/dts/tplink_wdr4300.dts
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
#include "ar934x.dtsi"
|
||||
|
||||
/ {
|
||||
model = "TP-Link WDR4300 Board";
|
||||
compatible = "tplink,wdr4300", "qca,ar934x";
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
spi0 = &spi0;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
};
|
||||
|
||||
&ehci0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&gmac0 {
|
||||
phy-mode = "rgmii";
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
spi-max-frequency = <25000000>;
|
||||
status = "okay";
|
||||
spi-flash@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
compatible = "spi-flash";
|
||||
memory-map = <0x1e000000 0x00800000>;
|
||||
spi-max-frequency = <25000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
clock-frequency = <40000000>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&xtal {
|
||||
clock-frequency = <40000000>;
|
||||
};
|
@ -23,6 +23,12 @@ struct arch_global_data {
|
||||
unsigned long tbl;
|
||||
unsigned long lastinc;
|
||||
#endif
|
||||
#ifdef CONFIG_ARCH_ATH79
|
||||
unsigned long id;
|
||||
unsigned long soc;
|
||||
unsigned long rev;
|
||||
unsigned long ver;
|
||||
#endif
|
||||
};
|
||||
|
||||
#include <asm-generic/global_data.h>
|
||||
|
@ -64,7 +64,7 @@
|
||||
/* 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
|
||||
addiu \sz, \sz, 1
|
||||
|
||||
/* sz *= line_sz */
|
||||
mul \sz, \sz, \line_sz
|
||||
|
55
arch/mips/mach-ath79/Kconfig
Normal file
55
arch/mips/mach-ath79/Kconfig
Normal file
@ -0,0 +1,55 @@
|
||||
menu "QCA/Atheros 7xxx/9xxx platforms"
|
||||
depends on ARCH_ATH79
|
||||
|
||||
config SYS_SOC
|
||||
default "ath79"
|
||||
|
||||
config SOC_AR933X
|
||||
bool
|
||||
select SUPPORTS_BIG_ENDIAN
|
||||
select SUPPORTS_CPU_MIPS32_R1
|
||||
select SUPPORTS_CPU_MIPS32_R2
|
||||
select MIPS_TUNE_24KC
|
||||
help
|
||||
This supports QCA/Atheros ar933x family SOCs.
|
||||
|
||||
config SOC_AR934X
|
||||
bool
|
||||
select SUPPORTS_BIG_ENDIAN
|
||||
select SUPPORTS_CPU_MIPS32_R1
|
||||
select SUPPORTS_CPU_MIPS32_R2
|
||||
select MIPS_TUNE_74KC
|
||||
help
|
||||
This supports QCA/Atheros ar934x family SOCs.
|
||||
|
||||
config SOC_QCA953X
|
||||
bool
|
||||
select SUPPORTS_BIG_ENDIAN
|
||||
select SUPPORTS_CPU_MIPS32_R1
|
||||
select SUPPORTS_CPU_MIPS32_R2
|
||||
select MIPS_TUNE_24KC
|
||||
help
|
||||
This supports QCA/Atheros qca953x family SOCs.
|
||||
|
||||
choice
|
||||
prompt "Board select"
|
||||
|
||||
config TARGET_AP121
|
||||
bool "AP121 Reference Board"
|
||||
select SOC_AR933X
|
||||
|
||||
config TARGET_AP143
|
||||
bool "AP143 Reference Board"
|
||||
select SOC_QCA953X
|
||||
|
||||
config BOARD_TPLINK_WDR4300
|
||||
bool "TP-Link WDR4300 Board"
|
||||
select SOC_AR934X
|
||||
|
||||
endchoice
|
||||
|
||||
source "board/qca/ap121/Kconfig"
|
||||
source "board/qca/ap143/Kconfig"
|
||||
source "board/tplink/wdr4300/Kconfig"
|
||||
|
||||
endmenu
|
11
arch/mips/mach-ath79/Makefile
Normal file
11
arch/mips/mach-ath79/Makefile
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += reset.o
|
||||
obj-y += cpu.o
|
||||
obj-y += dram.o
|
||||
|
||||
obj-$(CONFIG_SOC_AR933X) += ar933x/
|
||||
obj-$(CONFIG_SOC_AR934X) += ar934x/
|
||||
obj-$(CONFIG_SOC_QCA953X) += qca953x/
|
7
arch/mips/mach-ath79/ar933x/Makefile
Normal file
7
arch/mips/mach-ath79/ar933x/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += clk.o
|
||||
obj-y += ddr.o
|
||||
obj-y += lowlevel_init.o
|
89
arch/mips/mach-ath79/ar933x/clk.c
Normal file
89
arch/mips/mach-ath79/ar933x/clk.c
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/reset.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static u32 ar933x_get_xtal(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = get_bootstrap();
|
||||
if (val & AR933X_BOOTSTRAP_REF_CLK_40)
|
||||
return 40000000;
|
||||
else
|
||||
return 25000000;
|
||||
}
|
||||
|
||||
int get_serial_clock(void)
|
||||
{
|
||||
return ar933x_get_xtal();
|
||||
}
|
||||
|
||||
int get_clocks(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 val, xtal, pll, div;
|
||||
|
||||
regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
xtal = ar933x_get_xtal();
|
||||
val = readl(regs + AR933X_PLL_CPU_CONFIG_REG);
|
||||
|
||||
/* VCOOUT = XTAL * DIV_INT */
|
||||
div = (val >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT)
|
||||
& AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
|
||||
pll = xtal / div;
|
||||
|
||||
/* PLLOUT = VCOOUT * (1/2^OUTDIV) */
|
||||
div = (val >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT)
|
||||
& AR933X_PLL_CPU_CONFIG_NINT_MASK;
|
||||
pll *= div;
|
||||
div = (val >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT)
|
||||
& AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
|
||||
if (!div)
|
||||
div = 1;
|
||||
pll >>= div;
|
||||
|
||||
val = readl(regs + AR933X_PLL_CLK_CTRL_REG);
|
||||
|
||||
/* CPU_CLK = PLLOUT / CPU_POST_DIV */
|
||||
div = ((val >> AR933X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT)
|
||||
& AR933X_PLL_CLK_CTRL_CPU_POST_DIV_MASK) + 1;
|
||||
gd->cpu_clk = pll / div;
|
||||
|
||||
/* DDR_CLK = PLLOUT / DDR_POST_DIV */
|
||||
div = ((val >> AR933X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT)
|
||||
& AR933X_PLL_CLK_CTRL_DDR_POST_DIV_MASK) + 1;
|
||||
gd->mem_clk = pll / div;
|
||||
|
||||
/* AHB_CLK = PLLOUT / AHB_POST_DIV */
|
||||
div = ((val >> AR933X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT)
|
||||
& AR933X_PLL_CLK_CTRL_AHB_POST_DIV_MASK) + 1;
|
||||
gd->bus_clk = pll / div;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_bus_freq(ulong dummy)
|
||||
{
|
||||
if (!gd->bus_clk)
|
||||
get_clocks();
|
||||
return gd->bus_clk;
|
||||
}
|
||||
|
||||
ulong get_ddr_freq(ulong dummy)
|
||||
{
|
||||
if (!gd->mem_clk)
|
||||
get_clocks();
|
||||
return gd->mem_clk;
|
||||
}
|
333
arch/mips/mach-ath79/ar933x/ddr.c
Normal file
333
arch/mips/mach-ath79/ar933x/ddr.c
Normal file
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
* Based on Atheros LSDK/QSDK
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/reset.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define DDR_CTRL_UPD_EMR3S BIT(5)
|
||||
#define DDR_CTRL_UPD_EMR2S BIT(4)
|
||||
#define DDR_CTRL_PRECHARGE BIT(3)
|
||||
#define DDR_CTRL_AUTO_REFRESH BIT(2)
|
||||
#define DDR_CTRL_UPD_EMRS BIT(1)
|
||||
#define DDR_CTRL_UPD_MRS BIT(0)
|
||||
|
||||
#define DDR_REFRESH_EN BIT(14)
|
||||
#define DDR_REFRESH_M 0x3ff
|
||||
#define DDR_REFRESH(x) ((x) & 0x3ff)
|
||||
#define DDR_REFRESH_VAL_25M (DDR_REFRESH_EN | DDR_REFRESH(390))
|
||||
#define DDR_REFRESH_VAL_40M (DDR_REFRESH_EN | DDR_REFRESH(624))
|
||||
|
||||
#define DDR_TRAS_S 0
|
||||
#define DDR_TRAS_M 0x1f
|
||||
#define DDR_TRAS(x) ((x) << DDR_TRAS_S)
|
||||
#define DDR_TRCD_M 0xf
|
||||
#define DDR_TRCD_S 5
|
||||
#define DDR_TRCD(x) ((x) << DDR_TRCD_S)
|
||||
#define DDR_TRP_M 0xf
|
||||
#define DDR_TRP_S 9
|
||||
#define DDR_TRP(x) ((x) << DDR_TRP_S)
|
||||
#define DDR_TRRD_M 0xf
|
||||
#define DDR_TRRD_S 13
|
||||
#define DDR_TRRD(x) ((x) << DDR_TRRD_S)
|
||||
#define DDR_TRFC_M 0x7f
|
||||
#define DDR_TRFC_S 17
|
||||
#define DDR_TRFC(x) ((x) << DDR_TRFC_S)
|
||||
#define DDR_TMRD_M 0xf
|
||||
#define DDR_TMRD_S 23
|
||||
#define DDR_TMRD(x) ((x) << DDR_TMRD_S)
|
||||
#define DDR_CAS_L_M 0x17
|
||||
#define DDR_CAS_L_S 27
|
||||
#define DDR_CAS_L(x) (((x) & DDR_CAS_L_M) << DDR_CAS_L_S)
|
||||
#define DDR_OPEN BIT(30)
|
||||
#define DDR_CONF_REG_VAL (DDR_TRAS(16) | DDR_TRCD(6) | \
|
||||
DDR_TRP(6) | DDR_TRRD(4) | \
|
||||
DDR_TRFC(30) | DDR_TMRD(15) | \
|
||||
DDR_CAS_L(7) | DDR_OPEN)
|
||||
|
||||
#define DDR_BURST_LEN_S 0
|
||||
#define DDR_BURST_LEN_M 0xf
|
||||
#define DDR_BURST_LEN(x) ((x) << DDR_BURST_LEN_S)
|
||||
#define DDR_BURST_TYPE BIT(4)
|
||||
#define DDR_CNTL_OE_EN BIT(5)
|
||||
#define DDR_PHASE_SEL BIT(6)
|
||||
#define DDR_CKE BIT(7)
|
||||
#define DDR_TWR_S 8
|
||||
#define DDR_TWR_M 0xf
|
||||
#define DDR_TWR(x) ((x) << DDR_TWR_S)
|
||||
#define DDR_TRTW_S 12
|
||||
#define DDR_TRTW_M 0x1f
|
||||
#define DDR_TRTW(x) ((x) << DDR_TRTW_S)
|
||||
#define DDR_TRTP_S 17
|
||||
#define DDR_TRTP_M 0xf
|
||||
#define DDR_TRTP(x) ((x) << DDR_TRTP_S)
|
||||
#define DDR_TWTR_S 21
|
||||
#define DDR_TWTR_M 0x1f
|
||||
#define DDR_TWTR(x) ((x) << DDR_TWTR_S)
|
||||
#define DDR_G_OPEN_L_S 26
|
||||
#define DDR_G_OPEN_L_M 0xf
|
||||
#define DDR_G_OPEN_L(x) ((x) << DDR_G_OPEN_L_S)
|
||||
#define DDR_HALF_WIDTH_LOW BIT(31)
|
||||
#define DDR_CONF2_REG_VAL (DDR_BURST_LEN(8) | DDR_CNTL_OE_EN | \
|
||||
DDR_CKE | DDR_TWR(6) | DDR_TRTW(14) | \
|
||||
DDR_TRTP(8) | DDR_TWTR(14) | \
|
||||
DDR_G_OPEN_L(7) | DDR_HALF_WIDTH_LOW)
|
||||
|
||||
#define DDR2_CONF_TWL_S 10
|
||||
#define DDR2_CONF_TWL_M 0xf
|
||||
#define DDR2_CONF_TWL(x) (((x) & DDR2_CONF_TWL_M) << DDR2_CONF_TWL_S)
|
||||
#define DDR2_CONF_ODT BIT(9)
|
||||
#define DDR2_CONF_TFAW_S 2
|
||||
#define DDR2_CONF_TFAW_M 0x3f
|
||||
#define DDR2_CONF_TFAW(x) (((x) & DDR2_CONF_TFAW_M) << DDR2_CONF_TFAW_S)
|
||||
#define DDR2_CONF_EN BIT(0)
|
||||
#define DDR2_CONF_VAL (DDR2_CONF_TWL(2) | DDR2_CONF_ODT | \
|
||||
DDR2_CONF_TFAW(22) | DDR2_CONF_EN)
|
||||
|
||||
#define DDR1_EXT_MODE_VAL 0x02
|
||||
#define DDR2_EXT_MODE_VAL 0x402
|
||||
#define DDR2_EXT_MODE_OCD_VAL 0x382
|
||||
#define DDR1_MODE_DLL_VAL 0x133
|
||||
#define DDR2_MODE_DLL_VAL 0x100
|
||||
#define DDR1_MODE_VAL 0x33
|
||||
#define DDR2_MODE_VAL 0xa33
|
||||
#define DDR_TAP_VAL0 0x08
|
||||
#define DDR_TAP_VAL1 0x09
|
||||
|
||||
void ddr_init(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 val;
|
||||
|
||||
regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
writel(DDR_CONF_REG_VAL, regs + AR71XX_DDR_REG_CONFIG);
|
||||
writel(DDR_CONF2_REG_VAL, regs + AR71XX_DDR_REG_CONFIG2);
|
||||
|
||||
val = get_bootstrap();
|
||||
if (val & AR933X_BOOTSTRAP_DDR2) {
|
||||
/* AHB maximum timeout */
|
||||
writel(0xfffff, regs + AR933X_DDR_REG_TIMEOUT_MAX);
|
||||
|
||||
/* Enable DDR2 */
|
||||
writel(DDR2_CONF_VAL, regs + AR933X_DDR_REG_DDR2_CONFIG);
|
||||
|
||||
/* Precharge All */
|
||||
writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Disable High Temperature Self-Refresh, Full Array */
|
||||
writel(0x00, regs + AR933X_DDR_REG_EMR2);
|
||||
|
||||
/* Extended Mode Register 2 Set (EMR2S) */
|
||||
writel(DDR_CTRL_UPD_EMR2S, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
writel(0x00, regs + AR933X_DDR_REG_EMR3);
|
||||
|
||||
/* Extended Mode Register 3 Set (EMR3S) */
|
||||
writel(DDR_CTRL_UPD_EMR3S, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Enable DLL, Full strength, ODT Disabled */
|
||||
writel(0x00, regs + AR71XX_DDR_REG_EMR);
|
||||
|
||||
/* Extended Mode Register Set (EMRS) */
|
||||
writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Reset DLL */
|
||||
writel(DDR2_MODE_DLL_VAL, regs + AR71XX_DDR_REG_MODE);
|
||||
|
||||
/* Mode Register Set (MRS) */
|
||||
writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Precharge All */
|
||||
writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Auto Refresh */
|
||||
writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
|
||||
writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Write recovery (WR) 6 clock, CAS Latency 3, Burst Length 8 */
|
||||
writel(DDR2_MODE_VAL, regs + AR71XX_DDR_REG_MODE);
|
||||
/* Mode Register Set (MRS) */
|
||||
writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Enable OCD defaults, Enable DLL, Reduced Drive Strength */
|
||||
writel(DDR2_EXT_MODE_OCD_VAL, regs + AR71XX_DDR_REG_EMR);
|
||||
|
||||
/* Extended Mode Register Set (EMRS) */
|
||||
writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* OCD exit, Enable DLL, Enable /DQS, Reduced Drive Strength */
|
||||
writel(DDR2_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
|
||||
/* Extended Mode Register Set (EMRS) */
|
||||
writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Refresh time control */
|
||||
if (val & AR933X_BOOTSTRAP_REF_CLK_40)
|
||||
writel(DDR_REFRESH_VAL_40M, regs +
|
||||
AR71XX_DDR_REG_REFRESH);
|
||||
else
|
||||
writel(DDR_REFRESH_VAL_25M, regs +
|
||||
AR71XX_DDR_REG_REFRESH);
|
||||
|
||||
/* DQS 0 Tap Control */
|
||||
writel(DDR_TAP_VAL0, regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
|
||||
/* DQS 1 Tap Control */
|
||||
writel(DDR_TAP_VAL1, regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
|
||||
/* For 16-bit DDR */
|
||||
writel(0xff, regs + AR71XX_DDR_REG_RD_CYCLE);
|
||||
} else {
|
||||
/* AHB maximum timeout */
|
||||
writel(0xfffff, regs + AR933X_DDR_REG_TIMEOUT_MAX);
|
||||
|
||||
/* Precharge All */
|
||||
writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Reset DLL, Burst Length 8, CAS Latency 3 */
|
||||
writel(DDR1_MODE_DLL_VAL, regs + AR71XX_DDR_REG_MODE);
|
||||
|
||||
/* Forces an MRS update cycle in DDR */
|
||||
writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Enable DLL, Full strength */
|
||||
writel(DDR1_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
|
||||
|
||||
/* Extended Mode Register Set (EMRS) */
|
||||
writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Precharge All */
|
||||
writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Normal DLL, Burst Length 8, CAS Latency 3 */
|
||||
writel(DDR1_MODE_VAL, regs + AR71XX_DDR_REG_MODE);
|
||||
|
||||
/* Mode Register Set (MRS) */
|
||||
writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
|
||||
/* Refresh time control */
|
||||
if (val & AR933X_BOOTSTRAP_REF_CLK_40)
|
||||
writel(DDR_REFRESH_VAL_40M, regs +
|
||||
AR71XX_DDR_REG_REFRESH);
|
||||
else
|
||||
writel(DDR_REFRESH_VAL_25M, regs +
|
||||
AR71XX_DDR_REG_REFRESH);
|
||||
|
||||
/* DQS 0 Tap Control */
|
||||
writel(DDR_TAP_VAL0, regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
|
||||
/* DQS 1 Tap Control */
|
||||
writel(DDR_TAP_VAL1, regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
|
||||
/* For 16-bit DDR */
|
||||
writel(0xff, regs + AR71XX_DDR_REG_RD_CYCLE);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_tap_tuning(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 *addr_k0, *addr_k1, *addr;
|
||||
u32 val, tap, upper, lower;
|
||||
int i, j, dir, err, done;
|
||||
|
||||
regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
/* Init memory pattern */
|
||||
addr = (void *)CKSEG0ADDR(0x2000);
|
||||
for (i = 0; i < 256; i++) {
|
||||
val = 0;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (i & (1 << j)) {
|
||||
if (j % 2)
|
||||
val |= 0xffff0000;
|
||||
else
|
||||
val |= 0x0000ffff;
|
||||
}
|
||||
|
||||
if (j % 2) {
|
||||
*addr++ = val;
|
||||
val = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = 0;
|
||||
done = 0;
|
||||
dir = 1;
|
||||
tap = readl(regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
val = tap;
|
||||
while (!done) {
|
||||
err = 0;
|
||||
|
||||
/* Update new DDR tap value */
|
||||
writel(val, regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
writel(val, regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
|
||||
/* Compare DDR with cache */
|
||||
for (i = 0; i < 2; i++) {
|
||||
addr_k1 = (void *)CKSEG1ADDR(0x2000);
|
||||
addr_k0 = (void *)CKSEG0ADDR(0x2000);
|
||||
addr = (void *)CKSEG0ADDR(0x3000);
|
||||
|
||||
while (addr_k0 < addr) {
|
||||
if (*addr_k1++ != *addr_k0++) {
|
||||
err = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (err)
|
||||
break;
|
||||
}
|
||||
|
||||
if (err) {
|
||||
/* Save upper/lower threshold if error */
|
||||
if (dir) {
|
||||
dir = 0;
|
||||
val--;
|
||||
upper = val;
|
||||
val = tap;
|
||||
} else {
|
||||
val++;
|
||||
lower = val;
|
||||
done = 1;
|
||||
}
|
||||
} else {
|
||||
/* Try the next value until limitation */
|
||||
if (dir) {
|
||||
if (val < 0x20) {
|
||||
val++;
|
||||
} else {
|
||||
dir = 0;
|
||||
upper = val;
|
||||
val = tap;
|
||||
}
|
||||
} else {
|
||||
if (!val) {
|
||||
lower = val;
|
||||
done = 1;
|
||||
} else {
|
||||
val--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* compute an intermediate value and write back */
|
||||
val = (upper + lower) / 2;
|
||||
writel(val, regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
val++;
|
||||
writel(val, regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
}
|
280
arch/mips/mach-ath79/ar933x/lowlevel_init.S
Normal file
280
arch/mips/mach-ath79/ar933x/lowlevel_init.S
Normal file
@ -0,0 +1,280 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
* Based on Atheros LSDK/QSDK and u-boot_mod project
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
|
||||
#define SET_BIT(val, bit) ((val) | (1 << (bit)))
|
||||
#define SET_PLL_PD(val) SET_BIT(val, 30)
|
||||
#define AHB_DIV_TO_4(val) SET_BIT(SET_BIT(val, 15), 16)
|
||||
#define PLL_BYPASS(val) SET_BIT(val, 2)
|
||||
|
||||
#define MK_PLL_CONF(divint, refdiv, range, outdiv) \
|
||||
(((0x3F & divint) << 10) | \
|
||||
((0x1F & refdiv) << 16) | \
|
||||
((0x1 & range) << 21) | \
|
||||
((0x7 & outdiv) << 23) )
|
||||
|
||||
#define MK_CLK_CNTL(cpudiv, ddrdiv, ahbdiv) \
|
||||
(((0x3 & (cpudiv - 1)) << 5) | \
|
||||
((0x3 & (ddrdiv - 1)) << 10) | \
|
||||
((0x3 & (ahbdiv - 1)) << 15) )
|
||||
|
||||
/*
|
||||
* PLL_CPU_CONFIG_VAL
|
||||
*
|
||||
* Bit30 is set (CPU_PLLPWD = 1 -> power down control for CPU PLL)
|
||||
* After PLL configuration we need to clear this bit
|
||||
*
|
||||
* Values written into CPU PLL Configuration (CPU_PLL_CONFIG)
|
||||
*
|
||||
* bits 10..15 (6bit) DIV_INT (Integer part of the DIV to CPU PLL)
|
||||
* => 32 (0x20) VCOOUT = XTAL * DIV_INT
|
||||
* bits 16..20 (5bit) REFDIV (Reference clock divider)
|
||||
* => 1 (0x1) [Must start at values 1]
|
||||
* bits 21 (1bit) RANGE (VCO frequency range of the CPU PLL)
|
||||
* => 0 (0x0) [Doesn't impact clock values]
|
||||
* bits 23..25 (3bit) OUTDIV (Ratio between VCO and PLL output)
|
||||
* => 1 (0x1) [0 is illegal!]
|
||||
* PLLOUT = VCOOUT * (1/2^OUTDIV)
|
||||
*/
|
||||
/* DIV_INT=32 (25MHz*32/2=400MHz), REFDIV=1, RANGE=0, OUTDIV=1 */
|
||||
#define PLL_CPU_CONFIG_VAL_40M MK_PLL_CONF(20, 1, 0, 1)
|
||||
/* DIV_INT=20 (40MHz*20/2=400MHz), REFDIV=1, RANGE=0, OUTDIV=1 */
|
||||
#define PLL_CPU_CONFIG_VAL_25M MK_PLL_CONF(32, 1, 0, 1)
|
||||
|
||||
/*
|
||||
* PLL_CLK_CONTROL_VAL
|
||||
*
|
||||
* In PLL_CLK_CONTROL_VAL bit 2 is set (BYPASS = 1 -> bypass PLL)
|
||||
* After PLL configuration we need to clear this bit
|
||||
*
|
||||
* Values written into CPU Clock Control Register CLOCK_CONTROL
|
||||
*
|
||||
* bits 2 (1bit) BYPASS (Bypass PLL. This defaults to 1 for test.
|
||||
* Software must enable the CPU PLL for normal and
|
||||
* then set this bit to 0)
|
||||
* bits 5..6 (2bit) CPU_POST_DIV => 0 (DEFAULT, Ratio = 1)
|
||||
* CPU_CLK = PLLOUT / CPU_POST_DIV
|
||||
* bits 10..11 (2bit) DDR_POST_DIV => 0 (DEFAULT, Ratio = 1)
|
||||
* DDR_CLK = PLLOUT / DDR_POST_DIV
|
||||
* bits 15..16 (2bit) AHB_POST_DIV => 1 (DEFAULT, Ratio = 2)
|
||||
* AHB_CLK = PLLOUT / AHB_POST_DIV
|
||||
*
|
||||
*/
|
||||
#define PLL_CLK_CONTROL_VAL MK_CLK_CNTL(1, 1, 2)
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
|
||||
LEAF(lowlevel_init)
|
||||
/* These three WLAN_RESET will avoid original issue */
|
||||
li t3, 0x03
|
||||
1:
|
||||
li t0, CKSEG1ADDR(AR71XX_RESET_BASE)
|
||||
lw t1, AR933X_RESET_REG_RESET_MODULE(t0)
|
||||
ori t1, t1, 0x0800
|
||||
sw t1, AR933X_RESET_REG_RESET_MODULE(t0)
|
||||
nop
|
||||
lw t1, AR933X_RESET_REG_RESET_MODULE(t0)
|
||||
li t2, 0xfffff7ff
|
||||
and t1, t1, t2
|
||||
sw t1, AR933X_RESET_REG_RESET_MODULE(t0)
|
||||
nop
|
||||
addi t3, t3, -1
|
||||
bnez t3, 1b
|
||||
nop
|
||||
|
||||
li t2, 0x20
|
||||
2:
|
||||
beqz t2, 1b
|
||||
nop
|
||||
addi t2, t2, -1
|
||||
lw t5, AR933X_RESET_REG_BOOTSTRAP(t0)
|
||||
andi t1, t5, 0x10
|
||||
bnez t1, 2b
|
||||
nop
|
||||
|
||||
li t1, 0x02110E
|
||||
sw t1, AR933X_RESET_REG_BOOTSTRAP(t0)
|
||||
nop
|
||||
|
||||
/* RTC Force Wake */
|
||||
li t0, CKSEG1ADDR(AR933X_RTC_BASE)
|
||||
li t1, 0x03
|
||||
sw t1, AR933X_RTC_REG_FORCE_WAKE(t0)
|
||||
nop
|
||||
nop
|
||||
|
||||
/* RTC Reset */
|
||||
li t1, 0x00
|
||||
sw t1, AR933X_RTC_REG_RESET(t0)
|
||||
nop
|
||||
nop
|
||||
|
||||
li t1, 0x01
|
||||
sw t1, AR933X_RTC_REG_RESET(t0)
|
||||
nop
|
||||
nop
|
||||
|
||||
/* Wait for RTC in on state */
|
||||
1:
|
||||
lw t1, AR933X_RTC_REG_STATUS(t0)
|
||||
andi t1, t1, 0x02
|
||||
beqz t1, 1b
|
||||
nop
|
||||
|
||||
/* Program ki/kd */
|
||||
li t0, CKSEG1ADDR(AR933X_SRIF_BASE)
|
||||
andi t1, t5, 0x01 # t5 BOOT_STRAP
|
||||
bnez t1, 1f
|
||||
nop
|
||||
li t1, 0x19e82f01
|
||||
b 2f
|
||||
nop
|
||||
1:
|
||||
li t1, 0x18e82f01
|
||||
2:
|
||||
sw t1, AR933X_SRIF_DDR_DPLL2_REG(t0)
|
||||
|
||||
/* Program phase shift */
|
||||
lw t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
|
||||
li t2, 0xc07fffff
|
||||
and t1, t1, t2
|
||||
li t2, 0x800000
|
||||
or t1, t1, t2
|
||||
sw t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
|
||||
nop
|
||||
|
||||
/* in some cases, the SoC doesn't start with higher clock on AHB */
|
||||
li t0, CKSEG1ADDR(AR71XX_PLL_BASE)
|
||||
li t1, AHB_DIV_TO_4(PLL_BYPASS(PLL_CLK_CONTROL_VAL))
|
||||
sw t1, AR933X_PLL_CLK_CTRL_REG(t0)
|
||||
nop
|
||||
|
||||
/* Set SETTLE_TIME in CPU PLL */
|
||||
andi t1, t5, 0x01 # t5 BOOT_STRAP
|
||||
bnez t1, 1f
|
||||
nop
|
||||
li t1, 0x0352
|
||||
b 2f
|
||||
nop
|
||||
1:
|
||||
li t1, 0x0550
|
||||
2:
|
||||
sw t1, AR71XX_PLL_REG_SEC_CONFIG(t0)
|
||||
nop
|
||||
|
||||
/* Set nint, frac, refdiv, outdiv, range according to xtal */
|
||||
0:
|
||||
andi t1, t5, 0x01 # t5 BOOT_STRAP
|
||||
bnez t1, 1f
|
||||
nop
|
||||
li t1, SET_PLL_PD(PLL_CPU_CONFIG_VAL_25M)
|
||||
b 2f
|
||||
nop
|
||||
1:
|
||||
li t1, SET_PLL_PD(PLL_CPU_CONFIG_VAL_40M)
|
||||
2:
|
||||
sw t1, AR933X_PLL_CPU_CONFIG_REG(t0)
|
||||
nop
|
||||
1:
|
||||
lw t1, AR933X_PLL_CPU_CONFIG_REG(t0)
|
||||
li t2, 0x80000000
|
||||
and t1, t1, t2
|
||||
bnez t1, 1b
|
||||
nop
|
||||
|
||||
/* Put frac bit19:10 configuration */
|
||||
li t1, 0x1003E8
|
||||
sw t1, AR933X_PLL_DITHER_FRAC_REG(t0)
|
||||
nop
|
||||
|
||||
/* Clear PLL power down bit in CPU PLL configuration */
|
||||
andi t1, t5, 0x01 # t5 BOOT_STRAP
|
||||
bnez t1, 1f
|
||||
nop
|
||||
li t1, PLL_CPU_CONFIG_VAL_25M
|
||||
b 2f
|
||||
nop
|
||||
1:
|
||||
li t1, PLL_CPU_CONFIG_VAL_40M
|
||||
2:
|
||||
sw t1, AR933X_PLL_CPU_CONFIG_REG(t0)
|
||||
nop
|
||||
|
||||
/* Wait for PLL update -> bit 31 in CPU_PLL_CONFIG should be 0 */
|
||||
1:
|
||||
lw t1, AR933X_PLL_CPU_CONFIG_REG(t0)
|
||||
li t2, 0x80000000
|
||||
and t1, t1, t2
|
||||
bnez t1, 1b
|
||||
nop
|
||||
|
||||
/* Confirm DDR PLL lock */
|
||||
li t3, 100
|
||||
li t4, 0
|
||||
|
||||
2:
|
||||
addi t4, t4, 1
|
||||
bgt t4, t3, 0b
|
||||
nop
|
||||
|
||||
li t3, 5
|
||||
3:
|
||||
/* Clear do_meas */
|
||||
li t0, CKSEG1ADDR(AR933X_SRIF_BASE)
|
||||
lw t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
|
||||
li t2, 0xBFFFFFFF
|
||||
and t1, t1, t2
|
||||
sw t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
|
||||
nop
|
||||
|
||||
li t2, 10
|
||||
1:
|
||||
subu t2, t2, 1
|
||||
bnez t2, 1b
|
||||
nop
|
||||
|
||||
/* Set do_meas */
|
||||
li t2, 0x40000000
|
||||
or t1, t1, t2
|
||||
sw t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
|
||||
nop
|
||||
|
||||
/* Check meas_done */
|
||||
1:
|
||||
lw t1, AR933X_SRIF_DDR_DPLL4_REG(t0)
|
||||
andi t1, t1, 0x8
|
||||
beqz t1, 1b
|
||||
nop
|
||||
|
||||
lw t1, AR933X_SRIF_DDR_DPLL3_REG(t0)
|
||||
li t2, 0x007FFFF8
|
||||
and t1, t1, t2
|
||||
srl t1, t1, 3
|
||||
li t2, 0x4000
|
||||
bgt t1, t2, 2b
|
||||
nop
|
||||
addi t3, t3, -1
|
||||
bnez t3, 3b
|
||||
nop
|
||||
|
||||
/* clear PLL bypass (bit 2) in CPU CLOCK CONTROL register */
|
||||
li t0, CKSEG1ADDR(AR71XX_PLL_BASE)
|
||||
li t1, PLL_CLK_CONTROL_VAL
|
||||
sw t1, AR933X_PLL_CLK_CTRL_REG(t0)
|
||||
nop
|
||||
|
||||
nop
|
||||
jr ra
|
||||
nop
|
||||
END(lowlevel_init)
|
7
arch/mips/mach-ath79/ar934x/Makefile
Normal file
7
arch/mips/mach-ath79/ar934x/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += cpu.o
|
||||
obj-y += clk.o
|
||||
obj-y += ddr.o
|
334
arch/mips/mach-ath79/ar934x/clk.c
Normal file
334
arch/mips/mach-ath79/ar934x/clk.c
Normal file
@ -0,0 +1,334 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/reset.h>
|
||||
#include <wait_bit.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/*
|
||||
* The math for calculating PLL:
|
||||
* NFRAC * 2^8
|
||||
* NINT + -------------
|
||||
* XTAL [MHz] 2^(18 - 1)
|
||||
* PLL [MHz] = ------------ * ----------------------
|
||||
* REFDIV 2^OUTDIV
|
||||
*
|
||||
* Unfortunatelly, there is no way to reliably compute the variables.
|
||||
* The vendor U-Boot port contains macros for various combinations of
|
||||
* CPU PLL / DDR PLL / AHB bus speed and there is no obvious pattern
|
||||
* in those numbers.
|
||||
*/
|
||||
struct ar934x_pll_config {
|
||||
u8 range;
|
||||
u8 refdiv;
|
||||
u8 outdiv;
|
||||
/* Index 0 is for XTAL=25MHz , Index 1 is for XTAL=40MHz */
|
||||
u8 nint[2];
|
||||
};
|
||||
|
||||
struct ar934x_clock_config {
|
||||
u16 cpu_freq;
|
||||
u16 ddr_freq;
|
||||
u16 ahb_freq;
|
||||
|
||||
struct ar934x_pll_config cpu_pll;
|
||||
struct ar934x_pll_config ddr_pll;
|
||||
};
|
||||
|
||||
static const struct ar934x_clock_config ar934x_clock_config[] = {
|
||||
{ 300, 300, 150, { 1, 1, 1, { 24, 15 } }, { 1, 1, 1, { 24, 15 } } },
|
||||
{ 400, 200, 200, { 1, 1, 1, { 32, 20 } }, { 1, 1, 2, { 32, 20 } } },
|
||||
{ 400, 400, 200, { 0, 1, 1, { 32, 20 } }, { 0, 1, 1, { 32, 20 } } },
|
||||
{ 500, 400, 200, { 1, 1, 0, { 20, 12 } }, { 0, 1, 1, { 32, 20 } } },
|
||||
{ 533, 400, 200, { 1, 1, 0, { 21, 13 } }, { 0, 1, 1, { 32, 20 } } },
|
||||
{ 533, 500, 250, { 1, 1, 0, { 21, 13 } }, { 0, 1, 0, { 20, 12 } } },
|
||||
{ 560, 480, 240, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 19, 12 } } },
|
||||
{ 566, 400, 200, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 16, 10 } } },
|
||||
{ 566, 450, 225, { 1, 1, 0, { 22, 14 } }, { 0, 1, 1, { 36, 22 } } },
|
||||
{ 566, 475, 237, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 19, 11 } } },
|
||||
{ 566, 500, 250, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 20, 12 } } },
|
||||
{ 566, 525, 262, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 21, 13 } } },
|
||||
{ 566, 550, 275, { 1, 1, 0, { 22, 14 } }, { 1, 1, 0, { 22, 13 } } },
|
||||
{ 600, 266, 133, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 21, 16 } } },
|
||||
{ 600, 266, 200, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 21, 16 } } },
|
||||
{ 600, 300, 150, { 0, 1, 0, { 24, 15 } }, { 0, 1, 1, { 24, 15 } } },
|
||||
{ 600, 332, 166, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 26, 16 } } },
|
||||
{ 600, 332, 200, { 0, 1, 0, { 24, 15 } }, { 1, 1, 1, { 26, 16 } } },
|
||||
{ 600, 400, 200, { 0, 1, 0, { 24, 15 } }, { 0, 1, 1, { 32, 20 } } },
|
||||
{ 600, 450, 200, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 18, 20 } } },
|
||||
{ 600, 500, 250, { 0, 1, 0, { 24, 15 } }, { 1, 1, 0, { 20, 12 } } },
|
||||
{ 600, 525, 262, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 21, 20 } } },
|
||||
{ 600, 550, 275, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 22, 20 } } },
|
||||
{ 600, 575, 287, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 23, 14 } } },
|
||||
{ 600, 600, 300, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 24, 20 } } },
|
||||
{ 600, 650, 325, { 0, 1, 0, { 24, 15 } }, { 0, 1, 0, { 26, 20 } } },
|
||||
{ 650, 600, 300, { 0, 1, 0, { 26, 15 } }, { 0, 1, 0, { 24, 20 } } },
|
||||
{ 700, 400, 200, { 3, 1, 0, { 28, 17 } }, { 0, 1, 1, { 32, 20 } } },
|
||||
};
|
||||
|
||||
static void ar934x_srif_pll_cfg(void __iomem *pll_reg_base, const u32 srif_val)
|
||||
{
|
||||
u32 reg;
|
||||
do {
|
||||
writel(0x10810f00, pll_reg_base + 0x4);
|
||||
writel(srif_val, pll_reg_base + 0x0);
|
||||
writel(0xd0810f00, pll_reg_base + 0x4);
|
||||
writel(0x03000000, pll_reg_base + 0x8);
|
||||
writel(0xd0800f00, pll_reg_base + 0x4);
|
||||
|
||||
clrbits_be32(pll_reg_base + 0x8, BIT(30));
|
||||
udelay(5);
|
||||
setbits_be32(pll_reg_base + 0x8, BIT(30));
|
||||
udelay(5);
|
||||
|
||||
wait_for_bit("clk", pll_reg_base + 0xc, BIT(3), 1, 10, 0);
|
||||
|
||||
clrbits_be32(pll_reg_base + 0x8, BIT(30));
|
||||
udelay(5);
|
||||
|
||||
/* Check if CPU SRIF PLL locked. */
|
||||
reg = readl(pll_reg_base + 0x8);
|
||||
reg = (reg & 0x7ffff8) >> 3;
|
||||
} while (reg >= 0x40000);
|
||||
}
|
||||
|
||||
void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz)
|
||||
{
|
||||
void __iomem *srif_regs = map_physmem(AR934X_SRIF_BASE,
|
||||
AR934X_SRIF_SIZE, MAP_NOCACHE);
|
||||
void __iomem *pll_regs = map_physmem(AR71XX_PLL_BASE,
|
||||
AR71XX_PLL_SIZE, MAP_NOCACHE);
|
||||
const struct ar934x_pll_config *pll_cfg;
|
||||
int i, pll_nint, pll_refdiv, xtal_40 = 0;
|
||||
u32 reg, cpu_pll, cpu_srif, ddr_pll, ddr_srif;
|
||||
|
||||
/* Configure SRIF PLL with initial values. */
|
||||
writel(0x13210f00, srif_regs + AR934X_SRIF_CPU_DPLL2_REG);
|
||||
writel(0x03000000, srif_regs + AR934X_SRIF_CPU_DPLL3_REG);
|
||||
writel(0x13210f00, srif_regs + AR934X_SRIF_DDR_DPLL2_REG);
|
||||
writel(0x03000000, srif_regs + AR934X_SRIF_DDR_DPLL3_REG);
|
||||
writel(0x03000000, srif_regs + 0x188); /* Undocumented reg :-) */
|
||||
|
||||
/* Test for 40MHz XTAL */
|
||||
reg = get_bootstrap();
|
||||
if (reg & AR934X_BOOTSTRAP_REF_CLK_40) {
|
||||
xtal_40 = 1;
|
||||
cpu_srif = 0x41c00000;
|
||||
ddr_srif = 0x41680000;
|
||||
} else {
|
||||
xtal_40 = 0;
|
||||
cpu_srif = 0x29c00000;
|
||||
ddr_srif = 0x29680000;
|
||||
}
|
||||
|
||||
/* Locate CPU/DDR PLL configuration */
|
||||
for (i = 0; i < ARRAY_SIZE(ar934x_clock_config); i++) {
|
||||
if (cpu_mhz != ar934x_clock_config[i].cpu_freq)
|
||||
continue;
|
||||
if (ddr_mhz != ar934x_clock_config[i].ddr_freq)
|
||||
continue;
|
||||
if (ahb_mhz != ar934x_clock_config[i].ahb_freq)
|
||||
continue;
|
||||
|
||||
/* Entry found */
|
||||
pll_cfg = &ar934x_clock_config[i].cpu_pll;
|
||||
pll_nint = pll_cfg->nint[xtal_40];
|
||||
pll_refdiv = pll_cfg->refdiv;
|
||||
cpu_pll =
|
||||
(pll_nint << AR934X_PLL_CPU_CONFIG_NINT_SHIFT) |
|
||||
(pll_refdiv << AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) |
|
||||
(pll_cfg->range << AR934X_PLL_CPU_CONFIG_RANGE_SHIFT) |
|
||||
(pll_cfg->outdiv << AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT);
|
||||
|
||||
pll_cfg = &ar934x_clock_config[i].ddr_pll;
|
||||
pll_nint = pll_cfg->nint[xtal_40];
|
||||
pll_refdiv = pll_cfg->refdiv;
|
||||
ddr_pll =
|
||||
(pll_nint << AR934X_PLL_DDR_CONFIG_NINT_SHIFT) |
|
||||
(pll_refdiv << AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) |
|
||||
(pll_cfg->range << AR934X_PLL_DDR_CONFIG_RANGE_SHIFT) |
|
||||
(pll_cfg->outdiv << AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT);
|
||||
break;
|
||||
}
|
||||
|
||||
/* PLL configuration not found, hang. */
|
||||
if (i == ARRAY_SIZE(ar934x_clock_config))
|
||||
hang();
|
||||
|
||||
/* Set PLL Bypass */
|
||||
setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
|
||||
AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS);
|
||||
setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
|
||||
AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS);
|
||||
setbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
|
||||
AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS);
|
||||
|
||||
/* Configure CPU PLL */
|
||||
writel(cpu_pll | AR934X_PLL_CPU_CONFIG_PLLPWD,
|
||||
pll_regs + AR934X_PLL_CPU_CONFIG_REG);
|
||||
/* Configure DDR PLL */
|
||||
writel(ddr_pll | AR934X_PLL_DDR_CONFIG_PLLPWD,
|
||||
pll_regs + AR934X_PLL_DDR_CONFIG_REG);
|
||||
/* Configure PLL routing */
|
||||
writel(AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS |
|
||||
AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS |
|
||||
AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS |
|
||||
(0 << AR934X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) |
|
||||
(0 << AR934X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) |
|
||||
(1 << AR934X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) |
|
||||
AR934X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL |
|
||||
AR934X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL |
|
||||
AR934X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL,
|
||||
pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
|
||||
|
||||
/* Configure SRIF PLLs, which is completely undocumented :-) */
|
||||
ar934x_srif_pll_cfg(srif_regs + AR934X_SRIF_CPU_DPLL1_REG, cpu_srif);
|
||||
ar934x_srif_pll_cfg(srif_regs + AR934X_SRIF_DDR_DPLL1_REG, ddr_srif);
|
||||
|
||||
/* Unset PLL Bypass */
|
||||
clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
|
||||
AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS);
|
||||
clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
|
||||
AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS);
|
||||
clrbits_be32(pll_regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG,
|
||||
AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS);
|
||||
|
||||
/* Enable PLL dithering */
|
||||
writel((1 << AR934X_PLL_DDR_DIT_FRAC_STEP_SHIFT) |
|
||||
(0xf << AR934X_PLL_DDR_DIT_UPD_CNT_SHIFT),
|
||||
pll_regs + AR934X_PLL_DDR_DIT_FRAC_REG);
|
||||
writel(48 << AR934X_PLL_CPU_DIT_UPD_CNT_SHIFT,
|
||||
pll_regs + AR934X_PLL_CPU_DIT_FRAC_REG);
|
||||
}
|
||||
|
||||
static u32 ar934x_get_xtal(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = get_bootstrap();
|
||||
if (val & AR934X_BOOTSTRAP_REF_CLK_40)
|
||||
return 40000000;
|
||||
else
|
||||
return 25000000;
|
||||
}
|
||||
|
||||
int get_serial_clock(void)
|
||||
{
|
||||
return ar934x_get_xtal();
|
||||
}
|
||||
|
||||
static u32 ar934x_cpupll_to_hz(const u32 regval)
|
||||
{
|
||||
const u32 outdiv = (regval >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
|
||||
AR934X_PLL_CPU_CONFIG_OUTDIV_MASK;
|
||||
const u32 refdiv = (regval >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
|
||||
AR934X_PLL_CPU_CONFIG_REFDIV_MASK;
|
||||
const u32 nint = (regval >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) &
|
||||
AR934X_PLL_CPU_CONFIG_NINT_MASK;
|
||||
const u32 nfrac = (regval >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
|
||||
AR934X_PLL_CPU_CONFIG_NFRAC_MASK;
|
||||
const u32 xtal = ar934x_get_xtal();
|
||||
|
||||
return (xtal * (nint + (nfrac >> 9))) / (refdiv * (1 << outdiv));
|
||||
}
|
||||
|
||||
static u32 ar934x_ddrpll_to_hz(const u32 regval)
|
||||
{
|
||||
const u32 outdiv = (regval >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
|
||||
AR934X_PLL_DDR_CONFIG_OUTDIV_MASK;
|
||||
const u32 refdiv = (regval >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
|
||||
AR934X_PLL_DDR_CONFIG_REFDIV_MASK;
|
||||
const u32 nint = (regval >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) &
|
||||
AR934X_PLL_DDR_CONFIG_NINT_MASK;
|
||||
const u32 nfrac = (regval >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
|
||||
AR934X_PLL_DDR_CONFIG_NFRAC_MASK;
|
||||
const u32 xtal = ar934x_get_xtal();
|
||||
|
||||
return (xtal * (nint + (nfrac >> 9))) / (refdiv * (1 << outdiv));
|
||||
}
|
||||
|
||||
static void ar934x_update_clock(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 ctrl, cpu, cpupll, ddr, ddrpll;
|
||||
u32 cpudiv, ddrdiv, busdiv;
|
||||
u32 cpuclk, ddrclk, busclk;
|
||||
|
||||
regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
cpu = readl(regs + AR934X_PLL_CPU_CONFIG_REG);
|
||||
ddr = readl(regs + AR934X_PLL_DDR_CONFIG_REG);
|
||||
ctrl = readl(regs + AR934X_PLL_CPU_DDR_CLK_CTRL_REG);
|
||||
|
||||
cpupll = ar934x_cpupll_to_hz(cpu);
|
||||
ddrpll = ar934x_ddrpll_to_hz(ddr);
|
||||
|
||||
if (ctrl & AR934X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
|
||||
cpuclk = ar934x_get_xtal();
|
||||
else if (ctrl & AR934X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
|
||||
cpuclk = cpupll;
|
||||
else
|
||||
cpuclk = ddrpll;
|
||||
|
||||
if (ctrl & AR934X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
|
||||
ddrclk = ar934x_get_xtal();
|
||||
else if (ctrl & AR934X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
|
||||
ddrclk = ddrpll;
|
||||
else
|
||||
ddrclk = cpupll;
|
||||
|
||||
if (ctrl & AR934X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
|
||||
busclk = ar934x_get_xtal();
|
||||
else if (ctrl & AR934X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
|
||||
busclk = ddrpll;
|
||||
else
|
||||
busclk = cpupll;
|
||||
|
||||
cpudiv = (ctrl >> AR934X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
|
||||
AR934X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
|
||||
ddrdiv = (ctrl >> AR934X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
|
||||
AR934X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
|
||||
busdiv = (ctrl >> AR934X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
|
||||
AR934X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
|
||||
|
||||
gd->cpu_clk = cpuclk / (cpudiv + 1);
|
||||
gd->mem_clk = ddrclk / (ddrdiv + 1);
|
||||
gd->bus_clk = busclk / (busdiv + 1);
|
||||
}
|
||||
|
||||
ulong get_bus_freq(ulong dummy)
|
||||
{
|
||||
ar934x_update_clock();
|
||||
return gd->bus_clk;
|
||||
}
|
||||
|
||||
ulong get_ddr_freq(ulong dummy)
|
||||
{
|
||||
ar934x_update_clock();
|
||||
return gd->mem_clk;
|
||||
}
|
||||
|
||||
int do_ar934x_showclk(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
ar934x_update_clock();
|
||||
printf("CPU: %8ld MHz\n", gd->cpu_clk / 1000000);
|
||||
printf("Memory: %8ld MHz\n", gd->mem_clk / 1000000);
|
||||
printf("AHB: %8ld MHz\n", gd->bus_clk / 1000000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
clocks, CONFIG_SYS_MAXARGS, 1, do_ar934x_showclk,
|
||||
"display clocks",
|
||||
""
|
||||
);
|
10
arch/mips/mach-ath79/ar934x/cpu.c
Normal file
10
arch/mips/mach-ath79/ar934x/cpu.c
Normal file
@ -0,0 +1,10 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
/* The lowlevel_init() is not needed on AR934x */
|
||||
void lowlevel_init(void) {}
|
163
arch/mips/mach-ath79/ar934x/ddr.c
Normal file
163
arch/mips/mach-ath79/ar934x/ddr.c
Normal file
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* Based on RAM init sequence by Piotr Dymacz <pepe2k@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/reset.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum {
|
||||
AR934X_SDRAM = 0,
|
||||
AR934X_DDR1,
|
||||
AR934X_DDR2,
|
||||
};
|
||||
|
||||
struct ar934x_mem_config {
|
||||
u32 config1;
|
||||
u32 config2;
|
||||
u32 mode;
|
||||
u32 extmode;
|
||||
u32 tap;
|
||||
};
|
||||
|
||||
static const struct ar934x_mem_config ar934x_mem_config[] = {
|
||||
[AR934X_SDRAM] = { 0x7fbe8cd0, 0x959f66a8, 0x33, 0, 0x1f1f },
|
||||
[AR934X_DDR1] = { 0x7fd48cd0, 0x99d0e6a8, 0x33, 0, 0x14 },
|
||||
[AR934X_DDR2] = { 0xc7d48cd0, 0x9dd0e6a8, 0x33, 0, 0x10012 },
|
||||
};
|
||||
|
||||
void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz)
|
||||
{
|
||||
void __iomem *ddr_regs;
|
||||
const struct ar934x_mem_config *memcfg;
|
||||
int memtype;
|
||||
u32 reg, cycle, ctl;
|
||||
|
||||
ddr_regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
reg = get_bootstrap();
|
||||
if (reg & AR934X_BOOTSTRAP_SDRAM_DISABLED) { /* DDR */
|
||||
if (reg & AR934X_BOOTSTRAP_DDR1) { /* DDR 1 */
|
||||
memtype = AR934X_DDR1;
|
||||
cycle = 0xffff;
|
||||
} else { /* DDR 2 */
|
||||
memtype = AR934X_DDR2;
|
||||
if (gd->arch.rev) {
|
||||
ctl = BIT(6); /* Undocumented bit :-( */
|
||||
if (reg & BIT(3))
|
||||
cycle = 0xff;
|
||||
else
|
||||
cycle = 0xffff;
|
||||
} else {
|
||||
/* Force DDR2/x16 configuratio on old chips. */
|
||||
ctl = 0;
|
||||
cycle = 0xffff; /* DDR2 16bit */
|
||||
}
|
||||
|
||||
writel(0xe59, ddr_regs + AR934X_DDR_REG_DDR2_CONFIG);
|
||||
udelay(100);
|
||||
|
||||
writel(0x10, ddr_regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
|
||||
writel(0x20, ddr_regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
|
||||
writel(ctl, ddr_regs + AR934X_DDR_REG_CTL_CONF);
|
||||
udelay(10);
|
||||
}
|
||||
} else { /* SDRAM */
|
||||
memtype = AR934X_SDRAM;
|
||||
cycle = 0xffffffff;
|
||||
|
||||
writel(0x13b, ddr_regs + AR934X_DDR_REG_CTL_CONF);
|
||||
udelay(100);
|
||||
|
||||
/* Undocumented register */
|
||||
writel(0x13b, ddr_regs + 0x118);
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
memcfg = &ar934x_mem_config[memtype];
|
||||
|
||||
writel(memcfg->config1, ddr_regs + AR71XX_DDR_REG_CONFIG);
|
||||
udelay(100);
|
||||
|
||||
writel(memcfg->config2, ddr_regs + AR71XX_DDR_REG_CONFIG2);
|
||||
udelay(100);
|
||||
|
||||
writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
|
||||
writel(memcfg->mode | 0x100, ddr_regs + AR71XX_DDR_REG_MODE);
|
||||
mdelay(1);
|
||||
|
||||
writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
|
||||
if (memtype == AR934X_DDR2) {
|
||||
writel(memcfg->mode | 0x100, ddr_regs + AR71XX_DDR_REG_EMR);
|
||||
udelay(100);
|
||||
|
||||
writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
if (memtype != AR934X_SDRAM)
|
||||
writel(0x402, ddr_regs + AR71XX_DDR_REG_EMR);
|
||||
|
||||
udelay(100);
|
||||
|
||||
writel(0x2, ddr_regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
|
||||
writel(0x8, ddr_regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
|
||||
writel(memcfg->mode, ddr_regs + AR71XX_DDR_REG_MODE);
|
||||
udelay(100);
|
||||
|
||||
writel(0x1, ddr_regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
|
||||
writel(0x412c /* FIXME */, ddr_regs + AR71XX_DDR_REG_REFRESH);
|
||||
udelay(100);
|
||||
|
||||
writel(memcfg->tap, ddr_regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
writel(memcfg->tap, ddr_regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
|
||||
if (memtype != AR934X_SDRAM) {
|
||||
if ((gd->arch.rev && (reg & BIT(3))) || !gd->arch.rev) {
|
||||
writel(memcfg->tap,
|
||||
ddr_regs + AR934X_DDR_REG_TAP_CTRL2);
|
||||
writel(memcfg->tap,
|
||||
ddr_regs + AR934X_DDR_REG_TAP_CTRL3);
|
||||
}
|
||||
}
|
||||
|
||||
writel(cycle, ddr_regs + AR71XX_DDR_REG_RD_CYCLE);
|
||||
udelay(100);
|
||||
|
||||
writel(0x74444444, ddr_regs + AR934X_DDR_REG_BURST);
|
||||
udelay(100);
|
||||
|
||||
writel(0x222, ddr_regs + AR934X_DDR_REG_BURST2);
|
||||
udelay(100);
|
||||
|
||||
writel(0xfffff, ddr_regs + AR934X_DDR_REG_TIMEOUT_MAX);
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
void ddr_tap_tuning(void)
|
||||
{
|
||||
}
|
142
arch/mips/mach-ath79/cpu.c
Normal file
142
arch/mips/mach-ath79/cpu.c
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ath79.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
|
||||
struct ath79_soc_desc {
|
||||
const enum ath79_soc_type soc;
|
||||
const char *chip;
|
||||
const int major;
|
||||
const int minor;
|
||||
};
|
||||
|
||||
static const struct ath79_soc_desc desc[] = {
|
||||
{ATH79_SOC_AR7130, "7130",
|
||||
REV_ID_MAJOR_AR71XX, AR71XX_REV_ID_MINOR_AR7130},
|
||||
{ATH79_SOC_AR7141, "7141",
|
||||
REV_ID_MAJOR_AR71XX, AR71XX_REV_ID_MINOR_AR7141},
|
||||
{ATH79_SOC_AR7161, "7161",
|
||||
REV_ID_MAJOR_AR71XX, AR71XX_REV_ID_MINOR_AR7161},
|
||||
{ATH79_SOC_AR7240, "7240", REV_ID_MAJOR_AR7240, 0},
|
||||
{ATH79_SOC_AR7241, "7241", REV_ID_MAJOR_AR7241, 0},
|
||||
{ATH79_SOC_AR7242, "7242", REV_ID_MAJOR_AR7242, 0},
|
||||
{ATH79_SOC_AR9130, "9130",
|
||||
REV_ID_MAJOR_AR913X, AR913X_REV_ID_MINOR_AR9130},
|
||||
{ATH79_SOC_AR9132, "9132",
|
||||
REV_ID_MAJOR_AR913X, AR913X_REV_ID_MINOR_AR9132},
|
||||
{ATH79_SOC_AR9330, "9330", REV_ID_MAJOR_AR9330, 0},
|
||||
{ATH79_SOC_AR9331, "9331", REV_ID_MAJOR_AR9331, 0},
|
||||
{ATH79_SOC_AR9341, "9341", REV_ID_MAJOR_AR9341, 0},
|
||||
{ATH79_SOC_AR9342, "9342", REV_ID_MAJOR_AR9342, 0},
|
||||
{ATH79_SOC_AR9344, "9344", REV_ID_MAJOR_AR9344, 0},
|
||||
{ATH79_SOC_QCA9533, "9533", REV_ID_MAJOR_QCA9533, 0},
|
||||
{ATH79_SOC_QCA9533, "9533",
|
||||
REV_ID_MAJOR_QCA9533_V2, 0},
|
||||
{ATH79_SOC_QCA9556, "9556", REV_ID_MAJOR_QCA9556, 0},
|
||||
{ATH79_SOC_QCA9558, "9558", REV_ID_MAJOR_QCA9558, 0},
|
||||
{ATH79_SOC_TP9343, "9343", REV_ID_MAJOR_TP9343, 0},
|
||||
{ATH79_SOC_QCA9561, "9561", REV_ID_MAJOR_QCA9561, 0},
|
||||
};
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
void __iomem *base;
|
||||
enum ath79_soc_type soc = ATH79_SOC_UNKNOWN;
|
||||
u32 id, major, minor = 0;
|
||||
u32 rev = 0, ver = 1;
|
||||
int i;
|
||||
|
||||
base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
id = readl(base + AR71XX_RESET_REG_REV_ID);
|
||||
major = id & REV_ID_MAJOR_MASK;
|
||||
switch (major) {
|
||||
case REV_ID_MAJOR_AR71XX:
|
||||
case REV_ID_MAJOR_AR913X:
|
||||
minor = id & AR71XX_REV_ID_MINOR_MASK;
|
||||
rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
|
||||
rev &= AR71XX_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
|
||||
case REV_ID_MAJOR_QCA9533_V2:
|
||||
ver = 2;
|
||||
/* drop through */
|
||||
|
||||
case REV_ID_MAJOR_AR9341:
|
||||
case REV_ID_MAJOR_AR9342:
|
||||
case REV_ID_MAJOR_AR9344:
|
||||
case REV_ID_MAJOR_QCA9533:
|
||||
case REV_ID_MAJOR_QCA9556:
|
||||
case REV_ID_MAJOR_QCA9558:
|
||||
case REV_ID_MAJOR_TP9343:
|
||||
case REV_ID_MAJOR_QCA9561:
|
||||
rev = id & AR71XX_REV_ID_REVISION2_MASK;
|
||||
break;
|
||||
default:
|
||||
rev = id & AR71XX_REV_ID_REVISION_MASK;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(desc); i++) {
|
||||
if ((desc[i].major == major) &&
|
||||
(desc[i].minor == minor)) {
|
||||
soc = desc[i].soc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gd->arch.id = id;
|
||||
gd->arch.soc = soc;
|
||||
gd->arch.rev = rev;
|
||||
gd->arch.ver = ver;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
enum ath79_soc_type soc = ATH79_SOC_UNKNOWN;
|
||||
const char *chip = "????";
|
||||
u32 id, rev, ver;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(desc); i++) {
|
||||
if (desc[i].soc == gd->arch.soc) {
|
||||
chip = desc[i].chip;
|
||||
soc = desc[i].soc;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
id = gd->arch.id;
|
||||
rev = gd->arch.rev;
|
||||
ver = gd->arch.ver;
|
||||
|
||||
switch (soc) {
|
||||
case ATH79_SOC_QCA9533:
|
||||
case ATH79_SOC_QCA9556:
|
||||
case ATH79_SOC_QCA9558:
|
||||
case ATH79_SOC_QCA9561:
|
||||
printf("Qualcomm Atheros QCA%s ver %u rev %u\n", chip,
|
||||
ver, rev);
|
||||
break;
|
||||
case ATH79_SOC_TP9343:
|
||||
printf("Qualcomm Atheros TP%s rev %u\n", chip, rev);
|
||||
break;
|
||||
case ATH79_SOC_UNKNOWN:
|
||||
printf("ATH79: unknown SoC, id:0x%08x", id);
|
||||
break;
|
||||
default:
|
||||
printf("Atheros AR%s rev %u\n", chip, rev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
16
arch/mips/mach-ath79/dram.c
Normal file
16
arch/mips/mach-ath79/dram.c
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <mach/ddr.h>
|
||||
|
||||
phys_size_t initdram(int board_type)
|
||||
{
|
||||
ddr_tap_tuning();
|
||||
return get_ram_size((void *)KSEG1, SZ_256M);
|
||||
}
|
1263
arch/mips/mach-ath79/include/mach/ar71xx_regs.h
Normal file
1263
arch/mips/mach-ath79/include/mach/ar71xx_regs.h
Normal file
File diff suppressed because it is too large
Load Diff
149
arch/mips/mach-ath79/include/mach/ath79.h
Normal file
149
arch/mips/mach-ath79/include/mach/ath79.h
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Atheros AR71XX/AR724X/AR913X common definitions
|
||||
*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
* Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
|
||||
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_ATH79_H
|
||||
#define __ASM_MACH_ATH79_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum ath79_soc_type {
|
||||
ATH79_SOC_UNKNOWN,
|
||||
ATH79_SOC_AR7130,
|
||||
ATH79_SOC_AR7141,
|
||||
ATH79_SOC_AR7161,
|
||||
ATH79_SOC_AR7240,
|
||||
ATH79_SOC_AR7241,
|
||||
ATH79_SOC_AR7242,
|
||||
ATH79_SOC_AR9130,
|
||||
ATH79_SOC_AR9132,
|
||||
ATH79_SOC_AR9330,
|
||||
ATH79_SOC_AR9331,
|
||||
ATH79_SOC_AR9341,
|
||||
ATH79_SOC_AR9342,
|
||||
ATH79_SOC_AR9344,
|
||||
ATH79_SOC_QCA9533,
|
||||
ATH79_SOC_QCA9556,
|
||||
ATH79_SOC_QCA9558,
|
||||
ATH79_SOC_TP9343,
|
||||
ATH79_SOC_QCA9561,
|
||||
};
|
||||
|
||||
static inline int soc_is_ar71xx(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR7130 ||
|
||||
gd->arch.soc == ATH79_SOC_AR7141 ||
|
||||
gd->arch.soc == ATH79_SOC_AR7161;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar724x(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR7240 ||
|
||||
gd->arch.soc == ATH79_SOC_AR7241 ||
|
||||
gd->arch.soc == ATH79_SOC_AR7242;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar7240(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR7240;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar7241(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR7241;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar7242(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR7242;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar913x(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR9130 ||
|
||||
gd->arch.soc == ATH79_SOC_AR9132;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar933x(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR9330 ||
|
||||
gd->arch.soc == ATH79_SOC_AR9331;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar9341(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR9341;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar9342(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR9342;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar9344(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_AR9344;
|
||||
}
|
||||
|
||||
static inline int soc_is_ar934x(void)
|
||||
{
|
||||
return soc_is_ar9341() ||
|
||||
soc_is_ar9342() ||
|
||||
soc_is_ar9344();
|
||||
}
|
||||
|
||||
static inline int soc_is_qca9533(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_QCA9533;
|
||||
}
|
||||
|
||||
static inline int soc_is_qca953x(void)
|
||||
{
|
||||
return soc_is_qca9533();
|
||||
}
|
||||
|
||||
static inline int soc_is_qca9556(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_QCA9556;
|
||||
}
|
||||
|
||||
static inline int soc_is_qca9558(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_QCA9558;
|
||||
}
|
||||
|
||||
static inline int soc_is_qca955x(void)
|
||||
{
|
||||
return soc_is_qca9556() || soc_is_qca9558();
|
||||
}
|
||||
|
||||
static inline int soc_is_tp9343(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_TP9343;
|
||||
}
|
||||
|
||||
static inline int soc_is_qca9561(void)
|
||||
{
|
||||
return gd->arch.soc == ATH79_SOC_QCA9561;
|
||||
}
|
||||
|
||||
static inline int soc_is_qca956x(void)
|
||||
{
|
||||
return soc_is_tp9343() || soc_is_qca9561();
|
||||
}
|
||||
|
||||
int ath79_eth_reset(void);
|
||||
int ath79_usb_reset(void);
|
||||
|
||||
void ar934x_pll_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz);
|
||||
void ar934x_ddr_init(const u16 cpu_mhz, const u16 ddr_mhz, const u16 ahb_mhz);
|
||||
|
||||
#endif /* __ASM_MACH_ATH79_H */
|
13
arch/mips/mach-ath79/include/mach/ddr.h
Normal file
13
arch/mips/mach-ath79/include/mach/ddr.h
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_DDR_H
|
||||
#define __ASM_MACH_DDR_H
|
||||
|
||||
void ddr_init(void);
|
||||
void ddr_tap_tuning(void);
|
||||
|
||||
#endif /* __ASM_MACH_DDR_H */
|
14
arch/mips/mach-ath79/include/mach/reset.h
Normal file
14
arch/mips/mach-ath79/include/mach/reset.h
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __ASM_MACH_RESET_H
|
||||
#define __ASM_MACH_RESET_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
u32 get_bootstrap(void);
|
||||
|
||||
#endif /* __ASM_MACH_RESET_H */
|
7
arch/mips/mach-ath79/qca953x/Makefile
Normal file
7
arch/mips/mach-ath79/qca953x/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += clk.o
|
||||
obj-y += ddr.o
|
||||
obj-y += lowlevel_init.o
|
111
arch/mips/mach-ath79/qca953x/clk.c
Normal file
111
arch/mips/mach-ath79/qca953x/clk.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/reset.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static u32 qca953x_get_xtal(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = get_bootstrap();
|
||||
if (val & QCA953X_BOOTSTRAP_REF_CLK_40)
|
||||
return 40000000;
|
||||
else
|
||||
return 25000000;
|
||||
}
|
||||
|
||||
int get_serial_clock(void)
|
||||
{
|
||||
return qca953x_get_xtal();
|
||||
}
|
||||
|
||||
int get_clocks(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 val, ctrl, xtal, pll, div;
|
||||
|
||||
regs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
xtal = qca953x_get_xtal();
|
||||
ctrl = readl(regs + QCA953X_PLL_CLK_CTRL_REG);
|
||||
val = readl(regs + QCA953X_PLL_CPU_CONFIG_REG);
|
||||
|
||||
/* VCOOUT = XTAL * DIV_INT */
|
||||
div = (val >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT)
|
||||
& QCA953X_PLL_CPU_CONFIG_REFDIV_MASK;
|
||||
pll = xtal / div;
|
||||
|
||||
/* PLLOUT = VCOOUT * (1/2^OUTDIV) */
|
||||
div = (val >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT)
|
||||
& QCA953X_PLL_CPU_CONFIG_NINT_MASK;
|
||||
pll *= div;
|
||||
div = (val >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT)
|
||||
& QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
|
||||
if (!div)
|
||||
div = 1;
|
||||
pll >>= div;
|
||||
|
||||
/* CPU_CLK = PLLOUT / CPU_POST_DIV */
|
||||
div = ((ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT)
|
||||
& QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK) + 1;
|
||||
gd->cpu_clk = pll / div;
|
||||
|
||||
|
||||
val = readl(regs + QCA953X_PLL_DDR_CONFIG_REG);
|
||||
/* VCOOUT = XTAL * DIV_INT */
|
||||
div = (val >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT)
|
||||
& QCA953X_PLL_DDR_CONFIG_REFDIV_MASK;
|
||||
pll = xtal / div;
|
||||
|
||||
/* PLLOUT = VCOOUT * (1/2^OUTDIV) */
|
||||
div = (val >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT)
|
||||
& QCA953X_PLL_DDR_CONFIG_NINT_MASK;
|
||||
pll *= div;
|
||||
div = (val >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT)
|
||||
& QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
|
||||
if (!div)
|
||||
div = 1;
|
||||
pll >>= div;
|
||||
|
||||
/* DDR_CLK = PLLOUT / DDR_POST_DIV */
|
||||
div = ((ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT)
|
||||
& QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK) + 1;
|
||||
gd->mem_clk = pll / div;
|
||||
|
||||
div = ((ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT)
|
||||
& QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK) + 1;
|
||||
if (ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL) {
|
||||
/* AHB_CLK = DDR_CLK / AHB_POST_DIV */
|
||||
gd->bus_clk = gd->mem_clk / (div + 1);
|
||||
} else {
|
||||
/* AHB_CLK = CPU_CLK / AHB_POST_DIV */
|
||||
gd->bus_clk = gd->cpu_clk / (div + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ulong get_bus_freq(ulong dummy)
|
||||
{
|
||||
if (!gd->bus_clk)
|
||||
get_clocks();
|
||||
return gd->bus_clk;
|
||||
}
|
||||
|
||||
ulong get_ddr_freq(ulong dummy)
|
||||
{
|
||||
if (!gd->mem_clk)
|
||||
get_clocks();
|
||||
return gd->mem_clk;
|
||||
}
|
472
arch/mips/mach-ath79/qca953x/ddr.c
Normal file
472
arch/mips/mach-ath79/qca953x/ddr.c
Normal file
@ -0,0 +1,472 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
* Based on Atheros LSDK/QSDK
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/reset.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define DDR_CTRL_UPD_EMR3S BIT(5)
|
||||
#define DDR_CTRL_UPD_EMR2S BIT(4)
|
||||
#define DDR_CTRL_PRECHARGE BIT(3)
|
||||
#define DDR_CTRL_AUTO_REFRESH BIT(2)
|
||||
#define DDR_CTRL_UPD_EMRS BIT(1)
|
||||
#define DDR_CTRL_UPD_MRS BIT(0)
|
||||
|
||||
#define DDR_REFRESH_EN BIT(14)
|
||||
#define DDR_REFRESH_M 0x3ff
|
||||
#define DDR_REFRESH(x) ((x) & DDR_REFRESH_M)
|
||||
#define DDR_REFRESH_VAL (DDR_REFRESH_EN | DDR_REFRESH(312))
|
||||
|
||||
#define DDR_TRAS_S 0
|
||||
#define DDR_TRAS_M 0x1f
|
||||
#define DDR_TRAS(x) (((x) & DDR_TRAS_M) << DDR_TRAS_S)
|
||||
#define DDR_TRCD_M 0xf
|
||||
#define DDR_TRCD_S 5
|
||||
#define DDR_TRCD(x) (((x) & DDR_TRCD_M) << DDR_TRCD_S)
|
||||
#define DDR_TRP_M 0xf
|
||||
#define DDR_TRP_S 9
|
||||
#define DDR_TRP(x) (((x) & DDR_TRP_M) << DDR_TRP_S)
|
||||
#define DDR_TRRD_M 0xf
|
||||
#define DDR_TRRD_S 13
|
||||
#define DDR_TRRD(x) (((x) & DDR_TRRD_M) << DDR_TRRD_S)
|
||||
#define DDR_TRFC_M 0x7f
|
||||
#define DDR_TRFC_S 17
|
||||
#define DDR_TRFC(x) (((x) & DDR_TRFC_M) << DDR_TRFC_S)
|
||||
#define DDR_TMRD_M 0xf
|
||||
#define DDR_TMRD_S 23
|
||||
#define DDR_TMRD(x) (((x) & DDR_TMRD_M) << DDR_TMRD_S)
|
||||
#define DDR_CAS_L_M 0x17
|
||||
#define DDR_CAS_L_S 27
|
||||
#define DDR_CAS_L(x) (((x) & DDR_CAS_L_M) << DDR_CAS_L_S)
|
||||
#define DDR_OPEN BIT(30)
|
||||
#define DDR1_CONF_REG_VAL (DDR_TRAS(16) | DDR_TRCD(6) | \
|
||||
DDR_TRP(6) | DDR_TRRD(4) | \
|
||||
DDR_TRFC(7) | DDR_TMRD(5) | \
|
||||
DDR_CAS_L(7) | DDR_OPEN)
|
||||
#define DDR2_CONF_REG_VAL (DDR_TRAS(27) | DDR_TRCD(9) | \
|
||||
DDR_TRP(9) | DDR_TRRD(7) | \
|
||||
DDR_TRFC(21) | DDR_TMRD(15) | \
|
||||
DDR_CAS_L(17) | DDR_OPEN)
|
||||
|
||||
#define DDR_BURST_LEN_S 0
|
||||
#define DDR_BURST_LEN_M 0xf
|
||||
#define DDR_BURST_LEN(x) ((x) << DDR_BURST_LEN_S)
|
||||
#define DDR_BURST_TYPE BIT(4)
|
||||
#define DDR_CNTL_OE_EN BIT(5)
|
||||
#define DDR_PHASE_SEL BIT(6)
|
||||
#define DDR_CKE BIT(7)
|
||||
#define DDR_TWR_S 8
|
||||
#define DDR_TWR_M 0xf
|
||||
#define DDR_TWR(x) (((x) & DDR_TWR_M) << DDR_TWR_S)
|
||||
#define DDR_TRTW_S 12
|
||||
#define DDR_TRTW_M 0x1f
|
||||
#define DDR_TRTW(x) (((x) & DDR_TRTW_M) << DDR_TRTW_S)
|
||||
#define DDR_TRTP_S 17
|
||||
#define DDR_TRTP_M 0xf
|
||||
#define DDR_TRTP(x) (((x) & DDR_TRTP_M) << DDR_TRTP_S)
|
||||
#define DDR_TWTR_S 21
|
||||
#define DDR_TWTR_M 0x1f
|
||||
#define DDR_TWTR(x) (((x) & DDR_TWTR_M) << DDR_TWTR_S)
|
||||
#define DDR_G_OPEN_L_S 26
|
||||
#define DDR_G_OPEN_L_M 0xf
|
||||
#define DDR_G_OPEN_L(x) ((x) << DDR_G_OPEN_L_S)
|
||||
#define DDR_HALF_WIDTH_LOW BIT(31)
|
||||
#define DDR1_CONF2_REG_VAL (DDR_BURST_LEN(8) | DDR_CNTL_OE_EN | \
|
||||
DDR_CKE | DDR_TWR(13) | DDR_TRTW(14) | \
|
||||
DDR_TRTP(8) | DDR_TWTR(14) | \
|
||||
DDR_G_OPEN_L(6) | DDR_HALF_WIDTH_LOW)
|
||||
#define DDR2_CONF2_REG_VAL (DDR_BURST_LEN(8) | DDR_CNTL_OE_EN | \
|
||||
DDR_CKE | DDR_TWR(1) | DDR_TRTW(14) | \
|
||||
DDR_TRTP(9) | DDR_TWTR(21) | \
|
||||
DDR_G_OPEN_L(8) | DDR_HALF_WIDTH_LOW)
|
||||
|
||||
#define DDR_TWR_MSB BIT(3)
|
||||
#define DDR_TRAS_MSB BIT(2)
|
||||
#define DDR_TRFC_MSB_M 0x3
|
||||
#define DDR_TRFC_MSB(x) (x)
|
||||
#define DDR1_CONF3_REG_VAL 0
|
||||
#define DDR2_CONF3_REG_VAL (DDR_TWR_MSB | DDR_TRFC_MSB(2))
|
||||
|
||||
#define DDR_CTL_SRAM_TSEL BIT(30)
|
||||
#define DDR_CTL_SRAM_GE0_SYNC BIT(20)
|
||||
#define DDR_CTL_SRAM_GE1_SYNC BIT(19)
|
||||
#define DDR_CTL_SRAM_USB_SYNC BIT(18)
|
||||
#define DDR_CTL_SRAM_PCIE_SYNC BIT(17)
|
||||
#define DDR_CTL_SRAM_WMAC_SYNC BIT(16)
|
||||
#define DDR_CTL_SRAM_MISC1_SYNC BIT(15)
|
||||
#define DDR_CTL_SRAM_MISC2_SYNC BIT(14)
|
||||
#define DDR_CTL_PAD_DDR2_SEL BIT(6)
|
||||
#define DDR_CTL_HALF_WIDTH BIT(1)
|
||||
#define DDR_CTL_CONFIG_VAL (DDR_CTL_SRAM_TSEL | \
|
||||
DDR_CTL_SRAM_GE0_SYNC | \
|
||||
DDR_CTL_SRAM_GE1_SYNC | \
|
||||
DDR_CTL_SRAM_USB_SYNC | \
|
||||
DDR_CTL_SRAM_PCIE_SYNC | \
|
||||
DDR_CTL_SRAM_WMAC_SYNC | \
|
||||
DDR_CTL_HALF_WIDTH)
|
||||
|
||||
#define DDR_BURST_GE0_MAX_BL_S 0
|
||||
#define DDR_BURST_GE0_MAX_BL_M 0xf
|
||||
#define DDR_BURST_GE0_MAX_BL(x) \
|
||||
(((x) & DDR_BURST_GE0_MAX_BL_M) << DDR_BURST_GE0_MAX_BL_S)
|
||||
#define DDR_BURST_GE1_MAX_BL_S 4
|
||||
#define DDR_BURST_GE1_MAX_BL_M 0xf
|
||||
#define DDR_BURST_GE1_MAX_BL(x) \
|
||||
(((x) & DDR_BURST_GE1_MAX_BL_M) << DDR_BURST_GE1_MAX_BL_S)
|
||||
#define DDR_BURST_PCIE_MAX_BL_S 8
|
||||
#define DDR_BURST_PCIE_MAX_BL_M 0xf
|
||||
#define DDR_BURST_PCIE_MAX_BL(x) \
|
||||
(((x) & DDR_BURST_PCIE_MAX_BL_M) << DDR_BURST_PCIE_MAX_BL_S)
|
||||
#define DDR_BURST_USB_MAX_BL_S 12
|
||||
#define DDR_BURST_USB_MAX_BL_M 0xf
|
||||
#define DDR_BURST_USB_MAX_BL(x) \
|
||||
(((x) & DDR_BURST_USB_MAX_BL_M) << DDR_BURST_USB_MAX_BL_S)
|
||||
#define DDR_BURST_CPU_MAX_BL_S 16
|
||||
#define DDR_BURST_CPU_MAX_BL_M 0xf
|
||||
#define DDR_BURST_CPU_MAX_BL(x) \
|
||||
(((x) & DDR_BURST_CPU_MAX_BL_M) << DDR_BURST_CPU_MAX_BL_S)
|
||||
#define DDR_BURST_RD_MAX_BL_S 20
|
||||
#define DDR_BURST_RD_MAX_BL_M 0xf
|
||||
#define DDR_BURST_RD_MAX_BL(x) \
|
||||
(((x) & DDR_BURST_RD_MAX_BL_M) << DDR_BURST_RD_MAX_BL_S)
|
||||
#define DDR_BURST_WR_MAX_BL_S 24
|
||||
#define DDR_BURST_WR_MAX_BL_M 0xf
|
||||
#define DDR_BURST_WR_MAX_BL(x) \
|
||||
(((x) & DDR_BURST_WR_MAX_BL_M) << DDR_BURST_WR_MAX_BL_S)
|
||||
#define DDR_BURST_RWP_MASK_EN_S 28
|
||||
#define DDR_BURST_RWP_MASK_EN_M 0x3
|
||||
#define DDR_BURST_RWP_MASK_EN(x) \
|
||||
(((x) & DDR_BURST_RWP_MASK_EN_M) << DDR_BURST_RWP_MASK_EN_S)
|
||||
#define DDR_BURST_CPU_PRI_BE BIT(30)
|
||||
#define DDR_BURST_CPU_PRI BIT(31)
|
||||
#define DDR_BURST_VAL (DDR_BURST_CPU_PRI_BE | \
|
||||
DDR_BURST_RWP_MASK_EN(3) | \
|
||||
DDR_BURST_WR_MAX_BL(4) | \
|
||||
DDR_BURST_RD_MAX_BL(4) | \
|
||||
DDR_BURST_CPU_MAX_BL(4) | \
|
||||
DDR_BURST_USB_MAX_BL(4) | \
|
||||
DDR_BURST_PCIE_MAX_BL(4) | \
|
||||
DDR_BURST_GE1_MAX_BL(4) | \
|
||||
DDR_BURST_GE0_MAX_BL(4))
|
||||
|
||||
#define DDR_BURST_WMAC_MAX_BL_S 0
|
||||
#define DDR_BURST_WMAC_MAX_BL_M 0xf
|
||||
#define DDR_BURST_WMAC_MAX_BL(x) \
|
||||
(((x) & DDR_BURST_WMAC_MAX_BL_M) << DDR_BURST_WMAC_MAX_BL_S)
|
||||
#define DDR_BURST2_VAL DDR_BURST_WMAC_MAX_BL(4)
|
||||
|
||||
#define DDR2_CONF_TWL_S 10
|
||||
#define DDR2_CONF_TWL_M 0xf
|
||||
#define DDR2_CONF_TWL(x) \
|
||||
(((x) & DDR2_CONF_TWL_M) << DDR2_CONF_TWL_S)
|
||||
#define DDR2_CONF_ODT BIT(9)
|
||||
#define DDR2_CONF_TFAW_S 2
|
||||
#define DDR2_CONF_TFAW_M 0x3f
|
||||
#define DDR2_CONF_TFAW(x) \
|
||||
(((x) & DDR2_CONF_TFAW_M) << DDR2_CONF_TFAW_S)
|
||||
#define DDR2_CONF_EN BIT(0)
|
||||
#define DDR2_CONF_VAL (DDR2_CONF_TWL(5) | \
|
||||
DDR2_CONF_TFAW(31) | \
|
||||
DDR2_CONF_ODT | \
|
||||
DDR2_CONF_EN)
|
||||
|
||||
#define DDR1_EXT_MODE_VAL 0
|
||||
#define DDR2_EXT_MODE_VAL 0x402
|
||||
#define DDR2_EXT_MODE_OCD_VAL 0x782
|
||||
#define DDR1_MODE_DLL_VAL 0x133
|
||||
#define DDR2_MODE_DLL_VAL 0x143
|
||||
#define DDR1_MODE_VAL 0x33
|
||||
#define DDR2_MODE_VAL 0x43
|
||||
#define DDR1_TAP_VAL 0x20
|
||||
#define DDR2_TAP_VAL 0x10
|
||||
|
||||
#define DDR_REG_BIST_MASK_ADDR_0 0x2c
|
||||
#define DDR_REG_BIST_MASK_ADDR_1 0x30
|
||||
#define DDR_REG_BIST_MASK_AHB_GE0_0 0x34
|
||||
#define DDR_REG_BIST_COMP_AHB_GE0_0 0x38
|
||||
#define DDR_REG_BIST_MASK_AHB_GE1_0 0x3c
|
||||
#define DDR_REG_BIST_COMP_AHB_GE1_0 0x40
|
||||
#define DDR_REG_BIST_COMP_ADDR_0 0x64
|
||||
#define DDR_REG_BIST_COMP_ADDR_1 0x68
|
||||
#define DDR_REG_BIST_MASK_AHB_GE0_1 0x6c
|
||||
#define DDR_REG_BIST_COMP_AHB_GE0_1 0x70
|
||||
#define DDR_REG_BIST_MASK_AHB_GE1_1 0x74
|
||||
#define DDR_REG_BIST_COMP_AHB_GE1_1 0x78
|
||||
#define DDR_REG_BIST 0x11c
|
||||
#define DDR_REG_BIST_STATUS 0x120
|
||||
|
||||
#define DDR_BIST_COMP_CNT_S 1
|
||||
#define DDR_BIST_COMP_CNT_M 0xff
|
||||
#define DDR_BIST_COMP_CNT(x) \
|
||||
(((x) & DDR_BIST_COMP_CNT_M) << DDR_BIST_COMP_CNT_S)
|
||||
#define DDR_BIST_COMP_CNT_MASK \
|
||||
(DDR_BIST_COMP_CNT_M << DDR_BIST_COMP_CNT_S)
|
||||
#define DDR_BIST_TEST_START BIT(0)
|
||||
#define DDR_BIST_STATUS_DONE BIT(0)
|
||||
|
||||
/* 4 Row Address Bits, 4 Column Address Bits, 2 BA bits */
|
||||
#define DDR_BIST_MASK_ADDR_VAL 0xfa5de83f
|
||||
|
||||
#define DDR_TAP_MAGIC_VAL 0xaa55aa55
|
||||
#define DDR_TAP_MAX_VAL 0x40
|
||||
|
||||
void ddr_init(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 val;
|
||||
|
||||
regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
val = get_bootstrap();
|
||||
if (val & QCA953X_BOOTSTRAP_DDR1) {
|
||||
writel(DDR_CTL_CONFIG_VAL, regs + QCA953X_DDR_REG_CTL_CONF);
|
||||
udelay(10);
|
||||
|
||||
/* For 16-bit DDR */
|
||||
writel(0xffff, regs + AR71XX_DDR_REG_RD_CYCLE);
|
||||
udelay(100);
|
||||
|
||||
/* Burst size */
|
||||
writel(DDR_BURST_VAL, regs + QCA953X_DDR_REG_BURST);
|
||||
udelay(100);
|
||||
writel(DDR_BURST2_VAL, regs + QCA953X_DDR_REG_BURST2);
|
||||
udelay(100);
|
||||
|
||||
/* AHB maximum timeout */
|
||||
writel(0xfffff, regs + QCA953X_DDR_REG_TIMEOUT_MAX);
|
||||
udelay(100);
|
||||
|
||||
/* DRAM timing */
|
||||
writel(DDR1_CONF_REG_VAL, regs + AR71XX_DDR_REG_CONFIG);
|
||||
udelay(100);
|
||||
writel(DDR1_CONF2_REG_VAL, regs + AR71XX_DDR_REG_CONFIG2);
|
||||
udelay(100);
|
||||
writel(DDR1_CONF3_REG_VAL, regs + QCA953X_DDR_REG_CONFIG3);
|
||||
udelay(100);
|
||||
|
||||
/* Precharge All */
|
||||
writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* ODT disable, Full strength, Enable DLL */
|
||||
writel(DDR1_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
|
||||
udelay(100);
|
||||
|
||||
/* Update Extended Mode Register Set (EMRS) */
|
||||
writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Reset DLL, CAS Latency 3, Burst Length 8 */
|
||||
writel(DDR1_MODE_DLL_VAL, regs + AR71XX_DDR_REG_MODE);
|
||||
udelay(100);
|
||||
|
||||
/* Update Mode Register Set (MRS) */
|
||||
writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Precharge All */
|
||||
writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Auto Refresh */
|
||||
writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Normal DLL, CAS Latency 3, Burst Length 8 */
|
||||
writel(DDR1_MODE_VAL, regs + AR71XX_DDR_REG_MODE);
|
||||
udelay(100);
|
||||
|
||||
/* Update Mode Register Set (MRS) */
|
||||
writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Refresh time control */
|
||||
writel(DDR_REFRESH_VAL, regs + AR71XX_DDR_REG_REFRESH);
|
||||
udelay(100);
|
||||
|
||||
/* DQS 0 Tap Control */
|
||||
writel(DDR1_TAP_VAL, regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
|
||||
/* DQS 1 Tap Control */
|
||||
writel(DDR1_TAP_VAL, regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
} else {
|
||||
writel(DDR_CTRL_UPD_EMR2S, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
writel(DDR_CTRL_UPD_EMR3S, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(10);
|
||||
writel(DDR_CTL_CONFIG_VAL | DDR_CTL_PAD_DDR2_SEL,
|
||||
regs + QCA953X_DDR_REG_CTL_CONF);
|
||||
udelay(10);
|
||||
|
||||
/* For 16-bit DDR */
|
||||
writel(0xffff, regs + AR71XX_DDR_REG_RD_CYCLE);
|
||||
udelay(100);
|
||||
|
||||
/* Burst size */
|
||||
writel(DDR_BURST_VAL, regs + QCA953X_DDR_REG_BURST);
|
||||
udelay(100);
|
||||
writel(DDR_BURST2_VAL, regs + QCA953X_DDR_REG_BURST2);
|
||||
udelay(100);
|
||||
|
||||
/* AHB maximum timeout */
|
||||
writel(0xfffff, regs + QCA953X_DDR_REG_TIMEOUT_MAX);
|
||||
udelay(100);
|
||||
|
||||
/* DRAM timing */
|
||||
writel(DDR2_CONF_REG_VAL, regs + AR71XX_DDR_REG_CONFIG);
|
||||
udelay(100);
|
||||
writel(DDR2_CONF2_REG_VAL, regs + AR71XX_DDR_REG_CONFIG2);
|
||||
udelay(100);
|
||||
writel(DDR2_CONF3_REG_VAL, regs + QCA953X_DDR_REG_CONFIG3);
|
||||
udelay(100);
|
||||
|
||||
/* Enable DDR2 */
|
||||
writel(DDR2_CONF_VAL, regs + QCA953X_DDR_REG_DDR2_CONFIG);
|
||||
udelay(100);
|
||||
|
||||
/* Precharge All */
|
||||
writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Update Extended Mode Register 2 Set (EMR2S) */
|
||||
writel(DDR_CTRL_UPD_EMR2S, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Update Extended Mode Register 3 Set (EMR3S) */
|
||||
writel(DDR_CTRL_UPD_EMR3S, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* 150 ohm, Reduced strength, Enable DLL */
|
||||
writel(DDR2_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
|
||||
udelay(100);
|
||||
|
||||
/* Update Extended Mode Register Set (EMRS) */
|
||||
writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Reset DLL, CAS Latency 4, Burst Length 8 */
|
||||
writel(DDR2_MODE_DLL_VAL, regs + AR71XX_DDR_REG_MODE);
|
||||
udelay(100);
|
||||
|
||||
/* Update Mode Register Set (MRS) */
|
||||
writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Precharge All */
|
||||
writel(DDR_CTRL_PRECHARGE, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Auto Refresh */
|
||||
writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
writel(DDR_CTRL_AUTO_REFRESH, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Normal DLL, CAS Latency 4, Burst Length 8 */
|
||||
writel(DDR2_MODE_VAL, regs + AR71XX_DDR_REG_MODE);
|
||||
udelay(100);
|
||||
|
||||
/* Mode Register Set (MRS) */
|
||||
writel(DDR_CTRL_UPD_MRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Enable OCD, Enable DLL, Reduced Drive Strength */
|
||||
writel(DDR2_EXT_MODE_OCD_VAL, regs + AR71XX_DDR_REG_EMR);
|
||||
udelay(100);
|
||||
|
||||
/* Update Extended Mode Register Set (EMRS) */
|
||||
writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* OCD diable, Enable DLL, Reduced Drive Strength */
|
||||
writel(DDR2_EXT_MODE_VAL, regs + AR71XX_DDR_REG_EMR);
|
||||
udelay(100);
|
||||
|
||||
/* Update Extended Mode Register Set (EMRS) */
|
||||
writel(DDR_CTRL_UPD_EMRS, regs + AR71XX_DDR_REG_CONTROL);
|
||||
udelay(100);
|
||||
|
||||
/* Refresh time control */
|
||||
writel(DDR_REFRESH_VAL, regs + AR71XX_DDR_REG_REFRESH);
|
||||
udelay(100);
|
||||
|
||||
/* DQS 0 Tap Control */
|
||||
writel(DDR2_TAP_VAL, regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
|
||||
/* DQS 1 Tap Control */
|
||||
writel(DDR2_TAP_VAL, regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
}
|
||||
}
|
||||
|
||||
void ddr_tap_tuning(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 val, pass, tap, cnt, tap_val, last, first;
|
||||
|
||||
regs = map_physmem(AR71XX_DDR_CTRL_BASE, AR71XX_DDR_CTRL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
tap_val = readl(regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
first = DDR_TAP_MAGIC_VAL;
|
||||
last = 0;
|
||||
cnt = 0;
|
||||
tap = 0;
|
||||
|
||||
do {
|
||||
writel(tap, regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
writel(tap, regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
|
||||
writel(DDR_BIST_COMP_CNT(8), regs + DDR_REG_BIST_COMP_ADDR_1);
|
||||
writel(DDR_BIST_MASK_ADDR_VAL, regs + DDR_REG_BIST_MASK_ADDR_0);
|
||||
writel(0xffff, regs + DDR_REG_BIST_COMP_AHB_GE0_1);
|
||||
writel(0xffff, regs + DDR_REG_BIST_COMP_AHB_GE1_0);
|
||||
writel(0xffff, regs + DDR_REG_BIST_COMP_AHB_GE1_1);
|
||||
writel(0xffff, regs + DDR_REG_BIST_MASK_AHB_GE0_0);
|
||||
writel(0xffff, regs + DDR_REG_BIST_MASK_AHB_GE0_1);
|
||||
writel(0xffff, regs + DDR_REG_BIST_MASK_AHB_GE1_0);
|
||||
writel(0xffff, regs + DDR_REG_BIST_MASK_AHB_GE1_1);
|
||||
writel(0xffff, regs + DDR_REG_BIST_COMP_AHB_GE0_0);
|
||||
|
||||
/* Start BIST test */
|
||||
writel(DDR_BIST_TEST_START, regs + DDR_REG_BIST);
|
||||
|
||||
do {
|
||||
val = readl(regs + DDR_REG_BIST_STATUS);
|
||||
} while (!(val & DDR_BIST_STATUS_DONE));
|
||||
|
||||
/* Stop BIST test */
|
||||
writel(0, regs + DDR_REG_BIST);
|
||||
|
||||
pass = val & DDR_BIST_COMP_CNT_MASK;
|
||||
pass ^= DDR_BIST_COMP_CNT(8);
|
||||
if (!pass) {
|
||||
if (first != DDR_TAP_MAGIC_VAL) {
|
||||
last = tap;
|
||||
} else {
|
||||
first = tap;
|
||||
last = tap;
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
tap++;
|
||||
} while (tap < DDR_TAP_MAX_VAL);
|
||||
|
||||
if (cnt) {
|
||||
tap_val = (first + last) / 2;
|
||||
tap_val %= DDR_TAP_MAX_VAL;
|
||||
}
|
||||
|
||||
writel(tap_val, regs + AR71XX_DDR_REG_TAP_CTRL0);
|
||||
writel(tap_val, regs + AR71XX_DDR_REG_TAP_CTRL1);
|
||||
}
|
186
arch/mips/mach-ath79/qca953x/lowlevel_init.S
Normal file
186
arch/mips/mach-ath79/qca953x/lowlevel_init.S
Normal file
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
* Based on Atheros LSDK/QSDK
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <asm/asm.h>
|
||||
#include <asm/regdef.h>
|
||||
#include <asm/mipsregs.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
|
||||
#define MK_PLL_CONF(divint, refdiv, range, outdiv) \
|
||||
(((0x3F & divint) << 10) | \
|
||||
((0x1F & refdiv) << 16) | \
|
||||
((0x1 & range) << 21) | \
|
||||
((0x7 & outdiv) << 23) )
|
||||
|
||||
#define MK_CLK_CNTL(cpudiv, ddrdiv, ahbdiv) \
|
||||
(((0x3 & (cpudiv - 1)) << 5) | \
|
||||
((0x3 & (ddrdiv - 1)) << 10) | \
|
||||
((0x3 & (ahbdiv - 1)) << 15) )
|
||||
|
||||
#define SET_FIELD(name, v) (((v) & QCA953X_##name##_MASK) << \
|
||||
QCA953X_##name##_SHIFT)
|
||||
|
||||
#define DPLL2_KI(v) SET_FIELD(SRIF_DPLL2_KI, v)
|
||||
#define DPLL2_KD(v) SET_FIELD(SRIF_DPLL2_KD, v)
|
||||
#define DPLL2_PWD QCA953X_SRIF_DPLL2_PWD
|
||||
#define MK_DPLL2(ki, kd) (DPLL2_KI(ki) | DPLL2_KD(kd) | DPLL2_PWD)
|
||||
|
||||
#define PLL_CPU_NFRAC(v) SET_FIELD(PLL_CPU_CONFIG_NFRAC, v)
|
||||
#define PLL_CPU_NINT(v) SET_FIELD(PLL_CPU_CONFIG_NINT, v)
|
||||
#define PLL_CPU_REFDIV(v) SET_FIELD(PLL_CPU_CONFIG_REFDIV, v)
|
||||
#define PLL_CPU_OUTDIV(v) SET_FIELD(PLL_CPU_CONFIG_OUTDIV, v)
|
||||
#define MK_PLL_CPU_CONF(frac, nint, ref, outdiv) \
|
||||
(PLL_CPU_NFRAC(frac) | \
|
||||
PLL_CPU_NINT(nint) | \
|
||||
PLL_CPU_REFDIV(ref) | \
|
||||
PLL_CPU_OUTDIV(outdiv))
|
||||
|
||||
#define PLL_DDR_NFRAC(v) SET_FIELD(PLL_DDR_CONFIG_NFRAC, v)
|
||||
#define PLL_DDR_NINT(v) SET_FIELD(PLL_DDR_CONFIG_NINT, v)
|
||||
#define PLL_DDR_REFDIV(v) SET_FIELD(PLL_DDR_CONFIG_REFDIV, v)
|
||||
#define PLL_DDR_OUTDIV(v) SET_FIELD(PLL_DDR_CONFIG_OUTDIV, v)
|
||||
#define MK_PLL_DDR_CONF(frac, nint, ref, outdiv) \
|
||||
(PLL_DDR_NFRAC(frac) | \
|
||||
PLL_DDR_REFDIV(ref) | \
|
||||
PLL_DDR_NINT(nint) | \
|
||||
PLL_DDR_OUTDIV(outdiv) | \
|
||||
QCA953X_PLL_CONFIG_PWD)
|
||||
|
||||
#define PLL_CPU_CONF_VAL MK_PLL_CPU_CONF(0, 26, 1, 0)
|
||||
#define PLL_DDR_CONF_VAL MK_PLL_DDR_CONF(0, 15, 1, 0)
|
||||
|
||||
#define PLL_CLK_CTRL_PLL_BYPASS (QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS | \
|
||||
QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS | \
|
||||
QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
|
||||
|
||||
#define PLL_CLK_CTRL_CPU_DIV(v) SET_FIELD(PLL_CLK_CTRL_CPU_POST_DIV, v)
|
||||
#define PLL_CLK_CTRL_DDR_DIV(v) SET_FIELD(PLL_CLK_CTRL_DDR_POST_DIV, v)
|
||||
#define PLL_CLK_CTRL_AHB_DIV(v) SET_FIELD(PLL_CLK_CTRL_AHB_POST_DIV, v)
|
||||
#define MK_PLL_CLK_CTRL(cpu, ddr, ahb) \
|
||||
(PLL_CLK_CTRL_CPU_DIV(cpu) | \
|
||||
PLL_CLK_CTRL_DDR_DIV(ddr) | \
|
||||
PLL_CLK_CTRL_AHB_DIV(ahb))
|
||||
#define PLL_CLK_CTRL_VAL (MK_PLL_CLK_CTRL(0, 0, 2) | \
|
||||
PLL_CLK_CTRL_PLL_BYPASS | \
|
||||
QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL | \
|
||||
QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
|
||||
|
||||
#define PLL_DDR_DIT_FRAC_MAX(v) SET_FIELD(PLL_DDR_DIT_FRAC_MAX, v)
|
||||
#define PLL_DDR_DIT_FRAC_MIN(v) SET_FIELD(PLL_DDR_DIT_FRAC_MIN, v)
|
||||
#define PLL_DDR_DIT_FRAC_STEP(v) SET_FIELD(PLL_DDR_DIT_FRAC_STEP, v)
|
||||
#define PLL_DDR_DIT_UPD_CNT(v) SET_FIELD(PLL_DDR_DIT_UPD_CNT, v)
|
||||
#define PLL_CPU_DIT_FRAC_MAX(v) SET_FIELD(PLL_CPU_DIT_FRAC_MAX, v)
|
||||
#define PLL_CPU_DIT_FRAC_MIN(v) SET_FIELD(PLL_CPU_DIT_FRAC_MIN, v)
|
||||
#define PLL_CPU_DIT_FRAC_STEP(v) SET_FIELD(PLL_CPU_DIT_FRAC_STEP, v)
|
||||
#define PLL_CPU_DIT_UPD_CNT(v) SET_FIELD(PLL_CPU_DIT_UPD_CNT, v)
|
||||
#define MK_PLL_DDR_DIT_FRAC(max, min, step, cnt) \
|
||||
(QCA953X_PLL_DIT_FRAC_EN | \
|
||||
PLL_DDR_DIT_FRAC_MAX(max) | \
|
||||
PLL_DDR_DIT_FRAC_MIN(min) | \
|
||||
PLL_DDR_DIT_FRAC_STEP(step) | \
|
||||
PLL_DDR_DIT_UPD_CNT(cnt))
|
||||
#define MK_PLL_CPU_DIT_FRAC(max, min, step, cnt) \
|
||||
(QCA953X_PLL_DIT_FRAC_EN | \
|
||||
PLL_CPU_DIT_FRAC_MAX(max) | \
|
||||
PLL_CPU_DIT_FRAC_MIN(min) | \
|
||||
PLL_CPU_DIT_FRAC_STEP(step) | \
|
||||
PLL_CPU_DIT_UPD_CNT(cnt))
|
||||
#define PLL_CPU_DIT_FRAC_VAL MK_PLL_CPU_DIT_FRAC(63, 0, 1, 15)
|
||||
#define PLL_DDR_DIT_FRAC_VAL MK_PLL_DDR_DIT_FRAC(763, 635, 1, 15)
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
|
||||
LEAF(lowlevel_init)
|
||||
/* RTC Reset */
|
||||
li t0, CKSEG1ADDR(AR71XX_RESET_BASE)
|
||||
lw t1, QCA953X_RESET_REG_RESET_MODULE(t0)
|
||||
li t2, 0x08000000
|
||||
or t1, t1, t2
|
||||
sw t1, QCA953X_RESET_REG_RESET_MODULE(t0)
|
||||
nop
|
||||
lw t1, QCA953X_RESET_REG_RESET_MODULE(t0)
|
||||
li t2, 0xf7ffffff
|
||||
and t1, t1, t2
|
||||
sw t1, QCA953X_RESET_REG_RESET_MODULE(t0)
|
||||
nop
|
||||
|
||||
/* RTC Force Wake */
|
||||
li t0, CKSEG1ADDR(QCA953X_RTC_BASE)
|
||||
li t1, 0x01
|
||||
sw t1, QCA953X_RTC_REG_SYNC_RESET(t0)
|
||||
nop
|
||||
nop
|
||||
|
||||
/* Wait for RTC in on state */
|
||||
1:
|
||||
lw t1, QCA953X_RTC_REG_SYNC_STATUS(t0)
|
||||
andi t1, t1, 0x02
|
||||
beqz t1, 1b
|
||||
nop
|
||||
|
||||
li t0, CKSEG1ADDR(QCA953X_SRIF_BASE)
|
||||
li t1, MK_DPLL2(2, 16)
|
||||
sw t1, QCA953X_SRIF_BB_DPLL2_REG(t0)
|
||||
sw t1, QCA953X_SRIF_PCIE_DPLL2_REG(t0)
|
||||
sw t1, QCA953X_SRIF_DDR_DPLL2_REG(t0)
|
||||
sw t1, QCA953X_SRIF_CPU_DPLL2_REG(t0)
|
||||
|
||||
li t0, CKSEG1ADDR(AR71XX_PLL_BASE)
|
||||
lw t1, QCA953X_PLL_CLK_CTRL_REG(t0)
|
||||
ori t1, PLL_CLK_CTRL_PLL_BYPASS
|
||||
sw t1, QCA953X_PLL_CLK_CTRL_REG(t0)
|
||||
nop
|
||||
|
||||
li t1, PLL_CPU_CONF_VAL
|
||||
sw t1, QCA953X_PLL_CPU_CONFIG_REG(t0)
|
||||
nop
|
||||
|
||||
li t1, PLL_DDR_CONF_VAL
|
||||
sw t1, QCA953X_PLL_DDR_CONFIG_REG(t0)
|
||||
nop
|
||||
|
||||
li t1, PLL_CLK_CTRL_VAL
|
||||
sw t1, QCA953X_PLL_CLK_CTRL_REG(t0)
|
||||
nop
|
||||
|
||||
lw t1, QCA953X_PLL_CPU_CONFIG_REG(t0)
|
||||
li t2, ~QCA953X_PLL_CONFIG_PWD
|
||||
and t1, t1, t2
|
||||
sw t1, QCA953X_PLL_CPU_CONFIG_REG(t0)
|
||||
nop
|
||||
|
||||
lw t1, QCA953X_PLL_DDR_CONFIG_REG(t0)
|
||||
li t2, ~QCA953X_PLL_CONFIG_PWD
|
||||
and t1, t1, t2
|
||||
sw t1, QCA953X_PLL_DDR_CONFIG_REG(t0)
|
||||
nop
|
||||
|
||||
lw t1, QCA953X_PLL_CLK_CTRL_REG(t0)
|
||||
li t2, ~PLL_CLK_CTRL_PLL_BYPASS
|
||||
and t1, t1, t2
|
||||
sw t1, QCA953X_PLL_CLK_CTRL_REG(t0)
|
||||
nop
|
||||
|
||||
li t1, PLL_DDR_DIT_FRAC_VAL
|
||||
sw t1, QCA953X_PLL_DDR_DIT_FRAC_REG(t0)
|
||||
nop
|
||||
|
||||
li t1, PLL_CPU_DIT_FRAC_VAL
|
||||
sw t1, QCA953X_PLL_CPU_DIT_FRAC_REG(t0)
|
||||
nop
|
||||
|
||||
li t0, CKSEG1ADDR(AR71XX_RESET_BASE)
|
||||
lui t1, 0x03fc
|
||||
sw t1, 0xb4(t0)
|
||||
|
||||
nop
|
||||
jr ra
|
||||
nop
|
||||
END(lowlevel_init)
|
208
arch/mips/mach-ath79/reset.c
Normal file
208
arch/mips/mach-ath79/reset.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ath79.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
|
||||
void _machine_restart(void)
|
||||
{
|
||||
void __iomem *base;
|
||||
u32 reg = 0;
|
||||
|
||||
base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
||||
MAP_NOCACHE);
|
||||
if (soc_is_ar71xx())
|
||||
reg = AR71XX_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar724x())
|
||||
reg = AR724X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar913x())
|
||||
reg = AR913X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar933x())
|
||||
reg = AR933X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_ar934x())
|
||||
reg = AR934X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_qca953x())
|
||||
reg = QCA953X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_qca955x())
|
||||
reg = QCA955X_RESET_REG_RESET_MODULE;
|
||||
else if (soc_is_qca956x())
|
||||
reg = QCA956X_RESET_REG_RESET_MODULE;
|
||||
else
|
||||
puts("Reset register not defined for this SOC\n");
|
||||
|
||||
if (reg)
|
||||
setbits_be32(base + reg, AR71XX_RESET_FULL_CHIP);
|
||||
|
||||
while (1)
|
||||
/* NOP */;
|
||||
}
|
||||
|
||||
u32 get_bootstrap(void)
|
||||
{
|
||||
void __iomem *base;
|
||||
u32 reg = 0;
|
||||
|
||||
base = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
||||
MAP_NOCACHE);
|
||||
if (soc_is_ar933x())
|
||||
reg = AR933X_RESET_REG_BOOTSTRAP;
|
||||
else if (soc_is_ar934x())
|
||||
reg = AR934X_RESET_REG_BOOTSTRAP;
|
||||
else if (soc_is_qca953x())
|
||||
reg = QCA953X_RESET_REG_BOOTSTRAP;
|
||||
else if (soc_is_qca955x())
|
||||
reg = QCA955X_RESET_REG_BOOTSTRAP;
|
||||
else if (soc_is_qca956x())
|
||||
reg = QCA956X_RESET_REG_BOOTSTRAP;
|
||||
else
|
||||
puts("Bootstrap register not defined for this SOC\n");
|
||||
|
||||
if (reg)
|
||||
return readl(base + reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eth_init_ar933x(void)
|
||||
{
|
||||
void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
||||
MAP_NOCACHE);
|
||||
void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
void __iomem *gregs = map_physmem(AR933X_GMAC_BASE, AR933X_GMAC_SIZE,
|
||||
MAP_NOCACHE);
|
||||
const u32 mask = AR933X_RESET_GE0_MAC | AR933X_RESET_GE0_MDIO |
|
||||
AR933X_RESET_GE1_MAC | AR933X_RESET_GE1_MDIO |
|
||||
AR933X_RESET_ETH_SWITCH;
|
||||
|
||||
/* Clear MDIO slave EN bit. */
|
||||
clrbits_be32(rregs + AR933X_RESET_REG_BOOTSTRAP, BIT(17));
|
||||
mdelay(10);
|
||||
|
||||
/* Get Atheros S26 PHY out of reset. */
|
||||
clrsetbits_be32(pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG,
|
||||
0x1f, 0x10);
|
||||
mdelay(10);
|
||||
|
||||
setbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
|
||||
mdelay(10);
|
||||
clrbits_be32(rregs + AR933X_RESET_REG_RESET_MODULE, mask);
|
||||
mdelay(10);
|
||||
|
||||
/* Configure AR93xx GMAC register. */
|
||||
clrsetbits_be32(gregs + AR933X_GMAC_REG_ETH_CFG,
|
||||
AR933X_ETH_CFG_MII_GE0_MASTER |
|
||||
AR933X_ETH_CFG_MII_GE0_SLAVE,
|
||||
AR933X_ETH_CFG_MII_GE0_SLAVE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eth_init_ar934x(void)
|
||||
{
|
||||
void __iomem *rregs = map_physmem(AR71XX_RESET_BASE, AR71XX_RESET_SIZE,
|
||||
MAP_NOCACHE);
|
||||
void __iomem *pregs = map_physmem(AR71XX_PLL_BASE, AR71XX_PLL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
void __iomem *gregs = map_physmem(AR934X_GMAC_BASE, AR934X_GMAC_SIZE,
|
||||
MAP_NOCACHE);
|
||||
const u32 mask = AR934X_RESET_GE0_MAC | AR934X_RESET_GE0_MDIO |
|
||||
AR934X_RESET_GE1_MAC | AR934X_RESET_GE1_MDIO |
|
||||
AR934X_RESET_ETH_SWITCH_ANALOG;
|
||||
u32 reg;
|
||||
|
||||
reg = readl(rregs + AR934X_RESET_REG_BOOTSTRAP);
|
||||
if (reg & AR934X_BOOTSTRAP_REF_CLK_40)
|
||||
writel(0x570, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
|
||||
else
|
||||
writel(0x271, pregs + AR934X_PLL_SWITCH_CLOCK_CONTROL_REG);
|
||||
writel(BIT(26) | BIT(25), pregs + AR934X_PLL_ETH_XMII_CONTROL_REG);
|
||||
|
||||
setbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
|
||||
mdelay(1);
|
||||
clrbits_be32(rregs + AR934X_RESET_REG_RESET_MODULE, mask);
|
||||
mdelay(1);
|
||||
|
||||
/* Configure AR934x GMAC register. */
|
||||
writel(AR934X_ETH_CFG_RGMII_GMAC0, gregs + AR934X_GMAC_REG_ETH_CFG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath79_eth_reset(void)
|
||||
{
|
||||
/*
|
||||
* Un-reset ethernet. DM still doesn't have any notion of reset
|
||||
* framework, so we do it by hand here.
|
||||
*/
|
||||
if (soc_is_ar933x())
|
||||
return eth_init_ar933x();
|
||||
if (soc_is_ar934x())
|
||||
return eth_init_ar934x();
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int usb_reset_ar933x(void __iomem *reset_regs)
|
||||
{
|
||||
/* Ungate the USB block */
|
||||
setbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
|
||||
AR933X_RESET_USBSUS_OVERRIDE);
|
||||
mdelay(1);
|
||||
clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
|
||||
AR933X_RESET_USB_HOST);
|
||||
mdelay(1);
|
||||
clrbits_be32(reset_regs + AR933X_RESET_REG_RESET_MODULE,
|
||||
AR933X_RESET_USB_PHY);
|
||||
mdelay(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int usb_reset_ar934x(void __iomem *reset_regs)
|
||||
{
|
||||
/* Ungate the USB block */
|
||||
setbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
|
||||
AR934X_RESET_USBSUS_OVERRIDE);
|
||||
mdelay(1);
|
||||
clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
|
||||
AR934X_RESET_USB_PHY);
|
||||
mdelay(1);
|
||||
clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
|
||||
AR934X_RESET_USB_PHY_ANALOG);
|
||||
mdelay(1);
|
||||
clrbits_be32(reset_regs + AR934X_RESET_REG_RESET_MODULE,
|
||||
AR934X_RESET_USB_HOST);
|
||||
mdelay(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath79_usb_reset(void)
|
||||
{
|
||||
void __iomem *usbc_regs = map_physmem(AR71XX_USB_CTRL_BASE,
|
||||
AR71XX_USB_CTRL_SIZE,
|
||||
MAP_NOCACHE);
|
||||
void __iomem *reset_regs = map_physmem(AR71XX_RESET_BASE,
|
||||
AR71XX_RESET_SIZE,
|
||||
MAP_NOCACHE);
|
||||
/*
|
||||
* Turn on the Buff and Desc swap bits.
|
||||
* NOTE: This write into an undocumented register in mandatory to
|
||||
* get the USB controller operational in BigEndian mode.
|
||||
*/
|
||||
writel(0xf0000, usbc_regs + AR71XX_USB_CTRL_REG_CONFIG);
|
||||
|
||||
if (soc_is_ar933x())
|
||||
return usb_reset_ar933x(reset_regs);
|
||||
if (soc_is_ar934x())
|
||||
return usb_reset_ar934x(reset_regs);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
@ -24,7 +24,6 @@
|
||||
|
||||
.text
|
||||
.set noreorder
|
||||
.set mips32
|
||||
|
||||
.globl lowlevel_init
|
||||
lowlevel_init:
|
||||
|
12
board/qca/ap121/Kconfig
Normal file
12
board/qca/ap121/Kconfig
Normal file
@ -0,0 +1,12 @@
|
||||
if TARGET_AP121
|
||||
|
||||
config SYS_VENDOR
|
||||
default "qca"
|
||||
|
||||
config SYS_BOARD
|
||||
default "ap121"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "ap121"
|
||||
|
||||
endif
|
6
board/qca/ap121/MAINTAINERS
Normal file
6
board/qca/ap121/MAINTAINERS
Normal file
@ -0,0 +1,6 @@
|
||||
AP121 BOARD
|
||||
M: Wills Wang <wills.wang@live.com>
|
||||
S: Maintained
|
||||
F: board/qca/ap121/
|
||||
F: include/configs/ap121.h
|
||||
F: configs/ap121_defconfig
|
5
board/qca/ap121/Makefile
Normal file
5
board/qca/ap121/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y = ap121.o
|
50
board/qca/ap121/ap121.c
Normal file
50
board/qca/ap121/ap121.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/ddr.h>
|
||||
#include <debug_uart.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifdef CONFIG_DEBUG_UART_BOARD_INIT
|
||||
void board_debug_uart_init(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 val;
|
||||
|
||||
regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
/*
|
||||
* GPIO9 as input, GPIO10 as output
|
||||
*/
|
||||
val = readl(regs + AR71XX_GPIO_REG_OE);
|
||||
val &= ~AR933X_GPIO(9);
|
||||
val |= AR933X_GPIO(10);
|
||||
writel(val, regs + AR71XX_GPIO_REG_OE);
|
||||
|
||||
/*
|
||||
* Enable UART, GPIO9 as UART_SI, GPIO10 as UART_SO
|
||||
*/
|
||||
val = readl(regs + AR71XX_GPIO_REG_FUNC);
|
||||
val |= AR933X_GPIO_FUNC_UART_EN | AR933X_GPIO_FUNC_RES_TRUE;
|
||||
writel(val, regs + AR71XX_GPIO_REG_FUNC);
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_UART
|
||||
debug_uart_init();
|
||||
#endif
|
||||
ddr_init();
|
||||
return 0;
|
||||
}
|
12
board/qca/ap143/Kconfig
Normal file
12
board/qca/ap143/Kconfig
Normal file
@ -0,0 +1,12 @@
|
||||
if TARGET_AP143
|
||||
|
||||
config SYS_VENDOR
|
||||
default "qca"
|
||||
|
||||
config SYS_BOARD
|
||||
default "ap143"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "ap143"
|
||||
|
||||
endif
|
6
board/qca/ap143/MAINTAINERS
Normal file
6
board/qca/ap143/MAINTAINERS
Normal file
@ -0,0 +1,6 @@
|
||||
AP143 BOARD
|
||||
M: Wills Wang <wills.wang@live.com>
|
||||
S: Maintained
|
||||
F: board/qca/ap143/
|
||||
F: include/configs/ap143.h
|
||||
F: configs/ap143_defconfig
|
5
board/qca/ap143/Makefile
Normal file
5
board/qca/ap143/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y = ap143.o
|
66
board/qca/ap143/ap143.c
Normal file
66
board/qca/ap143/ap143.c
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/ddr.h>
|
||||
#include <debug_uart.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifdef CONFIG_DEBUG_UART_BOARD_INIT
|
||||
void board_debug_uart_init(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
u32 val;
|
||||
|
||||
regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
/*
|
||||
* GPIO9 as input, GPIO10 as output
|
||||
*/
|
||||
val = readl(regs + AR71XX_GPIO_REG_OE);
|
||||
val |= QCA953X_GPIO(9);
|
||||
val &= ~QCA953X_GPIO(10);
|
||||
writel(val, regs + AR71XX_GPIO_REG_OE);
|
||||
|
||||
/*
|
||||
* Enable GPIO10 as UART0_SOUT
|
||||
*/
|
||||
val = readl(regs + QCA953X_GPIO_REG_OUT_FUNC2);
|
||||
val &= ~QCA953X_GPIO_MUX_MASK(16);
|
||||
val |= QCA953X_GPIO_OUT_MUX_UART0_SOUT << 16;
|
||||
writel(val, regs + QCA953X_GPIO_REG_OUT_FUNC2);
|
||||
|
||||
/*
|
||||
* Enable GPIO9 as UART0_SIN
|
||||
*/
|
||||
val = readl(regs + QCA953X_GPIO_REG_IN_ENABLE0);
|
||||
val &= ~QCA953X_GPIO_MUX_MASK(8);
|
||||
val |= QCA953X_GPIO_IN_MUX_UART0_SIN << 8;
|
||||
writel(val, regs + QCA953X_GPIO_REG_IN_ENABLE0);
|
||||
|
||||
/*
|
||||
* Enable GPIO10 output
|
||||
*/
|
||||
val = readl(regs + AR71XX_GPIO_REG_OUT);
|
||||
val |= QCA953X_GPIO(10);
|
||||
writel(val, regs + AR71XX_GPIO_REG_OUT);
|
||||
}
|
||||
#endif
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_UART
|
||||
debug_uart_init();
|
||||
#endif
|
||||
ddr_init();
|
||||
return 0;
|
||||
}
|
15
board/tplink/wdr4300/Kconfig
Normal file
15
board/tplink/wdr4300/Kconfig
Normal file
@ -0,0 +1,15 @@
|
||||
if BOARD_TPLINK_WDR4300
|
||||
|
||||
config SYS_VENDOR
|
||||
default "tplink"
|
||||
|
||||
config SYS_SOC
|
||||
default "ath79"
|
||||
|
||||
config SYS_BOARD
|
||||
default "wdr4300"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "tplink_wdr4300"
|
||||
|
||||
endif
|
6
board/tplink/wdr4300/MAINTAINERS
Normal file
6
board/tplink/wdr4300/MAINTAINERS
Normal file
@ -0,0 +1,6 @@
|
||||
TPLINK_WDR4300 BOARD
|
||||
M: Marek Vasut <marex@denx.de>
|
||||
S: Maintained
|
||||
F: board/tplink/wdr4300/
|
||||
F: include/configs/tplink_wdr4300.h
|
||||
F: configs/tplink_wdr4300_defconfig
|
5
board/tplink/wdr4300/Makefile
Normal file
5
board/tplink/wdr4300/Makefile
Normal file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y = wdr4300.o
|
74
board/tplink/wdr4300/wdr4300.c
Normal file
74
board/tplink/wdr4300/wdr4300.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <mach/ath79.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
#include <mach/ddr.h>
|
||||
#include <debug_uart.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#ifdef CONFIG_USB
|
||||
static void wdr4300_usb_start(void)
|
||||
{
|
||||
void __iomem *gpio_regs = map_physmem(AR71XX_GPIO_BASE,
|
||||
AR71XX_GPIO_SIZE, MAP_NOCACHE);
|
||||
if (!gpio_regs)
|
||||
return;
|
||||
|
||||
/* Power up the USB HUB. */
|
||||
clrbits_be32(gpio_regs + AR71XX_GPIO_REG_OE, BIT(21) | BIT(22));
|
||||
writel(BIT(21) | BIT(22), gpio_regs + AR71XX_GPIO_REG_SET);
|
||||
mdelay(1);
|
||||
|
||||
ath79_usb_reset();
|
||||
}
|
||||
#else
|
||||
static inline void wdr4300_usb_start(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BOARD_EARLY_INIT_F
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
void __iomem *regs;
|
||||
|
||||
regs = map_physmem(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
/* Assure JTAG is not disconnected. */
|
||||
writel(0x40, regs + AR934X_GPIO_REG_FUNC);
|
||||
|
||||
/* Configure default GPIO input/output regs. */
|
||||
writel(0x3031b, regs + AR71XX_GPIO_REG_OE);
|
||||
writel(0x0f804, regs + AR71XX_GPIO_REG_OUT);
|
||||
|
||||
/* Configure pin multiplexing. */
|
||||
writel(0x00000000, regs + AR934X_GPIO_REG_OUT_FUNC0);
|
||||
writel(0x0b0a0980, regs + AR934X_GPIO_REG_OUT_FUNC1);
|
||||
writel(0x00180000, regs + AR934X_GPIO_REG_OUT_FUNC2);
|
||||
writel(0x00000000, regs + AR934X_GPIO_REG_OUT_FUNC3);
|
||||
writel(0x0000004d, regs + AR934X_GPIO_REG_OUT_FUNC4);
|
||||
writel(0x00000000, regs + AR934X_GPIO_REG_OUT_FUNC5);
|
||||
|
||||
#ifdef CONFIG_DEBUG_UART
|
||||
debug_uart_init();
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
|
||||
ar934x_pll_init(560, 480, 240);
|
||||
ar934x_ddr_init(560, 480, 240);
|
||||
#endif
|
||||
|
||||
wdr4300_usb_start();
|
||||
ath79_eth_reset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -341,6 +341,8 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
print_eth(0);
|
||||
printf("ip_addr = %s\n", getenv("ipaddr"));
|
||||
printf("baudrate = %u bps\n", gd->baudrate);
|
||||
print_num("relocaddr", gd->relocaddr);
|
||||
print_num("reloc off", gd->reloc_off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
47
configs/ap121_defconfig
Normal file
47
configs/ap121_defconfig
Normal file
@ -0,0 +1,47 @@
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x2000
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_ARCH_ATH79=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="ap121"
|
||||
CONFIG_SYS_PROMPT="ap121 # "
|
||||
# CONFIG_CMD_BDI is not set
|
||||
# CONFIG_CMD_CONSOLE is not set
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
# CONFIG_CMD_EXPORTENV is not set
|
||||
# CONFIG_CMD_IMPORTENV is not set
|
||||
# CONFIG_CMD_EDITENV is not set
|
||||
# CONFIG_CMD_CRC32 is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_SPI=y
|
||||
# CONFIG_CMD_FPGA is not set
|
||||
# CONFIG_CMD_NET is not set
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_BAR=y
|
||||
CONFIG_SPI_FLASH_ATMEL=y
|
||||
CONFIG_SPI_FLASH_EON=y
|
||||
CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_SST=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_SPI_FLASH_DATAFLASH=y
|
||||
CONFIG_SPI_FLASH_MTD=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCONF=y
|
||||
CONFIG_AR933X_PINCTRL=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DEBUG_UART_AR933X=y
|
||||
CONFIG_DEBUG_UART_BASE=0xb8020000
|
||||
CONFIG_DEBUG_UART_CLOCK=25000000
|
||||
CONFIG_DEBUG_UART_BOARD_INIT=y
|
||||
CONFIG_AR933X_UART=y
|
||||
CONFIG_ATH79_SPI=y
|
||||
CONFIG_USE_PRIVATE_LIBGCC=y
|
||||
CONFIG_OF_LIBFDT=y
|
47
configs/ap143_defconfig
Normal file
47
configs/ap143_defconfig
Normal file
@ -0,0 +1,47 @@
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x800
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_ARCH_ATH79=y
|
||||
CONFIG_TARGET_AP143=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="ap143"
|
||||
CONFIG_SYS_PROMPT="ap143 # "
|
||||
# CONFIG_CMD_BDI is not set
|
||||
# CONFIG_CMD_CONSOLE is not set
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
# CONFIG_CMD_EXPORTENV is not set
|
||||
# CONFIG_CMD_IMPORTENV is not set
|
||||
# CONFIG_CMD_EDITENV is not set
|
||||
# CONFIG_CMD_CRC32 is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_SPI=y
|
||||
# CONFIG_CMD_FPGA is not set
|
||||
# CONFIG_CMD_NET is not set
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_BAR=y
|
||||
CONFIG_SPI_FLASH_ATMEL=y
|
||||
CONFIG_SPI_FLASH_EON=y
|
||||
CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_SST=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_SPI_FLASH_DATAFLASH=y
|
||||
CONFIG_SPI_FLASH_MTD=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_QCA953X_PINCTRL=y
|
||||
CONFIG_DEBUG_UART=y
|
||||
CONFIG_DEBUG_UART_BASE=0xb8020000
|
||||
CONFIG_DEBUG_UART_CLOCK=25000000
|
||||
CONFIG_DEBUG_UART_SHIFT=2
|
||||
CONFIG_DEBUG_UART_BOARD_INIT=y
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_ATH79_SPI=y
|
||||
CONFIG_USE_PRIVATE_LIBGCC=y
|
||||
CONFIG_OF_LIBFDT=y
|
43
configs/tplink_wdr4300_defconfig
Normal file
43
configs/tplink_wdr4300_defconfig
Normal file
@ -0,0 +1,43 @@
|
||||
CONFIG_MIPS=y
|
||||
CONFIG_ARCH_ATH79=y
|
||||
CONFIG_BOARD_TPLINK_WDR4300=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x2000
|
||||
CONFIG_SYS_NS16550=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="tplink_wdr4300"
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
# CONFIG_CMD_FPGA is not set
|
||||
CONFIG_CMD_NET=y
|
||||
CONFIG_CMD_NFS=y
|
||||
CONFIG_CMD_DHCP=y
|
||||
CONFIG_CMD_PING=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_AG7XXX=y
|
||||
CONFIG_CLK=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_GENERIC=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_ATH79_SPI=y
|
||||
CONFIG_DM_SPI=y
|
||||
CONFIG_DM_SPI_FLASH=y
|
||||
CONFIG_CMD_SF=y
|
||||
CONFIG_CMD_SPI=y
|
||||
CONFIG_SPI_FLASH=y
|
||||
CONFIG_SPI_FLASH_ATMEL=y
|
||||
CONFIG_SPI_FLASH_EON=y
|
||||
CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
CONFIG_SPI_FLASH_MACRONIX=y
|
||||
CONFIG_SPI_FLASH_SPANSION=y
|
||||
CONFIG_SPI_FLASH_STMICRO=y
|
||||
CONFIG_SPI_FLASH_SST=y
|
||||
CONFIG_SPI_FLASH_WINBOND=y
|
||||
CONFIG_SPI_FLASH_DATAFLASH=y
|
||||
CONFIG_SPI_FLASH_MTD=y
|
||||
CONFIG_PINCTRL=y
|
24
doc/device-tree-bindings/serial/qca,ar9330-uart.txt
Normal file
24
doc/device-tree-bindings/serial/qca,ar9330-uart.txt
Normal file
@ -0,0 +1,24 @@
|
||||
* Qualcomm Atheros AR9330 High-Speed UART
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Must be "qca,ar9330-uart"
|
||||
|
||||
- reg: Specifies the physical base address of the controller and
|
||||
the length of the memory mapped region.
|
||||
|
||||
Additional requirements:
|
||||
|
||||
Each UART port must have an alias correctly numbered in "aliases"
|
||||
node.
|
||||
|
||||
Example:
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
};
|
||||
|
||||
uart0: uart@18020000 {
|
||||
compatible = "qca,ar9330-uart";
|
||||
reg = <0x18020000 0x14>;
|
||||
};
|
19
doc/device-tree-bindings/spi/spi-ath79.txt
Normal file
19
doc/device-tree-bindings/spi/spi-ath79.txt
Normal file
@ -0,0 +1,19 @@
|
||||
Binding for Qualcomm Atheros AR7xxx/AR9xxx SPI controller
|
||||
|
||||
Required properties:
|
||||
- compatible: has to be "qca,<soc-type>-spi", "qca,ar7100-spi" as fallback.
|
||||
- reg: Base address and size of the controllers memory area
|
||||
- #address-cells: <1>, as required by generic SPI binding.
|
||||
- #size-cells: <0>, also as required by generic SPI binding.
|
||||
|
||||
Child nodes as per the generic SPI binding.
|
||||
|
||||
Example:
|
||||
|
||||
spi@1f000000 {
|
||||
compatible = "qca,ar9132-spi", "qca,ar7100-spi";
|
||||
reg = <0x1f000000 0x10>;
|
||||
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
};
|
@ -28,6 +28,13 @@ config ALTERA_QSPI
|
||||
NOR flash to parallel flash interface. Please find details on the
|
||||
"Embedded Peripherals IP User Guide" of Altera.
|
||||
|
||||
config FLASH_PIC32
|
||||
bool "Microchip PIC32 Flash driver"
|
||||
depends on MACH_PIC32 && MTD
|
||||
help
|
||||
This enables access to Microchip PIC32 internal non-CFI flash
|
||||
chips through PIC32 Non-Volatile-Memory Controller.
|
||||
|
||||
endmenu
|
||||
|
||||
source "drivers/mtd/nand/Kconfig"
|
||||
|
@ -19,5 +19,6 @@ obj-$(CONFIG_HAS_DATAFLASH) += dataflash.o
|
||||
obj-$(CONFIG_FTSMC020) += ftsmc020.o
|
||||
obj-$(CONFIG_FLASH_CFI_LEGACY) += jedec_flash.o
|
||||
obj-$(CONFIG_MW_EEPROM) += mw_eeprom.o
|
||||
obj-$(CONFIG_FLASH_PIC32) += pic32_flash.o
|
||||
obj-$(CONFIG_ST_SMI) += st_smi.o
|
||||
obj-$(CONFIG_STM32_FLASH) += stm32_flash.o
|
||||
|
444
drivers/mtd/pic32_flash.c
Normal file
444
drivers/mtd/pic32_flash.c
Normal file
@ -0,0 +1,444 @@
|
||||
/*
|
||||
* Copyright (C) 2015
|
||||
* Cristian Birsan <cristian.birsan@microchip.com>
|
||||
* Purna Chandra Mandal <purna.mandal@microchip.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdt_support.h>
|
||||
#include <flash.h>
|
||||
#include <mach/pic32.h>
|
||||
#include <wait_bit.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* NVM Controller registers */
|
||||
struct pic32_reg_nvm {
|
||||
struct pic32_reg_atomic ctrl;
|
||||
struct pic32_reg_atomic key;
|
||||
struct pic32_reg_atomic addr;
|
||||
struct pic32_reg_atomic data;
|
||||
};
|
||||
|
||||
/* NVM operations */
|
||||
#define NVMOP_NOP 0
|
||||
#define NVMOP_WORD_WRITE 1
|
||||
#define NVMOP_PAGE_ERASE 4
|
||||
|
||||
/* NVM control bits */
|
||||
#define NVM_WR BIT(15)
|
||||
#define NVM_WREN BIT(14)
|
||||
#define NVM_WRERR BIT(13)
|
||||
#define NVM_LVDERR BIT(12)
|
||||
|
||||
/* NVM programming unlock register */
|
||||
#define LOCK_KEY 0x0
|
||||
#define UNLOCK_KEY1 0xaa996655
|
||||
#define UNLOCK_KEY2 0x556699aa
|
||||
|
||||
/*
|
||||
* PIC32 flash banks consist of number of pages, each page
|
||||
* into number of rows and rows into number of words.
|
||||
* Here we will maintain page information instead of sector.
|
||||
*/
|
||||
flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
|
||||
static struct pic32_reg_nvm *nvm_regs_p;
|
||||
|
||||
static inline void flash_initiate_operation(u32 nvmop)
|
||||
{
|
||||
/* set operation */
|
||||
writel(nvmop, &nvm_regs_p->ctrl.raw);
|
||||
|
||||
/* enable flash write */
|
||||
writel(NVM_WREN, &nvm_regs_p->ctrl.set);
|
||||
|
||||
/* unlock sequence */
|
||||
writel(LOCK_KEY, &nvm_regs_p->key.raw);
|
||||
writel(UNLOCK_KEY1, &nvm_regs_p->key.raw);
|
||||
writel(UNLOCK_KEY2, &nvm_regs_p->key.raw);
|
||||
|
||||
/* initiate operation */
|
||||
writel(NVM_WR, &nvm_regs_p->ctrl.set);
|
||||
}
|
||||
|
||||
static int flash_wait_till_busy(const char *func, ulong timeout)
|
||||
{
|
||||
int ret = wait_for_bit(__func__, &nvm_regs_p->ctrl.raw,
|
||||
NVM_WR, false, timeout, false);
|
||||
|
||||
return ret ? ERR_TIMOUT : ERR_OK;
|
||||
}
|
||||
|
||||
static inline int flash_complete_operation(void)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(&nvm_regs_p->ctrl.raw);
|
||||
if (tmp & NVM_WRERR) {
|
||||
printf("Error in Block Erase - Lock Bit may be set!\n");
|
||||
flash_initiate_operation(NVMOP_NOP);
|
||||
return ERR_PROTECTED;
|
||||
}
|
||||
|
||||
if (tmp & NVM_LVDERR) {
|
||||
printf("Error in Block Erase - low-vol detected!\n");
|
||||
flash_initiate_operation(NVMOP_NOP);
|
||||
return ERR_NOT_ERASED;
|
||||
}
|
||||
|
||||
/* disable flash write or erase operation */
|
||||
writel(NVM_WREN, &nvm_regs_p->ctrl.clr);
|
||||
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase flash sectors, returns:
|
||||
* ERR_OK - OK
|
||||
* ERR_INVAL - invalid sector arguments
|
||||
* ERR_TIMOUT - write timeout
|
||||
* ERR_NOT_ERASED - Flash not erased
|
||||
* ERR_UNKNOWN_FLASH_VENDOR - incorrect flash
|
||||
*/
|
||||
int flash_erase(flash_info_t *info, int s_first, int s_last)
|
||||
{
|
||||
ulong sect_start, sect_end, flags;
|
||||
int prot, sect;
|
||||
int rc;
|
||||
|
||||
if ((info->flash_id & FLASH_VENDMASK) != FLASH_MAN_MCHP) {
|
||||
printf("Can't erase unknown flash type %08lx - aborted\n",
|
||||
info->flash_id);
|
||||
return ERR_UNKNOWN_FLASH_VENDOR;
|
||||
}
|
||||
|
||||
if ((s_first < 0) || (s_first > s_last)) {
|
||||
printf("- no sectors to erase\n");
|
||||
return ERR_INVAL;
|
||||
}
|
||||
|
||||
prot = 0;
|
||||
for (sect = s_first; sect <= s_last; ++sect) {
|
||||
if (info->protect[sect])
|
||||
prot++;
|
||||
}
|
||||
|
||||
if (prot)
|
||||
printf("- Warning: %d protected sectors will not be erased!\n",
|
||||
prot);
|
||||
else
|
||||
printf("\n");
|
||||
|
||||
/* erase on unprotected sectors */
|
||||
for (sect = s_first; sect <= s_last; sect++) {
|
||||
if (info->protect[sect])
|
||||
continue;
|
||||
|
||||
/* disable interrupts */
|
||||
flags = disable_interrupts();
|
||||
|
||||
/* write destination page address (physical) */
|
||||
sect_start = CPHYSADDR(info->start[sect]);
|
||||
writel(sect_start, &nvm_regs_p->addr.raw);
|
||||
|
||||
/* page erase */
|
||||
flash_initiate_operation(NVMOP_PAGE_ERASE);
|
||||
|
||||
/* wait */
|
||||
rc = flash_wait_till_busy(__func__,
|
||||
CONFIG_SYS_FLASH_ERASE_TOUT);
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flags)
|
||||
enable_interrupts();
|
||||
|
||||
if (rc != ERR_OK)
|
||||
return rc;
|
||||
|
||||
rc = flash_complete_operation();
|
||||
if (rc != ERR_OK)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* flash content is updated but cache might contain stale
|
||||
* data, so invalidate dcache.
|
||||
*/
|
||||
sect_end = info->start[sect] + info->size / info->sector_count;
|
||||
invalidate_dcache_range(info->start[sect], sect_end);
|
||||
}
|
||||
|
||||
printf(" done\n");
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
int page_erase(flash_info_t *info, int sect)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write a word to flash */
|
||||
static int write_word(flash_info_t *info, ulong dest, ulong word)
|
||||
{
|
||||
ulong flags;
|
||||
int rc;
|
||||
|
||||
/* read flash to check if it is sufficiently erased */
|
||||
if ((readl((void __iomem *)dest) & word) != word) {
|
||||
printf("Error, Flash not erased!\n");
|
||||
return ERR_NOT_ERASED;
|
||||
}
|
||||
|
||||
/* disable interrupts */
|
||||
flags = disable_interrupts();
|
||||
|
||||
/* update destination page address (physical) */
|
||||
writel(CPHYSADDR(dest), &nvm_regs_p->addr.raw);
|
||||
writel(word, &nvm_regs_p->data.raw);
|
||||
|
||||
/* word write */
|
||||
flash_initiate_operation(NVMOP_WORD_WRITE);
|
||||
|
||||
/* wait for operation to complete */
|
||||
rc = flash_wait_till_busy(__func__, CONFIG_SYS_FLASH_WRITE_TOUT);
|
||||
|
||||
/* re-enable interrupts if necessary */
|
||||
if (flags)
|
||||
enable_interrupts();
|
||||
|
||||
if (rc != ERR_OK)
|
||||
return rc;
|
||||
|
||||
return flash_complete_operation();
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy memory to flash, returns:
|
||||
* ERR_OK - OK
|
||||
* ERR_TIMOUT - write timeout
|
||||
* ERR_NOT_ERASED - Flash not erased
|
||||
*/
|
||||
int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
|
||||
{
|
||||
ulong dst, tmp_le, len = cnt;
|
||||
int i, l, rc;
|
||||
uchar *cp;
|
||||
|
||||
/* get lower word aligned address */
|
||||
dst = (addr & ~3);
|
||||
|
||||
/* handle unaligned start bytes */
|
||||
l = addr - dst;
|
||||
if (l != 0) {
|
||||
tmp_le = 0;
|
||||
for (i = 0, cp = (uchar *)dst; i < l; ++i, ++cp)
|
||||
tmp_le |= *cp << (i * 8);
|
||||
|
||||
for (; (i < 4) && (cnt > 0); ++i, ++src, --cnt, ++cp)
|
||||
tmp_le |= *src << (i * 8);
|
||||
|
||||
for (; (cnt == 0) && (i < 4); ++i, ++cp)
|
||||
tmp_le |= *cp << (i * 8);
|
||||
|
||||
rc = write_word(info, dst, tmp_le);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
dst += 4;
|
||||
}
|
||||
|
||||
/* handle word aligned part */
|
||||
while (cnt >= 4) {
|
||||
tmp_le = src[0] | src[1] << 8 | src[2] << 16 | src[3] << 24;
|
||||
rc = write_word(info, dst, tmp_le);
|
||||
if (rc)
|
||||
goto out;
|
||||
src += 4;
|
||||
dst += 4;
|
||||
cnt -= 4;
|
||||
}
|
||||
|
||||
if (cnt == 0) {
|
||||
rc = ERR_OK;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* handle unaligned tail bytes */
|
||||
tmp_le = 0;
|
||||
for (i = 0, cp = (uchar *)dst; (i < 4) && (cnt > 0); ++i, ++cp) {
|
||||
tmp_le |= *src++ << (i * 8);
|
||||
--cnt;
|
||||
}
|
||||
|
||||
for (; i < 4; ++i, ++cp)
|
||||
tmp_le |= *cp << (i * 8);
|
||||
|
||||
rc = write_word(info, dst, tmp_le);
|
||||
out:
|
||||
/*
|
||||
* flash content updated by nvm controller but CPU cache might
|
||||
* have stale data, so invalidate dcache.
|
||||
*/
|
||||
invalidate_dcache_range(addr, addr + len);
|
||||
|
||||
printf(" done\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
void flash_print_info(flash_info_t *info)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (info->flash_id == FLASH_UNKNOWN) {
|
||||
printf("missing or unknown FLASH type\n");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_VENDMASK) {
|
||||
case FLASH_MAN_MCHP:
|
||||
printf("Microchip Technology ");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Vendor ");
|
||||
break;
|
||||
}
|
||||
|
||||
switch (info->flash_id & FLASH_TYPEMASK) {
|
||||
case FLASH_MCHP100T:
|
||||
printf("Internal (8 Mbit, 64 x 16k)\n");
|
||||
break;
|
||||
default:
|
||||
printf("Unknown Chip Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
printf(" Size: %ld MB in %d Sectors\n",
|
||||
info->size >> 20, info->sector_count);
|
||||
|
||||
printf(" Sector Start Addresses:");
|
||||
for (i = 0; i < info->sector_count; ++i) {
|
||||
if ((i % 5) == 0)
|
||||
printf("\n ");
|
||||
|
||||
printf(" %08lX%s", info->start[i],
|
||||
info->protect[i] ? " (RO)" : " ");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
unsigned long flash_init(void)
|
||||
{
|
||||
unsigned long size = 0;
|
||||
struct udevice *dev;
|
||||
int bank;
|
||||
|
||||
/* probe every MTD device */
|
||||
for (uclass_first_device(UCLASS_MTD, &dev); dev;
|
||||
uclass_next_device(&dev)) {
|
||||
/* nop */
|
||||
}
|
||||
|
||||
/* calc total flash size */
|
||||
for (bank = 0; bank < CONFIG_SYS_MAX_FLASH_BANKS; ++bank)
|
||||
size += flash_info[bank].size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static void pic32_flash_bank_init(flash_info_t *info,
|
||||
ulong base, ulong size)
|
||||
{
|
||||
ulong sect_size;
|
||||
int sect;
|
||||
|
||||
/* device & manufacturer code */
|
||||
info->flash_id = FLASH_MAN_MCHP | FLASH_MCHP100T;
|
||||
info->sector_count = CONFIG_SYS_MAX_FLASH_SECT;
|
||||
info->size = size;
|
||||
|
||||
/* update sector (i.e page) info */
|
||||
sect_size = info->size / info->sector_count;
|
||||
for (sect = 0; sect < info->sector_count; sect++) {
|
||||
info->start[sect] = base;
|
||||
/* protect each sector by default */
|
||||
info->protect[sect] = 1;
|
||||
base += sect_size;
|
||||
}
|
||||
}
|
||||
|
||||
static int pic32_flash_probe(struct udevice *dev)
|
||||
{
|
||||
void *blob = (void *)gd->fdt_blob;
|
||||
int node = dev->of_offset;
|
||||
const char *list, *end;
|
||||
const fdt32_t *cell;
|
||||
unsigned long addr, size;
|
||||
int parent, addrc, sizec;
|
||||
flash_info_t *info;
|
||||
int len, idx;
|
||||
|
||||
/*
|
||||
* decode regs. there are multiple reg tuples, and they need to
|
||||
* match with reg-names.
|
||||
*/
|
||||
parent = fdt_parent_offset(blob, node);
|
||||
of_bus_default_count_cells(blob, parent, &addrc, &sizec);
|
||||
list = fdt_getprop(blob, node, "reg-names", &len);
|
||||
if (!list)
|
||||
return -ENOENT;
|
||||
|
||||
end = list + len;
|
||||
cell = fdt_getprop(blob, node, "reg", &len);
|
||||
if (!cell)
|
||||
return -ENOENT;
|
||||
|
||||
for (idx = 0, info = &flash_info[0]; list < end;) {
|
||||
addr = fdt_translate_address((void *)blob, node, cell + idx);
|
||||
size = fdt_addr_to_cpu(cell[idx + addrc]);
|
||||
len = strlen(list);
|
||||
if (!strncmp(list, "nvm", len)) {
|
||||
/* NVM controller */
|
||||
nvm_regs_p = ioremap(addr, size);
|
||||
} else if (!strncmp(list, "bank", 4)) {
|
||||
/* Flash bank: use kseg0 cached address */
|
||||
pic32_flash_bank_init(info, CKSEG0ADDR(addr), size);
|
||||
info++;
|
||||
}
|
||||
idx += addrc + sizec;
|
||||
list += len + 1;
|
||||
}
|
||||
|
||||
/* disable flash write/erase operations */
|
||||
writel(NVM_WREN, &nvm_regs_p->ctrl.clr);
|
||||
|
||||
#if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
|
||||
/* monitor protection ON by default */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CONFIG_SYS_MONITOR_BASE,
|
||||
CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ENV_IS_IN_FLASH
|
||||
/* ENV protection ON by default */
|
||||
flash_protect(FLAG_PROTECT_SET,
|
||||
CONFIG_ENV_ADDR,
|
||||
CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
|
||||
&flash_info[0]);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id pic32_flash_ids[] = {
|
||||
{ .compatible = "microchip,pic32mzda-flash" },
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pic32_flash) = {
|
||||
.name = "pic32_flash",
|
||||
.id = UCLASS_MTD,
|
||||
.of_match = pic32_flash_ids,
|
||||
.probe = pic32_flash_probe,
|
||||
};
|
@ -105,6 +105,24 @@ config SPL_PINCONF
|
||||
|
||||
if PINCTRL || SPL_PINCTRL
|
||||
|
||||
config AR933X_PINCTRL
|
||||
bool "QCA/Athores ar933x pin control driver"
|
||||
depends on DM && SOC_AR933X
|
||||
help
|
||||
Support pin multiplexing control on QCA/Athores ar933x SoCs.
|
||||
The driver is controlled by a device tree node which contains
|
||||
both the GPIO definitions and pin control functions for each
|
||||
available multiplex function.
|
||||
|
||||
config QCA953X_PINCTRL
|
||||
bool "QCA/Athores qca953x pin control driver"
|
||||
depends on DM && SOC_QCA953X
|
||||
help
|
||||
Support pin multiplexing control on QCA/Athores qca953x SoCs.
|
||||
The driver is controlled by a device tree node which contains
|
||||
both the GPIO definitions and pin control functions for each
|
||||
available multiplex function.
|
||||
|
||||
config ROCKCHIP_PINCTRL
|
||||
bool "Rockchip pin control driver"
|
||||
depends on DM
|
||||
|
@ -6,6 +6,7 @@ obj-y += pinctrl-uclass.o
|
||||
obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC) += pinctrl-generic.o
|
||||
|
||||
obj-y += nxp/
|
||||
obj-$(CONFIG_ARCH_ATH79) += ath79/
|
||||
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
|
||||
obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
|
||||
|
||||
|
6
drivers/pinctrl/ath79/Makefile
Normal file
6
drivers/pinctrl/ath79/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-$(CONFIG_AR933X_PINCTRL) += pinctrl_ar933x.o
|
||||
obj-$(CONFIG_QCA953x_PINCTRL) += pinctrl_qca953x.o
|
136
drivers/pinctrl/ath79/pinctrl_ar933x.c
Normal file
136
drivers/pinctrl/ath79/pinctrl_ar933x.c
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum periph_id {
|
||||
PERIPH_ID_UART0,
|
||||
PERIPH_ID_SPI0,
|
||||
PERIPH_ID_NONE = -1,
|
||||
};
|
||||
|
||||
struct ar933x_pinctrl_priv {
|
||||
void __iomem *regs;
|
||||
};
|
||||
|
||||
static void pinctrl_ar933x_spi_config(struct ar933x_pinctrl_priv *priv, int cs)
|
||||
{
|
||||
switch (cs) {
|
||||
case 0:
|
||||
clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
|
||||
AR933X_GPIO(4), AR933X_GPIO(3) |
|
||||
AR933X_GPIO(5) | AR933X_GPIO(2));
|
||||
setbits_be32(priv->regs + AR71XX_GPIO_REG_FUNC,
|
||||
AR933X_GPIO_FUNC_SPI_EN |
|
||||
AR933X_GPIO_FUNC_RES_TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void pinctrl_ar933x_uart_config(struct ar933x_pinctrl_priv *priv, int uart_id)
|
||||
{
|
||||
switch (uart_id) {
|
||||
case PERIPH_ID_UART0:
|
||||
clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
|
||||
AR933X_GPIO(9), AR933X_GPIO(10));
|
||||
setbits_be32(priv->regs + AR71XX_GPIO_REG_FUNC,
|
||||
AR933X_GPIO_FUNC_UART_EN |
|
||||
AR933X_GPIO_FUNC_RES_TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int ar933x_pinctrl_request(struct udevice *dev, int func, int flags)
|
||||
{
|
||||
struct ar933x_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
debug("%s: func=%x, flags=%x\n", __func__, func, flags);
|
||||
switch (func) {
|
||||
case PERIPH_ID_SPI0:
|
||||
pinctrl_ar933x_spi_config(priv, flags);
|
||||
break;
|
||||
case PERIPH_ID_UART0:
|
||||
pinctrl_ar933x_uart_config(priv, func);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar933x_pinctrl_get_periph_id(struct udevice *dev,
|
||||
struct udevice *periph)
|
||||
{
|
||||
u32 cell[2];
|
||||
int ret;
|
||||
|
||||
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
|
||||
"interrupts", cell, ARRAY_SIZE(cell));
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch (cell[0]) {
|
||||
case 128:
|
||||
return PERIPH_ID_UART0;
|
||||
case 129:
|
||||
return PERIPH_ID_SPI0;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int ar933x_pinctrl_set_state_simple(struct udevice *dev,
|
||||
struct udevice *periph)
|
||||
{
|
||||
int func;
|
||||
|
||||
func = ar933x_pinctrl_get_periph_id(dev, periph);
|
||||
if (func < 0)
|
||||
return func;
|
||||
return ar933x_pinctrl_request(dev, func, 0);
|
||||
}
|
||||
|
||||
static struct pinctrl_ops ar933x_pinctrl_ops = {
|
||||
.set_state_simple = ar933x_pinctrl_set_state_simple,
|
||||
.request = ar933x_pinctrl_request,
|
||||
.get_periph_id = ar933x_pinctrl_get_periph_id,
|
||||
};
|
||||
|
||||
static int ar933x_pinctrl_probe(struct udevice *dev)
|
||||
{
|
||||
struct ar933x_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
fdt_addr_t addr;
|
||||
|
||||
addr = dev_get_addr(dev);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->regs = map_physmem(addr,
|
||||
AR71XX_GPIO_SIZE,
|
||||
MAP_NOCACHE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id ar933x_pinctrl_ids[] = {
|
||||
{ .compatible = "qca,ar933x-pinctrl" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pinctrl_ar933x) = {
|
||||
.name = "pinctrl_ar933x",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = ar933x_pinctrl_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct ar933x_pinctrl_priv),
|
||||
.ops = &ar933x_pinctrl_ops,
|
||||
.probe = ar933x_pinctrl_probe,
|
||||
};
|
156
drivers/pinctrl/ath79/pinctrl_qca953x.c
Normal file
156
drivers/pinctrl/ath79/pinctrl_qca953x.c
Normal file
@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum periph_id {
|
||||
PERIPH_ID_UART0,
|
||||
PERIPH_ID_SPI0,
|
||||
PERIPH_ID_NONE = -1,
|
||||
};
|
||||
|
||||
struct qca953x_pinctrl_priv {
|
||||
void __iomem *regs;
|
||||
};
|
||||
|
||||
static void pinctrl_qca953x_spi_config(struct qca953x_pinctrl_priv *priv, int cs)
|
||||
{
|
||||
switch (cs) {
|
||||
case 0:
|
||||
clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
|
||||
QCA953X_GPIO(5) | QCA953X_GPIO(6) |
|
||||
QCA953X_GPIO(7), QCA953X_GPIO(8));
|
||||
|
||||
clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_OUT_FUNC1,
|
||||
QCA953X_GPIO_MUX_MASK(8) |
|
||||
QCA953X_GPIO_MUX_MASK(16) |
|
||||
QCA953X_GPIO_MUX_MASK(24),
|
||||
(QCA953X_GPIO_OUT_MUX_SPI_CS0 << 8) |
|
||||
(QCA953X_GPIO_OUT_MUX_SPI_CLK << 16) |
|
||||
(QCA953X_GPIO_OUT_MUX_SPI_MOSI << 24));
|
||||
|
||||
clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_IN_ENABLE0,
|
||||
QCA953X_GPIO_MUX_MASK(0),
|
||||
QCA953X_GPIO_IN_MUX_SPI_DATA_IN);
|
||||
|
||||
setbits_be32(priv->regs + AR71XX_GPIO_REG_OUT,
|
||||
QCA953X_GPIO(8));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void pinctrl_qca953x_uart_config(struct qca953x_pinctrl_priv *priv, int uart_id)
|
||||
{
|
||||
switch (uart_id) {
|
||||
case PERIPH_ID_UART0:
|
||||
clrsetbits_be32(priv->regs + AR71XX_GPIO_REG_OE,
|
||||
QCA953X_GPIO(9), QCA953X_GPIO(10));
|
||||
|
||||
clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_OUT_FUNC2,
|
||||
QCA953X_GPIO_MUX_MASK(16),
|
||||
QCA953X_GPIO_OUT_MUX_UART0_SOUT << 16);
|
||||
|
||||
clrsetbits_be32(priv->regs + QCA953X_GPIO_REG_IN_ENABLE0,
|
||||
QCA953X_GPIO_MUX_MASK(8),
|
||||
QCA953X_GPIO_IN_MUX_UART0_SIN << 8);
|
||||
|
||||
setbits_be32(priv->regs + AR71XX_GPIO_REG_OUT,
|
||||
QCA953X_GPIO(10));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int qca953x_pinctrl_request(struct udevice *dev, int func, int flags)
|
||||
{
|
||||
struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
|
||||
debug("%s: func=%x, flags=%x\n", __func__, func, flags);
|
||||
switch (func) {
|
||||
case PERIPH_ID_SPI0:
|
||||
pinctrl_qca953x_spi_config(priv, flags);
|
||||
break;
|
||||
case PERIPH_ID_UART0:
|
||||
pinctrl_qca953x_uart_config(priv, func);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qca953x_pinctrl_get_periph_id(struct udevice *dev,
|
||||
struct udevice *periph)
|
||||
{
|
||||
u32 cell[2];
|
||||
int ret;
|
||||
|
||||
ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
|
||||
"interrupts", cell, ARRAY_SIZE(cell));
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch (cell[0]) {
|
||||
case 128:
|
||||
return PERIPH_ID_UART0;
|
||||
case 129:
|
||||
return PERIPH_ID_SPI0;
|
||||
}
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int qca953x_pinctrl_set_state_simple(struct udevice *dev,
|
||||
struct udevice *periph)
|
||||
{
|
||||
int func;
|
||||
|
||||
func = qca953x_pinctrl_get_periph_id(dev, periph);
|
||||
if (func < 0)
|
||||
return func;
|
||||
return qca953x_pinctrl_request(dev, func, 0);
|
||||
}
|
||||
|
||||
static struct pinctrl_ops qca953x_pinctrl_ops = {
|
||||
.set_state_simple = qca953x_pinctrl_set_state_simple,
|
||||
.request = qca953x_pinctrl_request,
|
||||
.get_periph_id = qca953x_pinctrl_get_periph_id,
|
||||
};
|
||||
|
||||
static int qca953x_pinctrl_probe(struct udevice *dev)
|
||||
{
|
||||
struct qca953x_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
fdt_addr_t addr;
|
||||
|
||||
addr = dev_get_addr(dev);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->regs = map_physmem(addr,
|
||||
AR71XX_GPIO_SIZE,
|
||||
MAP_NOCACHE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id qca953x_pinctrl_ids[] = {
|
||||
{ .compatible = "qca,qca953x-pinctrl" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pinctrl_qca953x) = {
|
||||
.name = "pinctrl_qca953x",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = qca953x_pinctrl_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct qca953x_pinctrl_priv),
|
||||
.ops = &qca953x_pinctrl_ops,
|
||||
.probe = qca953x_pinctrl_probe,
|
||||
};
|
@ -89,6 +89,15 @@ config DEBUG_UART_ALTERA_UART
|
||||
You will need to provide parameters to make this work. The driver will
|
||||
be available until the real driver model serial is running.
|
||||
|
||||
config DEBUG_UART_AR933X
|
||||
bool "QCA/Atheros ar933x"
|
||||
depends on AR933X_UART
|
||||
help
|
||||
Select this to enable a debug UART using the ar933x uart driver.
|
||||
You will need to provide parameters to make this work. The
|
||||
driver will be available until the real driver model serial is
|
||||
running.
|
||||
|
||||
config DEBUG_UART_NS16550
|
||||
bool "ns16550"
|
||||
help
|
||||
@ -263,6 +272,15 @@ config ALTERA_UART
|
||||
Select this to enable an UART for Altera devices. Please find
|
||||
details on the "Embedded Peripherals IP User Guide" of Altera.
|
||||
|
||||
config AR933X_UART
|
||||
bool "QCA/Atheros ar933x UART support"
|
||||
depends on DM_SERIAL && SOC_AR933X
|
||||
help
|
||||
Select this to enable UART support for QCA/Atheros ar933x
|
||||
devices. This driver uses driver model and requires a device
|
||||
tree binding to operate, please refer to the document at
|
||||
doc/device-tree-bindings/serial/qca,ar9330-uart.txt.
|
||||
|
||||
config FSL_LPUART
|
||||
bool "Freescale LPUART support"
|
||||
help
|
||||
|
@ -17,6 +17,7 @@ endif
|
||||
|
||||
obj-$(CONFIG_ALTERA_UART) += altera_uart.o
|
||||
obj-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
|
||||
obj-$(CONFIG_AR933X_UART) += serial_ar933x.o
|
||||
obj-$(CONFIG_ARM_DCC) += arm_dcc.o
|
||||
obj-$(CONFIG_ATMEL_USART) += atmel_usart.o
|
||||
obj-$(CONFIG_EFI_APP) += serial_efi.o
|
||||
|
243
drivers/serial/serial_ar933x.c
Normal file
243
drivers/serial/serial_ar933x.c
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <div64.h>
|
||||
#include <errno.h>
|
||||
#include <serial.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
|
||||
#define AR933X_UART_DATA_REG 0x00
|
||||
#define AR933X_UART_CS_REG 0x04
|
||||
#define AR933X_UART_CLK_REG 0x08
|
||||
|
||||
#define AR933X_UART_DATA_TX_RX_MASK 0xff
|
||||
#define AR933X_UART_DATA_RX_CSR BIT(8)
|
||||
#define AR933X_UART_DATA_TX_CSR BIT(9)
|
||||
#define AR933X_UART_CS_IF_MODE_S 2
|
||||
#define AR933X_UART_CS_IF_MODE_M 0x3
|
||||
#define AR933X_UART_CS_IF_MODE_DTE 1
|
||||
#define AR933X_UART_CS_IF_MODE_DCE 2
|
||||
#define AR933X_UART_CS_TX_RDY_ORIDE BIT(7)
|
||||
#define AR933X_UART_CS_RX_RDY_ORIDE BIT(8)
|
||||
#define AR933X_UART_CLK_STEP_M 0xffff
|
||||
#define AR933X_UART_CLK_SCALE_M 0xfff
|
||||
#define AR933X_UART_CLK_SCALE_S 16
|
||||
#define AR933X_UART_CLK_STEP_S 0
|
||||
|
||||
struct ar933x_serial_priv {
|
||||
void __iomem *regs;
|
||||
};
|
||||
|
||||
/*
|
||||
* Baudrate algorithm come from Linux/drivers/tty/serial/ar933x_uart.c
|
||||
* baudrate = (clk / (scale + 1)) * (step * (1 / 2^17))
|
||||
*/
|
||||
static u32 ar933x_serial_get_baud(u32 clk, u32 scale, u32 step)
|
||||
{
|
||||
u64 t;
|
||||
u32 div;
|
||||
|
||||
div = (2 << 16) * (scale + 1);
|
||||
t = clk;
|
||||
t *= step;
|
||||
t += (div / 2);
|
||||
do_div(t, div);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static void ar933x_serial_get_scale_step(u32 clk, u32 baud,
|
||||
u32 *scale, u32 *step)
|
||||
{
|
||||
u32 tscale, baudrate;
|
||||
long min_diff;
|
||||
|
||||
*scale = 0;
|
||||
*step = 0;
|
||||
|
||||
min_diff = baud;
|
||||
for (tscale = 0; tscale < AR933X_UART_CLK_SCALE_M; tscale++) {
|
||||
u64 tstep;
|
||||
int diff;
|
||||
|
||||
tstep = baud * (tscale + 1);
|
||||
tstep *= (2 << 16);
|
||||
do_div(tstep, clk);
|
||||
|
||||
if (tstep > AR933X_UART_CLK_STEP_M)
|
||||
break;
|
||||
|
||||
baudrate = ar933x_serial_get_baud(clk, tscale, tstep);
|
||||
diff = abs(baudrate - baud);
|
||||
if (diff < min_diff) {
|
||||
min_diff = diff;
|
||||
*scale = tscale;
|
||||
*step = tstep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int ar933x_serial_setbrg(struct udevice *dev, int baudrate)
|
||||
{
|
||||
struct ar933x_serial_priv *priv = dev_get_priv(dev);
|
||||
u32 val, scale, step;
|
||||
|
||||
val = get_serial_clock();
|
||||
ar933x_serial_get_scale_step(val, baudrate, &scale, &step);
|
||||
|
||||
val = (scale & AR933X_UART_CLK_SCALE_M)
|
||||
<< AR933X_UART_CLK_SCALE_S;
|
||||
val |= (step & AR933X_UART_CLK_STEP_M)
|
||||
<< AR933X_UART_CLK_STEP_S;
|
||||
writel(val, priv->regs + AR933X_UART_CLK_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar933x_serial_putc(struct udevice *dev, const char c)
|
||||
{
|
||||
struct ar933x_serial_priv *priv = dev_get_priv(dev);
|
||||
u32 data;
|
||||
|
||||
data = readl(priv->regs + AR933X_UART_DATA_REG);
|
||||
if (!(data & AR933X_UART_DATA_TX_CSR))
|
||||
return -EAGAIN;
|
||||
|
||||
data = (u32)c | AR933X_UART_DATA_TX_CSR;
|
||||
writel(data, priv->regs + AR933X_UART_DATA_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar933x_serial_getc(struct udevice *dev)
|
||||
{
|
||||
struct ar933x_serial_priv *priv = dev_get_priv(dev);
|
||||
u32 data;
|
||||
|
||||
data = readl(priv->regs + AR933X_UART_DATA_REG);
|
||||
if (!(data & AR933X_UART_DATA_RX_CSR))
|
||||
return -EAGAIN;
|
||||
|
||||
writel(AR933X_UART_DATA_RX_CSR, priv->regs + AR933X_UART_DATA_REG);
|
||||
return data & AR933X_UART_DATA_TX_RX_MASK;
|
||||
}
|
||||
|
||||
static int ar933x_serial_pending(struct udevice *dev, bool input)
|
||||
{
|
||||
struct ar933x_serial_priv *priv = dev_get_priv(dev);
|
||||
u32 data;
|
||||
|
||||
data = readl(priv->regs + AR933X_UART_DATA_REG);
|
||||
if (input)
|
||||
return (data & AR933X_UART_DATA_RX_CSR) ? 1 : 0;
|
||||
else
|
||||
return (data & AR933X_UART_DATA_TX_CSR) ? 0 : 1;
|
||||
}
|
||||
|
||||
static int ar933x_serial_probe(struct udevice *dev)
|
||||
{
|
||||
struct ar933x_serial_priv *priv = dev_get_priv(dev);
|
||||
fdt_addr_t addr;
|
||||
u32 val;
|
||||
|
||||
addr = dev_get_addr(dev);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->regs = map_physmem(addr, AR933X_UART_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
/*
|
||||
* UART controller configuration:
|
||||
* - no DMA
|
||||
* - no interrupt
|
||||
* - DCE mode
|
||||
* - no flow control
|
||||
* - set RX ready oride
|
||||
* - set TX ready oride
|
||||
*/
|
||||
val = (AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S) |
|
||||
AR933X_UART_CS_TX_RDY_ORIDE | AR933X_UART_CS_RX_RDY_ORIDE;
|
||||
writel(val, priv->regs + AR933X_UART_CS_REG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_serial_ops ar933x_serial_ops = {
|
||||
.putc = ar933x_serial_putc,
|
||||
.pending = ar933x_serial_pending,
|
||||
.getc = ar933x_serial_getc,
|
||||
.setbrg = ar933x_serial_setbrg,
|
||||
};
|
||||
|
||||
static const struct udevice_id ar933x_serial_ids[] = {
|
||||
{ .compatible = "qca,ar9330-uart" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(serial_ar933x) = {
|
||||
.name = "serial_ar933x",
|
||||
.id = UCLASS_SERIAL,
|
||||
.of_match = ar933x_serial_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct ar933x_serial_priv),
|
||||
.probe = ar933x_serial_probe,
|
||||
.ops = &ar933x_serial_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DEBUG_UART_AR933X
|
||||
|
||||
#include <debug_uart.h>
|
||||
|
||||
static inline void _debug_uart_init(void)
|
||||
{
|
||||
void __iomem *regs = (void *)CONFIG_DEBUG_UART_BASE;
|
||||
u32 val, scale, step;
|
||||
|
||||
/*
|
||||
* UART controller configuration:
|
||||
* - no DMA
|
||||
* - no interrupt
|
||||
* - DCE mode
|
||||
* - no flow control
|
||||
* - set RX ready oride
|
||||
* - set TX ready oride
|
||||
*/
|
||||
val = (AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S) |
|
||||
AR933X_UART_CS_TX_RDY_ORIDE | AR933X_UART_CS_RX_RDY_ORIDE;
|
||||
writel(val, regs + AR933X_UART_CS_REG);
|
||||
|
||||
ar933x_serial_get_scale_step(CONFIG_DEBUG_UART_CLOCK,
|
||||
CONFIG_BAUDRATE, &scale, &step);
|
||||
|
||||
val = (scale & AR933X_UART_CLK_SCALE_M)
|
||||
<< AR933X_UART_CLK_SCALE_S;
|
||||
val |= (step & AR933X_UART_CLK_STEP_M)
|
||||
<< AR933X_UART_CLK_STEP_S;
|
||||
writel(val, regs + AR933X_UART_CLK_REG);
|
||||
}
|
||||
|
||||
static inline void _debug_uart_putc(int c)
|
||||
{
|
||||
void __iomem *regs = (void *)CONFIG_DEBUG_UART_BASE;
|
||||
u32 data;
|
||||
|
||||
do {
|
||||
data = readl(regs + AR933X_UART_DATA_REG);
|
||||
} while (!(data & AR933X_UART_DATA_TX_CSR));
|
||||
|
||||
data = (u32)c | AR933X_UART_DATA_TX_CSR;
|
||||
writel(data, regs + AR933X_UART_DATA_REG);
|
||||
}
|
||||
|
||||
DEBUG_UART_FUNCS
|
||||
|
||||
#endif
|
@ -23,6 +23,15 @@ config ALTERA_SPI
|
||||
IP core. Please find details on the "Embedded Peripherals IP
|
||||
User Guide" of Altera.
|
||||
|
||||
config ATH79_SPI
|
||||
bool "Atheros SPI driver"
|
||||
depends on ARCH_ATH79
|
||||
help
|
||||
Enable the Atheros ar7xxx/ar9xxx SoC SPI driver, it was used
|
||||
to access SPI NOR flash and other SPI peripherals. This driver
|
||||
uses driver model and requires a device tree binding to operate.
|
||||
please refer to doc/device-tree-bindings/spi/spi-ath79.txt.
|
||||
|
||||
config CADENCE_QSPI
|
||||
bool "Cadence QSPI driver"
|
||||
help
|
||||
|
@ -17,6 +17,7 @@ endif
|
||||
|
||||
obj-$(CONFIG_ALTERA_SPI) += altera_spi.o
|
||||
obj-$(CONFIG_ARMADA100_SPI) += armada100_spi.o
|
||||
obj-$(CONFIG_ATH79_SPI) += ath79_spi.o
|
||||
obj-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
|
||||
obj-$(CONFIG_ATMEL_SPI) += atmel_spi.o
|
||||
obj-$(CONFIG_BFIN_SPI) += bfin_spi.o
|
||||
|
228
drivers/spi/ath79_spi.c
Normal file
228
drivers/spi/ath79_spi.c
Normal file
@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <spi.h>
|
||||
#include <dm.h>
|
||||
#include <div64.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm/types.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <mach/ar71xx_regs.h>
|
||||
|
||||
/* CLOCK_DIVIDER = 3 (SPI clock = 200 / 8 ~ 25 MHz) */
|
||||
#define ATH79_SPI_CLK_DIV(x) (((x) >> 1) - 1)
|
||||
#define ATH79_SPI_RRW_DELAY_FACTOR 12000
|
||||
#define ATH79_SPI_MHZ (1000 * 1000)
|
||||
|
||||
struct ath79_spi_priv {
|
||||
void __iomem *regs;
|
||||
u32 rrw_delay;
|
||||
};
|
||||
|
||||
static void spi_cs_activate(struct udevice *dev)
|
||||
{
|
||||
struct udevice *bus = dev_get_parent(dev);
|
||||
struct ath79_spi_priv *priv = dev_get_priv(bus);
|
||||
|
||||
writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
|
||||
writel(AR71XX_SPI_IOC_CS_ALL, priv->regs + AR71XX_SPI_REG_IOC);
|
||||
}
|
||||
|
||||
static void spi_cs_deactivate(struct udevice *dev)
|
||||
{
|
||||
struct udevice *bus = dev_get_parent(dev);
|
||||
struct ath79_spi_priv *priv = dev_get_priv(bus);
|
||||
|
||||
writel(AR71XX_SPI_IOC_CS_ALL, priv->regs + AR71XX_SPI_REG_IOC);
|
||||
writel(0, priv->regs + AR71XX_SPI_REG_FS);
|
||||
}
|
||||
|
||||
static int ath79_spi_claim_bus(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath79_spi_release_bus(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath79_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||
const void *dout, void *din, unsigned long flags)
|
||||
{
|
||||
struct udevice *bus = dev_get_parent(dev);
|
||||
struct ath79_spi_priv *priv = dev_get_priv(bus);
|
||||
struct dm_spi_slave_platdata *slave = dev_get_parent_platdata(dev);
|
||||
u8 *rx = din;
|
||||
const u8 *tx = dout;
|
||||
u8 curbyte, curbitlen, restbits;
|
||||
u32 bytes = bitlen / 8;
|
||||
u32 out, in;
|
||||
u64 tick;
|
||||
|
||||
if (flags & SPI_XFER_BEGIN)
|
||||
spi_cs_activate(dev);
|
||||
|
||||
restbits = (bitlen % 8);
|
||||
if (restbits)
|
||||
bytes++;
|
||||
|
||||
out = AR71XX_SPI_IOC_CS_ALL & ~(AR71XX_SPI_IOC_CS(slave->cs));
|
||||
while (bytes > 0) {
|
||||
bytes--;
|
||||
curbyte = 0;
|
||||
if (tx)
|
||||
curbyte = *tx++;
|
||||
|
||||
if (restbits && !bytes) {
|
||||
curbitlen = restbits;
|
||||
curbyte <<= 8 - restbits;
|
||||
} else {
|
||||
curbitlen = 8;
|
||||
}
|
||||
|
||||
for (curbyte <<= (8 - curbitlen); curbitlen; curbitlen--) {
|
||||
if (curbyte & 0x80)
|
||||
out |= AR71XX_SPI_IOC_DO;
|
||||
else
|
||||
out &= ~(AR71XX_SPI_IOC_DO);
|
||||
|
||||
writel(out, priv->regs + AR71XX_SPI_REG_IOC);
|
||||
|
||||
/* delay for low level */
|
||||
if (priv->rrw_delay) {
|
||||
tick = get_ticks() + priv->rrw_delay;
|
||||
while (get_ticks() < tick)
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
writel(out | AR71XX_SPI_IOC_CLK,
|
||||
priv->regs + AR71XX_SPI_REG_IOC);
|
||||
|
||||
/* delay for high level */
|
||||
if (priv->rrw_delay) {
|
||||
tick = get_ticks() + priv->rrw_delay;
|
||||
while (get_ticks() < tick)
|
||||
/*NOP*/;
|
||||
}
|
||||
|
||||
curbyte <<= 1;
|
||||
}
|
||||
|
||||
if (!bytes)
|
||||
writel(out, priv->regs + AR71XX_SPI_REG_IOC);
|
||||
|
||||
in = readl(priv->regs + AR71XX_SPI_REG_RDS);
|
||||
if (rx) {
|
||||
if (restbits && !bytes)
|
||||
*rx++ = (in << (8 - restbits));
|
||||
else
|
||||
*rx++ = in;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & SPI_XFER_END)
|
||||
spi_cs_deactivate(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ath79_spi_set_speed(struct udevice *bus, uint speed)
|
||||
{
|
||||
struct ath79_spi_priv *priv = dev_get_priv(bus);
|
||||
u32 val, div = 0;
|
||||
u64 time;
|
||||
|
||||
if (speed)
|
||||
div = get_bus_freq(0) / speed;
|
||||
|
||||
if (div > 63)
|
||||
div = 63;
|
||||
|
||||
if (div < 5)
|
||||
div = 5;
|
||||
|
||||
/* calculate delay */
|
||||
time = get_tbclk();
|
||||
do_div(time, speed / 2);
|
||||
val = get_bus_freq(0) / ATH79_SPI_MHZ;
|
||||
val = ATH79_SPI_RRW_DELAY_FACTOR / val;
|
||||
if (time > val)
|
||||
priv->rrw_delay = time - val + 1;
|
||||
else
|
||||
priv->rrw_delay = 0;
|
||||
|
||||
writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
|
||||
clrsetbits_be32(priv->regs + AR71XX_SPI_REG_CTRL,
|
||||
AR71XX_SPI_CTRL_DIV_MASK,
|
||||
ATH79_SPI_CLK_DIV(div));
|
||||
writel(0, priv->regs + AR71XX_SPI_REG_FS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath79_spi_set_mode(struct udevice *bus, uint mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath79_spi_probe(struct udevice *bus)
|
||||
{
|
||||
struct ath79_spi_priv *priv = dev_get_priv(bus);
|
||||
fdt_addr_t addr;
|
||||
|
||||
addr = dev_get_addr(bus);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->regs = map_physmem(addr,
|
||||
AR71XX_SPI_SIZE,
|
||||
MAP_NOCACHE);
|
||||
|
||||
/* Init SPI Hardware, disable remap, set clock */
|
||||
writel(AR71XX_SPI_FS_GPIO, priv->regs + AR71XX_SPI_REG_FS);
|
||||
writel(AR71XX_SPI_CTRL_RD | ATH79_SPI_CLK_DIV(8),
|
||||
priv->regs + AR71XX_SPI_REG_CTRL);
|
||||
writel(0, priv->regs + AR71XX_SPI_REG_FS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath79_cs_info(struct udevice *bus, uint cs,
|
||||
struct spi_cs_info *info)
|
||||
{
|
||||
/* Always allow activity on CS 0/1/2 */
|
||||
if (cs >= 3)
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_spi_ops ath79_spi_ops = {
|
||||
.claim_bus = ath79_spi_claim_bus,
|
||||
.release_bus = ath79_spi_release_bus,
|
||||
.xfer = ath79_spi_xfer,
|
||||
.set_speed = ath79_spi_set_speed,
|
||||
.set_mode = ath79_spi_set_mode,
|
||||
.cs_info = ath79_cs_info,
|
||||
};
|
||||
|
||||
static const struct udevice_id ath79_spi_ids[] = {
|
||||
{ .compatible = "qca,ar7100-spi" },
|
||||
{}
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(ath79_spi) = {
|
||||
.name = "ath79_spi",
|
||||
.id = UCLASS_SPI,
|
||||
.of_match = ath79_spi_ids,
|
||||
.ops = &ath79_spi_ops,
|
||||
.priv_auto_alloc_size = sizeof(struct ath79_spi_priv),
|
||||
.probe = ath79_spi_probe,
|
||||
};
|
@ -11,8 +11,12 @@ ifeq ($(ARCH),arm)
|
||||
LOAD_ADDR = 0x1000000
|
||||
endif
|
||||
ifeq ($(ARCH),mips)
|
||||
ifdef CONFIG_64BIT
|
||||
LOAD_ADDR = 0xffffffff80200000
|
||||
else
|
||||
LOAD_ADDR = 0x80200000
|
||||
endif
|
||||
endif
|
||||
|
||||
# Resulting ELF and binary exectuables will be named demo and demo.bin
|
||||
extra-y = demo
|
||||
|
@ -41,28 +41,29 @@ syscall:
|
||||
ldr pc, [ip]
|
||||
|
||||
#elif defined(CONFIG_MIPS)
|
||||
#include <asm/asm.h>
|
||||
.text
|
||||
.globl __start
|
||||
.ent __start
|
||||
__start:
|
||||
sw $sp, search_hint
|
||||
PTR_S $sp, search_hint
|
||||
b main
|
||||
.end __start
|
||||
|
||||
.globl syscall
|
||||
.ent syscall
|
||||
syscall:
|
||||
sw $ra, return_addr
|
||||
lw $t9, syscall_ptr
|
||||
PTR_S $ra, return_addr
|
||||
PTR_L $t9, syscall_ptr
|
||||
jalr $t9
|
||||
nop
|
||||
lw $ra, return_addr
|
||||
PTR_L $ra, return_addr
|
||||
jr $ra
|
||||
nop
|
||||
.end syscall
|
||||
|
||||
return_addr:
|
||||
.align 4
|
||||
.align 8
|
||||
.long 0
|
||||
#else
|
||||
#error No support for this arch!
|
||||
@ -70,7 +71,7 @@ return_addr:
|
||||
|
||||
.globl syscall_ptr
|
||||
syscall_ptr:
|
||||
.align 4
|
||||
.align 8
|
||||
.long 0
|
||||
|
||||
.globl search_hint
|
||||
|
@ -77,7 +77,7 @@ int ub_getc(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (!syscall(API_GETC, NULL, (uint32_t)&c))
|
||||
if (!syscall(API_GETC, NULL, &c))
|
||||
return -1;
|
||||
|
||||
return c;
|
||||
@ -87,7 +87,7 @@ int ub_tstc(void)
|
||||
{
|
||||
int t;
|
||||
|
||||
if (!syscall(API_TSTC, NULL, (uint32_t)&t))
|
||||
if (!syscall(API_TSTC, NULL, &t))
|
||||
return -1;
|
||||
|
||||
return t;
|
||||
@ -95,12 +95,12 @@ int ub_tstc(void)
|
||||
|
||||
void ub_putc(char c)
|
||||
{
|
||||
syscall(API_PUTC, NULL, (uint32_t)&c);
|
||||
syscall(API_PUTC, NULL, &c);
|
||||
}
|
||||
|
||||
void ub_puts(const char *s)
|
||||
{
|
||||
syscall(API_PUTS, NULL, (uint32_t)s);
|
||||
syscall(API_PUTS, NULL, s);
|
||||
}
|
||||
|
||||
/****************************************
|
||||
@ -126,7 +126,7 @@ struct sys_info * ub_get_sys_info(void)
|
||||
si.mr_no = UB_MAX_MR;
|
||||
memset(&mr, 0, sizeof(mr));
|
||||
|
||||
if (!syscall(API_GET_SYS_INFO, &err, (u_int32_t)&si))
|
||||
if (!syscall(API_GET_SYS_INFO, &err, &si))
|
||||
return NULL;
|
||||
|
||||
return ((err) ? NULL : &si);
|
||||
@ -344,7 +344,7 @@ char * ub_env_get(const char *name)
|
||||
{
|
||||
char *value;
|
||||
|
||||
if (!syscall(API_ENV_GET, NULL, (uint32_t)name, (uint32_t)&value))
|
||||
if (!syscall(API_ENV_GET, NULL, name, &value))
|
||||
return NULL;
|
||||
|
||||
return value;
|
||||
@ -352,7 +352,7 @@ char * ub_env_get(const char *name)
|
||||
|
||||
void ub_env_set(const char *name, char *value)
|
||||
{
|
||||
syscall(API_ENV_SET, NULL, (uint32_t)name, (uint32_t)value);
|
||||
syscall(API_ENV_SET, NULL, name, value);
|
||||
}
|
||||
|
||||
static char env_name[256];
|
||||
@ -369,7 +369,7 @@ const char * ub_env_enum(const char *last)
|
||||
* 'name=val' string), since the API_ENUM_ENV call uses envmatch()
|
||||
* internally, which handles such case
|
||||
*/
|
||||
if (!syscall(API_ENV_ENUM, NULL, (uint32_t)last, (uint32_t)&env))
|
||||
if (!syscall(API_ENV_ENUM, NULL, last, &env))
|
||||
return NULL;
|
||||
|
||||
if (!env)
|
||||
@ -396,7 +396,7 @@ int ub_display_get_info(int type, struct display_info *di)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!syscall(API_DISPLAY_GET_INFO, &err, (uint32_t)type, (uint32_t)di))
|
||||
if (!syscall(API_DISPLAY_GET_INFO, &err, type, di))
|
||||
return API_ESYSC;
|
||||
|
||||
return err;
|
||||
|
@ -65,6 +65,23 @@ gd_t *global_data;
|
||||
: : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "ip");
|
||||
#endif
|
||||
#elif defined(CONFIG_MIPS)
|
||||
#ifdef CONFIG_CPU_MIPS64
|
||||
/*
|
||||
* k0 ($26) holds the pointer to the global_data; t9 ($25) is a call-
|
||||
* clobbered register that is also used to set gp ($26). Note that the
|
||||
* jr instruction also executes the instruction immediately following
|
||||
* it; however, GCC/mips generates an additional `nop' after each asm
|
||||
* statement
|
||||
*/
|
||||
#define EXPORT_FUNC(f, a, x, ...) \
|
||||
asm volatile ( \
|
||||
" .globl " #x "\n" \
|
||||
#x ":\n" \
|
||||
" ld $25, %0($26)\n" \
|
||||
" ld $25, %1($25)\n" \
|
||||
" jr $25\n" \
|
||||
: : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9");
|
||||
#else
|
||||
/*
|
||||
* k0 ($26) holds the pointer to the global_data; t9 ($25) is a call-
|
||||
* clobbered register that is also used to set gp ($26). Note that the
|
||||
@ -80,6 +97,7 @@ gd_t *global_data;
|
||||
" lw $25, %1($25)\n" \
|
||||
" jr $25\n" \
|
||||
: : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9");
|
||||
#endif
|
||||
#elif defined(CONFIG_NIOS2)
|
||||
/*
|
||||
* gp holds the pointer to the global_data, r8 is call-clobbered
|
||||
|
@ -126,7 +126,7 @@
|
||||
|
||||
#define ATA_BLOCKSIZE 512 /* bytes */
|
||||
#define ATA_BLOCKSHIFT 9 /* 2 ^ ATA_BLOCKSIZESHIFT = 512 */
|
||||
#define ATA_SECTORWORDS (512 / sizeof(unsigned long))
|
||||
#define ATA_SECTORWORDS (512 / sizeof(uint32_t))
|
||||
|
||||
#ifndef ATA_RESET_TIME
|
||||
#define ATA_RESET_TIME 60 /* spec allows up to 31 seconds */
|
||||
|
86
include/configs/ap121.h
Normal file
86
include/configs/ap121.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#define CONFIG_SYS_TEXT_BASE 0x9f000000
|
||||
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
#define CONFIG_DISPLAY_BOARDINFO
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
#define CONFIG_SYS_HZ 1000
|
||||
#define CONFIG_SYS_MHZ 200
|
||||
#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000)
|
||||
|
||||
/* Cache Configuration */
|
||||
#define CONFIG_SYS_DCACHE_SIZE 0x8000
|
||||
#define CONFIG_SYS_ICACHE_SIZE 0x10000
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||
|
||||
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
|
||||
|
||||
#define CONFIG_SYS_MALLOC_LEN 0x40000
|
||||
#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x80000000
|
||||
#define CONFIG_SYS_LOAD_ADDR 0x81000000
|
||||
|
||||
#define CONFIG_SYS_NO_FLASH
|
||||
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0xbd000000
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE 0x8000
|
||||
#define CONFIG_SYS_INIT_SP_ADDR \
|
||||
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - 1)
|
||||
|
||||
#define CONFIG_BAUDRATE 115200
|
||||
#define CONFIG_SYS_BAUDRATE_TABLE \
|
||||
{9600, 19200, 38400, 57600, 115200}
|
||||
|
||||
#define CONFIG_BOOTDELAY 3
|
||||
#define CONFIG_BOOTARGS "console=ttyS0,115200 " \
|
||||
"root=/dev/mtdblock2 " \
|
||||
"rootfstype=squashfs"
|
||||
#define CONFIG_BOOTCOMMAND "sf probe;" \
|
||||
"mtdparts default;" \
|
||||
"bootm 0x9f300000"
|
||||
#define CONFIG_LZMA
|
||||
|
||||
#define MTDIDS_DEFAULT "nor0=spi-flash.0"
|
||||
#define MTDPARTS_DEFAULT "mtdparts=spi-flash.0:" \
|
||||
"256k(u-boot),64k(u-boot-env)," \
|
||||
"2752k(rootfs),896k(uImage)," \
|
||||
"64k(NVRAM),64k(ART)"
|
||||
|
||||
#define CONFIG_ENV_SPI_MAX_HZ 25000000
|
||||
#define CONFIG_ENV_IS_IN_SPI_FLASH
|
||||
#define CONFIG_ENV_OFFSET 0x40000
|
||||
#define CONFIG_ENV_SECT_SIZE 0x10000
|
||||
#define CONFIG_ENV_SIZE 0x10000
|
||||
|
||||
/*
|
||||
* Command
|
||||
*/
|
||||
#define CONFIG_CMD_MTDPARTS
|
||||
|
||||
/* Miscellaneous configurable options */
|
||||
#define CONFIG_SYS_CBSIZE 256
|
||||
#define CONFIG_SYS_MAXARGS 16
|
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
|
||||
sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
#define CONFIG_SYS_LONGHELP
|
||||
#define CONFIG_CMDLINE_EDITING
|
||||
#define CONFIG_AUTO_COMPLETE
|
||||
|
||||
/*
|
||||
* Diagnostics
|
||||
*/
|
||||
#define CONFIG_SYS_MEMTEST_START 0x80100000
|
||||
#define CONFIG_SYS_MEMTEST_END 0x83f00000
|
||||
#define CONFIG_CMD_MEMTEST
|
||||
|
||||
#endif /* __CONFIG_H */
|
90
include/configs/ap143.h
Normal file
90
include/configs/ap143.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2016 Wills Wang <wills.wang@live.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#define CONFIG_SYS_TEXT_BASE 0x9f000000
|
||||
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
#define CONFIG_DISPLAY_BOARDINFO
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
#define CONFIG_SYS_HZ 1000
|
||||
#define CONFIG_SYS_MHZ 325
|
||||
#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000)
|
||||
|
||||
/* Cache Configuration */
|
||||
#define CONFIG_SYS_DCACHE_SIZE 0x8000
|
||||
#define CONFIG_SYS_ICACHE_SIZE 0x10000
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||
|
||||
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
|
||||
|
||||
#define CONFIG_SYS_MALLOC_LEN 0x40000
|
||||
#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0x80000000
|
||||
#define CONFIG_SYS_LOAD_ADDR 0x81000000
|
||||
|
||||
#define CONFIG_SYS_NO_FLASH
|
||||
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0xbd000000
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE 0x2000
|
||||
#define CONFIG_SYS_INIT_SP_ADDR \
|
||||
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE - 1)
|
||||
|
||||
/*
|
||||
* Serial Port
|
||||
*/
|
||||
#define CONFIG_SYS_NS16550_CLK 25000000
|
||||
#define CONFIG_BAUDRATE 115200
|
||||
#define CONFIG_SYS_BAUDRATE_TABLE \
|
||||
{9600, 19200, 38400, 57600, 115200}
|
||||
|
||||
#define CONFIG_BOOTDELAY 3
|
||||
#define CONFIG_BOOTARGS "console=ttyS0,115200 " \
|
||||
"root=/dev/mtdblock2 " \
|
||||
"rootfstype=squashfs"
|
||||
#define CONFIG_BOOTCOMMAND "sf probe;" \
|
||||
"mtdparts default;" \
|
||||
"bootm 0x9f300000"
|
||||
#define CONFIG_LZMA
|
||||
|
||||
#define MTDIDS_DEFAULT "nor0=spi-flash.0"
|
||||
#define MTDPARTS_DEFAULT "mtdparts=spi-flash.0:" \
|
||||
"256k(u-boot),64k(u-boot-env)," \
|
||||
"2752k(rootfs),896k(uImage)," \
|
||||
"64k(NVRAM),64k(ART)"
|
||||
|
||||
#define CONFIG_ENV_SPI_MAX_HZ 25000000
|
||||
#define CONFIG_ENV_IS_IN_SPI_FLASH
|
||||
#define CONFIG_ENV_OFFSET 0x40000
|
||||
#define CONFIG_ENV_SECT_SIZE 0x10000
|
||||
#define CONFIG_ENV_SIZE 0x10000
|
||||
|
||||
/*
|
||||
* Command
|
||||
*/
|
||||
#define CONFIG_CMD_MTDPARTS
|
||||
|
||||
/* Miscellaneous configurable options */
|
||||
#define CONFIG_SYS_CBSIZE 256
|
||||
#define CONFIG_SYS_MAXARGS 16
|
||||
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
|
||||
sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||
#define CONFIG_SYS_LONGHELP
|
||||
#define CONFIG_CMDLINE_EDITING
|
||||
#define CONFIG_AUTO_COMPLETE
|
||||
|
||||
/*
|
||||
* Diagnostics
|
||||
*/
|
||||
#define CONFIG_SYS_MEMTEST_START 0x80100000
|
||||
#define CONFIG_SYS_MEMTEST_END 0x83f00000
|
||||
#define CONFIG_CMD_MEMTEST
|
||||
|
||||
#endif /* __CONFIG_H */
|
@ -58,6 +58,10 @@
|
||||
#define CONFIG_CMD_IDE
|
||||
#define CONFIG_DOS_PARTITION
|
||||
|
||||
#ifdef CONFIG_SYS_BIG_ENDIAN
|
||||
#define CONFIG_IDE_SWAP_IO
|
||||
#endif
|
||||
|
||||
#define CONFIG_SYS_IDE_MAXBUS 2
|
||||
#define CONFIG_SYS_ATA_IDE0_OFFSET 0x1f0
|
||||
#define CONFIG_SYS_ATA_IDE1_OFFSET 0x170
|
||||
|
@ -58,6 +58,10 @@
|
||||
#define CONFIG_CMD_IDE
|
||||
#define CONFIG_DOS_PARTITION
|
||||
|
||||
#ifdef CONFIG_SYS_BIG_ENDIAN
|
||||
#define CONFIG_IDE_SWAP_IO
|
||||
#endif
|
||||
|
||||
#define CONFIG_SYS_IDE_MAXBUS 2
|
||||
#define CONFIG_SYS_ATA_IDE0_OFFSET 0x1f0
|
||||
#define CONFIG_SYS_ATA_IDE1_OFFSET 0x170
|
||||
|
93
include/configs/tplink_wdr4300.h
Normal file
93
include/configs/tplink_wdr4300.h
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Marek Vasut <marex@denx.de>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#define CONFIG_SYS_TEXT_BASE 0xa1000000
|
||||
|
||||
#define CONFIG_DISPLAY_CPUINFO
|
||||
#define CONFIG_DISPLAY_BOARDINFO
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
#define CONFIG_SYS_HZ 1000
|
||||
#define CONFIG_SYS_MHZ 280
|
||||
#define CONFIG_SYS_MIPS_TIMER_FREQ (CONFIG_SYS_MHZ * 1000000)
|
||||
|
||||
/* Cache Configuration */
|
||||
#define CONFIG_SYS_DCACHE_SIZE 0x8000
|
||||
#define CONFIG_SYS_ICACHE_SIZE 0x10000
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||
|
||||
#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
|
||||
|
||||
#define CONFIG_SYS_MALLOC_LEN 0x40000
|
||||
#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000
|
||||
|
||||
#define CONFIG_SYS_SDRAM_BASE 0xa0000000
|
||||
#define CONFIG_SYS_LOAD_ADDR 0xa1000000
|
||||
#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR
|
||||
|
||||
#define CONFIG_SYS_NO_FLASH
|
||||
|
||||
#define CONFIG_SYS_INIT_RAM_ADDR 0xbd000000
|
||||
#define CONFIG_SYS_INIT_RAM_SIZE 0x8000
|
||||
#define CONFIG_SYS_INIT_SP_ADDR \
|
||||
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_RAM_SIZE)
|
||||
|
||||
/*
|
||||
* Serial Port
|
||||
*/
|
||||
#define CONFIG_SYS_NS16550_CLK 40000000
|
||||
#define CONFIG_BAUDRATE 115200
|
||||
#define CONFIG_SYS_BAUDRATE_TABLE \
|
||||
{9600, 19200, 38400, 57600, 115200}
|
||||
|
||||
#define CONFIG_BOOTDELAY 3
|
||||
#define CONFIG_BOOTARGS \
|
||||
"console=ttyS0,115200 root=/dev/mtdblock2 rootfstype=squashfs"
|
||||
#define CONFIG_BOOTCOMMAND \
|
||||
"dhcp 192.168.1.1:wdr4300.fit && bootm $loadaddr"
|
||||
#define CONFIG_LZMA
|
||||
|
||||
#define CONFIG_ENV_IS_NOWHERE
|
||||
#define CONFIG_ENV_SIZE 0x10000
|
||||
|
||||
/*
|
||||
* Command
|
||||
*/
|
||||
/* Miscellaneous configurable options */
|
||||
#define CONFIG_SYS_LONGHELP
|
||||
#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
|
||||
#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */
|
||||
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
|
||||
/* Boot argument buffer size */
|
||||
#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
|
||||
#define CONFIG_AUTO_COMPLETE /* Command auto complete */
|
||||
#define CONFIG_CMDLINE_EDITING /* Command history etc */
|
||||
#define CONFIG_SYS_HUSH_PARSER
|
||||
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
|
||||
|
||||
/* USB, USB storage, USB ethernet */
|
||||
#define CONFIG_EHCI_MMIO_BIG_ENDIAN
|
||||
#define CONFIG_EHCI_DESC_BIG_ENDIAN
|
||||
#define CONFIG_EHCI_IS_TDI
|
||||
|
||||
#define CONFIG_DOS_PARTITION
|
||||
|
||||
/*
|
||||
* Diagnostics
|
||||
*/
|
||||
#define CONFIG_SYS_MEMTEST_START 0x80100000
|
||||
#define CONFIG_SYS_MEMTEST_END 0x83f00000
|
||||
#define CONFIG_CMD_MEMTEST
|
||||
|
||||
#define CONFIG_USE_PRIVATE_LIBGCC
|
||||
|
||||
#define CONFIG_CMD_MII
|
||||
#define CONFIG_PHY_GIGE
|
||||
|
||||
#endif /* __CONFIG_H */
|
@ -400,6 +400,9 @@ extern flash_info_t *flash_get_info(ulong base);
|
||||
#define FLASH_STM800DT 0x00D7 /* STM M29W800DT (1M = 64K x 16, top) */
|
||||
#define FLASH_STM800DB 0x005B /* STM M29W800DB (1M = 64K x 16, bottom)*/
|
||||
|
||||
#define FLASH_MCHP100T 0x0060 /* MCHP internal (1M = 64K x 16) */
|
||||
#define FLASH_MCHP100B 0x0061 /* MCHP internal (1M = 64K x 16) */
|
||||
|
||||
#define FLASH_28F400_T 0x0062 /* MT 28F400B3 ID ( 4M = 256K x 16 ) */
|
||||
#define FLASH_28F400_B 0x0063 /* MT 28F400B3 ID ( 4M = 256K x 16 ) */
|
||||
|
||||
@ -486,7 +489,7 @@ extern flash_info_t *flash_get_info(ulong base);
|
||||
#define FLASH_MAN_SHARP 0x00500000
|
||||
#define FLASH_MAN_ATM 0x00600000
|
||||
#define FLASH_MAN_CFI 0x01000000
|
||||
|
||||
#define FLASH_MAN_MCHP 0x02000000 /* Microchip Technology */
|
||||
|
||||
#define FLASH_TYPEMASK 0x0000FFFF /* extract FLASH type information */
|
||||
#define FLASH_VENDMASK 0xFFFF0000 /* extract FLASH vendor information */
|
||||
|
Loading…
Reference in New Issue
Block a user