ar71xx: adding u-boot for nbg460n
This adds u-boot for nbg460n ar71xx target, as it is required as second stage bootloader. Signed-off-by: Michael Kurz <michi.kurz@googlemail.com> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@24418 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
dde3336f0d
commit
89cf40ace9
|
@ -0,0 +1,89 @@
|
||||||
|
#
|
||||||
|
# Copyright (C) 2010 OpenWrt.org
|
||||||
|
#
|
||||||
|
# This is free software, licensed under the GNU General Public License v2.
|
||||||
|
# See /LICENSE for more information.
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/rules.mk
|
||||||
|
include $(INCLUDE_DIR)/kernel.mk
|
||||||
|
|
||||||
|
PKG_NAME:=u-boot
|
||||||
|
PKG_VERSION:=2010.03
|
||||||
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
|
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
|
||||||
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||||
|
PKG_SOURCE_URL:=ftp://ftp.denx.de/pub/u-boot
|
||||||
|
PKG_MD5SUM:=
|
||||||
|
PKG_TARGETS:=bin
|
||||||
|
|
||||||
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
|
define uboot/Default
|
||||||
|
TITLE:=
|
||||||
|
CONFIG:=
|
||||||
|
IMAGE:=
|
||||||
|
endef
|
||||||
|
|
||||||
|
define uboot/nbg460n_550n_550nh
|
||||||
|
TITLE:=U-boot for the NBG460N/550N/550NH routers
|
||||||
|
endef
|
||||||
|
|
||||||
|
UBOOTS:=nbg460n_550n_550nh
|
||||||
|
|
||||||
|
define Package/uboot/template
|
||||||
|
define Package/uboot-ar71xx-$(1)
|
||||||
|
SECTION:=boot
|
||||||
|
CATEGORY:=Boot Loaders
|
||||||
|
DEPENDS:=@TARGET_ar71xx_generic_NBG_460N_550N_550NH
|
||||||
|
TITLE:=$(2)
|
||||||
|
URL:=http://www.denx.de/wiki/U-Boot
|
||||||
|
VARIANT:=$(1)
|
||||||
|
endef
|
||||||
|
endef
|
||||||
|
|
||||||
|
define BuildUbootPackage
|
||||||
|
$(eval $(uboot/Default))
|
||||||
|
$(eval $(uboot/$(1)))
|
||||||
|
$(call Package/uboot/template,$(1),$(TITLE))
|
||||||
|
endef
|
||||||
|
|
||||||
|
|
||||||
|
ifdef BUILD_VARIANT
|
||||||
|
$(eval $(call uboot/$(BUILD_VARIANT)))
|
||||||
|
UBOOT_CONFIG:=$(if $(CONFIG),$(CONFIG),$(BUILD_VARIANT))
|
||||||
|
UBOOT_IMAGE:=$(if $(IMAGE),$(IMAGE),openwrt-$(BOARD)-$(BUILD_VARIANT)-u-boot.bin)
|
||||||
|
endif
|
||||||
|
|
||||||
|
define Build/Prepare
|
||||||
|
$(call Build/Prepare/Default)
|
||||||
|
$(CP) ./files/* $(PKG_BUILD_DIR)
|
||||||
|
find $(PKG_BUILD_DIR) -name .svn | $(XARGS) rm -rf
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Configure
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||||
|
$(UBOOT_CONFIG)_config
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Build/Compile
|
||||||
|
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||||
|
CROSS_COMPILE=$(TARGET_CROSS)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Package/uboot/install/template
|
||||||
|
define Package/uboot-ar71xx-$(1)/install
|
||||||
|
$(INSTALL_DIR) $$(1)
|
||||||
|
$(CP) $(PKG_BUILD_DIR)/u-boot.bin $(BIN_DIR)/$(2)
|
||||||
|
endef
|
||||||
|
endef
|
||||||
|
|
||||||
|
$(foreach u,$(UBOOTS), \
|
||||||
|
$(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(SUBTARGET)-$(u)-u-boot.bin)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
$(foreach u,$(UBOOTS), \
|
||||||
|
$(eval $(call BuildUbootPackage,$(u))) \
|
||||||
|
$(eval $(call BuildPackage,uboot-ar71xx-$(u))) \
|
||||||
|
)
|
|
@ -0,0 +1,46 @@
|
||||||
|
#
|
||||||
|
# (C) Copyright 2003-2008
|
||||||
|
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
|
||||||
|
#
|
||||||
|
# See file CREDITS for list of people who contributed to this
|
||||||
|
# project.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License as
|
||||||
|
# published by the Free Software Foundation; either version 2 of
|
||||||
|
# the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
# MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
|
||||||
|
include $(TOPDIR)/config.mk
|
||||||
|
|
||||||
|
LIB = $(obj)lib$(BOARD).a
|
||||||
|
|
||||||
|
COBJS-y += $(BOARD).o
|
||||||
|
SOBJS-y += lowlevel_init.o
|
||||||
|
|
||||||
|
SRCS := $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||||
|
OBJS := $(addprefix $(obj),$(COBJS-y))
|
||||||
|
SOBJS := $(addprefix $(obj),$(SOBJS-y))
|
||||||
|
|
||||||
|
$(LIB): $(obj).depend $(OBJS) $(SOBJS)
|
||||||
|
$(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
|
||||||
|
|
||||||
|
|
||||||
|
#########################################################################
|
||||||
|
|
||||||
|
# defines $(obj).depend target
|
||||||
|
include $(SRCTREE)/rules.mk
|
||||||
|
|
||||||
|
sinclude $(obj).depend
|
||||||
|
|
||||||
|
#########################################################################
|
|
@ -0,0 +1 @@
|
||||||
|
TEXT_BASE = 0x81E00000
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Kurz <michi.kurz@googlemail.com>.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <version.h>
|
||||||
|
#include <asm/regdef.h>
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/addrspace.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.globl lowlevel_init
|
||||||
|
/*
|
||||||
|
All done by Bootbase, nothing to do
|
||||||
|
*/
|
||||||
|
lowlevel_init:
|
||||||
|
jr ra
|
||||||
|
nop
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Kurz <michi.kurz@googlemail.com>.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <netdev.h>
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/addrspace.h>
|
||||||
|
#include <asm/reboot.h>
|
||||||
|
#include <asm/ar71xx.h>
|
||||||
|
#include <asm/ar71xx_gpio.h>
|
||||||
|
|
||||||
|
#define NBG460N_WAN_LED 19
|
||||||
|
|
||||||
|
phys_size_t initdram(int board_type)
|
||||||
|
{
|
||||||
|
return (32*1024*1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
int checkboard(void)
|
||||||
|
{
|
||||||
|
// Set pin 19 to 1, to stop WAN LED blinking
|
||||||
|
ar71xx_setpindir(NBG460N_WAN_LED, 1);
|
||||||
|
ar71xx_setpin(NBG460N_WAN_LED, 1);
|
||||||
|
|
||||||
|
printf("U-boot on Zyxel NBG460N\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _machine_restart(void)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
writel((RESET_MODULE_FULL_CHIP | RESET_MODULE_DDR),
|
||||||
|
KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE));
|
||||||
|
readl(KSEG1ADDR(AR71XX_RESET_BASE + AR91XX_RESET_REG_RESET_MODULE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int board_eth_init(bd_t *bis)
|
||||||
|
{
|
||||||
|
char *phynames[] = {RTL8366_DEVNAME, RTL8366_DEVNAME};
|
||||||
|
u16 phyids[] = {RTL8366_LANPHY_ID, RTL8366_WANPHY_ID};
|
||||||
|
u16 phyfixed[] = {1, 0};
|
||||||
|
|
||||||
|
if (ag71xx_register(bis, phynames, phyids, phyfixed) <= 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366s_initialize())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366_mii_register(bis))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int misc_init_r(void) {
|
||||||
|
uint8_t macaddr[6];
|
||||||
|
uint8_t enetaddr[6];
|
||||||
|
|
||||||
|
debug("Testing mac addresses\n");
|
||||||
|
|
||||||
|
memcpy(macaddr, (uint8_t *) CONFIG_ETHADDR_ADDR, 6);
|
||||||
|
|
||||||
|
if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
|
||||||
|
debug("Setting eth0 mac addr to %pM\n", macaddr);
|
||||||
|
eth_setenv_enetaddr("ethaddr", macaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eth_getenv_enetaddr("eth1addr", enetaddr)) {
|
||||||
|
macaddr[5] += 1;
|
||||||
|
debug("Setting eth1 mac addr to %pM\n", macaddr);
|
||||||
|
eth_setenv_enetaddr("eth1addr", macaddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradbigmips")
|
||||||
|
OUTPUT_ARCH(mips)
|
||||||
|
ENTRY(_start)
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
. = 0x00000000;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
*(.text)
|
||||||
|
}
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.rodata : { *(.rodata) }
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.data : { *(.data) }
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.sdata : { *(.sdata) }
|
||||||
|
|
||||||
|
_gp = ALIGN(16);
|
||||||
|
|
||||||
|
__got_start = .;
|
||||||
|
.got : { *(.got) }
|
||||||
|
__got_end = .;
|
||||||
|
|
||||||
|
.sdata : { *(.sdata) }
|
||||||
|
|
||||||
|
__u_boot_cmd_start = .;
|
||||||
|
.u_boot_cmd : { *(.u_boot_cmd) }
|
||||||
|
__u_boot_cmd_end = .;
|
||||||
|
|
||||||
|
uboot_end_data = .;
|
||||||
|
num_got_entries = (__got_end - __got_start) >> 2;
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
.sbss : { *(.sbss) }
|
||||||
|
.bss : { *(.bss) }
|
||||||
|
uboot_end = .;
|
||||||
|
}
|
|
@ -0,0 +1,177 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Kurz <michi.kurz@googlemail.com>.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <asm/addrspace.h>
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <config.h>
|
||||||
|
#include <asm/ar71xx.h>
|
||||||
|
|
||||||
|
#define REG_SIZE 4
|
||||||
|
|
||||||
|
/* === END OF CONFIG === */
|
||||||
|
|
||||||
|
/* register offset */
|
||||||
|
#define OFS_RCV_BUFFER (0*REG_SIZE)
|
||||||
|
#define OFS_TRANS_HOLD (0*REG_SIZE)
|
||||||
|
#define OFS_SEND_BUFFER (0*REG_SIZE)
|
||||||
|
#define OFS_INTR_ENABLE (1*REG_SIZE)
|
||||||
|
#define OFS_INTR_ID (2*REG_SIZE)
|
||||||
|
#define OFS_DATA_FORMAT (3*REG_SIZE)
|
||||||
|
#define OFS_LINE_CONTROL (3*REG_SIZE)
|
||||||
|
#define OFS_MODEM_CONTROL (4*REG_SIZE)
|
||||||
|
#define OFS_RS232_OUTPUT (4*REG_SIZE)
|
||||||
|
#define OFS_LINE_STATUS (5*REG_SIZE)
|
||||||
|
#define OFS_MODEM_STATUS (6*REG_SIZE)
|
||||||
|
#define OFS_RS232_INPUT (6*REG_SIZE)
|
||||||
|
#define OFS_SCRATCH_PAD (7*REG_SIZE)
|
||||||
|
|
||||||
|
#define OFS_DIVISOR_LSB (0*REG_SIZE)
|
||||||
|
#define OFS_DIVISOR_MSB (1*REG_SIZE)
|
||||||
|
|
||||||
|
#define UART16550_READ(y) readl(KSEG1ADDR(AR71XX_UART_BASE+y))
|
||||||
|
#define UART16550_WRITE(x, z) writel(z, KSEG1ADDR((AR71XX_UART_BASE+x)))
|
||||||
|
|
||||||
|
void
|
||||||
|
ar71xx_sys_frequency(u32 *cpu_freq, u32 *ddr_freq, u32 *ahb_freq)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_AR91XX
|
||||||
|
u32 pll, pll_div, cpu_div, ahb_div, ddr_div, freq;
|
||||||
|
|
||||||
|
pll = readl(KSEG1ADDR(AR71XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE));
|
||||||
|
|
||||||
|
pll_div =
|
||||||
|
((pll & AR71XX_PLL_DIV_MASK) >> AR71XX_PLL_DIV_SHIFT) + 1;
|
||||||
|
|
||||||
|
cpu_div =
|
||||||
|
((pll & AR71XX_CPU_DIV_MASK) >> AR71XX_CPU_DIV_SHIFT) + 1;
|
||||||
|
|
||||||
|
ddr_div =
|
||||||
|
((pll & AR71XX_DDR_DIV_MASK) >> AR71XX_DDR_DIV_SHIFT) + 1;
|
||||||
|
|
||||||
|
ahb_div =
|
||||||
|
(((pll & AR71XX_AHB_DIV_MASK) >> AR71XX_AHB_DIV_SHIFT) + 1)*2;
|
||||||
|
|
||||||
|
freq = pll_div * 40000000;
|
||||||
|
|
||||||
|
if (cpu_freq)
|
||||||
|
*cpu_freq = freq/cpu_div;
|
||||||
|
|
||||||
|
if (ddr_freq)
|
||||||
|
*ddr_freq = freq/ddr_div;
|
||||||
|
|
||||||
|
if (ahb_freq)
|
||||||
|
*ahb_freq = (freq/cpu_div)/ahb_div;
|
||||||
|
|
||||||
|
#else
|
||||||
|
u32 pll, pll_div, ahb_div, ddr_div, freq;
|
||||||
|
|
||||||
|
pll = readl(KSEG1ADDR(AR91XX_PLL_REG_CPU_CONFIG + AR71XX_PLL_BASE));
|
||||||
|
|
||||||
|
pll_div =
|
||||||
|
((pll & AR91XX_PLL_DIV_MASK) >> AR91XX_PLL_DIV_SHIFT);
|
||||||
|
|
||||||
|
ddr_div =
|
||||||
|
((pll & AR91XX_DDR_DIV_MASK) >> AR91XX_DDR_DIV_SHIFT) + 1;
|
||||||
|
|
||||||
|
ahb_div =
|
||||||
|
(((pll & AR91XX_AHB_DIV_MASK) >> AR91XX_AHB_DIV_SHIFT) + 1)*2;
|
||||||
|
|
||||||
|
freq = pll_div * 5000000;
|
||||||
|
|
||||||
|
if (cpu_freq)
|
||||||
|
*cpu_freq = freq;
|
||||||
|
|
||||||
|
if (ddr_freq)
|
||||||
|
*ddr_freq = freq/ddr_div;
|
||||||
|
|
||||||
|
if (ahb_freq)
|
||||||
|
*ahb_freq = freq/ahb_div;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int serial_init(void)
|
||||||
|
{
|
||||||
|
u32 div;
|
||||||
|
u32 ahb_freq = 100000000;
|
||||||
|
|
||||||
|
ar71xx_sys_frequency (0, 0, &ahb_freq);
|
||||||
|
div = ahb_freq/(16 * CONFIG_BAUDRATE);
|
||||||
|
|
||||||
|
// enable uart pins
|
||||||
|
#ifndef CONFIG_AR91XX
|
||||||
|
writel(AR71XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC));
|
||||||
|
#else
|
||||||
|
writel(AR91XX_GPIO_FUNC_UART_EN, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_FUNC));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* set DIAB bit */
|
||||||
|
UART16550_WRITE(OFS_LINE_CONTROL, 0x80);
|
||||||
|
|
||||||
|
/* set divisor */
|
||||||
|
UART16550_WRITE(OFS_DIVISOR_LSB, (div & 0xff));
|
||||||
|
UART16550_WRITE(OFS_DIVISOR_MSB, ((div >> 8) & 0xff));
|
||||||
|
|
||||||
|
/* clear DIAB bit*/
|
||||||
|
UART16550_WRITE(OFS_LINE_CONTROL, 0x00);
|
||||||
|
|
||||||
|
/* set data format */
|
||||||
|
UART16550_WRITE(OFS_DATA_FORMAT, 0x3);
|
||||||
|
|
||||||
|
UART16550_WRITE(OFS_INTR_ENABLE, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_tstc (void)
|
||||||
|
{
|
||||||
|
return(UART16550_READ(OFS_LINE_STATUS) & 0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int serial_getc(void)
|
||||||
|
{
|
||||||
|
while(!serial_tstc());
|
||||||
|
|
||||||
|
return UART16550_READ(OFS_RCV_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void serial_putc(const char byte)
|
||||||
|
{
|
||||||
|
if (byte == '\n') serial_putc ('\r');
|
||||||
|
|
||||||
|
while (((UART16550_READ(OFS_LINE_STATUS)) & 0x20) == 0x0);
|
||||||
|
UART16550_WRITE(OFS_SEND_BUFFER, byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_setbrg (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_puts (const char *s)
|
||||||
|
{
|
||||||
|
while (*s)
|
||||||
|
{
|
||||||
|
serial_putc (*s++);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,809 @@
|
||||||
|
/*
|
||||||
|
* Atheros AR71xx built-in ethernet mac driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 Michael Kurz <michi.kurz@googlemail.com>
|
||||||
|
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||||
|
*
|
||||||
|
* Based on Atheros' AG7100 driver
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <net.h>
|
||||||
|
#include <miiphy.h>
|
||||||
|
|
||||||
|
#include <asm/ar71xx.h>
|
||||||
|
|
||||||
|
#include "ag71xx.h"
|
||||||
|
|
||||||
|
#ifdef AG71XX_DEBUG
|
||||||
|
#define DBG(fmt,args...) printf(fmt ,##args)
|
||||||
|
#else
|
||||||
|
#define DBG(fmt,args...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static struct ag71xx agtable[] = {
|
||||||
|
{
|
||||||
|
.mac_base = KSEG1ADDR(AR71XX_GE0_BASE),
|
||||||
|
.mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII0_CTRL),
|
||||||
|
.mii_if = CONFIG_AG71XX_MII0_IIF,
|
||||||
|
} , {
|
||||||
|
.mac_base = KSEG1ADDR(AR71XX_GE1_BASE),
|
||||||
|
.mii_ctrl = KSEG1ADDR(AR71XX_MII_BASE + MII_REG_MII1_CTRL),
|
||||||
|
.mii_if = CONFIG_AG71XX_MII1_IIF,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ag71xx_ring_alloc(struct ag71xx_ring *ring, unsigned int size)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
int i;
|
||||||
|
int rsize;
|
||||||
|
|
||||||
|
ring->desc_size = sizeof(struct ag71xx_desc);
|
||||||
|
if (ring->desc_size % (CONFIG_SYS_CACHELINE_SIZE)) {
|
||||||
|
rsize = roundup(ring->desc_size, CONFIG_SYS_CACHELINE_SIZE);
|
||||||
|
DBG("ag71xx: ring %p, desc size %u rounded to %u\n",
|
||||||
|
ring, ring->desc_size,
|
||||||
|
rsize);
|
||||||
|
ring->desc_size = rsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
ring->descs_cpu = (u8 *) malloc((size * ring->desc_size)
|
||||||
|
+ CONFIG_SYS_CACHELINE_SIZE - 1);
|
||||||
|
if (!ring->descs_cpu) {
|
||||||
|
err = -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
ring->descs_cpu = (u8 *) UNCACHED_SDRAM((((u32) ring->descs_cpu +
|
||||||
|
CONFIG_SYS_CACHELINE_SIZE - 1) & ~(CONFIG_SYS_CACHELINE_SIZE - 1)));
|
||||||
|
ring->descs_dma = (u8 *) virt_to_phys(ring->descs_cpu);
|
||||||
|
|
||||||
|
ring->size = size;
|
||||||
|
|
||||||
|
ring->buf = malloc(size * sizeof(*ring->buf));
|
||||||
|
if (!ring->buf) {
|
||||||
|
err = -1;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
memset(ring->buf, 0, size * sizeof(*ring->buf));
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
ring->buf[i].desc =
|
||||||
|
(struct ag71xx_desc *)&ring->descs_cpu[i * ring->desc_size];
|
||||||
|
DBG("ag71xx: ring %p, desc %d at %p\n",
|
||||||
|
ring, i, ring->buf[i].desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_cache( (u32) ring->buf, size * sizeof(*ring->buf));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_ring_tx_init(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
struct ag71xx_ring *ring = &ag->tx_ring;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < AG71XX_TX_RING_SIZE; i++) {
|
||||||
|
ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma +
|
||||||
|
ring->desc_size * ((i + 1) % AG71XX_TX_RING_SIZE)));
|
||||||
|
|
||||||
|
ring->buf[i].desc->ctrl = DESC_EMPTY;
|
||||||
|
ring->buf[i].skb = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ring->curr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_ring_rx_clean(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
struct ag71xx_ring *ring = &ag->rx_ring;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!ring->buf)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
|
||||||
|
ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]);
|
||||||
|
flush_cache((u32) NetRxPackets[i], PKTSIZE_ALIGN);
|
||||||
|
ring->buf[i].desc->ctrl = DESC_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ring->curr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ag71xx_ring_rx_init(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
struct ag71xx_ring *ring = &ag->rx_ring;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
|
||||||
|
ring->buf[i].desc->next = (u32) virt_to_phys((ring->descs_dma +
|
||||||
|
ring->desc_size * ((i + 1) % AG71XX_RX_RING_SIZE)));
|
||||||
|
|
||||||
|
DBG("ag71xx: RX desc at %p, next is %08x\n",
|
||||||
|
ring->buf[i].desc,
|
||||||
|
ring->buf[i].desc->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < AG71XX_RX_RING_SIZE; i++) {
|
||||||
|
ring->buf[i].desc->data = (u32) virt_to_phys(NetRxPackets[i]);
|
||||||
|
ring->buf[i].desc->ctrl = DESC_EMPTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ring->curr = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ag71xx_rings_init(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = ag71xx_ring_alloc(&ag->tx_ring, AG71XX_TX_RING_SIZE);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ag71xx_ring_tx_init(ag);
|
||||||
|
|
||||||
|
ret = ag71xx_ring_alloc(&ag->rx_ring, AG71XX_RX_RING_SIZE);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = ag71xx_ring_rx_init(ag);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ar71xx_set_pll(u32 cfg_reg, u32 pll_reg, u32 pll_val, u32 shift)
|
||||||
|
{
|
||||||
|
uint32_t base = KSEG1ADDR(AR71XX_PLL_BASE);
|
||||||
|
u32 t;
|
||||||
|
|
||||||
|
t = readl(base + cfg_reg);
|
||||||
|
t &= ~(3 << shift);
|
||||||
|
t |= (2 << shift);
|
||||||
|
writel(t, base + cfg_reg);
|
||||||
|
udelay(100);
|
||||||
|
|
||||||
|
writel(pll_val, base + pll_reg);
|
||||||
|
|
||||||
|
t |= (3 << shift);
|
||||||
|
writel(t, base + cfg_reg);
|
||||||
|
udelay(100);
|
||||||
|
|
||||||
|
t &= ~(3 << shift);
|
||||||
|
writel(t, base + cfg_reg);
|
||||||
|
udelay(100);
|
||||||
|
|
||||||
|
debug("ar71xx: pll_reg %#x: %#x\n", (unsigned int)(base + pll_reg),
|
||||||
|
readl(base + pll_reg));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ar91xx_set_pll_ge0(int speed)
|
||||||
|
{
|
||||||
|
//u32 val = ar71xx_get_eth_pll(0, speed);
|
||||||
|
u32 pll_val;
|
||||||
|
|
||||||
|
switch (speed) {
|
||||||
|
case SPEED_10:
|
||||||
|
pll_val = 0x00441099;
|
||||||
|
break;
|
||||||
|
case SPEED_100:
|
||||||
|
pll_val = 0x13000a44;
|
||||||
|
break;
|
||||||
|
case SPEED_1000:
|
||||||
|
pll_val = 0x1a000000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH0_INT_CLOCK,
|
||||||
|
pll_val, AR91XX_ETH0_PLL_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ar91xx_set_pll_ge1(int speed)
|
||||||
|
{
|
||||||
|
//u32 val = ar71xx_get_eth_pll(1, speed);
|
||||||
|
u32 pll_val;
|
||||||
|
|
||||||
|
switch (speed) {
|
||||||
|
case SPEED_10:
|
||||||
|
pll_val = 0x00441099;
|
||||||
|
break;
|
||||||
|
case SPEED_100:
|
||||||
|
pll_val = 0x13000a44;
|
||||||
|
break;
|
||||||
|
case SPEED_1000:
|
||||||
|
pll_val = 0x1a000000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
ar71xx_set_pll(AR91XX_PLL_REG_ETH_CONFIG, AR91XX_PLL_REG_ETH1_INT_CLOCK,
|
||||||
|
pll_val, AR91XX_ETH1_PLL_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_hw_set_macaddr(struct ag71xx *ag, unsigned char *mac)
|
||||||
|
{
|
||||||
|
u32 t;
|
||||||
|
|
||||||
|
t = (((u32) mac[5]) << 24) | (((u32) mac[4]) << 16)
|
||||||
|
| (((u32) mac[3]) << 8) | ((u32) mac[2]);
|
||||||
|
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_MAC_ADDR1, t);
|
||||||
|
|
||||||
|
t = (((u32) mac[1]) << 24) | (((u32) mac[0]) << 16);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_MAC_ADDR2, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_dma_reset(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
DBG("%s: txdesc reg: 0x%08x rxdesc reg: 0x%08x\n",
|
||||||
|
ag->dev->name,
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_TX_DESC),
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_RX_DESC));
|
||||||
|
|
||||||
|
/* stop RX and TX */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
|
||||||
|
|
||||||
|
/* clear descriptor addresses */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_TX_DESC, 0);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_DESC, 0);
|
||||||
|
|
||||||
|
/* clear pending RX/TX interrupts */
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_PR);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_PS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear pending errors */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_STATUS, RX_STATUS_BE | RX_STATUS_OF);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_TX_STATUS, TX_STATUS_BE | TX_STATUS_UR);
|
||||||
|
|
||||||
|
val = ag71xx_rr(ag, AG71XX_REG_RX_STATUS);
|
||||||
|
if (val)
|
||||||
|
printf("%s: unable to clear DMA Rx status: %08x\n",
|
||||||
|
ag->dev->name, val);
|
||||||
|
|
||||||
|
val = ag71xx_rr(ag, AG71XX_REG_TX_STATUS);
|
||||||
|
|
||||||
|
/* mask out reserved bits */
|
||||||
|
val &= ~0xff000000;
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
printf("%s: unable to clear DMA Tx status: %08x\n",
|
||||||
|
ag->dev->name, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ag71xx_halt(struct eth_device *dev)
|
||||||
|
{
|
||||||
|
struct ag71xx *ag = (struct ag71xx *) dev->priv;
|
||||||
|
|
||||||
|
/* stop RX engine */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_CTRL, 0);
|
||||||
|
|
||||||
|
ag71xx_dma_reset(ag);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_WAIT 1000
|
||||||
|
|
||||||
|
static int ag71xx_send(struct eth_device *dev, volatile void *packet,
|
||||||
|
int length)
|
||||||
|
{
|
||||||
|
struct ag71xx *ag = (struct ag71xx *) dev->priv;
|
||||||
|
struct ag71xx_ring *ring = &ag->tx_ring;
|
||||||
|
struct ag71xx_desc *desc;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
i = ring->curr % AG71XX_TX_RING_SIZE;
|
||||||
|
desc = ring->buf[i].desc;
|
||||||
|
|
||||||
|
if (!ag71xx_desc_empty(desc)) {
|
||||||
|
printf("%s: tx buffer full\n", ag->dev->name);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
flush_cache((u32) packet, length);
|
||||||
|
desc->data = (u32) virt_to_phys(packet);
|
||||||
|
desc->ctrl = (length & DESC_PKTLEN_M);
|
||||||
|
|
||||||
|
DBG("%s: sending %#08x length %#08x\n",
|
||||||
|
ag->dev->name, desc->data, desc->ctrl);
|
||||||
|
|
||||||
|
ring->curr++;
|
||||||
|
if (ring->curr >= AG71XX_TX_RING_SIZE){
|
||||||
|
ring->curr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* enable TX engine */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_TX_CTRL, TX_CTRL_TXE);
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_WAIT; i++)
|
||||||
|
{
|
||||||
|
if (ag71xx_desc_empty(desc))
|
||||||
|
break;
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
if (i == MAX_WAIT) {
|
||||||
|
printf("%s: tx timed out!\n", ag->dev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* disable TX engine */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_TX_CTRL, 0);
|
||||||
|
desc->data = 0;
|
||||||
|
desc->ctrl = DESC_EMPTY;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ag71xx_recv(struct eth_device *dev)
|
||||||
|
{
|
||||||
|
struct ag71xx *ag = (struct ag71xx *) dev->priv;
|
||||||
|
struct ag71xx_ring *ring = &ag->rx_ring;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
unsigned int i = ring->curr % AG71XX_RX_RING_SIZE;
|
||||||
|
struct ag71xx_desc *desc = ring->buf[i].desc;
|
||||||
|
int pktlen;
|
||||||
|
|
||||||
|
if (ag71xx_desc_empty(desc))
|
||||||
|
break;
|
||||||
|
|
||||||
|
DBG("%s: rx packets, curr=%u\n", dev->name, ring->curr);
|
||||||
|
|
||||||
|
pktlen = ag71xx_desc_pktlen(desc);
|
||||||
|
pktlen -= ETH_FCS_LEN;
|
||||||
|
|
||||||
|
|
||||||
|
NetReceive(NetRxPackets[i] , pktlen);
|
||||||
|
flush_cache( (u32) NetRxPackets[i], PKTSIZE_ALIGN);
|
||||||
|
|
||||||
|
ring->buf[i].desc->ctrl = DESC_EMPTY;
|
||||||
|
ring->curr++;
|
||||||
|
if (ring->curr >= AG71XX_RX_RING_SIZE){
|
||||||
|
ring->curr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ag71xx_rr(ag, AG71XX_REG_RX_CTRL) & RX_CTRL_RXE) == 0) {
|
||||||
|
/* start RX engine */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef AG71XX_DEBUG
|
||||||
|
static char *ag71xx_speed_str(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
switch (ag->speed) {
|
||||||
|
case SPEED_1000:
|
||||||
|
return "1000";
|
||||||
|
case SPEED_100:
|
||||||
|
return "100";
|
||||||
|
case SPEED_10:
|
||||||
|
return "10";
|
||||||
|
}
|
||||||
|
|
||||||
|
return "?";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ag71xx_link_adjust(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
u32 cfg2;
|
||||||
|
u32 ifctl;
|
||||||
|
u32 fifo5;
|
||||||
|
u32 mii_speed;
|
||||||
|
|
||||||
|
if (!ag->link) {
|
||||||
|
DBG("%s: link down\n", ag->dev->name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg2 = ag71xx_rr(ag, AG71XX_REG_MAC_CFG2);
|
||||||
|
cfg2 &= ~(MAC_CFG2_IF_1000 | MAC_CFG2_IF_10_100 | MAC_CFG2_FDX);
|
||||||
|
cfg2 |= (ag->duplex) ? MAC_CFG2_FDX : 0;
|
||||||
|
|
||||||
|
ifctl = ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL);
|
||||||
|
ifctl &= ~(MAC_IFCTL_SPEED);
|
||||||
|
|
||||||
|
fifo5 = ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5);
|
||||||
|
fifo5 &= ~FIFO_CFG5_BM;
|
||||||
|
|
||||||
|
switch (ag->speed) {
|
||||||
|
case SPEED_1000:
|
||||||
|
mii_speed = MII_CTRL_SPEED_1000;
|
||||||
|
cfg2 |= MAC_CFG2_IF_1000;
|
||||||
|
fifo5 |= FIFO_CFG5_BM;
|
||||||
|
break;
|
||||||
|
case SPEED_100:
|
||||||
|
mii_speed = MII_CTRL_SPEED_100;
|
||||||
|
cfg2 |= MAC_CFG2_IF_10_100;
|
||||||
|
ifctl |= MAC_IFCTL_SPEED;
|
||||||
|
break;
|
||||||
|
case SPEED_10:
|
||||||
|
mii_speed = MII_CTRL_SPEED_10;
|
||||||
|
cfg2 |= MAC_CFG2_IF_10_100;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG3, 0x00780fff);
|
||||||
|
|
||||||
|
if (ag->macNum == 0)
|
||||||
|
ar91xx_set_pll_ge0(ag->speed);
|
||||||
|
else
|
||||||
|
ar91xx_set_pll_ge1(ag->speed);
|
||||||
|
|
||||||
|
ag71xx_mii_ctrl_set_speed(ag, mii_speed);
|
||||||
|
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
|
||||||
|
|
||||||
|
DBG("%s: link up (%sMbps/%s duplex)\n",
|
||||||
|
ag->dev->name,
|
||||||
|
ag71xx_speed_str(ag),
|
||||||
|
(1 == ag->duplex) ? "Full" : "Half");
|
||||||
|
|
||||||
|
DBG("%s: fifo_cfg0=%#x, fifo_cfg1=%#x, fifo_cfg2=%#x\n",
|
||||||
|
ag->dev->name,
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG0),
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG1),
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG2));
|
||||||
|
|
||||||
|
DBG("%s: fifo_cfg3=%#x, fifo_cfg4=%#x, fifo_cfg5=%#x\n",
|
||||||
|
ag->dev->name,
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG3),
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG4),
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_FIFO_CFG5));
|
||||||
|
|
||||||
|
DBG("%s: mac_cfg2=%#x, mac_ifctl=%#x, mii_ctrl=%#x\n",
|
||||||
|
ag->dev->name,
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_MAC_CFG2),
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_MAC_IFCTL),
|
||||||
|
ag71xx_mii_ctrl_rr(ag));
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
|
||||||
|
static int ag71xx_getMiiSpeed(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
uint16_t phyreg, cap;
|
||||||
|
|
||||||
|
if (miiphy_read(ag->phyname, ag->phyid,
|
||||||
|
PHY_BMSR, &phyreg)) {
|
||||||
|
puts("PHY_BMSR read failed, assuming no link\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((phyreg & PHY_BMSR_LS) == 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (miiphy_read(ag->phyname, ag->phyid,
|
||||||
|
PHY_1000BTSR, &phyreg))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (phyreg & PHY_1000BTSR_1000FD) {
|
||||||
|
ag->speed = SPEED_1000;
|
||||||
|
ag->duplex = 1;
|
||||||
|
} else if (phyreg & PHY_1000BTSR_1000HD) {
|
||||||
|
ag->speed = SPEED_1000;
|
||||||
|
ag->duplex = 0;
|
||||||
|
} else {
|
||||||
|
if (miiphy_read(ag->phyname, ag->phyid,
|
||||||
|
PHY_ANAR, &cap))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (miiphy_read(ag->phyname, ag->phyid,
|
||||||
|
PHY_ANLPAR, &phyreg))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
cap &= phyreg;
|
||||||
|
if (cap & PHY_ANLPAR_TXFD) {
|
||||||
|
ag->speed = SPEED_100;
|
||||||
|
ag->duplex = 1;
|
||||||
|
} else if (cap & PHY_ANLPAR_TX) {
|
||||||
|
ag->speed = SPEED_100;
|
||||||
|
ag->duplex = 0;
|
||||||
|
} else if (cap & PHY_ANLPAR_10FD) {
|
||||||
|
ag->speed = SPEED_10;
|
||||||
|
ag->duplex = 1;
|
||||||
|
} else {
|
||||||
|
ag->speed = SPEED_10;
|
||||||
|
ag->duplex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ag->link = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int ag71xx_hw_start(struct eth_device *dev, bd_t * bd)
|
||||||
|
{
|
||||||
|
struct ag71xx *ag = (struct ag71xx *) dev->priv;
|
||||||
|
|
||||||
|
ag71xx_dma_reset(ag);
|
||||||
|
|
||||||
|
ag71xx_ring_rx_clean(ag);
|
||||||
|
ag71xx_ring_tx_init(ag);
|
||||||
|
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_TX_DESC,
|
||||||
|
(u32) virt_to_phys(ag->tx_ring.descs_dma));
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_DESC,
|
||||||
|
(u32) virt_to_phys(ag->rx_ring.descs_dma));
|
||||||
|
|
||||||
|
ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr);
|
||||||
|
|
||||||
|
if (ag->phyfixed) {
|
||||||
|
ag->link = 1;
|
||||||
|
ag->duplex = 1;
|
||||||
|
ag->speed = SPEED_1000;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
|
||||||
|
if (ag71xx_getMiiSpeed(ag))
|
||||||
|
return -1;
|
||||||
|
#else
|
||||||
|
/* only fixed, without mii */
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
ag71xx_link_adjust(ag);
|
||||||
|
|
||||||
|
DBG("%s: txdesc reg: %#08x rxdesc reg: %#08x\n",
|
||||||
|
ag->dev->name,
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_TX_DESC),
|
||||||
|
ag71xx_rr(ag, AG71XX_REG_RX_DESC));
|
||||||
|
|
||||||
|
/* start RX engine */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_CTRL, RX_CTRL_RXE);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FIFO_CFG0_INIT (FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT)
|
||||||
|
|
||||||
|
#define FIFO_CFG4_INIT (FIFO_CFG4_DE | FIFO_CFG4_DV | FIFO_CFG4_FC | \
|
||||||
|
FIFO_CFG4_CE | FIFO_CFG4_CR | FIFO_CFG4_LM | \
|
||||||
|
FIFO_CFG4_LO | FIFO_CFG4_OK | FIFO_CFG4_MC | \
|
||||||
|
FIFO_CFG4_BC | FIFO_CFG4_DR | FIFO_CFG4_LE | \
|
||||||
|
FIFO_CFG4_CF | FIFO_CFG4_PF | FIFO_CFG4_UO | \
|
||||||
|
FIFO_CFG4_VT)
|
||||||
|
|
||||||
|
#define FIFO_CFG5_INIT (FIFO_CFG5_DE | FIFO_CFG5_DV | FIFO_CFG5_FC | \
|
||||||
|
FIFO_CFG5_CE | FIFO_CFG5_LO | FIFO_CFG5_OK | \
|
||||||
|
FIFO_CFG5_MC | FIFO_CFG5_BC | FIFO_CFG5_DR | \
|
||||||
|
FIFO_CFG5_CF | FIFO_CFG5_PF | FIFO_CFG5_VT | \
|
||||||
|
FIFO_CFG5_LE | FIFO_CFG5_FT | FIFO_CFG5_16 | \
|
||||||
|
FIFO_CFG5_17 | FIFO_CFG5_SF)
|
||||||
|
|
||||||
|
static int ag71xx_hw_init(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t reg;
|
||||||
|
uint32_t mask, mii_type;
|
||||||
|
|
||||||
|
if (ag->macNum == 0) {
|
||||||
|
mask = (RESET_MODULE_GE0_MAC | RESET_MODULE_GE0_PHY);
|
||||||
|
mii_type = 0x13;
|
||||||
|
} else {
|
||||||
|
mask = (RESET_MODULE_GE1_MAC | RESET_MODULE_GE1_PHY);
|
||||||
|
mii_type = 0x11;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mac soft reset
|
||||||
|
ag71xx_sb(ag, AG71XX_REG_MAC_CFG1, MAC_CFG1_SR);
|
||||||
|
udelay(20);
|
||||||
|
|
||||||
|
// device stop
|
||||||
|
reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
|
||||||
|
ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg | mask);
|
||||||
|
udelay(100 * 1000);
|
||||||
|
|
||||||
|
// device start
|
||||||
|
reg = ar71xx_reset_rr(AR91XX_RESET_REG_RESET_MODULE);
|
||||||
|
ar71xx_reset_wr(AR91XX_RESET_REG_RESET_MODULE, reg & ~mask);
|
||||||
|
udelay(100 * 1000);
|
||||||
|
|
||||||
|
/* setup MAC configuration registers */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_MAC_CFG1, (MAC_CFG1_RXE | MAC_CFG1_TXE));
|
||||||
|
|
||||||
|
ag71xx_sb(ag, AG71XX_REG_MAC_CFG2,
|
||||||
|
MAC_CFG2_PAD_CRC_EN | MAC_CFG2_LEN_CHECK);
|
||||||
|
|
||||||
|
/* setup FIFO configuration register 0 */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG0, FIFO_CFG0_INIT);
|
||||||
|
|
||||||
|
/* setup MII interface type */
|
||||||
|
ag71xx_mii_ctrl_set_if(ag, ag->mii_if);
|
||||||
|
|
||||||
|
/* setup mdio clock divisor */
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_MII_CFG, MII_CFG_CLK_DIV_20);
|
||||||
|
|
||||||
|
/* setup FIFO configuration registers */
|
||||||
|
ag71xx_sb(ag, AG71XX_REG_FIFO_CFG4, FIFO_CFG4_INIT);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG1, 0x0fff0000);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG2, 0x00001fff);
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, FIFO_CFG5_INIT);
|
||||||
|
|
||||||
|
ag71xx_dma_reset(ag);
|
||||||
|
|
||||||
|
ret = ag71xx_rings_init(ag);
|
||||||
|
if (ret)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_TX_DESC,
|
||||||
|
(u32) virt_to_phys(ag->tx_ring.descs_dma));
|
||||||
|
ag71xx_wr(ag, AG71XX_REG_RX_DESC,
|
||||||
|
(u32) virt_to_phys(ag->rx_ring.descs_dma));
|
||||||
|
|
||||||
|
ag71xx_hw_set_macaddr(ag, ag->dev->enetaddr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
|
||||||
|
#define AG71XX_MDIO_RETRY 1000
|
||||||
|
#define AG71XX_MDIO_DELAY 5
|
||||||
|
|
||||||
|
static inline struct ag71xx *ag71xx_name2mac(char *devname)
|
||||||
|
{
|
||||||
|
if (strcmp(devname, agtable[0].dev->name) == 0)
|
||||||
|
return &agtable[0];
|
||||||
|
else if (strcmp(devname, agtable[1].dev->name) == 0)
|
||||||
|
return &agtable[1];
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ag71xx_mdio_wr(struct ag71xx *ag, unsigned reg,
|
||||||
|
u32 value)
|
||||||
|
{
|
||||||
|
uint32_t r;
|
||||||
|
|
||||||
|
r = ag->mac_base + reg;
|
||||||
|
writel(value, r);
|
||||||
|
|
||||||
|
/* flush write */
|
||||||
|
(void) readl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ag71xx_mdio_rr(struct ag71xx *ag, unsigned reg)
|
||||||
|
{
|
||||||
|
return readl(ag->mac_base + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ag71xx_mdio_read(char *devname, unsigned char addr,
|
||||||
|
unsigned char reg, unsigned short *val)
|
||||||
|
{
|
||||||
|
struct ag71xx *ag = ag71xx_name2mac(devname);
|
||||||
|
uint16_t regData;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
|
||||||
|
ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR,
|
||||||
|
((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
|
||||||
|
ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_READ);
|
||||||
|
|
||||||
|
i = AG71XX_MDIO_RETRY;
|
||||||
|
while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
|
||||||
|
if (i-- == 0) {
|
||||||
|
printf("%s: mii_read timed out\n",
|
||||||
|
ag->dev->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
udelay(AG71XX_MDIO_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
regData = (uint16_t) ag71xx_mdio_rr(ag, AG71XX_REG_MII_STATUS) & 0xffff;
|
||||||
|
ag71xx_mdio_wr(ag, AG71XX_REG_MII_CMD, MII_CMD_WRITE);
|
||||||
|
|
||||||
|
DBG("mii_read: addr=%04x, reg=%04x, value=%04x\n", addr, reg, regData);
|
||||||
|
|
||||||
|
if (val)
|
||||||
|
*val = regData;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ag71xx_mdio_write(char *devname, unsigned char addr,
|
||||||
|
unsigned char reg, unsigned short val)
|
||||||
|
{
|
||||||
|
struct ag71xx *ag = ag71xx_name2mac(devname);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (ag == NULL)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
DBG("mii_write: addr=%04x, reg=%04x, value=%04x\n", addr, reg, val);
|
||||||
|
|
||||||
|
ag71xx_mdio_wr(ag, AG71XX_REG_MII_ADDR,
|
||||||
|
((addr & 0xff) << MII_ADDR_SHIFT) | (reg & 0xff));
|
||||||
|
ag71xx_mdio_wr(ag, AG71XX_REG_MII_CTRL, val);
|
||||||
|
|
||||||
|
i = AG71XX_MDIO_RETRY;
|
||||||
|
while (ag71xx_mdio_rr(ag, AG71XX_REG_MII_IND) & MII_IND_BUSY) {
|
||||||
|
if (i-- == 0) {
|
||||||
|
printf("%s: mii_write timed out\n",
|
||||||
|
ag->dev->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
udelay(AG71XX_MDIO_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ag71xx_register(bd_t * bis, char *phyname[], uint16_t phyid[], uint16_t phyfixed[])
|
||||||
|
{
|
||||||
|
int i, num = 0;
|
||||||
|
u8 used_ports[MAX_AG71XX_DEVS] = CONFIG_AG71XX_PORTS;
|
||||||
|
|
||||||
|
for (i = 0; i < MAX_AG71XX_DEVS; i++) {
|
||||||
|
/*skip if port is configured not to use */
|
||||||
|
if (used_ports[i] == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
agtable[i].dev = malloc(sizeof(struct eth_device));
|
||||||
|
if (agtable[i].dev == NULL) {
|
||||||
|
puts("malloc failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
memset(agtable[i].dev, 0, sizeof(struct eth_device));
|
||||||
|
sprintf(agtable[i].dev->name, "eth%d", i);
|
||||||
|
|
||||||
|
agtable[i].dev->iobase = 0;
|
||||||
|
agtable[i].dev->init = ag71xx_hw_start;
|
||||||
|
agtable[i].dev->halt = ag71xx_halt;
|
||||||
|
agtable[i].dev->send = ag71xx_send;
|
||||||
|
agtable[i].dev->recv = ag71xx_recv;
|
||||||
|
agtable[i].dev->priv = (void *) (&agtable[i]);
|
||||||
|
agtable[i].macNum = i;
|
||||||
|
eth_register(agtable[i].dev);
|
||||||
|
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
|
||||||
|
|
||||||
|
if ((phyname == NULL) || (phyid == NULL) || (phyfixed == NULL))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
agtable[i].phyname = strdup(phyname[i]);
|
||||||
|
agtable[i].phyid = phyid[i];
|
||||||
|
agtable[i].phyfixed = phyfixed[i];
|
||||||
|
|
||||||
|
miiphy_register(agtable[i].dev->name, ag71xx_mdio_read,
|
||||||
|
ag71xx_mdio_write);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ag71xx_hw_init(&agtable[i]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
|
@ -0,0 +1,374 @@
|
||||||
|
/*
|
||||||
|
* Atheros AR71xx built-in ethernet mac driver
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||||
|
*
|
||||||
|
* Based on Atheros' AG7100 driver
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __AG71XX_H
|
||||||
|
#define __AG71XX_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
|
#include <asm/ar71xx.h>
|
||||||
|
|
||||||
|
// controller has 2 ports
|
||||||
|
#define MAX_AG71XX_DEVS 2
|
||||||
|
|
||||||
|
#define ETH_FCS_LEN 4
|
||||||
|
|
||||||
|
#define SPEED_10 10
|
||||||
|
#define SPEED_100 100
|
||||||
|
#define SPEED_1000 1000
|
||||||
|
|
||||||
|
|
||||||
|
#define AG71XX_INT_ERR (AG71XX_INT_RX_BE | AG71XX_INT_TX_BE)
|
||||||
|
#define AG71XX_INT_TX (AG71XX_INT_TX_PS)
|
||||||
|
#define AG71XX_INT_RX (AG71XX_INT_RX_PR | AG71XX_INT_RX_OF)
|
||||||
|
|
||||||
|
#define AG71XX_INT_POLL (AG71XX_INT_RX | AG71XX_INT_TX)
|
||||||
|
#define AG71XX_INT_INIT (AG71XX_INT_ERR | AG71XX_INT_POLL)
|
||||||
|
|
||||||
|
#define AG71XX_TX_FIFO_LEN 2048
|
||||||
|
#define AG71XX_TX_MTU_LEN 1536
|
||||||
|
#define AG71XX_RX_PKT_RESERVE 64
|
||||||
|
#define AG71XX_RX_PKT_SIZE \
|
||||||
|
(AG71XX_RX_PKT_RESERVE + ETH_HLEN + ETH_FRAME_LEN + ETH_FCS_LEN)
|
||||||
|
|
||||||
|
#ifndef CONFIG_SYS_RX_ETH_BUFFER
|
||||||
|
#define AG71XX_TX_RING_SIZE 4
|
||||||
|
#define AG71XX_RX_RING_SIZE 4
|
||||||
|
#else
|
||||||
|
#define AG71XX_TX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER
|
||||||
|
#define AG71XX_RX_RING_SIZE CONFIG_SYS_RX_ETH_BUFFER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define AG71XX_TX_THRES_STOP (AG71XX_TX_RING_SIZE - 4)
|
||||||
|
#define AG71XX_TX_THRES_WAKEUP \
|
||||||
|
(AG71XX_TX_RING_SIZE - (AG71XX_TX_RING_SIZE / 4))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct ag71xx_desc {
|
||||||
|
u32 data;
|
||||||
|
u32 ctrl;
|
||||||
|
#define DESC_EMPTY BIT(31)
|
||||||
|
#define DESC_MORE BIT(24)
|
||||||
|
#define DESC_PKTLEN_M 0xfff
|
||||||
|
u32 next;
|
||||||
|
u32 pad;
|
||||||
|
} __attribute__((aligned(4)));
|
||||||
|
|
||||||
|
struct ag71xx_buf {
|
||||||
|
struct sk_buff *skb;
|
||||||
|
struct ag71xx_desc *desc;
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
u32 pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ag71xx_ring {
|
||||||
|
struct ag71xx_buf *buf;
|
||||||
|
u8 *descs_cpu;
|
||||||
|
u8 *descs_dma;
|
||||||
|
unsigned int desc_size;
|
||||||
|
unsigned int curr;
|
||||||
|
unsigned int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ag71xx {
|
||||||
|
uint32_t mac_base;
|
||||||
|
uint32_t mii_ctrl;
|
||||||
|
|
||||||
|
struct eth_device *dev;
|
||||||
|
|
||||||
|
struct ag71xx_ring rx_ring;
|
||||||
|
struct ag71xx_ring tx_ring;
|
||||||
|
|
||||||
|
char *phyname;
|
||||||
|
u16 phyid;
|
||||||
|
u16 phyfixed;
|
||||||
|
uint32_t link;
|
||||||
|
uint32_t speed;
|
||||||
|
int32_t duplex;
|
||||||
|
uint32_t macNum;
|
||||||
|
uint32_t mii_if;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ag71xx_link_adjust(struct ag71xx *ag);
|
||||||
|
|
||||||
|
int ag71xx_phy_connect(struct ag71xx *ag);
|
||||||
|
void ag71xx_phy_disconnect(struct ag71xx *ag);
|
||||||
|
void ag71xx_phy_start(struct ag71xx *ag);
|
||||||
|
void ag71xx_phy_stop(struct ag71xx *ag);
|
||||||
|
|
||||||
|
static inline int ag71xx_desc_empty(struct ag71xx_desc *desc)
|
||||||
|
{
|
||||||
|
return ((desc->ctrl & DESC_EMPTY) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ag71xx_desc_pktlen(struct ag71xx_desc *desc)
|
||||||
|
{
|
||||||
|
return (desc->ctrl & DESC_PKTLEN_M);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register offsets */
|
||||||
|
#define AG71XX_REG_MAC_CFG1 0x0000
|
||||||
|
#define AG71XX_REG_MAC_CFG2 0x0004
|
||||||
|
#define AG71XX_REG_MAC_IPG 0x0008
|
||||||
|
#define AG71XX_REG_MAC_HDX 0x000c
|
||||||
|
#define AG71XX_REG_MAC_MFL 0x0010
|
||||||
|
#define AG71XX_REG_MII_CFG 0x0020
|
||||||
|
#define AG71XX_REG_MII_CMD 0x0024
|
||||||
|
#define AG71XX_REG_MII_ADDR 0x0028
|
||||||
|
#define AG71XX_REG_MII_CTRL 0x002c
|
||||||
|
#define AG71XX_REG_MII_STATUS 0x0030
|
||||||
|
#define AG71XX_REG_MII_IND 0x0034
|
||||||
|
#define AG71XX_REG_MAC_IFCTL 0x0038
|
||||||
|
#define AG71XX_REG_MAC_ADDR1 0x0040
|
||||||
|
#define AG71XX_REG_MAC_ADDR2 0x0044
|
||||||
|
#define AG71XX_REG_FIFO_CFG0 0x0048
|
||||||
|
#define AG71XX_REG_FIFO_CFG1 0x004c
|
||||||
|
#define AG71XX_REG_FIFO_CFG2 0x0050
|
||||||
|
#define AG71XX_REG_FIFO_CFG3 0x0054
|
||||||
|
#define AG71XX_REG_FIFO_CFG4 0x0058
|
||||||
|
#define AG71XX_REG_FIFO_CFG5 0x005c
|
||||||
|
#define AG71XX_REG_FIFO_RAM0 0x0060
|
||||||
|
#define AG71XX_REG_FIFO_RAM1 0x0064
|
||||||
|
#define AG71XX_REG_FIFO_RAM2 0x0068
|
||||||
|
#define AG71XX_REG_FIFO_RAM3 0x006c
|
||||||
|
#define AG71XX_REG_FIFO_RAM4 0x0070
|
||||||
|
#define AG71XX_REG_FIFO_RAM5 0x0074
|
||||||
|
#define AG71XX_REG_FIFO_RAM6 0x0078
|
||||||
|
#define AG71XX_REG_FIFO_RAM7 0x007c
|
||||||
|
|
||||||
|
#define AG71XX_REG_TX_CTRL 0x0180
|
||||||
|
#define AG71XX_REG_TX_DESC 0x0184
|
||||||
|
#define AG71XX_REG_TX_STATUS 0x0188
|
||||||
|
#define AG71XX_REG_RX_CTRL 0x018c
|
||||||
|
#define AG71XX_REG_RX_DESC 0x0190
|
||||||
|
#define AG71XX_REG_RX_STATUS 0x0194
|
||||||
|
#define AG71XX_REG_INT_ENABLE 0x0198
|
||||||
|
#define AG71XX_REG_INT_STATUS 0x019c
|
||||||
|
|
||||||
|
#define MAC_CFG1_TXE BIT(0) /* Tx Enable */
|
||||||
|
#define MAC_CFG1_STX BIT(1) /* Synchronize Tx Enable */
|
||||||
|
#define MAC_CFG1_RXE BIT(2) /* Rx Enable */
|
||||||
|
#define MAC_CFG1_SRX BIT(3) /* Synchronize Rx Enable */
|
||||||
|
#define MAC_CFG1_TFC BIT(4) /* Tx Flow Control Enable */
|
||||||
|
#define MAC_CFG1_RFC BIT(5) /* Rx Flow Control Enable */
|
||||||
|
#define MAC_CFG1_LB BIT(8) /* Loopback mode */
|
||||||
|
#define MAC_CFG1_SR BIT(31) /* Soft Reset */
|
||||||
|
|
||||||
|
#define MAC_CFG2_FDX BIT(0)
|
||||||
|
#define MAC_CFG2_CRC_EN BIT(1)
|
||||||
|
#define MAC_CFG2_PAD_CRC_EN BIT(2)
|
||||||
|
#define MAC_CFG2_LEN_CHECK BIT(4)
|
||||||
|
#define MAC_CFG2_HUGE_FRAME_EN BIT(5)
|
||||||
|
#define MAC_CFG2_IF_1000 BIT(9)
|
||||||
|
#define MAC_CFG2_IF_10_100 BIT(8)
|
||||||
|
|
||||||
|
#define FIFO_CFG0_WTM BIT(0) /* Watermark Module */
|
||||||
|
#define FIFO_CFG0_RXS BIT(1) /* Rx System Module */
|
||||||
|
#define FIFO_CFG0_RXF BIT(2) /* Rx Fabric Module */
|
||||||
|
#define FIFO_CFG0_TXS BIT(3) /* Tx System Module */
|
||||||
|
#define FIFO_CFG0_TXF BIT(4) /* Tx Fabric Module */
|
||||||
|
#define FIFO_CFG0_ALL (FIFO_CFG0_WTM | FIFO_CFG0_RXS | FIFO_CFG0_RXF \
|
||||||
|
| FIFO_CFG0_TXS | FIFO_CFG0_TXF)
|
||||||
|
|
||||||
|
#define FIFO_CFG0_ENABLE_SHIFT 8
|
||||||
|
|
||||||
|
#define FIFO_CFG4_DE BIT(0) /* Drop Event */
|
||||||
|
#define FIFO_CFG4_DV BIT(1) /* RX_DV Event */
|
||||||
|
#define FIFO_CFG4_FC BIT(2) /* False Carrier */
|
||||||
|
#define FIFO_CFG4_CE BIT(3) /* Code Error */
|
||||||
|
#define FIFO_CFG4_CR BIT(4) /* CRC error */
|
||||||
|
#define FIFO_CFG4_LM BIT(5) /* Length Mismatch */
|
||||||
|
#define FIFO_CFG4_LO BIT(6) /* Length out of range */
|
||||||
|
#define FIFO_CFG4_OK BIT(7) /* Packet is OK */
|
||||||
|
#define FIFO_CFG4_MC BIT(8) /* Multicast Packet */
|
||||||
|
#define FIFO_CFG4_BC BIT(9) /* Broadcast Packet */
|
||||||
|
#define FIFO_CFG4_DR BIT(10) /* Dribble */
|
||||||
|
#define FIFO_CFG4_LE BIT(11) /* Long Event */
|
||||||
|
#define FIFO_CFG4_CF BIT(12) /* Control Frame */
|
||||||
|
#define FIFO_CFG4_PF BIT(13) /* Pause Frame */
|
||||||
|
#define FIFO_CFG4_UO BIT(14) /* Unsupported Opcode */
|
||||||
|
#define FIFO_CFG4_VT BIT(15) /* VLAN tag detected */
|
||||||
|
#define FIFO_CFG4_FT BIT(16) /* Frame Truncated */
|
||||||
|
#define FIFO_CFG4_UC BIT(17) /* Unicast Packet */
|
||||||
|
|
||||||
|
#define FIFO_CFG5_DE BIT(0) /* Drop Event */
|
||||||
|
#define FIFO_CFG5_DV BIT(1) /* RX_DV Event */
|
||||||
|
#define FIFO_CFG5_FC BIT(2) /* False Carrier */
|
||||||
|
#define FIFO_CFG5_CE BIT(3) /* Code Error */
|
||||||
|
#define FIFO_CFG5_LM BIT(4) /* Length Mismatch */
|
||||||
|
#define FIFO_CFG5_LO BIT(5) /* Length Out of Range */
|
||||||
|
#define FIFO_CFG5_OK BIT(6) /* Packet is OK */
|
||||||
|
#define FIFO_CFG5_MC BIT(7) /* Multicast Packet */
|
||||||
|
#define FIFO_CFG5_BC BIT(8) /* Broadcast Packet */
|
||||||
|
#define FIFO_CFG5_DR BIT(9) /* Dribble */
|
||||||
|
#define FIFO_CFG5_CF BIT(10) /* Control Frame */
|
||||||
|
#define FIFO_CFG5_PF BIT(11) /* Pause Frame */
|
||||||
|
#define FIFO_CFG5_UO BIT(12) /* Unsupported Opcode */
|
||||||
|
#define FIFO_CFG5_VT BIT(13) /* VLAN tag detected */
|
||||||
|
#define FIFO_CFG5_LE BIT(14) /* Long Event */
|
||||||
|
#define FIFO_CFG5_FT BIT(15) /* Frame Truncated */
|
||||||
|
#define FIFO_CFG5_16 BIT(16) /* unknown */
|
||||||
|
#define FIFO_CFG5_17 BIT(17) /* unknown */
|
||||||
|
#define FIFO_CFG5_SF BIT(18) /* Short Frame */
|
||||||
|
#define FIFO_CFG5_BM BIT(19) /* Byte Mode */
|
||||||
|
|
||||||
|
#define AG71XX_INT_TX_PS BIT(0)
|
||||||
|
#define AG71XX_INT_TX_UR BIT(1)
|
||||||
|
#define AG71XX_INT_TX_BE BIT(3)
|
||||||
|
#define AG71XX_INT_RX_PR BIT(4)
|
||||||
|
#define AG71XX_INT_RX_OF BIT(6)
|
||||||
|
#define AG71XX_INT_RX_BE BIT(7)
|
||||||
|
|
||||||
|
#define MAC_IFCTL_SPEED BIT(16)
|
||||||
|
|
||||||
|
#define MII_CFG_CLK_DIV_4 0
|
||||||
|
#define MII_CFG_CLK_DIV_6 2
|
||||||
|
#define MII_CFG_CLK_DIV_8 3
|
||||||
|
#define MII_CFG_CLK_DIV_10 4
|
||||||
|
#define MII_CFG_CLK_DIV_14 5
|
||||||
|
#define MII_CFG_CLK_DIV_20 6
|
||||||
|
#define MII_CFG_CLK_DIV_28 7
|
||||||
|
#define MII_CFG_RESET BIT(31)
|
||||||
|
|
||||||
|
#define MII_CMD_WRITE 0x0
|
||||||
|
#define MII_CMD_READ 0x1
|
||||||
|
#define MII_ADDR_SHIFT 8
|
||||||
|
#define MII_IND_BUSY BIT(0)
|
||||||
|
#define MII_IND_INVALID BIT(2)
|
||||||
|
|
||||||
|
#define TX_CTRL_TXE BIT(0) /* Tx Enable */
|
||||||
|
|
||||||
|
#define TX_STATUS_PS BIT(0) /* Packet Sent */
|
||||||
|
#define TX_STATUS_UR BIT(1) /* Tx Underrun */
|
||||||
|
#define TX_STATUS_BE BIT(3) /* Bus Error */
|
||||||
|
|
||||||
|
#define RX_CTRL_RXE BIT(0) /* Rx Enable */
|
||||||
|
|
||||||
|
#define RX_STATUS_PR BIT(0) /* Packet Received */
|
||||||
|
#define RX_STATUS_OF BIT(2) /* Rx Overflow */
|
||||||
|
#define RX_STATUS_BE BIT(3) /* Bus Error */
|
||||||
|
|
||||||
|
#define MII_CTRL_IF_MASK 3
|
||||||
|
#define MII_CTRL_SPEED_SHIFT 4
|
||||||
|
#define MII_CTRL_SPEED_MASK 3
|
||||||
|
#define MII_CTRL_SPEED_10 0
|
||||||
|
#define MII_CTRL_SPEED_100 1
|
||||||
|
#define MII_CTRL_SPEED_1000 2
|
||||||
|
|
||||||
|
static inline void ag71xx_wr(struct ag71xx *ag, unsigned reg, u32 value)
|
||||||
|
{
|
||||||
|
__raw_writel(value, ag->mac_base + reg);
|
||||||
|
/* flush write */
|
||||||
|
(void) __raw_readl(ag->mac_base + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ag71xx_rr(struct ag71xx *ag, unsigned reg)
|
||||||
|
{
|
||||||
|
return __raw_readl(ag->mac_base + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ag71xx_sb(struct ag71xx *ag, unsigned reg, u32 mask)
|
||||||
|
{
|
||||||
|
uint32_t r;
|
||||||
|
|
||||||
|
r = ag->mac_base + reg;
|
||||||
|
__raw_writel(__raw_readl(r) | mask, r);
|
||||||
|
/* flush write */
|
||||||
|
(void)__raw_readl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ag71xx_cb(struct ag71xx *ag, unsigned reg, u32 mask)
|
||||||
|
{
|
||||||
|
uint32_t r;
|
||||||
|
|
||||||
|
r = ag->mac_base + reg;
|
||||||
|
__raw_writel(__raw_readl(r) & ~mask, r);
|
||||||
|
/* flush write */
|
||||||
|
(void) __raw_readl(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ag71xx_int_enable(struct ag71xx *ag, u32 ints)
|
||||||
|
{
|
||||||
|
ag71xx_sb(ag, AG71XX_REG_INT_ENABLE, ints);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ag71xx_int_disable(struct ag71xx *ag, u32 ints)
|
||||||
|
{
|
||||||
|
ag71xx_cb(ag, AG71XX_REG_INT_ENABLE, ints);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ag71xx_mii_ctrl_wr(struct ag71xx *ag, u32 value)
|
||||||
|
{
|
||||||
|
__raw_writel(value, ag->mii_ctrl);
|
||||||
|
|
||||||
|
/* flush write */
|
||||||
|
__raw_readl(ag->mii_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ag71xx_mii_ctrl_rr(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
return __raw_readl(ag->mii_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline ag71xx_mii_ctrl_set_if(struct ag71xx *ag,
|
||||||
|
unsigned int mii_if)
|
||||||
|
{
|
||||||
|
u32 t;
|
||||||
|
|
||||||
|
t = ag71xx_mii_ctrl_rr(ag);
|
||||||
|
t &= ~(MII_CTRL_IF_MASK);
|
||||||
|
t |= (mii_if & MII_CTRL_IF_MASK);
|
||||||
|
ag71xx_mii_ctrl_wr(ag, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void inline ag71xx_mii_ctrl_set_speed(struct ag71xx *ag,
|
||||||
|
unsigned int speed)
|
||||||
|
{
|
||||||
|
u32 t;
|
||||||
|
|
||||||
|
t = ag71xx_mii_ctrl_rr(ag);
|
||||||
|
t &= ~(MII_CTRL_SPEED_MASK << MII_CTRL_SPEED_SHIFT);
|
||||||
|
t |= (speed & MII_CTRL_SPEED_MASK) << MII_CTRL_SPEED_SHIFT;
|
||||||
|
ag71xx_mii_ctrl_wr(ag, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_AG71XX_AR8216_SUPPORT
|
||||||
|
void ag71xx_add_ar8216_header(struct ag71xx *ag, struct sk_buff *skb);
|
||||||
|
int ag71xx_remove_ar8216_header(struct ag71xx *ag, struct sk_buff *skb,
|
||||||
|
int pktlen);
|
||||||
|
static inline int ag71xx_has_ar8216(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
return ag71xx_get_pdata(ag)->has_ar8216;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline void ag71xx_add_ar8216_header(struct ag71xx *ag,
|
||||||
|
struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ag71xx_remove_ar8216_header(struct ag71xx *ag,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
int pktlen)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static inline int ag71xx_has_ar8216(struct ag71xx *ag)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _AG71XX_H */
|
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Kurz <michi.kurz@googlemail.com>.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef RTL8366_MII_H
|
||||||
|
#define RTL8366_MII_H
|
||||||
|
|
||||||
|
#define MII_CONTROL_REG 0
|
||||||
|
#define MII_STATUS_REG 1
|
||||||
|
#define MII_PHY_ID0 2
|
||||||
|
#define MII_PHY_ID1 3
|
||||||
|
#define MII_LOCAL_CAP 4
|
||||||
|
#define MII_REMOTE_CAP 5
|
||||||
|
#define MII_EXT_AUTONEG 6
|
||||||
|
#define MII_LOCAL_NEXT_PAGE 7
|
||||||
|
#define MII_REMOTE_NEXT_PAGE 8
|
||||||
|
#define MII_GIGA_CONTROL 9
|
||||||
|
#define MII_GIGA_STATUS 10
|
||||||
|
#define MII_EXT_STATUS_REG 15
|
||||||
|
|
||||||
|
/* Control register */
|
||||||
|
#define MII_CONTROL_1000MBPS 6
|
||||||
|
#define MII_CONTROL_COLL_TEST 7
|
||||||
|
#define MII_CONTROL_FULLDUPLEX 8
|
||||||
|
#define MII_CONTROL_RENEG 9
|
||||||
|
#define MII_CONTROL_ISOLATE 10
|
||||||
|
#define MII_CONTROL_POWERDOWN 11
|
||||||
|
#define MII_CONTROL_AUTONEG 12
|
||||||
|
#define MII_CONTROL_100MBPS 13
|
||||||
|
#define MII_CONTROL_LOOPBACK 14
|
||||||
|
#define MII_CONTROL_RESET 15
|
||||||
|
|
||||||
|
/* Status/Extended status register */
|
||||||
|
/* Basic status */
|
||||||
|
#define MII_STATUS_CAPABILITY 0
|
||||||
|
#define MII_STATUS_JABBER 1
|
||||||
|
#define MII_STATUS_LINK_UP 2
|
||||||
|
#define MII_STATUS_AUTONEG_ABLE 3
|
||||||
|
#define MII_STATUS_REMOTE_FAULT 4
|
||||||
|
#define MII_STATUS_AUTONEG_DONE 5
|
||||||
|
#define MII_STATUS_NO_PREAMBLE 6
|
||||||
|
#define MII_STATUS_RESERVED 7
|
||||||
|
#define MII_STATUS_EXTENDED 8
|
||||||
|
#define MII_STATUS_100_T2_HALF 9
|
||||||
|
#define MII_STATUS_100_T2_FULL 10
|
||||||
|
#define MII_STATUS_10_TX_HALF 11
|
||||||
|
#define MII_STATUS_10_TX_FULL 12
|
||||||
|
#define MII_STATUS_100_TX_HALF 13
|
||||||
|
#define MII_STATUS_100_TX_FULL 14
|
||||||
|
#define MII_STATUS_100_T4 15
|
||||||
|
|
||||||
|
#define MII_GIGA_CONTROL_HALF 8
|
||||||
|
#define MII_GIGA_CONTROL_FULL 9
|
||||||
|
#define MII_GIGA_STATUS_HALF 10
|
||||||
|
#define MII_GIGA_STATUS_FULL 11
|
||||||
|
|
||||||
|
/* Extended status */
|
||||||
|
#define MII_STATUS_1000_T_HALF 12
|
||||||
|
#define MII_STATUS_1000_T_FULL 13
|
||||||
|
#define MII_STATUS_1000_X_HALF 14
|
||||||
|
#define MII_STATUS_1000_X_FULL 15
|
||||||
|
|
||||||
|
/* Local/Remmote capability register */
|
||||||
|
#define MII_CAP_10BASE_TX 5
|
||||||
|
#define MII_CAP_10BASE_TX_FULL 6
|
||||||
|
#define MII_CAP_100BASE_TX 7
|
||||||
|
#define MII_CAP_100BASE_TX_FULL 8
|
||||||
|
#define MII_CAP_100BASE_T4 9
|
||||||
|
#define MII_CAP_SYMM_PAUSE 10
|
||||||
|
#define MII_CAP_ASYMM_PAUSE 11
|
||||||
|
#define MII_CAP_RESERVED 12
|
||||||
|
#define MII_CAP_REMOTE_FAULT 13
|
||||||
|
#define MII_CAP_ACKNOWLEDGE 14
|
||||||
|
#define MII_CAP_NEXT_PAGE 15
|
||||||
|
#define MII_CAP_IEEE_802_3 0x0001
|
||||||
|
|
||||||
|
#define MII_LINK_MODE_MASK 0x1f
|
||||||
|
|
||||||
|
#define REALTEK_RTL8366_CHIP_ID0 0x001C
|
||||||
|
#define REALTEK_RTL8366_CHIP_ID1 0xC940
|
||||||
|
#define REALTEK_RTL8366_CHIP_ID1_MP 0xC960
|
||||||
|
|
||||||
|
#define REALTEK_MIN_PORT_ID 0
|
||||||
|
#define REALTEK_MAX_PORT_ID 5
|
||||||
|
#define REALTEK_MIN_PHY_ID REALTEK_MIN_PORT_ID
|
||||||
|
#define REALTEK_MAX_PHY_ID 4
|
||||||
|
#define REALTEK_CPU_PORT_ID REALTEK_MAX_PORT_ID
|
||||||
|
#define REALTEK_PHY_PORT_MASK ((1<<(REALTEK_MAX_PHY_ID+1)) - (1<<REALTEK_MIN_PHY_ID))
|
||||||
|
#define REALTEK_CPU_PORT_MASK (1<<REALTEK_CPU_PORT_ID)
|
||||||
|
#define REALTEK_ALL_PORT_MASK (REALTEK_PHY_PORT_MASK | REALTEK_CPU_PORT_MASK)
|
||||||
|
|
||||||
|
/* port ability */
|
||||||
|
#define RTL8366S_PORT_ABILITY_BASE 0x0011
|
||||||
|
|
||||||
|
/* port vlan control register */
|
||||||
|
#define RTL8366S_PORT_VLAN_CTRL_BASE 0x0058
|
||||||
|
|
||||||
|
/* port linking status */
|
||||||
|
#define RTL8366S_PORT_LINK_STATUS_BASE 0x0060
|
||||||
|
#define RTL8366S_PORT_STATUS_SPEED_BIT 0
|
||||||
|
#define RTL8366S_PORT_STATUS_SPEED_MSK 0x0003
|
||||||
|
#define RTL8366S_PORT_STATUS_DUPLEX_BIT 2
|
||||||
|
#define RTL8366S_PORT_STATUS_DUPLEX_MSK 0x0004
|
||||||
|
#define RTL8366S_PORT_STATUS_LINK_BIT 4
|
||||||
|
#define RTL8366S_PORT_STATUS_LINK_MSK 0x0010
|
||||||
|
#define RTL8366S_PORT_STATUS_TXPAUSE_BIT 5
|
||||||
|
#define RTL8366S_PORT_STATUS_TXPAUSE_MSK 0x0020
|
||||||
|
#define RTL8366S_PORT_STATUS_RXPAUSE_BIT 6
|
||||||
|
#define RTL8366S_PORT_STATUS_RXPAUSE_MSK 0x0040
|
||||||
|
#define RTL8366S_PORT_STATUS_AN_BIT 7
|
||||||
|
#define RTL8366S_PORT_STATUS_AN_MSK 0x0080
|
||||||
|
|
||||||
|
/* internal control */
|
||||||
|
#define RTL8366S_RESET_CONTROL_REG 0x0100
|
||||||
|
#define RTL8366S_RESET_QUEUE_BIT 2
|
||||||
|
|
||||||
|
#define RTL8366S_CHIP_ID_REG 0x0105
|
||||||
|
|
||||||
|
/* MAC control */
|
||||||
|
#define RTL8366S_MAC_FORCE_CTRL0_REG 0x0F04
|
||||||
|
#define RTL8366S_MAC_FORCE_CTRL1_REG 0x0F05
|
||||||
|
|
||||||
|
|
||||||
|
/* PHY registers control */
|
||||||
|
#define RTL8366S_PHY_ACCESS_CTRL_REG 0x8028
|
||||||
|
#define RTL8366S_PHY_ACCESS_DATA_REG 0x8029
|
||||||
|
|
||||||
|
#define RTL8366S_PHY_CTRL_READ 1
|
||||||
|
#define RTL8366S_PHY_CTRL_WRITE 0
|
||||||
|
|
||||||
|
#define RTL8366S_PHY_REG_MASK 0x1F
|
||||||
|
#define RTL8366S_PHY_PAGE_OFFSET 5
|
||||||
|
#define RTL8366S_PHY_PAGE_MASK (0x7<<5)
|
||||||
|
#define RTL8366S_PHY_NO_OFFSET 9
|
||||||
|
#define RTL8366S_PHY_NO_MASK (0x1F<<9)
|
||||||
|
|
||||||
|
#define RTL8366S_PHY_NO_MAX 4
|
||||||
|
#define RTL8366S_PHY_PAGE_MAX 7
|
||||||
|
#define RTL8366S_PHY_ADDR_MAX 31
|
||||||
|
|
||||||
|
/* cpu port control reg */
|
||||||
|
#define RTL8366S_CPU_CTRL_REG 0x004F
|
||||||
|
#define RTL8366S_CPU_DRP_BIT 14
|
||||||
|
#define RTL8366S_CPU_DRP_MSK 0x4000
|
||||||
|
#define RTL8366S_CPU_INSTAG_BIT 15
|
||||||
|
#define RTL8366S_CPU_INSTAG_MSK 0x8000
|
||||||
|
|
||||||
|
/* LED registers*/
|
||||||
|
#define RTL8366S_LED_BLINK_REG 0x420
|
||||||
|
#define RTL8366S_LED_BLINKRATE_BIT 0
|
||||||
|
#define RTL8366S_LED_BLINKRATE_MSK 0x0007
|
||||||
|
#define RTL8366S_LED_INDICATED_CONF_REG 0x421
|
||||||
|
#define RTL8366S_LED_0_1_FORCE_REG 0x422
|
||||||
|
#define RTL8366S_LED_2_3_FORCE_REG 0x423
|
||||||
|
#define RTL8366S_LEDCONF_LEDFORCE 0x1F
|
||||||
|
#define RTL8366S_LED_GROUP_MAX 4
|
||||||
|
|
||||||
|
#define RTL8366S_GREEN_FEATURE_REG 0x000A
|
||||||
|
#define RTL8366S_GREEN_FEATURE_TX_BIT 3
|
||||||
|
#define RTL8366S_GREEN_FEATURE_TX_MSK 0x0008
|
||||||
|
#define RTL8366S_GREEN_FEATURE_RX_BIT 4
|
||||||
|
#define RTL8366S_GREEN_FEATURE_RX_MSK 0x0010
|
||||||
|
|
||||||
|
#define RTL8366S_MODEL_ID_REG 0x5C
|
||||||
|
#define RTL8366S_REV_ID_REG 0x5D
|
||||||
|
#define RTL8366S_MODEL_8366SR 0x6027
|
||||||
|
#define RTL8366S_MODEL_8366RB 0x5937
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,786 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Kurz <michi.kurz@googlemail.com>.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <net.h>
|
||||||
|
#include <netdev.h>
|
||||||
|
#include <miiphy.h>
|
||||||
|
#include MII_GPIOINCLUDE
|
||||||
|
|
||||||
|
#include "rtl8366.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG_RTL8366
|
||||||
|
#define DBG(fmt,args...) printf (fmt ,##args)
|
||||||
|
#else
|
||||||
|
#define DBG(fmt,args...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Soft SMI functions
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define DELAY 2
|
||||||
|
|
||||||
|
static void smi_init(void)
|
||||||
|
{
|
||||||
|
MII_SDAINPUT;
|
||||||
|
MII_SCKINPUT;
|
||||||
|
|
||||||
|
MII_SETSDA(1);
|
||||||
|
MII_SETSCK(1);
|
||||||
|
|
||||||
|
udelay(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void smi_start(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* rtl8366 chip needs a extra clock with
|
||||||
|
* SDA high before start condition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* set gpio pins output */
|
||||||
|
MII_SDAOUTPUT;
|
||||||
|
MII_SCKOUTPUT;
|
||||||
|
udelay(DELAY);
|
||||||
|
|
||||||
|
/* set initial state: SCK:0, SDA:1 */
|
||||||
|
MII_SETSCK(0);
|
||||||
|
MII_SETSDA(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
|
||||||
|
/* toggle clock */
|
||||||
|
MII_SETSCK(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSCK(0);
|
||||||
|
udelay(DELAY);
|
||||||
|
|
||||||
|
/* start condition */
|
||||||
|
MII_SETSCK(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSDA(0);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSCK(0);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSDA(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void smi_stop(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* rtl8366 chip needs a extra clock with
|
||||||
|
* SDA high after stop condition
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* stop condition */
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSDA(0);
|
||||||
|
MII_SETSCK(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSDA(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSCK(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSCK(0);
|
||||||
|
udelay(DELAY);
|
||||||
|
|
||||||
|
/* toggle clock */
|
||||||
|
MII_SETSCK(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSCK(0);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSCK(1);
|
||||||
|
|
||||||
|
/* set gpio pins input */
|
||||||
|
MII_SDAINPUT;
|
||||||
|
MII_SCKINPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void smi_writeBits(uint32_t data, uint8_t length)
|
||||||
|
{
|
||||||
|
uint8_t test;
|
||||||
|
|
||||||
|
for( ; length > 0; length--) {
|
||||||
|
udelay(DELAY);
|
||||||
|
|
||||||
|
/* output data */
|
||||||
|
test = (((data & (1 << (length - 1))) != 0) ? 1 : 0);
|
||||||
|
MII_SETSDA(test);
|
||||||
|
udelay(DELAY);
|
||||||
|
|
||||||
|
/* toogle clock */
|
||||||
|
MII_SETSCK(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
MII_SETSCK(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t smi_readBits(uint8_t length)
|
||||||
|
{
|
||||||
|
uint32_t ret;
|
||||||
|
|
||||||
|
MII_SDAINPUT;
|
||||||
|
|
||||||
|
for(ret = 0 ; length > 0; length--) {
|
||||||
|
udelay(DELAY);
|
||||||
|
|
||||||
|
ret <<= 1;
|
||||||
|
|
||||||
|
/* toogle clock */
|
||||||
|
MII_SETSCK(1);
|
||||||
|
udelay(DELAY);
|
||||||
|
ret |= MII_GETSDA;
|
||||||
|
MII_SETSCK(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
MII_SDAOUTPUT;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int smi_waitAck(void)
|
||||||
|
{
|
||||||
|
uint32_t retry = 0;
|
||||||
|
|
||||||
|
while (smi_readBits(1)) {
|
||||||
|
if (retry++ == 5)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int smi_read(uint32_t reg, uint32_t *data)
|
||||||
|
{
|
||||||
|
uint32_t rawData;
|
||||||
|
|
||||||
|
/* send start condition */
|
||||||
|
smi_start();
|
||||||
|
/* send CTRL1 code: 0b1010*/
|
||||||
|
smi_writeBits(0x0a, 4);
|
||||||
|
/* send CTRL2 code: 0b100 */
|
||||||
|
smi_writeBits(0x04, 3);
|
||||||
|
/* send READ command */
|
||||||
|
smi_writeBits(0x01, 1);
|
||||||
|
|
||||||
|
/* wait for ACK */
|
||||||
|
if (smi_waitAck())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* send address low */
|
||||||
|
smi_writeBits(reg & 0xFF, 8);
|
||||||
|
/* wait for ACK */
|
||||||
|
if (smi_waitAck())
|
||||||
|
return -1;
|
||||||
|
/* send address high */
|
||||||
|
smi_writeBits((reg & 0xFF00) >> 8, 8);
|
||||||
|
/* wait for ACK */
|
||||||
|
if (smi_waitAck())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* read data low */
|
||||||
|
rawData = (smi_readBits(8) & 0xFF);
|
||||||
|
/* send ACK */
|
||||||
|
smi_writeBits(0, 1);
|
||||||
|
/* read data high */
|
||||||
|
rawData |= (smi_readBits(8) & 0xFF) << 8;
|
||||||
|
/* send NACK */
|
||||||
|
smi_writeBits(1, 1);
|
||||||
|
|
||||||
|
/* send stop condition */
|
||||||
|
smi_stop();
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
*data = rawData;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int smi_write(uint32_t reg, uint32_t data)
|
||||||
|
{
|
||||||
|
/* send start condition */
|
||||||
|
smi_start();
|
||||||
|
/* send CTRL1 code: 0b1010*/
|
||||||
|
smi_writeBits(0x0a, 4);
|
||||||
|
/* send CTRL2 code: 0b100 */
|
||||||
|
smi_writeBits(0x04, 3);
|
||||||
|
/* send WRITE command */
|
||||||
|
smi_writeBits(0x00, 1);
|
||||||
|
|
||||||
|
/* wait for ACK */
|
||||||
|
if (smi_waitAck())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* send address low */
|
||||||
|
smi_writeBits(reg & 0xFF, 8);
|
||||||
|
/* wait for ACK */
|
||||||
|
if (smi_waitAck())
|
||||||
|
return -1;
|
||||||
|
/* send address high */
|
||||||
|
smi_writeBits((reg & 0xFF00) >> 8, 8);
|
||||||
|
/* wait for ACK */
|
||||||
|
if (smi_waitAck())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* send data low */
|
||||||
|
smi_writeBits(data & 0xFF, 8);
|
||||||
|
/* wait for ACK */
|
||||||
|
if (smi_waitAck())
|
||||||
|
return -1;
|
||||||
|
/* send data high */
|
||||||
|
smi_writeBits((data & 0xFF00) >> 8, 8);
|
||||||
|
/* wait for ACK */
|
||||||
|
if (smi_waitAck())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* send stop condition */
|
||||||
|
smi_stop();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Switch register read / write functions
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
static int rtl8366_readRegister(uint32_t reg, uint16_t *data)
|
||||||
|
{
|
||||||
|
uint32_t regData;
|
||||||
|
|
||||||
|
DBG("rtl8366: read register=%#04x, data=", reg);
|
||||||
|
|
||||||
|
if (smi_read(reg, ®Data)) {
|
||||||
|
printf("\nrtl8366 smi read failed!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
*data = regData;
|
||||||
|
|
||||||
|
DBG("%#04x\n", regData);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8366_writeRegister(uint32_t reg, uint16_t data)
|
||||||
|
{
|
||||||
|
DBG("rtl8366: write register=%#04x, data=%#04x\n", reg, data);
|
||||||
|
|
||||||
|
if (smi_write(reg, data)) {
|
||||||
|
printf("rtl8366 smi write failed!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8366_setRegisterBit(uint32_t reg, uint32_t bitNum, uint32_t value)
|
||||||
|
{
|
||||||
|
uint16_t regData;
|
||||||
|
|
||||||
|
if (bitNum >= 16)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366_readRegister(reg, ®Data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
regData |= (1 << bitNum);
|
||||||
|
else
|
||||||
|
regData &= ~(1 << bitNum);
|
||||||
|
|
||||||
|
if (rtl8366_writeRegister(reg, regData))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// MII PHY read / write functions
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
static int rtl8366_getPhyReg(uint32_t phyNum, uint32_t reg, uint16_t *data)
|
||||||
|
{
|
||||||
|
uint16_t phyAddr, regData;
|
||||||
|
|
||||||
|
if (phyNum > RTL8366S_PHY_NO_MAX) {
|
||||||
|
printf("rtl8366s: invalid phy number!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phyNum > RTL8366S_PHY_ADDR_MAX) {
|
||||||
|
printf("rtl8366s: invalid phy register number!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
|
||||||
|
RTL8366S_PHY_CTRL_READ))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
|
||||||
|
| (reg & RTL8366S_PHY_REG_MASK);
|
||||||
|
if (rtl8366_writeRegister(phyAddr, 0))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366_readRegister(RTL8366S_PHY_ACCESS_DATA_REG, ®Data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
*data = regData;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8366_setPhyReg(uint32_t phyNum, uint32_t reg, uint16_t data)
|
||||||
|
{
|
||||||
|
uint16_t phyAddr;
|
||||||
|
|
||||||
|
if (phyNum > RTL8366S_PHY_NO_MAX) {
|
||||||
|
printf("rtl8366s: invalid phy number!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phyNum > RTL8366S_PHY_ADDR_MAX) {
|
||||||
|
printf("rtl8366s: invalid phy register number!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
|
||||||
|
RTL8366S_PHY_CTRL_WRITE))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
phyAddr = 0x8000 | (1 << (phyNum + RTL8366S_PHY_NO_OFFSET))
|
||||||
|
| (reg & RTL8366S_PHY_REG_MASK);
|
||||||
|
if (rtl8366_writeRegister(phyAddr, data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8366_miiread(char *devname, uchar phy_adr, uchar reg, ushort *data)
|
||||||
|
{
|
||||||
|
uint16_t regData;
|
||||||
|
|
||||||
|
DBG("rtl8366_miiread: devname=%s, addr=%#02x, reg=%#02x\n",
|
||||||
|
devname, phy_adr, reg);
|
||||||
|
|
||||||
|
if (strcmp(devname, RTL8366_DEVNAME) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366_getPhyReg(phy_adr, reg, ®Data)) {
|
||||||
|
printf("rtl8366_miiread: write failed!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data)
|
||||||
|
*data = regData;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8366_miiwrite(char *devname, uchar phy_adr, uchar reg, ushort data)
|
||||||
|
{
|
||||||
|
DBG("rtl8366_miiwrite: devname=%s, addr=%#02x, reg=%#02x, data=%#04x\n",
|
||||||
|
devname, phy_adr, reg, data);
|
||||||
|
|
||||||
|
if (strcmp(devname, RTL8366_DEVNAME) != 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366_setPhyReg(phy_adr, reg, data)) {
|
||||||
|
printf("rtl8366_miiwrite: write failed!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366_mii_register(bd_t *bis)
|
||||||
|
{
|
||||||
|
miiphy_register(strdup(RTL8366_DEVNAME), rtl8366_miiread,
|
||||||
|
rtl8366_miiwrite);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
// Switch management functions
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
int rtl8366s_setGreenFeature(uint32_t tx, uint32_t rx)
|
||||||
|
{
|
||||||
|
if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
|
||||||
|
RTL8366S_GREEN_FEATURE_TX_BIT, tx))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366_setRegisterBit(RTL8366S_GREEN_FEATURE_REG,
|
||||||
|
RTL8366S_GREEN_FEATURE_RX_BIT, rx))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_setPowerSaving(uint32_t phyNum, uint32_t enabled)
|
||||||
|
{
|
||||||
|
uint16_t regData;
|
||||||
|
|
||||||
|
if (phyNum > RTL8366S_PHY_NO_MAX)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366_getPhyReg(phyNum, 12, ®Data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
regData |= (1 << 12);
|
||||||
|
else
|
||||||
|
regData &= ~(1 << 12);
|
||||||
|
|
||||||
|
if (rtl8366_setPhyReg(phyNum, 12, regData))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_setGreenEthernet(uint32_t greenFeature, uint32_t powerSaving)
|
||||||
|
{
|
||||||
|
uint32_t phyNum, i;
|
||||||
|
uint16_t regData;
|
||||||
|
|
||||||
|
const uint16_t greenSettings[][2] =
|
||||||
|
{
|
||||||
|
{0xBE5B,0x3500},
|
||||||
|
{0xBE5C,0xB975},
|
||||||
|
{0xBE5D,0xB9B9},
|
||||||
|
{0xBE77,0xA500},
|
||||||
|
{0xBE78,0x5A78},
|
||||||
|
{0xBE79,0x6478}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, ®Data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (regData)
|
||||||
|
{
|
||||||
|
case 0x0000:
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
|
||||||
|
return -1;
|
||||||
|
if (rtl8366_writeRegister(greenSettings[i][0], greenSettings[i][1]))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTL8366S_MODEL_8366SR:
|
||||||
|
if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG, RTL8366S_PHY_CTRL_WRITE))
|
||||||
|
return -1;
|
||||||
|
if (rtl8366_writeRegister(greenSettings[0][0], greenSettings[0][1]))
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("rtl8366s_initChip: unsupported chip found!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366s_setGreenFeature(greenFeature, powerSaving))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (phyNum = 0; phyNum <= RTL8366S_PHY_NO_MAX; phyNum++) {
|
||||||
|
if (rtl8366s_setPowerSaving(phyNum, powerSaving))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_setCPUPortMask(uint8_t port, uint32_t enabled)
|
||||||
|
{
|
||||||
|
if(port >= 6){
|
||||||
|
printf("rtl8366s_setCPUPortMask: invalid port number\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG, port, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_setCPUDisableInsTag(uint32_t enable)
|
||||||
|
{
|
||||||
|
return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
|
||||||
|
RTL8366S_CPU_INSTAG_BIT, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_setCPUDropUnda(uint32_t enable)
|
||||||
|
{
|
||||||
|
return rtl8366_setRegisterBit(RTL8366S_CPU_CTRL_REG,
|
||||||
|
RTL8366S_CPU_DRP_BIT, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_setCPUPort(uint8_t port, uint32_t noTag, uint32_t dropUnda)
|
||||||
|
{
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
if(port >= 6){
|
||||||
|
printf("rtl8366s_setCPUPort: invalid port number\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reset register */
|
||||||
|
for(i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
if(rtl8366s_setCPUPortMask(i, 0)){
|
||||||
|
printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rtl8366s_setCPUPortMask(port, 1)){
|
||||||
|
printf("rtl8366s_setCPUPort: rtl8366s_setCPUPortMask failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rtl8366s_setCPUDisableInsTag(noTag)){
|
||||||
|
printf("rtl8366s_setCPUPort: rtl8366s_setCPUDisableInsTag fail\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rtl8366s_setCPUDropUnda(dropUnda)){
|
||||||
|
printf("rtl8366s_setCPUPort: rtl8366s_setCPUDropUnda fail\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_setLedConfig(uint32_t ledNum, uint8_t config)
|
||||||
|
{
|
||||||
|
uint16_t regData;
|
||||||
|
|
||||||
|
if(ledNum >= RTL8366S_LED_GROUP_MAX) {
|
||||||
|
DBG("rtl8366s_setLedConfig: invalid led group\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config > RTL8366S_LEDCONF_LEDFORCE) {
|
||||||
|
DBG("rtl8366s_setLedConfig: invalid led config\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, ®Data)) {
|
||||||
|
printf("rtl8366s_setLedConfig: failed to get led register!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
regData &= ~(0xF << (ledNum * 4));
|
||||||
|
regData |= config << (ledNum * 4);
|
||||||
|
|
||||||
|
if (rtl8366_writeRegister(RTL8366S_LED_INDICATED_CONF_REG, regData)) {
|
||||||
|
printf("rtl8366s_setLedConfig: failed to set led register!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_getLedConfig(uint32_t ledNum, uint8_t *config)
|
||||||
|
{
|
||||||
|
uint16_t regData;
|
||||||
|
|
||||||
|
if(ledNum >= RTL8366S_LED_GROUP_MAX) {
|
||||||
|
DBG("rtl8366s_getLedConfig: invalid led group\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366_readRegister(RTL8366S_LED_INDICATED_CONF_REG, ®Data)) {
|
||||||
|
printf("rtl8366s_getLedConfig: failed to get led register!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config)
|
||||||
|
*config = (regData >> (ledNum * 4)) & 0xF;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_setLedForceValue(uint32_t group0, uint32_t group1,
|
||||||
|
uint32_t group2, uint32_t group3)
|
||||||
|
{
|
||||||
|
uint16_t regData;
|
||||||
|
|
||||||
|
regData = (group0 & 0x3F) | ((group1 & 0x3F) << 6);
|
||||||
|
if (rtl8366_writeRegister(RTL8366S_LED_0_1_FORCE_REG, regData)) {
|
||||||
|
printf("rtl8366s_setLedForceValue: failed to set led register!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
regData = (group2 & 0x3F) | ((group3 & 0x3F) << 6);
|
||||||
|
if (rtl8366_writeRegister(RTL8366S_LED_2_3_FORCE_REG, regData)) {
|
||||||
|
printf("rtl8366s_setLedForceValue: failed to set led register!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_initChip(void)
|
||||||
|
{
|
||||||
|
uint32_t ledGroup, i = 0;
|
||||||
|
uint16_t regData;
|
||||||
|
uint8_t ledData[RTL8366S_LED_GROUP_MAX];
|
||||||
|
const uint16_t (*chipData)[2];
|
||||||
|
|
||||||
|
const uint16_t chipB[][2] =
|
||||||
|
{
|
||||||
|
{0x0000, 0x0038},{0x8100, 0x1B37},{0xBE2E, 0x7B9F},{0xBE2B, 0xA4C8},
|
||||||
|
{0xBE74, 0xAD14},{0xBE2C, 0xDC00},{0xBE69, 0xD20F},{0xBE3B, 0xB414},
|
||||||
|
{0xBE24, 0x0000},{0xBE23, 0x00A1},{0xBE22, 0x0008},{0xBE21, 0x0120},
|
||||||
|
{0xBE20, 0x1000},{0xBE24, 0x0800},{0xBE24, 0x0000},{0xBE24, 0xF000},
|
||||||
|
{0xBE23, 0xDF01},{0xBE22, 0xDF20},{0xBE21, 0x101A},{0xBE20, 0xA0FF},
|
||||||
|
{0xBE24, 0xF800},{0xBE24, 0xF000},{0x0242, 0x02BF},{0x0245, 0x02BF},
|
||||||
|
{0x0248, 0x02BF},{0x024B, 0x02BF},{0x024E, 0x02BF},{0x0251, 0x02BF},
|
||||||
|
{0x0230, 0x0A32},{0x0233, 0x0A32},{0x0236, 0x0A32},{0x0239, 0x0A32},
|
||||||
|
{0x023C, 0x0A32},{0x023F, 0x0A32},{0x0254, 0x0A3F},{0x0255, 0x0064},
|
||||||
|
{0x0256, 0x0A3F},{0x0257, 0x0064},{0x0258, 0x0A3F},{0x0259, 0x0064},
|
||||||
|
{0x025A, 0x0A3F},{0x025B, 0x0064},{0x025C, 0x0A3F},{0x025D, 0x0064},
|
||||||
|
{0x025E, 0x0A3F},{0x025F, 0x0064},{0x0260, 0x0178},{0x0261, 0x01F4},
|
||||||
|
{0x0262, 0x0320},{0x0263, 0x0014},{0x021D, 0x9249},{0x021E, 0x0000},
|
||||||
|
{0x0100, 0x0004},{0xBE4A, 0xA0B4},{0xBE40, 0x9C00},{0xBE41, 0x501D},
|
||||||
|
{0xBE48, 0x3602},{0xBE47, 0x8051},{0xBE4C, 0x6465},{0x8000, 0x1F00},
|
||||||
|
{0x8001, 0x000C},{0x8008, 0x0000},{0x8007, 0x0000},{0x800C, 0x00A5},
|
||||||
|
{0x8101, 0x02BC},{0xBE53, 0x0005},{0x8E45, 0xAFE8},{0x8013, 0x0005},
|
||||||
|
{0xBE4B, 0x6700},{0x800B, 0x7000},{0xBE09, 0x0E00},
|
||||||
|
{0xFFFF, 0xABCD}
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint16_t chipDefault[][2] =
|
||||||
|
{
|
||||||
|
{0x0242, 0x02BF},{0x0245, 0x02BF},{0x0248, 0x02BF},{0x024B, 0x02BF},
|
||||||
|
{0x024E, 0x02BF},{0x0251, 0x02BF},
|
||||||
|
{0x0254, 0x0A3F},{0x0256, 0x0A3F},{0x0258, 0x0A3F},{0x025A, 0x0A3F},
|
||||||
|
{0x025C, 0x0A3F},{0x025E, 0x0A3F},
|
||||||
|
{0x0263, 0x007C},{0x0100, 0x0004},
|
||||||
|
{0xBE5B, 0x3500},{0x800E, 0x200F},{0xBE1D, 0x0F00},{0x8001, 0x5011},
|
||||||
|
{0x800A, 0xA2F4},{0x800B, 0x17A3},{0xBE4B, 0x17A3},{0xBE41, 0x5011},
|
||||||
|
{0xBE17, 0x2100},{0x8000, 0x8304},{0xBE40, 0x8304},{0xBE4A, 0xA2F4},
|
||||||
|
{0x800C, 0xA8D5},{0x8014, 0x5500},{0x8015, 0x0004},{0xBE4C, 0xA8D5},
|
||||||
|
{0xBE59, 0x0008},{0xBE09, 0x0E00},{0xBE36, 0x1036},{0xBE37, 0x1036},
|
||||||
|
{0x800D, 0x00FF},{0xBE4D, 0x00FF},
|
||||||
|
{0xFFFF, 0xABCD}
|
||||||
|
};
|
||||||
|
|
||||||
|
DBG("rtl8366s_initChip\n");
|
||||||
|
|
||||||
|
/* save current led config and set to led force */
|
||||||
|
for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
|
||||||
|
if (rtl8366s_getLedConfig(ledGroup, &ledData[ledGroup]))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366s_setLedConfig(ledGroup, RTL8366S_LEDCONF_LEDFORCE))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366s_setLedForceValue(0,0,0,0))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (rtl8366_readRegister(RTL8366S_MODEL_ID_REG, ®Data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
switch (regData)
|
||||||
|
{
|
||||||
|
case 0x0000:
|
||||||
|
chipData = chipB;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTL8366S_MODEL_8366SR:
|
||||||
|
chipData = chipDefault;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
printf("rtl8366s_initChip: unsupported chip found!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG("rtl8366s_initChip: found %x chip\n", regData);
|
||||||
|
|
||||||
|
while ((chipData[i][0] != 0xFFFF) && (chipData[i][1] != 0xABCD)) {
|
||||||
|
|
||||||
|
/* phy settings*/
|
||||||
|
if ((chipData[i][0] & 0xBE00) == 0xBE00) {
|
||||||
|
if (rtl8366_writeRegister(RTL8366S_PHY_ACCESS_CTRL_REG,
|
||||||
|
RTL8366S_PHY_CTRL_WRITE))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366_writeRegister(chipData[i][0], chipData[i][1]))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* chip needs some time */
|
||||||
|
udelay(100 * 1000);
|
||||||
|
|
||||||
|
/* restore led config */
|
||||||
|
for (ledGroup = 0; ledGroup < RTL8366S_LED_GROUP_MAX; ledGroup++) {
|
||||||
|
if (rtl8366s_setLedConfig(ledGroup, ledData[ledGroup]))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rtl8366s_initialize(void)
|
||||||
|
{
|
||||||
|
uint16_t regData;
|
||||||
|
|
||||||
|
DBG("rtl8366s_initialize: start setup\n");
|
||||||
|
|
||||||
|
smi_init();
|
||||||
|
|
||||||
|
rtl8366_readRegister(RTL8366S_CHIP_ID_REG, ®Data);
|
||||||
|
DBG("Realtek 8366SR switch ID %#04x\n", regData);
|
||||||
|
|
||||||
|
if (regData != 0x8366) {
|
||||||
|
printf("rtl8366s_initialize: found unsupported switch\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366s_initChip()) {
|
||||||
|
printf("rtl8366s_initialize: init chip failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rtl8366s_setGreenEthernet(1, 1)) {
|
||||||
|
printf("rtl8366s_initialize: set green ethernet failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set port 5 noTag and don't dropUnda */
|
||||||
|
if (rtl8366s_setCPUPort(5, 1, 0)) {
|
||||||
|
printf("rtl8366s_initialize: set CPU port failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,191 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Kurz <michi.kurz@googlemail.com>
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
#include <spi.h>
|
||||||
|
|
||||||
|
#include <asm/addrspace.h>
|
||||||
|
#include <asm/types.h>
|
||||||
|
#include <asm/ar71xx.h>
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Definitions
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef DEBUG_SPI
|
||||||
|
#define PRINTD(fmt,args...) printf (fmt ,##args)
|
||||||
|
#else
|
||||||
|
#define PRINTD(fmt,args...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ar71xx_spi_slave {
|
||||||
|
struct spi_slave slave;
|
||||||
|
unsigned int mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct ar71xx_spi_slave *to_ar71xx_spi(struct spi_slave *slave)
|
||||||
|
{
|
||||||
|
return container_of(slave, struct ar71xx_spi_slave, slave);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*=====================================================================*/
|
||||||
|
/* Public Functions */
|
||||||
|
/*=====================================================================*/
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
* Initialization
|
||||||
|
*/
|
||||||
|
|
||||||
|
void spi_init()
|
||||||
|
{
|
||||||
|
PRINTD("ar71xx_spi: spi_init");
|
||||||
|
|
||||||
|
// Init SPI Hardware, disable remap, set clock
|
||||||
|
__raw_writel(0x43, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_CTRL));
|
||||||
|
|
||||||
|
PRINTD(" ---> out\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
|
||||||
|
unsigned int max_hz, unsigned int mode)
|
||||||
|
{
|
||||||
|
struct ar71xx_spi_slave *ss;
|
||||||
|
|
||||||
|
PRINTD("ar71xx_spi: spi_setup_slave");
|
||||||
|
|
||||||
|
if ((bus != 0) || (cs > 2))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ss = malloc(sizeof(struct ar71xx_spi_slave));
|
||||||
|
if (!ss)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ss->slave.bus = bus;
|
||||||
|
ss->slave.cs = cs;
|
||||||
|
ss->mode = mode;
|
||||||
|
|
||||||
|
/* TODO: Use max_hz to limit the SCK rate */
|
||||||
|
|
||||||
|
PRINTD(" ---> out\n");
|
||||||
|
|
||||||
|
return &ss->slave;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_free_slave(struct spi_slave *slave)
|
||||||
|
{
|
||||||
|
struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave);
|
||||||
|
|
||||||
|
free(ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
int spi_claim_bus(struct spi_slave *slave)
|
||||||
|
{
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_release_bus(struct spi_slave *slave)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
|
||||||
|
void *din, unsigned long flags)
|
||||||
|
{
|
||||||
|
struct ar71xx_spi_slave *ss = to_ar71xx_spi(slave);
|
||||||
|
uint8_t *rx = din;
|
||||||
|
const uint8_t *tx = dout;
|
||||||
|
uint8_t curbyte, curbitlen, restbits;
|
||||||
|
uint32_t bytes = bitlen / 8;
|
||||||
|
uint32_t out;
|
||||||
|
uint32_t in;
|
||||||
|
|
||||||
|
PRINTD("ar71xx_spi: spi_xfer: slave:%p bitlen:%08x dout:%p din:%p flags:%08x\n", slave, bitlen, dout, din, flags);
|
||||||
|
|
||||||
|
if (flags & SPI_XFER_BEGIN) {
|
||||||
|
__raw_writel(SPI_FS_GPIO, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS));
|
||||||
|
__raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
|
||||||
|
}
|
||||||
|
|
||||||
|
restbits = (bitlen % 8);
|
||||||
|
if (restbits != 0)
|
||||||
|
bytes++;
|
||||||
|
|
||||||
|
// enable chip select
|
||||||
|
out = SPI_IOC_CS_ALL & ~(SPI_IOC_CS(slave->cs));
|
||||||
|
|
||||||
|
while (bytes--) {
|
||||||
|
|
||||||
|
curbyte = 0;
|
||||||
|
if (tx) {
|
||||||
|
curbyte = *tx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (restbits != 0) {
|
||||||
|
curbitlen = restbits;
|
||||||
|
curbyte <<= 8 - restbits;
|
||||||
|
} else {
|
||||||
|
curbitlen = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINTD("ar71xx_spi: sending: data:%02x length:%d\n", curbyte, curbitlen);
|
||||||
|
|
||||||
|
/* clock starts at inactive polarity */
|
||||||
|
for (curbyte <<= (8 - curbitlen); curbitlen; curbitlen--) {
|
||||||
|
|
||||||
|
if (curbyte & (1 << 7))
|
||||||
|
out |= SPI_IOC_DO;
|
||||||
|
else
|
||||||
|
out &= ~(SPI_IOC_DO);
|
||||||
|
|
||||||
|
/* setup MSB (to slave) on trailing edge */
|
||||||
|
__raw_writel(out, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
|
||||||
|
|
||||||
|
__raw_writel(out | SPI_IOC_CLK, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
|
||||||
|
|
||||||
|
curbyte <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
in = __raw_readl(KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_RDS));
|
||||||
|
PRINTD("ar71xx_spi: received:%02x\n", in);
|
||||||
|
|
||||||
|
if (rx) {
|
||||||
|
if (restbits == 0) {
|
||||||
|
*rx++ = in;
|
||||||
|
} else {
|
||||||
|
*rx++ = (in << (8 - restbits));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & SPI_XFER_END) {
|
||||||
|
__raw_writel(SPI_IOC_CS(slave->cs), KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
|
||||||
|
__raw_writel(SPI_IOC_CS_ALL, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_IOC));
|
||||||
|
__raw_writel(0, KSEG1ADDR(AR71XX_SPI_BASE + SPI_REG_FS));
|
||||||
|
}
|
||||||
|
|
||||||
|
PRINTD(" ---> out\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,515 @@
|
||||||
|
/*
|
||||||
|
* Atheros AR71xx SoC specific definitions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008-2009 Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
|
||||||
|
*
|
||||||
|
* Parts of this file are based on Atheros' 2.6.15 BSP
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 as published
|
||||||
|
* by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __ASM_MACH_AR71XX_H
|
||||||
|
#define __ASM_MACH_AR71XX_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLER__
|
||||||
|
|
||||||
|
#define BIT(x) (1<<(x))
|
||||||
|
|
||||||
|
#define AR71XX_PCI_MEM_BASE 0x10000000
|
||||||
|
#define AR71XX_PCI_MEM_SIZE 0x08000000
|
||||||
|
#define AR71XX_APB_BASE 0x18000000
|
||||||
|
#define AR71XX_GE0_BASE 0x19000000
|
||||||
|
#define AR71XX_GE0_SIZE 0x01000000
|
||||||
|
#define AR71XX_GE1_BASE 0x1a000000
|
||||||
|
#define AR71XX_GE1_SIZE 0x01000000
|
||||||
|
#define AR71XX_EHCI_BASE 0x1b000000
|
||||||
|
#define AR71XX_EHCI_SIZE 0x01000000
|
||||||
|
#define AR71XX_OHCI_BASE 0x1c000000
|
||||||
|
#define AR71XX_OHCI_SIZE 0x01000000
|
||||||
|
#define AR7240_OHCI_BASE 0x1b000000
|
||||||
|
#define AR7240_OHCI_SIZE 0x01000000
|
||||||
|
#define AR71XX_SPI_BASE 0x1f000000
|
||||||
|
#define AR71XX_SPI_SIZE 0x01000000
|
||||||
|
|
||||||
|
#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
|
||||||
|
#define AR71XX_DDR_CTRL_SIZE 0x10000
|
||||||
|
#define AR71XX_CPU_BASE (AR71XX_APB_BASE + 0x00010000)
|
||||||
|
#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
|
||||||
|
#define AR71XX_UART_SIZE 0x10000
|
||||||
|
#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
|
||||||
|
#define AR71XX_USB_CTRL_SIZE 0x10000
|
||||||
|
#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
|
||||||
|
#define AR71XX_GPIO_SIZE 0x10000
|
||||||
|
#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
|
||||||
|
#define AR71XX_PLL_SIZE 0x10000
|
||||||
|
#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
|
||||||
|
#define AR71XX_RESET_SIZE 0x10000
|
||||||
|
#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
|
||||||
|
#define AR71XX_MII_SIZE 0x10000
|
||||||
|
#define AR71XX_SLIC_BASE (AR71XX_APB_BASE + 0x00090000)
|
||||||
|
#define AR71XX_SLIC_SIZE 0x10000
|
||||||
|
#define AR71XX_DMA_BASE (AR71XX_APB_BASE + 0x000A0000)
|
||||||
|
#define AR71XX_DMA_SIZE 0x10000
|
||||||
|
#define AR71XX_STEREO_BASE (AR71XX_APB_BASE + 0x000B0000)
|
||||||
|
#define AR71XX_STEREO_SIZE 0x10000
|
||||||
|
|
||||||
|
#define AR724X_PCI_CRP_BASE (AR71XX_APB_BASE + 0x000C0000)
|
||||||
|
#define AR724X_PCI_CRP_SIZE 0x100
|
||||||
|
|
||||||
|
#define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000F0000)
|
||||||
|
#define AR724X_PCI_CTRL_SIZE 0x100
|
||||||
|
|
||||||
|
#define AR91XX_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
|
||||||
|
#define AR91XX_WMAC_SIZE 0x30000
|
||||||
|
|
||||||
|
#define AR71XX_MEM_SIZE_MIN 0x0200000
|
||||||
|
#define AR71XX_MEM_SIZE_MAX 0x10000000
|
||||||
|
|
||||||
|
#define AR71XX_CPU_IRQ_BASE 0
|
||||||
|
#define AR71XX_MISC_IRQ_BASE 8
|
||||||
|
#define AR71XX_MISC_IRQ_COUNT 8
|
||||||
|
#define AR71XX_GPIO_IRQ_BASE 16
|
||||||
|
#define AR71XX_GPIO_IRQ_COUNT 32
|
||||||
|
#define AR71XX_PCI_IRQ_BASE 48
|
||||||
|
#define AR71XX_PCI_IRQ_COUNT 8
|
||||||
|
|
||||||
|
#define AR71XX_CPU_IRQ_IP2 (AR71XX_CPU_IRQ_BASE + 2)
|
||||||
|
#define AR71XX_CPU_IRQ_USB (AR71XX_CPU_IRQ_BASE + 3)
|
||||||
|
#define AR71XX_CPU_IRQ_GE0 (AR71XX_CPU_IRQ_BASE + 4)
|
||||||
|
#define AR71XX_CPU_IRQ_GE1 (AR71XX_CPU_IRQ_BASE + 5)
|
||||||
|
#define AR71XX_CPU_IRQ_MISC (AR71XX_CPU_IRQ_BASE + 6)
|
||||||
|
#define AR71XX_CPU_IRQ_TIMER (AR71XX_CPU_IRQ_BASE + 7)
|
||||||
|
|
||||||
|
#define AR71XX_MISC_IRQ_TIMER (AR71XX_MISC_IRQ_BASE + 0)
|
||||||
|
#define AR71XX_MISC_IRQ_ERROR (AR71XX_MISC_IRQ_BASE + 1)
|
||||||
|
#define AR71XX_MISC_IRQ_GPIO (AR71XX_MISC_IRQ_BASE + 2)
|
||||||
|
#define AR71XX_MISC_IRQ_UART (AR71XX_MISC_IRQ_BASE + 3)
|
||||||
|
#define AR71XX_MISC_IRQ_WDOG (AR71XX_MISC_IRQ_BASE + 4)
|
||||||
|
#define AR71XX_MISC_IRQ_PERFC (AR71XX_MISC_IRQ_BASE + 5)
|
||||||
|
#define AR71XX_MISC_IRQ_OHCI (AR71XX_MISC_IRQ_BASE + 6)
|
||||||
|
#define AR71XX_MISC_IRQ_DMA (AR71XX_MISC_IRQ_BASE + 7)
|
||||||
|
|
||||||
|
#define AR71XX_GPIO_IRQ(_x) (AR71XX_GPIO_IRQ_BASE + (_x))
|
||||||
|
|
||||||
|
#define AR71XX_PCI_IRQ_DEV0 (AR71XX_PCI_IRQ_BASE + 0)
|
||||||
|
#define AR71XX_PCI_IRQ_DEV1 (AR71XX_PCI_IRQ_BASE + 1)
|
||||||
|
#define AR71XX_PCI_IRQ_DEV2 (AR71XX_PCI_IRQ_BASE + 2)
|
||||||
|
#define AR71XX_PCI_IRQ_CORE (AR71XX_PCI_IRQ_BASE + 4)
|
||||||
|
|
||||||
|
extern u32 ar71xx_ahb_freq;
|
||||||
|
extern u32 ar71xx_cpu_freq;
|
||||||
|
extern u32 ar71xx_ddr_freq;
|
||||||
|
|
||||||
|
enum ar71xx_soc_type {
|
||||||
|
AR71XX_SOC_UNKNOWN,
|
||||||
|
AR71XX_SOC_AR7130,
|
||||||
|
AR71XX_SOC_AR7141,
|
||||||
|
AR71XX_SOC_AR7161,
|
||||||
|
AR71XX_SOC_AR7240,
|
||||||
|
AR71XX_SOC_AR7241,
|
||||||
|
AR71XX_SOC_AR7242,
|
||||||
|
AR71XX_SOC_AR9130,
|
||||||
|
AR71XX_SOC_AR9132
|
||||||
|
};
|
||||||
|
|
||||||
|
extern enum ar71xx_soc_type ar71xx_soc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PLL block
|
||||||
|
*/
|
||||||
|
#define AR71XX_PLL_REG_CPU_CONFIG 0x00
|
||||||
|
#define AR71XX_PLL_REG_SEC_CONFIG 0x04
|
||||||
|
#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
|
||||||
|
#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
|
||||||
|
|
||||||
|
#define AR71XX_PLL_DIV_SHIFT 3
|
||||||
|
#define AR71XX_PLL_DIV_MASK 0x1f
|
||||||
|
#define AR71XX_CPU_DIV_SHIFT 16
|
||||||
|
#define AR71XX_CPU_DIV_MASK 0x3
|
||||||
|
#define AR71XX_DDR_DIV_SHIFT 18
|
||||||
|
#define AR71XX_DDR_DIV_MASK 0x3
|
||||||
|
#define AR71XX_AHB_DIV_SHIFT 20
|
||||||
|
#define AR71XX_AHB_DIV_MASK 0x7
|
||||||
|
|
||||||
|
#define AR71XX_ETH0_PLL_SHIFT 17
|
||||||
|
#define AR71XX_ETH1_PLL_SHIFT 19
|
||||||
|
|
||||||
|
#define AR724X_PLL_REG_CPU_CONFIG 0x00
|
||||||
|
#define AR724X_PLL_REG_PCIE_CONFIG 0x18
|
||||||
|
|
||||||
|
#define AR724X_PLL_DIV_SHIFT 0
|
||||||
|
#define AR724X_PLL_DIV_MASK 0x3ff
|
||||||
|
#define AR724X_PLL_REF_DIV_SHIFT 10
|
||||||
|
#define AR724X_PLL_REF_DIV_MASK 0xf
|
||||||
|
#define AR724X_AHB_DIV_SHIFT 19
|
||||||
|
#define AR724X_AHB_DIV_MASK 0x1
|
||||||
|
#define AR724X_DDR_DIV_SHIFT 22
|
||||||
|
#define AR724X_DDR_DIV_MASK 0x3
|
||||||
|
|
||||||
|
#define AR91XX_PLL_REG_CPU_CONFIG 0x00
|
||||||
|
#define AR91XX_PLL_REG_ETH_CONFIG 0x04
|
||||||
|
#define AR91XX_PLL_REG_ETH0_INT_CLOCK 0x14
|
||||||
|
#define AR91XX_PLL_REG_ETH1_INT_CLOCK 0x18
|
||||||
|
|
||||||
|
#define AR91XX_PLL_DIV_SHIFT 0
|
||||||
|
#define AR91XX_PLL_DIV_MASK 0x3ff
|
||||||
|
#define AR91XX_DDR_DIV_SHIFT 22
|
||||||
|
#define AR91XX_DDR_DIV_MASK 0x3
|
||||||
|
#define AR91XX_AHB_DIV_SHIFT 19
|
||||||
|
#define AR91XX_AHB_DIV_MASK 0x1
|
||||||
|
|
||||||
|
#define AR91XX_ETH0_PLL_SHIFT 20
|
||||||
|
#define AR91XX_ETH1_PLL_SHIFT 22
|
||||||
|
|
||||||
|
// extern void __iomem *ar71xx_pll_base;
|
||||||
|
|
||||||
|
// static inline void ar71xx_pll_wr(unsigned reg, u32 val)
|
||||||
|
// {
|
||||||
|
// __raw_writel(val, ar71xx_pll_base + reg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static inline u32 ar71xx_pll_rr(unsigned reg)
|
||||||
|
// {
|
||||||
|
// return __raw_readl(ar71xx_pll_base + reg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* USB_CONFIG block
|
||||||
|
*/
|
||||||
|
#define USB_CTRL_REG_FLADJ 0x00
|
||||||
|
#define USB_CTRL_REG_CONFIG 0x04
|
||||||
|
|
||||||
|
// extern void __iomem *ar71xx_usb_ctrl_base;
|
||||||
|
|
||||||
|
// static inline void ar71xx_usb_ctrl_wr(unsigned reg, u32 val)
|
||||||
|
// {
|
||||||
|
// __raw_writel(val, ar71xx_usb_ctrl_base + reg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static inline u32 ar71xx_usb_ctrl_rr(unsigned reg)
|
||||||
|
// {
|
||||||
|
// return __raw_readl(ar71xx_usb_ctrl_base + reg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO block
|
||||||
|
*/
|
||||||
|
#define GPIO_REG_OE 0x00
|
||||||
|
#define GPIO_REG_IN 0x04
|
||||||
|
#define GPIO_REG_OUT 0x08
|
||||||
|
#define GPIO_REG_SET 0x0c
|
||||||
|
#define GPIO_REG_CLEAR 0x10
|
||||||
|
#define GPIO_REG_INT_MODE 0x14
|
||||||
|
#define GPIO_REG_INT_TYPE 0x18
|
||||||
|
#define GPIO_REG_INT_POLARITY 0x1c
|
||||||
|
#define GPIO_REG_INT_PENDING 0x20
|
||||||
|
#define GPIO_REG_INT_ENABLE 0x24
|
||||||
|
#define GPIO_REG_FUNC 0x28
|
||||||
|
|
||||||
|
#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
|
||||||
|
#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
|
||||||
|
#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
|
||||||
|
#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12)
|
||||||
|
#define AR71XX_GPIO_FUNC_UART_EN BIT(8)
|
||||||
|
#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4)
|
||||||
|
#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0)
|
||||||
|
|
||||||
|
#define AR71XX_GPIO_COUNT 16
|
||||||
|
|
||||||
|
#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19)
|
||||||
|
#define AR724X_GPIO_FUNC_SPI_EN BIT(18)
|
||||||
|
#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
|
||||||
|
#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
|
||||||
|
#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12)
|
||||||
|
#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11)
|
||||||
|
#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10)
|
||||||
|
#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9)
|
||||||
|
#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8)
|
||||||
|
#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
|
||||||
|
#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
|
||||||
|
#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
|
||||||
|
#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
|
||||||
|
#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
|
||||||
|
#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
|
||||||
|
#define AR724X_GPIO_FUNC_UART_EN BIT(1)
|
||||||
|
#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0)
|
||||||
|
|
||||||
|
#define AR724X_GPIO_COUNT 18
|
||||||
|
|
||||||
|
#define AR91XX_GPIO_FUNC_WMAC_LED_EN BIT(22)
|
||||||
|
#define AR91XX_GPIO_FUNC_EXP_PORT_CS_EN BIT(21)
|
||||||
|
#define AR91XX_GPIO_FUNC_I2S_REFCLKEN BIT(20)
|
||||||
|
#define AR91XX_GPIO_FUNC_I2S_MCKEN BIT(19)
|
||||||
|
#define AR91XX_GPIO_FUNC_I2S1_EN BIT(18)
|
||||||
|
#define AR91XX_GPIO_FUNC_I2S0_EN BIT(17)
|
||||||
|
#define AR91XX_GPIO_FUNC_SLIC_EN BIT(16)
|
||||||
|
#define AR91XX_GPIO_FUNC_UART_RTSCTS_EN BIT(9)
|
||||||
|
#define AR91XX_GPIO_FUNC_UART_EN BIT(8)
|
||||||
|
#define AR91XX_GPIO_FUNC_USB_CLK_EN BIT(4)
|
||||||
|
|
||||||
|
#define AR91XX_GPIO_COUNT 22
|
||||||
|
|
||||||
|
// extern void __iomem *ar71xx_gpio_base;
|
||||||
|
|
||||||
|
// static inline void ar71xx_gpio_wr(unsigned reg, u32 value)
|
||||||
|
// {
|
||||||
|
// __raw_writel(value, ar71xx_gpio_base + reg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static inline u32 ar71xx_gpio_rr(unsigned reg)
|
||||||
|
// {
|
||||||
|
// return __raw_readl(ar71xx_gpio_base + reg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void ar71xx_gpio_init(void) __init;
|
||||||
|
// void ar71xx_gpio_function_enable(u32 mask);
|
||||||
|
// void ar71xx_gpio_function_disable(u32 mask);
|
||||||
|
// void ar71xx_gpio_function_setup(u32 set, u32 clear);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DDR_CTRL block
|
||||||
|
*/
|
||||||
|
#define AR71XX_DDR_REG_PCI_WIN0 0x7c
|
||||||
|
#define AR71XX_DDR_REG_PCI_WIN1 0x80
|
||||||
|
#define AR71XX_DDR_REG_PCI_WIN2 0x84
|
||||||
|
#define AR71XX_DDR_REG_PCI_WIN3 0x88
|
||||||
|
#define AR71XX_DDR_REG_PCI_WIN4 0x8c
|
||||||
|
#define AR71XX_DDR_REG_PCI_WIN5 0x90
|
||||||
|
#define AR71XX_DDR_REG_PCI_WIN6 0x94
|
||||||
|
#define AR71XX_DDR_REG_PCI_WIN7 0x98
|
||||||
|
#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
|
||||||
|
#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
|
||||||
|
#define AR71XX_DDR_REG_FLUSH_USB 0xa4
|
||||||
|
#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
|
||||||
|
|
||||||
|
#define AR724X_DDR_REG_FLUSH_GE0 0x7c
|
||||||
|
#define AR724X_DDR_REG_FLUSH_GE1 0x80
|
||||||
|
#define AR724X_DDR_REG_FLUSH_USB 0x84
|
||||||
|
#define AR724X_DDR_REG_FLUSH_PCIE 0x88
|
||||||
|
|
||||||
|
#define AR91XX_DDR_REG_FLUSH_GE0 0x7c
|
||||||
|
#define AR91XX_DDR_REG_FLUSH_GE1 0x80
|
||||||
|
#define AR91XX_DDR_REG_FLUSH_USB 0x84
|
||||||
|
#define AR91XX_DDR_REG_FLUSH_WMAC 0x88
|
||||||
|
|
||||||
|
#define PCI_WIN0_OFFS 0x10000000
|
||||||
|
#define PCI_WIN1_OFFS 0x11000000
|
||||||
|
#define PCI_WIN2_OFFS 0x12000000
|
||||||
|
#define PCI_WIN3_OFFS 0x13000000
|
||||||
|
#define PCI_WIN4_OFFS 0x14000000
|
||||||
|
#define PCI_WIN5_OFFS 0x15000000
|
||||||
|
#define PCI_WIN6_OFFS 0x16000000
|
||||||
|
#define PCI_WIN7_OFFS 0x07000000
|
||||||
|
|
||||||
|
// extern void __iomem *ar71xx_ddr_base;
|
||||||
|
|
||||||
|
// static inline void ar71xx_ddr_wr(unsigned reg, u32 val)
|
||||||
|
// {
|
||||||
|
// __raw_writel(val, ar71xx_ddr_base + reg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static inline u32 ar71xx_ddr_rr(unsigned reg)
|
||||||
|
// {
|
||||||
|
// return __raw_readl(ar71xx_ddr_base + reg);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// void ar71xx_ddr_flush(u32 reg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PCI block
|
||||||
|
*/
|
||||||
|
#define AR71XX_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + PCI_WIN7_OFFS + 0x10000)
|
||||||
|
#define AR71XX_PCI_CFG_SIZE 0x100
|
||||||
|
|
||||||
|
#define PCI_REG_CRP_AD_CBE 0x00
|
||||||
|
#define PCI_REG_CRP_WRDATA 0x04
|
||||||
|
#define PCI_REG_CRP_RDDATA 0x08
|
||||||
|
#define PCI_REG_CFG_AD 0x0c
|
||||||
|
#define PCI_REG_CFG_CBE 0x10
|
||||||
|
#define PCI_REG_CFG_WRDATA 0x14
|
||||||
|
#define PCI_REG_CFG_RDDATA 0x18
|
||||||
|
#define PCI_REG_PCI_ERR 0x1c
|
||||||
|
#define PCI_REG_PCI_ERR_ADDR 0x20
|
||||||
|
#define PCI_REG_AHB_ERR 0x24
|
||||||
|
#define PCI_REG_AHB_ERR_ADDR 0x28
|
||||||
|
|
||||||
|
#define PCI_CRP_CMD_WRITE 0x00010000
|
||||||
|
#define PCI_CRP_CMD_READ 0x00000000
|
||||||
|
#define PCI_CFG_CMD_READ 0x0000000a
|
||||||
|
#define PCI_CFG_CMD_WRITE 0x0000000b
|
||||||
|
|
||||||
|
#define PCI_IDSEL_ADL_START 17
|
||||||
|
|
||||||
|
#define AR724X_PCI_CFG_BASE (AR71XX_PCI_MEM_BASE + 0x4000000)
|
||||||
|
#define AR724X_PCI_CFG_SIZE 0x1000
|
||||||
|
|
||||||
|
#define AR724X_PCI_REG_APP 0x00
|
||||||
|
#define AR724X_PCI_REG_RESET 0x18
|
||||||
|
#define AR724X_PCI_REG_INT_STATUS 0x4c
|
||||||
|
#define AR724X_PCI_REG_INT_MASK 0x50
|
||||||
|
|
||||||
|
#define AR724X_PCI_APP_LTSSM_ENABLE BIT(0)
|
||||||
|
#define AR724X_PCI_RESET_LINK_UP BIT(0)
|
||||||
|
|
||||||
|
#define AR724X_PCI_INT_DEV0 BIT(14)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RESET block
|
||||||
|
*/
|
||||||
|
#define AR71XX_RESET_REG_TIMER 0x00
|
||||||
|
#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
|
||||||
|
#define AR71XX_RESET_REG_WDOG_CTRL 0x08
|
||||||
|
#define AR71XX_RESET_REG_WDOG 0x0c
|
||||||
|
#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
|
||||||
|
#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
|
||||||
|
#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
|
||||||
|
#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
|
||||||
|
#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
|
||||||
|
#define AR71XX_RESET_REG_RESET_MODULE 0x24
|
||||||
|
#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
|
||||||
|
#define AR71XX_RESET_REG_PERFC0 0x30
|
||||||
|
#define AR71XX_RESET_REG_PERFC1 0x34
|
||||||
|
#define AR71XX_RESET_REG_REV_ID 0x90
|
||||||
|
|
||||||
|
#define AR91XX_RESET_REG_GLOBAL_INT_STATUS 0x18
|
||||||
|
#define AR91XX_RESET_REG_RESET_MODULE 0x1c
|
||||||
|
#define AR91XX_RESET_REG_PERF_CTRL 0x20
|
||||||
|
#define AR91XX_RESET_REG_PERFC0 0x24
|
||||||
|
#define AR91XX_RESET_REG_PERFC1 0x28
|
||||||
|
|
||||||
|
#define AR724X_RESET_REG_RESET_MODULE 0x1c
|
||||||
|
|
||||||
|
#define WDOG_CTRL_LAST_RESET BIT(31)
|
||||||
|
#define WDOG_CTRL_ACTION_MASK 3
|
||||||
|
#define WDOG_CTRL_ACTION_NONE 0 /* no action */
|
||||||
|
#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
|
||||||
|
#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
|
||||||
|
#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
|
||||||
|
|
||||||
|
#define MISC_INT_DMA BIT(7)
|
||||||
|
#define MISC_INT_OHCI BIT(6)
|
||||||
|
#define MISC_INT_PERFC BIT(5)
|
||||||
|
#define MISC_INT_WDOG BIT(4)
|
||||||
|
#define MISC_INT_UART BIT(3)
|
||||||
|
#define MISC_INT_GPIO BIT(2)
|
||||||
|
#define MISC_INT_ERROR BIT(1)
|
||||||
|
#define MISC_INT_TIMER BIT(0)
|
||||||
|
|
||||||
|
#define PCI_INT_CORE BIT(4)
|
||||||
|
#define PCI_INT_DEV2 BIT(2)
|
||||||
|
#define PCI_INT_DEV1 BIT(1)
|
||||||
|
#define PCI_INT_DEV0 BIT(0)
|
||||||
|
|
||||||
|
#define RESET_MODULE_EXTERNAL BIT(28)
|
||||||
|
#define RESET_MODULE_FULL_CHIP BIT(24)
|
||||||
|
#define RESET_MODULE_AMBA2WMAC BIT(22)
|
||||||
|
#define RESET_MODULE_CPU_NMI BIT(21)
|
||||||
|
#define RESET_MODULE_CPU_COLD BIT(20)
|
||||||
|
#define RESET_MODULE_DMA BIT(19)
|
||||||
|
#define RESET_MODULE_SLIC BIT(18)
|
||||||
|
#define RESET_MODULE_STEREO BIT(17)
|
||||||
|
#define RESET_MODULE_DDR BIT(16)
|
||||||
|
#define RESET_MODULE_GE1_MAC BIT(13)
|
||||||
|
#define RESET_MODULE_GE1_PHY BIT(12)
|
||||||
|
#define RESET_MODULE_USBSUS_OVERRIDE BIT(10)
|
||||||
|
#define RESET_MODULE_GE0_MAC BIT(9)
|
||||||
|
#define RESET_MODULE_GE0_PHY BIT(8)
|
||||||
|
#define RESET_MODULE_USB_OHCI_DLL BIT(6)
|
||||||
|
#define RESET_MODULE_USB_HOST BIT(5)
|
||||||
|
#define RESET_MODULE_USB_PHY BIT(4)
|
||||||
|
#define RESET_MODULE_USB_OHCI_DLL_7240 BIT(3)
|
||||||
|
#define RESET_MODULE_PCI_BUS BIT(1)
|
||||||
|
#define RESET_MODULE_PCI_CORE BIT(0)
|
||||||
|
|
||||||
|
#define AR724X_RESET_GE1_MDIO BIT(23)
|
||||||
|
#define AR724X_RESET_GE0_MDIO BIT(22)
|
||||||
|
#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
|
||||||
|
#define AR724X_RESET_PCIE_PHY BIT(7)
|
||||||
|
#define AR724X_RESET_PCIE BIT(6)
|
||||||
|
|
||||||
|
#define REV_ID_MAJOR_MASK 0xfff0
|
||||||
|
#define REV_ID_MAJOR_AR71XX 0x00a0
|
||||||
|
#define REV_ID_MAJOR_AR913X 0x00b0
|
||||||
|
#define REV_ID_MAJOR_AR7240 0x00c0
|
||||||
|
#define REV_ID_MAJOR_AR7241 0x0100
|
||||||
|
#define REV_ID_MAJOR_AR7242 0x1100
|
||||||
|
|
||||||
|
#define AR71XX_REV_ID_MINOR_MASK 0x3
|
||||||
|
#define AR71XX_REV_ID_MINOR_AR7130 0x0
|
||||||
|
#define AR71XX_REV_ID_MINOR_AR7141 0x1
|
||||||
|
#define AR71XX_REV_ID_MINOR_AR7161 0x2
|
||||||
|
#define AR71XX_REV_ID_REVISION_MASK 0x3
|
||||||
|
#define AR71XX_REV_ID_REVISION_SHIFT 2
|
||||||
|
|
||||||
|
#define AR91XX_REV_ID_MINOR_MASK 0x3
|
||||||
|
#define AR91XX_REV_ID_MINOR_AR9130 0x0
|
||||||
|
#define AR91XX_REV_ID_MINOR_AR9132 0x1
|
||||||
|
#define AR91XX_REV_ID_REVISION_MASK 0x3
|
||||||
|
#define AR91XX_REV_ID_REVISION_SHIFT 2
|
||||||
|
|
||||||
|
#define AR724X_REV_ID_REVISION_MASK 0x3
|
||||||
|
|
||||||
|
// extern void __iomem *ar71xx_reset_base;
|
||||||
|
|
||||||
|
static inline void ar71xx_reset_wr(unsigned reg, u32 val)
|
||||||
|
{
|
||||||
|
__raw_writel(val, KSEG1ADDR(AR71XX_RESET_BASE) + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 ar71xx_reset_rr(unsigned reg)
|
||||||
|
{
|
||||||
|
return __raw_readl(KSEG1ADDR(AR71XX_RESET_BASE) + reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// void ar71xx_device_stop(u32 mask);
|
||||||
|
// void ar71xx_device_start(u32 mask);
|
||||||
|
// int ar71xx_device_stopped(u32 mask);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI block
|
||||||
|
*/
|
||||||
|
#define SPI_REG_FS 0x00 /* Function Select */
|
||||||
|
#define SPI_REG_CTRL 0x04 /* SPI Control */
|
||||||
|
#define SPI_REG_IOC 0x08 /* SPI I/O Control */
|
||||||
|
#define SPI_REG_RDS 0x0c /* Read Data Shift */
|
||||||
|
|
||||||
|
#define SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
|
||||||
|
|
||||||
|
#define SPI_CTRL_RD BIT(6) /* Remap Disable */
|
||||||
|
#define SPI_CTRL_DIV_MASK 0x3f
|
||||||
|
|
||||||
|
#define SPI_IOC_DO BIT(0) /* Data Out pin */
|
||||||
|
#define SPI_IOC_CLK BIT(8) /* CLK pin */
|
||||||
|
#define SPI_IOC_CS(n) BIT(16 + (n))
|
||||||
|
#define SPI_IOC_CS0 SPI_IOC_CS(0)
|
||||||
|
#define SPI_IOC_CS1 SPI_IOC_CS(1)
|
||||||
|
#define SPI_IOC_CS2 SPI_IOC_CS(2)
|
||||||
|
#define SPI_IOC_CS_ALL (SPI_IOC_CS0 | SPI_IOC_CS1 | SPI_IOC_CS2)
|
||||||
|
|
||||||
|
// void ar71xx_flash_acquire(void);
|
||||||
|
// void ar71xx_flash_release(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* MII_CTRL block
|
||||||
|
*/
|
||||||
|
#define MII_REG_MII0_CTRL 0x00
|
||||||
|
#define MII_REG_MII1_CTRL 0x04
|
||||||
|
|
||||||
|
#define MII0_CTRL_IF_GMII 0
|
||||||
|
#define MII0_CTRL_IF_MII 1
|
||||||
|
#define MII0_CTRL_IF_RGMII 2
|
||||||
|
#define MII0_CTRL_IF_RMII 3
|
||||||
|
|
||||||
|
#define MII1_CTRL_IF_RGMII 0
|
||||||
|
#define MII1_CTRL_IF_RMII 1
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLER__ */
|
||||||
|
|
||||||
|
#endif /* __ASM_MACH_AR71XX_H */
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Kurz <michi.kurz@googlemail.com>.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _AR71XX_GPIO_H
|
||||||
|
#define _AR71XX_GPIO_H
|
||||||
|
|
||||||
|
#include <common.h>
|
||||||
|
#include <asm/ar71xx.h>
|
||||||
|
|
||||||
|
static inline void ar71xx_setpin(uint8_t pin, uint8_t state)
|
||||||
|
{
|
||||||
|
uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
|
||||||
|
|
||||||
|
if (state != 0) {
|
||||||
|
reg |= (1 << pin);
|
||||||
|
} else {
|
||||||
|
reg &= ~(1 << pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
|
||||||
|
readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OUT));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t ar71xx_getpin(uint8_t pin)
|
||||||
|
{
|
||||||
|
uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_IN));
|
||||||
|
return (((reg & (1 << pin)) != 0) ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ar71xx_setpindir(uint8_t pin, uint8_t direction)
|
||||||
|
{
|
||||||
|
uint32_t reg = readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
|
||||||
|
|
||||||
|
if (direction != 0) {
|
||||||
|
reg |= (1 << pin);
|
||||||
|
} else {
|
||||||
|
reg &= ~(1 << pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(reg, KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
|
||||||
|
readl(KSEG1ADDR(AR71XX_GPIO_BASE + GPIO_REG_OE));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* AR71XX_GPIO_H */
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2010
|
||||||
|
* Michael Kurz <michi.kurz@googlemail.com>.
|
||||||
|
*
|
||||||
|
* See file CREDITS for list of people who contributed to this
|
||||||
|
* project.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||||||
|
* MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This file contains the configuration parameters for the zyxel nbg460n board. */
|
||||||
|
|
||||||
|
#ifndef _NBG460N_CONFIG_H
|
||||||
|
#define _NBG460N_CONFIG_H
|
||||||
|
|
||||||
|
#define CONFIG_MIPS32 1 /* MIPS32 CPU core */
|
||||||
|
#define CONFIG_AR71XX 1
|
||||||
|
#define CONFIG_AR91XX 1
|
||||||
|
#define CONFIG_SYS_HZ 1000
|
||||||
|
#define CONFIG_SYS_MIPS_TIMER_FREQ (400000000/2)
|
||||||
|
|
||||||
|
/* Cache Configuration */
|
||||||
|
#define CONFIG_SYS_DCACHE_SIZE 32768
|
||||||
|
#define CONFIG_SYS_ICACHE_SIZE 65536
|
||||||
|
#define CONFIG_SYS_CACHELINE_SIZE 32
|
||||||
|
/* Cache lock for stack */
|
||||||
|
#define CONFIG_SYS_INIT_SP_OFFSET 0x1000
|
||||||
|
|
||||||
|
#define CONFIG_SYS_MONITOR_BASE (TEXT_BASE)
|
||||||
|
|
||||||
|
#define CONFIG_BAUDRATE 115200
|
||||||
|
#define CONFIG_SYS_BAUDRATE_TABLE {115200}
|
||||||
|
|
||||||
|
#define CONFIG_MISC_INIT_R
|
||||||
|
|
||||||
|
/* SPI-Flash support */
|
||||||
|
#define CONFIG_SPI_FLASH
|
||||||
|
#define CONFIG_AR71XX_SPI
|
||||||
|
#define CONFIG_SPI_FLASH_MACRONIX
|
||||||
|
#define CONFIG_SF_DEFAULT_HZ 25000000
|
||||||
|
|
||||||
|
#define CONFIG_ENV_SPI_MAX_HZ 25000000
|
||||||
|
#define CONFIG_ENV_SPI_BUS 0
|
||||||
|
#define CONFIG_ENV_SPI_CS 0
|
||||||
|
|
||||||
|
#define CONFIG_ENV_IS_IN_SPI_FLASH
|
||||||
|
#define CONFIG_ENV_ADDR 0xbfc20000
|
||||||
|
#define CONFIG_ENV_OFFSET 0x20000
|
||||||
|
#define CONFIG_ENV_SIZE 0x01000
|
||||||
|
#define CONFIG_ENV_SECT_SIZE 0x10000
|
||||||
|
#define CONFIG_SYS_MAX_FLASH_BANKS 1
|
||||||
|
#define CONFIG_SYS_MAX_FLASH_SECT 64
|
||||||
|
#define CONFIG_SYS_FLASH_BASE 0xbfc00000
|
||||||
|
|
||||||
|
/* Net support */
|
||||||
|
#define CONFIG_ETHADDR_ADDR 0xbfc0fff8
|
||||||
|
#define CONFIG_SYS_RX_ETH_BUFFER 16
|
||||||
|
#define CONFIG_AG71XX
|
||||||
|
#define CONFIG_AG71XX_PORTS { 1, 1 }
|
||||||
|
#define CONFIG_AG71XX_MII0_IIF MII0_CTRL_IF_RGMII
|
||||||
|
#define CONFIG_AG71XX_MII1_IIF MII1_CTRL_IF_RGMII
|
||||||
|
#define CONFIG_NET_MULTI
|
||||||
|
#define CONFIG_IPADDR 192.168.1.254
|
||||||
|
#define CONFIG_SERVERIP 192.168.1.42
|
||||||
|
|
||||||
|
/* Switch support */
|
||||||
|
#define CONFIG_MII
|
||||||
|
#define CONFIG_RTL8366_MII
|
||||||
|
#define RTL8366_PIN_SDA 16
|
||||||
|
#define RTL8366_PIN_SCK 18
|
||||||
|
#define MII_GPIOINCLUDE <asm/ar71xx_gpio.h>
|
||||||
|
#define MII_SETSDA(x) ar71xx_setpin(RTL8366_PIN_SDA, x)
|
||||||
|
#define MII_GETSDA ar71xx_getpin(RTL8366_PIN_SDA)
|
||||||
|
#define MII_SETSCK(x) ar71xx_setpin(RTL8366_PIN_SCK, x)
|
||||||
|
#define MII_SDAINPUT ar71xx_setpindir(RTL8366_PIN_SDA, 0)
|
||||||
|
#define MII_SDAOUTPUT ar71xx_setpindir(RTL8366_PIN_SDA, 1)
|
||||||
|
#define MII_SCKINPUT ar71xx_setpindir(RTL8366_PIN_SCK, 0)
|
||||||
|
#define MII_SCKOUTPUT ar71xx_setpindir(RTL8366_PIN_SCK, 1)
|
||||||
|
|
||||||
|
#define CONFIG_BOOTDELAY 3
|
||||||
|
#define CONFIG_BOOTARGS "console=ttyS0,115200 rootfstype==squashfs,jffs2 noinitrd machtype=NBG460N"
|
||||||
|
#define CONFIG_BOOTCOMMAND "bootm 0xbfc70000"
|
||||||
|
#define CONFIG_LZMA
|
||||||
|
|
||||||
|
|
||||||
|
/* Commands */
|
||||||
|
#define CONFIG_SYS_NO_FLASH
|
||||||
|
#include <config_cmd_default.h>
|
||||||
|
#undef CONFIG_CMD_BDI
|
||||||
|
#undef CONFIG_CMD_FPGA
|
||||||
|
#undef CONFIG_CMD_IMI
|
||||||
|
#undef CONFIG_CMD_IMLS
|
||||||
|
#undef CONFIG_CMD_LOADS
|
||||||
|
#define CONFIG_CMD_SF
|
||||||
|
#define CONFIG_CMD_MII
|
||||||
|
#define CONFIG_CMD_PING
|
||||||
|
#define CONFIG_CMD_DHCP
|
||||||
|
#define CONFIG_CMD_SPI
|
||||||
|
|
||||||
|
/* Miscellaneous configurable options */
|
||||||
|
#define CONFIG_SYS_PROMPT "U-Boot> "
|
||||||
|
#define CONFIG_SYS_CBSIZE 256
|
||||||
|
#define CONFIG_SYS_MAXARGS 16
|
||||||
|
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
|
||||||
|
#define CONFIG_SYS_LONGHELP 1
|
||||||
|
#define CONFIG_CMDLINE_EDITING 1
|
||||||
|
#define CONFIG_AUTO_COMPLETE
|
||||||
|
#define CONFIG_SYS_HUSH_PARSER
|
||||||
|
#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
|
||||||
|
|
||||||
|
/* Size of malloc() pool */
|
||||||
|
#define CONFIG_SYS_MALLOC_LEN ROUND(3 * 0x10000 + 128*1024, 0x1000)
|
||||||
|
#define CONFIG_SYS_GBL_DATA_SIZE 128 /* 128 bytes for initial data */
|
||||||
|
|
||||||
|
#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024
|
||||||
|
|
||||||
|
#define CONFIG_SYS_SDRAM_BASE 0x80000000 /* Cached addr */
|
||||||
|
#define CONFIG_SYS_LOAD_ADDR 0x80060000 /* default load address */
|
||||||
|
|
||||||
|
#define CONFIG_SYS_MEMTEST_START 0x80000800
|
||||||
|
#define CONFIG_SYS_MEMTEST_END 0x81E00000
|
||||||
|
|
||||||
|
#endif /* _NBG460N_CONFIG_H */
|
|
@ -0,0 +1,28 @@
|
||||||
|
diff -ur u-boot-2010.03/cpu/mips/Makefile u-boot-nbg/cpu/mips/Makefile
|
||||||
|
--- u-boot-2010.03/cpu/mips/Makefile 2010-03-31 23:54:39.000000000 +0200
|
||||||
|
+++ u-boot-nbg/cpu/mips/Makefile 2010-04-15 18:58:01.000000000 +0200
|
||||||
|
@@ -33,6 +33,7 @@
|
||||||
|
COBJS-$(CONFIG_INCA_IP) += asc_serial.o incaip_clock.o
|
||||||
|
COBJS-$(CONFIG_PURPLE) += asc_serial.o
|
||||||
|
COBJS-$(CONFIG_SOC_AU1X00) += au1x00_eth.o au1x00_serial.o au1x00_usb_ohci.o
|
||||||
|
+COBJS-$(CONFIG_AR71XX) += ar71xx_serial.o
|
||||||
|
|
||||||
|
SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c)
|
||||||
|
OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y))
|
||||||
|
diff -ur u-boot-2010.03/Makefile u-boot-nbg/Makefile
|
||||||
|
--- u-boot-2010.03/Makefile 2010-03-31 23:54:39.000000000 +0200
|
||||||
|
+++ u-boot-nbg/Makefile 2010-04-11 23:31:29.000000000 +0200
|
||||||
|
@@ -3455,6 +3455,13 @@
|
||||||
|
@$(MKCONFIG) -a qemu-mips mips mips qemu-mips
|
||||||
|
|
||||||
|
#########################################################################
|
||||||
|
+## MIPS32 AR71XX (24K)
|
||||||
|
+#########################################################################
|
||||||
|
+
|
||||||
|
+nbg460n_550n_550nh_config : unconfig
|
||||||
|
+ @$(MKCONFIG) -a nbg460n mips mips nbg460n zyxel
|
||||||
|
+
|
||||||
|
+#########################################################################
|
||||||
|
## MIPS64 5Kc
|
||||||
|
#########################################################################
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
diff -ur u-boot-2010.03/drivers/spi/Makefile u-boot-nbg/drivers/spi/Makefile
|
||||||
|
--- u-boot-2010.03/drivers/spi/Makefile 2010-03-31 23:54:39.000000000 +0200
|
||||||
|
+++ u-boot-nbg/drivers/spi/Makefile 2010-04-15 19:31:27.000000000 +0200
|
||||||
|
@@ -25,6 +25,7 @@
|
||||||
|
|
||||||
|
LIB := $(obj)libspi.a
|
||||||
|
|
||||||
|
+COBJS-$(CONFIG_AR71XX_SPI) += ar71xx_spi.o
|
||||||
|
COBJS-$(CONFIG_ATMEL_DATAFLASH_SPI) += atmel_dataflash_spi.o
|
||||||
|
COBJS-$(CONFIG_ATMEL_SPI) += atmel_spi.o
|
||||||
|
COBJS-$(CONFIG_BFIN_SPI) += bfin_spi.o
|
|
@ -0,0 +1,22 @@
|
||||||
|
diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile
|
||||||
|
--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200
|
||||||
|
+++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
|
||||||
|
COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
|
||||||
|
COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
|
||||||
|
+COBJS-$(CONFIG_AG71XX) += ag71xx.o
|
||||||
|
COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
|
||||||
|
COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
|
||||||
|
COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o
|
||||||
|
diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h
|
||||||
|
--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200
|
||||||
|
+++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200
|
||||||
|
@@ -42,6 +42,7 @@
|
||||||
|
|
||||||
|
/* Driver initialization prototypes */
|
||||||
|
int au1x00_enet_initialize(bd_t*);
|
||||||
|
+int ag71xx_register(bd_t * bis, char *phyname[], u16 phyid[], u16 phyfixed[]);
|
||||||
|
int at91emac_register(bd_t *bis, unsigned long iobase);
|
||||||
|
int bfin_EMAC_initialize(bd_t *bis);
|
||||||
|
int cs8900_initialize(u8 dev_num, int base_addr);
|
|
@ -0,0 +1,28 @@
|
||||||
|
diff -ur u-boot-2010.03/drivers/net/Makefile u-boot-nbg/drivers/net/Makefile
|
||||||
|
--- u-boot-2010.03/drivers/net/Makefile 2010-03-31 23:54:39.000000000 +0200
|
||||||
|
+++ u-boot-nbg/drivers/net/Makefile 2010-04-19 23:30:01.000000000 +0200
|
||||||
|
@@ -65,6 +65,7 @@
|
||||||
|
COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o
|
||||||
|
COBJS-$(CONFIG_RTL8139) += rtl8139.o
|
||||||
|
COBJS-$(CONFIG_RTL8169) += rtl8169.o
|
||||||
|
+COBJS-$(CONFIG_RTL8366_MII) += phy/rtl8366_mii.o
|
||||||
|
COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o
|
||||||
|
COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
|
||||||
|
COBJS-$(CONFIG_SMC91111) += smc91111.o
|
||||||
|
diff -ur u-boot-2010.03/include/netdev.h u-boot-nbg/include/netdev.h
|
||||||
|
--- u-boot-2010.03/include/netdev.h 2010-03-31 23:54:39.000000000 +0200
|
||||||
|
+++ u-boot-nbg/include/netdev.h 2010-05-02 11:30:58.000000000 +0200
|
||||||
|
@@ -175,5 +175,13 @@
|
||||||
|
|
||||||
|
int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
|
||||||
|
#endif /* CONFIG_MV88E61XX_SWITCH */
|
||||||
|
+
|
||||||
|
+#if defined(CONFIG_RTL8366_MII)
|
||||||
|
+#define RTL8366_DEVNAME "rtl8366"
|
||||||
|
+#define RTL8366_WANPHY_ID 4
|
||||||
|
+#define RTL8366_LANPHY_ID -1
|
||||||
|
+int rtl8366_mii_register(bd_t *bis);
|
||||||
|
+int rtl8366s_initialize(void);
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#endif /* _NETDEV_H_ */
|
Loading…
Reference in New Issue