MIPS: qca955x: Enable Support for AP135 target

this change enables the support for the AP135 target

Change-Id: I772cdf3a135ac327fec21c42be6248f22d3d3f83
Signed-off-by: Prabhu Jayakumar <pjayak@codeaurora.org>
This commit is contained in:
Prabhu Jayakumar 2016-11-10 14:08:01 +05:30 committed by Gerrit - the friendly Code Review server
parent b0333e0960
commit 44bdfc09e8
17 changed files with 7245 additions and 0 deletions

View file

@ -50,6 +50,12 @@ config TARGET_QCA956X
select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2
config TARGET_QCA955X
bool "Support QCA955X"
select SUPPORTS_BIG_ENDIAN
select SUPPORTS_CPU_MIPS32_R1
select SUPPORTS_CPU_MIPS32_R2
config TARGET_PB1X00
bool "Support pb1x00"
select SUPPORTS_LITTLE_ENDIAN
@ -66,6 +72,7 @@ source "board/micronas/vct/Kconfig"
source "board/pb1x00/Kconfig"
source "board/qemu-mips/Kconfig"
source "board/qca/mips32/qca956x/Kconfig"
source "board/qca/mips32/qca955x/Kconfig"
if MIPS

View file

@ -0,0 +1,173 @@
/*
* 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 <prototypes.h>
//#include <gmac_defines.h>
//#include <config.h>
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <command.h>
#include <asm/io.h>
#include <asm/addrspace.h>
#include <asm/types.h>
#include <atheros.h>
#include "ath_phy.h"
#include "athrs17_phy.h"
uint32_t athrs17_reg_read(uint32_t reg_addr);
void athrs17_reg_write(uint32_t reg_addr, uint32_t reg_val);
#ifdef ATH_RGMII_CAL
# define ATHR_PHY_MAX 1
void s17_reg_rmw(unsigned int reg_addr, unsigned int reg_val)
{
reg_val |= athrs17_reg_read(reg_addr);
athrs17_reg_write(reg_addr,reg_val);
}
void init_s17(void)
{
int phyUnit = 0;
int phyBase = 0;
int phyAddr = 0;
unsigned int rddata;
athrs17_reg_write(0x624 , 0x003f3f3f);
athrs17_reg_write(0x10 , 0x40000000);
athrs17_reg_write(0x4 , 0x07500000);
athrs17_reg_write(0xc , 0x01000000);
athrs17_reg_write(0x7c , 0x000000fe); // 1gbps
//athrs17_reg_write(0x7c , 0x0000007d); // 100 mbps
//athrs17_reg_write(0x7c , 0x0000007c); // 10 mbps
for (phyUnit= 0; phyUnit <= ATHR_PHY_MAX; phyUnit++)
{
phyBase = 0;
phyAddr = phyUnit;
// To enable loopback on a phy
// rddata = s17_phy_read(phyAddr, 0x0);
// s17_phy_write(phyAddr, 0x0, (rddata | (1 << 14)));
/* For 100M waveform */
phy_reg_write(0, phyAddr, 0x1d, 0x18);
phy_reg_write(0, phyAddr, 0x1e, 0x02ea);
/* Turn On Gigabit Clock */
phy_reg_write(0, phyAddr, 0x1d, 0x3d);
phy_reg_write(0, phyAddr, 0x1e, 0x48a0);
}
/* Enable flow control */
s17_reg_rmw(0x80,0x30);
s17_reg_rmw(0x84,0x30);
s17_reg_rmw(0x88,0x30);
s17_reg_rmw(0x8c,0x30);
s17_reg_rmw(0x90,0x30);
}
void vlan_config(void)
{
athrs17_reg_write(S17_P0LOOKUP_CTRL_REG, 0x0014001e);
athrs17_reg_write(S17_P0VLAN_CTRL0_REG, 0x10001);
athrs17_reg_write(S17_P1LOOKUP_CTRL_REG, 0x0014001d);
athrs17_reg_write(S17_P1VLAN_CTRL0_REG, 0x10001);
athrs17_reg_write(S17_P2LOOKUP_CTRL_REG, 0x0014001b);
athrs17_reg_write(S17_P2VLAN_CTRL0_REG, 0x10001);
athrs17_reg_write(S17_P3LOOKUP_CTRL_REG, 0x00140017);
athrs17_reg_write(S17_P3VLAN_CTRL0_REG, 0x10001);
athrs17_reg_write(S17_P4LOOKUP_CTRL_REG, 0x0014000f);
athrs17_reg_write(S17_P4VLAN_CTRL0_REG, 0x10001);
athrs17_reg_write(S17_P5LOOKUP_CTRL_REG, 0x00140040);
athrs17_reg_write(S17_P5VLAN_CTRL0_REG, 0x20001);
athrs17_reg_write(S17_P6LOOKUP_CTRL_REG, 0x00140020);
athrs17_reg_write(S17_P6VLAN_CTRL0_REG, 0x20001);
}
void init_s17_lpbk(void)
{
int phyUnit = 0;
int phyBase = 0;
int phyAddr = 0;
unsigned int rddata;
#ifdef ATH_S17_MAC0_SGMII
athrs17_reg_write(0x4 , 0x080080);
athrs17_reg_write(0xc , 0x07600000);
athrs17_reg_write(0x94 , 0x000000fe); // 1gbps
athrs17_reg_write(0x624 , 0x007f7f7f);
printf ("Vlan config...\n");
vlan_config();
#else
athrs17_reg_write(0x624 , 0x003f3f3f);
athrs17_reg_write(0x4 , 0x07500000);
athrs17_reg_write(0xc , 0x01000000);
#endif
athrs17_reg_write(0x10 , 0x4000000);
athrs17_reg_write(0x7c , 0x000000fe); // 1gbps
//athrs17_reg_write(0x7c , 0x0000007d); // 100 mbps
//athrs17_reg_write(0x7c , 0x0000007c); // 10 mbps
phyBase = 0;
#ifdef ATH_S17_MAC0_SGMII
phyAddr = 4;
#else
phyAddr = 0;
#endif
// To enable loopback on single phy
phy_reg_write(0, phyAddr, 0x0, 0xc140);
for(rddata=0; rddata<1000; rddata++);
phy_reg_write(0, phyAddr, 0x0, 0x4140);
for(rddata=0; rddata<1000; rddata++);
rddata = phy_reg_read(0, phyAddr, 0x0);
#ifdef DEBUG
printf("s17 phy0 register value 0x%08x\n", rddata);
#endif
#ifndef CONFIG_MACH_QCA955x
// power down other phys
#ifdef ATH_S17_MAC0_SGMII
phy_reg_write(0, 0x0, 0x0, 0x8800);
#else
phy_reg_write(0, 0x4, 0x0, 0x8800);
#endif
phy_reg_write(0, 0x1, 0x0, 0x8800);
phy_reg_write(0, 0x2, 0x0, 0x8800);
phy_reg_write(0, 0x3, 0x0, 0x8800);
#endif
/* For 100M waveform */
phy_reg_write(0, phyAddr, 0x1d, 0x18);
phy_reg_write(0, phyAddr, 0x1e, 0x02ea);
/* Turn On Gigabit Clock */
phy_reg_write(0, phyAddr, 0x1d, 0x3d);
phy_reg_write(0, phyAddr, 0x1e, 0x48a0);
/* Enable flow control */
s17_reg_rmw(0x80,0x30);
s17_reg_rmw(0x84,0x30);
s17_reg_rmw(0x88,0x30);
s17_reg_rmw(0x8c,0x30);
s17_reg_rmw(0x90,0x30);
}
#endif /* #ifdef RGMII_CAL */

View file

@ -0,0 +1,167 @@
/*
* 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(4) | \
BB_DPLL2_KD_SET(0x60) | \
BB_DPLL2_PLL_PWD_SET(1) | \
BB_DPLL2_DELTA_SET(0x1e));
reg_write(PCIe_DPLL2_ADDRESS, PCIe_DPLL2_KI_SET(4) | \
PCIe_DPLL2_KD_SET(0x60) | \
PCIe_DPLL2_PLL_PWD_SET(1) | \
PCIe_DPLL2_DELTA_SET(0x1e));
reg_write(DDR_DPLL2_ADDRESS, DDR_DPLL2_KI_SET(4) | \
DDR_DPLL2_KD_SET(0x60) | \
DDR_DPLL2_PLL_PWD_SET(1) | \
DDR_DPLL2_DELTA_SET(0x1e));
reg_write(CPU_DPLL2_ADDRESS, CPU_DPLL2_KI_SET(4) | \
CPU_DPLL2_KD_SET(0x60) | \
CPU_DPLL2_PLL_PWD_SET(1) | \
CPU_DPLL2_DELTA_SET(0x1e));
li t5, CPU_PLL_CONFIG_NINT_VAL
li t6, DDR_PLL_CONFIG_NINT_VAL
li t4, CPU_PLL_DITHER_VAL
li t3, DDR_PLL_DITHER_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);
or t8, t8, t5
sw t8, 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);
or t8, t8, t6
sw t8, 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));
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));
ddr_pll_dither_unset:
li t7, KSEG1ADDR(DDR_PLL_DITHER_ADDRESS);
sw t3, 0(t7);
cpu_pll_dither_unset:
li t7, KSEG1ADDR(CPU_PLL_DITHER_ADDRESS);
sw t4, 0(t7);
#endif /* !defined(CONFIG_ATH_NAND_BR) */
#endif /* !defined(CONFIG_ATH_EMULATION) */
jr ra
nop

View file

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

View file

@ -0,0 +1,42 @@
BOARD=board955x
COMPRESSED_UBOOT=0
ETH_CONFIG=_s17
obj-y = \
$(BOARD).o \
flash.o \
extra.o \
init-955x.o \
../common/ath_serial.o \
../common/ath_pci.o \
../common/qca-mach-common.o \
../common/athrs17_lpbk.o \
rgmii-cal-955x.o \
qca-eth-955x.o
ifeq ($(ATH_DUAL_FLASH),1)
OBJS += ../common/ath_nand.o ../../../drivers/nand/nand_ids.o
endif
ifndef BOOT_FROM_NAND
obj-y += ../common/ath_flash.o
endif
ifeq ($(ATH_RGMII_CAL),1)
obj-y += rgmii-cal-955x.o
obj-y += ../common/athrs17_lpbk.o
endif
ifeq ($(ETH_CONFIG2), _s17)
OBJS += ../common/athrs17_phy.o
endif
ifeq ($(ETH_CONFIG), _s17)
obj-y += ../common/athrs17_phy.o
endif
ifeq ($(ETH_CONFIG), _s27)
OBJS += ../common/athr_s27_phy.o
endif
obj-y += 955x.o tap-955x.o

View file

