From: Felix Fietkau Date: Mon, 23 Jan 2017 07:23:55 +0000 (+0100) Subject: uboot-ar71xx: switch to using u-boot.mk X-Git-Tag: v18.06.0-rc1~3998 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=83783f296a18e6e481f23b2019575e45c437db4e;p=oweals%2Fopenwrt.git uboot-ar71xx: switch to using u-boot.mk Signed-off-by: Felix Fietkau --- diff --git a/package/boot/uboot-ar71xx/Makefile b/package/boot/uboot-ar71xx/Makefile index 70f96713e6..e0bc39fe94 100644 --- a/package/boot/uboot-ar71xx/Makefile +++ b/package/boot/uboot-ar71xx/Makefile @@ -6,90 +6,26 @@ # 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_HASH:=902d1b2c15787df55186fae4033685fb0c5a5a12755a08383e97c4a3e255925b -PKG_SOURCE_URL:= \ - http://mirror2.openwrt.org/sources \ - ftp://ftp.denx.de/pub/u-boot -PKG_TARGETS:=bin - -PKG_LICENSE:=GPL-2.0 GPL-2.0+ -PKG_LICENSE_FILES:=Licenses/README +include $(INCLUDE_DIR)/u-boot.mk 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 - DEFAULT:=y if (TARGET_ar71xx_generic_DEVICE_NBG_460N_550N_550NH || TARGET_DEVICE_ar71xx_generic_DEVICE_NBG_460N_550N_550NH || TARGET_ar71xx_generic_Default) -endef - -UBOOTS:=nbg460n_550n_550nh - -define Package/uboot/template -define Package/uboot-ar71xx-$(1) - SECTION:=boot - CATEGORY:=Boot Loaders - TITLE:=$(2) - DEPENDS:=@TARGET_ar71xx_generic - 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)) +define U-Boot/Default + BUILD_TARGET:=ar71xx + BUILD_SUBTARGET:=generic 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 +define U-Boot/nbg460n_550n_550nh + TITLE:=NBG460N/550N/550NH routers + BUILD_DEVICES:=NBG_460N_550N_550NH + HIDDEN:=y endef -$(foreach u,$(UBOOTS), \ - $(eval $(call Package/uboot/install/template,$(u),openwrt-$(BOARD)-$(SUBTARGET)-$(u)-u-boot.bin)) \ -) +UBOOT_TARGETS:=nbg460n_550n_550nh -$(foreach u,$(UBOOTS), \ - $(eval $(call BuildUbootPackage,$(u))) \ - $(eval $(call BuildPackage,uboot-ar71xx-$(u))) \ -) +$(eval $(call BuildPackage/U-Boot)) diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile deleted file mode 100644 index b0a385babf..0000000000 --- a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# -# (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 - -######################################################################### diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk deleted file mode 100644 index e042e78bf8..0000000000 --- a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/config.mk +++ /dev/null @@ -1 +0,0 @@ -TEXT_BASE = 0x81E00000 diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S deleted file mode 100644 index 83084c8d48..0000000000 --- a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/lowlevel_init.S +++ /dev/null @@ -1,39 +0,0 @@ -/* - * (C) Copyright 2010 - * Michael Kurz . - * - * 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 -#include -#include -#include -#include - - - -.globl lowlevel_init -/* - All done by Bootbase, nothing to do -*/ -lowlevel_init: - jr ra - nop - diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c deleted file mode 100644 index 03a479d522..0000000000 --- a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/nbg460n.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * (C) Copyright 2010 - * Michael Kurz . - * - * 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 -#include -#include -#include -#include -#include -#include - -#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; -} diff --git a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds b/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds deleted file mode 100644 index 8dc2b764c7..0000000000 --- a/package/boot/uboot-ar71xx/files/board/zyxel/nbg460n/u-boot.lds +++ /dev/null @@ -1,42 +0,0 @@ -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 = .; -} diff --git a/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c b/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c deleted file mode 100644 index f093318952..0000000000 --- a/package/boot/uboot-ar71xx/files/cpu/mips/ar71xx_serial.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * (C) Copyright 2010 - * Michael Kurz . - * - * 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 -#include -#include -#include - -#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++); - } -} diff --git a/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c deleted file mode 100644 index b3324c0197..0000000000 --- a/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.c +++ /dev/null @@ -1,809 +0,0 @@ -/* - * Atheros AR71xx built-in ethernet mac driver - * - * Copyright (C) 2010 Michael Kurz - * Copyright (C) 2008-2010 Gabor Juhos - * Copyright (C) 2008 Imre Kaloz - * - * 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 -#include -#include -#include - -#include - -#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; -} diff --git a/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h b/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h deleted file mode 100644 index edce429749..0000000000 --- a/package/boot/uboot-ar71xx/files/drivers/net/ag71xx.h +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Atheros AR71xx built-in ethernet mac driver - * - * Copyright (C) 2008-2010 Gabor Juhos - * Copyright (C) 2008 Imre Kaloz - * - * 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 -#include - -#include - -// 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 */ diff --git a/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h b/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h deleted file mode 100644 index f0567dd64a..0000000000 --- a/package/boot/uboot-ar71xx/files/drivers/net/phy/rtl8366.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * (C) Copyright 2010 - * Michael Kurz . - * - * 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<. - * - * 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 -#include -#include -#include -#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; -} diff --git a/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c b/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c deleted file mode 100644 index bbe27b16ef..0000000000 --- a/package/boot/uboot-ar71xx/files/drivers/spi/ar71xx_spi.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * (C) Copyright 2010 - * Michael Kurz - * - * 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 -#include -#include - -#include -#include -#include - -/*----------------------------------------------------------------------- - * 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; -} diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h deleted file mode 100644 index e8f3f61d27..0000000000 --- a/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx.h +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Atheros AR71xx SoC specific definitions - * - * Copyright (C) 2008-2009 Gabor Juhos - * Copyright (C) 2008 Imre Kaloz - * - * 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 -#include -#include - -#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 */ diff --git a/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h b/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h deleted file mode 100644 index c92364b881..0000000000 --- a/package/boot/uboot-ar71xx/files/include/asm-mips/ar71xx_gpio.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * (C) Copyright 2010 - * Michael Kurz . - * - * 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 -#include - -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 */ diff --git a/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h b/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h deleted file mode 100644 index dd9b4c38af..0000000000 --- a/package/boot/uboot-ar71xx/files/include/configs/nbg460n.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * (C) Copyright 2010 - * Michael Kurz . - * - * 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 -#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 -#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 */ diff --git a/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/Makefile b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/Makefile new file mode 100644 index 0000000000..b0a385babf --- /dev/null +++ b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/Makefile @@ -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 + +######################################################################### diff --git a/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/config.mk b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/config.mk new file mode 100644 index 0000000000..e042e78bf8 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/config.mk @@ -0,0 +1 @@ +TEXT_BASE = 0x81E00000 diff --git a/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/lowlevel_init.S b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/lowlevel_init.S new file mode 100644 index 0000000000..83084c8d48 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/lowlevel_init.S @@ -0,0 +1,39 @@ +/* + * (C) Copyright 2010 + * Michael Kurz . + * + * 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 +#include +#include +#include +#include + + + +.globl lowlevel_init +/* + All done by Bootbase, nothing to do +*/ +lowlevel_init: + jr ra + nop + diff --git a/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/nbg460n.c b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/nbg460n.c new file mode 100644 index 0000000000..03a479d522 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/nbg460n.c @@ -0,0 +1,96 @@ +/* + * (C) Copyright 2010 + * Michael Kurz . + * + * 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 +#include +#include +#include +#include +#include +#include + +#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; +} diff --git a/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/u-boot.lds b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/u-boot.lds new file mode 100644 index 0000000000..8dc2b764c7 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/board/zyxel/nbg460n/u-boot.lds @@ -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 = .; +} diff --git a/package/boot/uboot-ar71xx/src/cpu/mips/ar71xx_serial.c b/package/boot/uboot-ar71xx/src/cpu/mips/ar71xx_serial.c new file mode 100644 index 0000000000..f093318952 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/cpu/mips/ar71xx_serial.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2010 + * Michael Kurz . + * + * 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 +#include +#include +#include + +#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++); + } +} diff --git a/package/boot/uboot-ar71xx/src/drivers/net/ag71xx.c b/package/boot/uboot-ar71xx/src/drivers/net/ag71xx.c new file mode 100644 index 0000000000..b3324c0197 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/drivers/net/ag71xx.c @@ -0,0 +1,809 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2010 Michael Kurz + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include + +#include + +#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; +} diff --git a/package/boot/uboot-ar71xx/src/drivers/net/ag71xx.h b/package/boot/uboot-ar71xx/src/drivers/net/ag71xx.h new file mode 100644 index 0000000000..edce429749 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/drivers/net/ag71xx.h @@ -0,0 +1,374 @@ +/* + * Atheros AR71xx built-in ethernet mac driver + * + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include + +#include + +// 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 */ diff --git a/package/boot/uboot-ar71xx/src/drivers/net/phy/rtl8366.h b/package/boot/uboot-ar71xx/src/drivers/net/phy/rtl8366.h new file mode 100644 index 0000000000..f0567dd64a --- /dev/null +++ b/package/boot/uboot-ar71xx/src/drivers/net/phy/rtl8366.h @@ -0,0 +1,188 @@ +/* + * (C) Copyright 2010 + * Michael Kurz . + * + * 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<. + * + * 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 +#include +#include +#include +#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; +} diff --git a/package/boot/uboot-ar71xx/src/drivers/spi/ar71xx_spi.c b/package/boot/uboot-ar71xx/src/drivers/spi/ar71xx_spi.c new file mode 100644 index 0000000000..bbe27b16ef --- /dev/null +++ b/package/boot/uboot-ar71xx/src/drivers/spi/ar71xx_spi.c @@ -0,0 +1,191 @@ +/* + * (C) Copyright 2010 + * Michael Kurz + * + * 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 +#include +#include + +#include +#include +#include + +/*----------------------------------------------------------------------- + * 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; +} diff --git a/package/boot/uboot-ar71xx/src/include/asm-mips/ar71xx.h b/package/boot/uboot-ar71xx/src/include/asm-mips/ar71xx.h new file mode 100644 index 0000000000..e8f3f61d27 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/include/asm-mips/ar71xx.h @@ -0,0 +1,515 @@ +/* + * Atheros AR71xx SoC specific definitions + * + * Copyright (C) 2008-2009 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include + +#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 */ diff --git a/package/boot/uboot-ar71xx/src/include/asm-mips/ar71xx_gpio.h b/package/boot/uboot-ar71xx/src/include/asm-mips/ar71xx_gpio.h new file mode 100644 index 0000000000..c92364b881 --- /dev/null +++ b/package/boot/uboot-ar71xx/src/include/asm-mips/ar71xx_gpio.h @@ -0,0 +1,65 @@ +/* + * (C) Copyright 2010 + * Michael Kurz . + * + * 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 +#include + +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 */ diff --git a/package/boot/uboot-ar71xx/src/include/configs/nbg460n.h b/package/boot/uboot-ar71xx/src/include/configs/nbg460n.h new file mode 100644 index 0000000000..dd9b4c38af --- /dev/null +++ b/package/boot/uboot-ar71xx/src/include/configs/nbg460n.h @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2010 + * Michael Kurz . + * + * 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 +#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 +#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 */ diff --git a/target/linux/ar71xx/image/legacy.mk b/target/linux/ar71xx/image/legacy.mk index f80b700be8..d2f05e993e 100644 --- a/target/linux/ar71xx/image/legacy.mk +++ b/target/linux/ar71xx/image/legacy.mk @@ -761,24 +761,24 @@ define Image/Build/NetgearNAND $(call Image/Build/SysupgradeNAND,$(2),squashfs,$(KDIR_TMP)/vmlinux-$(2).uImage) endef +ZYXEL_UBOOT = $(KDIR)/u-boot-nbg460n_550n_550nh.bin +ZYXEL_UBOOT_BIN = $(wildcard $(BIN_DIR)/u-boot-nbg460n_550n_550nh/u-boot.bin) -ifdef CONFIG_PACKAGE_uboot-ar71xx-nbg460n_550n_550nh - Image/Build/ZyXEL/buildkernel=$(call MkuImageLzma,$(2),$(3)) +Image/Build/ZyXEL/buildkernel=$(call MkuImageLzma,$(2),$(3)) - define Image/Build/ZyXEL +define Image/Build/ZyXEL $(call Sysupgrade/KRuImage,$(1),$(2),917504,2752512) if [ -e "$(call sysupname,$(1),$(2))" ]; then \ - if [ ! -f $(BIN_DIR)/$(IMG_PREFIX)-$(2)-u-boot.bin ]; then \ - echo "Warning: $(IMG_PREFIX)-$(2)-u-boot.bin not found" >&2; \ + if [ ! -f $(ZYXEL_UBOOT) ]; then \ + echo "Warning: $(ZYXEL_UBOOT) not found" >&2; \ else \ $(STAGING_DIR_HOST)/bin/mkzynfw \ -B $(4) \ - -b $(BIN_DIR)/$(IMG_PREFIX)-$(2)-u-boot.bin \ + -b $(ZYXEL_UBOOT) \ -r $(call sysupname,$(1),$(2)):0x10000 \ -o $(call factoryname,$(1),$(2)); \ fi; fi - endef -endif +endef define Image/Build/ZyXELNAND/buildkernel $(eval kernelsize=$(call mtdpartsize,kernel,$(5))) @@ -1044,6 +1044,7 @@ define Image/Build/squashfs endef define Image/Prepare + $(if $(wildcard $(ZYXEL_UBOOT_BIN)),cp $(ZYXEL_UBOOT_BIN) $(ZYXEL_UBOOT)) $(call CompressLzma,$(KDIR)/vmlinux,$(KDIR)/vmlinux.bin.lzma) ifneq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),) $(call CompressLzma,$(KDIR)/vmlinux-initramfs,$(KDIR)/vmlinux-initramfs.bin.lzma)