Merge "MIPS: qca956x: initial changes for the AP152 target" into eggplant

This commit is contained in:
Linux Build Service Account 2016-11-17 01:33:00 -08:00 committed by Gerrit - the friendly Code Review server
commit 8c46bb2ecf
18 changed files with 7028 additions and 1 deletions

View file

@ -44,6 +44,12 @@ config TARGET_DBAU1X00
select SUPPORTS_CPU_MIPS32_R2
select SYS_MIPS_CACHE_INIT_RAM_LOAD
config TARGET_QCA956X
bool "Support QCA956X"
select SUPPORTS_BIG_ENDIAN
select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2
config TARGET_PB1X00
bool "Support pb1x00"
select SUPPORTS_LITTLE_ENDIAN
@ -59,6 +65,7 @@ source "board/imgtec/malta/Kconfig"
source "board/micronas/vct/Kconfig"
source "board/pb1x00/Kconfig"
source "board/qemu-mips/Kconfig"
source "board/qca/mips32/qca956x/Kconfig"
if MIPS

View file

@ -11,6 +11,14 @@
#include <asm/asm.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#ifdef CONFIG_ATH_SOC
# include <atheros.h>
#include <asm/addrspace.h>
#else
# include <ar7240_soc.h>
# define ATH_SPI_CLOCK 0xbf000004
#endif
#ifndef CONFIG_SYS_MIPS_CACHE_MODE
#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
@ -59,6 +67,9 @@
.globl _start
.text
_start:
#if defined(CONFIG_ATH_SOC)
#ifndef COMPRESSED_UBOOT
#if !defined(CONFIG_MACH_QCA956x)
/* U-boot entry point */
b reset
nop
@ -112,8 +123,105 @@ _start:
1: b 1b
nop
#endif
.align 4
reset:
#if !defined(CONFIG_ATH_NAND_BR)
/*
* Clearing CP0 registers - This is generally required for the MIPS-24k
* core used by Atheros.
*/
mtc0 zero, $0
mtc0 zero, $1
mtc0 zero, $2
mtc0 zero, $3
mtc0 zero, $4
mtc0 zero, $5
mtc0 zero, $6
mtc0 zero, $7
mtc0 zero, $8
mtc0 zero, $9
mtc0 zero, $10
mtc0 zero, $11
li t0, 0x10000004
mtc0 t0, $12
mtc0 zero, $13
mtc0 zero, $14
mtc0 zero, $15
mtc0 zero, $16
#if defined(CONFIG_MACH_QCA955x)
/*
* Workaround recommnded by MIPS for the Scorpion Freeze issue
*/
#define CONFIG_SCO_JRCD 1
#define CONFIG_SCO_IAGN !CONFIG_SCO_JRCD
#if CONFIG_SCO_IAGN && CONFIG_SCO_JRCD
#error Both CONFIG_SCO_IAGN and CONFIG_SCO_JRCD set
#endif
#if CONFIG_SCO_JRCD
/*
* JR Cache Prediction Disable. Disables JR target address prediction.
* Bit [0], CP0 Register 16, Select 6
* 0 - JR cache target address prediction is enabled.
* 1 - JR cache target address prediction is not enabled.
*/
mfc0 t0, $16, 6
li t1, (1 << 0)
or t0, t0, t1
mtc0 t0, $16, 6
#endif
#if CONFIG_SCO_IAGN
/*
* Bit [25], CP0 Register 16, Select 7
* Selective control of out-of-order behavior: issue ALU-side or
* load/store-side instructions (respectively) in program order.
*/
mfc0 t0, $16, 7
li t1, (1 << 25)
or t0, t0, t1
mtc0 t0, $16, 7
#endif
#endif /* CONFIG_MACH_QCA955x */
#define pref_on 0
#if pref_on
#define prefetch_val 3
mfc0 t0, $16, 7
li t1, ~(3 << 11)
and t0, t0, t1
li t1, (prefetch_val << 11)
or t0, t0, t1
mtc0 t0, $16, 7
#endif
#if !defined(CONFIG_WASP_SUPPORT)
mtc0 zero, $17
#endif
mtc0 zero, $18
mtc0 zero, $19
#if !defined(CONFIG_WASP_SUPPORT)
mtc0 zero, $20
mtc0 zero, $21
mtc0 zero, $22
#endif
#ifndef CONFIG_HORNET_EMU
mtc0 zero, $23
#endif
mtc0 zero, $24
mtc0 zero, $25
mtc0 zero, $26
mtc0 zero, $27
mtc0 zero, $28
#if defined(CONFIG_WASP_SUPPORT) || defined(CONFIG_MACH_QCA955x) || defined(CONFIG_MACH_QCA953x) || defined(CONFIG_MACH_QCA956x)
mtc0 zero, $29 # C0_TagHi
mtc0 zero, $28, 2 # C0_DTagLo
mtc0 zero, $29, 2 # C0_DTagHi
#endif
/* Clear watch registers */
MTC0 zero, CP0_WATCHLO
@ -134,6 +242,9 @@ reset:
mtc0 t0, CP0_CONFIG
#endif
#endif /* !defined(CONFIG_ATH_NAND_BR) */
#endif /* #ifndef COMPRESSED_UBOOT */
#endif /* defined(CONFIG_ATH_SOC) */
/*
* Initialize $gp, force pointer sized alignment of bal instruction to
* forbid the compiler to put nop's between bal and _gp. This is
@ -146,12 +257,86 @@ reset:
1:
PTR_L gp, 0(ra)
#if defined(CONFIG_ATH_SOC)
#if (defined(CONFIG_MACH_HORNET) && defined(CONFIG_HORNET_1_1_WAR)) || defined(CONFIG_MACH_QCA956x)
/**************************************************************************/
/*
* WAR: Hornet 1.1 currently need a reset once we boot to let the resetb has
* enough time to stable, so that trigger reset at 1st boot, system team
* is investigaing the issue, will remove in short
*/
do_reset_normal:
li t7, 0xbd000000
lw t8, 0(t7) // t8 : value of 0xb8050024
li t9, 0x12345678
sw t9, 0(t7)
bne t8, t9, do_reset // if 0xb8050024 == 0x19 , go to do_cpld
nop
b normal_path
do_reset:
li t7, 0xb806001c // load reset register 0x1806001c
lw t8, 0(t7)
li t9, 0x1000000 // bit24, fullchip reset
or t8, t8, t9 // t8: set bit 18
sw t8, 0(t7)
do_reset_loop:
b do_reset_loop
nop
normal_path:
#endif /* CONFIG_MACH_HORNET */
#endif /* CONFIG_ATH_SOC */
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
/* Initialize any external memory */
PTR_LA t9, lowlevel_init
jalr t9
nop
#if defined(CONFIG_ATH_SOC)
#if defined(CONFIG_MACH_HORNET)
la t9, hornet_ddr_init
jalr t9
nop
nop
#endif
la t0, rel_start
j t0
nop
rel_start:
#if defined(CONFIG_AR7100) || defined(CONFIG_AR7240) || defined(CONFIG_ATHEROS)
/* REMAP_DISABLE */
li a0, KSEG1ADDR(ATH_SPI_CLOCK)
#if defined(CONFIG_MACH_QCA955x) || defined(CONFIG_MACH_QCA953x) || defined(CONFIG_MACH_QCA956x)
li t0, 0x246
#elif defined(CONFIG_WASP_SUPPORT)
li t0, 0x243
#else
li t0, 0x43
#endif
sw t0, 0(a0)
#endif
#if defined(CONFIG_AR9100) && defined(CFG_HOWL_1_2)
/* Disable remap for parallel flash */
li t7, AR9100_FLASH_CONFIG;
lw t8, 0(t7);
li t9, 0xffbf0000;
and t8, t8, t9;
li t9, 0x22fc;
or t8, t8, t9;
li t9, 0xffcfffff; /* scale = 0 */
and t8, t8, t9;
sw t8, 0(t7);
#endif
#endif /* CONFIG_ATH_SOC */
/* Initialize caches... */
PTR_LA t9, mips_cache_reset
jalr t9
@ -164,7 +349,11 @@ reset:
/* Set up temporary stack */
PTR_LI t0, -16
PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
#if !defined( CONFIG_ATH_SOC)
PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
#else
PTR_LI t1, CFG_INIT_SRAM_SP_OFFSET
#endif
and sp, t1, t0 # force 16 byte alignment
PTR_SUB sp, sp, GD_SIZE # reserve space for gd
and sp, sp, t0 # force 16 byte alignment
@ -188,6 +377,10 @@ reset:
sw sp, 0(t0)
#endif
#if defined(CONFIG_MACH_QCA956x)
/* Initialize boot_flags to zero */
move a0, zero
#endif
PTR_LA t9, board_init_f
jr t9
move ra, zero

View file