@ -0,0 +1,157 @@
/*
* 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 " - Scorpion 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 " - Scorpion 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)
{
/* disable the CLK_OBS on GPIO_4 and set GPIO4 as input */
ath_reg_rmw_clear(GPIO_OE_ADDRESS, (1 << 4));
ath_reg_rmw_clear(GPIO_OUT_FUNCTION1_ADDRESS, GPIO_OUT_FUNCTION1_ENABLE_GPIO_4_MASK);
ath_reg_rmw_set(GPIO_OUT_FUNCTION1_ADDRESS, GPIO_OUT_FUNCTION1_ENABLE_GPIO_4_SET(0x80));
ath_reg_rmw_set(GPIO_OE_ADDRESS, (1 << 4));
/* Set GPIO 13 as input for LED functionality to be OFF during bootup */
ath_reg_rmw_set(GPIO_OE_ADDRESS, (1 << 13));
/* 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();
prmsg("tap = 0x%p\n", tap);
tap = (uint32_t *)0xbd007f10;
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[2], 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
ath_usb1_initial_config();
ath_usb2_initial_config();
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
void 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_DRVSTR_SET(0x3) |
XTAL_XTAL_CAPINDAC_SET(0x45) |
XTAL_XTAL_CAPOUTDAC_SET(0x45) |
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_ATBVREG_SET(0x0) |
XTAL_XTAL_OSCON_SET(0x1) |
XTAL_XTAL_PWDCLKIN_SET(0x0) |
XTAL_LOCAL_XTAL_SET(0x1) |
XTAL_PWD_SWREGCLK_SET(0x0) |
XTAL_SWREGCLK_EDGE_SEL_SET(0x0) |
XTAL_SPARE_SET(0xf);
/* checking feature enable bit 6 and caldata is valid */
if ((eep) && (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);
#define __str(x) # x
#define str(x) __str(x)
printf("Setting " str(XTAL_ADDRESS) " to 0x%x\n", val);
return;
}
#ifdef CONFIG_LAST_STAGE_INIT
int last_stage_init(void)
{
ath_set_tuning_caps();
return 0;
}
#endif

View file

@ -0,0 +1,46 @@
/*
* 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 <config.h>
#include <asm/types.h>
#include <flash.h>
#ifndef CONFIG_ATH_NAND_BR
/*
* sets up flash_info and returns size of FLASH (bytes)
*/
unsigned long
flash_get_geom (flash_info_t *flash_info)
{
int i;
/* XXX this is hardcoded until we figure out how to read flash id */
flash_info->flash_id = FLASH_M25P64;
flash_info->size = CFG_FLASH_SIZE; /* bytes */
flash_info->sector_count = flash_info->size / CFG_FLASH_SECTOR_SIZE;
for (i = 0; i < flash_info->sector_count; i++) {
flash_info->start[i] = CFG_FLASH_BASE +
(i * CFG_FLASH_SECTOR_SIZE);
flash_info->protect[i] = 0;
}
printf ("flash size %dMB, sector count = %d\n",
FLASH_SIZE, flash_info->sector_count);
return (flash_info->size);
}
#endif /* CONFIG_ATH_NAND_BR */

View file