@ -0,0 +1,191 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <config.h>
#include <version.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <atheros.h>
/*
* Helper macros.
* These Clobber t7, t8 and t9
*/
#define reg_write(_reg, _val) \
li t7, KSEG1ADDR(_reg); \
li t8, _val; \
sw t8, 0(t7);
#define reg_rmw_set(_reg, _mask, _val) \
li t7, KSEG1ADDR(_reg); \
lw t8, 0(t7); \
li t9, ~(_mask); \
and t8, t8, t9; \
li t9, _val; \
or t8, t8, t9; \
sw t8, 0(t7)
#define cpu_pll_set(_mask, _val) \
reg_rmw_set(CPU_PLL_CONFIG_ADDRESS, _mask, _val)
#define ddr_pll_set(_mask, _val) \
reg_rmw_set(DDR_PLL_CONFIG_ADDRESS, _mask, _val)
#define cpu_ddr_control_set(_mask, _val) \
reg_rmw_set(CPU_DDR_CLOCK_CONTROL_ADDRESS, _mask, _val)
/******************************************************************************
* first level initialization:
*
* 0) If clock cntrl reset switch is already set, we're recovering from
* "divider reset"; goto 3.
* 1) Setup divide ratios.
* 2) Reset.
* 3) Setup pll's, wait for lock.
*
*****************************************************************************/
.globl lowlevel_init
.type lowlevel_init, @function
.text
.align 4
lowlevel_init:
#if !defined(CONFIG_ATH_EMULATION)
#if !defined(CONFIG_ATH_NAND_BR)
reg_write(BB_DPLL2_ADDRESS, BB_DPLL2_KI_SET(2) | \
BB_DPLL2_KD_SET(0xa) | \
BB_DPLL2_OUTDIV_SET(1) | \
BB_DPLL2_PLL_PWD_SET(1) | \
BB_DPLL2_PHASE_SHIFT_SET(0x6));
reg_write(PCIe_DPLL2_ADDRESS, PCIe_DPLL2_KI_SET(2) | \
PCIe_DPLL2_KD_SET(0xa) | \
PCIe_DPLL2_PLL_PWD_SET(1) | \
PCIe_DPLL2_OUTDIV_SET(0x3) | \
PCIe_DPLL2_PHASE_SHIFT_SET(0x6));
reg_write(DDR_DPLL2_ADDRESS, DDR_DPLL2_KI_SET(2) | \
DDR_DPLL2_KD_SET(0xa) | \
DDR_DPLL2_PLL_PWD_SET(1) | \
DDR_DPLL2_PHASE_SHIFT_SET(0x6));
reg_write(CPU_DPLL2_ADDRESS, CPU_DPLL2_KI_SET(1) | \
CPU_DPLL2_KD_SET(0x7) | \
CPU_DPLL2_PLL_PWD_SET(1) | \
CPU_DPLL2_PHASE_SHIFT_SET(0x6));
li t5, CPU_PLL_CONFIG1_NINT_VAL
li t6, DDR_PLL_CONFIG1_NINT_VAL
li t4, CPU_PLL_DITHER1_VAL
li t3, DDR_PLL_DITHER1_VAL
li t7, PLL_CONFIG_VAL_F
lw t8, 0(t7)
li t7, PLL_MAGIC
beq t7, t8, read_from_flash
nop
j pll_bypass_set
nop
read_from_flash:
li t7, PLL_CONFIG_VAL_F + 4
lw t5, 0(t7)
lw t4, 4(t7)
lw t6, 8(t7)
lw t3, 12(t7)
pll_bypass_set:
cpu_ddr_control_set (CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK, CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1));
cpu_ddr_control_set (CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK, CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1));
cpu_ddr_control_set (CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK, CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1));
init_cpu_pll:
li t7, KSEG1ADDR(CPU_PLL_CONFIG_ADDRESS);
li t8, (CPU_PLL_CONFIG_PLLPWD_SET(1) | \
CPU_PLL_CONFIG_REF_DIV_VAL | \
CPU_PLL_CONFIG_RANGE_VAL | \
CPU_PLL_CONFIG_OUT_DIV_VAL1);
sw t8, 0(t7);
li t7, KSEG1ADDR(CPU_PLL_CONFIG1_ADDRESS);
sw t5, 0(t7);
init_ddr_pll:
li t7, KSEG1ADDR(DDR_PLL_CONFIG_ADDRESS);
li t8, (DDR_PLL_CONFIG_PLLPWD_SET(1) | \
DDR_PLL_CONFIG_REF_DIV_VAL | \
DDR_PLL_CONFIG_RANGE_VAL | \
DDR_PLL_CONFIG_OUT_DIV_VAL1);
sw t8, 0(t7);
li t7, KSEG1ADDR(DDR_PLL_CONFIG1_ADDRESS);
sw t6, 0(t7);
init_ahb_pll:
reg_write(CPU_DDR_CLOCK_CONTROL_ADDRESS,
CPU_DDR_CLOCK_CONTROL_AHB_DIV_VAL |
AHB_CLK_FROM_DDR |
CPU_AND_DDR_CLK_FROM_DDR |
CPU_AND_DDR_CLK_FROM_CPU |
CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV |
CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV |
CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(1) |
CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(1) |
CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(1));
ddr_pll_dither_unset:
li t7, KSEG1ADDR(DDR_PLL_DITHER1_ADDRESS);
sw t3, 0(t7);
li t7, KSEG1ADDR(DDR_PLL_DITHER2_ADDRESS);
li t8, DDR_PLL_DITHER2_VAL
sw t8, 0(t7);
cpu_pll_dither_unset:
li t7, KSEG1ADDR(CPU_PLL_DITHER1_ADDRESS);
sw t4, 0(t7);
li t7, KSEG1ADDR(CPU_PLL_DITHER2_ADDRESS);
li t8, CPU_PLL_DITHER2_VAL
sw t8, 0(t7);
pll_pwd_unset:
cpu_pll_set(CPU_PLL_CONFIG_PLLPWD_MASK, CPU_PLL_CONFIG_PLLPWD_SET(0));
ddr_pll_set(DDR_PLL_CONFIG_PLLPWD_MASK, DDR_PLL_CONFIG_PLLPWD_SET(0));
outdiv_unset:
cpu_pll_set(CPU_PLL_CONFIG_OUTDIV_MASK, CPU_PLL_CONFIG_OUT_DIV_VAL2);
ddr_pll_set(DDR_PLL_CONFIG_OUTDIV_MASK, DDR_PLL_CONFIG_OUT_DIV_VAL2);
pll_bypass_unset:
cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_MASK, CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_SET(0));
cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_MASK, CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_SET(0));
cpu_ddr_control_set(CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_MASK, CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_SET(0));
check_cpu_pll_locked:
li t7, KSEG1ADDR(CPU_PLL_CONFIG_ADDRESS);
lw t8, 0(t7);
li t9, 0x8000000;
and t8, t8, t9;
bne zero, t8, check_cpu_pll_locked;
check_ddr_pll_locked:
li t7, KSEG1ADDR(DDR_PLL_CONFIG_ADDRESS);
lw t8, 0(t7);
li t9, 0x8000000;
and t8, t8, t9;
bne zero, t8, check_ddr_pll_locked;
#endif /* !defined(CONFIG_ATH_NAND_BR) */
#endif /* !defined(CONFIG_ATH_EMULATION) */
jr ra
nop

View file

@ -0,0 +1,243 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <asm/addrspace.h>
#include <asm/types.h>
#include <config.h>
#include <atheros.h>
#include <serial.h>
int qca_serial_init(void)
{
//#if !defined(CONFIG_ATH_EMULATION)
uint32_t div, val;
div = ath_uart_freq() / (16 * CONFIG_BAUDRATE);
#if defined(CONFIG_SCO_SLAVE_CONNECTED)
val = ath_reg_rd(GPIO_OE_ADDRESS) & (~0xcbf410u);
#elif defined(CONFIG_MACH_QCA956x)
val = ath_reg_rd(GPIO_OE_ADDRESS) & 0xbbfdf6;
#else
val = ath_reg_rd(GPIO_OE_ADDRESS) & (~0xcffc10u);
#endif
#if defined(CONFIG_ATH_SPI_NAND_CS_GPIO)
val |= 1 << CONFIG_ATH_SPI_NAND_CS_GPIO;
#endif
#if defined(CONFIG_ATH_SPI_CS1_GPIO)
val |= 1 << CONFIG_ATH_SPI_CS1_GPIO;
#endif
ath_reg_wr(GPIO_OE_ADDRESS, val);
#ifdef CONFIG_MACH_QCA956x
#if defined(UART_RX20_TX22)
val = (ath_reg_rd(GPIO_OE_ADDRESS) & (~0x400000));
ath_reg_wr(GPIO_OE_ADDRESS, val);
ath_reg_rmw_clear(GPIO_OUT_FUNCTION5_ADDRESS,
GPIO_OUT_FUNCTION5_ENABLE_GPIO_22_MASK);
ath_reg_rmw_set(GPIO_OUT_FUNCTION5_ADDRESS,
GPIO_OUT_FUNCTION5_ENABLE_GPIO_22_SET(0x16));
ath_reg_rmw_clear(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_MASK);
ath_reg_rmw_set(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0x14));
#elif defined(UART_RX18_TX22)
val = (ath_reg_rd(GPIO_OE_ADDRESS) & (~0x400000)) | 0x40000;
ath_reg_wr(GPIO_OE_ADDRESS, val);
ath_reg_rmw_clear(GPIO_OUT_FUNCTION5_ADDRESS,
GPIO_OUT_FUNCTION5_ENABLE_GPIO_22_MASK);
ath_reg_rmw_set(GPIO_OUT_FUNCTION5_ADDRESS,
GPIO_OUT_FUNCTION5_ENABLE_GPIO_22_SET(0x16));
ath_reg_rmw_clear(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_MASK);
ath_reg_rmw_set(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0x12));
#elif defined(UART_RX18_TX20)
val = (ath_reg_rd(GPIO_OE_ADDRESS) & (~0x100000)) | 0x40000;
ath_reg_wr(GPIO_OE_ADDRESS, val);
val = ath_reg_rd(GPIO_OUT_ADDRESS) | 0xeffff6;
ath_reg_wr(GPIO_OUT_ADDRESS, val);
ath_reg_rmw_clear(GPIO_OUT_FUNCTION5_ADDRESS,
GPIO_OUT_FUNCTION5_ENABLE_GPIO_20_MASK);
ath_reg_rmw_set(GPIO_OUT_FUNCTION5_ADDRESS,
GPIO_OUT_FUNCTION5_ENABLE_GPIO_20_SET(0x16));
ath_reg_rmw_clear(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_MASK);
ath_reg_rmw_set(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0x12));
#elif defined(UART_RX24_TX20)
// Turn off LED before XLNA swap to GPO
val = ath_reg_rd(GPIO_OUT_ADDRESS) | 0xaffff6;
ath_reg_wr(GPIO_OUT_ADDRESS, val);
//Switch GPI and GPO and XPA, XLNA
ath_reg_wr(GPIO_FUNCTION_ADDRESS, 0x8000);
val = (ath_reg_rd(GPIO_OE_ADDRESS) & (~0x100000)) | 0x1000000;
ath_reg_wr(GPIO_OE_ADDRESS, val);
ath_reg_rmw_set(GPIO_OUT_FUNCTION5_ADDRESS,
GPIO_OUT_FUNCTION5_ENABLE_GPIO_20_SET(0x16));
ath_reg_rmw_clear(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0xff));
ath_reg_rmw_set(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0x18));
#elif defined(TEST_BOARD_UART)
//Switch GPI and GPO and XPA1, ANTC
ath_reg_wr(GPIO_FUNCTION_ADDRESS, 0xc000);
val = ath_reg_rd(GPIO_OE_ADDRESS) & (~0x2000);
ath_reg_wr(GPIO_OE_ADDRESS, val);
ath_reg_rmw_clear(GPIO_OUT_FUNCTION3_ADDRESS,
GPIO_OUT_FUNCTION3_ENABLE_GPIO_13_MASK);
ath_reg_rmw_set(GPIO_OUT_FUNCTION3_ADDRESS,
GPIO_OUT_FUNCTION3_ENABLE_GPIO_13_SET(0x16));
ath_reg_rmw_clear(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0xff));
ath_reg_rmw_set(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0x17));
#else
val = (ath_reg_rd(GPIO_OE_ADDRESS) & (~0x100000)) | 0x80000;
ath_reg_wr(GPIO_OE_ADDRESS, val);
ath_reg_rmw_set(GPIO_OUT_FUNCTION5_ADDRESS,
GPIO_OUT_FUNCTION5_ENABLE_GPIO_20_SET(0x16));
ath_reg_rmw_clear(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0xff));
ath_reg_rmw_set(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0x13));
#endif
val = ath_reg_rd(GPIO_OUT_ADDRESS) | 0xaffff6;
ath_reg_wr(GPIO_OUT_ADDRESS, val);
val = ath_reg_rd(GPIO_SPARE_ADDRESS);
ath_reg_wr(GPIO_SPARE_ADDRESS, (val | 0x8402));
#else
ath_reg_rmw_set(GPIO_OUT_FUNCTION2_ADDRESS,
GPIO_OUT_FUNCTION2_ENABLE_GPIO_10_SET(0x16));
ath_reg_rmw_clear(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0xff));
ath_reg_rmw_set(GPIO_IN_ENABLE0_ADDRESS,
GPIO_IN_ENABLE0_UART_SIN_SET(0x9));
val = ath_reg_rd(GPIO_OUT_ADDRESS) | 0xcffc10u;
ath_reg_wr(GPIO_OUT_ADDRESS, val);
val = ath_reg_rd(GPIO_SPARE_ADDRESS);
ath_reg_wr(GPIO_SPARE_ADDRESS, (val | 0x8402));
ath_reg_wr(GPIO_OUT_ADDRESS, 0x2f);
#endif
/*
* set DIAB bit
*/
ath_uart_wr(OFS_LINE_CONTROL, 0x80);
/* set divisor */
ath_uart_wr(OFS_DIVISOR_LSB, (div & 0xff));
ath_uart_wr(OFS_DIVISOR_MSB, ((div >> 8) & 0xff));
/* clear DIAB bit*/
ath_uart_wr(OFS_LINE_CONTROL, 0x00);
/* set data format */
ath_uart_wr(OFS_DATA_FORMAT, 0x3);
ath_uart_wr(OFS_INTR_ENABLE, 0);
//#endif
return 0;
}
int qca_serial_tstc (void)
{
return(ath_uart_rd(OFS_LINE_STATUS) & 0x1);
}
u8 qca_serial_getc(void)
{
while(!serial_tstc());
return ath_uart_rd(OFS_RCV_BUFFER);
}
void qca_serial_putc(u8 byte)
{
if (byte == '\n') serial_putc ('\r');
while (((ath_uart_rd(OFS_LINE_STATUS)) & 0x20) == 0x0);
ath_uart_wr(OFS_SEND_BUFFER, byte);
}
void qca_serial_setbrg (void)
{
}
void qca_serial_puts (const char *s)
{
while (*s)
{
serial_putc (*s++);
}
}
static struct serial_device qca956x_serial_drv = {
.name = "qca956x_serial",
.start = qca_serial_init,
.stop = NULL,
.setbrg = NULL,
.putc = qca_serial_putc,
.puts = qca_serial_puts,
.getc = qca_serial_getc,
.tstc = qca_serial_tstc,
};
void qca_serial_initialize(void)
{
serial_register(&qca956x_serial_drv);
}
__weak struct serial_device *default_serial_console(void)
{
return &qca956x_serial_drv;
}

View file

@ -0,0 +1,671 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <asm/addrspace.h>
#include <atheros.h>
#define ATH_MAX_DDR_SIZE (256 * 1024 * 1024)
#define ATH_DDR_SIZE_INCR (4 * 1024 * 1024)
int
ath_ddr_find_size(void)
{
uint8_t *p = (uint8_t *)KSEG1, pat = 0x77;
int i;
#define max_i (ATH_MAX_DDR_SIZE / ATH_DDR_SIZE_INCR)
*p = pat;
/*
* DDR wraps around. Write a pattern to 0x0000_0000. Write an
* address pattern at 4M, 8M, 16M etc. and check when
* 0x0000_0000 gets overwritten.
*/
for(i = 1; (i < max_i); i++) {
*(p + i * ATH_DDR_SIZE_INCR) = (uint8_t)(i);
if (*p != pat) {
break;
}
}
return ((i < max_i) ? (i * ATH_DDR_SIZE_INCR) : ATH_MAX_DDR_SIZE);
}
inline int
ath_ram_type(uint32_t bs)
{
if (RST_BOOTSTRAP_DDR_SELECT_GET(bs)) {
return ATH_MEM_DDR1;
} else {
return ATH_MEM_DDR2;
}
}
/* Notice the value CFG_DDR2_DRAGONFLY_CAS_LATENCY
* Should Sync with CFG_PLL_FREQ
* */
#ifndef CFG_DDR2_DRAGONFLY_CAS_LATENCY
#define CFG_DDR2_DRAGONFLY_CAS_LATENCY 4
#endif
#ifdef CONFIG_TB614
# define DDR_CONFIG2_SWAP_A26_A27_VAL (0x1)
#else
# define DDR_CONFIG2_SWAP_A26_A27_VAL (0x0)
#endif
#if CFG_DDR2_DRAGONFLY_CAS_LATENCY == 3
#define CFG_DDR2_CONFIG_VAL DDR_CONFIG_CAS_LATENCY_MSB_SET(0x0) | \
DDR_CONFIG_OPEN_PAGE_SET(0x1) | \
DDR_CONFIG_CAS_LATENCY_SET(0x7) | \
DDR_CONFIG_TMRD_SET(0x6) | \
DDR_CONFIG_TRFC_SET(0x10) | \
DDR_CONFIG_TRRD_SET(0x5) | \
DDR_CONFIG_TRP_SET(0x8) | \
DDR_CONFIG_TRCD_SET(0x8) | \
DDR_CONFIG_TRAS_SET(0x17)
#define CFG_DDR2_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
DDR_CONFIG2_SWAP_A26_A27_SET(DDR_CONFIG2_SWAP_A26_A27_VAL) | \
DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0x6) | \
DDR_CONFIG2_TWTR_SET(0x12) | \
DDR_CONFIG2_TRTP_SET(0xa) | \
DDR_CONFIG2_TRTW_SET(0xe) | \
DDR_CONFIG2_TWR_SET(0xf) | \
DDR_CONFIG2_CKE_SET(0x1) | \
DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \
DDR_CONFIG2_BURST_LENGTH_SET(0x8)
#define CFG_DDR2_CONFIG3_VAL 0x00000002
#define CFG_DDR2_EXT_MODE_VAL1 0x782
#define CFG_DDR2_EXT_MODE_VAL2 0x402
#define CFG_DDR2_MODE_VAL_INIT 0x733
#define CFG_DDR2_MODE_VAL 0x633
#define CFG_DDR2_TAP_VAL 0x10
#define CFG_DDR2_EN_TWL_VAL 0x00000e65
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32 0xff
#elif CFG_DDR2_DRAGONFLY_CAS_LATENCY == 4
#define CFG_DDR2_CONFIG_VAL DDR_CONFIG_CAS_LATENCY_MSB_SET(0x1) | \
DDR_CONFIG_OPEN_PAGE_SET(0x1) | \
DDR_CONFIG_CAS_LATENCY_SET(0x1) | \
DDR_CONFIG_TMRD_SET(0x6) | \
DDR_CONFIG_TRFC_SET(0x11) | \
DDR_CONFIG_TRRD_SET(0x6) | \
DDR_CONFIG_TRP_SET(0x8) | \
DDR_CONFIG_TRCD_SET(0x8) | \
DDR_CONFIG_TRAS_SET(0x18)
#define CFG_DDR2_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
DDR_CONFIG2_SWAP_A26_A27_SET(DDR_CONFIG2_SWAP_A26_A27_VAL) | \
DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0x8) | \
DDR_CONFIG2_TWTR_SET(0x12) | \
DDR_CONFIG2_TRTP_SET(0xa) | \
DDR_CONFIG2_TRTW_SET(0xe) | \
DDR_CONFIG2_TWR_SET(0xf) | \
DDR_CONFIG2_CKE_SET(0x1) | \
DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \
DDR_CONFIG2_BURST_LENGTH_SET(0x8)
#define CFG_DDR2_CONFIG3_VAL 0x0000000a
#define CFG_DDR2_EXT_MODE_VAL1 0x782
#define CFG_DDR2_EXT_MODE_VAL2 0x402
#define CFG_DDR2_MODE_VAL_INIT 0x743
#define CFG_DDR2_MODE_VAL 0x643
#define CFG_DDR2_TAP_VAL 0x10
#define CFG_DDR2_EN_TWL_VAL 0x0000166d
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32 0xff
#elif CFG_DDR2_DRAGONFLY_CAS_LATENCY == 5
#define CFG_DDR2_CONFIG_VAL DDR_CONFIG_CAS_LATENCY_MSB_SET(0x1) | \
DDR_CONFIG_OPEN_PAGE_SET(0x1) | \
DDR_CONFIG_CAS_LATENCY_SET(0x4) | \
DDR_CONFIG_TMRD_SET(0x6) | \
DDR_CONFIG_TRFC_SET(0x16) | \
DDR_CONFIG_TRRD_SET(0x7) | \
DDR_CONFIG_TRP_SET(0xb) | \
DDR_CONFIG_TRCD_SET(0xb) | \
DDR_CONFIG_TRAS_SET(0)
#define CFG_DDR2_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
DDR_CONFIG2_SWAP_A26_A27_SET(DDR_CONFIG2_SWAP_A26_A27_VAL) | \
DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0xa) | \
DDR_CONFIG2_TWTR_SET(0x16) | \
DDR_CONFIG2_TRTP_SET(0xa) | \
DDR_CONFIG2_TRTW_SET(0xe) | \
DDR_CONFIG2_TWR_SET(0x2) | \
DDR_CONFIG2_CKE_SET(0x1) | \
DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \
DDR_CONFIG2_BURST_LENGTH_SET(0x8)
#define CFG_DDR2_CONFIG3_VAL 0x0000000e
#define CFG_DDR2_EXT_MODE_VAL1 0x782
#define CFG_DDR2_EXT_MODE_VAL2 0x402
#define CFG_DDR2_MODE_VAL_INIT 0xb53
#define CFG_DDR2_MODE_VAL 0xa53
#define CFG_DDR2_TAP_VAL 0x10
#define CFG_DDR2_EN_TWL_VAL 0x00001e91
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32 0xff
#elif CFG_DDR2_DRAGONFLY_CAS_LATENCY == 6
#define CFG_DDR2_CONFIG_VAL DDR_CONFIG_CAS_LATENCY_MSB_SET(0x1) | \
DDR_CONFIG_OPEN_PAGE_SET(0x1) | \
DDR_CONFIG_CAS_LATENCY_SET(0x6) | \
DDR_CONFIG_TMRD_SET(0x6) | \
DDR_CONFIG_TRFC_SET(0x16) | \
DDR_CONFIG_TRRD_SET(0x7) | \
DDR_CONFIG_TRP_SET(0xb) | \
DDR_CONFIG_TRCD_SET(0xb) | \
DDR_CONFIG_TRAS_SET(0)
#define CFG_DDR2_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
DDR_CONFIG2_SWAP_A26_A27_SET(DDR_CONFIG2_SWAP_A26_A27_VAL) | \
DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0xc) | \
DDR_CONFIG2_TWTR_SET(0x18) | \
DDR_CONFIG2_TRTP_SET(0xa) | \
DDR_CONFIG2_TRTW_SET(0xe) | \
DDR_CONFIG2_TWR_SET(0x2) | \
DDR_CONFIG2_CKE_SET(0x1) | \
DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \
DDR_CONFIG2_BURST_LENGTH_SET(0x8)
#define CFG_DDR2_CONFIG3_VAL 0x0000000e
#define CFG_DDR2_EXT_MODE_VAL1 0x782
#define CFG_DDR2_EXT_MODE_VAL2 0x402
#define CFG_DDR2_MODE_VAL_INIT 0xb63
#define CFG_DDR2_MODE_VAL 0xa63
#define CFG_DDR2_TAP_VAL 0x10
#define CFG_DDR2_EN_TWL_VAL 0x00002691
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32 0xff
#endif
/* CAL = 3 FOR DDR */
#define CFG_DDR1_CONFIG_VAL DDR_CONFIG_OPEN_PAGE_SET(0x1) | \
DDR_CONFIG_CAS_LATENCY_SET(0x7) | \
DDR_CONFIG_TMRD_SET(0x6) | \
DDR_CONFIG_TRFC_SET(0x9) | \
DDR_CONFIG_TRRD_SET(0x5) | \
DDR_CONFIG_TRP_SET(0x8) | \
DDR_CONFIG_TRCD_SET(0x8) | \
DDR_CONFIG_TRAS_SET(0x15)
#define CFG_DDR1_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0x6) | \
DDR_CONFIG2_TWTR_SET(0x10) | \
DDR_CONFIG2_TRTP_SET(0xa) | \
DDR_CONFIG2_TRTW_SET(0x10) | \
DDR_CONFIG2_TWR_SET(0xf) | \
DDR_CONFIG2_CKE_SET(0x1) | \
DDR_CONFIG2_CNTL_OE_EN_SET(0x1) | \
DDR_CONFIG2_BURST_LENGTH_SET(0x8)
#define CFG_DDR1_CONFIG3_VAL 0x0
#define CFG_DDR1_EXT_MODE_VAL 0x2
#define CFG_DDR1_MODE_VAL_INIT 0x133
#define CFG_DDR1_MODE_VAL 0x33
#define CFG_DDR1_RD_DATA_THIS_CYCLE_VAL_16 0xffff
#define CFG_DDR1_RD_DATA_THIS_CYCLE_VAL_32 0xff
#define CFG_DDR1_TAP_VAL 0x10
#define CFG_DDR1_EN_TWL_VAL 0x00000664
#define CFG_DDR_CTL_CONFIG DDR_CTL_CONFIG_SRAM_TSEL_SET(0x1) | \
DDR_CTL_CONFIG_GE0_SRAM_SYNC_SET(0x1) | \
DDR_CTL_CONFIG_GE1_SRAM_SYNC_SET(0x1) | \
DDR_CTL_CONFIG_USB_SRAM_SYNC_SET(0x1) | \
DDR_CTL_CONFIG_PCIE_SRAM_SYNC_SET(0x1) | \
DDR_CTL_CONFIG_WMAC_SRAM_SYNC_SET(0x1) | \
DDR_CTL_CONFIG_MISC_SRC1_SRAM_SYNC_SET(0x1) | \
DDR_CTL_CONFIG_MISC_SRC2_SRAM_SYNC_SET(0x1)
int /* ram type */
ath_ddr_initial_config(uint32_t refresh)
{
#if !defined(CONFIG_ATH_NAND_BR) && !defined(CONFIG_ATH_EMULATION)
int ddr_config, ddr_config2, ddr_config3, ext_mod, mod_val,
mod_val_init, cycle_val, tap_val, type, ctl_config;
uint32_t *pll = (unsigned *)PLL_CONFIG_VAL_F;
uint32_t bootstrap;
prmsg("\nsri\n");
#ifdef CONFIG_MACH_955x
prmsg("Scorpion 1.%d\n", ath_reg_rd(RST_REVISION_ID_ADDRESS) & 0xf);
#elif defined (CONFIG_MACH_956x)
prmsg("Dragonfly 1.%d\n", ath_reg_rd(RST_REVISION_ID_ADDRESS) & 0xf);
#endif
bootstrap = ath_reg_rd(RST_BOOTSTRAP_ADDRESS);
switch(type = ath_ram_type(bootstrap)) {
case ATH_MEM_DDR2:
ddr_config = CFG_DDR2_CONFIG_VAL;
ddr_config2 = CFG_DDR2_CONFIG2_VAL;
ddr_config3 = CFG_DDR2_CONFIG3_VAL;
ext_mod = CFG_DDR2_EXT_MODE_VAL2;
mod_val_init = CFG_DDR2_MODE_VAL_INIT;
mod_val = CFG_DDR2_MODE_VAL;
tap_val = CFG_DDR2_TAP_VAL;
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x10);
udelay(10);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x20);
udelay(10);
prmsg("%s(%d): (", __func__, __LINE__);
ctl_config = CFG_DDR_CTL_CONFIG |
DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(0x1) |
DDR_CTL_CONFIG_HALF_WIDTH_SET(0x1);
cycle_val = CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16;
ctl_config |= CPU_DDR_SYNC_MODE;
ath_reg_wr_nf(DDR_CTL_CONFIG_ADDRESS, ctl_config);
prmsg("ddr2 init)\n");
udelay(10);
break;
case ATH_MEM_DDR1:
ddr_config = CFG_DDR1_CONFIG_VAL;
ddr_config2 = CFG_DDR1_CONFIG2_VAL;
ddr_config3 = CFG_DDR1_CONFIG3_VAL;
ext_mod = CFG_DDR1_EXT_MODE_VAL;
mod_val_init = CFG_DDR1_MODE_VAL_INIT;
mod_val = CFG_DDR1_MODE_VAL;
tap_val = CFG_DDR1_TAP_VAL;
prmsg("%s(%d): (", __func__, __LINE__);
cycle_val = CFG_DDR1_RD_DATA_THIS_CYCLE_VAL_16;
ctl_config = CFG_DDR_CTL_CONFIG |
DDR_CTL_CONFIG_HALF_WIDTH_SET(0x1);
ctl_config |= CPU_DDR_SYNC_MODE;
ath_reg_wr_nf(DDR_CTL_CONFIG_ADDRESS, ctl_config);
udelay(10);
prmsg("ddr1 init)\n");
break;
}
#if 0
if (*pll == PLL_MAGIC) {
uint32_t cas = pll[5];
if (cas == 3 || cas == 4) {
cas = (cas * 2) + 2;
ddr_config &= ~(DDR_CONFIG_CAS_LATENCY_MSB_MASK |
DDR_CONFIG_CAS_LATENCY_MASK);
ddr_config |= DDR_CONFIG_CAS_LATENCY_SET(cas & 0x7) |
DDR_CONFIG_CAS_LATENCY_MSB_SET((cas >> 3) & 1);
cas = pll[5];
ddr_config2 &= ~DDR_CONFIG2_GATE_OPEN_LATENCY_MASK;
ddr_config2 |= DDR_CONFIG2_GATE_OPEN_LATENCY_SET((2 * cas) + 1);
if (type == ATH_MEM_DDR2) {
uint32_t tmp;
tmp = ath_reg_rd(DDR2_CONFIG_ADDRESS);
tmp &= ~DDR2_CONFIG_DDR2_TWL_MASK;
tmp |= DDR2_CONFIG_DDR2_TWL_SET(cas == 3 ? 3 : 5);
ath_reg_wr_nf(DDR2_CONFIG_ADDRESS, tmp);
}
mod_val = (cas == 3 ? 0x33 : 0x43);
mod_val_init = 0x100 | mod_val;
}
}
#endif
ath_reg_wr_nf(DDR_RD_DATA_THIS_CYCLE_ADDRESS, cycle_val);
udelay(100);
ath_reg_wr_nf(DDR_BURST_ADDRESS, 0x74444444);
udelay(100);
ath_reg_wr_nf(DDR_BURST2_ADDRESS, 0x44444444);
udelay(100);
ath_reg_wr_nf(DDR_FSM_WAIT_CTRL_ADDRESS, DDR_FSM_WAIT_CTRL_VAL);
udelay(100);
ath_reg_wr_nf(DDR_AHB_MASTER_TIMEOUT_MAX_ADDRESS, 0xfffff);
udelay(100);
ath_reg_wr_nf(DDR_CONFIG_ADDRESS, ddr_config);
udelay(100);
ath_reg_wr_nf(DDR_CONFIG2_ADDRESS, ddr_config2);
udelay(100);
ath_reg_wr(DDR_CONFIG_3_ADDRESS, ddr_config3);
udelay(100);
if (type == ATH_MEM_DDR2) {
ath_reg_wr_nf(DDR2_CONFIG_ADDRESS, CFG_DDR2_EN_TWL_VAL);
udelay(100);
}
if (type == ATH_MEM_DDR1) {
ath_reg_wr_nf(DDR2_CONFIG_ADDRESS, CFG_DDR1_EN_TWL_VAL);
udelay(100);
}
ath_reg_wr_nf(DDR_CONFIG2_ADDRESS, ddr_config2 | 0x80); // CKE Enable
udelay(100);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x8); // Precharge
udelay(10);
if (type == ATH_MEM_DDR2) {
ath_reg_wr_nf(DDR_EMR2_ADDRESS, 0);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x10); // EMR2
udelay(10);
ath_reg_wr_nf(DDR_EMR3_ADDRESS, 0);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x20); // EMR3
udelay(10);
}
if (type == ATH_MEM_DDR1 || type == ATH_MEM_DDR2) {
ath_reg_wr_nf(DDR_EXTENDED_MODE_REGISTER_ADDRESS, CFG_DDR2_EXT_MODE_VAL2); // EMR DLL enable, Reduced Driver Impedance control, Differential DQS disabled
udelay(100);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x2); // EMR write
udelay(10);
}
ath_reg_wr_nf(DDR_MODE_REGISTER_ADDRESS, mod_val_init);
udelay(1000);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x1); // MR Write
udelay(10);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x8); // Precharge
udelay(10);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x4); // Auto Refresh
udelay(10);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x4); // Auto Refresh
udelay(10);
// Issue MRS to remove DLL out-of-reset
ath_reg_wr_nf(DDR_MODE_REGISTER_ADDRESS, mod_val);
udelay(100);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x1); // MR write
udelay(100);
if (type == ATH_MEM_DDR2) {
ath_reg_wr_nf(DDR_EXTENDED_MODE_REGISTER_ADDRESS, CFG_DDR2_EXT_MODE_VAL1);
udelay(100);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x2); // EMR write
udelay(100);
ath_reg_wr_nf(DDR_EXTENDED_MODE_REGISTER_ADDRESS, CFG_DDR2_EXT_MODE_VAL2);
udelay(100);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x2); // EMR write
udelay(100);
refresh = CFG_DDR2_REFRESH_VAL;
}
ath_reg_wr_nf(DDR_REFRESH_ADDRESS, refresh);
udelay(100);
ath_reg_wr(TAP_CONTROL_0_ADDRESS, tap_val);
ath_reg_wr(TAP_CONTROL_1_ADDRESS, tap_val);
ath_reg_wr (TAP_CONTROL_2_ADDRESS, tap_val);
ath_reg_wr (TAP_CONTROL_3_ADDRESS, tap_val);
if (type == ATH_MEM_DDR2) {
ath_reg_wr(PMU1_ADDRESS, 0x633c8176);
// Set DDR2 Voltage to 1.8 volts
ath_reg_wr(PMU2_ADDRESS, PMU2_SWREGMSB_SET(0x40) |
PMU2_PGM_SET(0x1));
}
/*
* Based on SGMII validation for stucks, packet errors were observed and it was
* mostly due to noise pickup on SGMII lines. Switching regulator register is to
* be programmed with proper setting to avoid such stucks.
*/
if (type == ATH_MEM_DDR1){
ath_reg_wr(PMU1_ADDRESS, 0x633c8176);
ath_reg_wr(PMU2_ADDRESS, 0x10200000);
}
ath_sys_frequency();
return type;
#else // !nand flash and !emulation
return 0;
#endif
}
int
ath_uart_freq(void)
{
if (ath_reg_rd(RST_BOOTSTRAP_ADDRESS) & RST_BOOTSTRAP_REF_CLK_MASK) {
return 40 * 1000 * 1000;
} else {
return 25 * 1000 * 1000;
}
}
void
ath_sys_frequency()
{
#if !defined(CONFIG_ATH_EMULATION)
unsigned int rdata, i;
unsigned int cpu_pll_low_int, cpu_pll_low_frac, cpu_pll_high_int, cpu_pll_high_frac;
unsigned int ddr_pll_low_int, ddr_pll_low_frac, ddr_pll_high_int, ddr_pll_high_frac;
unsigned int cpu_clk_low, cpu_clk_high;
unsigned int ddr_clk_low, ddr_clk_high;
unsigned int ahb_clk_low, ahb_clk_high;
/* CPU_DDR_CLOCK_CONTROL */
unsigned int ahbclk_from_ddrpll, ahb_post_div, ddr_post_div, cpu_post_div;
unsigned int cpu_ddr_clk_from_cpupll, cpu_ddr_clk_from_ddrpll;
unsigned int ahb_pll_bypass, ddr_pll_bypass, cpu_pll_bypass;
/* CPU_PLL_CONFIG, CPU_PLL_CONFIG1, CPU_PLL_DITHER1, CPU_PLL_DITHER2 */
unsigned int cpu_pllpwd, cpu_outdiv, cpu_Refdiv, cpu_Nint;
unsigned int cpu_dither_en, cpu_NFrac_Min, cpu_NFrac_Max;
unsigned int cpu_NFrac_Min_17_5, cpu_NFrac_Min_4_0;
unsigned int cpu_NFrac_Max_17_5, cpu_NFrac_Max_4_0;
/* DDR_PLL_CONFIG, DDR_PLL_CONFIG1, DDR_PLL_DITHER1, DDR_PLL_DITHER2 */
unsigned int ddr_pllpwd, ddr_outdiv, ddr_Refdiv, ddr_Nint;
unsigned int ddr_dither_en, ddr_NFrac_Min, ddr_NFrac_Max;
unsigned int ddr_NFrac_Min_17_5, ddr_NFrac_Min_4_0;
unsigned int ddr_NFrac_Max_17_5, ddr_NFrac_Max_4_0;
static uint32_t ath_cpu_freq, ath_ddr_freq, ath_ahb_freq;
#endif
uint32_t ref_clk;
#if defined(CONFIG_ATH_EMULATION)
ref_clk = (40 * 1000000);
#else
ref_clk = ath_uart_freq();
#endif
#ifdef CONFIG_ATH_EMULATION
ath_cpu_freq = 80000000;
ath_ddr_freq = 80000000;
ath_ahb_freq = 40000000;
#else
rdata = ath_reg_rd(CPU_DDR_CLOCK_CONTROL_ADDRESS);
ahbclk_from_ddrpll = CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_GET(rdata);
ahb_post_div = CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_GET(rdata);
ddr_post_div = CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_GET(rdata);
cpu_post_div = CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_GET(rdata);
cpu_ddr_clk_from_cpupll = CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_CPUPLL_GET(rdata);
cpu_ddr_clk_from_ddrpll = CPU_DDR_CLOCK_CONTROL_CPU_DDR_CLK_FROM_DDRPLL_GET(rdata);
ahb_pll_bypass = CPU_DDR_CLOCK_CONTROL_AHB_PLL_BYPASS_GET(rdata);
ddr_pll_bypass = CPU_DDR_CLOCK_CONTROL_DDR_PLL_BYPASS_GET(rdata);
cpu_pll_bypass = CPU_DDR_CLOCK_CONTROL_CPU_PLL_BYPASS_GET(rdata);
if (ahb_pll_bypass) {
ath_ahb_freq = ref_clk / (ahb_post_div + 1);
//*ahb_clk_h = ref_clk / (ahb_post_div + 1);
}
if (ddr_pll_bypass) {
ath_ddr_freq = ref_clk;
//*ddr_clk_h = ref_clk;
}
if (cpu_pll_bypass) {
ath_cpu_freq = ref_clk;
//*cpu_clk_h = ref_clk;
}
if (ahb_pll_bypass && ddr_pll_bypass && cpu_pll_bypass) {
return;
}
rdata = ath_reg_rd(CPU_PLL_CONFIG_ADDRESS);
cpu_pllpwd = CPU_PLL_CONFIG_PLLPWD_GET(rdata);
cpu_outdiv = CPU_PLL_CONFIG_OUTDIV_GET(rdata);
cpu_Refdiv = CPU_PLL_CONFIG_REFDIV_GET(rdata);
rdata = ath_reg_rd(CPU_PLL_CONFIG1_ADDRESS);
cpu_Nint = CPU_PLL_CONFIG1_NINT_GET(rdata);
rdata = ath_reg_rd(CPU_PLL_DITHER1_ADDRESS);
cpu_dither_en = CPU_PLL_DITHER1_DITHER_EN_GET(rdata);
cpu_NFrac_Min = CPU_PLL_DITHER1_NFRAC_MIN_GET(rdata);
cpu_NFrac_Min_17_5 = (cpu_NFrac_Min >> 5) & 0x1fff;
cpu_NFrac_Min_4_0 = cpu_NFrac_Min & 0x1f;
rdata = ath_reg_rd(CPU_PLL_DITHER1_ADDRESS);
cpu_NFrac_Max = CPU_PLL_DITHER2_NFRAC_MAX_GET(rdata);
cpu_NFrac_Max_17_5 = (cpu_NFrac_Max >> 5) & 0x1fff;
cpu_NFrac_Max_4_0 = cpu_NFrac_Max & 0x1f;
rdata = ath_reg_rd(DDR_PLL_CONFIG_ADDRESS);
ddr_pllpwd = DDR_PLL_CONFIG_PLLPWD_GET(rdata);
ddr_outdiv = DDR_PLL_CONFIG_OUTDIV_GET(rdata);
ddr_Refdiv = DDR_PLL_CONFIG_REFDIV_GET(rdata);
rdata = ath_reg_rd(DDR_PLL_CONFIG1_ADDRESS);
ddr_Nint = DDR_PLL_CONFIG1_NINT_GET(rdata);
rdata = ath_reg_rd(DDR_PLL_DITHER1_ADDRESS);
ddr_dither_en = DDR_PLL_DITHER1_DITHER_EN_GET(rdata);
ddr_NFrac_Min = DDR_PLL_DITHER1_NFRAC_MIN_GET(rdata);
ddr_NFrac_Min_17_5 = (ddr_NFrac_Min >> 5) & 0x1fff;
ddr_NFrac_Min_4_0 = ddr_NFrac_Min & 0x1f;
rdata = ath_reg_rd(DDR_PLL_DITHER1_ADDRESS);
ddr_NFrac_Max = DDR_PLL_DITHER2_NFRAC_MAX_GET(rdata);
ddr_NFrac_Max_17_5 = (ddr_NFrac_Max >> 5) & 0x1fff;
ddr_NFrac_Max_4_0 = ddr_NFrac_Max & 0x1f;
/* CPU PLL */
i = (ref_clk/cpu_Refdiv);
cpu_pll_low_int = i*cpu_Nint;
cpu_pll_high_int = cpu_pll_low_int;
cpu_pll_low_frac = (i/(25*32))*((cpu_NFrac_Min_17_5*25 + cpu_NFrac_Min_4_0)/(8192/32));
cpu_pll_high_frac = (i/(25*32))*((cpu_NFrac_Max_17_5*25 + cpu_NFrac_Max_4_0)/(8192/32));
if (!cpu_dither_en || cpu_pll_high_frac <= cpu_pll_low_frac) {
cpu_pll_high_frac = cpu_pll_low_frac;
}
/* DDR PLL */
i = (ref_clk/ddr_Refdiv);
ddr_pll_low_int = i*ddr_Nint;
ddr_pll_high_int = ddr_pll_low_int;
ddr_pll_low_frac = (i/(25*32))*((ddr_NFrac_Min_17_5*25 + ddr_NFrac_Min_4_0)/(8192/32));
ddr_pll_high_frac = (i/(25*32))*((ddr_NFrac_Max_17_5*25 + ddr_NFrac_Max_4_0)/(8192/32));
if (!ddr_dither_en || ddr_pll_high_frac <= ddr_pll_low_frac) {
ddr_pll_high_frac = ddr_pll_low_frac;
}
/* CPU Clock, DDR Clock, AHB Clock (before post div) */
if (cpu_ddr_clk_from_cpupll) {
cpu_clk_low = cpu_pll_low_int + cpu_pll_low_frac;
cpu_clk_high = cpu_pll_high_int + cpu_pll_high_frac;
if (cpu_outdiv != 0) {
cpu_clk_low /= (2*cpu_outdiv);
cpu_clk_high /= (2*cpu_outdiv);
}
ddr_clk_low = cpu_clk_low;
ddr_clk_high = cpu_clk_high;
} else if (cpu_ddr_clk_from_ddrpll) {
ddr_clk_low = ddr_pll_low_int + ddr_pll_low_frac;
ddr_clk_high = ddr_pll_high_int + ddr_pll_high_frac;
if (ddr_outdiv != 0) {
ddr_clk_low /= (2*ddr_outdiv);
ddr_clk_high /= (2*ddr_outdiv);
}
cpu_clk_low = ddr_clk_low;
cpu_clk_high = ddr_clk_high;
} else {
cpu_clk_low = cpu_pll_low_int + cpu_pll_low_frac;
cpu_clk_high = cpu_pll_high_int + cpu_pll_high_frac;
ddr_clk_low = ddr_pll_low_int + ddr_pll_low_frac;
ddr_clk_high = ddr_pll_high_int + ddr_pll_high_frac;
if (cpu_outdiv != 0) {
cpu_clk_low /= (2*cpu_outdiv);
cpu_clk_high /= (2*cpu_outdiv);
}
if (ddr_outdiv != 0) {
ddr_clk_low /= (2*ddr_outdiv);
ddr_clk_high /= (2*ddr_outdiv);
}
}
if (ahbclk_from_ddrpll) {
ahb_clk_low = ddr_clk_low;
ahb_clk_high = ddr_clk_high;
} else {
ahb_clk_low = cpu_clk_low;
ahb_clk_high = cpu_clk_high;
}
/* CPU Clock, DDR Clock, AHB Clock */
cpu_clk_low /= (cpu_post_div + 1);
cpu_clk_high /= (cpu_post_div + 1);
ddr_clk_low /= (ddr_post_div + 1);
ddr_clk_high /= (ddr_post_div + 1);
ahb_clk_low /= (ahb_post_div + 1);
ahb_clk_high /= (ahb_post_div + 1);
ath_cpu_freq = cpu_clk_low;
ath_ddr_freq = ddr_clk_low;
ath_ahb_freq = ahb_clk_low;
//*cpu_clk_h = cpu_clk_high;
//*ddr_clk_h = ddr_clk_high;
//*ahb_clk_h = ahb_clk_high;
#endif
prmsg("%s: cpu %u ddr %u ahb %u\n", __func__,
ath_cpu_freq / 1000000,
ath_ddr_freq / 1000000,
ath_ahb_freq / 1000000);
}

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <command.h>
#include <asm/mipsregs.h>
#if defined(CONFIG_AR7100)
#include <asm/addrspace.h>
#include <ar7100_soc.h>
#endif
#if defined(CONFIG_AR7240)
#include <asm/addrspace.h>
#include <ar7240_soc.h>
#endif
#if defined(CONFIG_ATHEROS)
#include <asm/addrspace.h>
#include <atheros.h>
#endif
static inline void mips_compare_set(u32 v)
{
asm volatile ("mtc0 %0, $11" : : "r" (v));
}
static inline void mips_count_set(u32 v)
{
asm volatile ("mtc0 %0, $9" : : "r" (v));
}
static inline u32 mips_count_get(void)
{
u32 count;
asm volatile ("mfc0 %0, $9" : "=r" (count) :);
return count;
}
/*
* timer without interrupts
*/
int timer_init(void)
{
mips_compare_set(0);
mips_count_set(0);
return 0;
}
void _machine_restart(void)
{
#if defined(CONFIG_ATHEROS)
while (1) {
ath_reg_wr(RST_RESET_ADDRESS, RST_RESET_FULL_CHIP_RESET_SET(1));
}
#elif defined(CONFIG_INCA_IP)
*INCA_IP_WDT_RST_REQ = 0x3f;
#elif defined(CONFIG_PURPLE) || defined(CONFIG_TB0229)
void (*f)(void) = (void *) 0xbfc00000;
f();
#elif defined(CONFIG_AR7100)
#ifndef COMPRESSED_UBOOT
fprintf(stdout, "\nResetting...\n");
#endif /* #ifndef COMPRESSED_UBOOT */
for (;;) {
ar7100_reg_wr(AR7100_RESET,
(AR7100_RESET_FULL_CHIP | AR7100_RESET_DDR));
}
#elif defined(CONFIG_AR7240)
#ifndef COMPRESSED_UBOOT
fprintf(stdout, "\nResetting...\n");
#endif /* #ifndef COMPRESSED_UBOOT */
for (;;) {
#ifdef CONFIG_WASP
if (ar7240_reg_rd(AR7240_REV_ID) & 0xf) {
ar7240_reg_wr(AR7240_RESET,
(AR7240_RESET_FULL_CHIP | AR7240_RESET_DDR));
} else {
/*
* WAR for full chip reset spi vs. boot-rom selection
* bug in wasp 1.0
*/
ar7240_reg_wr (AR7240_GPIO_OE,
ar7240_reg_rd(AR7240_GPIO_OE) & (~(1 << 17)));
}
#else
ar7240_reg_wr(AR7240_RESET,
(AR7240_RESET_FULL_CHIP | AR7240_RESET_DDR));
#endif
}
#endif
#ifndef COMPRESSED_UBOOT
fprintf(stderr, "*** reset failed ***\n");
#endif /* #ifndef COMPRESSED_UBOOT */
return 0;
}