@ -0,0 +1,476 @@
/*
* 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;
}
}
#define CFG_DDR2_SCORPION_CAS_LATENCY 4
#ifdef CONFIG_TB614
# define DDR_CONFIG2_SWAP_A26_A27_VAL (0x1)
#else
# define DDR_CONFIG2_SWAP_A26_A27_VAL (0x0)
#endif
#if CFG_DDR2_SCORPION_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(0xf) | \
DDR_CONFIG_TRFC_SET(0x15) | \
DDR_CONFIG_TRRD_SET(0x7) | \
DDR_CONFIG_TRP_SET(0x9) | \
DDR_CONFIG_TRCD_SET(0x9) | \
DDR_CONFIG_TRAS_SET(0x1b)
#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(0x15) | \
DDR_CONFIG2_TRTP_SET(0x9) | \
DDR_CONFIG2_TRTW_SET(0xe) | \
DDR_CONFIG2_TWR_SET(0x1) | \
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_VAL 0x402
#define CFG_DDR2_MODE_VAL_INIT 0x143
#define CFG_DDR2_MODE_VAL 0x43
#define CFG_DDR2_TAP_VAL 0x10
#define CFG_DDR2_EN_TWL_VAL 0x0000167d
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32 0xff
#elif CFG_DDR2_SCORPION_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(0xf) | \
DDR_CONFIG_TRFC_SET(0x15) | \
DDR_CONFIG_TRRD_SET(0x7) | \
DDR_CONFIG_TRP_SET(0x9) | \
DDR_CONFIG_TRCD_SET(0x9) | \
DDR_CONFIG_TRAS_SET(0x1b)
#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(0xb) | \
DDR_CONFIG2_TWTR_SET(0x15) | \
DDR_CONFIG2_TRTP_SET(0x9) | \
DDR_CONFIG2_TRTW_SET(0xe) | \
DDR_CONFIG2_TWR_SET(0x1) | \
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_VAL 0x402
#define CFG_DDR2_MODE_VAL_INIT 0x153
#define CFG_DDR2_MODE_VAL 0x53
#define CFG_DDR2_TAP_VAL 0x10
#define CFG_DDR2_EN_TWL_VAL 0x00001e7d
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_16 0xffff
#define CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32 0xff
#endif
#define CFG_DDR1_CONFIG_VAL DDR_CONFIG_OPEN_PAGE_SET(0x1) | \
DDR_CONFIG_CAS_LATENCY_SET(0x7) | \
DDR_CONFIG_TMRD_SET(0x5) | \
DDR_CONFIG_TRFC_SET(0x7) | \
DDR_CONFIG_TRRD_SET(0x4) | \
DDR_CONFIG_TRP_SET(0x6) | \
DDR_CONFIG_TRCD_SET(0x6) | \
DDR_CONFIG_TRAS_SET(0x10)
#define CFG_DDR1_CONFIG2_VAL DDR_CONFIG2_HALF_WIDTH_LOW_SET(0x1) | \
DDR_CONFIG2_GATE_OPEN_LATENCY_SET(0x6) | \
DDR_CONFIG2_TWTR_SET(0xe) | \
DDR_CONFIG2_TRTP_SET(0x8) | \
DDR_CONFIG2_TRTW_SET(0xe) | \
DDR_CONFIG2_TWR_SET(0xd) | \
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 0x0
#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 0x20
#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");
prmsg("Scorpion 1.%d\n", ath_reg_rd(RST_REVISION_ID_ADDRESS) & 0xf);
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_VAL;
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__);
if (RST_BOOTSTRAP_DDR_WIDTH_GET(bootstrap)) {
prmsg("32");
ctl_config = CFG_DDR_CTL_CONFIG |
DDR_CTL_CONFIG_PAD_DDR2_SEL_SET(0x1);
cycle_val = CFG_DDR2_RD_DATA_THIS_CYCLE_VAL_32;
} else {
prmsg("16");
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("bit) 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__);
if (RST_BOOTSTRAP_DDR_WIDTH_GET(bootstrap)) {
prmsg("32");
ctl_config = CFG_DDR_CTL_CONFIG;
cycle_val = CFG_DDR1_RD_DATA_THIS_CYCLE_VAL_32;
} else {
prmsg("16");
cycle_val = CFG_DDR1_RD_DATA_THIS_CYCLE_VAL_16;
ctl_config = 0;
}
ctl_config |= CPU_DDR_SYNC_MODE;
ath_reg_wr_nf(DDR_CTL_CONFIG_ADDRESS, ctl_config);
udelay(10);
prmsg("bit) 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_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);
}
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_CONTROL_ADDRESS, 0x10); // EMR2
udelay(10);
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_VAL); // 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, 0x782);
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_VAL);
udelay(100);
ath_reg_wr_nf(DDR_CONTROL_ADDRESS, 0x2); // EMR write
udelay(100);
}
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);
if (RST_BOOTSTRAP_DDR_WIDTH_GET(bootstrap)) {
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_LDO_TUNE_SET(3) |
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.
*/
ath_reg_rmw_clear(PMU1_ADDRESS, (7<<1));
ath_reg_rmw_set(PMU1_ADDRESS, (1<<3));
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)
uint32_t pll, out_div, ref_div, nint, frac, clk_ctrl;
#endif
uint32_t ref = ath_uart_freq();
uint32_t ath_cpu_freq = 0, ath_ddr_freq = 0, ath_ahb_freq = 0;
if (ath_cpu_freq)
goto done;
#ifdef CONFIG_ATH_EMULATION
ath_cpu_freq = 80000000;
ath_ddr_freq = 80000000;
ath_ahb_freq = 40000000;
#else
prmsg("%s: ", __func__);
clk_ctrl = ath_reg_rd(ATH_DDR_CLK_CTRL);
#if 0
pll = ath_reg_rd(CPU_DPLL2_ADDRESS);
if (CPU_DPLL2_LOCAL_PLL_GET(pll)) {
out_div = CPU_DPLL2_OUTDIV_GET(pll);
pll = ath_reg_rd(CPU_DPLL_ADDRESS);
nint = CPU_DPLL_NINT_GET(pll);
frac = CPU_DPLL_NFRAC_GET(pll);
ref_div = CPU_DPLL_REFDIV_GET(pll);
pll = ref >> 18;
frac = frac * pll / ref_div;
prmsg("cpu srif ");
} else {
#endif
pll = ath_reg_rd(ATH_PLL_CONFIG);
out_div = CPU_PLL_CONFIG_OUTDIV_GET(pll);
ref_div = CPU_PLL_CONFIG_REFDIV_GET(pll);
nint = CPU_PLL_CONFIG_NINT_GET(pll);
frac = CPU_PLL_CONFIG_NFRAC_GET(pll);
pll = ref >> 6;
frac = frac * pll / ref_div;
// }
ath_cpu_freq = (((nint * (ref / ref_div)) + frac) >> out_div) /
(CPU_DDR_CLOCK_CONTROL_CPU_POST_DIV_GET(clk_ctrl) + 1);
#if 0
pll = ath_reg_rd(DDR_DPLL2_ADDRESS);
if (DDR_DPLL2_LOCAL_PLL_GET(pll)) {
out_div = DDR_DPLL2_OUTDIV_GET(pll);
pll = ath_reg_rd(DDR_DPLL_ADDRESS);
nint = DDR_DPLL_NINT_GET(pll);
frac = DDR_DPLL_NFRAC_GET(pll);
ref_div = DDR_DPLL_REFDIV_GET(pll);
pll = ref >> 18;
frac = frac * pll / ref_div;
prmsg("ddr srif ");
} else {
#endif
pll = ath_reg_rd(ATH_DDR_PLL_CONFIG);
out_div = DDR_PLL_CONFIG_OUTDIV_GET(pll);
ref_div = DDR_PLL_CONFIG_REFDIV_GET(pll);
nint = DDR_PLL_CONFIG_NINT_GET(pll);
frac = DDR_PLL_CONFIG_NFRAC_GET(pll);
pll = ref >> 10;
frac = frac * pll / ref_div;
// }
ath_ddr_freq = (((nint * (ref / ref_div)) + frac) >> out_div) /
(CPU_DDR_CLOCK_CONTROL_DDR_POST_DIV_GET(clk_ctrl) + 1);
if (CPU_DDR_CLOCK_CONTROL_AHBCLK_FROM_DDRPLL_GET(clk_ctrl)) {
ath_ahb_freq = ath_ddr_freq /
(CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_GET(clk_ctrl) + 1);
} else {
ath_ahb_freq = ath_cpu_freq /
(CPU_DDR_CLOCK_CONTROL_AHB_POST_DIV_GET(clk_ctrl) + 1);
}
#endif
done:
prmsg("cpu %u ddr %u ahb %u\n",
ath_cpu_freq / 1000000,
ath_ddr_freq / 1000000,
ath_ahb_freq / 1000000);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,421 @@
/*
* 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 _AGxxxx_H
#define _AGxxxx_H
#include <linux/types.h>
#ifdef ATH_RGMII_CAL
#define rgmii_cal_alg() rgmii_calib(mac);
#else
#define rgmii_cal_alg()
#endif
/*
* h/w descriptor
*/
typedef struct {
uint32_t pkt_start_addr,
is_empty : 1,
res1 : 10,
ftpp_override : 5,
res2 : 4,
pkt_size : 12,
next_desc;
} ath_gmac_desc_t;
#define NO_OF_TX_FIFOS 8
#define NO_OF_RX_FIFOS 8
typedef struct {
ath_gmac_desc_t *fifo_tx[NO_OF_TX_FIFOS],
*fifo_rx[NO_OF_RX_FIFOS];
struct eth_device *dev;
uint32_t next_tx,
next_rx,
link,
duplex,
speed,
mac_unit,
mac_base;
} ath_gmac_mac_t;
#define ath_gmac_reg_wr(_mac, _x, _y) ath_reg_wr(((_x) + _mac->mac_base), (_y))
#define ath_gmac_reg_rd(_mac, _x) ath_reg_rd(((_x) + _mac->mac_base))
#define ath_gmac_reg_rmw_set(_mac, _x, _y) \
ath_reg_rmw_set(((_x) + _mac->mac_base ), (_y))
#define ath_gmac_reg_rmw_clear(_mac, _x, _y) \
ath_reg_rmw_clear(((_x) + _mac->mac_base), (_y))
#ifdef COMPRESSED_UBOOT
#define _1000BASET 1000
#define _100BASET 100
#define _10BASET 10
#endif /* #ifdef COMPRESSED_UBOOT */
/*
* spd is _1000BASET, _100BASET etc. defined in include/miiphy.h
*/
#define mii_reg(_mac) (ATH_MII0_CTRL + ((_mac)->mac_unit * 4))
#define mii_if(_mac) (((_mac)->mac_unit == 0) ? mii0_if : mii1_if)
#define ath_gmac_set_mii_ctrl_speed(_mac, _spd) do { \
ath_reg_rmw_clear(mii_reg(_mac), (3 << 4)); \
ath_reg_rmw_set(mii_reg(_mac), ((_spd) << 4)); \
} while (0)
#if defined (CFG_MII0_GMII)
# define ath_gmac_get_mii_if() 0
#elif defined (CFG_MII0_MII)
# define ath_gmac_get_mii_if() 0
#elif defined (CFG_MII0_RGMII)
# define ath_gmac_get_mii_if() 0
#elif defined (CFG_MII0_RMII)
# define ath_gmac_get_mii_if() 0
#endif
#define MAX_WAIT 1000
/*
* Config/Mac Register definitions
*/
#define ATH_MAC_CFG1 0x00
#define ATH_MAC_CFG2 0x04
#define ATH_MAC_IFCTL 0x38
/*
* fifo control registers
*/
#define ATH_MAC_FIFO_CFG_0 0x48
#define ATH_MAC_FIFO_CFG_1 0x4c
#define ATH_MAC_FIFO_CFG_2 0x50
#define ATH_MAC_FIFO_CFG_3 0x54
#define ATH_MAC_FIFO_CFG_4 0x58
#define ATH_MAC_FIFO_CFG_5 0x5c
#define ATH_BYTE_PER_CLK_EN (1 << 19)
#define ATH_MAC_FIFO_RAM_0 0x60
#define ATH_MAC_FIFO_RAM_1 0x64
#define ATH_MAC_FIFO_RAM_2 0x68
#define ATH_MAC_FIFO_RAM_3 0x6c
#define ATH_MAC_FIFO_RAM_4 0x70
#define ATH_MAC_FIFO_RAM_5 0x74
#define ATH_MAC_FIFO_RAM_6 0x78
#define ATH_MAC_FIFO_RAM_7 0x7c
/*
* fields
*/
#define ATH_MAC_CFG1_SOFT_RST (1 << 31)
#define ATH_MAC_CFG1_RX_RST (1 << 19)
#define ATH_MAC_CFG1_TX_RST (1 << 18)
#define ATH_MAC_CFG1_LOOPBACK (1 << 8)
#define ATH_MAC_CFG1_RX_EN (1 << 2)
#define ATH_MAC_CFG1_TX_EN (1 << 0)
#define ATH_MAC_CFG2_FDX (1 << 0)
#define ATH_MAC_CFG2_PAD_CRC_EN (1 << 2)
#define ATH_MAC_CFG2_LEN_CHECK (1 << 4)
#define ATH_MAC_CFG2_HUGE_FRAME_EN (1 << 5)
#define ATH_MAC_CFG2_IF_1000 (1 << 9)
#define ATH_MAC_CFG2_IF_10_100 (1 << 8)
#define ATH_MAC_IFCTL_SPEED (1 << 16)
/*
* DMA (tx/rx) register defines
*/
#define ATH_DMA_TX_CTRL 0x180
#define ATH_DMA_TX_DESC 0x184
#define ATH_DMA_TX_STATUS 0x188
#define ATH_DMA_RX_CTRL 0x18c
#define ATH_DMA_RX_DESC 0x190
#define ATH_DMA_RX_STATUS 0x194
#define ATH_DMA_INTR_MASK 0x198
#define ATH_DMA_INTR 0x19c
/*
* tx/rx ctrl and status bits
*/
#define ATH_TXE (1 << 0)
#define ATH_TX_STATUS_PKTCNT_SHIFT 16
#define ATH_TX_STATUS_PKT_SENT 0x1
#define ATH_TX_STATUS_URN 0x2
#define ATH_TX_STATUS_BUS_ERROR 0x8
#define ATH_RXE (1 << 0)
#define ATH_RX_STATUS_PKTCNT_MASK 0xff0000
#define ATH_RX_STATUS_PKT_RCVD (1 << 0)
#define ATH_RX_STATUS_OVF (1 << 2)
#define ATH_RX_STATUS_BUS_ERROR (1 << 3)
/*
* Int and int mask
*/
#define ATH_INTR_TX (1 << 0)
#define ATH_INTR_TX_URN (1 << 1)
#define ATH_INTR_TX_BUS_ERROR (1 << 3)
#define ATH_INTR_RX (1 << 4)
#define ATH_INTR_RX_OVF (1 << 6)
#define ATH_INTR_RX_BUS_ERROR (1 << 7)
/*
* MII registers
*/
#define ATH_MAC_MII_MGMT_CFG 0x20
#define ATH_MGMT_CFG_CLK_DIV_20 0x07
#define ATH_MII_MGMT_CMD 0x24
#define ATH_MGMT_CMD_READ 0x1
#define ATH_MII_MGMT_ADDRESS 0x28
#define ATH_ADDR_SHIFT 8
#define ATH_MII_MGMT_CTRL 0x2c
#define ATH_MII_MGMT_STATUS 0x30
#define ATH_MII_MGMT_IND 0x34
#define ATH_MGMT_IND_BUSY (1 << 0)
#define ATH_MGMT_IND_INVALID (1 << 2)
#define ATH_GE_MAC_ADDR1 0x40
#define ATH_GE_MAC_ADDR2 0x44
/*
* Ethernet config registers
*/
#define ATH_ETH_CFG 0x18070000
#define ATH_ETH_CFG_RGMII_GE0 (1<<0)
#define ATH_ETH_CFG_MII_GE0 (1<<1)
#define ATH_ETH_CFG_GMII_GE0 (1<<2)
#define ATH_ETH_CFG_RMII_GE0 (1<<10)
#define ATH_ETH_CFG_RMII_HISPD_GE0 (1<<11)
#define ATH_ETH_CFG_RMII_MASTER_MODE (1<<12)
#define ATH_ETH_CFG_MII_GE0_MASTER (1<<3)
#define ATH_ETH_CFG_MII_GE0_SLAVE (1<<4)
#define ATH_ETH_CFG_GE0_ERR_EN (1<<5)
#define ATH_ETH_CFG_SW_ONLY_MODE (1<<6)
#define ATH_ETH_CFG_SW_PHY_SWAP (1<<7)
#define ATH_ETH_CFG_SW_PHY_ADDR_SWAP (1<<8)
#define ATH_ETH_CFG_RXD_DELAY (1 << 14)
#define ATH_ETH_CFG_RDV_DELAY (1 << 16)
#define ATH_ETH_SWITCH_CLK_SPARE 0x18050024
#define ETH_XMII_TX_INVERT_MSB 31
#define ETH_XMII_TX_INVERT_LSB 31
#define ETH_XMII_TX_INVERT_MASK 0x80000000
#define ETH_XMII_TX_INVERT_GET(x) (((x) & ETH_XMII_TX_INVERT_MASK) >> ETH_XMII_TX_INVERT_LSB)
#define ETH_XMII_TX_INVERT_SET(x) (((x) << ETH_XMII_TX_INVERT_LSB) & ETH_XMII_TX_INVERT_MASK)
#define ETH_XMII_TX_INVERT_RESET 0x0 // 0
#define ETH_XMII_GIGE_QUAD_MSB 30
#define ETH_XMII_GIGE_QUAD_LSB 30
#define ETH_XMII_GIGE_QUAD_MASK 0x40000000
#define ETH_XMII_GIGE_QUAD_GET(x) (((x) & ETH_XMII_GIGE_QUAD_MASK) >> ETH_XMII_GIGE_QUAD_LSB)
#define ETH_XMII_GIGE_QUAD_SET(x) (((x) << ETH_XMII_GIGE_QUAD_LSB) & ETH_XMII_GIGE_QUAD_MASK)
#define ETH_XMII_GIGE_QUAD_RESET 0x0 // 0
#define ETH_XMII_RX_DELAY_MSB 29
#define ETH_XMII_RX_DELAY_LSB 28
#define ETH_XMII_RX_DELAY_MASK 0x30000000
#define ETH_XMII_RX_DELAY_GET(x) (((x) & ETH_XMII_RX_DELAY_MASK) >> ETH_XMII_RX_DELAY_LSB)
#define ETH_XMII_RX_DELAY_SET(x) (((x) << ETH_XMII_RX_DELAY_LSB) & ETH_XMII_RX_DELAY_MASK)
#define ETH_XMII_RX_DELAY_RESET 0x0 // 0
#define ETH_XMII_TX_DELAY_MSB 27
#define ETH_XMII_TX_DELAY_LSB 26
#define ETH_XMII_TX_DELAY_MASK 0x0c000000
#define ETH_XMII_TX_DELAY_GET(x) (((x) & ETH_XMII_TX_DELAY_MASK) >> ETH_XMII_TX_DELAY_LSB)
#define ETH_XMII_TX_DELAY_SET(x) (((x) << ETH_XMII_TX_DELAY_LSB) & ETH_XMII_TX_DELAY_MASK)
#define ETH_XMII_TX_DELAY_RESET 0x0 // 0
#define ETH_XMII_GIGE_MSB 25
#define ETH_XMII_GIGE_LSB 25
#define ETH_XMII_GIGE_MASK 0x02000000
#define ETH_XMII_GIGE_GET(x) (((x) & ETH_XMII_GIGE_MASK) >> ETH_XMII_GIGE_LSB)
#define ETH_XMII_GIGE_SET(x) (((x) << ETH_XMII_GIGE_LSB) & ETH_XMII_GIGE_MASK)
#define ETH_XMII_GIGE_RESET 0x0 // 0
#define ETH_XMII_OFFSET_PHASE_MSB 24
#define ETH_XMII_OFFSET_PHASE_LSB 24
#define ETH_XMII_OFFSET_PHASE_MASK 0x01000000
#define ETH_XMII_OFFSET_PHASE_GET(x) (((x) & ETH_XMII_OFFSET_PHASE_MASK) >> ETH_XMII_OFFSET_PHASE_LSB)
#define ETH_XMII_OFFSET_PHASE_SET(x) (((x) << ETH_XMII_OFFSET_PHASE_LSB) & ETH_XMII_OFFSET_PHASE_MASK)
#define ETH_XMII_OFFSET_PHASE_RESET 0x0 // 0
#define ETH_XMII_OFFSET_COUNT_MSB 23
#define ETH_XMII_OFFSET_COUNT_LSB 16
#define ETH_XMII_OFFSET_COUNT_MASK 0x00ff0000
#define ETH_XMII_OFFSET_COUNT_GET(x) (((x) & ETH_XMII_OFFSET_COUNT_MASK) >> ETH_XMII_OFFSET_COUNT_LSB)
#define ETH_XMII_OFFSET_COUNT_SET(x) (((x) << ETH_XMII_OFFSET_COUNT_LSB) & ETH_XMII_OFFSET_COUNT_MASK)
#define ETH_XMII_OFFSET_COUNT_RESET 0x0 // 0
#define ETH_XMII_PHASE1_COUNT_MSB 15
#define ETH_XMII_PHASE1_COUNT_LSB 8
#define ETH_XMII_PHASE1_COUNT_MASK 0x0000ff00
#define ETH_XMII_PHASE1_COUNT_GET(x) (((x) & ETH_XMII_PHASE1_COUNT_MASK) >> ETH_XMII_PHASE1_COUNT_LSB)
#define ETH_XMII_PHASE1_COUNT_SET(x) (((x) << ETH_XMII_PHASE1_COUNT_LSB) & ETH_XMII_PHASE1_COUNT_MASK)
#define ETH_XMII_PHASE1_COUNT_RESET 0x1 // 1
#define ETH_XMII_PHASE0_COUNT_MSB 7
#define ETH_XMII_PHASE0_COUNT_LSB 0
#define ETH_XMII_PHASE0_COUNT_MASK 0x000000ff
#define ETH_XMII_PHASE0_COUNT_GET(x) (((x) & ETH_XMII_PHASE0_COUNT_MASK) >> ETH_XMII_PHASE0_COUNT_LSB)
#define ETH_XMII_PHASE0_COUNT_SET(x) (((x) << ETH_XMII_PHASE0_COUNT_LSB) & ETH_XMII_PHASE0_COUNT_MASK)
#define ETH_XMII_PHASE0_COUNT_RESET 0x1 // 1
#define ETH_XMII_ADDRESS 0x18050028
#define ETH_CFG_ETH_SPARE_MSB 31
#define ETH_CFG_ETH_SPARE_LSB 22
#define ETH_CFG_ETH_SPARE_MASK 0xffc00000
#define ETH_CFG_ETH_SPARE_GET(x) (((x) & ETH_CFG_ETH_SPARE_MASK) >> ETH_CFG_ETH_SPARE_LSB)
#define ETH_CFG_ETH_SPARE_SET(x) (((x) << ETH_CFG_ETH_SPARE_LSB) & ETH_CFG_ETH_SPARE_MASK)
#define ETH_CFG_ETH_SPARE_RESET 0x0 // 0
#define ETH_CFG_ETH_TXEN_DELAY_MSB 21
#define ETH_CFG_ETH_TXEN_DELAY_LSB 20
#define ETH_CFG_ETH_TXEN_DELAY_MASK 0x00300000
#define ETH_CFG_ETH_TXEN_DELAY_GET(x) (((x) & ETH_CFG_ETH_TXEN_DELAY_MASK) >> ETH_CFG_ETH_TXEN_DELAY_LSB)
#define ETH_CFG_ETH_TXEN_DELAY_SET(x) (((x) << ETH_CFG_ETH_TXEN_DELAY_LSB) & ETH_CFG_ETH_TXEN_DELAY_MASK)
#define ETH_CFG_ETH_TXEN_DELAY_RESET 0x0 // 0
#define ETH_CFG_ETH_TXD_DELAY_MSB 19
#define ETH_CFG_ETH_TXD_DELAY_LSB 18
#define ETH_CFG_ETH_TXD_DELAY_MASK 0x000c0000
#define ETH_CFG_ETH_TXD_DELAY_GET(x) (((x) & ETH_CFG_ETH_TXD_DELAY_MASK) >> ETH_CFG_ETH_TXD_DELAY_LSB)
#define ETH_CFG_ETH_TXD_DELAY_SET(x) (((x) << ETH_CFG_ETH_TXD_DELAY_LSB) & ETH_CFG_ETH_TXD_DELAY_MASK)
#define ETH_CFG_ETH_TXD_DELAY_RESET 0x0 // 0
#define ETH_CFG_ETH_RXDV_DELAY_MSB 17
#define ETH_CFG_ETH_RXDV_DELAY_LSB 16
#define ETH_CFG_ETH_RXDV_DELAY_MASK 0x00030000
#define ETH_CFG_ETH_RXDV_DELAY_GET(x) (((x) & ETH_CFG_ETH_RXDV_DELAY_MASK) >> ETH_CFG_ETH_RXDV_DELAY_LSB)
#define ETH_CFG_ETH_RXDV_DELAY_SET(x) (((x) << ETH_CFG_ETH_RXDV_DELAY_LSB) & ETH_CFG_ETH_RXDV_DELAY_MASK)
#define ETH_CFG_ETH_RXDV_DELAY_RESET 0x0 // 0
#define ETH_CFG_ETH_RXD_DELAY_MSB 15
#define ETH_CFG_ETH_RXD_DELAY_LSB 14
#define ETH_CFG_ETH_RXD_DELAY_MASK 0x0000c000
#define ETH_CFG_ETH_RXD_DELAY_GET(x) (((x) & ETH_CFG_ETH_RXD_DELAY_MASK) >> ETH_CFG_ETH_RXD_DELAY_LSB)
#define ETH_CFG_ETH_RXD_DELAY_SET(x) (((x) << ETH_CFG_ETH_RXD_DELAY_LSB) & ETH_CFG_ETH_RXD_DELAY_MASK)
#define ETH_CFG_ETH_RXD_DELAY_RESET 0x0 // 0
#define ETH_CFG_RMII_GE0_MASTER_MSB 12
#define ETH_CFG_RMII_GE0_MASTER_LSB 12
#define ETH_CFG_RMII_GE0_MASTER_MASK 0x00001000
#define ETH_CFG_RMII_GE0_MASTER_GET(x) (((x) & ETH_CFG_RMII_GE0_MASTER_MASK) >> ETH_CFG_RMII_GE0_MASTER_LSB)
#define ETH_CFG_RMII_GE0_MASTER_SET(x) (((x) << ETH_CFG_RMII_GE0_MASTER_LSB) & ETH_CFG_RMII_GE0_MASTER_MASK)
#define ETH_CFG_RMII_GE0_MASTER_RESET 0x1 // 1
#define ETH_CFG_MII_CNTL_SPEED_MSB 11
#define ETH_CFG_MII_CNTL_SPEED_LSB 11
#define ETH_CFG_MII_CNTL_SPEED_MASK 0x00000800
#define ETH_CFG_MII_CNTL_SPEED_GET(x) (((x) & ETH_CFG_MII_CNTL_SPEED_MASK) >> ETH_CFG_MII_CNTL_SPEED_LSB)
#define ETH_CFG_MII_CNTL_SPEED_SET(x) (((x) << ETH_CFG_MII_CNTL_SPEED_LSB) & ETH_CFG_MII_CNTL_SPEED_MASK)
#define ETH_CFG_MII_CNTL_SPEED_RESET 0x0 // 0
#define ETH_CFG_RMII_GE0_MSB 10
#define ETH_CFG_RMII_GE0_LSB 10
#define ETH_CFG_RMII_GE0_MASK 0x00000400
#define ETH_CFG_RMII_GE0_GET(x) (((x) & ETH_CFG_RMII_GE0_MASK) >> ETH_CFG_RMII_GE0_LSB)
#define ETH_CFG_RMII_GE0_SET(x) (((x) << ETH_CFG_RMII_GE0_LSB) & ETH_CFG_RMII_GE0_MASK)
#define ETH_CFG_RMII_GE0_RESET 0x0 // 0
#define ETH_CFG_GE0_SGMII_MSB 6
#define ETH_CFG_GE0_SGMII_LSB 6
#define ETH_CFG_GE0_SGMII_MASK 0x00000040
#define ETH_CFG_GE0_SGMII_GET(x) (((x) & ETH_CFG_GE0_SGMII_MASK) >> ETH_CFG_GE0_SGMII_LSB)
#define ETH_CFG_GE0_SGMII_SET(x) (((x) << ETH_CFG_GE0_SGMII_LSB) & ETH_CFG_GE0_SGMII_MASK)
#define ETH_CFG_GE0_SGMII_RESET 0x0 // 0
#define ETH_CFG_GE0_ERR_EN_MSB 5
#define ETH_CFG_GE0_ERR_EN_LSB 5
#define ETH_CFG_GE0_ERR_EN_MASK 0x00000020
#define ETH_CFG_GE0_ERR_EN_GET(x) (((x) & ETH_CFG_GE0_ERR_EN_MASK) >> ETH_CFG_GE0_ERR_EN_LSB)
#define ETH_CFG_GE0_ERR_EN_SET(x) (((x) << ETH_CFG_GE0_ERR_EN_LSB) & ETH_CFG_GE0_ERR_EN_MASK)
#define ETH_CFG_GE0_ERR_EN_RESET 0x0 // 0
#define ETH_CFG_MII_GE0_SLAVE_MSB 4
#define ETH_CFG_MII_GE0_SLAVE_LSB 4
#define ETH_CFG_MII_GE0_SLAVE_MASK 0x00000010
#define ETH_CFG_MII_GE0_SLAVE_GET(x) (((x) & ETH_CFG_MII_GE0_SLAVE_MASK) >> ETH_CFG_MII_GE0_SLAVE_LSB)
#define ETH_CFG_MII_GE0_SLAVE_SET(x) (((x) << ETH_CFG_MII_GE0_SLAVE_LSB) & ETH_CFG_MII_GE0_SLAVE_MASK)
#define ETH_CFG_MII_GE0_SLAVE_RESET 0x0 // 0
#define ETH_CFG_MII_GE0_MASTER_MSB 3
#define ETH_CFG_MII_GE0_MASTER_LSB 3
#define ETH_CFG_MII_GE0_MASTER_MASK 0x00000008
#define ETH_CFG_MII_GE0_MASTER_GET(x) (((x) & ETH_CFG_MII_GE0_MASTER_MASK) >> ETH_CFG_MII_GE0_MASTER_LSB)
#define ETH_CFG_MII_GE0_MASTER_SET(x) (((x) << ETH_CFG_MII_GE0_MASTER_LSB) & ETH_CFG_MII_GE0_MASTER_MASK)
#define ETH_CFG_MII_GE0_MASTER_RESET 0x0 // 0
#define ETH_CFG_GMII_GE0_MSB 2
#define ETH_CFG_GMII_GE0_LSB 2
#define ETH_CFG_GMII_GE0_MASK 0x00000004
#define ETH_CFG_GMII_GE0_GET(x) (((x) & ETH_CFG_GMII_GE0_MASK) >> ETH_CFG_GMII_GE0_LSB)
#define ETH_CFG_GMII_GE0_SET(x) (((x) << ETH_CFG_GMII_GE0_LSB) & ETH_CFG_GMII_GE0_MASK)
#define ETH_CFG_GMII_GE0_RESET 0x0 // 0
#define ETH_CFG_MII_GE0_MSB 1
#define ETH_CFG_MII_GE0_LSB 1
#define ETH_CFG_MII_GE0_MASK 0x00000002
#define ETH_CFG_MII_GE0_GET(x) (((x) & ETH_CFG_MII_GE0_MASK) >> ETH_CFG_MII_GE0_LSB)
#define ETH_CFG_MII_GE0_SET(x) (((x) << ETH_CFG_MII_GE0_LSB) & ETH_CFG_MII_GE0_MASK)
#define ETH_CFG_MII_GE0_RESET 0x0 // 0
#define ETH_CFG_RGMII_GE0_MSB 0
#define ETH_CFG_RGMII_GE0_LSB 0
#define ETH_CFG_RGMII_GE0_MASK 0x00000001
#define ETH_CFG_RGMII_GE0_GET(x) (((x) & ETH_CFG_RGMII_GE0_MASK) >> ETH_CFG_RGMII_GE0_LSB)
#define ETH_CFG_RGMII_GE0_SET(x) (((x) << ETH_CFG_RGMII_GE0_LSB) & ETH_CFG_RGMII_GE0_MASK)
#define ETH_CFG_RGMII_GE0_RESET 0x0 // 0
#define ETH_CFG_ADDRESS 0x18070000
/*
* ownership of descriptors between DMA and cpu
*/
#define ath_gmac_rx_owned_by_dma(_ds) ((_ds)->is_empty == 1)
#define ath_gmac_rx_give_to_dma(_ds) ((_ds)->is_empty = 1)
#define ath_gmac_tx_owned_by_dma(_ds) ((_ds)->is_empty == 0)
#define ath_gmac_tx_give_to_dma(_ds) ((_ds)->is_empty = 0)
#define ath_gmac_tx_own(_ds) ((_ds)->is_empty = 1)
/*
* link settings
*/
#define ath_gmac_set_mac_duplex(_mac, _fdx) do { \
if ((_fdx)) { \
ath_gmac_reg_rmw_set(_mac, \
ATH_MAC_CFG2, ATH_MAC_CFG2_FDX);\
} else { \
ath_gmac_reg_rmw_clear(_mac, \
ATH_MAC_CFG2, ATH_MAC_CFG2_FDX);\
} \
} while (0)
#define ath_gmac_set_mac_if(_mac, _isXGMII) do { \
ath_gmac_reg_rmw_clear(_mac, ATH_MAC_CFG2, \
ATH_MAC_CFG2_IF_1000 | \
ATH_MAC_CFG2_IF_10_100); \
if ((_isXGMII)) { \
ath_gmac_reg_rmw_set(_mac, ATH_MAC_CFG2, \
ATH_MAC_CFG2_IF_1000); \
ath_gmac_reg_rmw_set(_mac, ATH_MAC_FIFO_CFG_5, \
ATH_BYTE_PER_CLK_EN); \
} else { \
ath_gmac_reg_rmw_set(_mac, ATH_MAC_CFG2, \
ATH_MAC_CFG2_IF_10_100); \
ath_gmac_reg_rmw_clear(_mac, ATH_MAC_FIFO_CFG_5,\
ATH_BYTE_PER_CLK_EN); \
} \
} while (0)
#define ath_gmac_set_mac_speed(_mac, _is100) do { \
if ((_is100)) { \
ath_gmac_reg_rmw_set(_mac, ATH_MAC_IFCTL, \
ATH_MAC_IFCTL_SPEED); \
} else { \
ath_gmac_reg_rmw_clear(_mac, ATH_MAC_IFCTL, \
ATH_MAC_IFCTL_SPEED); \
} \
} while (0)
#endif