View file

@ -0,0 +1,196 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <config.h>
#include <version.h>
#include <asm/regdef.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <atheros.h>
.globl ath_ddr_tap_cal
.type ath_ddr_tap_cal, @function
.text
.align 4
ath_ddr_tap_cal:
li a0, 0xbd001f00
sw zero, 0x0(a0) // Place where the tap values are saved and used for SWEEP
sw zero, 0x4(a0) // Place where the number of passing taps are saved.
sw zero, 0x14(a0) // Place where the last pass tap value is stored
li a1, 0xaa55aa55 // Indicates that the First pass tap value is not found
sw a1, 0x10(a0) // Place where the First pass tap value is stored
nop
li a0, 0xb8060000 // RESET_BASE_ADDRESS
lw a1, 0x1c(a0) // Reading the RST_RESET_ADDRESS
li a2, 0x08000000 // Setting the RST_RESET_RTC_RESET
or a1, a1, a2
sw a1, 0x1c(a0)
li a3, 0xffffffff
xor a2, a2, a3
and a1, a1, a2
sw a1, 0x1c(a0) // Taking the RTC out of RESET
nop
li a0, 0xb8107000 // RTC_BASE_ADDRESS
li a1, 0x1
sw a1, 0x0040(a0) // RTC_SYNC_RESET_ADDRESS
li a2, 0x2
_poll_for_RTC_ON:
lw a1, 0x0044(a0) // RTC_SYNC_STATUS_ADDRESS
and a1, a2, a1
bne a1, a2, _poll_for_RTC_ON
_CHANGE_TAPS:
li t0, 0xbd001f00 // Read the current value of the TAP for programming
lw t1, 0x0(t0)
li t2, 0x00000000
or t3, t1, t2
li t0, 0xb8000000 // DDR_BASE_ADDRESS
sw t3, 0x1c(t0) // TAP_CONTROL_0_ADDRESS
sw t3, 0x20(t0) // TAP_CONTROL_1_ADDRESS
sw t3, 0x24(t0) // TAP_CONTROL_2_ADDRESS
sw t3, 0x28(t0) // TAP_CONTROL_3_ADDRESS
li t1, 0x00000010 // Running the test 8 times
sw t1, 0x0068(t0) // PERF_COMP_ADDR_1_ADDRESS
li t1, 0xfa5de83f // 4 Row Address Bits, 4 Column Address Bits, 2 BA bits
sw t1, 0x002c(t0) // PERF_MASK_ADDR_0_ADDRESS
li t1, 0x0000ffff
sw t1, 0x0070(t0) // PERF_COMP_AHB_GE0_1_ADDRESS
li t1, 0x0000ffff
sw t1, 0x0040(t0) // PERF_COMP_AHB_GE1_0_ADDRESS
li t1, 0x0000ffff
sw t1, 0x0078(t0) // PERF_COMP_AHB_GE1_1_ADDRESS
li t1, 0x0000ffff
sw t1, 0x0034(t0) // PERF_MASK_AHB_GE0_0_ADDRESS
li t1, 0x0000ffff
sw t1, 0x006c(t0) // PERF_MASK_AHB_GE0_1_ADDRESS
li t1, 0x0000ffff
sw t1, 0x003c(t0) // PERF_MASK_AHB_GE1_0_ADDRESS
li t1, 0x0000ffff
sw t1, 0x0074(t0) // PERF_MASK_AHB_GE1_1_ADDRESS
li t1, 0x0000ffff
sw t1, 0x0038(t0) // PERF_COMP_AHB_GE0_0_ADDRESS
li t1, 0x00000001
sw t1, 0x011c(t0) // DDR_BIST_ADDRESS
li t2, 0x1
_bist_done_poll:
lw t1, 0x0120(t0) // DDR_BIST_STATUS_ADDRESS
and t1, t1, t2
bne t1, t2, _bist_done_poll
lw t1, 0x0120(t0) // DDR_BIST_STATUS_ADDRESS
li t4, 0x000001fe
and t2, t1, t4
srl t2, t2, 0x1 // no. of Pass Runs
li t5, 0x00000000
sw t5, 0x011c(t0) //DDR_BIST_ADDRESS - Stop the DDR BIST test
li t5, 0x0001fe00
and t5, t5, t1
bnez t5, _iterate_tap // This is a redundant compare but nevertheless - Comparing the FAILS
lw t1, 0x0068(t0) // PERF_COMP_ADDR_1_ADDRESS
li t3, 0x000001fe
and t3, t3, t1
srl t3, t3, 0x1 // No. of runs in the config register.
bne t3, t2, _iterate_tap
pass_tap:
li t0, 0xbd001f00
lw t1, 0x4(t0)
addiu t1, t1, 0x1
sw t1, 0x4(t0)
li t0, 0xbd001f10
lw t1, 0x0(t0)
li t2, 0xaa55aa55
beq t1, t2, _first_pass
nop
li t0, 0xbd001f00
lw t1, 0x0(t0)
li t0, 0xbd001f10
sw t1, 0x4(t0)
nop
b _iterate_tap
nop
_first_pass:
li t0, 0xbd001f00
lw t1, 0x0(t0)
li t0, 0xbd001f10
sw t1, 0x0(t0)
sw t1, 0x4(t0)
nop
_iterate_tap:
li t0, 0xbd001f00
lw t1, 0x0(t0)
li t2, 0x3f
beq t1, t2, _STOP_TEST
nop
addiu t1, t1, 0x1
sw t1, 0x0(t0)
nop
b _CHANGE_TAPS
_STOP_TEST:
li t0, 0xbd001f00
lw t1, 0x4(t0)
bnez t1, _load_center_tap
nop
li t3, 0x8 // Default Tap to be used
b _load_tap_into_reg
_load_center_tap:
li t0, 0xbd001f10
lw t1, 0x0(t0)
lw t2, 0x4(t0)
add t3, t1, t2
srl t3, t3, 0x1
li t4, 0x3f
and t3, t3, t4
_load_tap_into_reg:
li t0, 0xb8000000
sw t3, 0x1c(t0) // TAP_CONTROL_0_ADDRESS
sw t3, 0x20(t0) // TAP_CONTROL_1_ADDRESS
sw t3, 0x24(t0) // TAP_CONTROL_2_ADDRESS
sw t3, 0x28(t0) // TAP_CONTROL_3_ADDRESS
jr ra
nop

View file

@ -0,0 +1,15 @@
if TARGET_QCA956X
config SYS_CPU
default "qca956x"
config SYS_BOARD
default "mips32/qca956x"
config SYS_VENDOR
default "qca"
config SYS_CONFIG_NAME
default "qca956x"
endif

View file

@ -0,0 +1,3 @@
obj-y := board956x.o extra.o ../common/init-956x.o \
../common/956x.o ../common/tap-956x.o \
../common/ath_serial.o ../common/qca-mach-common.o

View file

@ -0,0 +1,170 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <command.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <config.h>
#include <version.h>
#include <atheros.h>
extern int ath_ddr_initial_config(uint32_t refresh);
extern int ath_ddr_find_size(void);
#ifdef COMPRESSED_UBOOT
# define prmsg(...)
# define args char *s
# define board_str(a) do { \
char ver[] = "0"; \
strcpy(s, a " - Dragonfly 1."); \
ver[0] += ath_reg_rd(RST_REVISION_ID_ADDRESS) \
& 0xf; \
strcat(s, ver); \
} while (0)
#else
# define prmsg printf
# define args void
# define board_str(a) \
printf(a " - Dragonfly 1.%d", ath_reg_rd \
(RST_REVISION_ID_ADDRESS) & 0xf)
#endif
void
ath_usb1_initial_config(void)
{
#define unset(a) (~(a))
ath_reg_wr_nf(SWITCH_CLOCK_SPARE_ADDRESS,
ath_reg_rd(SWITCH_CLOCK_SPARE_ADDRESS) |
SWITCH_CLOCK_SPARE_USB_REFCLK_FREQ_SEL_SET(5));
udelay(1000);
ath_reg_rmw_set(RST_RESET_ADDRESS,
RST_RESET_USB_PHY_SUSPEND_OVERRIDE_SET(1));
udelay(1000);
ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_USB_PHY_RESET_SET(1));
udelay(1000);
ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_USB_PHY_ARESET_SET(1));
udelay(1000);
ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_USB_HOST_RESET_SET(1));
udelay(1000);
ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_USB_PHY_PLL_PWD_EXT_SET(1));
udelay(10);
ath_reg_rmw_set(RST_RESET2_ADDRESS, RST_RESET2_USB1_EXT_PWR_SEQ_SET(1));
udelay(10);
}
void
ath_usb2_initial_config(void)
{
if (is_drqfn()) {
return;
}
ath_reg_rmw_set(RST_RESET2_ADDRESS, RST_RESET2_USB2_MODE_SET(1));
udelay(10);
ath_reg_rmw_set(RST_RESET2_ADDRESS,
RST_RESET2_USB_PHY2_SUSPEND_OVERRIDE_SET(1));
udelay(1000);
ath_reg_rmw_clear(RST_RESET2_ADDRESS, RST_RESET2_USB_PHY2_RESET_SET(1));
udelay(1000);
ath_reg_rmw_clear(RST_RESET2_ADDRESS, RST_RESET2_USB_PHY2_ARESET_SET(1));
udelay(1000);
ath_reg_rmw_clear(RST_RESET2_ADDRESS, RST_RESET2_USB_HOST2_RESET_SET(1));
udelay(1000);
ath_reg_rmw_clear(RST_RESET2_ADDRESS, RST_RESET2_USB_PHY2_PLL_PWD_EXT_SET(1));
udelay(10);
ath_reg_rmw_set(RST_RESET2_ADDRESS, RST_RESET2_USB2_EXT_PWR_SEQ_SET(1));
udelay(10);
}
void ath_gpio_config(void)
{
#if defined(CONFIG_CUS249)
/* Turn on System LED GPIO18 for CUS249 */
ath_reg_rmw_clear(GPIO_OUT_ADDRESS, (1 << 18));
#endif
/* Turn off JUMPST_LED and 5Gz LED during bootup */
// ath_reg_rmw_set(GPIO_OE_ADDRESS, (1 << 15));
// ath_reg_rmw_set(GPIO_OE_ADDRESS, (1 << 12));
}
int
ath_mem_config(void)
{
unsigned int type, reg32, *tap;
extern uint32_t *ath_ddr_tap_cal(void);
#if !defined(CONFIG_ATH_EMULATION)
#if !defined(CONFIG_ATH_NAND_BR)
type = ath_ddr_initial_config(CFG_DDR_REFRESH_VAL);
tap = ath_ddr_tap_cal();
// tap = (uint32_t *)0xbd001f10;
// prmsg("Tap (low, high) = (0x%x, 0x%x)\n", tap[0], tap[1]);
tap = (uint32_t *)TAP_CONTROL_0_ADDRESS;
prmsg("Tap values = (0x%x, 0x%x, 0x%x, 0x%x)\n",
tap[0], tap[1], tap[2], tap[3]);
/* Take WMAC out of reset */
reg32 = ath_reg_rd(RST_RESET_ADDRESS);
reg32 = reg32 & ~RST_RESET_RTC_RESET_SET(1);
ath_reg_wr_nf(RST_RESET_ADDRESS, reg32);
#endif
#if defined(CONFIG_USB)
ath_usb1_initial_config();
ath_usb2_initial_config();
#else
//turn off not support interface register
reg32 = ath_reg_rd(RST_RESET_ADDRESS);
reg32 = reg32 | RST_RESET_USB_PHY_PLL_PWD_EXT_SET(1);
ath_reg_wr_nf(RST_RESET_ADDRESS, reg32);
reg32 = ath_reg_rd(RST_CLKGAT_EN_ADDRESS);
reg32 = reg32 & ~(RST_CLKGAT_EN_PCIE_EP_SET(1) | RST_CLKGAT_EN_PCIE_RC_SET(1) |
RST_CLKGAT_EN_PCIE_RC2_SET(1) | RST_CLKGAT_EN_CLK100_PCIERC_SET(1) |
RST_CLKGAT_EN_CLK100_PCIERC2_SET(1) | RST_CLKGAT_EN_USB1_SET(1) |
RST_CLKGAT_EN_USB2_SET(1));
ath_reg_wr_nf(RST_CLKGAT_EN_ADDRESS, reg32);
reg32 = ath_reg_rd(RST_RESET2_ADDRESS);
reg32 = reg32 | RST_RESET2_USB_PHY2_PLL_PWD_EXT_SET(1);
ath_reg_wr_nf(RST_RESET2_ADDRESS, reg32);
ath_reg_wr_nf(BIAS4_ADDRESS, 0x6df6ffe0);
ath_reg_wr_nf(BIAS5_ADDRESS, 0x7ffffffe);
#endif
ath_gpio_config();
#endif /* !defined(CONFIG_ATH_EMULATION) */
return ath_ddr_find_size();
}
phys_size_t initdram(int board_type)
{
return (ath_mem_config());
}
int checkboard(args)
{
board_str(CONFIG_BOARD_NAME);
return 0;
}

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <common.h>
#include <command.h>
#include <asm/mipsregs.h>
#include <asm/addrspace.h>
#include <config.h>
#include <version.h>
#include <atheros.h>
#ifdef CONFIG_ATH_NAND_BR
#include <nand.h>
#endif
#ifdef CONFIG_ATH_NAND_BR
void *
ath_get_nand_cal_data(void)
{
extern unsigned long long ath_nand_get_cal_offset(const char *ba);
ulong off,size;
int ret;
static u_char nand_cal_data[256 * 1024];
nand_info_t *nand;
/*
* caldata partition is of 128k
*
*/
nand = &nand_info[nand_curr_device];
size = nand->erasesize;
/*
* Get the Offset of Caldata partition
*/
off = ath_nand_get_cal_offset(getenv("bootargs"));
if(off == ATH_CAL_OFF_INVAL) {
printf("Invalid CAL offset \n");
return 1;
}
/*
* Get the values from flash, and program into the MAC address
* registers
*/
ret = nand_read(nand, (loff_t)off, &size, nand_cal_data);
printf(" %d bytes %s: %s\n", size,
"read", ret ? "ERROR" : "OK");
if(ret != 0 ) {
return NULL;
}
return nand_cal_data;
}
#endif
int ath_set_tuning_caps(void)
{
typedef struct {
u_int8_t pad[0x28],
params_for_tuning_caps[2],
featureEnable;
} __attribute__((__packed__)) ar9300_eeprom_t;
ar9300_eeprom_t *eep;
uint32_t val;
#ifdef CONFIG_ATH_NAND_BR
eep = (ar9300_eeprom_t *)ath_get_nand_cal_data();
#else
eep = (ar9300_eeprom_t *)WLANCAL;
#endif /* CONFIG_ATH_NAND_BR */
val = XTAL_TCXODET_SET(0x0) |
XTAL_XTAL_CAPINDAC_SET(0x4b) |
XTAL_XTAL_CAPOUTDAC_SET(0x4b) |
XTAL_XTAL_DRVSTR_SET(0x0) |
XTAL_XTAL_SHORTXIN_SET(0x0) |
XTAL_XTAL_LOCALBIAS_SET(0x1) |
XTAL_XTAL_PWDCLKD_SET(0x0) |
XTAL_XTAL_BIAS2X_SET(0x0) |
XTAL_XTAL_LBIAS2X_SET(0x0) |
XTAL_XTAL_SELVREG_SET(0X0) |
XTAL_XTAL_OSCON_SET(0x1) |
XTAL_XTAL_PWDCLKIN_SET(0x0) |
XTAL_LOCAL_XTAL_SET(0x0) |
XTAL_PWD_SWREGCLK_SET(0x0) |
XTAL_LOCAL_EXT_CLK_OUT_EN_SET(0X0) |
XTAL_EXT_CLK_OUT_EN_SET(0X0) |
XTAL_XTAL_SVREG_SET(0X0) |
XTAL_RBK_UDSEL_SET(0X0) |
XTAL_SPARE_SET(0x0);
/* checking feature enable bit 6 and caldata is valid */
if ((eep->featureEnable & 0x40) && (eep->pad[0x0] != 0xff)) {
val &= ~(XTAL_XTAL_CAPINDAC_MASK | XTAL_XTAL_CAPOUTDAC_MASK);
val |= XTAL_XTAL_CAPINDAC_SET(eep->params_for_tuning_caps[0]) |
XTAL_XTAL_CAPOUTDAC_SET(eep->params_for_tuning_caps[0]);
}
ath_reg_wr(XTAL_ADDRESS, val);
ath_reg_wr(XTAL2_ADDRESS, XTAL2_DCA_BYPASS_SET(0x1) |
XTAL2_FSM_START_L_SET(0x1));
ath_reg_wr(XTAL3_ADDRESS, XTAL3_EVAL_LENGTH_SET(0x400) |
XTAL3_HARMONIC_NUMBER_SET(0xa2));
#define __str(x) # x
#define str(x) __str(x)
#if defined(CONFIG_AP151)
val = ath_reg_rd(GPIO_FUNCTION_ADDRESS);
ath_reg_wr(GPIO_FUNCTION_ADDRESS, val | 0x2);
#endif
printf("Setting " str(XTAL_ADDRESS) " to 0x%x\n", val);
return 0;
}