View file

@ -0,0 +1,116 @@
/*
* 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 _QCA_ETH_955x_PHY_H
#define _QCA_ETH_955x_PHY_H
#include <miiphy.h>
#ifdef CONFIG_ATHR_8033_PHY
extern int athrs_ar8033_reg_init(void *arg);
extern int athrs_ar8033_phy_setup(void *arg);
extern int athrs_ar8033_phy_is_fdx(int ethUnit);
extern int athrs_ar8033_phy_is_link_alive(int phyUnit);
extern int athrs_ar8033_phy_is_up(int ethUnit);
extern int athrs_ar8033_phy_speed(int ethUnit,int phyUnit);
#endif
#ifdef CONFIG_ATHRS17_PHY
extern int athrs17_phy_setup(int ethUnit);
extern int athrs17_phy_is_up(int ethUnit);
extern int athrs17_phy_is_fdx(int ethUnit);
extern int athrs17_phy_speed(int ethUnit);
#endif
static inline void ath_gmac_phy_setup(int unit)
{
#ifdef CONFIG_ATHRS17_PHY
if (unit == 0) {
athrs17_phy_setup(unit);
} else
#endif
{
#ifdef CONFIG_VIR_PHY
athr_vir_phy_setup(unit);
#endif
#if defined(CONFIG_ATHRS17_PHY) && !defined (CFG_DUAL_PHY_SUPPORT)
athrs17_phy_setup(unit);
#endif
}
}
static inline void ath_gmac_phy_link(int unit, int *link)
{
#ifdef CONFIG_ATHRS17_PHY
if (unit == 0) {
*link = athrs17_phy_is_up(unit);
} else
#endif
{
#ifdef CONFIG_VIR_PHY
*link = athr_vir_phy_is_up(unit);
#endif
#ifdef CONFIG_ATHR_8033_PHY
*link = athrs_ar8033_phy_is_up(unit);
#endif
#if defined(CONFIG_ATHRS17_PHY) && !defined (CFG_DUAL_PHY_SUPPORT)
*link = athrs17_phy_is_up(unit);
#endif
}
}
static inline void ath_gmac_phy_duplex(int unit, int *duplex)
{
#ifdef CONFIG_ATHRS17_PHY
if (unit == 0) {
*duplex = athrs17_phy_is_fdx(unit);
} else
#endif
{
#ifdef CONFIG_VIR_PHY
*duplex = athr_vir_phy_is_fdx(unit);
#endif
#ifdef CONFIG_ATHR_8033_PHY
*duplex = athrs_ar8033_phy_is_fdx(unit);
#endif
#if defined(CONFIG_ATHRS17_PHY) && !defined(CFG_DUAL_PHY_SUPPORT)
*duplex = athrs17_phy_is_fdx(unit);
#endif
}
}
static inline void ath_gmac_phy_speed(int unit, int *speed)
{
#ifdef CONFIG_ATHRS17_PHY
if (unit == 0) {
*speed = _1000BASET;
} else
#endif
{
#ifdef CONFIG_VIR_PHY
*speed = athr_vir_phy_speed(unit);
#endif
#ifdef CONFIG_ATHR_8033_PHY
*speed = athrs_ar8033_phy_speed(unit, 5);
#endif
#if defined(CONFIG_ATHRS17_PHY) && !defined (CFG_DUAL_PHY_SUPPORT)
*speed = _1000BASET;
#endif
}
}
#endif /* _QCA_ETH_955x_PHY_H */