View file

@ -64,6 +64,11 @@
#ifdef CONFIG_AVR32
#include <asm/arch/mmu.h>
#endif
#if defined(CONFIG_MIPS) && defined(CONFIG_MACH_QCA956x)
int ath_set_tuning_caps(void);
#else
#define ath_set_tuning_caps() /* nothing */
#endif
DECLARE_GLOBAL_DATA_PTR;
@ -949,6 +954,9 @@ init_fnc_t init_sequence_r[] = {
#endif
#if defined(CONFIG_SPARC)
prom_init,
#endif
#if defined(CONFIG_MIPS) && defined(CONFIG_MACH_QCA956x)
ath_set_tuning_caps,
#endif
run_main_loop,
};

16
configs/qca956x_defconfig Normal file
View file

@ -0,0 +1,16 @@
CONFIG_MIPS=y
CONFIG_TARGET_QCA956X=y
CONFIG_SYS_EXTRA_OPTIONS="QCA956X"
CONFIG_SYS_PROMPT="QCA9563# "
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_ELF is not set
# CONFIG_CMD_RUN is not set
# CONFIG_CMD_SAVEENV is not set
# CONFIG_CMD_LOADB is not set
# CONFIG_CMD_LOADS is not set
# CONFIG_CMD_FLASH is not set
# CONFIG_CMD_FPGA is not set
# CONFIG_CMD_SETEXPR is not set
CONFIG_USE_PRIVATE_LIBGCC=y
CONFIG_SYS_MALLOC_F_LEN=0x200
CONFIG_SYS_MALLOC_F=y

View file

@ -155,6 +155,7 @@ serial_initfunc(sh_serial_initialize);
serial_initfunc(stm32_serial_initialize);
serial_initfunc(uartlite_serial_initialize);
serial_initfunc(zynq_serial_initialize);
serial_initfunc(qca_serial_initialize);
/**
* serial_register() - Register serial driver with serial driver core
@ -246,6 +247,7 @@ void serial_initialize(void)
stm32_serial_initialize();
uartlite_serial_initialize();
zynq_serial_initialize();
qca_serial_initialize();
serial_assign(default_serial_console()->name);
}

4538
include/956x.h Normal file

File diff suppressed because it is too large Load diff

355
include/atheros.h Normal file
View file

@ -0,0 +1,355 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _ATHEROS_H
#define _ATHEROS_H
/*
* Set everything to zero. The corresponding header will
* undef and re-define the appropriate ones
*/
#define is_ar7100() (0)
#define is_ar7240() (0)
#define is_ar7241() (0)
#define is_ar7242() (0)
#define is_ar9330() (0)
#define is_ar933x() (0)
#define is_hornet() (0)
#define is_ar934x() (0)
#define is_wasp() (0)
#define is_qca955x() (0)
#define is_sco() (0)
#define is_qca953x() (0)
#define is_hb() (0)
#define is_qca956x() (0)
#define ATH_CONSOLE_BAUD 115200
#define AR7240_REV_1_2 0xc2
#ifdef CONFIG_ATH_EMULATION
#define is_emu() (1)
#else
#define is_emu() (0)
#endif
#ifdef CONFIG_F1E_PHY
#define is_f1e() 1
#else
#define is_f1e() 0
#endif
#ifdef CONFIG_F2E_PHY
#define is_f2e() 1
#else
#define is_f2e() 0
#endif
#ifdef CONFIG_ATHRS16_PHY
#define is_s16() 1
#else
#define is_s16() 0
#endif
#ifdef CONFIG_ATHRS17_PHY
#define is_s17() 1
#else
#define is_s17() 0
#endif
#ifdef CONFIG_ATHR_8033_PHY
#define is_ar8033() 1
#else
#define is_ar8033() 0
#endif
#ifdef CONFIG_VIR_PHY
#define is_vir_phy() 1
#else
#define is_vir_phy() 0
#endif
#ifdef CFG_ATHRS27_PHY
#define is_s27() 1
#else
#define is_s27() 0
#endif
#define ath_arch_init_irq() /* nothing */
#ifndef __ASSEMBLY__
int ath_uart_freq(void);
typedef unsigned int ath_reg_t;
#ifdef COMPRESSED_UBOOT
# define prmsg(...)
#else
# define prmsg printf
#endif
#endif /* __ASSEMBLY__ */
#define ath_reg_rd(_phys) (*(volatile ath_reg_t *)KSEG1ADDR(_phys))
#define ath_reg_wr_nf(_phys, _val) \
((*(volatile ath_reg_t *)KSEG1ADDR(_phys)) = (_val))
#define ath_reg_wr(_phys, _val) do { \
ath_reg_wr_nf(_phys, _val); \
ath_reg_rd(_phys); \
} while(0)
#define ath_reg_rmw_set(_reg, _mask) do { \
ath_reg_wr((_reg), (ath_reg_rd((_reg)) | (_mask))); \
ath_reg_rd((_reg)); \
} while(0)
#define ath_reg_rmw_clear(_reg, _mask) do { \
ath_reg_wr((_reg), (ath_reg_rd((_reg)) & ~(_mask))); \
ath_reg_rd((_reg)); \
} while(0)
#define ath_uart_rd(y) ath_reg_rd((ATH_UART_BASE+y))
#define ath_uart_wr(x, z) ath_reg_wr((ATH_UART_BASE+x), z)
#define REG_OFFSET 4
#define OFS_RCV_BUFFER (0 * REG_OFFSET)
#define OFS_TRANS_HOLD (0 * REG_OFFSET)
#define OFS_SEND_BUFFER (0 * REG_OFFSET)
#define OFS_INTR_ENABLE (1 * REG_OFFSET)
#define OFS_INTR_ID (2 * REG_OFFSET)
#define OFS_DATA_FORMAT (3 * REG_OFFSET)
#define OFS_LINE_CONTROL (3 * REG_OFFSET)
#define OFS_MODEM_CONTROL (4 * REG_OFFSET)
#define OFS_RS232_OUTPUT (4 * REG_OFFSET)
#define OFS_LINE_STATUS (5 * REG_OFFSET)
#define OFS_MODEM_STATUS (6 * REG_OFFSET)
#define OFS_RS232_INPUT (6 * REG_OFFSET)
#define OFS_SCRATCH_PAD (7 * REG_OFFSET)
#define OFS_DIVISOR_LSB (0 * REG_OFFSET)
#define OFS_DIVISOR_MSB (1 * REG_OFFSET)
/*
* PLL Config for different CPU/DDR/AHB frequencies
*/
#define CFG_PLL_720_600_200 0x01
#define CFG_PLL_720_680_240 0x02
#define CFG_PLL_720_600_240 0x03
#define CFG_PLL_680_680_226 0x04
#define CFG_PLL_720_600_300 0x05
#define CFG_PLL_400_400_200 0x06
#define CFG_PLL_560_450_220 0x07
#define CFG_PLL_550_400_200 0x08
#define CFG_PLL_550_600_200 0x09
#define CFG_PLL_600_600_200 0x0a
#define CFG_PLL_750_400_250 0x0b
#define CFG_PLL_800_400_266 0x0c
#define CFG_PLL_750_667_250 0x0d
#define CFG_PLL_800_600_266 0x0e
#define CFG_PLL_800_667_266 0x0f
#define CFG_PLL_810_700_270 0x10
#define CFG_PLL_810_666_270 0x11
#define CFG_PLL_775_650_258 0x12
#define CFG_PLL_650_400_200 0x13
#define CFG_PLL_650_600_200 0x14
#define UBOOT_SIZE (256 * 1024)
#define PLL_FLASH_ADDR (CFG_FLASH_BASE + UBOOT_SIZE)
#define PLL_CONFIG_VAL_F (PLL_FLASH_ADDR + CFG_FLASH_SECTOR_SIZE - 0x20)
#define PLL_MAGIC 0xaabbccdd
#define SRIF_PLL_CONFIG_VAL_F (PLL_CONFIG_VAL_F - 12)
#define SRIF_PLL_MAGIC 0x73726966 /* srif */
#include <config.h>
#if defined(CONFIG_MACH_AR724x)
# include <724x.h>
#elif defined(CONFIG_MACH_AR933x)
# include <933x.h>
#elif defined(CONFIG_MACH_AR934x)
# include <934x.h>
#elif defined(CONFIG_MACH_QCA955x)
# include <955x.h>
#elif defined(CONFIG_MACH_QCA953x)
# include <953x.h>
#elif defined(CONFIG_MACH_QCA956x)
# include <956x.h>
#else
# error "Building U-Boot for unknown device"
#endif
#ifndef __ASSEMBLY__
#define ATH_MEM_SDRAM 1
#define ATH_MEM_DDR1 2
#define ATH_MEM_DDR2 3
/*
* GPIO Access & Control
*/
void ath_gpio_init(void);
void ath_gpio_down(void);
void ath_gpio_up(void);
void ath_gpio_irq_init(int);
/*
* GPIO Helper Functions
*/
void ath_gpio_enable_slic(void);
/* enable UART block, takes away GPIO 10 and 9 */
void ath_gpio_enable_uart(void);
/* enable STEREO block, takes away GPIO 11,8,7, and 6 */
void ath_gpio_enable_stereo(void);
/* allow CS0/CS1 to be controlled via SPI register, takes away GPIO0/GPIO1 */
void ath_gpio_enable_spi_cs1_cs0(void);
/* allow GPIO0/GPIO1 to be used as SCL/SDA for software based i2c */
void ath_gpio_enable_i2c_on_gpio_0_1(void);
/*
* GPIO General Functions
*/
void ath_gpio_drive_low(unsigned int mask);
void ath_gpio_drive_high(unsigned int mask);
unsigned int ath_gpio_float_high_test(unsigned int mask);
/* Functions to access SPI through software. Example:
*
* ath_spi_down(); ---------------------- disable others from accessing SPI bus taking semaphore
* ath_spi_enable_soft_access(); -------- disable HW control of SPI
*
* <board specific chip select routine>
*
* <read/write SPI using using custom routine or general purposeflash routines
* Custom routine may use:
*
* ath_spi_raw_output_u8(unsigned char)
* ath_spi_raw_output_u32(unsigned int)
* ath_spi_raw_input_u32()
*
* General purpose flash routines:
* ath_spi_flash_read_page(unsigned int addr, unsigned char *data, int len);
* ath_spi_flash_write_page(unsigned int addr, unsigned char *data, int len);
* ath_spi_flash_sector_erase(unsigned int addr);
* >
*
* <board specific chip deselect routine>
*
* ath_spi_disable_soft_acess(); ------- enable HW control of SPI bus
* ath_spi_up(); ----------------------- enable others to access SPI bus releasing semaphore
*/
void ath_spi_init(void);
void ath_spi_down(void);
void ath_spi_up(void);
static inline void
ath_spi_enable_soft_access(void)
{
ath_reg_wr_nf(ATH_SPI_FS, 1);
}
static inline void
ath_spi_disable_soft_access(void)
{
ath_reg_wr_nf(ATH_SPI_WRITE, ATH_SPI_CS_DIS);
ath_reg_wr_nf(ATH_SPI_FS, 0);
}
void ath_spi_raw_output_u8(unsigned char val);
void ath_spi_raw_output_u32(unsigned int val);
unsigned int ath_spi_raw_input_u8(void);
unsigned int ath_spi_raw_input_u32(void);
void ath_spi_flash_read_page(unsigned int addr, unsigned char *data, int len);
void ath_spi_flash_write_page(unsigned int addr, unsigned char *data, int len);
void ath_spi_flash_sector_erase(unsigned int addr);
/*
* Allow access to cs0-2 when GPIO Function enables cs0-2 through SPI register.
*/
static inline void
ath_spi_enable_cs0(void)
{
unsigned int cs;
ath_spi_down();
ath_spi_enable_soft_access();
cs = ath_reg_rd(ATH_SPI_WRITE) & ~ATH_SPI_CS_DIS;
ath_reg_wr_nf(ATH_SPI_WRITE, ATH_SPI_CS_ENABLE_0 | cs);
}
static inline void
ath_spi_enable_cs1(void)
{
unsigned int cs;
#if defined(CONFIG_MACH_AR934x) || \
defined(CONFIG_MACH_QCA955x)
ath_spi_down();
ath_spi_init();
ath_spi_enable_soft_access();
cs = ath_reg_rd(ATH_SPI_WRITE) & ATH_SPI_CS_DIS;
ath_reg_wr_nf(ATH_SPI_WRITE, cs | ATH_SPI_CLK_HIGH);
cs = ath_reg_rd(ATH_SPI_WRITE) & ~ATH_SPI_CS_DIS;
ath_reg_wr_nf(ATH_SPI_WRITE, ATH_SPI_CS_ENABLE_1 | cs | ATH_SPI_CLK_HIGH);
ath_reg_wr_nf(ATH_SPI_WRITE, ATH_SPI_CS_ENABLE_1 | cs);
#else
ath_spi_down();
ath_spi_enable_soft_access();
cs = ath_reg_rd(ATH_SPI_WRITE) & ~ATH_SPI_CS_DIS;
ath_reg_wr_nf(ATH_SPI_WRITE, ATH_SPI_CS_ENABLE_1 | cs);
#endif
}
static inline void
ath_spi_disable_cs(void)
{
unsigned int cs = ath_reg_rd(ATH_SPI_WRITE) | ATH_SPI_CS_DIS;
ath_reg_wr_nf(ATH_SPI_WRITE, cs);
ath_spi_disable_soft_access();
ath_spi_up();
}
/*
* Example usage to access BOOT flash
*/
static inline void
ath_spi_flash_cs0_sector_erase(unsigned int addr)
{
ath_spi_enable_cs0();
ath_spi_flash_sector_erase(addr);
ath_spi_disable_cs();
}
static inline void
ath_spi_flash_cs0_write_page(unsigned int addr, unsigned char *data, int len)
{
ath_spi_enable_cs0();
ath_spi_flash_write_page(addr, data, len);
ath_spi_disable_cs();
}
#endif /* __ASSEMBLY__ */
#endif /* _ATHEROS_H */