View file

@ -0,0 +1,618 @@
/*
* 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 <gmac_defines.h>
//#include <prototypes.h>
#include <config.h>
#include <common.h>
#include <malloc.h>
#include <net.h>
#include <command.h>
#include <asm/io.h>
#include <asm/addrspace.h>
#include <asm/types.h>
#include <atheros.h>
#include "qca-eth-955x.h"
#include "qca-eth-955x_phy.h"
#ifdef ATH_RGMII_CAL
#define NUM_DESCRIPTORS 10 //Number of packets to be looped back
#define node_tx_buf_len 100 // No of bytes per packet to be looped back
#define DEBUG 0
#define DEBUG_1 1
#define GE0_PEMSTAT_RBYT (0x9c + ATH_GE0_BASE)
#define GE0_PEMSTAT_RPKT (0xA0 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RFCS (0xA4 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RMCA (0xA8 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RBCA (0xAC + ATH_GE0_BASE)
#define GE0_PEMSTAT_RXCF (0xB0 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RXPF (0xB4 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RXUO (0xB8 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RALN (0xBC + ATH_GE0_BASE)
#define GE0_PEMSTAT_RFLR (0xC0 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RCDE (0xC4 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RCSE (0xC8 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RUND (0xCC + ATH_GE0_BASE)
#define GE0_PEMSTAT_ROVR (0xD0 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RFRG (0xD4 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RJBR (0xD8 + ATH_GE0_BASE)
#define GE0_PEMSTAT_RDRP (0xDC + ATH_GE0_BASE)
#define GE0_PEMSTAT_TPKT (0xE0 + ATH_GE0_BASE)
#define NUM_DESCS 10
void init_s17_lpbk(void);
uint32_t athrs17_reg_read(uint32_t reg_addr);
void athrs17_reg_write(uint32_t reg_addr, uint32_t reg_val);
int results[5] = { 0, 1, 1, 1, 0 };
int find;
void big_del(void)
{
int i;
for (i = 0; i < 10000; i++) ;
}
// This should tell us what the best of the 4 values is. It should also tell us what the longest sequence is.
// Since only four bits are used the best of 4 values can be easily arrived at by a truth table.
// Presently we have an algorithm though.
int find_value(void)
{
int i;
int start_ok = 9;
int end_ok = 9;
int longest_start_ok = 0;
int longest_end_ok = 0;
int longest_ok_cnt = -1;
int first = 0;
for (i = 0; i < 5; i++) {
#if DEBUG
printf("results [%d]: %d\n", i, results[i]);
#endif
if (results[i] == 1) {
if (start_ok == 9) {
start_ok = i;
if (first == 0) {
longest_start_ok = i;
longest_end_ok = i;
first = 1;
}
}
}
if (results[i] == 0) {
if (end_ok == 9) {
end_ok = i - 1;
}
if ((end_ok - start_ok) > longest_ok_cnt) {
longest_start_ok = start_ok;
longest_end_ok = end_ok;
longest_ok_cnt = (end_ok - start_ok);
}
start_ok = 9;
end_ok = 9;
}
}
#if DEBUG
printf("FINAL VALUE - ");
#endif
find = (longest_end_ok + longest_start_ok) / 2;
#if DEBUG
printf("find - %d\n", find);
printf("FINAL OK COUNT - %d\n", longest_ok_cnt + 1);
#endif
return (longest_ok_cnt + 1);
}
int pkt_compare_data(void)
{
unsigned int i, j;
//unsigned int k,rddata;
unsigned int node_rx_buf_len;
//unsigned int * node_tx_desc_ptr = (unsigned int *) 0xa0280000;
unsigned int *node_rx_desc_ptr = (unsigned int *)0xa0380000;
unsigned int *node_tx_buf_addr = (unsigned int *)0xa0680000;
unsigned int *node_rx_buf_addr = (unsigned int *)0xa0580000;
unsigned int error = 0;
unsigned pkt_err[NUM_DESCS];
node_rx_buf_len = (*(node_rx_desc_ptr + 0x1) & 0xfff) - 0x4;
// node_tx_buf_len = *(node_tx_desc_ptr + (NUM_DESCS-1)*0x3+0x1) & 0xfff;
for (j = 0; j < NUM_DESCS; j++) {
node_rx_buf_len = (*(node_rx_desc_ptr + (NUM_DESCS - 1) * 0x3 + 0x1) & 0xfff) - 0x4;
pkt_err[j] = 0;
for (i = 0; i < (node_rx_buf_len / 4); i++) {
if (((*(node_rx_buf_addr + i + (j * 0x100))) != *(node_tx_buf_addr + i))) {
error = error + 0x1;
pkt_err[j] = 1;
}
}
//node_rx_buf_addr = node_rx_buf_addr + 0x100;
}
if (error == 0) {
return 0;
} else {
for (j = 0; j < NUM_DESCS; j++) {
node_rx_buf_len = (*(node_rx_desc_ptr + (NUM_DESCS - 1) * 0x3 + 0x1) & 0xfff) - 0x4;
if (pkt_err[j] == 1) {
#if DEBUG
printf("PKT %d\n", j);
printf("---------------------------------\n");
for (i = 0; i < (node_rx_buf_len / 4); i++) {
//if(((*(node_rx_buf_addr + i )) != *(node_tx_buf_addr + i)))
if (((*(node_rx_buf_addr + i + (j * 0x100))) != *(node_tx_buf_addr + i))) {
printf("->");
} else {
printf(" ");
}
printf("%x", (*(node_rx_buf_addr + i + (j * 0x100))));
printf(" ");
printf("%x\n", (*(node_tx_buf_addr + i)));
}
printf("---------------------------------\n");
#endif
}
//node_rx_buf_addr = node_rx_buf_addr + 0x100;
}
return 1;
}
}
void rgmii_calib(ath_gmac_mac_t * mac)
{
unsigned int i;
unsigned int j;
unsigned int k, l, m;
unsigned int rddata, error = 0;
volatile unsigned int * rd_register;
unsigned int node_rx_buf_len = 1600;
unsigned int node_rx_buf_len1;
unsigned int *node_tx_desc_ptr = (unsigned int *)0xa0280000;
unsigned int *node_rx_desc_ptr = (unsigned int *)0xa0380000;
unsigned int *node_rx_buf_addr = (unsigned int *)0xa0580000;
unsigned int *node_tx_buf_addr = (unsigned int *)0xa0680000;
unsigned int *node_comp_result = (unsigned int *)0xa0200000;
unsigned int s17_tx_pkt = 0;
unsigned int s17_rx_pkt = 0;
unsigned int to;
unsigned int pass = 1;
unsigned int fail = 0;
int lgst = 0;
int old_lgst = 0;
unsigned int xmii[16];
unsigned int eth_cfg[16];
unsigned int xmii_val = 0;
unsigned int eth_cfg_val = 1;
unsigned int tx_fix = 0;
// GIGE Enable
ath_reg_wr(ETH_XMII_ADDRESS, ETH_XMII_TX_INVERT_SET(0x1) |
ETH_XMII_RX_DELAY_SET(0x2) |
ETH_XMII_TX_DELAY_SET(0x1) |
ETH_XMII_GIGE_SET(0x1));
while ((ath_reg_rd(SGMII_SERDES_ADDRESS) & SGMII_SERDES_LOCK_DETECT_STATUS_SET(1)) == 0) {
printf("TEST: WAIT FOR LOCK\n");
}
big_del();
// MAC INITS
// RGMII Enable on GE0
//eth_init();
init_s17_lpbk();
athrs17_reg_write(0x30, 1);
ath_reg_wr(ETH_CFG_ADDRESS, ETH_CFG_ETH_RXDV_DELAY_SET(0x3) |
ETH_CFG_ETH_RXD_DELAY_SET(0x3) |
ETH_CFG_RGMII_GE0_SET(0x1));
ath_reg_rmw_clear(RST_RESET_ADDRESS, RST_RESET_GE0_MAC_RESET_MASK); // Bringing GE0 out of RESET
ath_gmac_reg_wr(mac, ATH_MAC_CFG2, 0x7235); //for 1000mbps
//ath_reg_wr(GE0_MAC_CONFIG_2,0x7135); //for 100mbps
ath_gmac_reg_wr(mac, ATH_MAC_IFCTL, 0x00000);
ath_gmac_reg_wr(mac, ATH_MAC_CFG1, 0x005);
//ath_reg_wr(GE0_MAC_CONFIG_1,0x105); // For MAC Loopback
ath_gmac_reg_wr(mac, ATH_DMA_INTR_MASK, 0); // Disable interrupt mask
ath_gmac_reg_wr(mac, ATH_GE_MAC_ADDR1, 0x003fffff); //ethernet mac address
ath_gmac_reg_wr(mac, ATH_GE_MAC_ADDR2, 0xfffe0000); //ethernet mac address
ath_gmac_reg_wr(mac, ATH_MAC_MII_MGMT_CFG, 0x6); //clock/20= 2MHz
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_0, 0x1f00); // Enable the FIFO modules
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_1, 0x10ffff);
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_3, 0x1f00140);
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_4, 0x1000);
//ath_reg_wr(GE0_FIFO_CFG_REG_5, 0xbefff); //enable drop
ath_gmac_reg_wr(mac, ATH_MAC_FIFO_CFG_5, 0xfffff); //for 1000Mbps
//ath_reg_wr(GE0_FIFO_CFG_REG_5, 0x7ffff);//for 100Mbps
//************
// PACKETS
//***********
// Initialise Data in Memory for TX and RX
for (i = 0; i < node_tx_buf_len; i++)
*(node_tx_buf_addr + i) = i | (i + 1) << 8 | (i + 2) << 16 | (i + 3) << 24;
#if DEBUG
printf("TEST: Inits Done\n");
#endif
// Set Up Transmit Descriptor Table
for (i = 0; i < NUM_DESCRIPTORS; i++) {
*(node_tx_desc_ptr + (i * 0x3)) = ((unsigned int)node_tx_buf_addr & 0x0fffffff);
*(node_tx_desc_ptr + (i * 0x3) + 0x1) = (node_tx_buf_len & 0x7fffffff);
if (i == (NUM_DESCRIPTORS - 1))
*(node_tx_desc_ptr + (i * 0x3) + 0x2) = ((unsigned int)node_tx_desc_ptr & 0x0fffffff);
else
*(node_tx_desc_ptr + (i * 0x3) + 0x2) = ((unsigned int)node_tx_desc_ptr & 0x0fffffff) + (i * 0xc) + 0xc;
}
ath_gmac_reg_wr(mac, ATH_DMA_TX_DESC, ((unsigned int)node_tx_desc_ptr & 0x0fffffff));
ath_gmac_reg_wr(mac, ATH_DMA_TX_STATUS, 0xfffffff); // clear dma status
for (i = 0; i < NUM_DESCRIPTORS; i++) {
*(node_rx_desc_ptr + (i * 0x3)) = ((unsigned int)node_rx_buf_addr & 0x0fffffff);
*(node_rx_desc_ptr + (i * 0x3) + 0x1) = (node_rx_buf_len & 0xfff) | (1 << 31);
if (i == (NUM_DESCRIPTORS - 1))
*(node_rx_desc_ptr + (i * 0x3) + 0x2) = ((unsigned int)node_rx_desc_ptr & 0x0fffffff);
else
*(node_rx_desc_ptr + (i * 0x3) + 0x2) = ((unsigned int)node_rx_desc_ptr & 0x0fffffff) + (i * 0xc) + 0xc;
node_rx_buf_addr = node_rx_buf_addr + 0x100;
}
ath_gmac_reg_wr(mac, ATH_DMA_RX_DESC, ((unsigned int)node_rx_desc_ptr & 0x0fffffff));
ath_gmac_reg_wr(mac, ATH_DMA_RX_STATUS, 0xfffffff); // clear dma status
k = 0;
// Enable TX and RX MAC
ath_gmac_reg_wr(mac, ATH_MAC_CFG1, 0x005);
// This routine will go through 16 combinations to find the best value for TX_DELAY, GIGE_QUAD, TX_INVERT
for (l = 0; l < 16; l++) {
// initialize pass. this will be made zero if there is a failure in packet reception compare
pass = 1;
// fail due to checks in rx etc. this is not the same as !pass
fail = 0;
// GIGE_QUAD - 0
// TX_INVERT - 0
// TX_DELAY - 0,1,2,3
if (l < 4) {
// GIGE Enable and TX_DELAY
rddata = ETH_XMII_GIGE_SET(0x1) |
ETH_XMII_TX_DELAY_SET(l);
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
rddata = ath_reg_rd(ETH_XMII_ADDRESS);
#if DEBUG
printf("TEST: ETH_XMII - 0x%08x\n", rddata);
#endif
}
// GIGE_QUAD - 1
// TX_INVERT - 0
// TX_DELAY - 0,1,2,3
if ((l < 8) && (l > 3)) {
// GIGE Enable and TX_DELAY & GIGE_QUAD
rddata = ETH_XMII_GIGE_QUAD_SET(0x1) |
ETH_XMII_GIGE_SET(0x1) |
ETH_XMII_TX_DELAY_SET(l);
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
rddata = ath_reg_rd(ETH_XMII_ADDRESS);
#if DEBUG
printf("TEST: ETH_XMII - 0x%08x\n", rddata);
#endif
}
// GIGE_QUAD - 0
// TX_INVERT - 1
// TX_DELAY - 0,1,2,3
if ((l < 12) && (l > 7)) {
// GIGE Enable and TX_DELAY and TX_INVERT
rddata = ETH_XMII_TX_INVERT_SET(0x1) |
ETH_XMII_GIGE_SET(0x1) |
ETH_XMII_TX_DELAY_SET(l);
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
rddata = ath_reg_rd(ETH_XMII_ADDRESS);
#if DEBUG
printf("TEST: ETH_XMII - 0x%08x\n", rddata);
#endif
}
// GIGE_QUAD - 0
// TX_INVERT - 1
// TX_DELAY - 0,1,2,3
if ((l < 16) && (l > 11)) {
// GIGE Enable and TX_DELAY and TX_INVERT and GIGE_QUAD
rddata = ETH_XMII_TX_INVERT_SET(0x1) |
ETH_XMII_GIGE_QUAD_SET(0x1) |
ETH_XMII_GIGE_SET(0x1) |
ETH_XMII_TX_DELAY_SET(l);
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
rddata = ath_reg_rd(ETH_XMII_ADDRESS);
#if DEBUG
printf("TEST: ETH_XMII - 0x%08x\n", rddata);
#endif
}
xmii[l] = rddata;
// counts when to print out counter stats
k++;
// Set Up Receive Descriptor Table
node_rx_buf_len = 0x0;
ath_gmac_reg_wr(mac, ATH_DMA_RX_CTRL, 0x1); // enable dma rx
ath_gmac_reg_wr(mac, ATH_DMA_TX_CTRL, 0x1); // enable dma tx
rd_register = node_tx_desc_ptr + (NUM_DESCRIPTORS - 1) * 0x3 + 0x1;
rddata = (*(rd_register) & (1 << 31));
while (rddata != (1 << 31))
rddata = (*(rd_register) & (1 << 31));
#if DEBUG
printf("TEST: Tx Done \n");
#endif
to = 0;
rd_register = node_rx_desc_ptr + (NUM_DESCS - 1) * 0x3 + 0x1;
rddata = (*(rd_register) & (1 << 31));
while (rddata != 0x0) {
rddata = (*(rd_register) & (1 << 31));
to++;
if (to > 100000) {
#if DEBUG
printf("TEST: ERROR!! Atleast 1 packet in GE0 not seen.\n");
#endif
fail = 1;
break;
}
}
#if DEBUG
printf("TEST: Rx Done \n");
#endif
if (k % 1 == 0) {
for (j = GE0_PEMSTAT_RBYT; j <= GE0_PEMSTAT_RDRP; j = j + 4) {
rddata = ath_reg_rd(j);
switch (j) {
#if DEBUG
case GE0_PEMSTAT_RPKT:
printf("TEST: RPKT - 0x%08x\n", rddata);
break;
case GE0_PEMSTAT_TPKT:
printf("TEST: TPKT - 0x%08x\n", rddata);
break;
#endif
}
}
#ifdef ATH_S17_MAC0_SGMII
s17_rx_pkt = athrs17_reg_read(0x163c) + (athrs17_reg_read(0x1640) << 16);
#else
s17_rx_pkt = athrs17_reg_read(0x103c) + (athrs17_reg_read(0x1040) << 16);
#endif
#if DEBUG
printf("TEST: RPKT in S17 0x%08x\n", s17_rx_pkt);
#endif
#ifdef ATH_S17_MAC0_SGMII
s17_tx_pkt = athrs17_reg_read(0x1684) + (athrs17_reg_read(0x1688) << 16);
#else
s17_tx_pkt = athrs17_reg_read(0x1084) + (athrs17_reg_read(0x1088) << 16);
#endif
#if DEBUG
printf("TEST: TPKT in S17 0x%08x\n", s17_tx_pkt);
#endif
// Compare BYTES in TX
if (s17_tx_pkt != 0x410) {
#if DEBUG
printf("TEST: PKTS @ S17 - 0x%08x\n", rddata);
#endif
pass = 0;
fail = 1;
}
}
if (fail == 0) {
error = pkt_compare_data();
}
if (error == 0) {
#if DEBUG
printf("TEST: PACKET COMPARISON PASS\n");
#endif
} else {
#if DEBUG
printf("TEST: ERROR!! PACKET COMPARISON FAIL\n");
#endif
fail = 1;
}
for (i = 0; i < NUM_DESCRIPTORS; i++) {
*(node_tx_desc_ptr + (i * 0x3) + 0x1) = (node_tx_buf_len & 0x7fffffff);
*(node_rx_desc_ptr + (i * 0x3) + 0x1) = (node_rx_buf_len & 0xfff) | (1 << 31);
}
// populate results and find the optimum value of programming
results[(l % 4)] = pass;
if (((l % 4) == 3)) {
lgst = find_value();
if (lgst > old_lgst) {
old_lgst = lgst;
xmii_val = xmii[(l - 3) + find];
}
}
}
#if DEBUG_1
printf("TEST: FINAL REG VAL after TX Calibration - 0x%08x\n", xmii_val);
#endif
tx_fix = xmii_val;
old_lgst = 0;
// Using the previously arrived at value of TX Calib we calibrate RX DELAYS. For this we use RX DAT and EN Delays
for (l = 0; l < 16; l++) {
// initialize pass. this will be made zero if there is a failure in packet reception compare
pass = 1;
// fail due to checks in rx etc. this is not the same as !pass
fail = 0;
rddata = ath_reg_rd(ETH_CFG_ADDRESS);
#if DEBUG
printf("TEST: Initial ETH_CFG - 0x%08x\n", rddata);
#endif
// RXD_DELAY - l / 4 -> 0, 1, 2, 3
// RXEN_DELAY - l / 4 -> 0, 1, 2, 3
// RX_DELAY - l & 3 -> 0, 1, 2, 3
ath_reg_rmw_clear(ETH_CFG_ADDRESS,
ETH_CFG_ETH_RXDV_DELAY_MASK |
ETH_CFG_ETH_RXD_DELAY_MASK);
ath_reg_rmw_set(ETH_CFG_ADDRESS,
ETH_CFG_ETH_RXDV_DELAY_SET(l / 4) |
ETH_CFG_ETH_RXD_DELAY_SET(l / 4));
rddata = ath_reg_rd(ETH_CFG_ADDRESS);
#if DEBUG
printf("TEST: ETH_CFG - 0x%08x\n", rddata);
#endif
eth_cfg[l] = rddata;
rddata = tx_fix | ETH_XMII_RX_DELAY_SET(l);
ath_reg_wr(ETH_XMII_ADDRESS, rddata);
xmii[l] = rddata;
// counts when to print out counter stats
k++;
// Set Up Receive Descriptor Table
node_rx_buf_len = 0x0;
ath_gmac_reg_wr(mac, ATH_DMA_RX_CTRL, 0x1); // enable dma rx
ath_gmac_reg_wr(mac, ATH_DMA_TX_CTRL, 0x1); // enable dma tx
rd_register = node_tx_desc_ptr + (NUM_DESCRIPTORS - 1) * 0x3 + 0x1;
rddata = (*(rd_register) & (1 << 31));
while (rddata != (1 << 31))
rddata = (*(rd_register) & (1 << 31));
#if DEBUG
printf("TEST: Tx Done \n");
#endif
to = 0;
rd_register = node_rx_desc_ptr + (NUM_DESCS - 1) * 0x3 + 0x1;
rddata = (*(rd_register) & (1 << 31));
while (rddata != 0x0) {
rddata = (*(rd_register) & (1 << 31));
to++;
if (to > 100000) {
#if DEBUG
printf("TEST: ERROR!! Atleast 1 packet in GE0 not seen.\n");
#endif
// This check for RX.
pass = 0;
fail = 1;
break;
}
}
#if DEBUG
printf("TEST: Rx Done \n");
#endif
if (k % 1 == 0) {
for (j = GE0_PEMSTAT_RBYT; j <= GE0_PEMSTAT_RDRP; j = j + 4) {
rddata = ath_reg_rd(j);
switch (j) {
#if DEBUG
case GE0_PEMSTAT_RPKT:
printf("TEST: RPKT 0x%08x\n", rddata);
break;
case GE0_PEMSTAT_TPKT:
printf("TEST: TPKT 0x%08x\n", rddata);
break;
#endif
}
}
#ifdef ATH_S17_MAC0_SGMII
s17_rx_pkt = athrs17_reg_read(0x163c) + (athrs17_reg_read(0x1640) << 16);
#else
s17_rx_pkt = athrs17_reg_read(0x103c) + (athrs17_reg_read(0x1040) << 16);
#endif
#if DEBUG
printf("TEST: RPKT in S17 0x%08x\n", s17_rx_pkt);
#endif
#ifdef ATH_S17_MAC0_SGMII
s17_tx_pkt = athrs17_reg_read(0x1684) + (athrs17_reg_read(0x1688) << 16);
#else
s17_tx_pkt = athrs17_reg_read(0x1084) + (athrs17_reg_read(0x1088) << 16);
#endif
#if DEBUG
printf("TEST: TPKT in S17 0x%08x\n", s17_tx_pkt);
#endif
// Compare BYTES in TX
if (s17_tx_pkt != 0x410) {
#if DEBUG
printf("TEST: PKTS @ S17 - 0x%08x\n", rddata);
#endif
pass = 0;
fail = 1;
}
}
if (fail == 0) {
error = pkt_compare_data();
}
if (error == 0) {
//printf("TEST: PACKET COMPARISON PASS\n");
} else {
#if DEBUG
printf("TEST: ERROR!! PACKET COMPARISON FAIL\n");
#endif
fail = 1;
// Different from TX. This ensures packets are received back properly for a valid config.
pass = 0;
}
for (i = 0; i < NUM_DESCRIPTORS; i++) {
*(node_tx_desc_ptr + (i * 0x3) + 0x1) = (node_tx_buf_len & 0x7fffffff);
*(node_rx_desc_ptr + (i * 0x3) + 0x1) = (node_rx_buf_len & 0xfff) | (1 << 31);
}
// populate results and find the optimum value of programming
// For every set of 4 configurations find longest valid configs and number.
results[(l % 4)] = pass;
if (((l % 4) == 3)) {
lgst = find_value();
if (lgst > old_lgst) {
old_lgst = lgst;
xmii_val = xmii[(l - 3) + find];
eth_cfg_val = eth_cfg[(l - 3) + find];
}
}
}
// And write to these registers.
#if DEBUG_1
printf("TEST: FINAL XMII VAL after RX Calibration - 0x%08x\n", xmii_val);
#endif
ath_reg_wr(ETH_XMII_ADDRESS, xmii_val);
#if DEBUG_1
printf("TEST: FINAL ETH_CFG VAL after RX Calibration - 0x%08x\n", eth_cfg_val);
#endif
ath_reg_wr(ETH_CFG_ADDRESS, eth_cfg_val);
ath_gmac_reg_wr(mac,ATH_MAC_CFG1,1<<31);
}
#endif /* #ifdef RGMII_CAL */