View file

@ -24,6 +24,7 @@ typedef volatile unsigned char vu_char;
#include <asm/ptrace.h>
#include <stdarg.h>
#include <linux/kernel.h>
#if defined(CONFIG_PCI) && defined(CONFIG_4xx)
#include <pci.h>
#endif

179
include/configs/qca956x.h Normal file
View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2016 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#define CONFIG_MIPS32 1 /* MIPS32 CPU core */
#define CONFIG_BOOTDELAY 2 /* autoboot after 4 seconds */
#define CONFIG_TIMESTAMP /* Print image info with timestamp */
#define CONFIG_MII 1
#define CFG_CMD_MII 1
#define CONFIG_COMMANDS 1
#define CFG_DDR2_DRAGONFLY_CAS_LATENCY 5
#define CFG_ATH_GMAC_NMACS 1
#define CFG_ATH_GE1_IS_CONNECTED 1
#define CONFIG_ATHRS_GMAC_SGMII 1
#define ATH_S17_MAC0_SGMII 1
#define CONFIG_ATHRS_GMAC_SGMII 1
#define CONFIG_ATHRS17_PHY 1
#define ATH_SGMII_FORCED_MODE 1
#define CONFIG_SYS_RX_ETH_BUFFER 8
#define CONFIG_TFTP_BLOCKSIZE 512
#define CONFIG_SYS_CACHELINE_SIZE 32
#define CONFIG_SYS_ICACHE_SIZE 65536
#define CONFIG_SYS_DCACHE_SIZE 32768
#define CONFIG_SYS_LOAD_ADDR 0x81000000
#define CONFIG_LZMA 1
#define CONFIG_ATHEROS 1
#define CONFIG_IMAGE_FORMAT_LEGACY
#define CONFIG_SYS_SDRAM_BASE 0x80000000
#define CONFIG_SYS_INIT_SP_OFFSET 0xbd001800 // Redundant ?
#define CFG_INIT_SRAM_SP_OFFSET 0xbd001800
#define CONFIG_SYS_MAXARGS 16
#define CONFIG_SYS_FLASH_BASE 0x9f000000
#define CONFIG_SYS_MAX_FLASH_BANKS 1
#define CONFIG_SYS_MAX_FLASH_SECT 256
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_BAUDRATE_TABLE {115200}
#define UART_RX18_TX22 1
/* Console I/O Buffer Size */
#define CONFIG_SYS_CBSIZE 512
/* Print Buffer Size */
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16)
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_SYS_PROMPT_HUSH_PS2 "hush>"
/* Timer Specific */
#define CONFIG_SYS_MHZ 775
/* Since the count is incremented every other tick, divide by 2 -- CFG_HZ*/
#define CONFIG_SYS_MIPS_TIMER_FREQ ((CONFIG_SYS_MHZ * 1000000)/2)
/*
* The following #defines are needed to get flash environment right
*/
#define CONFIG_SYS_MONITOR_BASE 0x9f000000
#define CONFIG_SYS_MONITOR_LEN (192 << 10)
#define CONFIG_SYS_MALLOC_LEN (128*1024)
#ifndef FLASH_SIZE
#define FLASH_SIZE 16
#endif
/*-----------------------------------------------------------------------
* FLASH and environment organization
*/
#define CFG_MAX_FLASH_BANKS 1 /* max number of memory banks */
#if (FLASH_SIZE == 16)
#define CFG_MAX_FLASH_SECT 256 /* max number of sectors on one chip */
#define ATH_MTDPARTS_MIB0 "64k(mib0)"
#elif (FLASH_SIZE == 8)
#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */
#define ATH_MTDPARTS_MIB0 "64k(mib0)"
#elif (FLASH_SIZE == 4)
#define CFG_MAX_FLASH_SECT 64 /* max number of sectors on one chip */
#define ATH_MTDPARTS_MIB0 "64k(mib0)"
#elif (FLASH_SIZE == 2)
#define CFG_MAX_FLASH_SECT 32 /* max number of sectors on one chip */
#define ATH_MTDPARTS_MIB0 "64k(mib0)"
#else
# error "Invalid flash Size/sector "
#endif
#define CFG_FLASH_SECTOR_SIZE (64*1024)
#if (FLASH_SIZE == 16)
#define CFG_FLASH_SIZE 0x01000000 /* Total flash size */
#elif (FLASH_SIZE == 8)
#define CFG_FLASH_SIZE 0x00800000 /* max number of sectors on one chip */
#elif (FLASH_SIZE == 4)
#define CFG_FLASH_SIZE 0x00400000 /* Total flash size */
#elif (FLASH_SIZE == 2)
#define CFG_FLASH_SIZE 0x00200000 /* Total flash size */
#else
# error "Invalid flash Size "
#endif
#if defined(CONFIG_ATH_NAND_BR) && defined(COMPRESSED_UBOOT)
#define CFG_FLASH_BASE 0xa0100000
#else
/* NOR Flash start address */
#define CFG_FLASH_BASE 0x9f000000
#endif
#ifdef COMPRESSED_UBOOT
#define BOOTSTRAP_TEXT_BASE CFG_FLASH_BASE
#define BOOTSTRAP_CFG_MONITOR_BASE BOOTSTRAP_TEXT_BASE
#endif
/*
* Defines to change flash size on reboot
*/
#ifdef ENABLE_DYNAMIC_CONF
#define UBOOT_FLASH_SIZE (256 * 1024)
#define UBOOT_ENV_SEC_START (CFG_FLASH_BASE + UBOOT_FLASH_SIZE)
#define CFG_FLASH_MAGIC 0xaabacada
#define CFG_FLASH_MAGIC_F (UBOOT_ENV_SEC_START + CFG_FLASH_SECTOR_SIZE - 0x20)
#define CFG_FLASH_SECTOR_SIZE_F *(volatile int *)(CFG_FLASH_MAGIC_F + 0x4)
#define CFG_FLASH_SIZE_F *(volatile int *)(CFG_FLASH_MAGIC_F + 0x8) /* Total flash size */
#define CFG_MAX_FLASH_SECT_F (CFG_FLASH_SIZE / CFG_FLASH_SECTOR_SIZE) /* max number of sectors on one chip */
#else
#define CFG_FLASH_SIZE_F CFG_FLASH_SIZE
#define CFG_FLASH_SECTOR_SIZE_F CFG_FLASH_SECTOR_SIZE
#endif
#define CONFIG_ENV_IS_NOWHERE 1
#define CONFIG_SYS_NO_FLASH 1
//#define CONFIG_ENV_IS_IN_FLASH 1
#define CONFIG_ENV_SIZE CFG_FLASH_SECTOR_SIZE //CFG_ENV_SIZE
#define CONFIG_ENV_ADDR 0x9f040000
#define CONFIG_SYS_TEXT_BASE 0x9f000000
#define CONFIG_ATH_SOC 1
#define CONFIG_MACH_QCA956x 1
// DDR2
// 0x40c3 25MHz
// 0x4138 40MHz
// DDR1
// 0x4186 25Mhz
// 0x4270 40Mhz
#define CFG_DDR_REFRESH_VAL 0x4186
#define CFG_DDR2_REFRESH_VAL 0x40c3
#define __CONFIG_BOARD_NAME ap152
#define CONFIG_BOARD_NAME "ap152"
/*
** Parameters defining the location of the calibration/initialization
** information for the two Merlin devices.
** NOTE: **This will change with different flash configurations**
*/
#define WLANCAL 0x9fff1000
/* For Merlin, both PCI, PCI-E interfaces are valid */
#define ATH_ART_PCICFG_OFFSET 12