View file

@ -0,0 +1,198 @@
/*
* 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, 0xbd007f00
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, 0xbd007f00 // 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, 0x545fc332
sw t1, 0x0070(t0) // PERF_COMP_AHB_GE0_1_ADDRESS
li t1, 0xaba03ccd
sw t1, 0x0040(t0) // PERF_COMP_AHB_GE1_0_ADDRESS
li t1, 0x545fc332
sw t1, 0x0078(t0) // PERF_COMP_AHB_GE1_1_ADDRESS
li t1, 0xaba03ccd
sw t1, 0x0034(t0) // PERF_MASK_AHB_GE0_0_ADDRESS
li t1, 0x545fc332
sw t1, 0x006c(t0) // PERF_MASK_AHB_GE0_1_ADDRESS
li t1, 0xaba03ccd
sw t1, 0x003c(t0) // PERF_MASK_AHB_GE1_0_ADDRESS
li t1, 0x545fc332
sw t1, 0x0074(t0) // PERF_MASK_AHB_GE1_1_ADDRESS
li t1, 0xaba03ccd
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, 0xbd007f00
lw t1, 0x4(t0)
addiu t1, t1, 0x1
sw t1, 0x4(t0)
li t0, 0xbd007f10
lw t1, 0x0(t0)
li t2, 0xaa55aa55
beq t1, t2, _first_pass
nop
li t0, 0xbd007f00
lw t1, 0x0(t0)
li t0, 0xbd007f10
sw t1, 0x4(t0)
nop
b _iterate_tap
nop
_first_pass:
li t0, 0xbd007f00
lw t1, 0x0(t0)
li t0, 0xbd007f10
sw t1, 0x0(t0)
sw t1, 0x4(t0)
nop
_iterate_tap:
li t0, 0xbd007f00
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, 0xbd007f00
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, 0xbd007f10
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

17
configs/qca955x_defconfig Normal file
View file

@ -0,0 +1,17 @@
CONFIG_MIPS=y
CONFIG_TARGET_QCA955X=y
CONFIG_SYS_EXTRA_OPTIONS="QCA955X"
CONFIG_SYS_PROMPT="QCA955X# "
# CONFIG_CMD_BDI is not set
# CONFIG_CMD_ELF is not set
CONFIG_CMD_RUN=y
CONFIG_CMD_SAVEENV=y
CONFIG_CMD_PING=y
# CONFIG_CMD_LOADB is not set
# CONFIG_CMD_LOADS is not set
CONFIG_CMD_FLASH=y
# 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

3477
include/955x.h Normal file

File diff suppressed because it is too large Load diff

185
include/configs/qca955x.h Normal file
View file

@ -0,0 +1,185 @@
#define CONFIG_MIPS32 1 /* MIPS32 CPU core */
#define CONFIG_BOOTDELAY 2 /* autoboot after 4 seconds */
#define CONFIG_TIMESTAMP /* Print image info with timestamp */
/*
* Console I/O configuration
*/
#define CONFIG_BAUDRATE 115200
#define CONFIG_SYS_BAUDRATE_TABLE {115200}
/* 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>"
/*
* FLASH and environment organization
*/
#ifndef FLASH_SIZE
#define FLASH_SIZE 16
#endif
#define CONFIG_SYS_MAX_FLASH_BANKS 1 /* max number of memory banks */
#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 "8256k(mib0)"
#elif (FLASH_SIZE == 8)
#define CFG_MAX_FLASH_SECT 128 /* max number of sectors on one chip */
#define ATH_MTDPARTS_MIB0 "64k(mib0)"
#else
#define CFG_MAX_FLASH_SECT 64 /* max number of sectors on one chip */
#define ATH_MTDPARTS_MIB0 "64k(mib0)"
#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 */
#else
#define CFG_FLASH_SIZE 0x00400000 /* Total flash size */
#endif
#ifndef COMPRESSED_UBOOT
#define ENABLE_DYNAMIC_CONF 1
#endif
#if (CFG_MAX_FLASH_SECT * CFG_FLASH_SECTOR_SIZE) != CFG_FLASH_SIZE
# error "Invalid flash configuration"
#endif
#define CFG_FLASH_WORD_SIZE unsigned short
#if defined(CONFIG_ATH_NAND_BR) && defined(COMPRESSED_UBOOT)
#define CFG_FLASH_BASE 0xa0100000
#else
/* NOR Flash start address */
#define CFG_FLASH_BASE 0x9f000000
#define CONFIG_SYS_TEXT_BASE 0x9f000000
#endif
#ifdef COMPRESSED_UBOOT
#define BOOTSTRAP_TEXT_BASE CFG_FLASH_BASE
#define BOOTSTRAP_CFG_MONITOR_BASE BOOTSTRAP_TEXT_BASE
#endif
#define CONFIG_PCI_CONFIG_DATA_IN_OTP
/*
* 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 */
#else
#define CFG_FLASH_SIZE_F CFG_FLASH_SIZE
#define CFG_FLASH_SECTOR_SIZE_F CFG_FLASH_SECTOR_SIZE
#endif
/*
** 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
#define BOARDCAL 0x9fff0000
#define ATHEROS_PRODUCT_ID 137
#define CAL_SECTOR (CFG_MAX_FLASH_SECT - 1)
/* For Merlin, both PCI, PCI-E interfaces are valid */
#define ATH_ART_PCICFG_OFFSET 12
/*
* The following for ENV settings
*/
#define CONFIG_SYS_MAXARGS 16
#define CONFIG_SYS_FLASH_BASE 0x9f000000
#define CONFIG_SYS_MAX_FLASH_SECT 256
#define CONFIG_ENV_IS_IN_FLASH 1
#define CONFIG_ENV_SIZE CFG_FLASH_SECTOR_SIZE //CFG_ENV_SIZE
#define CONFIG_ENV_ADDR 0x9f040000
/* Timer Specific */
#define CONFIG_SYS_MHZ 720
/* Since the count is incremented every other tick, divide by 2 -- CFG_HZ*/
#define CONFIG_SYS_MIPS_TIMER_FREQ ((CONFIG_SYS_MHZ * 1000000)/2)
#define CFG_DDR_REFRESH_VAL 0x4138
/*
* 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)
#define CONFIG_SYS_BOOTPARAMS_LEN (64*1024)
/*
* Cache Configuration
*/
#define CONFIG_SYS_CACHELINE_SIZE 32
#define CONFIG_SYS_ICACHE_SIZE 65536
#define CONFIG_SYS_DCACHE_SIZE 32768
#define CONFIG_PCI 1
#define CONFIG_CMD_PCI
#define CONFIG_PCI_SCAN_SHOW
/*#define CONFIG_USB 1*/
#define CONFIG_ATH_SOC 1
#define CONFIG_ATHEROS 1
#define CONFIG_MACH_QCA955x 1
/*#define CFG_INIT_STACK_IN_SRAM 1 -- OBSOLETE.*/
#define CONFIG_AP135 1
#define __CONFIG_BOARD_NAME ap135
#define CONFIG_BOARD_NAME "ap135"
#define CFG_PLL_FREQ CFG_PLL_720_600_200
#define ATH_SGMII_FORCED 1
#define CONFIG_ATHRS17_PHY 1
#define CFG_ATH_GMAC_NMACS 2
#define CFG_ATH_GE1_IS_CONNECTED 1
#define CONFIG_ATHRS_GMAC_SGMII 1
#define CONFIG_ATH_S17_WAN 1
#define ATH_S17_MAC0_SGMII 1
#define ATH_SGMII_FORCED_MODE 1
#define ATH_RGMII_CAL 1
#define CONFIG_LAST_STAGE_INIT
#define CONFIG_SYS_SDRAM_BASE 0x80000000
#define CONFIG_SYS_LOAD_ADDR 0x81000000
/*
* Cache lock for stack
*/
#define CONFIG_SYS_INIT_SP_OFFSET 0x1000
#define CFG_INIT_SRAM_SP_OFFSET 0xbd007000
/*
* Image type
*/
#define CONFIG_LZMA 1
#define CONFIG_IMAGE_FORMAT_LEGACY
/*
* ethernet environment
*/
#define CONFIG_SYS_RX_ETH_BUFFER 8
#define CONFIG_TFTP_BLOCKSIZE 512
#define CONFIG_MII 1
#define CFG_CMD_MII 1
#define CONFIG_COMMANDS 1