diff options
author | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-10-05 10:12:53 +0000 |
---|---|---|
committer | blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-10-05 10:12:53 +0000 |
commit | 5c105d9f3fd086aff195d3849dcf847d6b0bd927 (patch) | |
tree | 1229a11f725bfa58aa7c57a76898553bb5f6654a /target/linux/brcm63xx | |
download | openwrt-5c105d9f3fd086aff195d3849dcf847d6b0bd927.tar.gz openwrt-5c105d9f3fd086aff195d3849dcf847d6b0bd927.zip |
branch Attitude Adjustment
git-svn-id: svn://svn.openwrt.org/openwrt/branches/attitude_adjustment@33625 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/brcm63xx')
165 files changed, 17852 insertions, 0 deletions
diff --git a/target/linux/brcm63xx/Makefile b/target/linux/brcm63xx/Makefile new file mode 100644 index 000000000..098820f40 --- /dev/null +++ b/target/linux/brcm63xx/Makefile @@ -0,0 +1,27 @@ +# +# Copyright (C) 2006-2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk + +ARCH:=mips +BOARD:=brcm63xx +BOARDNAME:=Broadcom BCM63xx +FEATURES:=squashfs jffs2 usb atm pci pcmcia +LINUX_VERSION:=3.3.8 +MAINTAINER:=Florian Fainelli <florian@openwrt.org> + +include $(INCLUDE_DIR)/target.mk + +DEFAULT_PACKAGES += kmod-switch kmod-input-gpio-keys-polled \ + kmod-button-hotplug + +define Target/Description + Build firmware images for Broadcom based xDSL/routers + currently supports BCM6338, BCM6348 and BCM6358 based devices. + (e.g. Inventel Livebox, Siemens SE515, Neufbox 4) +endef + +$(eval $(call BuildTarget)) diff --git a/target/linux/brcm63xx/base-files.mk b/target/linux/brcm63xx/base-files.mk new file mode 100644 index 000000000..d6682bd38 --- /dev/null +++ b/target/linux/brcm63xx/base-files.mk @@ -0,0 +1,5 @@ +define Package/base-files/install-target + rm -f $(1)/etc/config/network +endef + + diff --git a/target/linux/brcm63xx/base-files/etc/diag.sh b/target/linux/brcm63xx/base-files/etc/diag.sh new file mode 100755 index 000000000..d492cd553 --- /dev/null +++ b/target/linux/brcm63xx/base-files/etc/diag.sh @@ -0,0 +1,71 @@ +#!/bin/sh +# +# Copyright (C) 2007 OpenWrt.org +# +# + +. /lib/brcm63xx.sh + +led_set_attr() { + [ -f "/sys/class/leds/$1/$2" ] && echo "$3" > "/sys/class/leds/$1/$2" +} + +status_led_set_timer() { + led_set_attr $status_led "trigger" "timer" + led_set_attr $status_led "delay_on" "$1" + led_set_attr $status_led "delay_off" "$2" + [ -n "$status_led2" ] && { + led_set_attr $status_led2 "trigger" "timer" + led_set_attr $status_led2 "delay_on" "$1" + led_set_attr $status_led2 "delay_off" "$2" + } +} + +status_led_set_morse() { + led_set_attr $status_led "trigger" "morse" + led_set_attr $status_led "delay" "$1" + led_set_attr $status_led "message" "$2" + [ -n "$status_led2" ] && { + led_set_attr $status_led2 "trigger" "morse" + led_set_attr $status_led2 "delay" "$1" + led_set_attr $status_led2 "message" "$2" + } +} + +status_led_on() { + led_set_attr $status_led "trigger" "none" + led_set_attr $status_led "brightness" 255 + [ -n "$status_led2" ] && { + led_set_attr $status_led2 "trigger" "none" + led_set_attr $status_led2 "brightness" 255 + } +} + +status_led_off() { + led_set_attr $status_led "trigger" "none" + led_set_attr $status_led "brightness" 0 + [ -n "$status_led2" ] && { + led_set_attr $status_led2 "trigger" "none" + led_set_attr $status_led2 "brightness" 0 + } +} + +set_state() { + case "$1" in + preinit) + insmod leds-gpio + status_led_on + status_led_set_timer 200 200 + ;; + failsafe) + status_led_set_timer 50 50 + ;; + done) + if [ "${status_led/power}" != "$status_led" ]; then + status_led_on + else + status_led_off + fi + ;; + esac +} diff --git a/target/linux/brcm63xx/base-files/etc/init.d/defconfig b/target/linux/brcm63xx/base-files/etc/init.d/defconfig new file mode 100755 index 000000000..a49c32785 --- /dev/null +++ b/target/linux/brcm63xx/base-files/etc/init.d/defconfig @@ -0,0 +1,18 @@ +#!/bin/sh /etc/rc.common +# +# Copyright (C) 2009 OpenWrt.org +# + +START=05 + +start() { + . /lib/brcm63xx.sh + + [ ! -d /etc/defconfig/$board_name ] && board_name="generic" + + for f in $( ls /etc/defconfig/$board_name ); do + if [ ! -e /etc/config/$f ]; then + cp /etc/defconfig/$board_name/$f /etc/config/ + fi + done +} diff --git a/target/linux/brcm63xx/base-files/etc/uci-defaults/brcm63xx_fixcrc.sh b/target/linux/brcm63xx/base-files/etc/uci-defaults/brcm63xx_fixcrc.sh new file mode 100755 index 000000000..f5b6d440e --- /dev/null +++ b/target/linux/brcm63xx/base-files/etc/uci-defaults/brcm63xx_fixcrc.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# +# Copyright (C) 2007 OpenWrt.org +# +# + +. /lib/brcm63xx.sh + +do_fixcrc() { + mtd fixtrx linux +} + +brcm63xx_detect + +case "$board_name" in + 96328avng |\ + 963281TAN |\ + "CPVA502+" |\ + AW4339U |\ + CPVA642 |\ + CT6373-1 |\ + MAGIC |\ + V2110 |\ + V2500V_BB) + do_fixcrc + ;; +esac + diff --git a/target/linux/brcm63xx/base-files/etc/uci-defaults/network b/target/linux/brcm63xx/base-files/etc/uci-defaults/network new file mode 100755 index 000000000..53c29ac5a --- /dev/null +++ b/target/linux/brcm63xx/base-files/etc/uci-defaults/network @@ -0,0 +1,54 @@ +#!/bin/sh +# +# Copyright (C) 2012 OpenWrt.org +# + +[ -e /etc/config/network ] && exit 0 + +touch /etc/config/network + +. /lib/functions/uci-defaults.sh +. /lib/brcm63xx.sh + +ucidef_set_interface_loopback + +case "$board_name" in + +96328avng |\ +963281TAN |\ +96348A-122 |\ +96358-502V |\ +CT6373-1 |\ +AW4339U |\ +CPVA642 |\ +CT536_CT5621 |\ +D-4P-W |\ +NB6 |\ +SPW303V |\ +SPW500V |\ +V2110 |\ +96348W3) + ucidef_set_interface_lan "eth0" + ;; + +AW4139) + ucidef_set_interface_lan "eth0.1" + ucidef_add_switch "eth0" "1" "1" + ucidef_add_switch_vlan "eth0" "1" "0 1 2 3 4 5t" + ;; + +DVG3810BN) + ucidef_set_interfaces_lan_wan "eth1.1" "eth0" + ucidef_add_switch "eth1" "1" "1" + ucidef_add_switch_vlan "eth1" "1" "0 1 2 3 4 5t" + ;; + +*) + ucidef_set_interfaces_lan_wan "eth1" "eth0" + ;; + +esac + +uci commit network + +exit 0 diff --git a/target/linux/brcm63xx/base-files/lib/brcm63xx.sh b/target/linux/brcm63xx/base-files/lib/brcm63xx.sh new file mode 100755 index 000000000..11774770d --- /dev/null +++ b/target/linux/brcm63xx/base-files/lib/brcm63xx.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# +# Copyright (C) 2007 OpenWrt.org +# +# + +board_name="" +status_led="" +status_led2="" +sys_mtd_part="" +brcm63xx_has_reset_button="" + +brcm63xx_detect() { + board_name=$(awk 'BEGIN{FS="[ \t:/]+"} /system type/ {print $4}' /proc/cpuinfo) + + if [ "$board_name" = "96358VW" ] && [ -e /proc/switch/eth1/enable ]; then + board_name="DVAG3810BN" + fi + + case "$board_name" in + 96328avng) + status_led="96328avng::power" + ifname=eth0 + ;; + 963281TAN) + status_led="963281TAN::power" + ifname=eth0 + ;; + 96348GW) + status_led="power" + brcm63xx_has_reset_button="true" + ifname=eth1 + ;; + GW6000) + brcm63xx_has_reset_button="true" + ifname=eth1 + ;; + GW6200) + status_led="line1" + status_led2="tel" + brcm63xx_has_reset_button="true" + ifname=eth1 + ;; + 96348GW-11) + status_led="power" + brcm63xx_has_reset_button="true" + ifname=eth1 + ;; + CT536_CT5621) + status_led="power" + brcm63xx_has_reset_button="true" + ifname=eth0 + ;; + SPW500V) + status_led="power:green" + brcm63xx_has_reset_button="true" + ifname=eth0 + ;; + AW4139 |\ + AW4339U) + status_led="dsl-274xb:green:power" + brcm63xx_has_reset_button="true" + ifname=eth0 + ;; + 96358-502V) + status_led="spw303v:green:power+adsl" + brcm63xx_has_reset_button="true" + ifname=eth0 + ;; + V2110) + status_led="V2110:power:green" + brcm63xx_has_reset_button="true" + ifname=eth0 + ;; + CPVA642) + status_led="power:green" + brcm63xx_has_reset_button="true" + ifname=eth0 + ;; + D-4P-W) + status_led="power:green" + brcm63xx_has_reset_button="true" + ifname=eth0 + ;; + NB6) + brcm63xx_has_reset_button="true" + ifname=eth0 + ;; + *) + ;; + esac +} + +brcm63xx_detect diff --git a/target/linux/brcm63xx/base-files/lib/preinit/03_do_brcm63xx.sh b/target/linux/brcm63xx/base-files/lib/preinit/03_do_brcm63xx.sh new file mode 100644 index 000000000..dd60c4995 --- /dev/null +++ b/target/linux/brcm63xx/base-files/lib/preinit/03_do_brcm63xx.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +do_brcm63xx() { + . /lib/brcm63xx.sh +} + +boot_hook_add preinit_main do_brcm63xx diff --git a/target/linux/brcm63xx/base-files/lib/preinit/05_failsafe_config_switch_brcm63xx b/target/linux/brcm63xx/base-files/lib/preinit/05_failsafe_config_switch_brcm63xx new file mode 100644 index 000000000..43da8cc06 --- /dev/null +++ b/target/linux/brcm63xx/base-files/lib/preinit/05_failsafe_config_switch_brcm63xx @@ -0,0 +1,15 @@ +#!/bin/sh + +failsafe_ip() { + [ -d "/proc/switch/$ifname" ] && { + ifconfig "$ifname" 0.0.0.0 down + echo "0 1 2 3 4 ${cpu_port:-5u*}" > "/proc/switch/$ifname/vlan/0/ports" + } + + [ -n "$pi_ifname" ] && grep -q "$pi_ifname" /proc/net/dev && { + ifconfig $pi_ifname $pi_ip netmask $pi_netmask broadcast $pi_broadcast up + } +} + +boot_hook_add failsafe failsafe_ip + diff --git a/target/linux/brcm63xx/base-files/lib/preinit/05_init_interfaces_brcm63xx b/target/linux/brcm63xx/base-files/lib/preinit/05_init_interfaces_brcm63xx new file mode 100644 index 000000000..b7cbecd4f --- /dev/null +++ b/target/linux/brcm63xx/base-files/lib/preinit/05_init_interfaces_brcm63xx @@ -0,0 +1,26 @@ +#!/bin/sh + +set_preinit_iface() { + ifname=eth1 + + . /lib/brcm63xx.sh + + ifconfig $ifname 0.0.0.0 up +} + +check_module () { + module="$1"; shift; params="$*" + + insmod "$module" "$params" + sleep 1 + grep "^$module" /proc/modules + return $? +} + +init_iface() { + insmod switch-core + check_module switch-robo || check_module switch-adm || rmmod switch-core +} + +boot_hook_add preinit_main set_preinit_iface +boot_hook_add preinit_main init_iface diff --git a/target/linux/brcm63xx/base-files/lib/preinit/05_reset_button_brcm63xx b/target/linux/brcm63xx/base-files/lib/preinit/05_reset_button_brcm63xx new file mode 100644 index 000000000..f33825f96 --- /dev/null +++ b/target/linux/brcm63xx/base-files/lib/preinit/05_reset_button_brcm63xx @@ -0,0 +1,16 @@ +#!/bin/sh + +. /lib/brcm63xx.sh + +enable_reset_button() { + if [ "$brcm63xx_has_reset_button" = "true" ]; then + insmod input-core + insmod input-polldev + insmod gpio_buttons + insmod button-hotplug + fi +} + +boot_hook_add preinit_main enable_reset_button + + diff --git a/target/linux/brcm63xx/base-files/lib/preinit/15_set_preinit_interface_brcm63xx b/target/linux/brcm63xx/base-files/lib/preinit/15_set_preinit_interface_brcm63xx new file mode 100644 index 000000000..9d366fa33 --- /dev/null +++ b/target/linux/brcm63xx/base-files/lib/preinit/15_set_preinit_interface_brcm63xx @@ -0,0 +1,44 @@ +#!/bin/sh + +port_net_echo() { + [ -n "$pi_ifname" ] && grep -q "$pi_ifname" /proc/net/dev && { + if [ "$pi_preinit_net_messages" = "y" ] || [ "$pi_failsafe_net_message" = "true" ] && [ "$pi_preinit_no_failsafe_netmsg" != "y" ]; then + netmsg $pi_broadcast "$1" + fi + } +} + +preinit_ip_deconfig() { + if [ -z "$pi_ifname" ]; then + ifconfig $ifname 0.0.0.0 down + else + grep -q "$pi_ifname" /proc/net/dev && { + ifconfig $pi_ifname 0.0.0.0 down + } + fi + [ -d "/proc/switch/$ifname" ] && { + echo 1 > "/proc/switch/$ifname/reset" + echo "0 1 2 3 4 ${cpu_port:-5u*}" > "/proc/switch/$ifname/vlan/0/ports" + } + +} + +preinit_net_echo() { + preinit_ip + + [ -d "/proc/switch/$ifname" ] && { + echo 1 > "/proc/switch/$ifname/reset" + + # this would be easier if we blasted the message across all ports + # but we don't want packets leaking across interfaces + for port in $(seq 0 4); do { + echo "$port ${cpu_port:-5u*}" > "/proc/switch/$ifname/vlan/0/ports" + port_net_echo $1 + }; done + + echo "0 ${cpu_port:-5u*}" > "/proc/switch/$ifname/vlan/0/ports" + + } || port_net_echo $1 +} + + diff --git a/target/linux/brcm63xx/base-files/lib/preinit/20_failsafe_net_echo_brcm63xx b/target/linux/brcm63xx/base-files/lib/preinit/20_failsafe_net_echo_brcm63xx new file mode 100644 index 000000000..f030cb283 --- /dev/null +++ b/target/linux/brcm63xx/base-files/lib/preinit/20_failsafe_net_echo_brcm63xx @@ -0,0 +1,12 @@ +#!/bin/sh + +indicate_failsafe() { + preinit_net_echo() { + port_net_echo $1 + } + echo "- failsafe -" + preinit_net_echo "Entering Failsafe!\n" + indicate_failsafe_led +} + + diff --git a/target/linux/brcm63xx/base-files/lib/upgrade/platform.sh b/target/linux/brcm63xx/base-files/lib/upgrade/platform.sh new file mode 100644 index 000000000..1a025f7d7 --- /dev/null +++ b/target/linux/brcm63xx/base-files/lib/upgrade/platform.sh @@ -0,0 +1,16 @@ +PART_NAME=linux +platform_check_image() { + [ "$ARGC" -gt 1 ] && return 1 + case "$(get_magic_word "$1")" in + 3600) + # 6348GW-11 boards use openwrt-96348GW-11-squashfs-cfe.bin files + return 0 + ;; + *) + echo "Invalid image type. Please use only .bin files" + return 1 + ;; + esac +} + +# use default for platform_do_upgrade() diff --git a/target/linux/brcm63xx/config-3.3 b/target/linux/brcm63xx/config-3.3 new file mode 100644 index 000000000..f8cf4869c --- /dev/null +++ b/target/linux/brcm63xx/config-3.3 @@ -0,0 +1,161 @@ +CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y +CONFIG_ARCH_DISCARD_MEMBLOCK=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_REQUIRE_GPIOLIB=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_AUDIT=y +CONFIG_AUDIT_GENERIC=y +CONFIG_BCM63XX=y +CONFIG_BCM63XX_CPU_6328=y +CONFIG_BCM63XX_CPU_6338=y +CONFIG_BCM63XX_CPU_6345=y +CONFIG_BCM63XX_CPU_6348=y +CONFIG_BCM63XX_CPU_6358=y +CONFIG_BCM63XX_CPU_6362=y +CONFIG_BCM63XX_CPU_6368=y +CONFIG_BCM63XX_ENET=y +CONFIG_BCM63XX_PHY=y +CONFIG_BCM63XX_WDT=y +CONFIG_BCMA_POSSIBLE=y +CONFIG_BOARD_BCM963XX=y +# CONFIG_BOARD_LIVEBOX is not set +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_CEVT_R4K=y +CONFIG_CEVT_R4K_LIB=y +CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 noinitrd console=ttyS0,115200" +CONFIG_CMDLINE_BOOL=y +# CONFIG_CMDLINE_OVERRIDE is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_CPU_HAS_PREFETCH=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_CPU_MIPS32=y +CONFIG_CPU_MIPS32_R1=y +CONFIG_CPU_MIPSR1=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_CRAMFS=y +CONFIG_CSRC_R4K=y +CONFIG_CSRC_R4K_LIB=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DMA_NONCOHERENT=y +CONFIG_EARLY_PRINTK=y +CONFIG_ELF_CORE=y +CONFIG_FIRMWARE_IN_KERNEL=y +CONFIG_GENERIC_ATOMIC64=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y +CONFIG_GENERIC_CMOS_UPDATE=y +CONFIG_GENERIC_GPIO=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GPIOLIB=y +CONFIG_GPIO_74X164=y +CONFIG_GPIO_DEVICE=y +CONFIG_GPIO_SYSFS=y +# CONFIG_HAMRADIO is not set +CONFIG_HARDWARE_WATCHPOINTS=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_HAVE_ARCH_KGDB=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_DMA_ATTRS=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=y +CONFIG_HAVE_GENERIC_HARDIRQS=y +CONFIG_HAVE_IDE=y +CONFIG_HAVE_IRQ_WORK=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_HAVE_MEMBLOCK_NODE_MAP=y +CONFIG_HAVE_OPROFILE=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_HW_HAS_PCI=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_BCM63XX=y +CONFIG_HZ=250 +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +CONFIG_IMAGE_CMDLINE_HACK=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +CONFIG_IRQ_CPU=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_KEXEC=y +CONFIG_LEDS_GPIO=y +CONFIG_M25PXX_USE_FAST_READ=y +CONFIG_MDIO_BOARDINFO=y +CONFIG_MIPS=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 +# CONFIG_MIPS_MACHINE is not set +CONFIG_MIPS_MT_DISABLED=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MTD_BCM63XX_PARTS=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_BE_BYTE_SWAP=y +# CONFIG_MTD_CFI_GEOMETRY is not set +# CONFIG_MTD_CFI_NOSWAP is not set +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_M25P80=y +CONFIG_MTD_PHYSMAP=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y +CONFIG_PAGEFLAGS_EXTENDED=y +CONFIG_PCI=y +# CONFIG_PCIEAER is not set +CONFIG_PCIEPORTBUS=y +CONFIG_PCI_DOMAINS=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PHYLIB=y +CONFIG_RTL8366_SMI=y +CONFIG_RTL8367_PHY=y +CONFIG_POSIX_MQUEUE=y +CONFIG_POSIX_MQUEUE_SYSCTL=y +# CONFIG_PREEMPT_RCU is not set +CONFIG_RELAY=y +# CONFIG_SCSI_DMA is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_BCM63XX=y +CONFIG_SERIAL_BCM63XX_CONSOLE=y +CONFIG_SPI=y +# CONFIG_SPI_BCM63XX is not set +CONFIG_SPI_BCM63XX_HSSPI=y +CONFIG_SPI_BITBANG=y +CONFIG_SPI_GPIO=y +CONFIG_SPI_MASTER=y +CONFIG_SQUASHFS_EMBEDDED=y +CONFIG_SSB=y +CONFIG_SSB_B43_PCI_BRIDGE=y +CONFIG_SSB_BLOCKIO=y +# CONFIG_SSB_DRIVER_MIPS is not set +CONFIG_SSB_DRIVER_PCICORE=y +CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y +CONFIG_SSB_PCIHOST=y +CONFIG_SSB_PCIHOST_POSSIBLE=y +CONFIG_SSB_SPROM=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_SWCONFIG=y +CONFIG_SYS_HAS_CPU_MIPS32_R1=y +CONFIG_SYS_HAS_EARLY_PRINTK=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_ARBIT_HZ=y +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_USB_ARCH_HAS_XHCI=y +CONFIG_USB_SUPPORT=y +CONFIG_VM_EVENT_COUNTERS=y +CONFIG_WATCHDOG_NOWAYOUT=y +CONFIG_XZ_DEC=y +CONFIG_ZONE_DMA_FLAG=0 diff --git a/target/linux/brcm63xx/files/arch/mips/include/asm/mach-bcm63xx/bcm_tag.h b/target/linux/brcm63xx/files/arch/mips/include/asm/mach-bcm63xx/bcm_tag.h new file mode 100644 index 000000000..2730edc9a --- /dev/null +++ b/target/linux/brcm63xx/files/arch/mips/include/asm/mach-bcm63xx/bcm_tag.h @@ -0,0 +1,70 @@ +#ifndef __BCM63XX_TAG_H +#define __BCM63XX_TAG_H + +#define TAGVER_LEN 4 /* Length of Tag Version */ +#define TAGLAYOUT_LEN 4 /* Length of FlashLayoutVer */ +#define SIG1_LEN 20 /* Company Signature 1 Length */ +#define SIG2_LEN 14 /* Company Signature 2 Lenght */ +#define BOARDID_LEN 16 /* Length of BoardId */ +#define ENDIANFLAG_LEN 2 /* Endian Flag Length */ +#define CHIPID_LEN 6 /* Chip Id Length */ +#define IMAGE_LEN 10 /* Length of Length Field */ +#define ADDRESS_LEN 12 /* Length of Address field */ +#define DUALFLAG_LEN 2 /* Dual Image flag Length */ +#define INACTIVEFLAG_LEN 2 /* Inactie Flag Length */ +#define RSASIG_LEN 20 /* Length of RSA Signature in tag */ +#define TAGINFO1_LEN 30 /* Length of vendor information field1 in tag */ +#define FLASHLAYOUTVER_LEN 4 /* Length of Flash Layout Version String tag */ +#define TAGINFO2_LEN 16 /* Length of vendor information field2 in tag */ +#define CRC_LEN 4 /* Length of CRC in bytes */ +#define ALTTAGINFO_LEN 54 /* Alternate length for vendor information; Pirelli */ + +#define NUM_PIRELLI 2 +#define IMAGETAG_CRC_START 0xFFFFFFFF + +#define PIRELLI_BOARDS { \ + "AGPF-S0", \ + "DWV-S0", \ +} + +/* + * The broadcom firmware assumes the rootfs starts the image, + * therefore uses the rootfs start (flashImageAddress) + * to determine where to flash the image. Since we have the kernel first + * we have to give it the kernel address, but the crc uses the length + * associated with this address (rootLength), which is added to the kernel + * length (kernelLength) to determine the length of image to flash and thus + * needs to be rootfs + deadcode (jffs2 EOF marker) +*/ + +struct bcm_tag { + char tagVersion[TAGVER_LEN]; // 0-3: Version of the image tag + char sig_1[SIG1_LEN]; // 4-23: Company Line 1 + char sig_2[SIG2_LEN]; // 24-37: Company Line 2 + char chipid[CHIPID_LEN]; // 38-43: Chip this image is for + char boardid[BOARDID_LEN]; // 44-59: Board name + char big_endian[ENDIANFLAG_LEN]; // 60-61: Map endianness -- 1 BE 0 LE + char totalLength[IMAGE_LEN]; // 62-71: Total length of image + char cfeAddress[ADDRESS_LEN]; // 72-83: Address in memory of CFE + char cfeLength[IMAGE_LEN]; // 84-93: Size of CFE + char flashImageStart[ADDRESS_LEN]; // 94-105: Address in memory of image start (kernel for OpenWRT, rootfs for stock firmware) + char flashRootLength[IMAGE_LEN]; // 106-115: Size of rootfs for flashing + char kernelAddress[ADDRESS_LEN]; // 116-127: Address in memory of kernel + char kernelLength[IMAGE_LEN]; // 128-137: Size of kernel + char dualImage[DUALFLAG_LEN]; // 138-139: Unused at present + char inactiveFlag[INACTIVEFLAG_LEN]; // 140-141: Unused at present + char rsa_signature[RSASIG_LEN]; // 142-161: RSA Signature (unused at present; some vendors may use this) + char information1[TAGINFO1_LEN]; // 162-191: Compilation and related information (not generated/used by OpenWRT) + char flashLayoutVer[FLASHLAYOUTVER_LEN];// 192-195: Version flash layout + char fskernelCRC[CRC_LEN]; // 196-199: kernel+rootfs CRC32 + char information2[TAGINFO2_LEN]; // 200-215: Unused at present except Alice Gate where is is information + char imageCRC[CRC_LEN]; // 216-219: CRC32 of image less imagetag (kernel for Alice Gate) + char rootfsCRC[CRC_LEN]; // 220-223: CRC32 of rootfs partition + char kernelCRC[CRC_LEN]; // 224-227: CRC32 of kernel partition + char imageSequence[4]; // 228-231: Image sequence number + char rootLength[4]; // 232-235: steal from reserved1 to keep the real root length so we can use in the flash map even after we have change the rootLength to 0 to satisfy devices that check CRC on every boot + char headerCRC[CRC_LEN]; // 236-239: CRC32 of header excluding tagVersion + char reserved2[16]; // 240-255: Unused at present +}; + +#endif /* __BCM63XX_TAG_H */ diff --git a/target/linux/brcm63xx/image/Makefile b/target/linux/brcm63xx/image/Makefile new file mode 100644 index 000000000..af5a68c82 --- /dev/null +++ b/target/linux/brcm63xx/image/Makefile @@ -0,0 +1,259 @@ +# +# Copyright (C) 2006-2011 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/image.mk + +LOADADDR = 0x80010000 # RAM start + 16M +KERNEL_ENTRY = $(LOADADDR) # Newer kernels add a jmp to the kernel_entry at the start of the binary +RAMSIZE = 0x01000000 # 64MB + +LOADER_MAKEOPTS= \ + KDIR=$(KDIR) \ + LOADADDR=$(LOADADDR) \ + KERNEL_ENTRY=$(KERNEL_ENTRY) \ + RAMSIZE=$(RAMSIZE) + +define trxalign/jffs2-128k +-a 0x20000 +endef +define trxalign/jffs2-64k +-a 0x10000 +endef +define trxalign/squashfs +-a 1024 +endef + +define Image/LimitName16 +$(shell expr substr "$(1)" 1 16) +endef + +define Image/Build/CFE + # Generate the tagged image + $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ + --output $(BIN_DIR)/openwrt-$(4)-$(1)-cfe.bin \ + --boardid $(2) --chipid $(3) --entry $(KERNEL_ENTRY) \ + --load-addr $(LOADADDR) --rsa-signature "$(5)" \ + --info1 "-$(call Image/LimitName16,$(4))" --info2 $(1) \ + $(6) $(7) $(8) $(9) +endef + +define Image/Build/CFEFIXUP + # Generate the tagged image + $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ + --output $(BIN_DIR)/openwrt-$(5)-$(1)-cfe.bin \ + --boardid $(2) --chipid $(4) --entry $(KERNEL_ENTRY) \ + --load-addr $(LOADADDR) --rsa-signature "$(6)" \ + --info1 "+$(call Image/LimitName16,$(3))" --info2 $(1) \ + $(7) $(8) $(9) $(10) +endef + +define Image/Build/CFEHW553 + # Generate the tagged image + $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ + --output $(BIN_DIR)/openwrt-$(5)-$(1)-cfe.bin \ + --boardid $(2) --chipid $(3) --entry $(LOADADDR) \ + --load-addr $(LOADADDR) --tag-version 7 \ + --block-size 0x20000 --image-offset $(4) +endef + +define Image/Build/CFEAGPF + # Generate the tagged image + $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ + --output $(BIN_DIR)/openwrt-$(5)-$(1)-cfe.bin \ + --boardid $(2) --chipid $(3) --entry $(LOADADDR) \ + --load-addr $(LOADADDR) --tag-version 8 \ + --signature2 IMAGE --block-size 0x20000 \ + --image-offset $(4) --info1 "-$(call Image/LimitName16,$(5))" --info2 $(1) +endef + +define Image/Build/RG100A + # Generate the tagged image + $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ + --output $(BIN_DIR)/openwrt-$(5)-$(1)-cfe.bin \ + --boardid $(2) --chipid $(3) --entry $(LOADADDR) \ + --load-addr $(LOADADDR) --block-size 0x20000 \ + --image-offset $(4) --info1 "-$(call Image/LimitName16,$(5))" --info2 $(1) +endef + +define Image/Build/RedBoot + cp $(KDIR)/vmlinux.elf $(BIN_DIR)/openwrt-$(1)-vmlinux.elf + gzip -9 -c $(KDIR)/vmlinux > $(KDIR)/vmlinux.bin.gz + $(STAGING_DIR_HOST)/bin/lzma e $(KDIR)/vmlinux $(KDIR)/vmlinux.bin.l7 + dd if=$(KDIR)/vmlinux.bin.l7 of=$(BIN_DIR)/openwrt-$(1)-vmlinux.lzma bs=65536 conv=sync + dd if=$(KDIR)/vmlinux.bin.gz of=$(BIN_DIR)/openwrt-$(1)-vmlinux.gz bs=65536 conv=sync +endef + +define Image/Build/SPW303V + # Generate the tagged image + $(STAGING_DIR_HOST)/bin/imagetag -i $(KDIR)/vmlinux.lzma.cfe -f $(KDIR)/root.$(1) \ + --output $(BIN_DIR)/openwrt-$(4)-$(1)-cfe.bin.tmp \ + --boardid $(2) --chipid $(3) --entry $(KERNEL_ENTRY) \ + --load-addr $(LOADADDR) --rsa-signature "$(5)" \ + --pad 4 $(6) $(7) $(8) $(9) + # Fix up header + $(STAGING_DIR_HOST)/bin/spw303v -i $(BIN_DIR)/openwrt-$(4)-$(1)-cfe.bin.tmp \ + -o $(BIN_DIR)/openwrt-$(4)-$(1)-cfe-sysupgrade.bin + $(STAGING_DIR_HOST)/bin/xorimage -i $(BIN_DIR)/openwrt-$(4)-$(1)-cfe-sysupgrade.bin \ + -o $(BIN_DIR)/openwrt-$(4)-$(1)-cfe-factory.bin + rm -f $(BIN_DIR)/openwrt-$(4)-$(1)-cfe.bin.tmp +endef + +define Image/Build/CFEOLD + $(TOPDIR)/scripts/brcmImage.pl -t -p \ + -b $(2) -c $(3) \ + -k $(KDIR)/vmlinux.lzma.cfe \ + -r $(KDIR)/root.$(1) \ + -o $(BIN_DIR)/openwrt-$(2)-$(1)-cfe.bin +endef + +define Build/Clean + $(MAKE) -C lzma-loader clean +endef + +define Image/Prepare + # Standard LZMA kernel + cat $(KDIR)/vmlinux | $(STAGING_DIR_HOST)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $(KDIR)/vmlinux.lzma + + # CFE is a LZMA nazi! It took me hours to find out the parameters! + # Also I think lzma has a bug cause it generates different output depending on + # if you use stdin / stdout or not. Use files instead of stdio here, cause + # otherwise CFE will complain and not boot the image. + $(STAGING_DIR_HOST)/bin/lzma e -d22 -fb64 -a1 $(KDIR)/vmlinux $(KDIR)/vmlinux.lzma.tmp + + # Strip out the length, CFE doesn't like this + dd if=$(KDIR)/vmlinux.lzma.tmp of=$(KDIR)/vmlinux.lzma.cfe bs=5 count=1 + dd if=$(KDIR)/vmlinux.lzma.tmp of=$(KDIR)/vmlinux.lzma.cfe ibs=13 obs=5 skip=1 seek=1 conv=notrunc + rm -f $(KDIR)/vmlinux.lzma.tmp + + # Build the LZMA loader + rm -f $(KDIR)/loader.gz + $(MAKE) -C lzma-loader \ + BUILD_DIR="$(KDIR)" \ + TARGET="$(KDIR)" \ + clean install + + echo -ne "\\x00" >> $(KDIR)/loader.gz + rm -f $(KDIR)/fs_mark + touch $(KDIR)/fs_mark + $(call prepare_generic_squashfs,$(KDIR)/fs_mark) +endef + +define Image/Build + dd if=$(KDIR)/root.$(1) of=$(BIN_DIR)/$(IMG_PREFIX)-root.$(1) bs=128k conv=sync + # Various routers + $(call Image/Build/CFE,$(1),96328avng,6328,96328avng-4M-flash-generic,,--pad 2) + $(call Image/Build/CFE,$(1),96328avng,6328,96328avng-8M-flash-generic,,--pad 4) + $(call Image/Build/CFE,$(1),96328avng,6328,96328avng-16M-flash-generic,,--pad 8) + $(call Image/Build/CFE,$(1),963281TAN,6328,963481TAN-4M-flash-generic,,--pad 2) + $(call Image/Build/CFE,$(1),963281TAN,6328,963481TAN-8M-flash-generic,,--pad 4) + $(call Image/Build/CFE,$(1),963281TAN,6328,963481TAN-16M-flash-generic,,--pad 8) + $(call Image/Build/CFE,$(1),96345GW2,6345,96345GW2-generic) + $(call Image/Build/CFE,$(1),96345GW2,6345,96348GW2-bc221,,--layoutver 5) + $(call Image/Build/CFE,$(1),96345GW2,6345,92345GW2-rev,OpenWRT-$(REVISION)) + $(call Image/Build/CFE,$(1),96348GW,6348,96348GW-generic,,) + $(call Image/Build/CFE,$(1),96348R,6348,96348R-generic,,) + $(call Image/Build/CFE,$(1),96348GW,6348,96348GW-bc221,,--layoutver 5) + $(call Image/Build/CFE,$(1),6338GW,6338,6338GW-generic,,) + $(call Image/Build/CFE,$(1),6338W,6338,6338W-generic,,) + $(call Image/Build/CFE,$(1),96348GW-11,6348,96348GW-11-generic) + $(call Image/Build/CFE,$(1),96348GW-10,6348,96348GW-10-generic) + $(call Image/Build/CFE,$(1),96348A-122,6348,96348A-122-generic) + $(call Image/Build/CFE,$(1),96358VW,6358,96358VW-generic) + $(call Image/Build/CFE,$(1),96358VW2,6358,96358VW2-generic) + $(call Image/Build/CFE,$(1),96368MVNgr,6368,96368MVNgr-generic) + $(call Image/Build/CFE,$(1),96368MVWG,6368,96368MVWG-generic) + + # BT Voyager V210_BTR + $(call Image/Build/CFE,$(1),V210_BB,6348,BTV210_BTR,,--layoutver 5) + # BT Voyager V210_ROI, V210_WB + $(call Image/Build/CFE,$(1),V210,6348,BTV210_ROI_WB,,--layoutver 5) + # BT Voyager V2091_BTR + $(call Image/Build/CFE,$(1),V2091_BB,6348,BTV2091_BTR,,--layoutver 5) + # BT Voyager V2091_ROI, V2091_WB + $(call Image/Build/CFE,$(1),V2091,6348,BTV2091_ROI_WB,,--layoutver 5) + # BT Voyager V220V, V220V_MGCP_BTR + $(call Image/Build/CFE,$(1),RTA1052V,6348,BTV220V_MGCP_BTR,,--layoutver 5) + # BT Voyager V2110, V2110_AA, V2110_ROI + $(call Image/Build/CFE,$(1),V2110,6348,BTV2110,,--layoutver 5) + # BT Voyager V2500V, V2500V_SIP_CLUB, V2500V_AA + $(call Image/Build/CFE,$(1),V2500V_BB,6348,BTV2500V,,--layoutver 5) + # RTA1025W_16 (numerous routers) + $(call Image/Build/CFE,$(1),RTA1025W_16,6348,RTA1025W_16,,--layoutver 5) + # RTA1320_16M (numerous routers) + $(call Image/Build/CFE,$(1),RTA1320_16M,6338,RTA1320_16M,,--layoutver 5) + # Tecom GW6000 + $(call Image/Build/CFEFIXUP,$(1),96348GW,GW6000,6348,GW6000) + # Tecom GW6200 + $(call Image/Build/CFEFIXUP,$(1),96348GW,GW6200,6348,GW6200,$(shell printf '\x99')) + # Neufbox4 + $(call Image/Build/CFE,$(1),96358VW,6358,NEUFBOX4,OpenWRT-$(REVISION)) + # Neufbox6 + $(call Image/Build/CFE,$(1),NB6-SER-r0,6362,NEUFBOX6,OpenWRT-$(REVISION)) + # Comtrend 6373 + $(call Image/Build/CFE,$(1),CT6373-1,6358,CT6373) + # Comtrend 536, 5621 + $(call Image/Build/CFEFIXUP,$(1),96348GW-11,CT536_CT5621,6348,CT536_CT5621) + # Davolink DV201AMR + $(call Image/Build/CFEOLD,$(1),DV201AMR,6348) + # USR 9108 + $(call Image/Build/CFE,$(1),96348GW-A,6348,USR9108) + # NetGear DG834GT, DG834PN + $(call Image/Build/CFE,$(1),96348GW-10,6348,DG834GT_DG834PN) + # Belkin f5d7633 + $(call Image/Build/CFE,$(1),96348GW-10,6348,F5D7633) + # D-Link DSL-2640B, rev B2 + $(call Image/Build/CFE,$(1),D-4P-W,6348,DSL2640B-B2) + # D-Link DSL-2650U + $(call Image/Build/CFE,$(1),96358VW2,6358,DSL2650U) + # D-Link DSL-2740B/DSL-2741B, rev C2 + $(call Image/Build/CFEFIXUP,$(1),96358GW,AW4139,6358,DSL274XB-C2) + # D-Link DSL-2740B/DSL-2741B, rev C3 + $(call Image/Build/CFE,$(1),AW4139,6358,DSL274XB-C3) + # D-Link DSL-2740B/DSL-2741B, rev F1 + $(call Image/Build/CFE,$(1),AW4339U,6328,DSL274XB-F1-EU,,--signature2="4.06.01.EUF1" --pad 4) + $(call Image/Build/CFE,$(1),AW4339U,6328,DSL274XB-F1-AU,,--signature2="4.06.01.AUF1" --pad 4) + # D-Link DVA-G3810BN/TL + $(call Image/Build/CFEFIXUP,$(1),96358VW,DVAG3810BN,6358,DVAG3810BN) + + # TP-Link TD-8810A, TD-8810B, TD-8811A, TD-8811B + $(call Image/Build/CFE,$(1),8L-2M-8M,6338,TP8810_8811) + # TP-Link 8900GB + $(call Image/Build/CFE,$(1),96348GW-11,6348,TD8900GB,$(shell printf 'PRID\x89\x10\x00\x02')) + + # Sagem F@ST2404 + $(call Image/Build/CFE,$(1),F@ST2404,6348,F@ST2404-cfe) + $(call Image/Build/CFE,$(1),F@ST2404,6348,F@ST2404,OpenWRT-$(REVISION)) + # Inventel Livebox + $(call Image/Build/RedBoot,livebox) + # Pirelli Alice Gate VoIP 2 Plus Wi-Fi AGPF-S0 + $(call Image/Build/CFEAGPF,$(1),AGPF-S0,6358,0x20000,AGV2+W-cfe) + $(call Image/Build/CFEAGPF,$(1),AGPF-S0,6358,0x20000,AGV2+W) + # Pirelli A226G + $(call Image/Build/CFEAGPF,$(1),DWV-S0,6358,0x10000,A226G-cfe) + $(call Image/Build/CFEAGPF,$(1),DWV-S0,6358,0x10000,A226G) + + # Pirelli A226M + $(call Image/Build/CFEAGPF,$(1),DWV-S0,6358,0x20000,A226M-cfe) + $(call Image/Build/CFEAGPF,$(1),DWV-S0,6358,0x20000,A226M) + + # RG100A,DB120 etc. + $(call Image/Build/RG100A,$(1),96358VW2,6358,0x20000,RG100A_DB120) + + # Telsey CPVA642-type (e.g. CPA-ZNTE60T) + $(call Image/Build/CFE,$(1),CPVA642,6358,CPA-ZNTE60T,,--signature "Telsey Tlc",--signature2 "99.99.999",--second-image-flag "0") + + # T-Com Speedport W 500V + $(call Image/Build/CFEFIXUP,$(1),96348GW,SPW500V,6348,SPW500V) + + #HW553 + $(call Image/Build/CFEHW553,$(1),HW553,6358,0x20000,HW553) + + # T-Com Speedport W 303V Typ B + $(call Image/Build/SPW303V,$(1),96358-502V,6358,SPW303V) +endef + +$(eval $(call BuildImage)) diff --git a/target/linux/brcm63xx/image/README.images-bcm63xx b/target/linux/brcm63xx/image/README.images-bcm63xx new file mode 100644 index 000000000..91b6d019e --- /dev/null +++ b/target/linux/brcm63xx/image/README.images-bcm63xx @@ -0,0 +1,127 @@ +The image neede to flash onto a Broadcom 63xx-series board depends on the +board, method you are using to flash, and, for web-based flash, on the version +of the Broadcom code your router uses. + +There are two major revisions of the Broadcom code as far as imagetags are +concerned, before 3.08 and after 3.08, however there are some variations +within in that, either due to vendor differences or due to changes at +Broadcom (it's not clear yet which is the case). In addtion Pirelli modified +the Broadcom code, so Alice Gate models use a different imagetag than any +other vendor. + +The imagetag format for flashing via CFE is the same for almost all the +boards, and is the same for all images generated by the imagetag utility. +Images flashable using cfe are labelled openwrt-<board>-<filesystem>-cfe.bin + +The imagetags for tftp/ftp flashing is based on Broadcom 3.00-3.04 imagetags +and is known to be correct as the source code GPL and is available for reading. + +Broadcom code 2.21 is based on the BT Voyager firmware image I looked at. It +may in fact be BT Voyager-specific. 2.21 is actually more difficult to deal +with the imagetag from 3.00 as it has three different CRC calculations in +addtition to the header CRC. + +Broadcom 3.00-3.02 flashing has been tested on Comtrend CT-5261, CT-536 and +Tecom GW6000, and is the version of the flashing that was present before the +imagetags were split by broadcom code version (early June 2009) + +3.04 is guessed to be the same as 3.00-3.02 based on available information + +Broadom 3.06 is thought to be the same as 3.00-3.02, however the only 3.06 +this author (Daniel Dickinson) has seen is the Alice Gate (Pirelli) firmware +which is known to be different due to vendor (Pirelli) modifications to the +Broadcom code. + +Broadcom 3.10 uses an imagetag that is believed to apply to all 3.10 and 3.12 +versions, and has been tested on the Tecom GW6200. This version introdec changes to +the imagetag to deal with TR69 (a remote rouer management system developed by the +DSL forum). There is a field for vendor-specific information, that at least in some +cases is not optional. It is based on the hexedit of a neufbox4 firmware image, the +information in https://dev.openwrt.org/ticket/4987, and the hexedit of a Tecom +GW6200 image. + +Some boards share the same tag format, but require vendor-specific fields in +the board. In that case the tagid is shared, but the filename of the generated +image reflects the router for which the image was created. + +router |method | codever |filename ++-------------+-------------+---------+--------------------------------------- +|any |cfe+most web | any |openwrt-<board>-<fs>-cfe.bin +|AGVoIP2+WiFi |cfe |alice3.06|openwrt-AGV2+W-cfe-<fs>-cfe.bin +|AGVoIP2+WiFi |web |alice3.06|openwrt-AGV2+W-cfe-<fs>-cfe.bin +|CT536 |web |3.02 |openwrt-CT536_CT5621-<fs>-cfe.bin +|CT5621 |web |3.02 |openwrt-CT536_CT5621-<fs>-cfe.bin +|DG834GT |web |3.02 |openwrt-DG834GT_DG834PN-<fs>-cfe.bin +|DG834PN |web |3.02 |openwrt-DG834GT_DG834PN-<fs>-cfe.bin +|DSL-2640B |web |3.10 |openwrt-DSL2640B-<fs>-cfe.bin +|DSL-2740B |web |3.10 |openwrt-DSL2670B-<fs>-cfe.bin +|F5D7633 |web |3.10 |openwrt-F5D7633-<fs>-cfe.bin +|F@ST2404 |web |3.0X? |openwrt-F@ST2404-cfe-<fs>-cfe.bin +|F@ST2404 |web |3.1X? |openwrt-F@ST2404-<fs>-cfe.bin +|GW6000 |web |3.00 |openwrt-GW6000-<fs>-cfe.bin +|GW6200 |web |3.10 |openwrt-GW6200-<fs>-cfe.bin +|Neufbox4 |web |3.12 |openwrt-NEUFBOX4-<fs>-cfe.bin +|TD8810A |web |3.06 |openwrt-TD8810-<fs>-cfe.bin +|TD8810B |web |3.06 |openwrt-TD8810-<fs>-cfe.bin +|TD8811A |web |3.06 |openwrt-TD8811-<fs>-cfe.bin +|TD8811B |web |3.06 |openwrt-TD881-<fs>-cfe.bin +|TD8900GB |web |3.06 |openwrt-TD8900DB<fs>-cfe.bin +|USR9108 |web |3.0X? |openwrt-USR9108-<fs>-cfe.bin +|V2091_BTR |web |2.21 |openwrt-V2091_BTR-<fs>-cfe.bin +|V2091_ROI |web |2.21 |openwrt-V2091-<fs>-cfe.bin +|V2091_WB |web |2.21 |openwrt-V2091-<fs>-cfe.bin +|V210_BTR |web |2.21 |openwrt-V210_BTR-<fs>-cfe.bin +|V210_ROI |web |2.21 |openwrt-V210-ROI_WB<fs>-cfe.bin +|V210_WB |web |2.21 |openwrt-V210-ROI_WB<fs>-cfe.bin +|V2110 |web |2.21 |openwrt-V2110-<fs>-cfe.bin +|V2110_AA |web |2.21 |openwrt-V2110-<fs>-cfe.bin +|V2110_ROI |web |2.21 |openwrt-V2110-<fs>-cfe.bin +|V2500V |web |2.21 |openwrt-V2500V<fs>-cfe.bin +|V2500V_AA |web |2.21 |openwrt-V2500V-<fs>-cfe.bin +|V2500V_SIP_CLUB |web |2.21 |openwrt-V2500V-<fs>-cfe.bin + +Old imagetag routers +-------------------- +Davolink DV201AMR + +Redboot routers +--------------- +Inventel Livebox + +Known router->code versions +--------------------------- + +Vendor |Model |Code Ver +---------------------------+------------------------------------------+-------- +Belkin |F5D7633 |3.10 +British Telecom (BT) |Voyager V2091_BTR |2.21 +British Telecom (BT) |Voyager V2091_ROI |2.21 +British Telecom (BT) |Voyager V2091_WB |2.21 +British Telecom (BT) |Voyager V210_BTR |2.21 +British Telecom (BT) |Voyager V210_ROI |2.21 +British Telecom (BT) |Voyager V210_WB |2.21 +British Telecom (BT) |Voyager V2110 |2.21 +British Telecom (BT) |Voyager V2110_AA |2.21 +British Telecom (BT) |Voyager V2110_ROI |2.21 +British Telecom (BT) |Voyager V220V |2.21 +British Telecom (BT) |Voyager V2500V |2.21 +British Telecom (BT) |Voyager V2500V_AA |2.21 +British Telecom (BT) |Voyager V2500V_SIP_CLUB |2.21 +Comtrend |CT-5261 |3.02 +Comtrend |CT-536 |3.02 +D-Link |DSL-2640B |3.10 +D-Link |DSL-2670B |3.10 +NetGear |DG834GT |3.02 +NetGear |DG834PN |3.02 +Neuf Cegetel |Neufbox 4 |3.12 +Pirelli |Alice Gate Wi-Fi (+VoIP models?) |ag 3.06 +Sagem |F@ST2404 |? +TP-Link |TD-8810A |3.06 +TP-Link |TD-8810B |3.06 +TP-Link |TD-8811A |3.06 +TP-Link |TD-8811B |3.06 +TP-Link |TD-W8900GB |3.06 +Tecom |GW6000 |3.00 +Tecom |GW6200 |3.10 +USR |9108 |? + diff --git a/target/linux/brcm63xx/image/lzma-loader/Makefile b/target/linux/brcm63xx/image/lzma-loader/Makefile new file mode 100644 index 000000000..5dd6f5097 --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/Makefile @@ -0,0 +1,33 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME := lzma-loader +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +$(PKG_BUILD_DIR)/.prepared: + mkdir $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ + touch $@ + +$(PKG_BUILD_DIR)/loader.gz: $(PKG_BUILD_DIR)/.prepared + $(MAKE) -C $(PKG_BUILD_DIR) CC="$(TARGET_CC)" \ + LD="$(TARGET_CROSS)ld" CROSS_COMPILE="$(TARGET_CROSS)" + +download: +prepare: $(PKG_BUILD_DIR)/.prepared +compile: $(PKG_BUILD_DIR)/loader.gz +install: + +ifneq ($(TARGET),) +install: compile + $(CP) $(PKG_BUILD_DIR)/loader.gz $(PKG_BUILD_DIR)/loader.elf $(TARGET)/ +endif + +clean: + rm -rf $(PKG_BUILD_DIR) diff --git a/target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.c b/target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.c new file mode 100644 index 000000000..951700bdd --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.c @@ -0,0 +1,663 @@ +/* + LzmaDecode.c + LZMA Decoder + + LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#ifndef Byte +#define Byte unsigned char +#endif + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +typedef struct _CRangeDecoder +{ + Byte *Buffer; + Byte *BufferLim; + UInt32 Range; + UInt32 Code; + #ifdef _LZMA_IN_CB + ILzmaInCallback *InCallback; + int Result; + #endif + int ExtraBytes; +} CRangeDecoder; + +Byte RangeDecoderReadByte(CRangeDecoder *rd) +{ + if (rd->Buffer == rd->BufferLim) + { + #ifdef _LZMA_IN_CB + UInt32 size; + rd->Result = rd->InCallback->Read(rd->InCallback, &rd->Buffer, &size); + rd->BufferLim = rd->Buffer + size; + if (size == 0) + #endif + { + rd->ExtraBytes = 1; + return 0xFF; + } + } + return (*rd->Buffer++); +} + +/* #define ReadByte (*rd->Buffer++) */ +#define ReadByte (RangeDecoderReadByte(rd)) + +void RangeDecoderInit(CRangeDecoder *rd, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + Byte *stream, UInt32 bufferSize + #endif + ) +{ + int i; + #ifdef _LZMA_IN_CB + rd->InCallback = inCallback; + rd->Buffer = rd->BufferLim = 0; + #else + rd->Buffer = stream; + rd->BufferLim = stream + bufferSize; + #endif + rd->ExtraBytes = 0; + rd->Code = 0; + rd->Range = (0xFFFFFFFF); + for(i = 0; i < 5; i++) + rd->Code = (rd->Code << 8) | ReadByte; +} + +#define RC_INIT_VAR UInt32 range = rd->Range; UInt32 code = rd->Code; +#define RC_FLUSH_VAR rd->Range = range; rd->Code = code; +#define RC_NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | ReadByte; } + +UInt32 RangeDecoderDecodeDirectBits(CRangeDecoder *rd, int numTotalBits) +{ + RC_INIT_VAR + UInt32 result = 0; + int i; + for (i = numTotalBits; i > 0; i--) + { + /* UInt32 t; */ + range >>= 1; + + result <<= 1; + if (code >= range) + { + code -= range; + result |= 1; + } + /* + t = (code - range) >> 31; + t &= 1; + code -= range & (t - 1); + result = (result + result) | (1 - t); + */ + RC_NORMALIZE + } + RC_FLUSH_VAR + return result; +} + +int RangeDecoderBitDecode(CProb *prob, CRangeDecoder *rd) +{ + UInt32 bound = (rd->Range >> kNumBitModelTotalBits) * *prob; + if (rd->Code < bound) + { + rd->Range = bound; + *prob += (kBitModelTotal - *prob) >> kNumMoveBits; + if (rd->Range < kTopValue) + { + rd->Code = (rd->Code << 8) | ReadByte; + rd->Range <<= 8; + } + return 0; + } + else + { + rd->Range -= bound; + rd->Code -= bound; + *prob -= (*prob) >> kNumMoveBits; + if (rd->Range < kTopValue) + { + rd->Code = (rd->Code << 8) | ReadByte; + rd->Range <<= 8; + } + return 1; + } +} + +#define RC_GET_BIT2(prob, mi, A0, A1) \ + UInt32 bound = (range >> kNumBitModelTotalBits) * *prob; \ + if (code < bound) \ + { A0; range = bound; *prob += (kBitModelTotal - *prob) >> kNumMoveBits; mi <<= 1; } \ + else \ + { A1; range -= bound; code -= bound; *prob -= (*prob) >> kNumMoveBits; mi = (mi + mi) + 1; } \ + RC_NORMALIZE + +#define RC_GET_BIT(prob, mi) RC_GET_BIT2(prob, mi, ; , ;) + +int RangeDecoderBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ + int mi = 1; + int i; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + for(i = numLevels; i > 0; i--) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + mi; + RC_GET_BIT(prob, mi) + #else + mi = (mi + mi) + RangeDecoderBitDecode(probs + mi, rd); + #endif + } + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return mi - (1 << numLevels); +} + +int RangeDecoderReverseBitTreeDecode(CProb *probs, int numLevels, CRangeDecoder *rd) +{ + int mi = 1; + int i; + int symbol = 0; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + for(i = 0; i < numLevels; i++) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + mi; + RC_GET_BIT2(prob, mi, ; , symbol |= (1 << i)) + #else + int bit = RangeDecoderBitDecode(probs + mi, rd); + mi = mi + mi + bit; + symbol |= (bit << i); + #endif + } + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +Byte LzmaLiteralDecode(CProb *probs, CRangeDecoder *rd) +{ + int symbol = 1; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + do + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + symbol; + RC_GET_BIT(prob, symbol) + #else + symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); + #endif + } + while (symbol < 0x100); + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +Byte LzmaLiteralDecodeMatch(CProb *probs, CRangeDecoder *rd, Byte matchByte) +{ + int symbol = 1; + #ifdef _LZMA_LOC_OPT + RC_INIT_VAR + #endif + do + { + int bit; + int matchBit = (matchByte >> 7) & 1; + matchByte <<= 1; + #ifdef _LZMA_LOC_OPT + { + CProb *prob = probs + ((1 + matchBit) << 8) + symbol; + RC_GET_BIT2(prob, symbol, bit = 0, bit = 1) + } + #else + bit = RangeDecoderBitDecode(probs + ((1 + matchBit) << 8) + symbol, rd); + symbol = (symbol << 1) | bit; + #endif + if (matchBit != bit) + { + while (symbol < 0x100) + { + #ifdef _LZMA_LOC_OPT + CProb *prob = probs + symbol; + RC_GET_BIT(prob, symbol) + #else + symbol = (symbol + symbol) | RangeDecoderBitDecode(probs + symbol, rd); + #endif + } + break; + } + } + while (symbol < 0x100); + #ifdef _LZMA_LOC_OPT + RC_FLUSH_VAR + #endif + return symbol; +} + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + +int LzmaLenDecode(CProb *p, CRangeDecoder *rd, int posState) +{ + if(RangeDecoderBitDecode(p + LenChoice, rd) == 0) + return RangeDecoderBitTreeDecode(p + LenLow + + (posState << kLenNumLowBits), kLenNumLowBits, rd); + if(RangeDecoderBitDecode(p + LenChoice2, rd) == 0) + return kLenNumLowSymbols + RangeDecoderBitTreeDecode(p + LenMid + + (posState << kLenNumMidBits), kLenNumMidBits, rd); + return kLenNumLowSymbols + kLenNumMidSymbols + + RangeDecoderBitTreeDecode(p + LenHigh, kLenNumHighBits, rd); +} + +#define kNumStates 12 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +#ifdef _LZMA_OUT_READ + +typedef struct _LzmaVarState +{ + CRangeDecoder RangeDecoder; + Byte *Dictionary; + UInt32 DictionarySize; + UInt32 DictionaryPos; + UInt32 GlobalPos; + UInt32 Reps[4]; + int lc; + int lp; + int pb; + int State; + int PreviousIsMatch; + int RemainLen; +} LzmaVarState; + +int LzmaDecoderInit( + unsigned char *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + unsigned char *dictionary, UInt32 dictionarySize, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + unsigned char *inStream, UInt32 inSize + #endif + ) +{ + LzmaVarState *vs = (LzmaVarState *)buffer; + CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); + UInt32 i; + if (bufferSize < numProbs * sizeof(CProb) + sizeof(LzmaVarState)) + return LZMA_RESULT_NOT_ENOUGH_MEM; + vs->Dictionary = dictionary; + vs->DictionarySize = dictionarySize; + vs->DictionaryPos = 0; + vs->GlobalPos = 0; + vs->Reps[0] = vs->Reps[1] = vs->Reps[2] = vs->Reps[3] = 1; + vs->lc = lc; + vs->lp = lp; + vs->pb = pb; + vs->State = 0; + vs->PreviousIsMatch = 0; + vs->RemainLen = 0; + dictionary[dictionarySize - 1] = 0; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + RangeDecoderInit(&vs->RangeDecoder, + #ifdef _LZMA_IN_CB + inCallback + #else + inStream, inSize + #endif + ); + return LZMA_RESULT_OK; +} + +int LzmaDecode(unsigned char *buffer, + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed) +{ + LzmaVarState *vs = (LzmaVarState *)buffer; + CProb *p = (CProb *)(buffer + sizeof(LzmaVarState)); + CRangeDecoder rd = vs->RangeDecoder; + int state = vs->State; + int previousIsMatch = vs->PreviousIsMatch; + Byte previousByte; + UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; + UInt32 nowPos = 0; + UInt32 posStateMask = (1 << (vs->pb)) - 1; + UInt32 literalPosMask = (1 << (vs->lp)) - 1; + int lc = vs->lc; + int len = vs->RemainLen; + UInt32 globalPos = vs->GlobalPos; + + Byte *dictionary = vs->Dictionary; + UInt32 dictionarySize = vs->DictionarySize; + UInt32 dictionaryPos = vs->DictionaryPos; + + if (len == -1) + { + *outSizeProcessed = 0; + return LZMA_RESULT_OK; + } + + while(len > 0 && nowPos < outSize) + { + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + len--; + } + if (dictionaryPos == 0) + previousByte = dictionary[dictionarySize - 1]; + else + previousByte = dictionary[dictionaryPos - 1]; +#else + +int LzmaDecode( + Byte *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + unsigned char *inStream, UInt32 inSize, + #endif + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed) +{ + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + lp)); + CProb *p = (CProb *)buffer; + CRangeDecoder rd; + UInt32 i; + int state = 0; + int previousIsMatch = 0; + Byte previousByte = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + UInt32 nowPos = 0; + UInt32 posStateMask = (1 << pb) - 1; + UInt32 literalPosMask = (1 << lp) - 1; + int len = 0; + if (bufferSize < numProbs * sizeof(CProb)) + return LZMA_RESULT_NOT_ENOUGH_MEM; + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + RangeDecoderInit(&rd, + #ifdef _LZMA_IN_CB + inCallback + #else + inStream, inSize + #endif + ); +#endif + + *outSizeProcessed = 0; + while(nowPos < outSize) + { + int posState = (int)( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & posStateMask); + #ifdef _LZMA_IN_CB + if (rd.Result != LZMA_RESULT_OK) + return rd.Result; + #endif + if (rd.ExtraBytes != 0) + return LZMA_RESULT_DATA_ERROR; + if (RangeDecoderBitDecode(p + IsMatch + (state << kNumPosBitsMax) + posState, &rd) == 0) + { + CProb *probs = p + Literal + (LZMA_LIT_SIZE * + ((( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + if (previousIsMatch) + { + Byte matchByte; + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + matchByte = dictionary[pos]; + #else + matchByte = outStream[nowPos - rep0]; + #endif + previousByte = LzmaLiteralDecodeMatch(probs, &rd, matchByte); + previousIsMatch = 0; + } + else + previousByte = LzmaLiteralDecode(probs, &rd); + outStream[nowPos++] = previousByte; + #ifdef _LZMA_OUT_READ + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #endif + } + else + { + previousIsMatch = 1; + if (RangeDecoderBitDecode(p + IsRep + state, &rd) == 1) + { + if (RangeDecoderBitDecode(p + IsRepG0 + state, &rd) == 0) + { + if (RangeDecoderBitDecode(p + IsRep0Long + (state << kNumPosBitsMax) + posState, &rd) == 0) + { + #ifdef _LZMA_OUT_READ + UInt32 pos; + #endif + if ( + (nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + == 0) + return LZMA_RESULT_DATA_ERROR; + state = state < 7 ? 9 : 11; + #ifdef _LZMA_OUT_READ + pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + continue; + } + } + else + { + UInt32 distance; + if(RangeDecoderBitDecode(p + IsRepG1 + state, &rd) == 0) + distance = rep1; + else + { + if(RangeDecoderBitDecode(p + IsRepG2 + state, &rd) == 0) + distance = rep2; + else + { + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + len = LzmaLenDecode(p + RepLenCoder, &rd, posState); + state = state < 7 ? 8 : 11; + } + else + { + int posSlot; + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < 7 ? 7 : 10; + len = LzmaLenDecode(p + LenCoder, &rd, posState); + posSlot = RangeDecoderBitTreeDecode(p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits), kNumPosSlotBits, &rd); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = ((2 | ((UInt32)posSlot & 1)) << numDirectBits); + if (posSlot < kEndPosModelIndex) + { + rep0 += RangeDecoderReverseBitTreeDecode( + p + SpecPos + rep0 - posSlot - 1, numDirectBits, &rd); + } + else + { + rep0 += RangeDecoderDecodeDirectBits(&rd, + numDirectBits - kNumAlignBits) << kNumAlignBits; + rep0 += RangeDecoderReverseBitTreeDecode(p + Align, kNumAlignBits, &rd); + } + } + else + rep0 = posSlot; + rep0++; + } + if (rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = -1; + break; + } + if (rep0 > nowPos + #ifdef _LZMA_OUT_READ + + globalPos + #endif + ) + { + return LZMA_RESULT_DATA_ERROR; + } + len += kMatchMinLen; + do + { + #ifdef _LZMA_OUT_READ + UInt32 pos = dictionaryPos - rep0; + if (pos >= dictionarySize) + pos += dictionarySize; + previousByte = dictionary[pos]; + dictionary[dictionaryPos] = previousByte; + if (++dictionaryPos == dictionarySize) + dictionaryPos = 0; + #else + previousByte = outStream[nowPos - rep0]; + #endif + outStream[nowPos++] = previousByte; + len--; + } + while(len > 0 && nowPos < outSize); + } + } + + #ifdef _LZMA_OUT_READ + vs->RangeDecoder = rd; + vs->DictionaryPos = dictionaryPos; + vs->GlobalPos = globalPos + nowPos; + vs->Reps[0] = rep0; + vs->Reps[1] = rep1; + vs->Reps[2] = rep2; + vs->Reps[3] = rep3; + vs->State = state; + vs->PreviousIsMatch = previousIsMatch; + vs->RemainLen = len; + #endif + + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.h b/target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.h new file mode 100644 index 000000000..f58944e3c --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/src/LzmaDecode.h @@ -0,0 +1,100 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.05 Copyright (c) 1999-2004 Igor Pavlov (2004-08-25) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +/* #define _LZMA_IN_CB */ +/* Use callback for input data */ + +/* #define _LZMA_OUT_READ */ +/* Use read function for output data */ + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +/* #define _LZMA_LOC_OPT */ +/* Enable local speed optimizations inside code */ + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb unsigned short +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 +#define LZMA_RESULT_NOT_ENOUGH_MEM 2 + +#ifdef _LZMA_IN_CB +typedef struct _ILzmaInCallback +{ + int (*Read)(void *object, unsigned char **buffer, UInt32 *bufferSize); +} ILzmaInCallback; +#endif + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +/* +bufferSize = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)))* sizeof(CProb) +bufferSize += 100 in case of _LZMA_OUT_READ +by default CProb is unsigned short, +but if specify _LZMA_PROB_32, CProb will be UInt32(unsigned int) +*/ + +#ifdef _LZMA_OUT_READ +int LzmaDecoderInit( + unsigned char *buffer, UInt32 bufferSize, + int lc, int lp, int pb, + unsigned char *dictionary, UInt32 dictionarySize, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback + #else + unsigned char *inStream, UInt32 inSize + #endif +); +#endif + +int LzmaDecode( + unsigned char *buffer, + #ifndef _LZMA_OUT_READ + UInt32 bufferSize, + int lc, int lp, int pb, + #ifdef _LZMA_IN_CB + ILzmaInCallback *inCallback, + #else + unsigned char *inStream, UInt32 inSize, + #endif + #endif + unsigned char *outStream, UInt32 outSize, + UInt32 *outSizeProcessed); + +#endif diff --git a/target/linux/brcm63xx/image/lzma-loader/src/Makefile b/target/linux/brcm63xx/image/lzma-loader/src/Makefile new file mode 100644 index 000000000..83e2c5238 --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/src/Makefile @@ -0,0 +1,77 @@ +# +# Makefile for Broadcom BCM947XX boards +# +# Copyright 2001-2003, Broadcom Corporation +# All Rights Reserved. +# +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. +# +# Copyright 2004 Manuel Novoa III <mjn3@codepoet.org> +# Modified to support bzip'd kernels. +# Of course, it would be better to integrate bunzip capability into CFE. +# +# Copyright 2005 Oleg I. Vdovikin <oleg@cs.msu.su> +# Cleaned up, modified for lzma support, removed from kernel +# + +TEXT_START := 0x80010000 +BZ_TEXT_START := 0x80300000 + +OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .reginfo -R .note -R .comment -R .mdebug -S + +CFLAGS = -D__KERNEL__ -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ + -fno-strict-aliasing -fno-common -fomit-frame-pointer -G 0 -mno-abicalls -fno-pic \ + -ffunction-sections -pipe -mlong-calls -fno-common \ + -mabi=32 -march=mips32 -Wa,-32 -Wa,-march=mips32 -Wa,-mips32 -Wa,--trap +CFLAGS += -DLOADADDR=$(TEXT_START) -D_LZMA_IN_CB + +ASFLAGS = $(CFLAGS) -D__ASSEMBLY__ -DBZ_TEXT_START=$(BZ_TEXT_START) + +SEDFLAGS := s/BZ_TEXT_START/$(BZ_TEXT_START)/;s/TEXT_START/$(TEXT_START)/ + +OBJECTS := head.o data.o + +all: loader.gz loader.elf + +# Don't build dependencies, this may die if $(CC) isn't gcc +dep: + +install: + +loader.gz: loader + gzip -nc9 $< > $@ + +loader.elf: loader.o + cp $< $@ + +loader: loader.o + $(OBJCOPY) $< $@ + +loader.o: loader.lds $(OBJECTS) + $(LD) -static --gc-sections -no-warn-mismatch -T loader.lds -o $@ $(OBJECTS) + +loader.lds: loader.lds.in Makefile + @sed "$(SEDFLAGS)" < $< > $@ + +data.o: data.lds decompress.image + $(LD) -no-warn-mismatch -T data.lds -r -o $@ -b binary decompress.image -b elf32-tradlittlemips + +data.lds: + @echo "SECTIONS { .data : { code_start = .; *(.data) code_stop = .; }}" > $@ + +decompress.image: decompress + $(OBJCOPY) $< $@ + +decompress: decompress.lds decompress.o LzmaDecode.o + $(LD) -static --gc-sections -no-warn-mismatch -T decompress.lds -o $@ decompress.o LzmaDecode.o + +decompress.lds: decompress.lds.in Makefile + @sed "$(SEDFLAGS)" < $< > $@ + +mrproper: clean + +clean: + rm -f loader.gz loader decompress *.lds *.o *.image diff --git a/target/linux/brcm63xx/image/lzma-loader/src/README b/target/linux/brcm63xx/image/lzma-loader/src/README new file mode 100644 index 000000000..16649e950 --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/src/README @@ -0,0 +1,55 @@ +/* + * LZMA compressed kernel decompressor for bcm947xx boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> + * + * 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 + * + */ + +The code is intended to decompress kernel, being compressed using lzma utility +build using 7zip LZMA SDK. This utility is located in the LZMA_Alone directory + +decompressor code expects that your .trx file consist of three partitions: + +1) decompressor itself (this is gziped code which pmon/cfe will extract and run +on boot-up instead of real kernel) +2) LZMA compressed kernel (both streamed and regular modes are supported now) +3) Root filesystem + +Please be sure to apply the following patch for use this new trx layout (it will +allow using both new and old trx files for root filesystem lookup code) + +--- linuz/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:24:27.503322896 +0300 ++++ linux/arch/mips/brcm-boards/bcm947xx/setup.c 2005-01-23 19:29:05.237100944 +0300 +@@ -221,7 +221,9 @@ + /* Try looking at TRX header for rootfs offset */ + if (le32_to_cpu(trx->magic) == TRX_MAGIC) { + bcm947xx_parts[1].offset = off; +- if (le32_to_cpu(trx->offsets[1]) > off) ++ if (le32_to_cpu(trx->offsets[2]) > off) ++ off = le32_to_cpu(trx->offsets[2]); ++ else if (le32_to_cpu(trx->offsets[1]) > off) + off = le32_to_cpu(trx->offsets[1]); + continue; + } + + +Revision history: + 0.02 Initial release + 0.03 Added Mineharu Takahara <mtakahar@yahoo.com> patch to pass actual + output size to decoder (stream mode compressed input is not + a requirement anymore) + 0.04 Reordered functions using lds script diff --git a/target/linux/brcm63xx/image/lzma-loader/src/decompress.c b/target/linux/brcm63xx/image/lzma-loader/src/decompress.c new file mode 100644 index 000000000..ec510e21e --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/src/decompress.c @@ -0,0 +1,175 @@ +/* + * LZMA compressed kernel decompressor for bcm947xx boards + * + * Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su> + * + * 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 + * + * + * Please note, this was code based on the bunzip2 decompressor code + * by Manuel Novoa III (mjn3@codepoet.org), although the only thing left + * is an idea and part of original vendor code + * + * + * 12-Mar-2005 Mineharu Takahara <mtakahar@yahoo.com> + * pass actual output size to decoder (stream mode + * compressed input is not a requirement anymore) + * + * 24-Apr-2005 Oleg I. Vdovikin + * reordered functions using lds script, removed forward decl + * + */ + +#include "LzmaDecode.h" + +#define BCM4710_FLASH 0x1fc00000 /* Flash */ + +#define KSEG0 0x80000000 +#define KSEG1 0xa0000000 + +#define KSEG1ADDR(a) ((((unsigned)(a)) & 0x1fffffffU) | KSEG1) + +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 + +#define cache_unroll(base,op) \ + __asm__ __volatile__( \ + ".set noreorder;\n" \ + ".set mips3;\n" \ + "cache %1, (%0);\n" \ + ".set mips0;\n" \ + ".set reorder\n" \ + : \ + : "r" (base), \ + "i" (op)); + +static __inline__ void blast_icache(unsigned long size, unsigned long lsize) +{ + unsigned long start = KSEG0; + unsigned long end = (start + size); + + while(start < end) { + cache_unroll(start,Index_Invalidate_I); + start += lsize; + } +} + +static __inline__ void blast_dcache(unsigned long size, unsigned long lsize) +{ + unsigned long start = KSEG0; + unsigned long end = (start + size); + + while(start < end) { + cache_unroll(start,Index_Writeback_Inv_D); + start += lsize; + } +} + +#define TRX_MAGIC 0x30524448 /* "HDR0" */ + +struct trx_header { + unsigned int magic; /* "HDR0" */ + unsigned int len; /* Length of file including header */ + unsigned int crc32; /* 32-bit CRC from flag_version to end of file */ + unsigned int flag_version; /* 0:15 flags, 16:31 version */ + unsigned int offsets[3]; /* Offsets of partitions from start of header */ +}; + +/* beyound the image end, size not known in advance */ +extern unsigned char workspace[]; + +unsigned int offset; +unsigned char *data; + +/* flash access should be aligned, so wrapper is used */ +/* read byte from the flash, all accesses are 32-bit aligned */ +static int read_byte(void *object, unsigned char **buffer, UInt32 *bufferSize) +{ + static unsigned int val; + + if (((unsigned int)offset % 4) == 0) { + val = *(unsigned int *)data; + data += 4; + } + + *bufferSize = 1; + *buffer = ((unsigned char *)&val) + (offset++ & 3); + + return LZMA_RESULT_OK; +} + +static __inline__ unsigned char get_byte(void) +{ + unsigned char *buffer; + UInt32 fake; + + return read_byte(0, &buffer, &fake), *buffer; +} + +/* should be the first function */ +void entry(unsigned long icache_size, unsigned long icache_lsize, + unsigned long dcache_size, unsigned long dcache_lsize) +{ + unsigned int i; /* temp value */ + unsigned int lc; /* literal context bits */ + unsigned int lp; /* literal pos state bits */ + unsigned int pb; /* pos state bits */ + unsigned int osize; /* uncompressed size */ + + ILzmaInCallback callback; + callback.Read = read_byte; + + /* look for trx header, 32-bit data access */ + for (data = ((unsigned char *) KSEG1ADDR(BCM4710_FLASH)); + ((struct trx_header *)data)->magic != TRX_MAGIC; data += 65536); + + /* compressed kernel is in the partition 0 or 1 */ + if (((struct trx_header *)data)->offsets[1] > 65536) + data += ((struct trx_header *)data)->offsets[0]; + else + data += ((struct trx_header *)data)->offsets[1]; + + offset = 0; + + /* lzma args */ + i = get_byte(); + lc = i % 9, i = i / 9; + lp = i % 5, pb = i / 5; + + /* skip rest of the LZMA coder property */ + for (i = 0; i < 4; i++) + get_byte(); + + /* read the lower half of uncompressed size in the header */ + osize = ((unsigned int)get_byte()) + + ((unsigned int)get_byte() << 8) + + ((unsigned int)get_byte() << 16) + + ((unsigned int)get_byte() << 24); + + /* skip rest of the header (upper half of uncompressed size) */ + for (i = 0; i < 4; i++) + get_byte(); + + /* decompress kernel */ + if (LzmaDecode(workspace, ~0, lc, lp, pb, &callback, + (unsigned char*)LOADADDR, osize, &i) == LZMA_RESULT_OK) + { + blast_dcache(dcache_size, dcache_lsize); + blast_icache(icache_size, icache_lsize); + + /* Jump to load address */ + ((void (*)(void)) LOADADDR)(); + } +} diff --git a/target/linux/brcm63xx/image/lzma-loader/src/decompress.lds.in b/target/linux/brcm63xx/image/lzma-loader/src/decompress.lds.in new file mode 100644 index 000000000..33f56f8a0 --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/src/decompress.lds.in @@ -0,0 +1,20 @@ +OUTPUT_ARCH(mips) +ENTRY(entry) +SECTIONS { + . = BZ_TEXT_START; + .text : { + *(.text.entry) + *(.text) + *(.rodata) + } + + .data : { + *(.data) + } + + .bss : { + *(.bss) + } + + workspace = .; +} diff --git a/target/linux/brcm63xx/image/lzma-loader/src/head.S b/target/linux/brcm63xx/image/lzma-loader/src/head.S new file mode 100644 index 000000000..9bfbd53d5 --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/src/head.S @@ -0,0 +1,155 @@ +/* Copyright 2005 Oleg I. Vdovikin (oleg@cs.msu.su) */ +/* cache manipulation adapted from Broadcom code */ +/* idea taken from original bunzip2 decompressor code */ +/* Copyright 2004 Manuel Novoa III (mjn3@codepoet.org) */ +/* Licensed under the linux kernel's version of the GPL.*/ + +#include <asm/asm.h> +#include <asm/regdef.h> + +#define KSEG0 0x80000000 + +#define C0_CONFIG $16 +#define C0_TAGLO $28 +#define C0_TAGHI $29 + +#define CONF1_DA_SHIFT 7 /* D$ associativity */ +#define CONF1_DA_MASK 0x00000380 +#define CONF1_DA_BASE 1 +#define CONF1_DL_SHIFT 10 /* D$ line size */ +#define CONF1_DL_MASK 0x00001c00 +#define CONF1_DL_BASE 2 +#define CONF1_DS_SHIFT 13 /* D$ sets/way */ +#define CONF1_DS_MASK 0x0000e000 +#define CONF1_DS_BASE 64 +#define CONF1_IA_SHIFT 16 /* I$ associativity */ +#define CONF1_IA_MASK 0x00070000 +#define CONF1_IA_BASE 1 +#define CONF1_IL_SHIFT 19 /* I$ line size */ +#define CONF1_IL_MASK 0x00380000 +#define CONF1_IL_BASE 2 +#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ +#define CONF1_IS_MASK 0x01c00000 +#define CONF1_IS_BASE 64 + +#define Index_Invalidate_I 0x00 +#define Index_Writeback_Inv_D 0x01 + + .text + LEAF(startup) + .set noreorder + + /* Copy decompressor code to the right place */ + li t2, BZ_TEXT_START + add a0, t2, 0 + la a1, code_start + la a2, code_stop +$L1: + lw t0, 0(a1) + sw t0, 0(a0) + add a1, 4 + add a0, 4 + blt a1, a2, $L1 + nop + + /* At this point we need to invalidate dcache and */ + /* icache before jumping to new code */ + +1: /* Get cache sizes */ + .set mips32 + mfc0 s0,C0_CONFIG,1 + .set mips0 + + li s1,CONF1_DL_MASK + and s1,s0 + beq s1,zero,nodc + nop + + srl s1,CONF1_DL_SHIFT + li t0,CONF1_DL_BASE + sll s1,t0,s1 /* s1 has D$ cache line size */ + + li s2,CONF1_DA_MASK + and s2,s0 + srl s2,CONF1_DA_SHIFT + addiu s2,CONF1_DA_BASE /* s2 now has D$ associativity */ + + li t0,CONF1_DS_MASK + and t0,s0 + srl t0,CONF1_DS_SHIFT + li s3,CONF1_DS_BASE + sll s3,s3,t0 /* s3 has D$ sets per way */ + + multu s2,s3 /* sets/way * associativity */ + mflo t0 /* total cache lines */ + + multu s1,t0 /* D$ linesize * lines */ + mflo s2 /* s2 is now D$ size in bytes */ + + /* Initilize the D$: */ + mtc0 zero,C0_TAGLO + mtc0 zero,C0_TAGHI + + li t0,KSEG0 /* Just an address for the first $ line */ + addu t1,t0,s2 /* + size of cache == end */ + + .set mips3 +1: cache Index_Writeback_Inv_D,0(t0) + .set mips0 + bne t0,t1,1b + addu t0,s1 + +nodc: + /* Now we get to do it all again for the I$ */ + + move s3,zero /* just in case there is no icache */ + move s4,zero + + li t0,CONF1_IL_MASK + and t0,s0 + beq t0,zero,noic + nop + + srl t0,CONF1_IL_SHIFT + li s3,CONF1_IL_BASE + sll s3,t0 /* s3 has I$ cache line size */ + + li t0,CONF1_IA_MASK + and t0,s0 + srl t0,CONF1_IA_SHIFT + addiu s4,t0,CONF1_IA_BASE /* s4 now has I$ associativity */ + + li t0,CONF1_IS_MASK + and t0,s0 + srl t0,CONF1_IS_SHIFT + li s5,CONF1_IS_BASE + sll s5,t0 /* s5 has I$ sets per way */ + + multu s4,s5 /* sets/way * associativity */ + mflo t0 /* s4 is now total cache lines */ + + multu s3,t0 /* I$ linesize * lines */ + mflo s4 /* s4 is cache size in bytes */ + + /* Initilize the I$: */ + mtc0 zero,C0_TAGLO + mtc0 zero,C0_TAGHI + + li t0,KSEG0 /* Just an address for the first $ line */ + addu t1,t0,s4 /* + size of cache == end */ + + .set mips3 +1: cache Index_Invalidate_I,0(t0) + .set mips0 + bne t0,t1,1b + addu t0,s3 + +noic: + move a0,s3 /* icache line size */ + move a1,s4 /* icache size */ + move a2,s1 /* dcache line size */ + jal t2 + move a3,s2 /* dcache size */ + + .set reorder + END(startup) diff --git a/target/linux/brcm63xx/image/lzma-loader/src/loader.lds.in b/target/linux/brcm63xx/image/lzma-loader/src/loader.lds.in new file mode 100644 index 000000000..20f2ea98e --- /dev/null +++ b/target/linux/brcm63xx/image/lzma-loader/src/loader.lds.in @@ -0,0 +1,17 @@ +OUTPUT_ARCH(mips) +ENTRY(startup) +SECTIONS { + . = TEXT_START; + .text : { + *(.text) + *(.rodata) + } + + .data : { + *(.data) + } + + .bss : { + *(.bss) + } +} diff --git a/target/linux/brcm63xx/modules.mk b/target/linux/brcm63xx/modules.mk new file mode 100644 index 000000000..43ec62430 --- /dev/null +++ b/target/linux/brcm63xx/modules.mk @@ -0,0 +1,37 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define KernelPackage/bcm63xx-spi + SUBMENU:=$(SPI_MENU) + TITLE:=Broadcom BCM63xx SPI driver + DEPENDS:=@TARGET_brcm63xx + KCONFIG:=CONFIG_SPI_BCM63XX + FILES:=$(LINUX_DIR)/drivers/spi/spi-bcm63xx.ko + AUTOLOAD:=$(call AutoLoad,92,spi-bcm63xx) +endef + +define KernelPackage/bcm63xx-spi/description + This package contains the Broadcom BCM63xx SPI Master driver +endef + +$(eval $(call KernelPackage,bcm63xx-spi)) + + +define KernelPackage/pcmcia-bcm63xx + SUBMENU:=$(PCMCIA_MENU) + TITLE:=Broadcom BCM63xx PCMCIA support + DEPENDS:=@TARGET_brcm63xx +kmod-pcmcia-rsrc + KCONFIG:=CONFIG_PCMCIA_BCM63XX + FILES:=$(LINUX_DIR)/drivers/pcmcia/bcm63xx_pcmcia.ko + AUTOLOAD:=$(call AutoLoad,41,bcm63xx_pcmcia) +endef + +define KernelPackage/pcmcia-bcm63xx/description + Kernel support for PCMCIA/CardBus controller on the BCM63xx SoC +endef + +$(eval $(call KernelPackage,pcmcia-bcm63xx)) diff --git a/target/linux/brcm63xx/patches-3.3/001-MIPS-BCM63XX-fix-platform_devices-id.patch b/target/linux/brcm63xx/patches-3.3/001-MIPS-BCM63XX-fix-platform_devices-id.patch new file mode 100644 index 000000000..f83490e6c --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/001-MIPS-BCM63XX-fix-platform_devices-id.patch @@ -0,0 +1,36 @@ +From cbcfe65e357666106c3c6250baf9c5ce33f3e3e3 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:39:53 +0100 +Subject: [PATCH 03/63] MIPS: BCM63XX: fix platform_devices id + +There is only one watchdog and VoIP DSP platform devices per board, use +-1 as the platform_device id accordingly. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/bcm63xx/dev-dsp.c | 2 +- + arch/mips/bcm63xx/dev-wdt.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/bcm63xx/dev-dsp.c ++++ b/arch/mips/bcm63xx/dev-dsp.c +@@ -31,7 +31,7 @@ static struct resource voip_dsp_resource + + static struct platform_device bcm63xx_voip_dsp_device = { + .name = "bcm63xx-voip-dsp", +- .id = 0, ++ .id = -1, + .num_resources = ARRAY_SIZE(voip_dsp_resources), + .resource = voip_dsp_resources, + }; +--- a/arch/mips/bcm63xx/dev-wdt.c ++++ b/arch/mips/bcm63xx/dev-wdt.c +@@ -21,7 +21,7 @@ static struct resource wdt_resources[] = + + static struct platform_device bcm63xx_wdt_device = { + .name = "bcm63xx-wdt", +- .id = 0, ++ .id = -1, + .num_resources = ARRAY_SIZE(wdt_resources), + .resource = wdt_resources, + }; diff --git a/target/linux/brcm63xx/patches-3.3/002-MIPS-BCM63XX-be-consistent-in-clock-bits-enable-nami.patch b/target/linux/brcm63xx/patches-3.3/002-MIPS-BCM63XX-be-consistent-in-clock-bits-enable-nami.patch new file mode 100644 index 000000000..439d11ea1 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/002-MIPS-BCM63XX-be-consistent-in-clock-bits-enable-nami.patch @@ -0,0 +1,93 @@ +From db1cc4ee366bf0528fcb8b4afa65dec915d98889 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:39:55 +0100 +Subject: [PATCH 04/63] MIPS: BCM63XX: be consistent in clock bits enable naming + +Remove the _CLK suffix from the BCM6368 clock bits definitions to be +consistent with what is already present. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/bcm63xx/clk.c | 6 ++-- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 36 ++++++++++---------- + 2 files changed, 21 insertions(+), 21 deletions(-) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -120,7 +120,7 @@ static void enetsw_set(struct clk *clk, + { + if (!BCMCPU_IS_6368()) + return; +- bcm_hwclock_set(CKCTL_6368_ROBOSW_CLK_EN | ++ bcm_hwclock_set(CKCTL_6368_ROBOSW_EN | + CKCTL_6368_SWPKT_USB_EN | + CKCTL_6368_SWPKT_SAR_EN, enable); + if (enable) { +@@ -163,7 +163,7 @@ static void usbh_set(struct clk *clk, in + if (BCMCPU_IS_6348()) + bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); + else if (BCMCPU_IS_6368()) +- bcm_hwclock_set(CKCTL_6368_USBH_CLK_EN, enable); ++ bcm_hwclock_set(CKCTL_6368_USBH_EN, enable); + } + + static struct clk clk_usbh = { +@@ -199,7 +199,7 @@ static void xtm_set(struct clk *clk, int + if (!BCMCPU_IS_6368()) + return; + +- bcm_hwclock_set(CKCTL_6368_SAR_CLK_EN | ++ bcm_hwclock_set(CKCTL_6368_SAR_EN | + CKCTL_6368_SWPKT_SAR_EN, enable); + + if (enable) { +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -90,29 +90,29 @@ + #define CKCTL_6368_PHYMIPS_EN (1 << 6) + #define CKCTL_6368_SWPKT_USB_EN (1 << 7) + #define CKCTL_6368_SWPKT_SAR_EN (1 << 8) +-#define CKCTL_6368_SPI_CLK_EN (1 << 9) +-#define CKCTL_6368_USBD_CLK_EN (1 << 10) +-#define CKCTL_6368_SAR_CLK_EN (1 << 11) +-#define CKCTL_6368_ROBOSW_CLK_EN (1 << 12) +-#define CKCTL_6368_UTOPIA_CLK_EN (1 << 13) +-#define CKCTL_6368_PCM_CLK_EN (1 << 14) +-#define CKCTL_6368_USBH_CLK_EN (1 << 15) ++#define CKCTL_6368_SPI_EN (1 << 9) ++#define CKCTL_6368_USBD_EN (1 << 10) ++#define CKCTL_6368_SAR_EN (1 << 11) ++#define CKCTL_6368_ROBOSW_EN (1 << 12) ++#define CKCTL_6368_UTOPIA_EN (1 << 13) ++#define CKCTL_6368_PCM_EN (1 << 14) ++#define CKCTL_6368_USBH_EN (1 << 15) + #define CKCTL_6368_DISABLE_GLESS_EN (1 << 16) +-#define CKCTL_6368_NAND_CLK_EN (1 << 17) +-#define CKCTL_6368_IPSEC_CLK_EN (1 << 17) ++#define CKCTL_6368_NAND_EN (1 << 17) ++#define CKCTL_6368_IPSEC_EN (1 << 17) + + #define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \ + CKCTL_6368_SWPKT_SAR_EN | \ +- CKCTL_6368_SPI_CLK_EN | \ +- CKCTL_6368_USBD_CLK_EN | \ +- CKCTL_6368_SAR_CLK_EN | \ +- CKCTL_6368_ROBOSW_CLK_EN | \ +- CKCTL_6368_UTOPIA_CLK_EN | \ +- CKCTL_6368_PCM_CLK_EN | \ +- CKCTL_6368_USBH_CLK_EN | \ ++ CKCTL_6368_SPI_EN | \ ++ CKCTL_6368_USBD_EN | \ ++ CKCTL_6368_SAR_EN | \ ++ CKCTL_6368_ROBOSW_EN | \ ++ CKCTL_6368_UTOPIA_EN | \ ++ CKCTL_6368_PCM_EN | \ ++ CKCTL_6368_USBH_EN | \ + CKCTL_6368_DISABLE_GLESS_EN | \ +- CKCTL_6368_NAND_CLK_EN | \ +- CKCTL_6368_IPSEC_CLK_EN) ++ CKCTL_6368_NAND_EN | \ ++ CKCTL_6368_IPSEC_EN) + + /* System PLL Control register */ + #define PERF_SYS_PLL_CTL_REG 0x8 diff --git a/target/linux/brcm63xx/patches-3.3/003-MIPS-BCM63XX-add-IRQ_SPI-and-CPU-specific-SPI-IRQ-va.patch b/target/linux/brcm63xx/patches-3.3/003-MIPS-BCM63XX-add-IRQ_SPI-and-CPU-specific-SPI-IRQ-va.patch new file mode 100644 index 000000000..b4c787c52 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/003-MIPS-BCM63XX-add-IRQ_SPI-and-CPU-specific-SPI-IRQ-va.patch @@ -0,0 +1,68 @@ +From 04456614952a9a848192253439b4e361f0321cb5 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:39:51 +0100 +Subject: [PATCH 05/63] MIPS: BCM63XX: add IRQ_SPI and CPU specific SPI IRQ values + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -478,6 +478,7 @@ static inline unsigned long bcm63xx_regs + */ + enum bcm63xx_irq { + IRQ_TIMER = 0, ++ IRQ_SPI, + IRQ_UART0, + IRQ_UART1, + IRQ_DSL, +@@ -509,6 +510,7 @@ enum bcm63xx_irq { + * 6338 irqs + */ + #define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) ++#define BCM_6338_SPI_IRQ (IRQ_INTERNAL_BASE + 1) + #define BCM_6338_UART0_IRQ (IRQ_INTERNAL_BASE + 2) + #define BCM_6338_UART1_IRQ 0 + #define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5) +@@ -539,6 +541,7 @@ enum bcm63xx_irq { + * 6345 irqs + */ + #define BCM_6345_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) ++#define BCM_6345_SPI_IRQ 0 + #define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2) + #define BCM_6345_UART1_IRQ 0 + #define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3) +@@ -569,6 +572,7 @@ enum bcm63xx_irq { + * 6348 irqs + */ + #define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) ++#define BCM_6348_SPI_IRQ (IRQ_INTERNAL_BASE + 1) + #define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2) + #define BCM_6348_UART1_IRQ 0 + #define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4) +@@ -599,6 +603,7 @@ enum bcm63xx_irq { + * 6358 irqs + */ + #define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) ++#define BCM_6358_SPI_IRQ (IRQ_INTERNAL_BASE + 1) + #define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2) + #define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3) + #define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29) +@@ -638,6 +643,7 @@ enum bcm63xx_irq { + #define BCM_6368_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32) + + #define BCM_6368_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) ++#define BCM_6368_SPI_IRQ (IRQ_INTERNAL_BASE + 1) + #define BCM_6368_UART0_IRQ (IRQ_INTERNAL_BASE + 2) + #define BCM_6368_UART1_IRQ (IRQ_INTERNAL_BASE + 3) + #define BCM_6368_DSL_IRQ (IRQ_INTERNAL_BASE + 4) +@@ -677,6 +683,7 @@ extern const int *bcm63xx_irqs; + + #define __GEN_CPU_IRQ_TABLE(__cpu) \ + [IRQ_TIMER] = BCM_## __cpu ##_TIMER_IRQ, \ ++ [IRQ_SPI] = BCM_## __cpu ##_SPI_IRQ, \ + [IRQ_UART0] = BCM_## __cpu ##_UART0_IRQ, \ + [IRQ_UART1] = BCM_## __cpu ##_UART1_IRQ, \ + [IRQ_DSL] = BCM_## __cpu ##_DSL_IRQ, \ diff --git a/target/linux/brcm63xx/patches-3.3/004-MIPS-BCM63XX-define-BCM6358-SPI-base-address.patch b/target/linux/brcm63xx/patches-3.3/004-MIPS-BCM63XX-define-BCM6358-SPI-base-address.patch new file mode 100644 index 000000000..0c314da74 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/004-MIPS-BCM63XX-define-BCM6358-SPI-base-address.patch @@ -0,0 +1,21 @@ +From bfd78dda2ad5afb4434ebe99c05528614065bdb1 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:39:56 +0100 +Subject: [PATCH 06/63] MIPS: BCM63XX: define BCM6358 SPI base address + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -289,7 +289,7 @@ enum bcm63xx_regs_set { + #define BCM_6358_UART0_BASE (0xfffe0100) + #define BCM_6358_UART1_BASE (0xfffe0120) + #define BCM_6358_GPIO_BASE (0xfffe0080) +-#define BCM_6358_SPI_BASE (0xdeadbeef) ++#define BCM_6358_SPI_BASE (0xfffe0800) + #define BCM_6358_SPI2_BASE (0xfffe0800) + #define BCM_6358_UDC0_BASE (0xfffe0800) + #define BCM_6358_OHCI0_BASE (0xfffe1400) diff --git a/target/linux/brcm63xx/patches-3.3/005-MIPS-BCM63XX-add-BCM6368-SPI-clock-mask.patch b/target/linux/brcm63xx/patches-3.3/005-MIPS-BCM63XX-add-BCM6368-SPI-clock-mask.patch new file mode 100644 index 000000000..b7fac8448 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/005-MIPS-BCM63XX-add-BCM6368-SPI-clock-mask.patch @@ -0,0 +1,26 @@ +From 9b990ee00f70bdd6a731dbe264d5acb453a6c5e2 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:39:57 +0100 +Subject: [PATCH 07/63] MIPS: BCM63XX: add BCM6368 SPI clock mask + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/bcm63xx/clk.c | 6 ++++-- + 1 files changed, 4 insertions(+), 2 deletions(-) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -181,9 +181,11 @@ static void spi_set(struct clk *clk, int + mask = CKCTL_6338_SPI_EN; + else if (BCMCPU_IS_6348()) + mask = CKCTL_6348_SPI_EN; +- else +- /* BCMCPU_IS_6358 */ ++ else if (BCMCPU_IS_6358()) + mask = CKCTL_6358_SPI_EN; ++ else ++ /* BCMCPU_IS_6368 */ ++ mask = CKCTL_6368_SPI_EN; + bcm_hwclock_set(mask, enable); + } + diff --git a/target/linux/brcm63xx/patches-3.3/006-MIPS-BCM63XX-define-SPI-register-sizes.patch b/target/linux/brcm63xx/patches-3.3/006-MIPS-BCM63XX-define-SPI-register-sizes.patch new file mode 100644 index 000000000..0eab43a18 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/006-MIPS-BCM63XX-define-SPI-register-sizes.patch @@ -0,0 +1,26 @@ +From 16ba44545156e4e7cc1e812ad93e562ce92fd74c Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:40:00 +0100 +Subject: [PATCH 08/63] MIPS: BCM63XX: define SPI register sizes. + +There are two distinct sizes for the SPI register depending on the SoC +generation (6338 & 6348 vs 6358 & 6368). + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -135,6 +135,10 @@ enum bcm63xx_regs_set { + #define RSET_DSL_LMEM_SIZE (64 * 1024 * 4) + #define RSET_DSL_SIZE 4096 + #define RSET_WDT_SIZE 12 ++#define BCM_6338_RSET_SPI_SIZE 64 ++#define BCM_6348_RSET_SPI_SIZE 64 ++#define BCM_6358_RSET_SPI_SIZE 1804 ++#define BCM_6368_RSET_SPI_SIZE 1804 + #define RSET_ENET_SIZE 2048 + #define RSET_ENETDMA_SIZE 2048 + #define RSET_ENETSW_SIZE 65536 diff --git a/target/linux/brcm63xx/patches-3.3/007-MIPS-BCM63XX-remove-SPI2-register.patch b/target/linux/brcm63xx/patches-3.3/007-MIPS-BCM63XX-remove-SPI2-register.patch new file mode 100644 index 000000000..cafef10db --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/007-MIPS-BCM63XX-remove-SPI2-register.patch @@ -0,0 +1,83 @@ +From 32511e7dfab9b9cabe2772e3f5430559294a8d1c Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:40:01 +0100 +Subject: [PATCH 09/63] MIPS: BCM63XX: remove SPI2 register + +This register was introduced with the support of the BCM6368 CPU in the idea +that its internal layout was different from the other CPUs SPI controller. +The controller is actually the same as the one present on BCM6358 so we can +remove this register and use the usual SPI register instead. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 10 +--------- + 1 files changed, 1 insertions(+), 9 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -102,7 +102,6 @@ enum bcm63xx_regs_set { + RSET_UART1, + RSET_GPIO, + RSET_SPI, +- RSET_SPI2, + RSET_UDC0, + RSET_OHCI0, + RSET_OHCI_PRIV, +@@ -166,7 +165,6 @@ enum bcm63xx_regs_set { + #define BCM_6338_UART1_BASE (0xdeadbeef) + #define BCM_6338_GPIO_BASE (0xfffe0400) + #define BCM_6338_SPI_BASE (0xfffe0c00) +-#define BCM_6338_SPI2_BASE (0xdeadbeef) + #define BCM_6338_UDC0_BASE (0xdeadbeef) + #define BCM_6338_USBDMA_BASE (0xfffe2400) + #define BCM_6338_OHCI0_BASE (0xdeadbeef) +@@ -210,7 +208,6 @@ enum bcm63xx_regs_set { + #define BCM_6345_UART1_BASE (0xdeadbeef) + #define BCM_6345_GPIO_BASE (0xfffe0400) + #define BCM_6345_SPI_BASE (0xdeadbeef) +-#define BCM_6345_SPI2_BASE (0xdeadbeef) + #define BCM_6345_UDC0_BASE (0xdeadbeef) + #define BCM_6345_USBDMA_BASE (0xfffe2800) + #define BCM_6345_ENET0_BASE (0xfffe1800) +@@ -253,7 +250,6 @@ enum bcm63xx_regs_set { + #define BCM_6348_UART1_BASE (0xdeadbeef) + #define BCM_6348_GPIO_BASE (0xfffe0400) + #define BCM_6348_SPI_BASE (0xfffe0c00) +-#define BCM_6348_SPI2_BASE (0xdeadbeef) + #define BCM_6348_UDC0_BASE (0xfffe1000) + #define BCM_6348_OHCI0_BASE (0xfffe1b00) + #define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00) +@@ -294,7 +290,6 @@ enum bcm63xx_regs_set { + #define BCM_6358_UART1_BASE (0xfffe0120) + #define BCM_6358_GPIO_BASE (0xfffe0080) + #define BCM_6358_SPI_BASE (0xfffe0800) +-#define BCM_6358_SPI2_BASE (0xfffe0800) + #define BCM_6358_UDC0_BASE (0xfffe0800) + #define BCM_6358_OHCI0_BASE (0xfffe1400) + #define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef) +@@ -335,8 +330,7 @@ enum bcm63xx_regs_set { + #define BCM_6368_UART0_BASE (0xb0000100) + #define BCM_6368_UART1_BASE (0xb0000120) + #define BCM_6368_GPIO_BASE (0xb0000080) +-#define BCM_6368_SPI_BASE (0xdeadbeef) +-#define BCM_6368_SPI2_BASE (0xb0000800) ++#define BCM_6368_SPI_BASE (0xb0000800) + #define BCM_6368_UDC0_BASE (0xdeadbeef) + #define BCM_6368_OHCI0_BASE (0xb0001600) + #define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef) +@@ -383,7 +377,6 @@ extern const unsigned long *bcm63xx_regs + __GEN_RSET_BASE(__cpu, UART1) \ + __GEN_RSET_BASE(__cpu, GPIO) \ + __GEN_RSET_BASE(__cpu, SPI) \ +- __GEN_RSET_BASE(__cpu, SPI2) \ + __GEN_RSET_BASE(__cpu, UDC0) \ + __GEN_RSET_BASE(__cpu, OHCI0) \ + __GEN_RSET_BASE(__cpu, OHCI_PRIV) \ +@@ -422,7 +415,6 @@ extern const unsigned long *bcm63xx_regs + [RSET_UART1] = BCM_## __cpu ##_UART1_BASE, \ + [RSET_GPIO] = BCM_## __cpu ##_GPIO_BASE, \ + [RSET_SPI] = BCM_## __cpu ##_SPI_BASE, \ +- [RSET_SPI2] = BCM_## __cpu ##_SPI2_BASE, \ + [RSET_UDC0] = BCM_## __cpu ##_UDC0_BASE, \ + [RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \ + [RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \ diff --git a/target/linux/brcm63xx/patches-3.3/008-MIPS-BCM63XX-define-internal-registers-offsets-of-th.patch b/target/linux/brcm63xx/patches-3.3/008-MIPS-BCM63XX-define-internal-registers-offsets-of-th.patch new file mode 100644 index 000000000..d3968fc81 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/008-MIPS-BCM63XX-define-internal-registers-offsets-of-th.patch @@ -0,0 +1,140 @@ +From 81f9e7d6aa1dde65483387ba9e9823ef44f90435 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:40:03 +0100 +Subject: [PATCH 10/63] MIPS: BCM63XX: define internal registers offsets of the SPI controller + +BCM6338, BCM6348, BCM6358 and BCM6368 basically use the same SPI controller +though the internal registers are shuffled, which still allows a common +driver to drive that IP block. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 119 +++++++++++++++++++++ + 1 files changed, 119 insertions(+), 0 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -973,4 +973,123 @@ + #define M2M_SRCID_REG(x) ((x) * 0x40 + 0x14) + #define M2M_DSTID_REG(x) ((x) * 0x40 + 0x18) + ++/************************************************************************* ++ * _REG relative to RSET_SPI ++ *************************************************************************/ ++ ++/* BCM 6338 SPI core */ ++#define SPI_6338_CMD 0x00 /* 16-bits register */ ++#define SPI_6338_INT_STATUS 0x02 ++#define SPI_6338_INT_MASK_ST 0x03 ++#define SPI_6338_INT_MASK 0x04 ++#define SPI_6338_ST 0x05 ++#define SPI_6338_CLK_CFG 0x06 ++#define SPI_6338_FILL_BYTE 0x07 ++#define SPI_6338_MSG_TAIL 0x09 ++#define SPI_6338_RX_TAIL 0x0b ++#define SPI_6338_MSG_CTL 0x40 ++#define SPI_6338_MSG_DATA 0x41 ++#define SPI_6338_MSG_DATA_SIZE 0x3f ++#define SPI_6338_RX_DATA 0x80 ++#define SPI_6338_RX_DATA_SIZE 0x3f ++ ++/* BCM 6348 SPI core */ ++#define SPI_6348_CMD 0x00 /* 16-bits register */ ++#define SPI_6348_INT_STATUS 0x02 ++#define SPI_6348_INT_MASK_ST 0x03 ++#define SPI_6348_INT_MASK 0x04 ++#define SPI_6348_ST 0x05 ++#define SPI_6348_CLK_CFG 0x06 ++#define SPI_6348_FILL_BYTE 0x07 ++#define SPI_6348_MSG_TAIL 0x09 ++#define SPI_6348_RX_TAIL 0x0b ++#define SPI_6348_MSG_CTL 0x40 ++#define SPI_6348_MSG_DATA 0x41 ++#define SPI_6348_MSG_DATA_SIZE 0x3f ++#define SPI_6348_RX_DATA 0x80 ++#define SPI_6348_RX_DATA_SIZE 0x3f ++ ++/* BCM 6358 SPI core */ ++#define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ ++#define SPI_6358_MSG_DATA 0x02 ++#define SPI_6358_MSG_DATA_SIZE 0x21e ++#define SPI_6358_RX_DATA 0x400 ++#define SPI_6358_RX_DATA_SIZE 0x220 ++#define SPI_6358_CMD 0x700 /* 16-bits register */ ++#define SPI_6358_INT_STATUS 0x702 ++#define SPI_6358_INT_MASK_ST 0x703 ++#define SPI_6358_INT_MASK 0x704 ++#define SPI_6358_ST 0x705 ++#define SPI_6358_CLK_CFG 0x706 ++#define SPI_6358_FILL_BYTE 0x707 ++#define SPI_6358_MSG_TAIL 0x709 ++#define SPI_6358_RX_TAIL 0x70B ++ ++/* BCM 6358 SPI core */ ++#define SPI_6368_MSG_CTL 0x00 /* 16-bits register */ ++#define SPI_6368_MSG_DATA 0x02 ++#define SPI_6368_MSG_DATA_SIZE 0x21e ++#define SPI_6368_RX_DATA 0x400 ++#define SPI_6368_RX_DATA_SIZE 0x220 ++#define SPI_6368_CMD 0x700 /* 16-bits register */ ++#define SPI_6368_INT_STATUS 0x702 ++#define SPI_6368_INT_MASK_ST 0x703 ++#define SPI_6368_INT_MASK 0x704 ++#define SPI_6368_ST 0x705 ++#define SPI_6368_CLK_CFG 0x706 ++#define SPI_6368_FILL_BYTE 0x707 ++#define SPI_6368_MSG_TAIL 0x709 ++#define SPI_6368_RX_TAIL 0x70B ++ ++/* Shared SPI definitions */ ++ ++/* Message configuration */ ++#define SPI_FD_RW 0x00 ++#define SPI_HD_W 0x01 ++#define SPI_HD_R 0x02 ++#define SPI_BYTE_CNT_SHIFT 0 ++#define SPI_MSG_TYPE_SHIFT 14 ++ ++/* Command */ ++#define SPI_CMD_NOOP 0x00 ++#define SPI_CMD_SOFT_RESET 0x01 ++#define SPI_CMD_HARD_RESET 0x02 ++#define SPI_CMD_START_IMMEDIATE 0x03 ++#define SPI_CMD_COMMAND_SHIFT 0 ++#define SPI_CMD_COMMAND_MASK 0x000f ++#define SPI_CMD_DEVICE_ID_SHIFT 4 ++#define SPI_CMD_PREPEND_BYTE_CNT_SHIFT 8 ++#define SPI_CMD_ONE_BYTE_SHIFT 11 ++#define SPI_CMD_ONE_WIRE_SHIFT 12 ++#define SPI_DEV_ID_0 0 ++#define SPI_DEV_ID_1 1 ++#define SPI_DEV_ID_2 2 ++#define SPI_DEV_ID_3 3 ++ ++/* Interrupt mask */ ++#define SPI_INTR_CMD_DONE 0x01 ++#define SPI_INTR_RX_OVERFLOW 0x02 ++#define SPI_INTR_TX_UNDERFLOW 0x04 ++#define SPI_INTR_TX_OVERFLOW 0x08 ++#define SPI_INTR_RX_UNDERFLOW 0x10 ++#define SPI_INTR_CLEAR_ALL 0x1f ++ ++/* Status */ ++#define SPI_RX_EMPTY 0x02 ++#define SPI_CMD_BUSY 0x04 ++#define SPI_SERIAL_BUSY 0x08 ++ ++/* Clock configuration */ ++#define SPI_CLK_20MHZ 0x00 ++#define SPI_CLK_0_391MHZ 0x01 ++#define SPI_CLK_0_781MHZ 0x02 /* default */ ++#define SPI_CLK_1_563MHZ 0x03 ++#define SPI_CLK_3_125MHZ 0x04 ++#define SPI_CLK_6_250MHZ 0x05 ++#define SPI_CLK_12_50MHZ 0x06 ++#define SPI_CLK_MASK 0x07 ++#define SPI_SSOFFTIME_MASK 0x38 ++#define SPI_SSOFFTIME_SHIFT 3 ++#define SPI_BYTE_SWAP 0x80 ++ + #endif /* BCM63XX_REGS_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/009-MIPS-BCM63XX-add-stub-to-register-the-SPI-platform-d.patch b/target/linux/brcm63xx/patches-3.3/009-MIPS-BCM63XX-add-stub-to-register-the-SPI-platform-d.patch new file mode 100644 index 000000000..a46041fd6 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/009-MIPS-BCM63XX-add-stub-to-register-the-SPI-platform-d.patch @@ -0,0 +1,243 @@ +From af84327888c7081662a6b949754fc54d32a50503 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:40:04 +0100 +Subject: [PATCH 11/63] MIPS: BCM63XX: add stub to register the SPI platform driver + +This patch adds the necessary stub to register the SPI platform driver. +Since the registers are shuffled between the 4 BCM63xx CPUs supported by +this SPI driver we also need to generate the internal register layout and +export this layout for the driver to use it properly. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/bcm63xx/Makefile | 3 +- + arch/mips/bcm63xx/dev-spi.c | 119 ++++++++++++++++++++ + .../include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | 89 +++++++++++++++ + 3 files changed, 210 insertions(+), 1 deletions(-) + create mode 100644 arch/mips/bcm63xx/dev-spi.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,5 +1,6 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ +- dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o ++ dev-dsp.o dev-enet.o dev-pcmcia.o dev-spi.o dev-uart.o \ ++ dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- /dev/null ++++ b/arch/mips/bcm63xx/dev-spi.c +@@ -0,0 +1,119 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org> ++ * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com> ++ */ ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/export.h> ++#include <linux/platform_device.h> ++#include <linux/err.h> ++#include <linux/clk.h> ++ ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_dev_spi.h> ++#include <bcm63xx_regs.h> ++ ++#ifdef BCMCPU_RUNTIME_DETECT ++/* ++ * register offsets ++ */ ++static const unsigned long bcm6338_regs_spi[] = { ++ __GEN_SPI_REGS_TABLE(6338) ++}; ++ ++static const unsigned long bcm6348_regs_spi[] = { ++ __GEN_SPI_REGS_TABLE(6348) ++}; ++ ++static const unsigned long bcm6358_regs_spi[] = { ++ __GEN_SPI_REGS_TABLE(6358) ++}; ++ ++static const unsigned long bcm6368_regs_spi[] = { ++ __GEN_SPI_REGS_TABLE(6368) ++}; ++ ++const unsigned long *bcm63xx_regs_spi; ++EXPORT_SYMBOL(bcm63xx_regs_spi); ++ ++static __init void bcm63xx_spi_regs_init(void) ++{ ++ if (BCMCPU_IS_6338()) ++ bcm63xx_regs_spi = bcm6338_regs_spi; ++ if (BCMCPU_IS_6348()) ++ bcm63xx_regs_spi = bcm6348_regs_spi; ++ if (BCMCPU_IS_6358()) ++ bcm63xx_regs_spi = bcm6358_regs_spi; ++ if (BCMCPU_IS_6368()) ++ bcm63xx_regs_spi = bcm6368_regs_spi; ++} ++#else ++static __init void bcm63xx_spi_regs_init(void) { } ++#endif ++ ++static struct resource spi_resources[] = { ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = -1, /* filled at runtime */ ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct bcm63xx_spi_pdata spi_pdata = { ++ .bus_num = 0, ++ .num_chipselect = 8, ++}; ++ ++static struct platform_device bcm63xx_spi_device = { ++ .name = "bcm63xx-spi", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(spi_resources), ++ .resource = spi_resources, ++ .dev = { ++ .platform_data = &spi_pdata, ++ }, ++}; ++ ++int __init bcm63xx_spi_register(void) ++{ ++ struct clk *periph_clk; ++ ++ if (BCMCPU_IS_6345()) ++ return -ENODEV; ++ ++ periph_clk = clk_get(NULL, "periph"); ++ if (IS_ERR(periph_clk)) { ++ pr_err("unable to get periph clock\n"); ++ return -ENODEV; ++ } ++ ++ /* Set bus frequency */ ++ spi_pdata.speed_hz = clk_get_rate(periph_clk); ++ ++ spi_resources[0].start = bcm63xx_regset_address(RSET_SPI); ++ spi_resources[0].end = spi_resources[0].start; ++ spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); ++ ++ if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { ++ spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1; ++ spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE; ++ } ++ ++ if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { ++ spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; ++ spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; ++ } ++ ++ bcm63xx_spi_regs_init(); ++ ++ return platform_device_register(&bcm63xx_spi_device); ++} +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +@@ -0,0 +1,89 @@ ++#ifndef BCM63XX_DEV_SPI_H ++#define BCM63XX_DEV_SPI_H ++ ++#include <linux/types.h> ++#include <bcm63xx_io.h> ++#include <bcm63xx_regs.h> ++ ++int __init bcm63xx_spi_register(void); ++ ++struct bcm63xx_spi_pdata { ++ unsigned int fifo_size; ++ int bus_num; ++ int num_chipselect; ++ u32 speed_hz; ++}; ++ ++enum bcm63xx_regs_spi { ++ SPI_CMD, ++ SPI_INT_STATUS, ++ SPI_INT_MASK_ST, ++ SPI_INT_MASK, ++ SPI_ST, ++ SPI_CLK_CFG, ++ SPI_FILL_BYTE, ++ SPI_MSG_TAIL, ++ SPI_RX_TAIL, ++ SPI_MSG_CTL, ++ SPI_MSG_DATA, ++ SPI_RX_DATA, ++}; ++ ++#define __GEN_SPI_RSET_BASE(__cpu, __rset) \ ++ case SPI_## __rset: \ ++ return SPI_## __cpu ##_## __rset; ++ ++#define __GEN_SPI_RSET(__cpu) \ ++ switch (reg) { \ ++ __GEN_SPI_RSET_BASE(__cpu, CMD) \ ++ __GEN_SPI_RSET_BASE(__cpu, INT_STATUS) \ ++ __GEN_SPI_RSET_BASE(__cpu, INT_MASK_ST) \ ++ __GEN_SPI_RSET_BASE(__cpu, INT_MASK) \ ++ __GEN_SPI_RSET_BASE(__cpu, ST) \ ++ __GEN_SPI_RSET_BASE(__cpu, CLK_CFG) \ ++ __GEN_SPI_RSET_BASE(__cpu, FILL_BYTE) \ ++ __GEN_SPI_RSET_BASE(__cpu, MSG_TAIL) \ ++ __GEN_SPI_RSET_BASE(__cpu, RX_TAIL) \ ++ __GEN_SPI_RSET_BASE(__cpu, MSG_CTL) \ ++ __GEN_SPI_RSET_BASE(__cpu, MSG_DATA) \ ++ __GEN_SPI_RSET_BASE(__cpu, RX_DATA) \ ++ } ++ ++#define __GEN_SPI_REGS_TABLE(__cpu) \ ++ [SPI_CMD] = SPI_## __cpu ##_CMD, \ ++ [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \ ++ [SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \ ++ [SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \ ++ [SPI_ST] = SPI_## __cpu ##_ST, \ ++ [SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \ ++ [SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \ ++ [SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \ ++ [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \ ++ [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \ ++ [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \ ++ [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA, ++ ++static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) ++{ ++#ifdef BCMCPU_RUNTIME_DETECT ++ extern const unsigned long *bcm63xx_regs_spi; ++ ++ return bcm63xx_regs_spi[reg]; ++#else ++#ifdef CONFIG_BCM63XX_CPU_6338 ++ __GEN_SPI_RSET(6338) ++#endif ++#ifdef CONFIG_BCM63XX_CPU_6348 ++ __GEN_SPI_RSET(6348) ++#endif ++#ifdef CONFIG_BCM63XX_CPU_6358 ++ __GEN_SPI_RSET(6358) ++#endif ++#ifdef CONFIG_BCM63XX_CPU_6368 ++ __GEN_SPI_RSET(6368) ++#endif ++#endif ++ return 0; ++} ++ ++#endif /* BCM63XX_DEV_SPI_H */ diff --git a/target/linux/brcm63xx/patches-3.3/010-MIPS-BCM63XX-make-board-setup-code-register-the-spi-.patch b/target/linux/brcm63xx/patches-3.3/010-MIPS-BCM63XX-make-board-setup-code-register-the-spi-.patch new file mode 100644 index 000000000..516569679 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/010-MIPS-BCM63XX-make-board-setup-code-register-the-spi-.patch @@ -0,0 +1,29 @@ +From fab0cbda27ab2400d6a461bf144007a0d5337527 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:40:05 +0100 +Subject: [PATCH 12/63] MIPS: BCM63XX: make board setup code register the spi platform device + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -25,6 +25,7 @@ + #include <bcm63xx_dev_enet.h> + #include <bcm63xx_dev_dsp.h> + #include <bcm63xx_dev_pcmcia.h> ++#include <bcm63xx_dev_spi.h> + #include <board_bcm963xx.h> + + #define PFX "board_bcm963xx: " +@@ -890,6 +891,8 @@ int __init board_register_devices(void) + } + #endif + ++ bcm63xx_spi_register(); ++ + /* read base address of boot chip select (0) */ + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); + val &= MPI_CSBASE_BASE_MASK; diff --git a/target/linux/brcm63xx/patches-3.3/011-spi-add-Broadcom-BCM63xx-SPI-controller-driver.patch b/target/linux/brcm63xx/patches-3.3/011-spi-add-Broadcom-BCM63xx-SPI-controller-driver.patch new file mode 100644 index 000000000..e4939599a --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/011-spi-add-Broadcom-BCM63xx-SPI-controller-driver.patch @@ -0,0 +1,532 @@ +From 5f592b818a2c5731bb12137e7cffc3aa6e24ee5a Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 1 Feb 2012 09:14:09 +0000 +Subject: [PATCH 13/63] spi: add Broadcom BCM63xx SPI controller driver + +This patch adds support for the SPI controller found on the Broadcom BCM63xx +SoCs. + +Signed-off-by: Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com> +Signed-off-by: Florian Fainelli <florian@openwrt.org> +Acked-by: Grant Likely <grant.likely@secretlab.ca> +--- + drivers/spi/Kconfig | 6 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-bcm63xx.c | 486 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 493 insertions(+), 0 deletions(-) + create mode 100644 drivers/spi/spi-bcm63xx.c + +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -94,6 +94,12 @@ config SPI_AU1550 + If you say yes to this option, support will be included for the + PSC SPI controller found on Au1550, Au1200 and Au1300 series. + ++config SPI_BCM63XX ++ tristate "Broadcom BCM63xx SPI controller" ++ depends on BCM63XX ++ help ++ Enable support for the SPI controller on the Broadcom BCM63xx SoCs. ++ + config SPI_BITBANG + tristate "Utilities for Bitbanging SPI masters" + help +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -14,6 +14,7 @@ obj-$(CONFIG_SPI_ALTERA) += spi-altera. + obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o + obj-$(CONFIG_SPI_ATH79) += spi-ath79.o + obj-$(CONFIG_SPI_AU1550) += spi-au1550.o ++obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o + obj-$(CONFIG_SPI_BFIN) += spi-bfin5xx.o + obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o + obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o +--- /dev/null ++++ b/drivers/spi/spi-bcm63xx.c +@@ -0,0 +1,486 @@ ++/* ++ * Broadcom BCM63xx SPI controller support ++ * ++ * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org> ++ * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com> ++ * ++ * 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., 51 Franklin Street, Fifth Floor, ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/clk.h> ++#include <linux/io.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/delay.h> ++#include <linux/interrupt.h> ++#include <linux/spi/spi.h> ++#include <linux/completion.h> ++#include <linux/err.h> ++ ++#include <bcm63xx_dev_spi.h> ++ ++#define PFX KBUILD_MODNAME ++#define DRV_VER "0.1.2" ++ ++struct bcm63xx_spi { ++ spinlock_t lock; ++ int stopping; ++ struct completion done; ++ ++ void __iomem *regs; ++ int irq; ++ ++ /* Platform data */ ++ u32 speed_hz; ++ unsigned fifo_size; ++ ++ /* Data buffers */ ++ const unsigned char *tx_ptr; ++ unsigned char *rx_ptr; ++ ++ /* data iomem */ ++ u8 __iomem *tx_io; ++ const u8 __iomem *rx_io; ++ ++ int remaining_bytes; ++ ++ struct clk *clk; ++ struct platform_device *pdev; ++}; ++ ++static inline u8 bcm_spi_readb(struct bcm63xx_spi *bs, ++ unsigned int offset) ++{ ++ return bcm_readb(bs->regs + bcm63xx_spireg(offset)); ++} ++ ++static inline u16 bcm_spi_readw(struct bcm63xx_spi *bs, ++ unsigned int offset) ++{ ++ return bcm_readw(bs->regs + bcm63xx_spireg(offset)); ++} ++ ++static inline void bcm_spi_writeb(struct bcm63xx_spi *bs, ++ u8 value, unsigned int offset) ++{ ++ bcm_writeb(value, bs->regs + bcm63xx_spireg(offset)); ++} ++ ++static inline void bcm_spi_writew(struct bcm63xx_spi *bs, ++ u16 value, unsigned int offset) ++{ ++ bcm_writew(value, bs->regs + bcm63xx_spireg(offset)); ++} ++ ++static const unsigned bcm63xx_spi_freq_table[SPI_CLK_MASK][2] = { ++ { 20000000, SPI_CLK_20MHZ }, ++ { 12500000, SPI_CLK_12_50MHZ }, ++ { 6250000, SPI_CLK_6_250MHZ }, ++ { 3125000, SPI_CLK_3_125MHZ }, ++ { 1563000, SPI_CLK_1_563MHZ }, ++ { 781000, SPI_CLK_0_781MHZ }, ++ { 391000, SPI_CLK_0_391MHZ } ++}; ++ ++static int bcm63xx_spi_setup_transfer(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); ++ u8 bits_per_word; ++ u8 clk_cfg, reg; ++ u32 hz; ++ int i; ++ ++ bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; ++ hz = (t) ? t->speed_hz : spi->max_speed_hz; ++ if (bits_per_word != 8) { ++ dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", ++ __func__, bits_per_word); ++ return -EINVAL; ++ } ++ ++ if (spi->chip_select > spi->master->num_chipselect) { ++ dev_err(&spi->dev, "%s, unsupported slave %d\n", ++ __func__, spi->chip_select); ++ return -EINVAL; ++ } ++ ++ /* Find the closest clock configuration */ ++ for (i = 0; i < SPI_CLK_MASK; i++) { ++ if (hz >= bcm63xx_spi_freq_table[i][0]) { ++ clk_cfg = bcm63xx_spi_freq_table[i][1]; ++ break; ++ } ++ } ++ ++ /* No matching configuration found, default to lowest */ ++ if (i == SPI_CLK_MASK) ++ clk_cfg = SPI_CLK_0_391MHZ; ++ ++ /* clear existing clock configuration bits of the register */ ++ reg = bcm_spi_readb(bs, SPI_CLK_CFG); ++ reg &= ~SPI_CLK_MASK; ++ reg |= clk_cfg; ++ ++ bcm_spi_writeb(bs, reg, SPI_CLK_CFG); ++ dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n", ++ clk_cfg, hz); ++ ++ return 0; ++} ++ ++/* the spi->mode bits understood by this driver: */ ++#define MODEBITS (SPI_CPOL | SPI_CPHA) ++ ++static int bcm63xx_spi_setup(struct spi_device *spi) ++{ ++ struct bcm63xx_spi *bs; ++ int ret; ++ ++ bs = spi_master_get_devdata(spi->master); ++ ++ if (bs->stopping) ++ return -ESHUTDOWN; ++ ++ if (!spi->bits_per_word) ++ spi->bits_per_word = 8; ++ ++ if (spi->mode & ~MODEBITS) { ++ dev_err(&spi->dev, "%s, unsupported mode bits %x\n", ++ __func__, spi->mode & ~MODEBITS); ++ return -EINVAL; ++ } ++ ++ ret = bcm63xx_spi_setup_transfer(spi, NULL); ++ if (ret < 0) { ++ dev_err(&spi->dev, "setup: unsupported mode bits %x\n", ++ spi->mode & ~MODEBITS); ++ return ret; ++ } ++ ++ dev_dbg(&spi->dev, "%s, mode %d, %u bits/w, %u nsec/bit\n", ++ __func__, spi->mode & MODEBITS, spi->bits_per_word, 0); ++ ++ return 0; ++} ++ ++/* Fill the TX FIFO with as many bytes as possible */ ++static void bcm63xx_spi_fill_tx_fifo(struct bcm63xx_spi *bs) ++{ ++ u8 size; ++ ++ /* Fill the Tx FIFO with as many bytes as possible */ ++ size = bs->remaining_bytes < bs->fifo_size ? bs->remaining_bytes : ++ bs->fifo_size; ++ memcpy_toio(bs->tx_io, bs->tx_ptr, size); ++ bs->remaining_bytes -= size; ++} ++ ++static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) ++{ ++ struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); ++ u16 msg_ctl; ++ u16 cmd; ++ ++ dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", ++ t->tx_buf, t->rx_buf, t->len); ++ ++ /* Transmitter is inhibited */ ++ bs->tx_ptr = t->tx_buf; ++ bs->rx_ptr = t->rx_buf; ++ init_completion(&bs->done); ++ ++ if (t->tx_buf) { ++ bs->remaining_bytes = t->len; ++ bcm63xx_spi_fill_tx_fifo(bs); ++ } ++ ++ /* Enable the command done interrupt which ++ * we use to determine completion of a command */ ++ bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); ++ ++ /* Fill in the Message control register */ ++ msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); ++ ++ if (t->rx_buf && t->tx_buf) ++ msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT); ++ else if (t->rx_buf) ++ msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT); ++ else if (t->tx_buf) ++ msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT); ++ ++ bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); ++ ++ /* Issue the transfer */ ++ cmd = SPI_CMD_START_IMMEDIATE; ++ cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); ++ cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT); ++ bcm_spi_writew(bs, cmd, SPI_CMD); ++ wait_for_completion(&bs->done); ++ ++ /* Disable the CMD_DONE interrupt */ ++ bcm_spi_writeb(bs, 0, SPI_INT_MASK); ++ ++ return t->len - bs->remaining_bytes; ++} ++ ++static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m) ++{ ++ struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); ++ struct spi_transfer *t; ++ int ret = 0; ++ ++ if (unlikely(list_empty(&m->transfers))) ++ return -EINVAL; ++ ++ if (bs->stopping) ++ return -ESHUTDOWN; ++ ++ list_for_each_entry(t, &m->transfers, transfer_list) { ++ ret += bcm63xx_txrx_bufs(spi, t); ++ } ++ ++ m->complete(m->context); ++ ++ return ret; ++} ++ ++/* This driver supports single master mode only. Hence ++ * CMD_DONE is the only interrupt we care about ++ */ ++static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id) ++{ ++ struct spi_master *master = (struct spi_master *)dev_id; ++ struct bcm63xx_spi *bs = spi_master_get_devdata(master); ++ u8 intr; ++ u16 cmd; ++ ++ /* Read interupts and clear them immediately */ ++ intr = bcm_spi_readb(bs, SPI_INT_STATUS); ++ bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); ++ bcm_spi_writeb(bs, 0, SPI_INT_MASK); ++ ++ /* A tansfer completed */ ++ if (intr & SPI_INTR_CMD_DONE) { ++ u8 rx_tail; ++ ++ rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); ++ ++ /* Read out all the data */ ++ if (rx_tail) ++ memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); ++ ++ /* See if there is more data to send */ ++ if (bs->remaining_bytes > 0) { ++ bcm63xx_spi_fill_tx_fifo(bs); ++ ++ /* Start the transfer */ ++ bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT, ++ SPI_MSG_CTL); ++ cmd = bcm_spi_readw(bs, SPI_CMD); ++ cmd |= SPI_CMD_START_IMMEDIATE; ++ cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); ++ bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); ++ bcm_spi_writew(bs, cmd, SPI_CMD); ++ } else { ++ complete(&bs->done); ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++ ++static int __devinit bcm63xx_spi_probe(struct platform_device *pdev) ++{ ++ struct resource *r; ++ struct device *dev = &pdev->dev; ++ struct bcm63xx_spi_pdata *pdata = pdev->dev.platform_data; ++ int irq; ++ struct spi_master *master; ++ struct clk *clk; ++ struct bcm63xx_spi *bs; ++ int ret; ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!r) { ++ dev_err(dev, "no iomem\n"); ++ ret = -ENXIO; ++ goto out; ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "no irq\n"); ++ ret = -ENXIO; ++ goto out; ++ } ++ ++ clk = clk_get(dev, "spi"); ++ if (IS_ERR(clk)) { ++ dev_err(dev, "no clock for device\n"); ++ ret = PTR_ERR(clk); ++ goto out; ++ } ++ ++ master = spi_alloc_master(dev, sizeof(*bs)); ++ if (!master) { ++ dev_err(dev, "out of memory\n"); ++ ret = -ENOMEM; ++ goto out_clk; ++ } ++ ++ bs = spi_master_get_devdata(master); ++ init_completion(&bs->done); ++ ++ platform_set_drvdata(pdev, master); ++ bs->pdev = pdev; ++ ++ if (!devm_request_mem_region(&pdev->dev, r->start, ++ resource_size(r), PFX)) { ++ dev_err(dev, "iomem request failed\n"); ++ ret = -ENXIO; ++ goto out_err; ++ } ++ ++ bs->regs = devm_ioremap_nocache(&pdev->dev, r->start, ++ resource_size(r)); ++ if (!bs->regs) { ++ dev_err(dev, "unable to ioremap regs\n"); ++ ret = -ENOMEM; ++ goto out_err; ++ } ++ ++ bs->irq = irq; ++ bs->clk = clk; ++ bs->fifo_size = pdata->fifo_size; ++ ++ ret = devm_request_irq(&pdev->dev, irq, bcm63xx_spi_interrupt, 0, ++ pdev->name, master); ++ if (ret) { ++ dev_err(dev, "unable to request irq\n"); ++ goto out_err; ++ } ++ ++ master->bus_num = pdata->bus_num; ++ master->num_chipselect = pdata->num_chipselect; ++ master->setup = bcm63xx_spi_setup; ++ master->transfer = bcm63xx_transfer; ++ bs->speed_hz = pdata->speed_hz; ++ bs->stopping = 0; ++ bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); ++ bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); ++ spin_lock_init(&bs->lock); ++ ++ /* Initialize hardware */ ++ clk_enable(bs->clk); ++ bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); ++ ++ /* register and we are done */ ++ ret = spi_register_master(master); ++ if (ret) { ++ dev_err(dev, "spi register failed\n"); ++ goto out_clk_disable; ++ } ++ ++ dev_info(dev, "at 0x%08x (irq %d, FIFOs size %d) v%s\n", ++ r->start, irq, bs->fifo_size, DRV_VER); ++ ++ return 0; ++ ++out_clk_disable: ++ clk_disable(clk); ++out_err: ++ platform_set_drvdata(pdev, NULL); ++ spi_master_put(master); ++out_clk: ++ clk_put(clk); ++out: ++ return ret; ++} ++ ++static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) ++{ ++ struct spi_master *master = platform_get_drvdata(pdev); ++ struct bcm63xx_spi *bs = spi_master_get_devdata(master); ++ ++ /* reset spi block */ ++ bcm_spi_writeb(bs, 0, SPI_INT_MASK); ++ spin_lock(&bs->lock); ++ bs->stopping = 1; ++ ++ /* HW shutdown */ ++ clk_disable(bs->clk); ++ clk_put(bs->clk); ++ ++ spin_unlock(&bs->lock); ++ platform_set_drvdata(pdev, 0); ++ spi_unregister_master(master); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int bcm63xx_spi_suspend(struct device *dev) ++{ ++ struct spi_master *master = ++ platform_get_drvdata(to_platform_device(dev)); ++ struct bcm63xx_spi *bs = spi_master_get_devdata(master); ++ ++ clk_disable(bs->clk); ++ ++ return 0; ++} ++ ++static int bcm63xx_spi_resume(struct device *dev) ++{ ++ struct spi_master *master = ++ platform_get_drvdata(to_platform_device(dev)); ++ struct bcm63xx_spi *bs = spi_master_get_devdata(master); ++ ++ clk_enable(bs->clk); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops bcm63xx_spi_pm_ops = { ++ .suspend = bcm63xx_spi_suspend, ++ .resume = bcm63xx_spi_resume, ++}; ++ ++#define BCM63XX_SPI_PM_OPS (&bcm63xx_spi_pm_ops) ++#else ++#define BCM63XX_SPI_PM_OPS NULL ++#endif ++ ++static struct platform_driver bcm63xx_spi_driver = { ++ .driver = { ++ .name = "bcm63xx-spi", ++ .owner = THIS_MODULE, ++ .pm = BCM63XX_SPI_PM_OPS, ++ }, ++ .probe = bcm63xx_spi_probe, ++ .remove = __devexit_p(bcm63xx_spi_remove), ++}; ++ ++module_platform_driver(bcm63xx_spi_driver); ++ ++MODULE_ALIAS("platform:bcm63xx_spi"); ++MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); ++MODULE_AUTHOR("Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>"); ++MODULE_DESCRIPTION("Broadcom BCM63xx SPI Controller driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm63xx/patches-3.3/012-mtd-bcm63xxpart-handle-Broadcom-partition-order.patch b/target/linux/brcm63xx/patches-3.3/012-mtd-bcm63xxpart-handle-Broadcom-partition-order.patch new file mode 100644 index 000000000..b12aed6b9 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/012-mtd-bcm63xxpart-handle-Broadcom-partition-order.patch @@ -0,0 +1,101 @@ +From a73c2d9dc7ea0d14fbf48db48e783d123162f5c3 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 19 Apr 2012 13:15:57 +0200 +Subject: [PATCH] mtd: bcm63xxpart: handle Broadcom partition order + +The original Broadcom partition order has the root fs in front of the +kernel, which resulted in miscalculated partition sizes. +Detect when such an image is on the flash and also reorder the partitions +accordingly. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Acked-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@linux.intel.com> +--- + drivers/mtd/bcm63xxpart.c | 41 ++++++++++++++++++++++++++++++----------- + 1 file changed, 30 insertions(+), 11 deletions(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -4,7 +4,7 @@ + * Copyright © 2006-2008 Florian Fainelli <florian@openwrt.org> + * Mike Albon <malbon@openwrt.org> + * Copyright © 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net> +- * Copyright © 2011 Jonas Gorski <jonas.gorski@gmail.com> ++ * Copyright © 2011-2012 Jonas Gorski <jonas.gorski@gmail.com> + * + * 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 +@@ -82,6 +82,7 @@ static int bcm63xx_parse_cfe_partitions( + int namelen = 0; + int i; + u32 computed_crc; ++ bool rootfs_first = false; + + if (bcm63xx_detect_cfe(master)) + return -EINVAL; +@@ -109,6 +110,7 @@ static int bcm63xx_parse_cfe_partitions( + char *boardid = &(buf->board_id[0]); + char *tagversion = &(buf->tag_version[0]); + ++ sscanf(buf->flash_image_start, "%u", &rootfsaddr); + sscanf(buf->kernel_address, "%u", &kerneladdr); + sscanf(buf->kernel_length, "%u", &kernellen); + sscanf(buf->total_length, "%u", &totallen); +@@ -117,10 +119,19 @@ static int bcm63xx_parse_cfe_partitions( + tagversion, boardid); + + kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; +- rootfsaddr = kerneladdr + kernellen; ++ rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; + spareaddr = roundup(totallen, master->erasesize) + cfelen; + sparelen = master->size - spareaddr - nvramlen; +- rootfslen = spareaddr - rootfsaddr; ++ ++ if (rootfsaddr < kerneladdr) { ++ /* default Broadcom layout */ ++ rootfslen = kerneladdr - rootfsaddr; ++ rootfs_first = true; ++ } else { ++ /* OpenWrt layout */ ++ rootfsaddr = kerneladdr + kernellen; ++ rootfslen = spareaddr - rootfsaddr; ++ } + } else { + pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", + buf->header_crc, computed_crc); +@@ -156,18 +167,26 @@ static int bcm63xx_parse_cfe_partitions( + curpart++; + + if (kernellen > 0) { +- parts[curpart].name = "kernel"; +- parts[curpart].offset = kerneladdr; +- parts[curpart].size = kernellen; ++ int kernelpart = curpart; ++ ++ if (rootfslen > 0 && rootfs_first) ++ kernelpart++; ++ parts[kernelpart].name = "kernel"; ++ parts[kernelpart].offset = kerneladdr; ++ parts[kernelpart].size = kernellen; + curpart++; + } + + if (rootfslen > 0) { +- parts[curpart].name = "rootfs"; +- parts[curpart].offset = rootfsaddr; +- parts[curpart].size = rootfslen; +- if (sparelen > 0) +- parts[curpart].size += sparelen; ++ int rootfspart = curpart; ++ ++ if (kernellen > 0 && rootfs_first) ++ rootfspart--; ++ parts[rootfspart].name = "rootfs"; ++ parts[rootfspart].offset = rootfsaddr; ++ parts[rootfspart].size = rootfslen; ++ if (sparelen > 0 && !rootfs_first) ++ parts[rootfspart].size += sparelen; + curpart++; + } + diff --git a/target/linux/brcm63xx/patches-3.3/013-spi-bcm63xx-convert-to-the-pump-message-infrastructu.patch b/target/linux/brcm63xx/patches-3.3/013-spi-bcm63xx-convert-to-the-pump-message-infrastructu.patch new file mode 100644 index 000000000..7d4d9514d --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/013-spi-bcm63xx-convert-to-the-pump-message-infrastructu.patch @@ -0,0 +1,289 @@ +From cde4384e1037c15e5dd04c68d19c75798b6281dd Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Fri, 20 Apr 2012 15:37:33 +0200 +Subject: [PATCH] spi/bcm63xx: convert to the pump message infrastructure + +This patch converts the bcm63xx SPI driver to use the SPI infrastructure +pump message queue. Since we were previously sleeping in the SPI +driver's transfer() function (which is not allowed) this is now fixed as well. + +To complete that conversion a certain number of changes have been made: +- the transfer len is split into multiple hardware transfers in case its + size is bigger than the hardware FIFO size +- the FIFO refill is no longer done in the interrupt context, which was a + bad idea leading to quick interrupt handler re-entrancy + +Tested-by: Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com> +Signed-off-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +--- + drivers/spi/spi-bcm63xx.c | 149 +++++++++++++++++++++++++++------------------ + 1 file changed, 89 insertions(+), 60 deletions(-) + +--- a/drivers/spi/spi-bcm63xx.c ++++ b/drivers/spi/spi-bcm63xx.c +@@ -1,7 +1,7 @@ + /* + * Broadcom BCM63xx SPI controller support + * +- * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org> ++ * Copyright (C) 2009-2012 Florian Fainelli <florian@openwrt.org> + * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com> + * + * This program is free software; you can redistribute it and/or +@@ -30,6 +30,8 @@ + #include <linux/spi/spi.h> + #include <linux/completion.h> + #include <linux/err.h> ++#include <linux/workqueue.h> ++#include <linux/pm_runtime.h> + + #include <bcm63xx_dev_spi.h> + +@@ -96,17 +98,12 @@ static const unsigned bcm63xx_spi_freq_t + { 391000, SPI_CLK_0_391MHZ } + }; + +-static int bcm63xx_spi_setup_transfer(struct spi_device *spi, +- struct spi_transfer *t) ++static int bcm63xx_spi_check_transfer(struct spi_device *spi, ++ struct spi_transfer *t) + { +- struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); + u8 bits_per_word; +- u8 clk_cfg, reg; +- u32 hz; +- int i; + + bits_per_word = (t) ? t->bits_per_word : spi->bits_per_word; +- hz = (t) ? t->speed_hz : spi->max_speed_hz; + if (bits_per_word != 8) { + dev_err(&spi->dev, "%s, unsupported bits_per_word=%d\n", + __func__, bits_per_word); +@@ -119,6 +116,19 @@ static int bcm63xx_spi_setup_transfer(st + return -EINVAL; + } + ++ return 0; ++} ++ ++static void bcm63xx_spi_setup_transfer(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); ++ u32 hz; ++ u8 clk_cfg, reg; ++ int i; ++ ++ hz = (t) ? t->speed_hz : spi->max_speed_hz; ++ + /* Find the closest clock configuration */ + for (i = 0; i < SPI_CLK_MASK; i++) { + if (hz >= bcm63xx_spi_freq_table[i][0]) { +@@ -139,8 +149,6 @@ static int bcm63xx_spi_setup_transfer(st + bcm_spi_writeb(bs, reg, SPI_CLK_CFG); + dev_dbg(&spi->dev, "Setting clock register to %02x (hz %d)\n", + clk_cfg, hz); +- +- return 0; + } + + /* the spi->mode bits understood by this driver: */ +@@ -165,7 +173,7 @@ static int bcm63xx_spi_setup(struct spi_ + return -EINVAL; + } + +- ret = bcm63xx_spi_setup_transfer(spi, NULL); ++ ret = bcm63xx_spi_check_transfer(spi, NULL); + if (ret < 0) { + dev_err(&spi->dev, "setup: unsupported mode bits %x\n", + spi->mode & ~MODEBITS); +@@ -190,28 +198,29 @@ static void bcm63xx_spi_fill_tx_fifo(str + bs->remaining_bytes -= size; + } + +-static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) ++static unsigned int bcm63xx_txrx_bufs(struct spi_device *spi, ++ struct spi_transfer *t) + { + struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); + u16 msg_ctl; + u16 cmd; + ++ /* Disable the CMD_DONE interrupt */ ++ bcm_spi_writeb(bs, 0, SPI_INT_MASK); ++ + dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n", + t->tx_buf, t->rx_buf, t->len); + + /* Transmitter is inhibited */ + bs->tx_ptr = t->tx_buf; + bs->rx_ptr = t->rx_buf; +- init_completion(&bs->done); + + if (t->tx_buf) { + bs->remaining_bytes = t->len; + bcm63xx_spi_fill_tx_fifo(bs); + } + +- /* Enable the command done interrupt which +- * we use to determine completion of a command */ +- bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); ++ init_completion(&bs->done); + + /* Fill in the Message control register */ + msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); +@@ -230,33 +239,76 @@ static int bcm63xx_txrx_bufs(struct spi_ + cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); + cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT); + bcm_spi_writew(bs, cmd, SPI_CMD); +- wait_for_completion(&bs->done); + +- /* Disable the CMD_DONE interrupt */ +- bcm_spi_writeb(bs, 0, SPI_INT_MASK); ++ /* Enable the CMD_DONE interrupt */ ++ bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); + + return t->len - bs->remaining_bytes; + } + +-static int bcm63xx_transfer(struct spi_device *spi, struct spi_message *m) ++static int bcm63xx_spi_prepare_transfer(struct spi_master *master) + { +- struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master); +- struct spi_transfer *t; +- int ret = 0; ++ struct bcm63xx_spi *bs = spi_master_get_devdata(master); + +- if (unlikely(list_empty(&m->transfers))) +- return -EINVAL; ++ pm_runtime_get_sync(&bs->pdev->dev); + +- if (bs->stopping) +- return -ESHUTDOWN; ++ return 0; ++} ++ ++static int bcm63xx_spi_unprepare_transfer(struct spi_master *master) ++{ ++ struct bcm63xx_spi *bs = spi_master_get_devdata(master); ++ ++ pm_runtime_put(&bs->pdev->dev); ++ ++ return 0; ++} ++ ++static int bcm63xx_spi_transfer_one(struct spi_master *master, ++ struct spi_message *m) ++{ ++ struct bcm63xx_spi *bs = spi_master_get_devdata(master); ++ struct spi_transfer *t; ++ struct spi_device *spi = m->spi; ++ int status = 0; ++ unsigned int timeout = 0; + + list_for_each_entry(t, &m->transfers, transfer_list) { +- ret += bcm63xx_txrx_bufs(spi, t); +- } ++ unsigned int len = t->len; ++ u8 rx_tail; + +- m->complete(m->context); ++ status = bcm63xx_spi_check_transfer(spi, t); ++ if (status < 0) ++ goto exit; ++ ++ /* configure adapter for a new transfer */ ++ bcm63xx_spi_setup_transfer(spi, t); ++ ++ while (len) { ++ /* send the data */ ++ len -= bcm63xx_txrx_bufs(spi, t); ++ ++ timeout = wait_for_completion_timeout(&bs->done, HZ); ++ if (!timeout) { ++ status = -ETIMEDOUT; ++ goto exit; ++ } ++ ++ /* read out all data */ ++ rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); ++ ++ /* Read out all the data */ ++ if (rx_tail) ++ memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); ++ } ++ ++ m->actual_length += t->len; ++ } ++exit: ++ m->status = status; ++ spi_finalize_current_message(master); + +- return ret; ++ return 0; + } + + /* This driver supports single master mode only. Hence +@@ -267,39 +319,15 @@ static irqreturn_t bcm63xx_spi_interrupt + struct spi_master *master = (struct spi_master *)dev_id; + struct bcm63xx_spi *bs = spi_master_get_devdata(master); + u8 intr; +- u16 cmd; + + /* Read interupts and clear them immediately */ + intr = bcm_spi_readb(bs, SPI_INT_STATUS); + bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); + bcm_spi_writeb(bs, 0, SPI_INT_MASK); + +- /* A tansfer completed */ +- if (intr & SPI_INTR_CMD_DONE) { +- u8 rx_tail; +- +- rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL); +- +- /* Read out all the data */ +- if (rx_tail) +- memcpy_fromio(bs->rx_ptr, bs->rx_io, rx_tail); +- +- /* See if there is more data to send */ +- if (bs->remaining_bytes > 0) { +- bcm63xx_spi_fill_tx_fifo(bs); +- +- /* Start the transfer */ +- bcm_spi_writew(bs, SPI_HD_W << SPI_MSG_TYPE_SHIFT, +- SPI_MSG_CTL); +- cmd = bcm_spi_readw(bs, SPI_CMD); +- cmd |= SPI_CMD_START_IMMEDIATE; +- cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT); +- bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK); +- bcm_spi_writew(bs, cmd, SPI_CMD); +- } else { +- complete(&bs->done); +- } +- } ++ /* A transfer completed */ ++ if (intr & SPI_INTR_CMD_DONE) ++ complete(&bs->done); + + return IRQ_HANDLED; + } +@@ -345,7 +373,6 @@ static int __devinit bcm63xx_spi_probe(s + } + + bs = spi_master_get_devdata(master); +- init_completion(&bs->done); + + platform_set_drvdata(pdev, master); + bs->pdev = pdev; +@@ -379,7 +406,9 @@ static int __devinit bcm63xx_spi_probe(s + master->bus_num = pdata->bus_num; + master->num_chipselect = pdata->num_chipselect; + master->setup = bcm63xx_spi_setup; +- master->transfer = bcm63xx_transfer; ++ master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer; ++ master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer; ++ master->transfer_one_message = bcm63xx_spi_transfer_one; + bs->speed_hz = pdata->speed_hz; + bs->stopping = 0; + bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); diff --git a/target/linux/brcm63xx/patches-3.3/014-spi-bcm63xx-don-t-use-the-stopping-state.patch b/target/linux/brcm63xx/patches-3.3/014-spi-bcm63xx-don-t-use-the-stopping-state.patch new file mode 100644 index 000000000..98bc90980 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/014-spi-bcm63xx-don-t-use-the-stopping-state.patch @@ -0,0 +1,68 @@ +From 1e41dc0ee2f3807328db95e4f87ff1333245190f Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Fri, 20 Apr 2012 15:37:34 +0200 +Subject: [PATCH] spi/bcm63xx: don't use the stopping state + +We do not need to use a flag to indicate if the master driver is stopping +it is sufficient to perform spi master unregistering in the platform +driver's remove function. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +--- + drivers/spi/spi-bcm63xx.c | 13 ++----------- + 1 file changed, 2 insertions(+), 11 deletions(-) + +--- a/drivers/spi/spi-bcm63xx.c ++++ b/drivers/spi/spi-bcm63xx.c +@@ -39,8 +39,6 @@ + #define DRV_VER "0.1.2" + + struct bcm63xx_spi { +- spinlock_t lock; +- int stopping; + struct completion done; + + void __iomem *regs; +@@ -161,9 +159,6 @@ static int bcm63xx_spi_setup(struct spi_ + + bs = spi_master_get_devdata(spi->master); + +- if (bs->stopping) +- return -ESHUTDOWN; +- + if (!spi->bits_per_word) + spi->bits_per_word = 8; + +@@ -410,10 +405,8 @@ static int __devinit bcm63xx_spi_probe(s + master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer; + master->transfer_one_message = bcm63xx_spi_transfer_one; + bs->speed_hz = pdata->speed_hz; +- bs->stopping = 0; + bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); + bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); +- spin_lock_init(&bs->lock); + + /* Initialize hardware */ + clk_enable(bs->clk); +@@ -447,18 +440,16 @@ static int __devexit bcm63xx_spi_remove( + struct spi_master *master = platform_get_drvdata(pdev); + struct bcm63xx_spi *bs = spi_master_get_devdata(master); + ++ spi_unregister_master(master); ++ + /* reset spi block */ + bcm_spi_writeb(bs, 0, SPI_INT_MASK); +- spin_lock(&bs->lock); +- bs->stopping = 1; + + /* HW shutdown */ + clk_disable(bs->clk); + clk_put(bs->clk); + +- spin_unlock(&bs->lock); + platform_set_drvdata(pdev, 0); +- spi_unregister_master(master); + + return 0; + } diff --git a/target/linux/brcm63xx/patches-3.3/015-spi-bcm63xx-set-master-driver-mode_bits.patch b/target/linux/brcm63xx/patches-3.3/015-spi-bcm63xx-set-master-driver-mode_bits.patch new file mode 100644 index 000000000..8b934d002 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/015-spi-bcm63xx-set-master-driver-mode_bits.patch @@ -0,0 +1,24 @@ +From 88a3a255a510ed193bf0cc35424761c3c9247586 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Fri, 20 Apr 2012 15:37:35 +0200 +Subject: [PATCH] spi/bcm63xx: set master driver mode_bits. + +We were not properly advertising the MODE bits supported by this driver, fix +that. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Grant Likely <grant.likely@secretlab.ca> +--- + drivers/spi/spi-bcm63xx.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/spi/spi-bcm63xx.c ++++ b/drivers/spi/spi-bcm63xx.c +@@ -404,6 +404,7 @@ static int __devinit bcm63xx_spi_probe(s + master->prepare_transfer_hardware = bcm63xx_spi_prepare_transfer; + master->unprepare_transfer_hardware = bcm63xx_spi_unprepare_transfer; + master->transfer_one_message = bcm63xx_spi_transfer_one; ++ master->mode_bits = MODEBITS; + bs->speed_hz = pdata->speed_hz; + bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); + bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); diff --git a/target/linux/brcm63xx/patches-3.3/016-spi-bcm63xx-fix-bcm6348-38.patch b/target/linux/brcm63xx/patches-3.3/016-spi-bcm63xx-fix-bcm6348-38.patch new file mode 100644 index 000000000..ce532571d --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/016-spi-bcm63xx-fix-bcm6348-38.patch @@ -0,0 +1,128 @@ +--- a/arch/mips/bcm63xx/dev-spi.c ++++ b/arch/mips/bcm63xx/dev-spi.c +@@ -106,11 +106,15 @@ int __init bcm63xx_spi_register(void) + if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) { + spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1; + spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE; ++ spi_pdata.msg_type_shift = SPI_6338_MSG_TYPE_SHIFT; ++ spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH; + } + + if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { + spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; + spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; ++ spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT; ++ spi_pdata.msg_ctl_width = SPI_6358_MSG_CTL_WIDTH; + } + + bcm63xx_spi_regs_init(); +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +@@ -9,6 +9,8 @@ int __init bcm63xx_spi_register(void); + + struct bcm63xx_spi_pdata { + unsigned int fifo_size; ++ unsigned int msg_type_shift; ++ unsigned int msg_ctl_width; + int bus_num; + int num_chipselect; + u32 speed_hz; +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -987,7 +987,8 @@ + #define SPI_6338_FILL_BYTE 0x07 + #define SPI_6338_MSG_TAIL 0x09 + #define SPI_6338_RX_TAIL 0x0b +-#define SPI_6338_MSG_CTL 0x40 ++#define SPI_6338_MSG_CTL 0x40 /* 8-bits register */ ++#define SPI_6338_MSG_CTL_WIDTH 8 + #define SPI_6338_MSG_DATA 0x41 + #define SPI_6338_MSG_DATA_SIZE 0x3f + #define SPI_6338_RX_DATA 0x80 +@@ -1003,7 +1004,8 @@ + #define SPI_6348_FILL_BYTE 0x07 + #define SPI_6348_MSG_TAIL 0x09 + #define SPI_6348_RX_TAIL 0x0b +-#define SPI_6348_MSG_CTL 0x40 ++#define SPI_6348_MSG_CTL 0x40 /* 8-bits register */ ++#define SPI_6348_MSG_CTL_WIDTH 8 + #define SPI_6348_MSG_DATA 0x41 + #define SPI_6348_MSG_DATA_SIZE 0x3f + #define SPI_6348_RX_DATA 0x80 +@@ -1011,6 +1013,7 @@ + + /* BCM 6358 SPI core */ + #define SPI_6358_MSG_CTL 0x00 /* 16-bits register */ ++#define SPI_6358_MSG_CTL_WIDTH 16 + #define SPI_6358_MSG_DATA 0x02 + #define SPI_6358_MSG_DATA_SIZE 0x21e + #define SPI_6358_RX_DATA 0x400 +@@ -1027,6 +1030,7 @@ + + /* BCM 6358 SPI core */ + #define SPI_6368_MSG_CTL 0x00 /* 16-bits register */ ++#define SPI_6368_MSG_CTL_WIDTH 16 + #define SPI_6368_MSG_DATA 0x02 + #define SPI_6368_MSG_DATA_SIZE 0x21e + #define SPI_6368_RX_DATA 0x400 +@@ -1048,7 +1052,10 @@ + #define SPI_HD_W 0x01 + #define SPI_HD_R 0x02 + #define SPI_BYTE_CNT_SHIFT 0 +-#define SPI_MSG_TYPE_SHIFT 14 ++#define SPI_6338_MSG_TYPE_SHIFT 6 ++#define SPI_6348_MSG_TYPE_SHIFT 6 ++#define SPI_6358_MSG_TYPE_SHIFT 14 ++#define SPI_6368_MSG_TYPE_SHIFT 14 + + /* Command */ + #define SPI_CMD_NOOP 0x00 +--- a/drivers/spi/spi-bcm63xx.c ++++ b/drivers/spi/spi-bcm63xx.c +@@ -47,6 +47,8 @@ struct bcm63xx_spi { + /* Platform data */ + u32 speed_hz; + unsigned fifo_size; ++ unsigned int msg_type_shift; ++ unsigned int msg_ctl_width; + + /* Data buffers */ + const unsigned char *tx_ptr; +@@ -221,13 +223,24 @@ static unsigned int bcm63xx_txrx_bufs(st + msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT); + + if (t->rx_buf && t->tx_buf) +- msg_ctl |= (SPI_FD_RW << SPI_MSG_TYPE_SHIFT); ++ msg_ctl |= (SPI_FD_RW << bs->msg_type_shift); + else if (t->rx_buf) +- msg_ctl |= (SPI_HD_R << SPI_MSG_TYPE_SHIFT); ++ msg_ctl |= (SPI_HD_R << bs->msg_type_shift); + else if (t->tx_buf) +- msg_ctl |= (SPI_HD_W << SPI_MSG_TYPE_SHIFT); ++ msg_ctl |= (SPI_HD_W << bs->msg_type_shift); + +- bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); ++ switch (bs->msg_ctl_width) { ++ case 8: ++ bcm_spi_writeb(bs, msg_ctl, SPI_MSG_CTL); ++ break; ++ case 16: ++ bcm_spi_writew(bs, msg_ctl, SPI_MSG_CTL); ++ break; ++ default: ++ dev_err(&spi->dev, "unknown MSG_CTL width: %d\n", ++ bs->msg_ctl_width); ++ return 0; ++ } + + /* Issue the transfer */ + cmd = SPI_CMD_START_IMMEDIATE; +@@ -406,6 +419,8 @@ static int __devinit bcm63xx_spi_probe(s + master->transfer_one_message = bcm63xx_spi_transfer_one; + master->mode_bits = MODEBITS; + bs->speed_hz = pdata->speed_hz; ++ bs->msg_type_shift = pdata->msg_type_shift; ++ bs->msg_ctl_width = pdata->msg_ctl_width; + bs->tx_io = (u8 *)(bs->regs + bcm63xx_spireg(SPI_MSG_DATA)); + bs->rx_io = (const u8 *)(bs->regs + bcm63xx_spireg(SPI_RX_DATA)); + diff --git a/target/linux/brcm63xx/patches-3.3/017-MIPS-BCM63XX-fix-BCM6368-IPSec-clock-bit.patch b/target/linux/brcm63xx/patches-3.3/017-MIPS-BCM63XX-fix-BCM6368-IPSec-clock-bit.patch new file mode 100644 index 000000000..81f87c610 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/017-MIPS-BCM63XX-fix-BCM6368-IPSec-clock-bit.patch @@ -0,0 +1,23 @@ +From 41ee87b6ddd525fab54e21ede506f2084bcabed3 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Wed, 25 Jan 2012 17:39:52 +0100 +Subject: [PATCH 14/63] MIPS: BCM63XX: fix BCM6368 IPSec clock bit + +The IPsec clock bit is 18 and not 17. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -99,7 +99,7 @@ + #define CKCTL_6368_USBH_EN (1 << 15) + #define CKCTL_6368_DISABLE_GLESS_EN (1 << 16) + #define CKCTL_6368_NAND_EN (1 << 17) +-#define CKCTL_6368_IPSEC_EN (1 << 17) ++#define CKCTL_6368_IPSEC_EN (1 << 18) + + #define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \ + CKCTL_6368_SWPKT_SAR_EN | \ diff --git a/target/linux/brcm63xx/patches-3.3/018-MIPS-BCM63XX-add-support-for-ipsec-clock.patch b/target/linux/brcm63xx/patches-3.3/018-MIPS-BCM63XX-add-support-for-ipsec-clock.patch new file mode 100644 index 000000000..6fffc1925 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/018-MIPS-BCM63XX-add-support-for-ipsec-clock.patch @@ -0,0 +1,48 @@ +From 0fec0136456ce214ea4df6b8ff3b3728befc816a Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Tue, 31 Jan 2012 15:12:22 +0100 +Subject: [PATCH 3/6] MIPS: BCM63XX: add support for "ipsec" clock + +This module is only available on BCM6368 so far and does not require +resetting the block. + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +Cc: linux-mips@linux-mips.org +Cc: mpm@selenic.com +Cc: herbert@gondor.apana.org.au +Patchwork: https://patchwork.linux-mips.org/patch/3324/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/bcm63xx/clk.c | 14 ++++++++++++++ + 1 files changed, 14 insertions(+), 0 deletions(-) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -224,6 +224,18 @@ static struct clk clk_xtm = { + }; + + /* ++ * IPsec clock ++ */ ++static void ipsec_set(struct clk *clk, int enable) ++{ ++ bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable); ++} ++ ++static struct clk clk_ipsec = { ++ .set = ipsec_set, ++}; ++ ++/* + * Internal peripheral clock + */ + static struct clk clk_periph = { +@@ -280,6 +292,8 @@ struct clk *clk_get(struct device *dev, + return &clk_periph; + if (BCMCPU_IS_6358() && !strcmp(id, "pcm")) + return &clk_pcm; ++ if (BCMCPU_IS_6368() && !strcmp(id, "ipsec")) ++ return &clk_ipsec; + return ERR_PTR(-ENOENT); + } + diff --git a/target/linux/brcm63xx/patches-3.3/019-MIPS-BCM63XX-add-RNG-peripheral-definitions.patch b/target/linux/brcm63xx/patches-3.3/019-MIPS-BCM63XX-add-RNG-peripheral-definitions.patch new file mode 100644 index 000000000..cd7bf37e9 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/019-MIPS-BCM63XX-add-RNG-peripheral-definitions.patch @@ -0,0 +1,113 @@ +From 357761c423c0f9e4af4aafe85be7889dc36f3584 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Tue, 31 Jan 2012 15:12:23 +0100 +Subject: [PATCH 4/6] MIPS: BCM63XX: add RNG peripheral definitions + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +Cc: linux-mips@linux-mips.org +Cc: mpm@selenic.com +Cc: herbert@gondor.apana.org.au +Patchwork: https://patchwork.linux-mips.org/patch/3326/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 9 +++++++++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 14 ++++++++++++++ + 2 files changed, 23 insertions(+), 0 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -129,6 +129,7 @@ enum bcm63xx_regs_set { + RSET_PCMDMA, + RSET_PCMDMAC, + RSET_PCMDMAS, ++ RSET_RNG + }; + + #define RSET_DSL_LMEM_SIZE (64 * 1024 * 4) +@@ -152,6 +153,7 @@ enum bcm63xx_regs_set { + #define RSET_XTMDMA_SIZE 256 + #define RSET_XTMDMAC_SIZE(chans) (16 * (chans)) + #define RSET_XTMDMAS_SIZE(chans) (16 * (chans)) ++#define RSET_RNG_SIZE 20 + + /* + * 6338 register sets base address +@@ -195,6 +197,7 @@ enum bcm63xx_regs_set { + #define BCM_6338_PCMDMA_BASE (0xdeadbeef) + #define BCM_6338_PCMDMAC_BASE (0xdeadbeef) + #define BCM_6338_PCMDMAS_BASE (0xdeadbeef) ++#define BCM_6338_RNG_BASE (0xdeadbeef) + + /* + * 6345 register sets base address +@@ -238,6 +241,7 @@ enum bcm63xx_regs_set { + #define BCM_6345_PCMDMA_BASE (0xdeadbeef) + #define BCM_6345_PCMDMAC_BASE (0xdeadbeef) + #define BCM_6345_PCMDMAS_BASE (0xdeadbeef) ++#define BCM_6345_RNG_BASE (0xdeadbeef) + + /* + * 6348 register sets base address +@@ -278,6 +282,7 @@ enum bcm63xx_regs_set { + #define BCM_6348_PCMDMA_BASE (0xdeadbeef) + #define BCM_6348_PCMDMAC_BASE (0xdeadbeef) + #define BCM_6348_PCMDMAS_BASE (0xdeadbeef) ++#define BCM_6348_RNG_BASE (0xdeadbeef) + + /* + * 6358 register sets base address +@@ -318,6 +323,7 @@ enum bcm63xx_regs_set { + #define BCM_6358_PCMDMA_BASE (0xfffe1800) + #define BCM_6358_PCMDMAC_BASE (0xfffe1900) + #define BCM_6358_PCMDMAS_BASE (0xfffe1a00) ++#define BCM_6358_RNG_BASE (0xdeadbeef) + + + /* +@@ -359,6 +365,7 @@ enum bcm63xx_regs_set { + #define BCM_6368_PCMDMA_BASE (0xb0005800) + #define BCM_6368_PCMDMAC_BASE (0xb0005a00) + #define BCM_6368_PCMDMAS_BASE (0xb0005c00) ++#define BCM_6368_RNG_BASE (0xb0004180) + + + extern const unsigned long *bcm63xx_regs_base; +@@ -404,6 +411,7 @@ extern const unsigned long *bcm63xx_regs + __GEN_RSET_BASE(__cpu, PCMDMA) \ + __GEN_RSET_BASE(__cpu, PCMDMAC) \ + __GEN_RSET_BASE(__cpu, PCMDMAS) \ ++ __GEN_RSET_BASE(__cpu, RNG) \ + } + + #define __GEN_CPU_REGS_TABLE(__cpu) \ +@@ -442,6 +450,7 @@ extern const unsigned long *bcm63xx_regs + [RSET_PCMDMA] = BCM_## __cpu ##_PCMDMA_BASE, \ + [RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \ + [RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \ ++ [RSET_RNG] = BCM_## __cpu ##_RNG_BASE, \ + + + static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -974,6 +974,20 @@ + #define M2M_DSTID_REG(x) ((x) * 0x40 + 0x18) + + /************************************************************************* ++ * _REG relative to RSET_RNG ++ *************************************************************************/ ++ ++#define RNG_CTRL 0x00 ++#define RNG_EN (1 << 0) ++ ++#define RNG_STAT 0x04 ++#define RNG_AVAIL_MASK (0xff000000) ++ ++#define RNG_DATA 0x08 ++#define RNG_THRES 0x0c ++#define RNG_MASK 0x10 ++ ++/************************************************************************* + * _REG relative to RSET_SPI + *************************************************************************/ + diff --git a/target/linux/brcm63xx/patches-3.3/020-MIPS-BCM63XX-add-RNG-driver-platform_device-stub.patch b/target/linux/brcm63xx/patches-3.3/020-MIPS-BCM63XX-add-RNG-driver-platform_device-stub.patch new file mode 100644 index 000000000..d759c5722 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/020-MIPS-BCM63XX-add-RNG-driver-platform_device-stub.patch @@ -0,0 +1,71 @@ +From 79fed26f65c22e0d67c9523f7a374f0585bd2803 Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Tue, 31 Jan 2012 15:12:24 +0100 +Subject: [PATCH 5/6] MIPS: BCM63XX: add RNG driver platform_device stub + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +Cc: linux-mips@linux-mips.org +Cc: mpm@selenic.com +Cc: herbert@gondor.apana.org.au +Patchwork: https://patchwork.linux-mips.org/patch/3325/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/bcm63xx/Makefile | 4 ++-- + arch/mips/bcm63xx/dev-rng.c | 40 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 42 insertions(+), 2 deletions(-) + create mode 100644 arch/mips/bcm63xx/dev-rng.c + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,6 +1,6 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ +- dev-dsp.o dev-enet.o dev-pcmcia.o dev-spi.o dev-uart.o \ +- dev-wdt.o ++ dev-dsp.o dev-enet.o dev-pcmcia.o dev-rng.o dev-spi.o \ ++ dev-uart.o dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- /dev/null ++++ b/arch/mips/bcm63xx/dev-rng.c +@@ -0,0 +1,40 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2011 Florian Fainelli <florian@openwrt.org> ++ */ ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <bcm63xx_cpu.h> ++ ++static struct resource rng_resources[] = { ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++}; ++ ++static struct platform_device bcm63xx_rng_device = { ++ .name = "bcm63xx-rng", ++ .id = -1, ++ .num_resources = ARRAY_SIZE(rng_resources), ++ .resource = rng_resources, ++}; ++ ++int __init bcm63xx_rng_register(void) ++{ ++ if (!BCMCPU_IS_6368()) ++ return -ENODEV; ++ ++ rng_resources[0].start = bcm63xx_regset_address(RSET_RNG); ++ rng_resources[0].end = rng_resources[0].start; ++ rng_resources[0].end += RSET_RNG_SIZE - 1; ++ ++ return platform_device_register(&bcm63xx_rng_device); ++} ++arch_initcall(bcm63xx_rng_register); diff --git a/target/linux/brcm63xx/patches-3.3/021-hw_random-add-Broadcom-BCM63xx-RNG-driver.patch b/target/linux/brcm63xx/patches-3.3/021-hw_random-add-Broadcom-BCM63xx-RNG-driver.patch new file mode 100644 index 000000000..7e66fd52a --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/021-hw_random-add-Broadcom-BCM63xx-RNG-driver.patch @@ -0,0 +1,229 @@ +From 1cfc5c76c5f48359716bd804daef2f2f7554fb4a Mon Sep 17 00:00:00 2001 +From: Florian Fainelli <florian@openwrt.org> +Date: Tue, 31 Jan 2012 15:12:25 +0100 +Subject: [PATCH 6/6] hw_random: add Broadcom BCM63xx RNG driver + +Signed-off-by: Florian Fainelli <florian@openwrt.org> +Cc: linux-mips@linux-mips.org +Cc: mpm@selenic.com +Cc: herbert@gondor.apana.org.au +Patchwork: https://patchwork.linux-mips.org/patch/3327/ +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + drivers/char/hw_random/Kconfig | 14 +++ + drivers/char/hw_random/Makefile | 1 + + drivers/char/hw_random/bcm63xx-rng.c | 175 ++++++++++++++++++++++++++++++++++ + 3 files changed, 190 insertions(+), 0 deletions(-) + create mode 100644 drivers/char/hw_random/bcm63xx-rng.c + +--- a/drivers/char/hw_random/Kconfig ++++ b/drivers/char/hw_random/Kconfig +@@ -73,6 +73,20 @@ config HW_RANDOM_ATMEL + + If unsure, say Y. + ++config HW_RANDOM_BCM63XX ++ tristate "Broadcom BCM63xx Random Number Generator support" ++ depends on HW_RANDOM && BCM63XX ++ default HW_RANDOM ++ ---help--- ++ This driver provides kernel-side support for the Random Number ++ Generator hardware found on the Broadcom BCM63xx SoCs. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called bcm63xx-rng ++ ++ If unusure, say Y. ++ ++ + config HW_RANDOM_GEODE + tristate "AMD Geode HW Random Number Generator support" + depends on HW_RANDOM && X86_32 && PCI +--- a/drivers/char/hw_random/Makefile ++++ b/drivers/char/hw_random/Makefile +@@ -8,6 +8,7 @@ obj-$(CONFIG_HW_RANDOM_TIMERIOMEM) += ti + obj-$(CONFIG_HW_RANDOM_INTEL) += intel-rng.o + obj-$(CONFIG_HW_RANDOM_AMD) += amd-rng.o + obj-$(CONFIG_HW_RANDOM_ATMEL) += atmel-rng.o ++obj-$(CONFIG_HW_RANDOM_BCM63XX) += bcm63xx-rng.o + obj-$(CONFIG_HW_RANDOM_GEODE) += geode-rng.o + obj-$(CONFIG_HW_RANDOM_N2RNG) += n2-rng.o + n2-rng-y := n2-drv.o n2-asm.o +--- /dev/null ++++ b/drivers/char/hw_random/bcm63xx-rng.c +@@ -0,0 +1,175 @@ ++/* ++ * Broadcom BCM63xx Random Number Generator support ++ * ++ * Copyright (C) 2011, Florian Fainelli <florian@openwrt.org> ++ * Copyright (C) 2009, Broadcom Corporation ++ * ++ */ ++#include <linux/module.h> ++#include <linux/slab.h> ++#include <linux/io.h> ++#include <linux/err.h> ++#include <linux/clk.h> ++#include <linux/platform_device.h> ++#include <linux/hw_random.h> ++ ++#include <bcm63xx_io.h> ++#include <bcm63xx_regs.h> ++ ++struct bcm63xx_rng_priv { ++ struct clk *clk; ++ void __iomem *regs; ++}; ++ ++#define to_rng_priv(rng) ((struct bcm63xx_rng_priv *)rng->priv) ++ ++static int bcm63xx_rng_init(struct hwrng *rng) ++{ ++ struct bcm63xx_rng_priv *priv = to_rng_priv(rng); ++ u32 val; ++ ++ val = bcm_readl(priv->regs + RNG_CTRL); ++ val |= RNG_EN; ++ bcm_writel(val, priv->regs + RNG_CTRL); ++ ++ return 0; ++} ++ ++static void bcm63xx_rng_cleanup(struct hwrng *rng) ++{ ++ struct bcm63xx_rng_priv *priv = to_rng_priv(rng); ++ u32 val; ++ ++ val = bcm_readl(priv->regs + RNG_CTRL); ++ val &= ~RNG_EN; ++ bcm_writel(val, priv->regs + RNG_CTRL); ++} ++ ++static int bcm63xx_rng_data_present(struct hwrng *rng, int wait) ++{ ++ struct bcm63xx_rng_priv *priv = to_rng_priv(rng); ++ ++ return bcm_readl(priv->regs + RNG_STAT) & RNG_AVAIL_MASK; ++} ++ ++static int bcm63xx_rng_data_read(struct hwrng *rng, u32 *data) ++{ ++ struct bcm63xx_rng_priv *priv = to_rng_priv(rng); ++ ++ *data = bcm_readl(priv->regs + RNG_DATA); ++ ++ return 4; ++} ++ ++static int __init bcm63xx_rng_probe(struct platform_device *pdev) ++{ ++ struct resource *r; ++ struct clk *clk; ++ int ret; ++ struct bcm63xx_rng_priv *priv; ++ struct hwrng *rng; ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!r) { ++ dev_err(&pdev->dev, "no iomem resource\n"); ++ ret = -ENXIO; ++ goto out; ++ } ++ ++ priv = kzalloc(sizeof(*priv), GFP_KERNEL); ++ if (!priv) { ++ dev_err(&pdev->dev, "no memory for private structure\n"); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ rng = kzalloc(sizeof(*rng), GFP_KERNEL); ++ if (!rng) { ++ dev_err(&pdev->dev, "no memory for rng structure\n"); ++ ret = -ENOMEM; ++ goto out_free_priv; ++ } ++ ++ platform_set_drvdata(pdev, rng); ++ rng->priv = (unsigned long)priv; ++ rng->name = pdev->name; ++ rng->init = bcm63xx_rng_init; ++ rng->cleanup = bcm63xx_rng_cleanup; ++ rng->data_present = bcm63xx_rng_data_present; ++ rng->data_read = bcm63xx_rng_data_read; ++ ++ clk = clk_get(&pdev->dev, "ipsec"); ++ if (IS_ERR(clk)) { ++ dev_err(&pdev->dev, "no clock for device\n"); ++ ret = PTR_ERR(clk); ++ goto out_free_rng; ++ } ++ ++ priv->clk = clk; ++ ++ if (!devm_request_mem_region(&pdev->dev, r->start, ++ resource_size(r), pdev->name)) { ++ dev_err(&pdev->dev, "request mem failed"); ++ ret = -ENOMEM; ++ goto out_free_rng; ++ } ++ ++ priv->regs = devm_ioremap_nocache(&pdev->dev, r->start, ++ resource_size(r)); ++ if (!priv->regs) { ++ dev_err(&pdev->dev, "ioremap failed"); ++ ret = -ENOMEM; ++ goto out_free_rng; ++ } ++ ++ clk_enable(clk); ++ ++ ret = hwrng_register(rng); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to register rng device\n"); ++ goto out_clk_disable; ++ } ++ ++ dev_info(&pdev->dev, "registered RNG driver\n"); ++ ++ return 0; ++ ++out_clk_disable: ++ clk_disable(clk); ++out_free_rng: ++ platform_set_drvdata(pdev, NULL); ++ kfree(rng); ++out_free_priv: ++ kfree(priv); ++out: ++ return ret; ++} ++ ++static int __devexit bcm63xx_rng_remove(struct platform_device *pdev) ++{ ++ struct hwrng *rng = platform_get_drvdata(pdev); ++ struct bcm63xx_rng_priv *priv = to_rng_priv(rng); ++ ++ hwrng_unregister(rng); ++ clk_disable(priv->clk); ++ kfree(priv); ++ kfree(rng); ++ platform_set_drvdata(pdev, NULL); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm63xx_rng_driver = { ++ .probe = bcm63xx_rng_probe, ++ .remove = __devexit_p(bcm63xx_rng_remove), ++ .driver = { ++ .name = "bcm63xx-rng", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++module_platform_driver(bcm63xx_rng_driver); ++ ++MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); ++MODULE_DESCRIPTION("Broadcom BCM63xx RNG driver"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm63xx/patches-3.3/022-MIPS-BCM63XX-Move-flash-registration-out-of-board_bc.patch b/target/linux/brcm63xx/patches-3.3/022-MIPS-BCM63XX-Move-flash-registration-out-of-board_bc.patch new file mode 100644 index 000000000..e9c85a2a6 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/022-MIPS-BCM63XX-Move-flash-registration-out-of-board_bc.patch @@ -0,0 +1,202 @@ +From bfe47f0f68b5f7a3a92d07266cba58b188fe10e7 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 12 Jun 2012 10:23:38 +0200 +Subject: [PATCH 1/8] MIPS: BCM63XX: Move flash registration out of board_bcm963xx.c + +board_bcm963xx.c is already large enough. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: Maxime Bizon <mbizon@freebox.fr> +Cc: Florian Fainelli <florian@openwrt.org> +Cc: Kevin Cernekee <cernekee@gmail.com> +Patchwork: https://patchwork.linux-mips.org/patch/3952/ +Reviewed-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/bcm63xx/Makefile | 4 +- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 49 +------------- + arch/mips/bcm63xx/dev-flash.c | 69 ++++++++++++++++++++ + .../include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 6 ++ + 4 files changed, 79 insertions(+), 49 deletions(-) + create mode 100644 arch/mips/bcm63xx/dev-flash.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,6 +1,6 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ +- dev-dsp.o dev-enet.o dev-pcmcia.o dev-rng.o dev-spi.o \ +- dev-uart.o dev-wdt.o ++ dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ ++ dev-spi.o dev-uart.o dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -11,9 +11,6 @@ + #include <linux/kernel.h> + #include <linux/string.h> + #include <linux/platform_device.h> +-#include <linux/mtd/mtd.h> +-#include <linux/mtd/partitions.h> +-#include <linux/mtd/physmap.h> + #include <linux/ssb/ssb.h> + #include <asm/addrspace.h> + #include <bcm63xx_board.h> +@@ -24,6 +21,7 @@ + #include <bcm63xx_dev_pci.h> + #include <bcm63xx_dev_enet.h> + #include <bcm63xx_dev_dsp.h> ++#include <bcm63xx_dev_flash.h> + #include <bcm63xx_dev_pcmcia.h> + #include <bcm63xx_dev_spi.h> + #include <board_bcm963xx.h> +@@ -809,40 +807,6 @@ void __init board_setup(void) + panic("unexpected CPU for bcm963xx board"); + } + +-static struct mtd_partition mtd_partitions[] = { +- { +- .name = "cfe", +- .offset = 0x0, +- .size = 0x40000, +- } +-}; +- +-static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL }; +- +-static struct physmap_flash_data flash_data = { +- .width = 2, +- .nr_parts = ARRAY_SIZE(mtd_partitions), +- .parts = mtd_partitions, +- .part_probe_types = bcm63xx_part_types, +-}; +- +-static struct resource mtd_resources[] = { +- { +- .start = 0, /* filled at runtime */ +- .end = 0, /* filled at runtime */ +- .flags = IORESOURCE_MEM, +- } +-}; +- +-static struct platform_device mtd_dev = { +- .name = "physmap-flash", +- .resource = mtd_resources, +- .num_resources = ARRAY_SIZE(mtd_resources), +- .dev = { +- .platform_data = &flash_data, +- }, +-}; +- + static struct gpio_led_platform_data bcm63xx_led_data; + + static struct platform_device bcm63xx_gpio_leds = { +@@ -856,8 +820,6 @@ static struct platform_device bcm63xx_gp + */ + int __init board_register_devices(void) + { +- u32 val; +- + if (board.has_uart0) + bcm63xx_uart_register(0); + +@@ -893,14 +855,7 @@ int __init board_register_devices(void) + + bcm63xx_spi_register(); + +- /* read base address of boot chip select (0) */ +- val = bcm_mpi_readl(MPI_CSBASE_REG(0)); +- val &= MPI_CSBASE_BASE_MASK; +- +- mtd_resources[0].start = val; +- mtd_resources[0].end = 0x1FFFFFFF; +- +- platform_device_register(&mtd_dev); ++ bcm63xx_flash_register(); + + bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds); + bcm63xx_led_data.leds = board.leds; +--- /dev/null ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -0,0 +1,69 @@ ++/* ++ * Broadcom BCM63xx flash registration ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> ++ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> ++ */ ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/partitions.h> ++#include <linux/mtd/physmap.h> ++ ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_dev_flash.h> ++#include <bcm63xx_regs.h> ++#include <bcm63xx_io.h> ++ ++static struct mtd_partition mtd_partitions[] = { ++ { ++ .name = "cfe", ++ .offset = 0x0, ++ .size = 0x40000, ++ } ++}; ++ ++static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL }; ++ ++static struct physmap_flash_data flash_data = { ++ .width = 2, ++ .parts = mtd_partitions, ++ .part_probe_types = bcm63xx_part_types, ++}; ++ ++static struct resource mtd_resources[] = { ++ { ++ .start = 0, /* filled at runtime */ ++ .end = 0, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device mtd_dev = { ++ .name = "physmap-flash", ++ .resource = mtd_resources, ++ .num_resources = ARRAY_SIZE(mtd_resources), ++ .dev = { ++ .platform_data = &flash_data, ++ }, ++}; ++ ++int __init bcm63xx_flash_register(void) ++{ ++ u32 val; ++ ++ /* read base address of boot chip select (0) */ ++ val = bcm_mpi_readl(MPI_CSBASE_REG(0)); ++ val &= MPI_CSBASE_BASE_MASK; ++ ++ mtd_resources[0].start = val; ++ mtd_resources[0].end = 0x1FFFFFFF; ++ ++ return platform_device_register(&mtd_dev); ++} +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h +@@ -0,0 +1,6 @@ ++#ifndef __BCM63XX_FLASH_H ++#define __BCM63XX_FLASH_H ++ ++int __init bcm63xx_flash_register(void); ++ ++#endif /* __BCM63XX_FLASH_H */ diff --git a/target/linux/brcm63xx/patches-3.3/023-MIPS-BCM63XX-Add-flash-type-detection.patch b/target/linux/brcm63xx/patches-3.3/023-MIPS-BCM63XX-Add-flash-type-detection.patch new file mode 100644 index 000000000..b0f13abba --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/023-MIPS-BCM63XX-Add-flash-type-detection.patch @@ -0,0 +1,137 @@ +From 0c921d542eb4359791cffd1737bf45184f6ae352 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 12 Jun 2012 10:23:39 +0200 +Subject: [PATCH 2/8] MIPS: BCM63XX: Add flash type detection + +On BCM6358 and BCM6368 the attached flash type is exposed through a +bootstrapping register. Use it for auto detecting the flash type on +those and default to parallel flash for earlier SoCs. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: Maxime Bizon <mbizon@freebox.fr> +Cc: Florian Fainelli <florian@openwrt.org> +Cc: Kevin Cernekee <cernekee@gmail.com> +Patchwork: https://patchwork.linux-mips.org/patch/3954/ +Reviewed-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/bcm63xx/dev-flash.c | 60 ++++++++++++++++++-- + .../include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 6 ++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 9 +++ + 3 files changed, 69 insertions(+), 6 deletions(-) + +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -7,6 +7,7 @@ + * + * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> + * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> ++ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com> + */ + + #include <linux/init.h> +@@ -54,16 +55,63 @@ static struct platform_device mtd_dev = + }, + }; + +-int __init bcm63xx_flash_register(void) ++static int __init bcm63xx_detect_flash_type(void) + { + u32 val; + +- /* read base address of boot chip select (0) */ +- val = bcm_mpi_readl(MPI_CSBASE_REG(0)); +- val &= MPI_CSBASE_BASE_MASK; ++ switch (bcm63xx_get_cpu_id()) { ++ case BCM6338_CPU_ID: ++ case BCM6345_CPU_ID: ++ case BCM6348_CPU_ID: ++ /* no way to auto detect so assume parallel */ ++ return BCM63XX_FLASH_TYPE_PARALLEL; ++ case BCM6358_CPU_ID: ++ val = bcm_gpio_readl(GPIO_STRAPBUS_REG); ++ if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL) ++ return BCM63XX_FLASH_TYPE_PARALLEL; ++ else ++ return BCM63XX_FLASH_TYPE_SERIAL; ++ case BCM6368_CPU_ID: ++ val = bcm_gpio_readl(GPIO_STRAPBUS_REG); ++ switch (val & STRAPBUS_6368_BOOT_SEL_MASK) { ++ case STRAPBUS_6368_BOOT_SEL_NAND: ++ return BCM63XX_FLASH_TYPE_NAND; ++ case STRAPBUS_6368_BOOT_SEL_SERIAL: ++ return BCM63XX_FLASH_TYPE_SERIAL; ++ case STRAPBUS_6368_BOOT_SEL_PARALLEL: ++ return BCM63XX_FLASH_TYPE_PARALLEL; ++ } ++ default: ++ return -EINVAL; ++ } ++} ++ ++int __init bcm63xx_flash_register(void) ++{ ++ int flash_type; ++ u32 val; + +- mtd_resources[0].start = val; +- mtd_resources[0].end = 0x1FFFFFFF; ++ flash_type = bcm63xx_detect_flash_type(); + +- return platform_device_register(&mtd_dev); ++ switch (flash_type) { ++ case BCM63XX_FLASH_TYPE_PARALLEL: ++ /* read base address of boot chip select (0) */ ++ val = bcm_mpi_readl(MPI_CSBASE_REG(0)); ++ val &= MPI_CSBASE_BASE_MASK; ++ ++ mtd_resources[0].start = val; ++ mtd_resources[0].end = 0x1FFFFFFF; ++ ++ return platform_device_register(&mtd_dev); ++ case BCM63XX_FLASH_TYPE_SERIAL: ++ pr_warn("unsupported serial flash detected\n"); ++ return -ENODEV; ++ case BCM63XX_FLASH_TYPE_NAND: ++ pr_warn("unsupported NAND flash detected\n"); ++ return -ENODEV; ++ default: ++ pr_err("flash detection failed for BCM%x: %d\n", ++ bcm63xx_get_cpu_id(), flash_type); ++ return -ENODEV; ++ } + } +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h +@@ -1,6 +1,12 @@ + #ifndef __BCM63XX_FLASH_H + #define __BCM63XX_FLASH_H + ++enum { ++ BCM63XX_FLASH_TYPE_PARALLEL, ++ BCM63XX_FLASH_TYPE_SERIAL, ++ BCM63XX_FLASH_TYPE_NAND, ++}; ++ + int __init bcm63xx_flash_register(void); + + #endif /* __BCM63XX_FLASH_H */ +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -507,6 +507,15 @@ + #define GPIO_BASEMODE_6368_MASK 0x7 + /* those bits must be kept as read in gpio basemode register*/ + ++#define GPIO_STRAPBUS_REG 0x40 ++#define STRAPBUS_6358_BOOT_SEL_PARALLEL (1 << 1) ++#define STRAPBUS_6358_BOOT_SEL_SERIAL (0 << 1) ++#define STRAPBUS_6368_BOOT_SEL_MASK 0x3 ++#define STRAPBUS_6368_BOOT_SEL_NAND 0 ++#define STRAPBUS_6368_BOOT_SEL_SERIAL 1 ++#define STRAPBUS_6368_BOOT_SEL_PARALLEL 3 ++ ++ + /************************************************************************* + * _REG relative to RSET_ENET + *************************************************************************/ diff --git a/target/linux/brcm63xx/patches-3.3/024-MIPS-BCM63XX-Use-the-Chip-ID-register-for-identifyin.patch b/target/linux/brcm63xx/patches-3.3/024-MIPS-BCM63XX-Use-the-Chip-ID-register-for-identifyin.patch new file mode 100644 index 000000000..e45a0d163 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/024-MIPS-BCM63XX-Use-the-Chip-ID-register-for-identifyin.patch @@ -0,0 +1,53 @@ +From a9168d99658bd050e49afc06880d140e2fc2c231 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 12 Jun 2012 10:23:40 +0200 +Subject: [PATCH 3/8] MIPS: BCM63XX: Use the Chip ID register for identifying the SoC + +Newer BCM63XX SoCs use virtually the same CPU ID, differing only in the +revision bits. But since they all have the Chip ID register at the same +location, we can use that to identify the SoC we are running on. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: Maxime Bizon <mbizon@freebox.fr> +Cc: Florian Fainelli <florian@openwrt.org> +Cc: Kevin Cernekee <cernekee@gmail.com> +Patchwork: https://patchwork.linux-mips.org/patch/3955/ +Reviewed-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/bcm63xx/cpu.c | 20 ++++++++++++-------- + 1 files changed, 12 insertions(+), 8 deletions(-) + +--- a/arch/mips/bcm63xx/cpu.c ++++ b/arch/mips/bcm63xx/cpu.c +@@ -228,17 +228,21 @@ void __init bcm63xx_cpu_init(void) + bcm63xx_irqs = bcm6345_irqs; + break; + case CPU_BMIPS4350: +- switch (read_c0_prid() & 0xf0) { +- case 0x10: ++ if ((read_c0_prid() & 0xf0) == 0x10) { + expected_cpu_id = BCM6358_CPU_ID; + bcm63xx_regs_base = bcm6358_regs_base; + bcm63xx_irqs = bcm6358_irqs; +- break; +- case 0x30: +- expected_cpu_id = BCM6368_CPU_ID; +- bcm63xx_regs_base = bcm6368_regs_base; +- bcm63xx_irqs = bcm6368_irqs; +- break; ++ } else { ++ /* all newer chips have the same chip id location */ ++ u16 chip_id = bcm_readw(BCM_6368_PERF_BASE); ++ ++ switch (chip_id) { ++ case BCM6368_CPU_ID: ++ expected_cpu_id = BCM6368_CPU_ID; ++ bcm63xx_regs_base = bcm6368_regs_base; ++ bcm63xx_irqs = bcm6368_irqs; ++ break; ++ } + } + break; + } diff --git a/target/linux/brcm63xx/patches-3.3/025-MIPS-BCM63XX-Add-basic-BCM6328-support.patch b/target/linux/brcm63xx/patches-3.3/025-MIPS-BCM63XX-Add-basic-BCM6328-support.patch new file mode 100644 index 000000000..a64eca85b --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/025-MIPS-BCM63XX-Add-basic-BCM6328-support.patch @@ -0,0 +1,590 @@ +From 8f9ed2e5502ed3ba3d4c89678cb44f43ccd5b9e0 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Wed, 13 Jun 2012 16:46:54 +0100 +Subject: [PATCH 4/8] MIPS: BCM63XX: Add basic BCM6328 support + +This includes CPU speed, memory size detection and working UART, but +lacking the appropriate drivers, no support for attached flash. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: Maxime Bizon <mbizon@freebox.fr> +Cc: Florian Fainelli <florian@openwrt.org> +Cc: Kevin Cernekee <cernekee@gmail.com> +Patchwork: https://patchwork.linux-mips.org/patch/3951/ +Reviewed-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/bcm63xx/Kconfig | 3 + + arch/mips/bcm63xx/boards/board_bcm963xx.c | 12 ++- + arch/mips/bcm63xx/cpu.c | 43 ++++++++ + arch/mips/bcm63xx/dev-flash.c | 6 + + arch/mips/bcm63xx/dev-spi.c | 2 +- + arch/mips/bcm63xx/irq.c | 21 ++++ + arch/mips/bcm63xx/prom.c | 4 +- + arch/mips/bcm63xx/setup.c | 13 ++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 111 ++++++++++++++++++++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | 2 + + arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h | 2 + + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 54 ++++++++++ + arch/mips/include/asm/mach-bcm63xx/ioremap.h | 1 + + 13 files changed, 265 insertions(+), 9 deletions(-) + +--- a/arch/mips/bcm63xx/Kconfig ++++ b/arch/mips/bcm63xx/Kconfig +@@ -1,6 +1,9 @@ + menu "CPU support" + depends on BCM63XX + ++config BCM63XX_CPU_6328 ++ bool "support 6328 CPU" ++ + config BCM63XX_CPU_6338 + bool "support 6338 CPU" + select HW_HAS_PCI +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -708,9 +708,15 @@ void __init board_prom_init(void) + char cfe_version[32]; + u32 val; + +- /* read base address of boot chip select (0) */ +- val = bcm_mpi_readl(MPI_CSBASE_REG(0)); +- val &= MPI_CSBASE_BASE_MASK; ++ /* read base address of boot chip select (0) ++ * 6328 does not have MPI but boots from a fixed address ++ */ ++ if (BCMCPU_IS_6328()) ++ val = 0x18000000; ++ else { ++ val = bcm_mpi_readl(MPI_CSBASE_REG(0)); ++ val &= MPI_CSBASE_BASE_MASK; ++ } + boot_addr = (u8 *)KSEG1ADDR(val); + + /* dump cfe version */ +--- a/arch/mips/bcm63xx/cpu.c ++++ b/arch/mips/bcm63xx/cpu.c +@@ -29,6 +29,14 @@ static u16 bcm63xx_cpu_rev; + static unsigned int bcm63xx_cpu_freq; + static unsigned int bcm63xx_memory_size; + ++static const unsigned long bcm6328_regs_base[] = { ++ __GEN_CPU_REGS_TABLE(6328) ++}; ++ ++static const int bcm6328_irqs[] = { ++ __GEN_CPU_IRQ_TABLE(6328) ++}; ++ + static const unsigned long bcm6338_regs_base[] = { + __GEN_CPU_REGS_TABLE(6338) + }; +@@ -99,6 +107,33 @@ unsigned int bcm63xx_get_memory_size(voi + static unsigned int detect_cpu_clock(void) + { + switch (bcm63xx_get_cpu_id()) { ++ case BCM6328_CPU_ID: ++ { ++ unsigned int tmp, mips_pll_fcvo; ++ ++ tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG); ++ mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK) ++ >> STRAPBUS_6328_FCVO_SHIFT; ++ ++ switch (mips_pll_fcvo) { ++ case 0x12: ++ case 0x14: ++ case 0x19: ++ return 160000000; ++ case 0x1c: ++ return 192000000; ++ case 0x13: ++ case 0x15: ++ return 200000000; ++ case 0x1a: ++ return 384000000; ++ case 0x16: ++ return 400000000; ++ default: ++ return 320000000; ++ } ++ ++ } + case BCM6338_CPU_ID: + /* BCM6338 has a fixed 240 Mhz frequency */ + return 240000000; +@@ -170,6 +205,9 @@ static unsigned int detect_memory_size(v + unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0; + u32 val; + ++ if (BCMCPU_IS_6328()) ++ return bcm_ddr_readl(DDR_CSEND_REG) << 24; ++ + if (BCMCPU_IS_6345()) { + val = bcm_sdram_readl(SDRAM_MBASE_REG); + return (val * 8 * 1024 * 1024); +@@ -237,6 +275,11 @@ void __init bcm63xx_cpu_init(void) + u16 chip_id = bcm_readw(BCM_6368_PERF_BASE); + + switch (chip_id) { ++ case BCM6328_CPU_ID: ++ expected_cpu_id = BCM6328_CPU_ID; ++ bcm63xx_regs_base = bcm6328_regs_base; ++ bcm63xx_irqs = bcm6328_irqs; ++ break; + case BCM6368_CPU_ID: + expected_cpu_id = BCM6368_CPU_ID; + bcm63xx_regs_base = bcm6368_regs_base; +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -60,6 +60,12 @@ static int __init bcm63xx_detect_flash_t + u32 val; + + switch (bcm63xx_get_cpu_id()) { ++ case BCM6328_CPU_ID: ++ val = bcm_misc_readl(MISC_STRAPBUS_6328_REG); ++ if (val & STRAPBUS_6328_BOOT_SEL_SERIAL) ++ return BCM63XX_FLASH_TYPE_SERIAL; ++ else ++ return BCM63XX_FLASH_TYPE_NAND; + case BCM6338_CPU_ID: + case BCM6345_CPU_ID: + case BCM6348_CPU_ID: +--- a/arch/mips/bcm63xx/dev-spi.c ++++ b/arch/mips/bcm63xx/dev-spi.c +@@ -87,7 +87,7 @@ int __init bcm63xx_spi_register(void) + { + struct clk *periph_clk; + +- if (BCMCPU_IS_6345()) ++ if (BCMCPU_IS_6328() || BCMCPU_IS_6345()) + return -ENODEV; + + periph_clk = clk_get(NULL, "periph"); +--- a/arch/mips/bcm63xx/irq.c ++++ b/arch/mips/bcm63xx/irq.c +@@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(uns + static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused; + + #ifndef BCMCPU_RUNTIME_DETECT ++#ifdef CONFIG_BCM63XX_CPU_6328 ++#define irq_stat_reg PERF_IRQSTAT_6328_REG ++#define irq_mask_reg PERF_IRQMASK_6328_REG ++#define irq_bits 64 ++#define is_ext_irq_cascaded 1 ++#define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE) ++#define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE) ++#define ext_irq_count 4 ++#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328 ++#define ext_irq_cfg_reg2 0 ++#endif + #ifdef CONFIG_BCM63XX_CPU_6338 + #define irq_stat_reg PERF_IRQSTAT_6338_REG + #define irq_mask_reg PERF_IRQMASK_6338_REG +@@ -118,6 +129,16 @@ static void bcm63xx_init_irq(void) + irq_mask_addr = bcm63xx_regset_address(RSET_PERF); + + switch (bcm63xx_get_cpu_id()) { ++ case BCM6328_CPU_ID: ++ irq_stat_addr += PERF_IRQSTAT_6328_REG; ++ irq_mask_addr += PERF_IRQMASK_6328_REG; ++ irq_bits = 64; ++ ext_irq_count = 4; ++ is_ext_irq_cascaded = 1; ++ ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE; ++ ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE; ++ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328; ++ break; + case BCM6338_CPU_ID: + irq_stat_addr += PERF_IRQSTAT_6338_REG; + irq_mask_addr += PERF_IRQMASK_6338_REG; +--- a/arch/mips/bcm63xx/prom.c ++++ b/arch/mips/bcm63xx/prom.c +@@ -26,7 +26,9 @@ void __init prom_init(void) + bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG); + + /* disable all hardware blocks clock for now */ +- if (BCMCPU_IS_6338()) ++ if (BCMCPU_IS_6328()) ++ mask = CKCTL_6328_ALL_SAFE_EN; ++ else if (BCMCPU_IS_6338()) + mask = CKCTL_6338_ALL_SAFE_EN; + else if (BCMCPU_IS_6345()) + mask = CKCTL_6345_ALL_SAFE_EN; +--- a/arch/mips/bcm63xx/setup.c ++++ b/arch/mips/bcm63xx/setup.c +@@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void) + + /* mask and clear all external irq */ + switch (bcm63xx_get_cpu_id()) { ++ case BCM6328_CPU_ID: ++ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328; ++ break; + case BCM6338_CPU_ID: + perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338; + break; +@@ -95,9 +98,13 @@ void bcm63xx_machine_reboot(void) + bcm6348_a1_reboot(); + + printk(KERN_INFO "triggering watchdog soft-reset...\n"); +- reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG); +- reg |= SYS_PLL_SOFT_RESET; +- bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG); ++ if (BCMCPU_IS_6328()) { ++ bcm_wdt_writel(1, WDT_SOFTRESET_REG); ++ } else { ++ reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG); ++ reg |= SYS_PLL_SOFT_RESET; ++ bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG); ++ } + while (1) + ; + } +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -9,6 +9,7 @@ + * compile time if only one CPU support is enabled (idea stolen from + * arm mach-types) + */ ++#define BCM6328_CPU_ID 0x6328 + #define BCM6338_CPU_ID 0x6338 + #define BCM6345_CPU_ID 0x6345 + #define BCM6348_CPU_ID 0x6348 +@@ -20,6 +21,19 @@ u16 __bcm63xx_get_cpu_id(void); + u16 bcm63xx_get_cpu_rev(void); + unsigned int bcm63xx_get_cpu_freq(void); + ++#ifdef CONFIG_BCM63XX_CPU_6328 ++# ifdef bcm63xx_get_cpu_id ++# undef bcm63xx_get_cpu_id ++# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() ++# define BCMCPU_RUNTIME_DETECT ++# else ++# define bcm63xx_get_cpu_id() BCM6328_CPU_ID ++# endif ++# define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID) ++#else ++# define BCMCPU_IS_6328() (0) ++#endif ++ + #ifdef CONFIG_BCM63XX_CPU_6338 + # ifdef bcm63xx_get_cpu_id + # undef bcm63xx_get_cpu_id +@@ -129,7 +143,8 @@ enum bcm63xx_regs_set { + RSET_PCMDMA, + RSET_PCMDMAC, + RSET_PCMDMAS, +- RSET_RNG ++ RSET_RNG, ++ RSET_MISC + }; + + #define RSET_DSL_LMEM_SIZE (64 * 1024 * 4) +@@ -156,6 +171,49 @@ enum bcm63xx_regs_set { + #define RSET_RNG_SIZE 20 + + /* ++ * 6328 register sets base address ++ */ ++#define BCM_6328_DSL_LMEM_BASE (0xdeadbeef) ++#define BCM_6328_PERF_BASE (0xb0000000) ++#define BCM_6328_TIMER_BASE (0xb0000040) ++#define BCM_6328_WDT_BASE (0xb000005c) ++#define BCM_6328_UART0_BASE (0xb0000100) ++#define BCM_6328_UART1_BASE (0xb0000120) ++#define BCM_6328_GPIO_BASE (0xb0000080) ++#define BCM_6328_SPI_BASE (0xdeadbeef) ++#define BCM_6328_UDC0_BASE (0xdeadbeef) ++#define BCM_6328_USBDMA_BASE (0xdeadbeef) ++#define BCM_6328_OHCI0_BASE (0xdeadbeef) ++#define BCM_6328_OHCI_PRIV_BASE (0xdeadbeef) ++#define BCM_6328_USBH_PRIV_BASE (0xdeadbeef) ++#define BCM_6328_MPI_BASE (0xdeadbeef) ++#define BCM_6328_PCMCIA_BASE (0xdeadbeef) ++#define BCM_6328_SDRAM_REGS_BASE (0xdeadbeef) ++#define BCM_6328_DSL_BASE (0xb0001900) ++#define BCM_6328_UBUS_BASE (0xdeadbeef) ++#define BCM_6328_ENET0_BASE (0xdeadbeef) ++#define BCM_6328_ENET1_BASE (0xdeadbeef) ++#define BCM_6328_ENETDMA_BASE (0xb000d800) ++#define BCM_6328_ENETDMAC_BASE (0xb000da00) ++#define BCM_6328_ENETDMAS_BASE (0xb000dc00) ++#define BCM_6328_ENETSW_BASE (0xb0e00000) ++#define BCM_6328_EHCI0_BASE (0x10002500) ++#define BCM_6328_SDRAM_BASE (0xdeadbeef) ++#define BCM_6328_MEMC_BASE (0xdeadbeef) ++#define BCM_6328_DDR_BASE (0xb0003000) ++#define BCM_6328_M2M_BASE (0xdeadbeef) ++#define BCM_6328_ATM_BASE (0xdeadbeef) ++#define BCM_6328_XTM_BASE (0xdeadbeef) ++#define BCM_6328_XTMDMA_BASE (0xb000b800) ++#define BCM_6328_XTMDMAC_BASE (0xdeadbeef) ++#define BCM_6328_XTMDMAS_BASE (0xdeadbeef) ++#define BCM_6328_PCM_BASE (0xb000a800) ++#define BCM_6328_PCMDMA_BASE (0xdeadbeef) ++#define BCM_6328_PCMDMAC_BASE (0xdeadbeef) ++#define BCM_6328_PCMDMAS_BASE (0xdeadbeef) ++#define BCM_6328_RNG_BASE (0xdeadbeef) ++#define BCM_6328_MISC_BASE (0xb0001800) ++/* + * 6338 register sets base address + */ + #define BCM_6338_DSL_LMEM_BASE (0xfff00000) +@@ -198,6 +256,7 @@ enum bcm63xx_regs_set { + #define BCM_6338_PCMDMAC_BASE (0xdeadbeef) + #define BCM_6338_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6338_RNG_BASE (0xdeadbeef) ++#define BCM_6338_MISC_BASE (0xdeadbeef) + + /* + * 6345 register sets base address +@@ -242,6 +301,7 @@ enum bcm63xx_regs_set { + #define BCM_6345_PCMDMAC_BASE (0xdeadbeef) + #define BCM_6345_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6345_RNG_BASE (0xdeadbeef) ++#define BCM_6345_MISC_BASE (0xdeadbeef) + + /* + * 6348 register sets base address +@@ -283,6 +343,7 @@ enum bcm63xx_regs_set { + #define BCM_6348_PCMDMAC_BASE (0xdeadbeef) + #define BCM_6348_PCMDMAS_BASE (0xdeadbeef) + #define BCM_6348_RNG_BASE (0xdeadbeef) ++#define BCM_6348_MISC_BASE (0xdeadbeef) + + /* + * 6358 register sets base address +@@ -324,6 +385,7 @@ enum bcm63xx_regs_set { + #define BCM_6358_PCMDMAC_BASE (0xfffe1900) + #define BCM_6358_PCMDMAS_BASE (0xfffe1a00) + #define BCM_6358_RNG_BASE (0xdeadbeef) ++#define BCM_6358_MISC_BASE (0xdeadbeef) + + + /* +@@ -366,6 +428,7 @@ enum bcm63xx_regs_set { + #define BCM_6368_PCMDMAC_BASE (0xb0005a00) + #define BCM_6368_PCMDMAS_BASE (0xb0005c00) + #define BCM_6368_RNG_BASE (0xb0004180) ++#define BCM_6368_MISC_BASE (0xdeadbeef) + + + extern const unsigned long *bcm63xx_regs_base; +@@ -412,6 +475,7 @@ extern const unsigned long *bcm63xx_regs + __GEN_RSET_BASE(__cpu, PCMDMAC) \ + __GEN_RSET_BASE(__cpu, PCMDMAS) \ + __GEN_RSET_BASE(__cpu, RNG) \ ++ __GEN_RSET_BASE(__cpu, MISC) \ + } + + #define __GEN_CPU_REGS_TABLE(__cpu) \ +@@ -451,6 +515,7 @@ extern const unsigned long *bcm63xx_regs + [RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \ + [RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \ + [RSET_RNG] = BCM_## __cpu ##_RNG_BASE, \ ++ [RSET_MISC] = BCM_## __cpu ##_MISC_BASE, \ + + + static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) +@@ -458,6 +523,9 @@ static inline unsigned long bcm63xx_regs + #ifdef BCMCPU_RUNTIME_DETECT + return bcm63xx_regs_base[set]; + #else ++#ifdef CONFIG_BCM63XX_CPU_6328 ++ __GEN_RSET(6328) ++#endif + #ifdef CONFIG_BCM63XX_CPU_6338 + __GEN_RSET(6338) + #endif +@@ -512,6 +580,47 @@ enum bcm63xx_irq { + }; + + /* ++ * 6328 irqs ++ */ ++#define BCM_6328_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32) ++ ++#define BCM_6328_TIMER_IRQ (IRQ_INTERNAL_BASE + 31) ++#define BCM_6328_SPI_IRQ 0 ++#define BCM_6328_UART0_IRQ (IRQ_INTERNAL_BASE + 28) ++#define BCM_6328_UART1_IRQ (BCM_6328_HIGH_IRQ_BASE + 7) ++#define BCM_6328_DSL_IRQ (IRQ_INTERNAL_BASE + 4) ++#define BCM_6328_UDC0_IRQ 0 ++#define BCM_6328_ENET0_IRQ 0 ++#define BCM_6328_ENET1_IRQ 0 ++#define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12) ++#define BCM_6328_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9) ++#define BCM_6328_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10) ++#define BCM_6328_PCMCIA_IRQ 0 ++#define BCM_6328_ENET0_RXDMA_IRQ 0 ++#define BCM_6328_ENET0_TXDMA_IRQ 0 ++#define BCM_6328_ENET1_RXDMA_IRQ 0 ++#define BCM_6328_ENET1_TXDMA_IRQ 0 ++#define BCM_6328_PCI_IRQ (IRQ_INTERNAL_BASE + 23) ++#define BCM_6328_ATM_IRQ 0 ++#define BCM_6328_ENETSW_RXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 0) ++#define BCM_6328_ENETSW_RXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 1) ++#define BCM_6328_ENETSW_RXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 2) ++#define BCM_6328_ENETSW_RXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 3) ++#define BCM_6328_ENETSW_TXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 4) ++#define BCM_6328_ENETSW_TXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 5) ++#define BCM_6328_ENETSW_TXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 6) ++#define BCM_6328_ENETSW_TXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 7) ++#define BCM_6328_XTM_IRQ (BCM_6328_HIGH_IRQ_BASE + 31) ++#define BCM_6328_XTM_DMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 11) ++ ++#define BCM_6328_PCM_DMA0_IRQ (IRQ_INTERNAL_BASE + 2) ++#define BCM_6328_PCM_DMA1_IRQ (IRQ_INTERNAL_BASE + 3) ++#define BCM_6328_EXT_IRQ0 (IRQ_INTERNAL_BASE + 24) ++#define BCM_6328_EXT_IRQ1 (IRQ_INTERNAL_BASE + 25) ++#define BCM_6328_EXT_IRQ2 (IRQ_INTERNAL_BASE + 26) ++#define BCM_6328_EXT_IRQ3 (IRQ_INTERNAL_BASE + 27) ++ ++/* + * 6338 irqs + */ + #define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +@@ -8,6 +8,8 @@ int __init bcm63xx_gpio_init(void); + static inline unsigned long bcm63xx_gpio_count(void) + { + switch (bcm63xx_get_cpu_id()) { ++ case BCM6328_CPU_ID: ++ return 32; + case BCM6358_CPU_ID: + return 40; + case BCM6338_CPU_ID: +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h +@@ -91,5 +91,7 @@ + #define bcm_memc_writel(v, o) bcm_rset_writel(RSET_MEMC, (v), (o)) + #define bcm_ddr_readl(o) bcm_rset_readl(RSET_DDR, (o)) + #define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o)) ++#define bcm_misc_readl(o) bcm_rset_readl(RSET_MISC, (o)) ++#define bcm_misc_writel(v, o) bcm_rset_writel(RSET_MISC, (v), (o)) + + #endif /* ! BCM63XX_IO_H_ */ +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -15,6 +15,30 @@ + /* Clock Control register */ + #define PERF_CKCTL_REG 0x4 + ++#define CKCTL_6328_PHYMIPS_EN (1 << 0) ++#define CKCTL_6328_ADSL_QPROC_EN (1 << 1) ++#define CKCTL_6328_ADSL_AFE_EN (1 << 2) ++#define CKCTL_6328_ADSL_EN (1 << 3) ++#define CKCTL_6328_MIPS_EN (1 << 4) ++#define CKCTL_6328_SAR_EN (1 << 5) ++#define CKCTL_6328_PCM_EN (1 << 6) ++#define CKCTL_6328_USBD_EN (1 << 7) ++#define CKCTL_6328_USBH_EN (1 << 8) ++#define CKCTL_6328_HSSPI_EN (1 << 9) ++#define CKCTL_6328_PCIE_EN (1 << 10) ++#define CKCTL_6328_ROBOSW_EN (1 << 11) ++ ++#define CKCTL_6328_ALL_SAFE_EN (CKCTL_6328_PHYMIPS_EN | \ ++ CKCTL_6328_ADSL_QPROC_EN | \ ++ CKCTL_6328_ADSL_AFE_EN | \ ++ CKCTL_6328_ADSL_EN | \ ++ CKCTL_6328_SAR_EN | \ ++ CKCTL_6328_PCM_EN | \ ++ CKCTL_6328_USBD_EN | \ ++ CKCTL_6328_USBH_EN | \ ++ CKCTL_6328_ROBOSW_EN | \ ++ CKCTL_6328_PCIE_EN) ++ + #define CKCTL_6338_ADSLPHY_EN (1 << 0) + #define CKCTL_6338_MPI_EN (1 << 1) + #define CKCTL_6338_DRAM_EN (1 << 2) +@@ -119,6 +143,7 @@ + #define SYS_PLL_SOFT_RESET 0x1 + + /* Interrupt Mask register */ ++#define PERF_IRQMASK_6328_REG 0x20 + #define PERF_IRQMASK_6338_REG 0xc + #define PERF_IRQMASK_6345_REG 0xc + #define PERF_IRQMASK_6348_REG 0xc +@@ -126,6 +151,7 @@ + #define PERF_IRQMASK_6368_REG 0x20 + + /* Interrupt Status register */ ++#define PERF_IRQSTAT_6328_REG 0x28 + #define PERF_IRQSTAT_6338_REG 0x10 + #define PERF_IRQSTAT_6345_REG 0x10 + #define PERF_IRQSTAT_6348_REG 0x10 +@@ -133,6 +159,7 @@ + #define PERF_IRQSTAT_6368_REG 0x28 + + /* External Interrupt Configuration register */ ++#define PERF_EXTIRQ_CFG_REG_6328 0x18 + #define PERF_EXTIRQ_CFG_REG_6338 0x14 + #define PERF_EXTIRQ_CFG_REG_6348 0x14 + #define PERF_EXTIRQ_CFG_REG_6358 0x14 +@@ -162,8 +189,21 @@ + + /* Soft Reset register */ + #define PERF_SOFTRESET_REG 0x28 ++#define PERF_SOFTRESET_6328_REG 0x10 + #define PERF_SOFTRESET_6368_REG 0x10 + ++#define SOFTRESET_6328_SPI_MASK (1 << 0) ++#define SOFTRESET_6328_EPHY_MASK (1 << 1) ++#define SOFTRESET_6328_SAR_MASK (1 << 2) ++#define SOFTRESET_6328_ENETSW_MASK (1 << 3) ++#define SOFTRESET_6328_USBS_MASK (1 << 4) ++#define SOFTRESET_6328_USBH_MASK (1 << 5) ++#define SOFTRESET_6328_PCM_MASK (1 << 6) ++#define SOFTRESET_6328_PCIE_CORE_MASK (1 << 7) ++#define SOFTRESET_6328_PCIE_MASK (1 << 8) ++#define SOFTRESET_6328_PCIE_EXT_MASK (1 << 9) ++#define SOFTRESET_6328_PCIE_HARD_MASK (1 << 10) ++ + #define SOFTRESET_6338_SPI_MASK (1 << 0) + #define SOFTRESET_6338_ENET_MASK (1 << 2) + #define SOFTRESET_6338_USBH_MASK (1 << 3) +@@ -307,6 +347,8 @@ + /* Watchdog reset length register */ + #define WDT_RSTLEN_REG 0x8 + ++/* Watchdog soft reset register (BCM6328 only) */ ++#define WDT_SOFTRESET_REG 0xc + + /************************************************************************* + * _REG relative to RSET_UARTx +@@ -933,6 +975,8 @@ + * _REG relative to RSET_DDR + *************************************************************************/ + ++#define DDR_CSEND_REG 0x8 ++ + #define DDR_DMIPSPLLCFG_REG 0x18 + #define DMIPSPLLCFG_M1_SHIFT 0 + #define DMIPSPLLCFG_M1_MASK (0xff << DMIPSPLLCFG_M1_SHIFT) +@@ -1122,4 +1166,14 @@ + #define SPI_SSOFFTIME_SHIFT 3 + #define SPI_BYTE_SWAP 0x80 + ++/************************************************************************* ++ * _REG relative to RSET_MISC ++ *************************************************************************/ ++ ++#define MISC_STRAPBUS_6328_REG 0x240 ++#define STRAPBUS_6328_FCVO_SHIFT 7 ++#define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT) ++#define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28) ++#define STRAPBUS_6328_BOOT_SEL_NAND (0 << 28) ++ + #endif /* BCM63XX_REGS_H_ */ +--- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h ++++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h +@@ -18,6 +18,7 @@ static inline int is_bcm63xx_internal_re + if (offset >= 0xfff00000) + return 1; + break; ++ case BCM6328_CPU_ID: + case BCM6368_CPU_ID: + if (offset >= 0xb0000000 && offset < 0xb1000000) + return 1; diff --git a/target/linux/brcm63xx/patches-3.3/026-MIPS-BCM63XX-Move-the-PCI-initialization-into-its-ow.patch b/target/linux/brcm63xx/patches-3.3/026-MIPS-BCM63XX-Move-the-PCI-initialization-into-its-ow.patch new file mode 100644 index 000000000..0f44b4910 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/026-MIPS-BCM63XX-Move-the-PCI-initialization-into-its-ow.patch @@ -0,0 +1,61 @@ +From b8420b9150fa03fcdfacd32e8c5ad286e208d5e9 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Wed, 13 Jun 2012 16:48:02 +0100 +Subject: [PATCH 5/8] MIPS: BCM63XX: Move the PCI initialization into its own function + +Also make the cpu check a bit more explicit. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: Maxime Bizon <mbizon@freebox.fr> +Cc: Florian Fainelli <florian@openwrt.org> +Cc: Kevin Cernekee <cernekee@gmail.com> +Patchwork: https://patchwork.linux-mips.org/patch/3953/ +Reviewed-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/pci/pci-bcm63xx.c | 25 +++++++++++++++++-------- + 1 files changed, 17 insertions(+), 8 deletions(-) + +--- a/arch/mips/pci/pci-bcm63xx.c ++++ b/arch/mips/pci/pci-bcm63xx.c +@@ -94,17 +94,10 @@ static void bcm63xx_int_cfg_writel(u32 v + + void __iomem *pci_iospace_start; + +-static int __init bcm63xx_pci_init(void) ++static int __init bcm63xx_register_pci(void) + { + unsigned int mem_size; + u32 val; +- +- if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368()) +- return -ENODEV; +- +- if (!bcm63xx_pci_enabled) +- return -ENODEV; +- + /* + * configuration access are done through IO space, remap 4 + * first bytes to access it from CPU. +@@ -221,4 +214,20 @@ static int __init bcm63xx_pci_init(void) + return 0; + } + ++ ++static int __init bcm63xx_pci_init(void) ++{ ++ if (!bcm63xx_pci_enabled) ++ return -ENODEV; ++ ++ switch (bcm63xx_get_cpu_id()) { ++ case BCM6348_CPU_ID: ++ case BCM6358_CPU_ID: ++ case BCM6368_CPU_ID: ++ return bcm63xx_register_pci(); ++ default: ++ return -ENODEV; ++ } ++} ++ + arch_initcall(bcm63xx_pci_init); diff --git a/target/linux/brcm63xx/patches-3.3/027-MIPS-BCM63XX-Add-PCIe-Support-for-BCM6328.patch b/target/linux/brcm63xx/patches-3.3/027-MIPS-BCM63XX-Add-PCIe-Support-for-BCM6328.patch new file mode 100644 index 000000000..ff375cd2a --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/027-MIPS-BCM63XX-Add-PCIe-Support-for-BCM6328.patch @@ -0,0 +1,427 @@ +From 45655e79f84e35c13b8964b961d804e64b3aca91 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Wed, 13 Jun 2012 17:07:13 +0100 +Subject: [PATCH 6/8] MIPS: BCM63XX: Add PCIe Support for BCM6328 + +Add support for the PCIe port found on BCM6328. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: Maxime Bizon <mbizon@freebox.fr> +Cc: Florian Fainelli <florian@openwrt.org> +Cc: Kevin Cernekee <cernekee@gmail.com> +Patchwork: https://patchwork.linux-mips.org/patch/3956/ +Reviewed-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/bcm63xx/Kconfig | 1 + + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 9 ++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h | 6 + + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 54 ++++++++++ + arch/mips/pci/ops-bcm63xx.c | 61 +++++++++++ + arch/mips/pci/pci-bcm63xx.c | 112 +++++++++++++++++++++ + arch/mips/pci/pci-bcm63xx.h | 5 + + 7 files changed, 248 insertions(+), 0 deletions(-) + +--- a/arch/mips/bcm63xx/Kconfig ++++ b/arch/mips/bcm63xx/Kconfig +@@ -3,6 +3,7 @@ menu "CPU support" + + config BCM63XX_CPU_6328 + bool "support 6328 CPU" ++ select HW_HAS_PCI + + config BCM63XX_CPU_6338 + bool "support 6338 CPU" +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -122,6 +122,7 @@ enum bcm63xx_regs_set { + RSET_USBH_PRIV, + RSET_MPI, + RSET_PCMCIA, ++ RSET_PCIE, + RSET_DSL, + RSET_ENET0, + RSET_ENET1, +@@ -188,6 +189,7 @@ enum bcm63xx_regs_set { + #define BCM_6328_USBH_PRIV_BASE (0xdeadbeef) + #define BCM_6328_MPI_BASE (0xdeadbeef) + #define BCM_6328_PCMCIA_BASE (0xdeadbeef) ++#define BCM_6328_PCIE_BASE (0xb0e40000) + #define BCM_6328_SDRAM_REGS_BASE (0xdeadbeef) + #define BCM_6328_DSL_BASE (0xb0001900) + #define BCM_6328_UBUS_BASE (0xdeadbeef) +@@ -232,6 +234,7 @@ enum bcm63xx_regs_set { + #define BCM_6338_USBH_PRIV_BASE (0xdeadbeef) + #define BCM_6338_MPI_BASE (0xfffe3160) + #define BCM_6338_PCMCIA_BASE (0xdeadbeef) ++#define BCM_6338_PCIE_BASE (0xdeadbeef) + #define BCM_6338_SDRAM_REGS_BASE (0xfffe3100) + #define BCM_6338_DSL_BASE (0xfffe1000) + #define BCM_6338_UBUS_BASE (0xdeadbeef) +@@ -279,6 +282,7 @@ enum bcm63xx_regs_set { + #define BCM_6345_ENETSW_BASE (0xdeadbeef) + #define BCM_6345_PCMCIA_BASE (0xfffe2028) + #define BCM_6345_MPI_BASE (0xfffe2000) ++#define BCM_6345_PCIE_BASE (0xdeadbeef) + #define BCM_6345_OHCI0_BASE (0xfffe2100) + #define BCM_6345_OHCI_PRIV_BASE (0xfffe2200) + #define BCM_6345_USBH_PRIV_BASE (0xdeadbeef) +@@ -320,6 +324,7 @@ enum bcm63xx_regs_set { + #define BCM_6348_USBH_PRIV_BASE (0xdeadbeef) + #define BCM_6348_MPI_BASE (0xfffe2000) + #define BCM_6348_PCMCIA_BASE (0xfffe2054) ++#define BCM_6348_PCIE_BASE (0xdeadbeef) + #define BCM_6348_SDRAM_REGS_BASE (0xfffe2300) + #define BCM_6348_M2M_BASE (0xfffe2800) + #define BCM_6348_DSL_BASE (0xfffe3000) +@@ -362,6 +367,7 @@ enum bcm63xx_regs_set { + #define BCM_6358_USBH_PRIV_BASE (0xfffe1500) + #define BCM_6358_MPI_BASE (0xfffe1000) + #define BCM_6358_PCMCIA_BASE (0xfffe1054) ++#define BCM_6358_PCIE_BASE (0xdeadbeef) + #define BCM_6358_SDRAM_REGS_BASE (0xfffe2300) + #define BCM_6358_M2M_BASE (0xdeadbeef) + #define BCM_6358_DSL_BASE (0xfffe3000) +@@ -405,6 +411,7 @@ enum bcm63xx_regs_set { + #define BCM_6368_USBH_PRIV_BASE (0xb0001700) + #define BCM_6368_MPI_BASE (0xb0001000) + #define BCM_6368_PCMCIA_BASE (0xb0001054) ++#define BCM_6368_PCIE_BASE (0xdeadbeef) + #define BCM_6368_SDRAM_REGS_BASE (0xdeadbeef) + #define BCM_6368_M2M_BASE (0xdeadbeef) + #define BCM_6368_DSL_BASE (0xdeadbeef) +@@ -453,6 +460,7 @@ extern const unsigned long *bcm63xx_regs + __GEN_RSET_BASE(__cpu, USBH_PRIV) \ + __GEN_RSET_BASE(__cpu, MPI) \ + __GEN_RSET_BASE(__cpu, PCMCIA) \ ++ __GEN_RSET_BASE(__cpu, PCIE) \ + __GEN_RSET_BASE(__cpu, DSL) \ + __GEN_RSET_BASE(__cpu, ENET0) \ + __GEN_RSET_BASE(__cpu, ENET1) \ +@@ -493,6 +501,7 @@ extern const unsigned long *bcm63xx_regs + [RSET_USBH_PRIV] = BCM_## __cpu ##_USBH_PRIV_BASE, \ + [RSET_MPI] = BCM_## __cpu ##_MPI_BASE, \ + [RSET_PCMCIA] = BCM_## __cpu ##_PCMCIA_BASE, \ ++ [RSET_PCIE] = BCM_## __cpu ##_PCIE_BASE, \ + [RSET_DSL] = BCM_## __cpu ##_DSL_BASE, \ + [RSET_ENET0] = BCM_## __cpu ##_ENET0_BASE, \ + [RSET_ENET1] = BCM_## __cpu ##_ENET1_BASE, \ +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h +@@ -40,6 +40,10 @@ + #define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \ + BCM_CB_MEM_SIZE - 1) + ++#define BCM_PCIE_MEM_BASE_PA 0x10f00000 ++#define BCM_PCIE_MEM_SIZE (16 * 1024 * 1024) ++#define BCM_PCIE_MEM_END_PA (BCM_PCIE_MEM_BASE_PA + \ ++ BCM_PCIE_MEM_SIZE - 1) + + /* + * Internal registers are accessed through KSEG3 +@@ -85,6 +89,8 @@ + #define bcm_mpi_writel(v, o) bcm_rset_writel(RSET_MPI, (v), (o)) + #define bcm_pcmcia_readl(o) bcm_rset_readl(RSET_PCMCIA, (o)) + #define bcm_pcmcia_writel(v, o) bcm_rset_writel(RSET_PCMCIA, (v), (o)) ++#define bcm_pcie_readl(o) bcm_rset_readl(RSET_PCIE, (o)) ++#define bcm_pcie_writel(v, o) bcm_rset_writel(RSET_PCIE, (v), (o)) + #define bcm_sdram_readl(o) bcm_rset_readl(RSET_SDRAM, (o)) + #define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o)) + #define bcm_memc_readl(o) bcm_rset_readl(RSET_MEMC, (o)) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -1169,6 +1169,9 @@ + /************************************************************************* + * _REG relative to RSET_MISC + *************************************************************************/ ++#define MISC_SERDES_CTRL_REG 0x0 ++#define SERDES_PCIE_EN (1 << 0) ++#define SERDES_PCIE_EXD_EN (1 << 15) + + #define MISC_STRAPBUS_6328_REG 0x240 + #define STRAPBUS_6328_FCVO_SHIFT 7 +@@ -1176,4 +1179,55 @@ + #define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28) + #define STRAPBUS_6328_BOOT_SEL_NAND (0 << 28) + ++/************************************************************************* ++ * _REG relative to RSET_PCIE ++ *************************************************************************/ ++ ++#define PCIE_CONFIG2_REG 0x408 ++#define CONFIG2_BAR1_SIZE_EN 1 ++#define CONFIG2_BAR1_SIZE_MASK 0xf ++ ++#define PCIE_IDVAL3_REG 0x43c ++#define IDVAL3_CLASS_CODE_MASK 0xffffff ++#define IDVAL3_SUBCLASS_SHIFT 8 ++#define IDVAL3_CLASS_SHIFT 16 ++ ++#define PCIE_DLSTATUS_REG 0x1048 ++#define DLSTATUS_PHYLINKUP (1 << 13) ++ ++#define PCIE_BRIDGE_OPT1_REG 0x2820 ++#define OPT1_RD_BE_OPT_EN (1 << 7) ++#define OPT1_RD_REPLY_BE_FIX_EN (1 << 9) ++#define OPT1_PCIE_BRIDGE_HOLE_DET_EN (1 << 11) ++#define OPT1_L1_INT_STATUS_MASK_POL (1 << 12) ++ ++#define PCIE_BRIDGE_OPT2_REG 0x2824 ++#define OPT2_UBUS_UR_DECODE_DIS (1 << 2) ++#define OPT2_TX_CREDIT_CHK_EN (1 << 4) ++#define OPT2_CFG_TYPE1_BD_SEL (1 << 7) ++#define OPT2_CFG_TYPE1_BUS_NO_SHIFT 16 ++#define OPT2_CFG_TYPE1_BUS_NO_MASK (0xff << OPT2_CFG_TYPE1_BUS_NO_SHIFT) ++ ++#define PCIE_BRIDGE_BAR0_BASEMASK_REG 0x2828 ++#define PCIE_BRIDGE_BAR1_BASEMASK_REG 0x2830 ++#define BASEMASK_REMAP_EN (1 << 0) ++#define BASEMASK_SWAP_EN (1 << 1) ++#define BASEMASK_MASK_SHIFT 4 ++#define BASEMASK_MASK_MASK (0xfff << BASEMASK_MASK_SHIFT) ++#define BASEMASK_BASE_SHIFT 20 ++#define BASEMASK_BASE_MASK (0xfff << BASEMASK_BASE_SHIFT) ++ ++#define PCIE_BRIDGE_BAR0_REBASE_ADDR_REG 0x282c ++#define PCIE_BRIDGE_BAR1_REBASE_ADDR_REG 0x2834 ++#define REBASE_ADDR_BASE_SHIFT 20 ++#define REBASE_ADDR_BASE_MASK (0xfff << REBASE_ADDR_BASE_SHIFT) ++ ++#define PCIE_BRIDGE_RC_INT_MASK_REG 0x2854 ++#define PCIE_RC_INT_A (1 << 0) ++#define PCIE_RC_INT_B (1 << 1) ++#define PCIE_RC_INT_C (1 << 2) ++#define PCIE_RC_INT_D (1 << 3) ++ ++#define PCIE_DEVICE_OFFSET 0x8000 ++ + #endif /* BCM63XX_REGS_H_ */ +--- a/arch/mips/pci/ops-bcm63xx.c ++++ b/arch/mips/pci/ops-bcm63xx.c +@@ -465,3 +465,64 @@ static void bcm63xx_fixup(struct pci_dev + + DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup); + #endif ++ ++static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn) ++{ ++ switch (bus->number) { ++ case PCIE_BUS_BRIDGE: ++ return (PCI_SLOT(devfn) == 0); ++ case PCIE_BUS_DEVICE: ++ if (PCI_SLOT(devfn) == 0) ++ return bcm_pcie_readl(PCIE_DLSTATUS_REG) ++ & DLSTATUS_PHYLINKUP; ++ default: ++ return false; ++ } ++} ++ ++static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 *val) ++{ ++ u32 data; ++ u32 reg = where & ~3; ++ ++ if (!bcm63xx_pcie_can_access(bus, devfn)) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ if (bus->number == PCIE_BUS_DEVICE) ++ reg += PCIE_DEVICE_OFFSET; ++ ++ data = bcm_pcie_readl(reg); ++ ++ *val = postprocess_read(data, where, size); ++ ++ return PCIBIOS_SUCCESSFUL; ++ ++} ++ ++static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn, ++ int where, int size, u32 val) ++{ ++ u32 data; ++ u32 reg = where & ~3; ++ ++ if (!bcm63xx_pcie_can_access(bus, devfn)) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ if (bus->number == PCIE_BUS_DEVICE) ++ reg += PCIE_DEVICE_OFFSET; ++ ++ ++ data = bcm_pcie_readl(reg); ++ ++ data = preprocess_write(data, val, where, size); ++ bcm_pcie_writel(data, reg); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++ ++struct pci_ops bcm63xx_pcie_ops = { ++ .read = bcm63xx_pcie_read, ++ .write = bcm63xx_pcie_write ++}; +--- a/arch/mips/pci/pci-bcm63xx.c ++++ b/arch/mips/pci/pci-bcm63xx.c +@@ -10,6 +10,7 @@ + #include <linux/pci.h> + #include <linux/kernel.h> + #include <linux/init.h> ++#include <linux/delay.h> + #include <asm/bootinfo.h> + + #include "pci-bcm63xx.h" +@@ -71,6 +72,26 @@ struct pci_controller bcm63xx_cb_control + }; + #endif + ++static struct resource bcm_pcie_mem_resource = { ++ .name = "bcm63xx PCIe memory space", ++ .start = BCM_PCIE_MEM_BASE_PA, ++ .end = BCM_PCIE_MEM_END_PA, ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct resource bcm_pcie_io_resource = { ++ .name = "bcm63xx PCIe IO space", ++ .start = 0, ++ .end = 0, ++ .flags = 0, ++}; ++ ++struct pci_controller bcm63xx_pcie_controller = { ++ .pci_ops = &bcm63xx_pcie_ops, ++ .io_resource = &bcm_pcie_io_resource, ++ .mem_resource = &bcm_pcie_mem_resource, ++}; ++ + static u32 bcm63xx_int_cfg_readl(u32 reg) + { + u32 tmp; +@@ -94,6 +115,95 @@ static void bcm63xx_int_cfg_writel(u32 v + + void __iomem *pci_iospace_start; + ++static void __init bcm63xx_reset_pcie(void) ++{ ++ u32 val; ++ ++ /* enable clock */ ++ val = bcm_perf_readl(PERF_CKCTL_REG); ++ val |= CKCTL_6328_PCIE_EN; ++ bcm_perf_writel(val, PERF_CKCTL_REG); ++ ++ /* enable SERDES */ ++ val = bcm_misc_readl(MISC_SERDES_CTRL_REG); ++ val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN; ++ bcm_misc_writel(val, MISC_SERDES_CTRL_REG); ++ ++ /* reset the PCIe core */ ++ val = bcm_perf_readl(PERF_SOFTRESET_6328_REG); ++ ++ val &= ~SOFTRESET_6328_PCIE_MASK; ++ val &= ~SOFTRESET_6328_PCIE_CORE_MASK; ++ val &= ~SOFTRESET_6328_PCIE_HARD_MASK; ++ val &= ~SOFTRESET_6328_PCIE_EXT_MASK; ++ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); ++ mdelay(10); ++ ++ val |= SOFTRESET_6328_PCIE_MASK; ++ val |= SOFTRESET_6328_PCIE_CORE_MASK; ++ val |= SOFTRESET_6328_PCIE_HARD_MASK; ++ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); ++ mdelay(10); ++ ++ val |= SOFTRESET_6328_PCIE_EXT_MASK; ++ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); ++ mdelay(200); ++} ++ ++static int __init bcm63xx_register_pcie(void) ++{ ++ u32 val; ++ ++ bcm63xx_reset_pcie(); ++ ++ /* configure the PCIe bridge */ ++ val = bcm_pcie_readl(PCIE_BRIDGE_OPT1_REG); ++ val |= OPT1_RD_BE_OPT_EN; ++ val |= OPT1_RD_REPLY_BE_FIX_EN; ++ val |= OPT1_PCIE_BRIDGE_HOLE_DET_EN; ++ val |= OPT1_L1_INT_STATUS_MASK_POL; ++ bcm_pcie_writel(val, PCIE_BRIDGE_OPT1_REG); ++ ++ /* setup the interrupts */ ++ val = bcm_pcie_readl(PCIE_BRIDGE_RC_INT_MASK_REG); ++ val |= PCIE_RC_INT_A | PCIE_RC_INT_B | PCIE_RC_INT_C | PCIE_RC_INT_D; ++ bcm_pcie_writel(val, PCIE_BRIDGE_RC_INT_MASK_REG); ++ ++ val = bcm_pcie_readl(PCIE_BRIDGE_OPT2_REG); ++ /* enable credit checking and error checking */ ++ val |= OPT2_TX_CREDIT_CHK_EN; ++ val |= OPT2_UBUS_UR_DECODE_DIS; ++ ++ /* set device bus/func for the pcie device */ ++ val |= (PCIE_BUS_DEVICE << OPT2_CFG_TYPE1_BUS_NO_SHIFT); ++ val |= OPT2_CFG_TYPE1_BD_SEL; ++ bcm_pcie_writel(val, PCIE_BRIDGE_OPT2_REG); ++ ++ /* setup class code as bridge */ ++ val = bcm_pcie_readl(PCIE_IDVAL3_REG); ++ val &= ~IDVAL3_CLASS_CODE_MASK; ++ val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT); ++ bcm_pcie_writel(val, PCIE_IDVAL3_REG); ++ ++ /* disable bar1 size */ ++ val = bcm_pcie_readl(PCIE_CONFIG2_REG); ++ val &= ~CONFIG2_BAR1_SIZE_MASK; ++ bcm_pcie_writel(val, PCIE_CONFIG2_REG); ++ ++ /* set bar0 to little endian */ ++ val = (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_BASE_SHIFT; ++ val |= (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_MASK_SHIFT; ++ val |= BASEMASK_REMAP_EN; ++ bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG); ++ ++ val = (BCM_PCIE_MEM_BASE_PA >> 20) << REBASE_ADDR_BASE_SHIFT; ++ bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG); ++ ++ register_pci_controller(&bcm63xx_pcie_controller); ++ ++ return 0; ++} ++ + static int __init bcm63xx_register_pci(void) + { + unsigned int mem_size; +@@ -221,6 +331,8 @@ static int __init bcm63xx_pci_init(void) + return -ENODEV; + + switch (bcm63xx_get_cpu_id()) { ++ case BCM6328_CPU_ID: ++ return bcm63xx_register_pcie(); + case BCM6348_CPU_ID: + case BCM6358_CPU_ID: + case BCM6368_CPU_ID: +--- a/arch/mips/pci/pci-bcm63xx.h ++++ b/arch/mips/pci/pci-bcm63xx.h +@@ -13,11 +13,16 @@ + */ + #define CARDBUS_PCI_IDSEL 0x8 + ++ ++#define PCIE_BUS_BRIDGE 0 ++#define PCIE_BUS_DEVICE 1 ++ + /* + * defined in ops-bcm63xx.c + */ + extern struct pci_ops bcm63xx_pci_ops; + extern struct pci_ops bcm63xx_cb_ops; ++extern struct pci_ops bcm63xx_pcie_ops; + + /* + * defined in pci-bcm63xx.c diff --git a/target/linux/brcm63xx/patches-3.3/028-MIPS-Expose-PCIe-drivers-for-MIPS.patch b/target/linux/brcm63xx/patches-3.3/028-MIPS-Expose-PCIe-drivers-for-MIPS.patch new file mode 100644 index 000000000..3169ca2fa --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/028-MIPS-Expose-PCIe-drivers-for-MIPS.patch @@ -0,0 +1,28 @@ +From 4831929b8c37aa866afca1498001c939377e5a67 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Wed, 13 Jun 2012 17:07:16 +0100 +Subject: [PATCH 7/8] MIPS: Expose PCIe drivers for MIPS + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +Cc: linux-mips@linux-mips.org +Cc: Maxime Bizon <mbizon@freebox.fr> +Cc: Florian Fainelli <florian@openwrt.org> +Cc: Kevin Cernekee <cernekee@gmail.com> +Patchwork: https://patchwork.linux-mips.org/patch/3957/ +Reviewed-by: Florian Fainelli <florian@openwrt.org> +Signed-off-by: Ralf Baechle <ralf@linux-mips.org> +--- + arch/mips/Kconfig | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +--- a/arch/mips/Kconfig ++++ b/arch/mips/Kconfig +@@ -2392,6 +2392,8 @@ config PCI_DOMAINS + + source "drivers/pci/Kconfig" + ++source "drivers/pci/pcie/Kconfig" ++ + # + # ISA support is now enabled via select. Too many systems still have the one + # or other ISA chip on the board that users don't know about so don't expect diff --git a/target/linux/brcm63xx/patches-3.3/100-MIPS-BCM63XX-add-missing-include-for-bcm63xx_gpio.h.patch b/target/linux/brcm63xx/patches-3.3/100-MIPS-BCM63XX-add-missing-include-for-bcm63xx_gpio.h.patch new file mode 100644 index 000000000..f6b15ac6f --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/100-MIPS-BCM63XX-add-missing-include-for-bcm63xx_gpio.h.patch @@ -0,0 +1,41 @@ +From a183d93bf0c6f9219ef1dd6e4948edf81c57ea3b Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 2 Feb 2012 09:27:58 +0100 +Subject: [PATCH] MIPS: BCM63XX: add missing include for bcm63xx_gpio.h + +bcm63xx_gpio.h uses macros defined in bcm63xx_cpu.h without including it, +leading to the following build failure: + + CC [M] drivers/mmc/core/cd-gpio.o +In file included from arch/mips/include/asm/mach-bcm63xx/gpio.h:4:0, + from arch/mips/include/asm/gpio.h:4, + from include/linux/gpio.h:30, + from drivers/mmc/core/cd-gpio.c:12: + +arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h: In function 'bcm63xx_gpio_count': +arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:10:2: error: implicit declaration of function 'bcm63xx_get_cpu_id' +arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:11:7: error: 'BCM6358_CPU_ID' undeclared (first use in this function) +arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:11:7: note: each undeclared identifier is reported only once for each function it appears in +arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:13:7: error: 'BCM6338_CPU_ID' undeclared (first use in this function) +arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:15:7: error: 'BCM6345_CPU_ID' undeclared (first use in this function) +arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:17:7: error: 'BCM6368_CPU_ID' undeclared (first use in this function) +arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h:19:7: error: 'BCM6348_CPU_ID' undeclared (first use in this function) + +make[7]: *** [drivers/mmc/core/cd-gpio.o] Error 1 + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + + arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +@@ -2,6 +2,7 @@ + #define BCM63XX_GPIO_H + + #include <linux/init.h> ++#include <bcm63xx_cpu.h> + + int __init bcm63xx_gpio_init(void); + diff --git a/target/linux/brcm63xx/patches-3.3/101-MTD-bcm63xxpart-remove-unused-variable.patch b/target/linux/brcm63xx/patches-3.3/101-MTD-bcm63xxpart-remove-unused-variable.patch new file mode 100644 index 000000000..470f96663 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/101-MTD-bcm63xxpart-remove-unused-variable.patch @@ -0,0 +1,41 @@ +From 2962bbe9cc807549c0705551c5b7be47e34e3fac Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Mon, 30 Apr 2012 09:32:56 +0200 +Subject: [PATCH 20/79] MTD: bcm63xxpart: remove unused variable + +namelen is never used, so drop it. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/mtd/bcm63xxpart.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -79,7 +79,6 @@ static int bcm63xx_parse_cfe_partitions( + unsigned int rootfsaddr, kerneladdr, spareaddr; + unsigned int rootfslen, kernellen, sparelen, totallen; + unsigned int cfelen, nvramlen; +- int namelen = 0; + int i; + u32 computed_crc; + bool rootfs_first = false; +@@ -143,15 +142,11 @@ static int bcm63xx_parse_cfe_partitions( + } + + /* Determine number of partitions */ +- namelen = 8; +- if (rootfslen > 0) { ++ if (rootfslen > 0) + nrparts++; +- namelen += 6; +- } +- if (kernellen > 0) { ++ ++ if (kernellen > 0) + nrparts++; +- namelen += 6; +- } + + /* Ask kernel for more memory */ + parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); diff --git a/target/linux/brcm63xx/patches-3.3/102-MTD-bcm63xxpart-merge-sparelen-calculation.patch b/target/linux/brcm63xx/patches-3.3/102-MTD-bcm63xxpart-merge-sparelen-calculation.patch new file mode 100644 index 000000000..da24b1b85 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/102-MTD-bcm63xxpart-merge-sparelen-calculation.patch @@ -0,0 +1,33 @@ +From fd2ab39f22af4176eb3d23acbc4d1218cf835065 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 8 May 2012 09:47:32 +0200 +Subject: [PATCH 21/79] MTD: bcm63xxpart: merge sparelen calculation + +The length of the spare part is calculated the same way in both branches +so move to a common place. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/mtd/bcm63xxpart.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -120,7 +120,6 @@ static int bcm63xx_parse_cfe_partitions( + kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; + rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; + spareaddr = roundup(totallen, master->erasesize) + cfelen; +- sparelen = master->size - spareaddr - nvramlen; + + if (rootfsaddr < kerneladdr) { + /* default Broadcom layout */ +@@ -138,8 +137,8 @@ static int bcm63xx_parse_cfe_partitions( + rootfslen = 0; + rootfsaddr = 0; + spareaddr = cfelen; +- sparelen = master->size - cfelen - nvramlen; + } ++ sparelen = master->size - spareaddr - nvramlen; + + /* Determine number of partitions */ + if (rootfslen > 0) diff --git a/target/linux/brcm63xx/patches-3.3/103-MTD-bcm63xxpart-make-fixed-part-length-calculation-m.patch b/target/linux/brcm63xx/patches-3.3/103-MTD-bcm63xxpart-make-fixed-part-length-calculation-m.patch new file mode 100644 index 000000000..ca0cddde9 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/103-MTD-bcm63xxpart-make-fixed-part-length-calculation-m.patch @@ -0,0 +1,49 @@ +From 465f1b3ff24dbf3bec43dce344a7bc2640e05ffc Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 8 May 2012 09:53:07 +0200 +Subject: [PATCH 22/79] MTD: bcm63xxpart: make fixed part length calculation + more generic + +The CFE does not use 4K sectors even if the flash supports it, so +for the fixed partitions like CFE itself or NVRAM the erase block +size is always 64k or bigger. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/mtd/bcm63xxpart.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -37,8 +37,7 @@ + + #define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */ + +-#define BCM63XX_MIN_CFE_SIZE 0x10000 /* always at least 64KiB */ +-#define BCM63XX_MIN_NVRAM_SIZE 0x10000 /* always at least 64KiB */ ++#define BCM63XX_CFE_BLOCK_SIZE 0x10000 /* always at least 64KiB */ + + #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 + +@@ -79,6 +78,7 @@ static int bcm63xx_parse_cfe_partitions( + unsigned int rootfsaddr, kerneladdr, spareaddr; + unsigned int rootfslen, kernellen, sparelen, totallen; + unsigned int cfelen, nvramlen; ++ unsigned int cfe_erasesize; + int i; + u32 computed_crc; + bool rootfs_first = false; +@@ -86,8 +86,11 @@ static int bcm63xx_parse_cfe_partitions( + if (bcm63xx_detect_cfe(master)) + return -EINVAL; + +- cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE); +- nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE); ++ cfe_erasesize = max_t(uint32_t, master->erasesize, ++ BCM63XX_CFE_BLOCK_SIZE); ++ ++ cfelen = cfe_erasesize; ++ nvramlen = cfe_erasesize; + + /* Allocate memory for buffer */ + buf = vmalloc(sizeof(struct bcm_tag)); diff --git a/target/linux/brcm63xx/patches-3.3/104-MTD-bcm63xxpart-move-the-last-curpart-to-its-correct.patch b/target/linux/brcm63xx/patches-3.3/104-MTD-bcm63xxpart-move-the-last-curpart-to-its-correct.patch new file mode 100644 index 000000000..8e05803ff --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/104-MTD-bcm63xxpart-move-the-last-curpart-to-its-correct.patch @@ -0,0 +1,26 @@ +From d5173b2c806f4039679b001f1b55a3c245afdf68 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 8 May 2012 10:02:13 +0200 +Subject: [PATCH 23/79] MTD: bcm63xxpart: move the last curpart++ to its + correct place + +The line belongs above the comment, not below it. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/mtd/bcm63xxpart.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -190,9 +190,9 @@ static int bcm63xx_parse_cfe_partitions( + parts[curpart].name = "nvram"; + parts[curpart].offset = master->size - nvramlen; + parts[curpart].size = nvramlen; ++ curpart++; + + /* Global partition "linux" to make easy firmware upgrade */ +- curpart++; + parts[curpart].name = "linux"; + parts[curpart].offset = cfelen; + parts[curpart].size = master->size - cfelen - nvramlen; diff --git a/target/linux/brcm63xx/patches-3.3/105-MTD-bcm63xxpart-use-correct-printk-format-for-partit.patch b/target/linux/brcm63xx/patches-3.3/105-MTD-bcm63xxpart-use-correct-printk-format-for-partit.patch new file mode 100644 index 000000000..60396abae --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/105-MTD-bcm63xxpart-use-correct-printk-format-for-partit.patch @@ -0,0 +1,27 @@ +From 55aa355612ce55dc1943f116ea49e795a098b60c Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 8 May 2012 10:03:27 +0200 +Subject: [PATCH 24/79] MTD: bcm63xxpart: use correct printk format for + partitions + +Use ll to be able to remove the casts. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/mtd/bcm63xxpart.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -198,9 +198,8 @@ static int bcm63xx_parse_cfe_partitions( + parts[curpart].size = master->size - cfelen - nvramlen; + + for (i = 0; i < nrparts; i++) +- pr_info("Partition %d is %s offset %lx and length %lx\n", i, +- parts[i].name, (long unsigned int)(parts[i].offset), +- (long unsigned int)(parts[i].size)); ++ pr_info("Partition %d is %s offset %llx and length %llx\n", i, ++ parts[i].name, parts[i].offset, parts[i].size); + + pr_info("Spare partition is offset %x and length %x\n", spareaddr, + sparelen); diff --git a/target/linux/brcm63xx/patches-3.3/106-bcm63xx_watchdog_section_mismatch.patch b/target/linux/brcm63xx/patches-3.3/106-bcm63xx_watchdog_section_mismatch.patch new file mode 100644 index 000000000..ae4157774 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/106-bcm63xx_watchdog_section_mismatch.patch @@ -0,0 +1,20 @@ +--- a/drivers/watchdog/bcm63xx_wdt.c ++++ b/drivers/watchdog/bcm63xx_wdt.c +@@ -301,7 +301,7 @@ static void bcm63xx_wdt_shutdown(struct + bcm63xx_wdt_pause(); + } + +-static struct platform_driver bcm63xx_wdt = { ++static struct platform_driver bcm63xx_wdt_driver = { + .probe = bcm63xx_wdt_probe, + .remove = __devexit_p(bcm63xx_wdt_remove), + .shutdown = bcm63xx_wdt_shutdown, +@@ -311,7 +311,7 @@ static struct platform_driver bcm63xx_wd + } + }; + +-module_platform_driver(bcm63xx_wdt); ++module_platform_driver(bcm63xx_wdt_driver); + + MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>"); + MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); diff --git a/target/linux/brcm63xx/patches-3.3/107-MIPS-BCM63XX-Fix-USB-IRQ-definitions-for-6328.patch b/target/linux/brcm63xx/patches-3.3/107-MIPS-BCM63XX-Fix-USB-IRQ-definitions-for-6328.patch new file mode 100644 index 000000000..c9d0421a2 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/107-MIPS-BCM63XX-Fix-USB-IRQ-definitions-for-6328.patch @@ -0,0 +1,26 @@ +From 960e1ef3c5b2d69a4a5a6984b6408d65221dd86c Mon Sep 17 00:00:00 2001 +From: Kevin Cernekee <cernekee@gmail.com> +Date: Sat, 23 Jun 2012 04:14:55 +0000 +Subject: [PATCH 06/81] MIPS: BCM63XX: Fix USB IRQ definitions for 6328 + +OHCI/EHCI are in the high (second) word. Not currently used by any +driver. + +Signed-off-by: Kevin Cernekee <cernekee@gmail.com> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -602,8 +602,8 @@ enum bcm63xx_irq { + #define BCM_6328_ENET0_IRQ 0 + #define BCM_6328_ENET1_IRQ 0 + #define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12) +-#define BCM_6328_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9) +-#define BCM_6328_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10) ++#define BCM_6328_OHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 9) ++#define BCM_6328_EHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 10) + #define BCM_6328_PCMCIA_IRQ 0 + #define BCM_6328_ENET0_RXDMA_IRQ 0 + #define BCM_6328_ENET0_TXDMA_IRQ 0 diff --git a/target/linux/brcm63xx/patches-3.3/108-BCM63XX-Add-register-definitions-for-USBD-depen.patch b/target/linux/brcm63xx/patches-3.3/108-BCM63XX-Add-register-definitions-for-USBD-depen.patch new file mode 100644 index 000000000..c2130a563 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/108-BCM63XX-Add-register-definitions-for-USBD-depen.patch @@ -0,0 +1,62 @@ +From 21bb8141c205ae48d331787debb6b272add90ac7 Mon Sep 17 00:00:00 2001 +From: Kevin Cernekee <cernekee@gmail.com> +Date: Sat, 23 Jun 2012 04:14:54 +0000 +Subject: [PATCH 05/81] MIPS: BCM63XX: Add register definitions for USBD + dependencies + +The USB 2.0 device depends on some functionality in other blocks, such +as GPIO and USBH. Add those register definitions here. + +Signed-off-by: Kevin Cernekee <cernekee@gmail.com> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 6 +++--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 8 ++++++++ + 2 files changed, 11 insertions(+), 3 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -184,9 +184,9 @@ enum bcm63xx_regs_set { + #define BCM_6328_SPI_BASE (0xdeadbeef) + #define BCM_6328_UDC0_BASE (0xdeadbeef) + #define BCM_6328_USBDMA_BASE (0xdeadbeef) +-#define BCM_6328_OHCI0_BASE (0xdeadbeef) ++#define BCM_6328_OHCI0_BASE (0xb0002600) + #define BCM_6328_OHCI_PRIV_BASE (0xdeadbeef) +-#define BCM_6328_USBH_PRIV_BASE (0xdeadbeef) ++#define BCM_6328_USBH_PRIV_BASE (0xb0002700) + #define BCM_6328_MPI_BASE (0xdeadbeef) + #define BCM_6328_PCMCIA_BASE (0xdeadbeef) + #define BCM_6328_PCIE_BASE (0xb0e40000) +@@ -199,7 +199,7 @@ enum bcm63xx_regs_set { + #define BCM_6328_ENETDMAC_BASE (0xb000da00) + #define BCM_6328_ENETDMAS_BASE (0xb000dc00) + #define BCM_6328_ENETSW_BASE (0xb0e00000) +-#define BCM_6328_EHCI0_BASE (0x10002500) ++#define BCM_6328_EHCI0_BASE (0xb0002500) + #define BCM_6328_SDRAM_BASE (0xdeadbeef) + #define BCM_6328_MEMC_BASE (0xdeadbeef) + #define BCM_6328_DDR_BASE (0xb0003000) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -543,6 +543,12 @@ + #define GPIO_MODE_6368_SPI_SSN5 (1 << 31) + + ++#define GPIO_PINMUX_OTHR_REG 0x24 ++#define GPIO_PINMUX_OTHR_6328_USB_SHIFT 12 ++#define GPIO_PINMUX_OTHR_6328_USB_MASK (3 << GPIO_PINMUX_OTHR_6328_USB_SHIFT) ++#define GPIO_PINMUX_OTHR_6328_USB_HOST (1 << GPIO_PINMUX_OTHR_6328_USB_SHIFT) ++#define GPIO_PINMUX_OTHR_6328_USB_DEV (2 << GPIO_PINMUX_OTHR_6328_USB_SHIFT) ++ + #define GPIO_BASEMODE_6368_REG 0x38 + #define GPIO_BASEMODE_6368_UART2 0x1 + #define GPIO_BASEMODE_6368_GPIO 0x0 +@@ -770,6 +776,8 @@ + #define USBH_PRIV_SWAP_6358_REG 0x0 + #define USBH_PRIV_SWAP_6368_REG 0x1c + ++#define USBH_PRIV_SWAP_USBD_SHIFT 6 ++#define USBH_PRIV_SWAP_USBD_MASK (1 << USBH_PRIV_SWAP_USBD_SHIFT) + #define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT 4 + #define USBH_PRIV_SWAP_EHCI_ENDN_MASK (1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT) + #define USBH_PRIV_SWAP_EHCI_DATA_SHIFT 3 diff --git a/target/linux/brcm63xx/patches-3.3/201-SPI-Allow-specifying-the-parsers-for-SPI-flash.patch b/target/linux/brcm63xx/patches-3.3/201-SPI-Allow-specifying-the-parsers-for-SPI-flash.patch new file mode 100644 index 000000000..00dc9c90e --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/201-SPI-Allow-specifying-the-parsers-for-SPI-flash.patch @@ -0,0 +1,38 @@ +From 3f650fc30aa0badf9d02842ce396cea3eef2eeaa Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Fri, 1 Jul 2011 23:16:47 +0200 +Subject: [PATCH 49/79] SPI: Allow specifying the parsers for SPI flash + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + include/linux/spi/flash.h | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/include/linux/spi/flash.h ++++ b/include/linux/spi/flash.h +@@ -2,7 +2,7 @@ + #define LINUX_SPI_FLASH_H + + struct mtd_partition; +- ++struct mtd_part_parser_data; + /** + * struct flash_platform_data: board-specific flash data + * @name: optional flash device name (eg, as used with mtdparts=) +@@ -10,6 +10,8 @@ struct mtd_partition; + * @nr_parts: number of mtd_partitions for static partitoning + * @type: optional flash device type (e.g. m25p80 vs m25p64), for use + * with chips that can't be queried for JEDEC or other IDs ++ * @part_probe_types: optional list of MTD parser names to use for ++ * partitioning + * + * Board init code (in arch/.../mach-xxx/board-yyy.c files) can + * provide information about SPI flash parts (such as DataFlash) to +@@ -25,6 +27,7 @@ struct flash_platform_data { + + char *type; + ++ const char **part_probe_types; + /* we'll likely add more ... use JEDEC IDs, etc */ + }; + diff --git a/target/linux/brcm63xx/patches-3.3/202-MTD-DEVICES-m25p80-use-parsers-if-provided-in-flash-.patch b/target/linux/brcm63xx/patches-3.3/202-MTD-DEVICES-m25p80-use-parsers-if-provided-in-flash-.patch new file mode 100644 index 000000000..486ec3a6d --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/202-MTD-DEVICES-m25p80-use-parsers-if-provided-in-flash-.patch @@ -0,0 +1,23 @@ +From c7c3c338cb25d7f55ddb3f6bfbf3572758ca3896 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 10 Nov 2011 16:53:08 +0100 +Subject: [PATCH 50/79] MTD: DEVICES: m25p80: use parsers if provided in flash + platform data + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/mtd/devices/m25p80.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -986,7 +986,8 @@ static int __devinit m25p_probe(struct s + /* partitions should match sector boundaries; and it may be good to + * use readonly partitions for writeprotected sectors (BP2..BP0). + */ +- return mtd_device_parse_register(&flash->mtd, NULL, &ppdata, ++ return mtd_device_parse_register(&flash->mtd, ++ data ? data->part_probe_types : NULL, &ppdata, + data ? data->parts : NULL, + data ? data->nr_parts : 0); + } diff --git a/target/linux/brcm63xx/patches-3.3/203-MTD-DEVICES-m25p80-add-support-for-limiting-reads.patch b/target/linux/brcm63xx/patches-3.3/203-MTD-DEVICES-m25p80-add-support-for-limiting-reads.patch new file mode 100644 index 000000000..847b6959e --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/203-MTD-DEVICES-m25p80-add-support-for-limiting-reads.patch @@ -0,0 +1,92 @@ +From 5fb4e8d7287ac8fcb33aae8b1e9e22c5a3c392bd Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 10 Nov 2011 17:33:40 +0100 +Subject: [PATCH 51/79] MTD: DEVICES: m25p80: add support for limiting reads + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/mtd/devices/m25p80.c | 29 +++++++++++++++++++++++++++-- + include/linux/spi/flash.h | 4 ++++ + 2 files changed, 31 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -100,6 +100,7 @@ struct m25p { + u16 addr_width; + u8 erase_opcode; + u8 *command; ++ int max_transfer_len; + }; + + static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) +@@ -346,10 +347,9 @@ static int m25p80_erase(struct mtd_info + * Read an address range from the flash chip. The address range + * may be any size provided it is within the physical boundaries. + */ +-static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, ++static int __m25p80_read(struct m25p *flash, loff_t from, size_t len, + size_t *retlen, u_char *buf) + { +- struct m25p *flash = mtd_to_m25p(mtd); + struct spi_transfer t[2]; + struct spi_message m; + +@@ -408,6 +408,28 @@ static int m25p80_read(struct mtd_info * + return 0; + } + ++static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, u_char *buf) ++{ ++ struct m25p *flash = mtd_to_m25p(mtd); ++ size_t off; ++ size_t read_len = flash->max_transfer_len; ++ size_t part_len; ++ int ret = 0; ++ ++ if (!read_len) ++ return __m25p80_read(flash, from, len, retlen, buf); ++ ++ *retlen = 0; ++ ++ for (off = 0; off < len && !ret; off += read_len) { ++ ret = __m25p80_read(flash, from + off, min(len - off, read_len), ++ &part_len, buf + off); ++ *retlen += part_len; ++ } ++ ++ return ret; ++} + /* + * Write an address range to the flash chip. Data must be written in + * FLASH_PAGESIZE chunks. The address range may be any size provided +@@ -897,6 +919,9 @@ static int __devinit m25p_probe(struct s + return -ENOMEM; + } + ++ if (data) ++ flash->max_transfer_len = data->max_transfer_len; ++ + flash->spi = spi; + mutex_init(&flash->lock); + dev_set_drvdata(&spi->dev, flash); +--- a/include/linux/spi/flash.h ++++ b/include/linux/spi/flash.h +@@ -13,6 +13,8 @@ struct mtd_part_parser_data; + * @part_probe_types: optional list of MTD parser names to use for + * partitioning + * ++ * @max_transfer_len: option maximum read/write length limitation for ++ * SPI controllers not able to transfer any length commands. + * Board init code (in arch/.../mach-xxx/board-yyy.c files) can + * provide information about SPI flash parts (such as DataFlash) to + * help set up the device and its appropriate default partitioning. +@@ -28,6 +30,8 @@ struct flash_platform_data { + char *type; + + const char **part_probe_types; ++ ++ unsigned int max_transfer_len; + /* we'll likely add more ... use JEDEC IDs, etc */ + }; + diff --git a/target/linux/brcm63xx/patches-3.3/300-reset_buttons.patch b/target/linux/brcm63xx/patches-3.3/300-reset_buttons.patch new file mode 100644 index 000000000..0e1d6f8d9 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/300-reset_buttons.patch @@ -0,0 +1,116 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -12,6 +12,8 @@ + #include <linux/string.h> + #include <linux/platform_device.h> + #include <linux/ssb/ssb.h> ++#include <linux/gpio_keys.h> ++#include <linux/input.h> + #include <asm/addrspace.h> + #include <bcm63xx_board.h> + #include <bcm63xx_cpu.h> +@@ -28,6 +30,9 @@ + + #define PFX "board_bcm963xx: " + ++#define BCM963XX_KEYS_POLL_INTERVAL 20 ++#define BCM963XX_KEYS_DEBOUNCE_INTERVAL (BCM963XX_KEYS_POLL_INTERVAL * 3) ++ + static struct bcm963xx_nvram nvram; + static unsigned int mac_addr_used; + static struct board_info board; +@@ -293,6 +298,16 @@ static struct board_info __initdata boar + .active_low = 1, + }, + }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 33, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, + }; + + static struct board_info __initdata board_96348gw = { +@@ -351,6 +366,16 @@ static struct board_info __initdata boar + .active_low = 1, + }, + }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 36, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, + }; + + static struct board_info __initdata board_FAST2404 = { +@@ -821,11 +846,23 @@ static struct platform_device bcm63xx_gp + .dev.platform_data = &bcm63xx_led_data, + }; + ++static struct gpio_keys_platform_data bcm63xx_gpio_keys_data = { ++ .poll_interval = BCM963XX_KEYS_POLL_INTERVAL, ++}; ++ ++static struct platform_device bcm63xx_gpio_keys_device = { ++ .name = "gpio-keys-polled", ++ .id = 0, ++ .dev.platform_data = &bcm63xx_gpio_keys_data, ++}; ++ + /* + * third stage init callback, register all board devices. + */ + int __init board_register_devices(void) + { ++ int button_count = 0; ++ + if (board.has_uart0) + bcm63xx_uart_register(0); + +@@ -868,5 +905,16 @@ int __init board_register_devices(void) + + platform_device_register(&bcm63xx_gpio_leds); + ++ /* count number of BUTTONs defined by this device */ ++ while (button_count < ARRAY_SIZE(board.buttons) && board.buttons[button_count].desc) ++ button_count++; ++ ++ if (button_count) { ++ bcm63xx_gpio_keys_data.nbuttons = button_count; ++ bcm63xx_gpio_keys_data.buttons = board.buttons; ++ ++ platform_device_register(&bcm63xx_gpio_keys_device); ++ } ++ + return 0; + } +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -3,6 +3,7 @@ + + #include <linux/types.h> + #include <linux/gpio.h> ++#include <linux/gpio_keys.h> + #include <linux/leds.h> + #include <bcm63xx_dev_enet.h> + #include <bcm63xx_dev_dsp.h> +@@ -57,6 +58,9 @@ struct board_info { + + /* GPIO LEDs */ + struct gpio_led leds[5]; ++ ++ /* Buttons */ ++ struct gpio_keys_button buttons[4]; + }; + + #endif /* ! BOARD_BCM963XX_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/301-led_count.patch b/target/linux/brcm63xx/patches-3.3/301-led_count.patch new file mode 100644 index 000000000..b6c1196a5 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/301-led_count.patch @@ -0,0 +1,41 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -862,6 +862,7 @@ static struct platform_device bcm63xx_gp + int __init board_register_devices(void) + { + int button_count = 0; ++ int led_count = 0; + + if (board.has_uart0) + bcm63xx_uart_register(0); +@@ -900,10 +901,16 @@ int __init board_register_devices(void) + + bcm63xx_flash_register(); + +- bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds); +- bcm63xx_led_data.leds = board.leds; ++ /* count number of LEDs defined by this device */ ++ while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name) ++ led_count++; ++ ++ if (led_count) { ++ bcm63xx_led_data.num_leds = led_count; ++ bcm63xx_led_data.leds = board.leds; + +- platform_device_register(&bcm63xx_gpio_leds); ++ platform_device_register(&bcm63xx_gpio_leds); ++ } + + /* count number of BUTTONs defined by this device */ + while (button_count < ARRAY_SIZE(board.buttons) && board.buttons[button_count].desc) +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -57,7 +57,7 @@ struct board_info { + struct bcm63xx_dsp_platform_data dsp; + + /* GPIO LEDs */ +- struct gpio_led leds[5]; ++ struct gpio_led leds[14]; + + /* Buttons */ + struct gpio_keys_button buttons[4]; diff --git a/target/linux/brcm63xx/patches-3.3/302-extended-platform-devices.patch b/target/linux/brcm63xx/patches-3.3/302-extended-platform-devices.patch new file mode 100644 index 000000000..b48ef733b --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/302-extended-platform-devices.patch @@ -0,0 +1,25 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -899,6 +899,9 @@ int __init board_register_devices(void) + + bcm63xx_spi_register(); + ++ if (board.num_devs) ++ platform_add_devices(board.devs, board.num_devs); ++ + bcm63xx_flash_register(); + + /* count number of LEDs defined by this device */ +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -61,6 +61,10 @@ struct board_info { + + /* Buttons */ + struct gpio_keys_button buttons[4]; ++ ++ /* Additional platform devices */ ++ struct platform_device **devs; ++ unsigned int num_devs; + }; + + #endif /* ! BOARD_BCM963XX_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/303-spi-board-info.patch b/target/linux/brcm63xx/patches-3.3/303-spi-board-info.patch new file mode 100644 index 000000000..517a53b56 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/303-spi-board-info.patch @@ -0,0 +1,33 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -14,6 +14,7 @@ + #include <linux/ssb/ssb.h> + #include <linux/gpio_keys.h> + #include <linux/input.h> ++#include <linux/spi/spi.h> + #include <asm/addrspace.h> + #include <bcm63xx_board.h> + #include <bcm63xx_cpu.h> +@@ -902,6 +903,9 @@ int __init board_register_devices(void) + if (board.num_devs) + platform_add_devices(board.devs, board.num_devs); + ++ if (board.num_spis) ++ spi_register_board_info(board.spis, board.num_spis); ++ + bcm63xx_flash_register(); + + /* count number of LEDs defined by this device */ +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -65,6 +65,10 @@ struct board_info { + /* Additional platform devices */ + struct platform_device **devs; + unsigned int num_devs; ++ ++ /* Additional platform devices */ ++ struct spi_board_info *spis; ++ unsigned int num_spis; + }; + + #endif /* ! BOARD_BCM963XX_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/304-boardid_fixup.patch b/target/linux/brcm63xx/patches-3.3/304-boardid_fixup.patch new file mode 100644 index 000000000..0c2fab575 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/304-boardid_fixup.patch @@ -0,0 +1,61 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -28,12 +28,16 @@ + #include <bcm63xx_dev_pcmcia.h> + #include <bcm63xx_dev_spi.h> + #include <board_bcm963xx.h> ++#include <bcm_tag.h> + + #define PFX "board_bcm963xx: " + + #define BCM963XX_KEYS_POLL_INTERVAL 20 + #define BCM963XX_KEYS_DEBOUNCE_INTERVAL (BCM963XX_KEYS_POLL_INTERVAL * 3) + ++#define CFE_OFFSET_64K 0x10000 ++#define CFE_OFFSET_128K 0x20000 ++ + static struct bcm963xx_nvram nvram; + static unsigned int mac_addr_used; + static struct board_info board; +@@ -724,6 +728,29 @@ static int board_get_mac_address(u8 *mac + return 0; + } + ++static void __init boardid_fixup(u8 *boot_addr) ++{ ++ struct bcm_tag *tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_64K); ++ ++ /* check if bcm_tag is at 64k offset */ ++ if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) { ++ /* else try 128k */ ++ tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_128K); ++ if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) { ++ /* No tag found */ ++ printk(KERN_DEBUG "No bcm_tag found!\n"); ++ return; ++ } ++ } ++ /* check if we should override the boardid */ ++ if (tag->information1[0] != '+') ++ return; ++ ++ strncpy(nvram.name, &tag->information1[1], BOARDID_LEN); ++ ++ printk(KERN_INFO "Overriding boardid with '%s'\n", nvram.name); ++} ++ + /* + * early init callback, read nvram data from flash and checksum it + */ +@@ -771,6 +798,11 @@ void __init board_prom_init(void) + return; + } + ++ if (strcmp(cfe_version, "unknown") != 0) { ++ /* cfe present */ ++ boardid_fixup(boot_addr); ++ } ++ + /* find board by name */ + for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { + if (strncmp(nvram.name, bcm963xx_boards[i]->name, diff --git a/target/linux/brcm63xx/patches-3.3/305-missing_ext_irq_bits.patch b/target/linux/brcm63xx/patches-3.3/305-missing_ext_irq_bits.patch new file mode 100644 index 000000000..703f4b54b --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/305-missing_ext_irq_bits.patch @@ -0,0 +1,96 @@ +--- a/arch/mips/bcm63xx/irq.c ++++ b/arch/mips/bcm63xx/irq.c +@@ -56,8 +56,8 @@ static void __internal_irq_unmask_64(uns + #define is_ext_irq_cascaded 0 + #define ext_irq_start 0 + #define ext_irq_end 0 +-#define ext_irq_count 0 +-#define ext_irq_cfg_reg1 0 ++#define ext_irq_count 4 ++#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6345 + #define ext_irq_cfg_reg2 0 + #endif + #ifdef CONFIG_BCM63XX_CPU_6348 +@@ -143,11 +143,15 @@ static void bcm63xx_init_irq(void) + irq_stat_addr += PERF_IRQSTAT_6338_REG; + irq_mask_addr += PERF_IRQMASK_6338_REG; + irq_bits = 32; ++ ext_irq_count = 4; ++ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338; + break; + case BCM6345_CPU_ID: + irq_stat_addr += PERF_IRQSTAT_6345_REG; + irq_mask_addr += PERF_IRQMASK_6345_REG; + irq_bits = 32; ++ ext_irq_count = 4; ++ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345; + break; + case BCM6348_CPU_ID: + irq_stat_addr += PERF_IRQSTAT_6348_REG; +@@ -434,7 +438,8 @@ static int bcm63xx_external_irq_set_type + reg = bcm_perf_readl(regaddr); + irq %= 4; + +- if (BCMCPU_IS_6348()) { ++ switch (bcm63xx_get_cpu_id()) { ++ case BCM6348_CPU_ID: + if (levelsense) + reg |= EXTIRQ_CFG_LEVELSENSE_6348(irq); + else +@@ -447,9 +452,12 @@ static int bcm63xx_external_irq_set_type + reg |= EXTIRQ_CFG_BOTHEDGE_6348(irq); + else + reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq); +- } ++ break; + +- if (BCMCPU_IS_6338() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) { ++ case BCM6338_CPU_ID: ++ case BCM6345_CPU_ID: ++ case BCM6358_CPU_ID: ++ case BCM6368_CPU_ID: + if (levelsense) + reg |= EXTIRQ_CFG_LEVELSENSE(irq); + else +@@ -462,6 +470,9 @@ static int bcm63xx_external_irq_set_type + reg |= EXTIRQ_CFG_BOTHEDGE(irq); + else + reg &= ~EXTIRQ_CFG_BOTHEDGE(irq); ++ break; ++ default: ++ BUG(); + } + + bcm_perf_writel(reg, regaddr); +--- a/arch/mips/bcm63xx/setup.c ++++ b/arch/mips/bcm63xx/setup.c +@@ -74,6 +74,9 @@ void bcm63xx_machine_reboot(void) + case BCM6338_CPU_ID: + perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338; + break; ++ case BCM6345_CPU_ID: ++ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6345; ++ break; + case BCM6348_CPU_ID: + perf_regs[0] = PERF_EXTIRQ_CFG_REG_6348; + break; +@@ -83,6 +86,9 @@ void bcm63xx_machine_reboot(void) + } + + for (i = 0; i < 2; i++) { ++ if (!perf_regs[i]) ++ break; ++ + reg = bcm_perf_readl(perf_regs[i]); + if (BCMCPU_IS_6348()) { + reg &= ~EXTIRQ_CFG_MASK_ALL_6348; +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -161,6 +161,7 @@ + /* External Interrupt Configuration register */ + #define PERF_EXTIRQ_CFG_REG_6328 0x18 + #define PERF_EXTIRQ_CFG_REG_6338 0x14 ++#define PERF_EXTIRQ_CFG_REG_6345 0x14 + #define PERF_EXTIRQ_CFG_REG_6348 0x14 + #define PERF_EXTIRQ_CFG_REG_6358 0x14 + #define PERF_EXTIRQ_CFG_REG_6368 0x18 diff --git a/target/linux/brcm63xx/patches-3.3/306-Revert-MIPS-BCM63XX-Call-board_register_device-from-.patch b/target/linux/brcm63xx/patches-3.3/306-Revert-MIPS-BCM63XX-Call-board_register_device-from-.patch new file mode 100644 index 000000000..aa7ef8bbd --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/306-Revert-MIPS-BCM63XX-Call-board_register_device-from-.patch @@ -0,0 +1,23 @@ +From a7d2622b6614fdca504c074a0cd307d5a1165c30 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 8 May 2012 09:39:01 +0200 +Subject: [PATCH 04/59] Revert "MIPS: BCM63XX: Call board_register_device from device_initcall()" + +This commit causes a race between PCI scan and SSB fallback SPROM handler +registration, causing the wifi to not work on slower systems. The only +subsystem touched from board_register_device is platform device +registration, which should be safe as an arch init call. + +This reverts commit d64ed7ada2f689d2c62af1892ca55e47d3653e36. +--- + arch/mips/bcm63xx/setup.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/arch/mips/bcm63xx/setup.c ++++ b/arch/mips/bcm63xx/setup.c +@@ -157,4 +157,4 @@ int __init bcm63xx_register_devices(void + return board_register_devices(); + } + +-device_initcall(bcm63xx_register_devices); ++arch_initcall(bcm63xx_register_devices); diff --git a/target/linux/brcm63xx/patches-3.3/307-MIPS-BCM63XX-allow-second-UART-on-BCM6328.patch b/target/linux/brcm63xx/patches-3.3/307-MIPS-BCM63XX-allow-second-UART-on-BCM6328.patch new file mode 100644 index 000000000..1418d65bf --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/307-MIPS-BCM63XX-allow-second-UART-on-BCM6328.patch @@ -0,0 +1,22 @@ +From c110865541e2d3782c412af9d48c016de5a64d9c Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 14 Jun 2011 21:14:39 +0200 +Subject: [PATCH 42/79] MIPS: BCM63XX: allow second UART on BCM6328 + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/dev-uart.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/arch/mips/bcm63xx/dev-uart.c ++++ b/arch/mips/bcm63xx/dev-uart.c +@@ -54,7 +54,8 @@ int __init bcm63xx_uart_register(unsigne + if (id >= ARRAY_SIZE(bcm63xx_uart_devices)) + return -ENODEV; + +- if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368())) ++ if (id == 1 && !BCMCPU_IS_6328() && !BCMCPU_IS_6358() && ++ !BCMCPU_IS_6368()) + return -ENODEV; + + if (id == 0) { diff --git a/target/linux/brcm63xx/patches-3.3/308-MIPS-BCM63XX-expose-the-HS-SPI-clock.patch b/target/linux/brcm63xx/patches-3.3/308-MIPS-BCM63XX-expose-the-HS-SPI-clock.patch new file mode 100644 index 000000000..8a11f8266 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/308-MIPS-BCM63XX-expose-the-HS-SPI-clock.patch @@ -0,0 +1,48 @@ +From 5aeb6273a610f8aab090b3499827177eb41311ba Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sat, 12 Nov 2011 12:19:09 +0100 +Subject: [PATCH 53/79] MIPS: BCM63XX: expose the HS SPI clock + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/clk.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -194,6 +194,26 @@ static struct clk clk_spi = { + }; + + /* ++ * SPI clock ++ */ ++static void hsspi_set(struct clk *clk, int enable) ++{ ++ u32 mask; ++ ++ if (BCMCPU_IS_6328()) ++ mask = CKCTL_6328_HSSPI_EN; ++ else ++ return; ++ ++ bcm_hwclock_set(mask, enable); ++} ++ ++static struct clk clk_hsspi = { ++ .set = hsspi_set, ++}; ++ ++ ++/* + * XTM clock + */ + static void xtm_set(struct clk *clk, int enable) +@@ -286,6 +306,8 @@ struct clk *clk_get(struct device *dev, + return &clk_usbh; + if (!strcmp(id, "spi")) + return &clk_spi; ++ if (!strcmp(id, "hsspi")) ++ return &clk_hsspi; + if (!strcmp(id, "xtm")) + return &clk_xtm; + if (!strcmp(id, "periph")) diff --git a/target/linux/brcm63xx/patches-3.3/309-MIPS-BCM63XX-add-HSSPI-register-definitions.patch b/target/linux/brcm63xx/patches-3.3/309-MIPS-BCM63XX-add-HSSPI-register-definitions.patch new file mode 100644 index 000000000..5e2cd96d3 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/309-MIPS-BCM63XX-add-HSSPI-register-definitions.patch @@ -0,0 +1,211 @@ +From 70f970222bc1096689ae1bffeb9ed09a7c4bed07 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sat, 12 Nov 2011 12:19:55 +0100 +Subject: [PATCH 28/60] MIPS: BCM63XX: add HSSPI register definitions + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 18 ++++++++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 47 +++++++++++++++++++++ + 2 files changed, 65 insertions(+), 0 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -116,6 +116,7 @@ enum bcm63xx_regs_set { + RSET_UART1, + RSET_GPIO, + RSET_SPI, ++ RSET_HSSPI, + RSET_UDC0, + RSET_OHCI0, + RSET_OHCI_PRIV, +@@ -159,6 +160,7 @@ enum bcm63xx_regs_set { + #define RSET_ENETDMA_SIZE 2048 + #define RSET_ENETSW_SIZE 65536 + #define RSET_UART_SIZE 24 ++#define RSET_HSSPI_SIZE 1536 + #define RSET_UDC_SIZE 256 + #define RSET_OHCI_SIZE 256 + #define RSET_EHCI_SIZE 256 +@@ -182,6 +184,7 @@ enum bcm63xx_regs_set { + #define BCM_6328_UART1_BASE (0xb0000120) + #define BCM_6328_GPIO_BASE (0xb0000080) + #define BCM_6328_SPI_BASE (0xdeadbeef) ++#define BCM_6328_HSSPI_BASE (0xb0001000) + #define BCM_6328_UDC0_BASE (0xdeadbeef) + #define BCM_6328_USBDMA_BASE (0xdeadbeef) + #define BCM_6328_OHCI0_BASE (0xb0002600) +@@ -227,6 +230,7 @@ enum bcm63xx_regs_set { + #define BCM_6338_UART1_BASE (0xdeadbeef) + #define BCM_6338_GPIO_BASE (0xfffe0400) + #define BCM_6338_SPI_BASE (0xfffe0c00) ++#define BCM_6338_HSSPI_BASE (0xdeadbeef) + #define BCM_6338_UDC0_BASE (0xdeadbeef) + #define BCM_6338_USBDMA_BASE (0xfffe2400) + #define BCM_6338_OHCI0_BASE (0xdeadbeef) +@@ -273,6 +277,7 @@ enum bcm63xx_regs_set { + #define BCM_6345_UART1_BASE (0xdeadbeef) + #define BCM_6345_GPIO_BASE (0xfffe0400) + #define BCM_6345_SPI_BASE (0xdeadbeef) ++#define BCM_6345_HSSPI_BASE (0xdeadbeef) + #define BCM_6345_UDC0_BASE (0xdeadbeef) + #define BCM_6345_USBDMA_BASE (0xfffe2800) + #define BCM_6345_ENET0_BASE (0xfffe1800) +@@ -318,6 +323,7 @@ enum bcm63xx_regs_set { + #define BCM_6348_UART1_BASE (0xdeadbeef) + #define BCM_6348_GPIO_BASE (0xfffe0400) + #define BCM_6348_SPI_BASE (0xfffe0c00) ++#define BCM_6348_HSSPI_BASE (0xdeadbeef) + #define BCM_6348_UDC0_BASE (0xfffe1000) + #define BCM_6348_OHCI0_BASE (0xfffe1b00) + #define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00) +@@ -361,6 +367,7 @@ enum bcm63xx_regs_set { + #define BCM_6358_UART1_BASE (0xfffe0120) + #define BCM_6358_GPIO_BASE (0xfffe0080) + #define BCM_6358_SPI_BASE (0xfffe0800) ++#define BCM_6358_HSSPI_BASE (0xdeadbeef) + #define BCM_6358_UDC0_BASE (0xfffe0800) + #define BCM_6358_OHCI0_BASE (0xfffe1400) + #define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef) +@@ -405,6 +412,7 @@ enum bcm63xx_regs_set { + #define BCM_6368_UART1_BASE (0xb0000120) + #define BCM_6368_GPIO_BASE (0xb0000080) + #define BCM_6368_SPI_BASE (0xb0000800) ++#define BCM_6368_HSSPI_BASE (0xdeadbeef) + #define BCM_6368_UDC0_BASE (0xdeadbeef) + #define BCM_6368_OHCI0_BASE (0xb0001600) + #define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef) +@@ -454,6 +462,7 @@ extern const unsigned long *bcm63xx_regs + __GEN_RSET_BASE(__cpu, UART1) \ + __GEN_RSET_BASE(__cpu, GPIO) \ + __GEN_RSET_BASE(__cpu, SPI) \ ++ __GEN_RSET_BASE(__cpu, HSSPI) \ + __GEN_RSET_BASE(__cpu, UDC0) \ + __GEN_RSET_BASE(__cpu, OHCI0) \ + __GEN_RSET_BASE(__cpu, OHCI_PRIV) \ +@@ -495,6 +504,7 @@ extern const unsigned long *bcm63xx_regs + [RSET_UART1] = BCM_## __cpu ##_UART1_BASE, \ + [RSET_GPIO] = BCM_## __cpu ##_GPIO_BASE, \ + [RSET_SPI] = BCM_## __cpu ##_SPI_BASE, \ ++ [RSET_HSSPI] = BCM_## __cpu ##_HSSPI_BASE, \ + [RSET_UDC0] = BCM_## __cpu ##_UDC0_BASE, \ + [RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \ + [RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \ +@@ -567,6 +577,7 @@ enum bcm63xx_irq { + IRQ_ENET0, + IRQ_ENET1, + IRQ_ENET_PHY, ++ IRQ_HSSPI, + IRQ_OHCI0, + IRQ_EHCI0, + IRQ_ENET0_RXDMA, +@@ -602,6 +613,7 @@ enum bcm63xx_irq { + #define BCM_6328_ENET0_IRQ 0 + #define BCM_6328_ENET1_IRQ 0 + #define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12) ++#define BCM_6328_HSSPI_IRQ (IRQ_INTERNAL_BASE + 29) + #define BCM_6328_OHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 9) + #define BCM_6328_EHCI0_IRQ (BCM_6328_HIGH_IRQ_BASE + 10) + #define BCM_6328_PCMCIA_IRQ 0 +@@ -640,6 +652,7 @@ enum bcm63xx_irq { + #define BCM_6338_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) + #define BCM_6338_ENET1_IRQ 0 + #define BCM_6338_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) ++#define BCM_6338_HSSPI_IRQ 0 + #define BCM_6338_OHCI0_IRQ 0 + #define BCM_6338_EHCI0_IRQ 0 + #define BCM_6338_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15) +@@ -671,6 +684,7 @@ enum bcm63xx_irq { + #define BCM_6345_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) + #define BCM_6345_ENET1_IRQ 0 + #define BCM_6345_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12) ++#define BCM_6345_HSSPI_IRQ 0 + #define BCM_6345_OHCI0_IRQ 0 + #define BCM_6345_EHCI0_IRQ 0 + #define BCM_6345_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 1) +@@ -702,6 +716,7 @@ enum bcm63xx_irq { + #define BCM_6348_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) + #define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7) + #define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) ++#define BCM_6348_HSSPI_IRQ 0 + #define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12) + #define BCM_6348_EHCI0_IRQ 0 + #define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20) +@@ -733,6 +748,7 @@ enum bcm63xx_irq { + #define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) + #define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6) + #define BCM_6358_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) ++#define BCM_6358_HSSPI_IRQ 0 + #define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5) + #define BCM_6358_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10) + #define BCM_6358_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15) +@@ -773,6 +789,7 @@ enum bcm63xx_irq { + #define BCM_6368_ENET0_IRQ 0 + #define BCM_6368_ENET1_IRQ 0 + #define BCM_6368_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 15) ++#define BCM_6368_HSSPI_IRQ 0 + #define BCM_6368_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5) + #define BCM_6368_EHCI0_IRQ (IRQ_INTERNAL_BASE + 7) + #define BCM_6368_PCMCIA_IRQ 0 +@@ -813,6 +830,7 @@ extern const int *bcm63xx_irqs; + [IRQ_ENET0] = BCM_## __cpu ##_ENET0_IRQ, \ + [IRQ_ENET1] = BCM_## __cpu ##_ENET1_IRQ, \ + [IRQ_ENET_PHY] = BCM_## __cpu ##_ENET_PHY_IRQ, \ ++ [IRQ_HSSPI] = BCM_## __cpu ##_HSSPI_IRQ, \ + [IRQ_OHCI0] = BCM_## __cpu ##_OHCI0_IRQ, \ + [IRQ_EHCI0] = BCM_## __cpu ##_EHCI0_IRQ, \ + [IRQ_ENET0_RXDMA] = BCM_## __cpu ##_ENET0_RXDMA_IRQ, \ +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -1239,4 +1239,51 @@ + + #define PCIE_DEVICE_OFFSET 0x8000 + ++/************************************************************************* ++ * _REG relative to RSET_HSSPI ++ *************************************************************************/ ++ ++#define HSSPI_GLOBAL_CTRL_REG 0x0 ++#define GLOBAL_CTRL_CLK_POLARITY (1 << 17) ++#define GLOBAL_CTRL_CLK_GATE_SSOFF (1 << 16) ++ ++#define HSSPI_GLOBAL_EXT_TRIGGER_REG 0x4 ++ ++#define HSSPI_INT_STATUS_REG 0x8 ++#define HSSPI_INT_STATUS_MASKED_REG 0xc ++#define HSSPI_INT_MASK_REG 0x10 ++ ++#define HSSPI_PING0_CMD_DONE (1 << 0) ++ ++#define HSSPI_INT_CLEAR_ALL 0xff001f1f ++ ++#define HSSPI_PINGPONG_COMMAND_REG(x) (0x80 + (x) * 0x40) ++#define PINGPONG_CMD_COMMAND_MASK 0xf ++#define PINGPONG_COMMAND_NOOP 0 ++#define PINGPONG_COMMAND_START_NOW 1 ++#define PINGPONG_COMMAND_START_TRIGGER 2 ++#define PINGPONG_COMMAND_HALT 3 ++#define PINGPONG_COMMAND_FLUSH 4 ++#define PINGPONG_CMD_PROFILE_SHIFT 8 ++#define PINGPONG_CMD_SS_SHIFT 12 ++ ++#define HSSPI_PINGPONG_STATUS_REG(x) (0x84 + (x) * 0x40) ++ ++#define HSSPI_PROFILE_CLK_CTRL_REG(x) (0x100 + (x) * 0x20) ++#define CLK_CTRL_ACCUM_RST_ON_LOOP (1 << 15) ++ ++#define HSSPI_PROFILE_SIGNAL_CTRL_REG(x) (0x104 + (x) * 0x20) ++#define SIGNAL_CTRL_LATCH_RISING (1 << 12) ++#define SIGNAL_CTRL_LAUNCH_RISING (1 << 13) ++#define SIGNAL_CTRL_ASYNC_INPUT_PATH (1 << 16) ++ ++#define HSSPI_PROFILE_MODE_CTRL_REG(x) (0x108 + (x) * 0x20) ++#define MODE_CTRL_MULTIDATA_RD_STRT_SHIFT 8 ++#define MODE_CTRL_MULTIDATA_WR_STRT_SHIFT 12 ++#define MODE_CTRL_MULTIDATA_RD_SIZE_SHIFT 16 ++#define MODE_CTRL_MULTIDATA_WR_SIZE_SHIFT 18 ++#define MODE_CTRL_PREPENDBYTE_CNT_SHIFT 24 ++ ++#define HSSPI_FIFO_REG(x) (0x200 + (x) * 0x200) ++ + #endif /* BCM63XX_REGS_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/310-board_leds_naming.patch b/target/linux/brcm63xx/patches-3.3/310-board_leds_naming.patch new file mode 100644 index 000000000..798e8018f --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/310-board_leds_naming.patch @@ -0,0 +1,267 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -61,28 +61,28 @@ static struct board_info __initdata boar + + .leds = { + { +- .name = "adsl", ++ .name = "96338GW:green:adsl", + .gpio = 3, + .active_low = 1, + }, + { +- .name = "ses", ++ .name = "96338GW:green:ses", + .gpio = 5, + .active_low = 1, + }, + { +- .name = "ppp-fail", ++ .name = "96338GW:green:ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { +- .name = "power", ++ .name = "96338GW!green:power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { +- .name = "stop", ++ .name = "96338GW:green:stop", + .gpio = 1, + .active_low = 1, + } +@@ -102,28 +102,28 @@ static struct board_info __initdata boar + + .leds = { + { +- .name = "adsl", ++ .name = "96338W:green:adsl", + .gpio = 3, + .active_low = 1, + }, + { +- .name = "ses", ++ .name = "96338W:green:ses", + .gpio = 5, + .active_low = 1, + }, + { +- .name = "ppp-fail", ++ .name = "96338W:green:ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { +- .name = "power", ++ .name = "96338W:green:power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { +- .name = "stop", ++ .name = "96338W:green:stop", + .gpio = 1, + .active_low = 1, + }, +@@ -162,29 +162,29 @@ static struct board_info __initdata boar + + .leds = { + { +- .name = "adsl-fail", ++ .name = "96348R:green:adsl-fail", + .gpio = 2, + .active_low = 1, + }, + { +- .name = "ppp", ++ .name = "96348R:green:ppp", + .gpio = 3, + .active_low = 1, + }, + { +- .name = "ppp-fail", ++ .name = "96348R:green:ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { +- .name = "power", ++ .name = "96348R:green:power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + + }, + { +- .name = "stop", ++ .name = "96348R:green:stop", + .gpio = 1, + .active_low = 1, + }, +@@ -223,28 +223,28 @@ static struct board_info __initdata boar + + .leds = { + { +- .name = "adsl-fail", ++ .name = "96348GW-10:green:adsl-fail", + .gpio = 2, + .active_low = 1, + }, + { +- .name = "ppp", ++ .name = "96348GW-10:green:ppp", + .gpio = 3, + .active_low = 1, + }, + { +- .name = "ppp-fail", ++ .name = "96348GW-10:green:ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { +- .name = "power", ++ .name = "96348GW-10:green:power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { +- .name = "stop", ++ .name = "96348GW-10:green:stop", + .gpio = 1, + .active_low = 1, + }, +@@ -277,28 +277,28 @@ static struct board_info __initdata boar + + .leds = { + { +- .name = "adsl-fail", ++ .name = "96348GW-11:green:adsl-fail", + .gpio = 2, + .active_low = 1, + }, + { +- .name = "ppp", ++ .name = "96348GW-11:green:ppp", + .gpio = 3, + .active_low = 1, + }, + { +- .name = "ppp-fail", ++ .name = "96348GW-11:green:ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { +- .name = "power", ++ .name = "96348GW-11:green:power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { +- .name = "stop", ++ .name = "96348GW-11:green:stop", + .gpio = 1, + .active_low = 1, + }, +@@ -345,28 +345,28 @@ static struct board_info __initdata boar + + .leds = { + { +- .name = "adsl-fail", ++ .name = "96348GW:green:adsl-fail", + .gpio = 2, + .active_low = 1, + }, + { +- .name = "ppp", ++ .name = "96348GW:green:ppp", + .gpio = 3, + .active_low = 1, + }, + { +- .name = "ppp-fail", ++ .name = "96348GW:green:ppp-fail", + .gpio = 4, + .active_low = 1, + }, + { +- .name = "power", ++ .name = "96348GW:green:power", + .gpio = 0, + .active_low = 1, + .default_trigger = "default-on", + }, + { +- .name = "stop", ++ .name = "96348GW:green:stop", + .gpio = 1, + .active_low = 1, + }, +@@ -498,27 +498,27 @@ static struct board_info __initdata boar + + .leds = { + { +- .name = "adsl-fail", ++ .name = "96358VW:green:adsl-fail", + .gpio = 15, + .active_low = 1, + }, + { +- .name = "ppp", ++ .name = "96358VW:green:ppp", + .gpio = 22, + .active_low = 1, + }, + { +- .name = "ppp-fail", ++ .name = "96358VW:green:ppp-fail", + .gpio = 23, + .active_low = 1, + }, + { +- .name = "power", ++ .name = "96358VW:green:power", + .gpio = 4, + .default_trigger = "default-on", + }, + { +- .name = "stop", ++ .name = "96358VW:green:stop", + .gpio = 5, + }, + }, +@@ -550,22 +550,22 @@ static struct board_info __initdata boar + + .leds = { + { +- .name = "adsl", ++ .name = "96358VW2:green:adsl", + .gpio = 22, + .active_low = 1, + }, + { +- .name = "ppp-fail", ++ .name = "96358VW2:green:ppp-fail", + .gpio = 23, + }, + { +- .name = "power", ++ .name = "96358VW2:green:power", + .gpio = 5, + .active_low = 1, + .default_trigger = "default-on", + }, + { +- .name = "stop", ++ .name = "96358VW2:green:stop", + .gpio = 4, + .active_low = 1, + }, diff --git a/target/linux/brcm63xx/patches-3.3/311-cfe_version_mod.patch b/target/linux/brcm63xx/patches-3.3/311-cfe_version_mod.patch new file mode 100644 index 000000000..1269bc0c4 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/311-cfe_version_mod.patch @@ -0,0 +1,26 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -777,6 +777,8 @@ void __init board_prom_init(void) + if (!memcmp(cfe, "cfe-v", 5)) + snprintf(cfe_version, sizeof(cfe_version), "%u.%u.%u-%u.%u", + cfe[5], cfe[6], cfe[7], cfe[8], cfe[9]); ++ else if (!memcmp(cfe, "cfe-", 4)) ++ snprintf(cfe_version, 16, "%s", (char *) &cfe[4]); + else + strcpy(cfe_version, "unknown"); + printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -54,10 +54,10 @@ static int bcm63xx_detect_cfe(struct mtd + if (ret) + return ret; + +- if (strncmp("cfe-v", buf, 5) == 0) ++ if (strncmp("cfe-", buf, 4) == 0) + return 0; + +- /* very old CFE's do not have the cfe-v string, so check for magic */ ++ /* very old CFE's do not have the cfe- string, so check for magic */ + ret = mtd_read(master, BCM63XX_CFE_MAGIC_OFFSET, 8, &retlen, + (void *)buf); + buf[retlen] = 0; diff --git a/target/linux/brcm63xx/patches-3.3/312-MIPS-BCM63XX-add-basic-BCM6362-support.patch b/target/linux/brcm63xx/patches-3.3/312-MIPS-BCM63XX-add-basic-BCM6362-support.patch new file mode 100644 index 000000000..5b6ecbed4 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/312-MIPS-BCM63XX-add-basic-BCM6362-support.patch @@ -0,0 +1,497 @@ +From 27ebbb819b1f92d52309276b29b7a56e362e5c4d Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Mon, 21 Nov 2011 00:48:52 +0100 +Subject: [PATCH 54/84] MIPS: BCM63XX: add basic BCM6362 support + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/Kconfig | 4 + + arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 +- + arch/mips/bcm63xx/cpu.c | 52 ++++++++- + arch/mips/bcm63xx/irq.c | 19 +++ + arch/mips/bcm63xx/prom.c | 2 + + arch/mips/bcm63xx/setup.c | 3 + + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 139 +++++++++++++++++++++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h | 2 + + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 59 +++++++++ + arch/mips/include/asm/mach-bcm63xx/ioremap.h | 1 + + 10 files changed, 281 insertions(+), 2 deletions(-) + +--- a/arch/mips/bcm63xx/Kconfig ++++ b/arch/mips/bcm63xx/Kconfig +@@ -25,6 +25,10 @@ config BCM63XX_CPU_6358 + bool "support 6358 CPU" + select HW_HAS_PCI + ++config BCM63XX_CPU_6362 ++ bool "support 6362 CPU" ++ select HW_HAS_PCI ++ + config BCM63XX_CPU_6368 + bool "support 6368 CPU" + select HW_HAS_PCI +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -764,7 +764,7 @@ void __init board_prom_init(void) + /* read base address of boot chip select (0) + * 6328 does not have MPI but boots from a fixed address + */ +- if (BCMCPU_IS_6328()) ++ if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) + val = 0x18000000; + else { + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); +--- a/arch/mips/bcm63xx/cpu.c ++++ b/arch/mips/bcm63xx/cpu.c +@@ -71,6 +71,15 @@ static const int bcm6358_irqs[] = { + + }; + ++static const unsigned long bcm6362_regs_base[] = { ++ __GEN_CPU_REGS_TABLE(6362) ++}; ++ ++static const int bcm6362_irqs[] = { ++ __GEN_CPU_IRQ_TABLE(6362) ++ ++}; ++ + static const unsigned long bcm6368_regs_base[] = { + __GEN_CPU_REGS_TABLE(6368) + }; +@@ -169,6 +178,42 @@ static unsigned int detect_cpu_clock(voi + return (16 * 1000000 * n1 * n2) / m1; + } + ++ case BCM6362_CPU_ID: ++ { ++ unsigned int tmp, mips_pll_fcvo; ++ ++ tmp = bcm_misc_readl(MISC_STRAPBUS_6362_REG); ++ mips_pll_fcvo = (tmp & STRAPBUS_6362_FCVO_MASK) ++ >> STRAPBUS_6362_FCVO_SHIFT; ++ switch (mips_pll_fcvo) { ++ case 0x03: ++ case 0x0b: ++ case 0x13: ++ case 0x1b: ++ return 240000000; ++ case 0x04: ++ case 0x0c: ++ case 0x14: ++ case 0x1c: ++ return 160000000; ++ case 0x05: ++ case 0x0e: ++ case 0x16: ++ case 0x1e: ++ case 0x1f: ++ return 400000000; ++ case 0x06: ++ return 440000000; ++ case 0x07: ++ case 0x17: ++ return 384000000; ++ case 0x15: ++ case 0x1d: ++ return 200000000; ++ default: ++ return 320000000; ++ } ++ } + case BCM6368_CPU_ID: + { + unsigned int tmp, p1, p2, ndiv, m1; +@@ -205,7 +250,7 @@ static unsigned int detect_memory_size(v + unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0; + u32 val; + +- if (BCMCPU_IS_6328()) ++ if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) + return bcm_ddr_readl(DDR_CSEND_REG) << 24; + + if (BCMCPU_IS_6345()) { +@@ -280,6 +325,11 @@ void __init bcm63xx_cpu_init(void) + bcm63xx_regs_base = bcm6328_regs_base; + bcm63xx_irqs = bcm6328_irqs; + break; ++ case BCM6362_CPU_ID: ++ expected_cpu_id = BCM6362_CPU_ID; ++ bcm63xx_regs_base = bcm6362_regs_base; ++ bcm63xx_irqs = bcm6362_irqs; ++ break; + case BCM6368_CPU_ID: + expected_cpu_id = BCM6368_CPU_ID; + bcm63xx_regs_base = bcm6368_regs_base; +--- a/arch/mips/bcm63xx/irq.c ++++ b/arch/mips/bcm63xx/irq.c +@@ -82,6 +82,14 @@ static void __internal_irq_unmask_64(uns + #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358 + #define ext_irq_cfg_reg2 0 + #endif ++#ifdef CONFIG_BCM63XX_CPU_6362 ++#define irq_stat_reg PERF_IRQSTAT_6362_REG ++#define irq_mask_reg PERF_IRQMASK_6362_REG ++#define irq_bits 64 ++#define is_ext_irq_cascaded 1 ++#define ext_irq_start (BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE) ++#define ext_irq_end (BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE) ++#endif + #ifdef CONFIG_BCM63XX_CPU_6368 + #define irq_stat_reg PERF_IRQSTAT_6368_REG + #define irq_mask_reg PERF_IRQMASK_6368_REG +@@ -170,6 +178,16 @@ static void bcm63xx_init_irq(void) + ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; + ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358; + break; ++ case BCM6362_CPU_ID: ++ irq_stat_addr += PERF_IRQSTAT_6362_REG; ++ irq_mask_addr += PERF_IRQMASK_6362_REG; ++ irq_bits = 64; ++ ext_irq_count = 4; ++ is_ext_irq_cascaded = 1; ++ ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE; ++ ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE; ++ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362; ++ break; + case BCM6368_CPU_ID: + irq_stat_addr += PERF_IRQSTAT_6368_REG; + irq_mask_addr += PERF_IRQMASK_6368_REG; +@@ -457,6 +475,7 @@ static int bcm63xx_external_irq_set_type + case BCM6338_CPU_ID: + case BCM6345_CPU_ID: + case BCM6358_CPU_ID: ++ case BCM6362_CPU_ID: + case BCM6368_CPU_ID: + if (levelsense) + reg |= EXTIRQ_CFG_LEVELSENSE(irq); +--- a/arch/mips/bcm63xx/prom.c ++++ b/arch/mips/bcm63xx/prom.c +@@ -36,6 +36,8 @@ void __init prom_init(void) + mask = CKCTL_6348_ALL_SAFE_EN; + else if (BCMCPU_IS_6358()) + mask = CKCTL_6358_ALL_SAFE_EN; ++ else if (BCMCPU_IS_6362()) ++ mask = CKCTL_6362_ALL_SAFE_EN; + else if (BCMCPU_IS_6368()) + mask = CKCTL_6368_ALL_SAFE_EN; + else +--- a/arch/mips/bcm63xx/setup.c ++++ b/arch/mips/bcm63xx/setup.c +@@ -83,6 +83,9 @@ void bcm63xx_machine_reboot(void) + case BCM6358_CPU_ID: + perf_regs[0] = PERF_EXTIRQ_CFG_REG_6358; + break; ++ case BCM6362_CPU_ID: ++ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6362; ++ break; + } + + for (i = 0; i < 2; i++) { +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -14,6 +14,7 @@ + #define BCM6345_CPU_ID 0x6345 + #define BCM6348_CPU_ID 0x6348 + #define BCM6358_CPU_ID 0x6358 ++#define BCM6362_CPU_ID 0x6362 + #define BCM6368_CPU_ID 0x6368 + + void __init bcm63xx_cpu_init(void); +@@ -86,6 +87,20 @@ unsigned int bcm63xx_get_cpu_freq(void); + # define BCMCPU_IS_6358() (0) + #endif + ++#ifdef CONFIG_BCM63XX_CPU_6362 ++# ifdef bcm63xx_get_cpu_id ++# undef bcm63xx_get_cpu_id ++# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() ++# define BCMCPU_RUNTIME_DETECT ++# else ++# define bcm63xx_get_cpu_id() BCM6362_CPU_ID ++# endif ++# define BCMCPU_IS_6362() (bcm63xx_get_cpu_id() == BCM6362_CPU_ID) ++#else ++# define BCMCPU_IS_6362() (0) ++#endif ++ ++ + #ifdef CONFIG_BCM63XX_CPU_6368 + # ifdef bcm63xx_get_cpu_id + # undef bcm63xx_get_cpu_id +@@ -402,6 +417,62 @@ enum bcm63xx_regs_set { + + + /* ++ * 6362 register sets base address ++ */ ++#define BCM_6362_DSL_LMEM_BASE (0xdeadbeef) ++#define BCM_6362_PERF_BASE (0xb0000000) ++#define BCM_6362_TIMER_BASE (0xb0000040) ++#define BCM_6362_WDT_BASE (0xb000005c) ++#define BCM_6362_UART0_BASE (0xb0000100) ++#define BCM_6362_UART1_BASE (0xb0000120) ++#define BCM_6362_GPIO_BASE (0xb0000080) ++#define BCM_6362_SPI_BASE (0xb0000800) ++#define BCM_6362_HSSPI_BASE (0xb0001000) ++#define BCM_6362_UDC0_BASE (0xdeadbeef) ++#define BCM_6362_USBDMA_BASE (0xb000c000) ++#define BCM_6362_OHCI0_BASE (0xb0002600) ++#define BCM_6362_OHCI_PRIV_BASE (0xdeadbeef) ++#define BCM_6362_USBH_PRIV_BASE (0xb0002700) ++#define BCM_6362_USBD_BASE (0xb0002400) ++#define BCM_6362_MPI_BASE (0xdeadbeef) ++#define BCM_6362_PCMCIA_BASE (0xdeadbeef) ++#define BCM_6362_PCIE_BASE (0xb0e40000) ++#define BCM_6362_SDRAM_REGS_BASE (0xdeadbeef) ++#define BCM_6362_DSL_BASE (0xdeadbeef) ++#define BCM_6362_UBUS_BASE (0xdeadbeef) ++#define BCM_6362_ENET0_BASE (0xdeadbeef) ++#define BCM_6362_ENET1_BASE (0xdeadbeef) ++#define BCM_6362_ENETDMA_BASE (0xb000d800) ++#define BCM_6362_ENETDMAC_BASE (0xb000da00) ++#define BCM_6362_ENETDMAS_BASE (0xb000dc00) ++#define BCM_6362_ENETSW_BASE (0xb0e00000) ++#define BCM_6362_EHCI0_BASE (0xb0002500) ++#define BCM_6362_SDRAM_BASE (0xdeadbeef) ++#define BCM_6362_MEMC_BASE (0xdeadbeef) ++#define BCM_6362_DDR_BASE (0xb0003000) ++#define BCM_6362_M2M_BASE (0xdeadbeef) ++#define BCM_6362_ATM_BASE (0xdeadbeef) ++#define BCM_6362_XTM_BASE (0xb0007800) ++#define BCM_6362_XTMDMA_BASE (0xb000b800) ++#define BCM_6362_XTMDMAC_BASE (0xdeadbeef) ++#define BCM_6362_XTMDMAS_BASE (0xdeadbeef) ++#define BCM_6362_PCM_BASE (0xb000a800) ++#define BCM_6362_PCMDMA_BASE (0xdeadbeef) ++#define BCM_6362_PCMDMAC_BASE (0xdeadbeef) ++#define BCM_6362_PCMDMAS_BASE (0xdeadbeef) ++#define BCM_6362_RNG_BASE (0xdeadbeef) ++#define BCM_6362_MISC_BASE (0xb0001800) ++ ++#define BCM_6362_NAND_REG_BASE (0xb0000200) ++#define BCM_6362_NAND_CACHE_BASE (0xb0000600) ++#define BCM_6362_LED_BASE (0xb0001900) ++#define BCM_6362_IPSEC_BASE (0xb0002800) ++#define BCM_6362_IPSEC_DMA_BASE (0xb000d000) ++#define BCM_6362_WLAN_CHIPCOMMON_BASE (0xb0004000) ++#define BCM_6362_WLAN_D11_BASE (0xb0005000) ++#define BCM_6362_WLAN_SHIM_BASE (0xb0007000) ++ ++/* + * 6368 register sets base address + */ + #define BCM_6368_DSL_LMEM_BASE (0xdeadbeef) +@@ -557,6 +628,9 @@ static inline unsigned long bcm63xx_regs + #ifdef CONFIG_BCM63XX_CPU_6358 + __GEN_RSET(6358) + #endif ++#ifdef CONFIG_BCM63XX_CPU_6362 ++ __GEN_RSET(6362) ++#endif + #ifdef CONFIG_BCM63XX_CPU_6368 + __GEN_RSET(6368) + #endif +@@ -777,6 +851,71 @@ enum bcm63xx_irq { + #define BCM_6358_EXT_IRQ3 (IRQ_INTERNAL_BASE + 28) + + /* ++ * 6362 irqs ++ */ ++#define BCM_6362_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32) ++ ++#define BCM_6362_TIMER_IRQ (IRQ_INTERNAL_BASE + 0) ++#define BCM_6362_SPI_IRQ (IRQ_INTERNAL_BASE + 2) ++#define BCM_6362_UART0_IRQ (IRQ_INTERNAL_BASE + 3) ++#define BCM_6362_UART1_IRQ (IRQ_INTERNAL_BASE + 4) ++#define BCM_6362_DSL_IRQ (IRQ_INTERNAL_BASE + 28) ++#define BCM_6362_UDC0_IRQ 0 ++#define BCM_6362_ENET0_IRQ 0 ++#define BCM_6362_ENET1_IRQ 0 ++#define BCM_6362_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 14) ++#define BCM_6362_HSSPI_IRQ (IRQ_INTERNAL_BASE + 5) ++#define BCM_6362_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9) ++#define BCM_6362_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10) ++#define BCM_6362_USBD_IRQ (IRQ_INTERNAL_BASE + 11) ++#define BCM_6362_USBD_RXDMA0_IRQ (IRQ_INTERNAL_BASE + 20) ++#define BCM_6362_USBD_TXDMA0_IRQ (IRQ_INTERNAL_BASE + 21) ++#define BCM_6362_USBD_RXDMA1_IRQ (IRQ_INTERNAL_BASE + 22) ++#define BCM_6362_USBD_TXDMA1_IRQ (IRQ_INTERNAL_BASE + 23) ++#define BCM_6362_USBD_RXDMA2_IRQ (IRQ_INTERNAL_BASE + 24) ++#define BCM_6362_USBD_TXDMA2_IRQ (IRQ_INTERNAL_BASE + 25) ++#define BCM_6362_PCMCIA_IRQ 0 ++#define BCM_6362_ENET0_RXDMA_IRQ 0 ++#define BCM_6362_ENET0_TXDMA_IRQ 0 ++#define BCM_6362_ENET1_RXDMA_IRQ 0 ++#define BCM_6362_ENET1_TXDMA_IRQ 0 ++#define BCM_6362_PCI_IRQ (IRQ_INTERNAL_BASE + 30) ++#define BCM_6362_ATM_IRQ 0 ++#define BCM_6362_ENETSW_RXDMA0_IRQ (BCM_6362_HIGH_IRQ_BASE + 0) ++#define BCM_6362_ENETSW_RXDMA1_IRQ (BCM_6362_HIGH_IRQ_BASE + 1) ++#define BCM_6362_ENETSW_RXDMA2_IRQ (BCM_6362_HIGH_IRQ_BASE + 2) ++#define BCM_6362_ENETSW_RXDMA3_IRQ (BCM_6362_HIGH_IRQ_BASE + 3) ++#define BCM_6362_ENETSW_TXDMA0_IRQ 0 ++#define BCM_6362_ENETSW_TXDMA1_IRQ 0 ++#define BCM_6362_ENETSW_TXDMA2_IRQ 0 ++#define BCM_6362_ENETSW_TXDMA3_IRQ 0 ++#define BCM_6362_XTM_IRQ 0 ++#define BCM_6362_XTM_DMA0_IRQ (BCM_6362_HIGH_IRQ_BASE + 12) ++ ++#define BCM_6362_RING_OSC_IRQ (IRQ_INTERNAL_BASE + 1) ++#define BCM_6362_WLAN_GPIO_IRQ (IRQ_INTERNAL_BASE + 6) ++#define BCM_6362_WLAN_IRQ (IRQ_INTERNAL_BASE + 7) ++#define BCM_6362_IPSEC_IRQ (IRQ_INTERNAL_BASE + 8) ++#define BCM_6362_NAND_IRQ (IRQ_INTERNAL_BASE + 12) ++#define BCM_6362_PCM_IRQ (IRQ_INTERNAL_BASE + 13) ++#define BCM_6362_DG_IRQ (IRQ_INTERNAL_BASE + 15) ++#define BCM_6362_EPHY_ENERGY0_IRQ (IRQ_INTERNAL_BASE + 16) ++#define BCM_6362_EPHY_ENERGY1_IRQ (IRQ_INTERNAL_BASE + 17) ++#define BCM_6362_EPHY_ENERGY2_IRQ (IRQ_INTERNAL_BASE + 18) ++#define BCM_6362_EPHY_ENERGY3_IRQ (IRQ_INTERNAL_BASE + 19) ++#define BCM_6362_IPSEC_DMA0_IRQ (IRQ_INTERNAL_BASE + 26) ++#define BCM_6362_IPSEC_DMA1_IRQ (IRQ_INTERNAL_BASE + 27) ++#define BCM_6362_FAP0_IRQ (IRQ_INTERNAL_BASE + 29) ++#define BCM_6362_PCM_DMA0_IRQ (BCM_6362_HIGH_IRQ_BASE + 4) ++#define BCM_6362_PCM_DMA1_IRQ (BCM_6362_HIGH_IRQ_BASE + 5) ++#define BCM_6362_DECT0_IRQ (BCM_6362_HIGH_IRQ_BASE + 6) ++#define BCM_6362_DECT1_IRQ (BCM_6362_HIGH_IRQ_BASE + 7) ++#define BCM_6362_EXT_IRQ0 (BCM_6362_HIGH_IRQ_BASE + 8) ++#define BCM_6362_EXT_IRQ1 (BCM_6362_HIGH_IRQ_BASE + 9) ++#define BCM_6362_EXT_IRQ2 (BCM_6362_HIGH_IRQ_BASE + 10) ++#define BCM_6362_EXT_IRQ3 (BCM_6362_HIGH_IRQ_BASE + 11) ++ ++/* + * 6368 irqs + */ + #define BCM_6368_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h +@@ -17,6 +17,8 @@ static inline unsigned long bcm63xx_gpio + return 8; + case BCM6345_CPU_ID: + return 16; ++ case BCM6362_CPU_ID: ++ return 48; + case BCM6368_CPU_ID: + return 38; + case BCM6348_CPU_ID: +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -107,6 +107,39 @@ + CKCTL_6358_USBSU_EN | \ + CKCTL_6358_EPHY_EN) + ++#define CKCTL_6362_ADSL_QPROC_EN (1 << 1) ++#define CKCTL_6362_ADSL_AFE_EN (1 << 2) ++#define CKCTL_6362_ADSL_EN (1 << 3) ++#define CKCTL_6362_MIPS_EN (1 << 4) ++#define CKCTL_6362_WLAN_OCP_EN (1 << 5) ++#define CKCTL_6362_SWPKT_USB_EN (1 << 7) ++#define CKCTL_6362_SWPKT_SAR_EN (1 << 8) ++#define CKCTL_6362_SAR_EN (1 << 9) ++#define CKCTL_6362_ROBOSW_EN (1 << 10) ++#define CKCTL_6362_PCM_EN (1 << 11) ++#define CKCTL_6362_USBD_EN (1 << 12) ++#define CKCTL_6362_USBH_EN (1 << 13) ++#define CKCTL_6362_IPSEC_EN (1 << 14) ++#define CKCTL_6362_SPI_EN (1 << 15) ++#define CKCTL_6362_HSSPI_EN (1 << 16) ++#define CKCTL_6362_PCIE_EN (1 << 17) ++#define CKCTL_6362_FAP_EN (1 << 18) ++#define CKCTL_6362_PHYMIPS_EN (1 << 19) ++#define CKCTL_6362_NAND_EN (1 << 20) ++ ++#define CKCTL_6362_ALL_SAFE_EN (CKCTL_6362_PHYMIPS_EN | \ ++ CKCTL_6362_ADSL_QPROC_EN | \ ++ CKCTL_6362_ADSL_AFE_EN | \ ++ CKCTL_6362_ADSL_EN | \ ++ CKCTL_6362_SAR_EN | \ ++ CKCTL_6362_PCM_EN | \ ++ CKCTL_6362_IPSEC_EN | \ ++ CKCTL_6362_USBD_EN | \ ++ CKCTL_6362_USBH_EN | \ ++ CKCTL_6362_ROBOSW_EN | \ ++ CKCTL_6362_PCIE_EN) ++ ++ + #define CKCTL_6368_VDSL_QPROC_EN (1 << 2) + #define CKCTL_6368_VDSL_AFE_EN (1 << 3) + #define CKCTL_6368_VDSL_BONDING_EN (1 << 4) +@@ -148,6 +181,7 @@ + #define PERF_IRQMASK_6345_REG 0xc + #define PERF_IRQMASK_6348_REG 0xc + #define PERF_IRQMASK_6358_REG 0xc ++#define PERF_IRQMASK_6362_REG 0x20 + #define PERF_IRQMASK_6368_REG 0x20 + + /* Interrupt Status register */ +@@ -156,6 +190,7 @@ + #define PERF_IRQSTAT_6345_REG 0x10 + #define PERF_IRQSTAT_6348_REG 0x10 + #define PERF_IRQSTAT_6358_REG 0x10 ++#define PERF_IRQSTAT_6362_REG 0x28 + #define PERF_IRQSTAT_6368_REG 0x28 + + /* External Interrupt Configuration register */ +@@ -164,6 +199,7 @@ + #define PERF_EXTIRQ_CFG_REG_6345 0x14 + #define PERF_EXTIRQ_CFG_REG_6348 0x14 + #define PERF_EXTIRQ_CFG_REG_6358 0x14 ++#define PERF_EXTIRQ_CFG_REG_6362 0x18 + #define PERF_EXTIRQ_CFG_REG_6368 0x18 + + #define PERF_EXTIRQ_CFG_REG2_6368 0x1c +@@ -191,6 +227,7 @@ + /* Soft Reset register */ + #define PERF_SOFTRESET_REG 0x28 + #define PERF_SOFTRESET_6328_REG 0x10 ++#define PERF_SOFTRESET_6362_REG 0x10 + #define PERF_SOFTRESET_6368_REG 0x10 + + #define SOFTRESET_6328_SPI_MASK (1 << 0) +@@ -244,6 +281,22 @@ + SOFTRESET_6348_ACLC_MASK | \ + SOFTRESET_6348_ADSLMIPSPLL_MASK) + ++#define SOFTRESET_6362_SPI_MASK (1 << 0) ++#define SOFTRESET_6362_IPSEC_MASK (1 << 1) ++#define SOFTRESET_6362_EPHY_MASK (1 << 2) ++#define SOFTRESET_6362_SAR_MASK (1 << 3) ++#define SOFTRESET_6362_ENETSW_MASK (1 << 4) ++#define SOFTRESET_6362_USBS_MASK (1 << 5) ++#define SOFTRESET_6362_USBH_MASK (1 << 6) ++#define SOFTRESET_6362_PCM_MASK (1 << 7) ++#define SOFTRESET_6362_PCIE_CORE_MASK (1 << 8) ++#define SOFTRESET_6362_PCIE_MASK (1 << 9) ++#define SOFTRESET_6362_PCIE_EXT_MASK (1 << 10) ++#define SOFTRESET_6362_WLAN_SHIM_MASK (1 << 11) ++#define SOFTRESET_6362_DDR_PHY_MASK (1 << 12) ++#define SOFTRESET_6362_FAP_MASK (1 << 13) ++#define SOFTRESET_6362_WLAN_UBUS_MASK (1 << 14) ++ + #define SOFTRESET_6368_SPI_MASK (1 << 0) + #define SOFTRESET_6368_MPI_MASK (1 << 3) + #define SOFTRESET_6368_EPHY_MASK (1 << 6) +@@ -1182,6 +1235,12 @@ + #define SERDES_PCIE_EN (1 << 0) + #define SERDES_PCIE_EXD_EN (1 << 15) + ++#define MISC_STRAPBUS_6362_REG 0x14 ++#define STRAPBUS_6362_FCVO_SHIFT 1 ++#define STRAPBUS_6362_FCVO_MASK (0x1f << STRAPBUS_6362_FCVO_SHIFT) ++#define STRAPBUS_6362_BOOT_SEL_SERIAL (1 << 15) ++#define STRAPBUS_6362_BOOT_SEL_NAND (0 << 15) ++ + #define MISC_STRAPBUS_6328_REG 0x240 + #define STRAPBUS_6328_FCVO_SHIFT 7 + #define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT) +--- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h ++++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h +@@ -19,6 +19,7 @@ static inline int is_bcm63xx_internal_re + return 1; + break; + case BCM6328_CPU_ID: ++ case BCM6362_CPU_ID: + case BCM6368_CPU_ID: + if (offset >= 0xb0000000 && offset < 0xb1000000) + return 1; diff --git a/target/linux/brcm63xx/patches-3.3/313-MIPS-BCM63XX-enable-pcie-for-BCM6362.patch b/target/linux/brcm63xx/patches-3.3/313-MIPS-BCM63XX-enable-pcie-for-BCM6362.patch new file mode 100644 index 000000000..36024d10b --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/313-MIPS-BCM63XX-enable-pcie-for-BCM6362.patch @@ -0,0 +1,110 @@ +From e49546bf3f255f028d0877ceeb7ed6466fe37d8a Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Mon, 21 Nov 2011 00:53:26 +0100 +Subject: [PATCH 56/84] MIPS: BCM63XX: enable pcie for BCM6362 + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 3 +- + arch/mips/pci/pci-bcm63xx.c | 57 +++++++++++++++------ + 2 files changed, 44 insertions(+), 16 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -1231,7 +1231,8 @@ + /************************************************************************* + * _REG relative to RSET_MISC + *************************************************************************/ +-#define MISC_SERDES_CTRL_REG 0x0 ++#define MISC_SERDES_CTRL_6328_REG 0x0 ++#define MISC_SERDES_CTRL_6362_REG 0x4 + #define SERDES_PCIE_EN (1 << 0) + #define SERDES_PCIE_EXD_EN (1 << 15) + +--- a/arch/mips/pci/pci-bcm63xx.c ++++ b/arch/mips/pci/pci-bcm63xx.c +@@ -118,35 +118,61 @@ void __iomem *pci_iospace_start; + static void __init bcm63xx_reset_pcie(void) + { + u32 val; ++ u32 reg; ++ u32 mask; + + /* enable clock */ ++ ++ if (BCMCPU_IS_6328()) ++ mask = CKCTL_6328_PCIE_EN; ++ else ++ mask = CKCTL_6362_PCIE_EN; ++ + val = bcm_perf_readl(PERF_CKCTL_REG); +- val |= CKCTL_6328_PCIE_EN; ++ val |= mask; + bcm_perf_writel(val, PERF_CKCTL_REG); + + /* enable SERDES */ +- val = bcm_misc_readl(MISC_SERDES_CTRL_REG); ++ ++ if (BCMCPU_IS_6328()) ++ reg = MISC_SERDES_CTRL_6328_REG; ++ else ++ reg = MISC_SERDES_CTRL_6362_REG; ++ ++ val = bcm_misc_readl(reg); + val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN; +- bcm_misc_writel(val, MISC_SERDES_CTRL_REG); ++ bcm_misc_writel(val, reg); + + /* reset the PCIe core */ +- val = bcm_perf_readl(PERF_SOFTRESET_6328_REG); ++ if (BCMCPU_IS_6328()) { ++ reg = PERF_SOFTRESET_6328_REG; ++ mask = SOFTRESET_6328_PCIE_MASK | SOFTRESET_6328_PCIE_CORE_MASK ++ | SOFTRESET_6328_PCIE_HARD_MASK; ++ } else { ++ reg = PERF_SOFTRESET_6362_REG; ++ mask = SOFTRESET_6362_PCIE_MASK | SOFTRESET_6362_PCIE_CORE_MASK; ++ } ++ val = bcm_perf_readl(reg); ++ val &= ~mask; ++ ++ if (BCMCPU_IS_6328()) ++ val &= ~SOFTRESET_6328_PCIE_EXT_MASK; ++ else ++ val &= ~SOFTRESET_6362_PCIE_EXT_MASK; + +- val &= ~SOFTRESET_6328_PCIE_MASK; +- val &= ~SOFTRESET_6328_PCIE_CORE_MASK; +- val &= ~SOFTRESET_6328_PCIE_HARD_MASK; +- val &= ~SOFTRESET_6328_PCIE_EXT_MASK; +- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); ++ bcm_perf_writel(val, reg); + mdelay(10); + +- val |= SOFTRESET_6328_PCIE_MASK; +- val |= SOFTRESET_6328_PCIE_CORE_MASK; +- val |= SOFTRESET_6328_PCIE_HARD_MASK; +- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); ++ val |= mask; ++ bcm_perf_writel(val, reg); + mdelay(10); + +- val |= SOFTRESET_6328_PCIE_EXT_MASK; +- bcm_perf_writel(val, PERF_SOFTRESET_6328_REG); ++ if (BCMCPU_IS_6328()) ++ val |= SOFTRESET_6328_PCIE_EXT_MASK; ++ else ++ val |= SOFTRESET_6362_PCIE_EXT_MASK; ++ ++ bcm_perf_writel(val, reg); + mdelay(200); + } + +@@ -332,6 +358,7 @@ static int __init bcm63xx_pci_init(void) + + switch (bcm63xx_get_cpu_id()) { + case BCM6328_CPU_ID: ++ case BCM6362_CPU_ID: + return bcm63xx_register_pcie(); + case BCM6348_CPU_ID: + case BCM6358_CPU_ID: diff --git a/target/linux/brcm63xx/patches-3.3/400-ohci-add-driver-for-bcm63xx-integrated-controller.patch b/target/linux/brcm63xx/patches-3.3/400-ohci-add-driver-for-bcm63xx-integrated-controller.patch new file mode 100644 index 000000000..debbb13cd --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/400-ohci-add-driver-for-bcm63xx-integrated-controller.patch @@ -0,0 +1,234 @@ +From 7b510c5754d3c46e1287803f51e8ecb177414438 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Fri, 10 Jun 2011 19:14:30 +0200 +Subject: [PATCH 23/63] ohci: add driver for bcm63xx integrated controller. + +--- + drivers/usb/host/Kconfig | 9 ++ + drivers/usb/host/ohci-bcm63xx.c | 175 +++++++++++++++++++++++++++++++++++++++ + drivers/usb/host/ohci-hcd.c | 5 + + drivers/usb/host/ohci.h | 2 +- + 4 files changed, 190 insertions(+), 1 deletions(-) + create mode 100644 drivers/usb/host/ohci-bcm63xx.c + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -296,6 +296,15 @@ config USB_OHCI_HCD + To compile this driver as a module, choose M here: the + module will be called ohci-hcd. + ++config USB_OHCI_BCM63XX ++ bool "Support for Broadcom 63xx on-chip OHCI USB controller" ++ depends on USB_OHCI_HCD && BCM63XX ++ select USB_OHCI_BIG_ENDIAN_DESC ++ select USB_OHCI_BIG_ENDIAN_MMIO ++ ---help--- ++ Enables support for the on-chip OHCI controller on ++ BCM63XX chips. ++ + config USB_OHCI_HCD_OMAP1 + bool "OHCI support for OMAP1/2 chips" + depends on USB_OHCI_HCD && (ARCH_OMAP1 || ARCH_OMAP2) +--- /dev/null ++++ b/drivers/usb/host/ohci-bcm63xx.c +@@ -0,0 +1,175 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> ++ */ ++ ++#include <linux/init.h> ++#include <linux/clk.h> ++#include <linux/platform_device.h> ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_regs.h> ++#include <bcm63xx_io.h> ++ ++static struct clk *usb_host_clock; ++ ++static int __devinit ohci_bcm63xx_start(struct usb_hcd *hcd) ++{ ++ struct ohci_hcd *ohci = hcd_to_ohci(hcd); ++ int ret; ++ ++ ohci->num_ports = 1; ++ ++ ret = ohci_init(ohci); ++ if (ret < 0) ++ return ret; ++ ++ /* FIXME: autodetected port 2 is shared with USB slave */ ++ ++ ret = ohci_run(ohci); ++ if (ret < 0) { ++ err("can't start %s", hcd->self.bus_name); ++ ohci_stop(hcd); ++ return ret; ++ } ++ return 0; ++} ++ ++static const struct hc_driver ohci_bcm63xx_hc_driver = { ++ .description = hcd_name, ++ .product_desc = "BCM63XX integrated OHCI controller", ++ .hcd_priv_size = sizeof(struct ohci_hcd), ++ ++ .irq = ohci_irq, ++ .flags = HCD_USB11 | HCD_MEMORY, ++ .start = ohci_bcm63xx_start, ++ .stop = ohci_stop, ++ .shutdown = ohci_shutdown, ++ .urb_enqueue = ohci_urb_enqueue, ++ .urb_dequeue = ohci_urb_dequeue, ++ .endpoint_disable = ohci_endpoint_disable, ++ .get_frame_number = ohci_get_frame, ++ .hub_status_data = ohci_hub_status_data, ++ .hub_control = ohci_hub_control, ++ .start_port_reset = ohci_start_port_reset, ++}; ++ ++static int __devinit ohci_hcd_bcm63xx_drv_probe(struct platform_device *pdev) ++{ ++ struct resource *res_mem; ++ struct usb_hcd *hcd; ++ struct ohci_hcd *ohci; ++ struct clk *clk; ++ u32 reg; ++ int ret, irq; ++ ++ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ irq = platform_get_irq(pdev, 0); ++ if (!res_mem || irq < 0) ++ return -ENODEV; ++ ++ /* enable USB host clock */ ++ clk = clk_get(&pdev->dev, "usbh"); ++ if (IS_ERR(clk)) ++ return -ENODEV; ++ ++ clk_enable(clk); ++ usb_host_clock = clk; ++ msleep(100); ++ ++ if (BCMCPU_IS_6348()) ++ bcm_rset_writel(RSET_OHCI_PRIV, 0, OHCI_PRIV_REG); ++ else if (BCMCPU_IS_6358()) { ++ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6358_REG); ++ reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK; ++ reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK; ++ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6358_REG); ++ /* ++ * The magic value comes for the original vendor BSP ++ * and is needed for USB to work. Datasheet does not ++ * help, so the magic value is used as-is. ++ */ ++ bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, ++ USBH_PRIV_TEST_6358_REG); ++ ++ } else if (BCMCPU_IS_6368()) { ++ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG); ++ reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK; ++ reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK; ++ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6368_REG); ++ ++ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SETUP_6368_REG); ++ reg |= USBH_PRIV_SETUP_IOC_MASK; ++ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SETUP_6368_REG); ++ } ++ ++ hcd = usb_create_hcd(&ohci_bcm63xx_hc_driver, &pdev->dev, "bcm63xx"); ++ if (!hcd) ++ return -ENOMEM; ++ hcd->rsrc_start = res_mem->start; ++ hcd->rsrc_len = res_mem->end - res_mem->start + 1; ++ ++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { ++ pr_debug("request_mem_region failed\n"); ++ ret = -EBUSY; ++ goto out; ++ } ++ ++ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); ++ if (!hcd->regs) { ++ pr_debug("ioremap failed\n"); ++ ret = -EIO; ++ goto out1; ++ } ++ ++ ohci = hcd_to_ohci(hcd); ++ ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC | ++ OHCI_QUIRK_FRAME_NO; ++ ohci_hcd_init(ohci); ++ ++ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); ++ if (ret) ++ goto out2; ++ ++ platform_set_drvdata(pdev, hcd); ++ return 0; ++ ++out2: ++ iounmap(hcd->regs); ++out1: ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++out: ++ usb_put_hcd(hcd); ++ return ret; ++} ++ ++static int __devexit ohci_hcd_bcm63xx_drv_remove(struct platform_device *pdev) ++{ ++ struct usb_hcd *hcd; ++ ++ hcd = platform_get_drvdata(pdev); ++ usb_remove_hcd(hcd); ++ iounmap(hcd->regs); ++ usb_put_hcd(hcd); ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++ if (usb_host_clock) { ++ clk_disable(usb_host_clock); ++ clk_put(usb_host_clock); ++ } ++ platform_set_drvdata(pdev, NULL); ++ return 0; ++} ++ ++static struct platform_driver ohci_hcd_bcm63xx_driver = { ++ .probe = ohci_hcd_bcm63xx_drv_probe, ++ .remove = __devexit_p(ohci_hcd_bcm63xx_drv_remove), ++ .shutdown = usb_hcd_platform_shutdown, ++ .driver = { ++ .name = "bcm63xx_ohci", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++MODULE_ALIAS("platform:bcm63xx_ohci"); +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -1121,6 +1121,11 @@ MODULE_LICENSE ("GPL"); + #define PLATFORM_DRIVER ohci_xls_driver + #endif + ++#ifdef CONFIG_USB_OHCI_BCM63XX ++#include "ohci-bcm63xx.c" ++#define PLATFORM_DRIVER ohci_hcd_bcm63xx_driver ++#endif ++ + #if !defined(PCI_DRIVER) && \ + !defined(PLATFORM_DRIVER) && \ + !defined(OMAP1_PLATFORM_DRIVER) && \ +--- a/drivers/usb/host/ohci.h ++++ b/drivers/usb/host/ohci.h +@@ -652,7 +652,7 @@ static inline u32 hc32_to_cpup (const st + * some big-endian SOC implementations. Same thing happens with PSW access. + */ + +-#ifdef CONFIG_PPC_MPC52xx ++#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_BCM63XX) + #define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO) + #else + #define big_endian_frame_no_quirk(ohci) 0 diff --git a/target/linux/brcm63xx/patches-3.3/401-MIPS-BCM63XX-register-ohci-device.patch b/target/linux/brcm63xx/patches-3.3/401-MIPS-BCM63XX-register-ohci-device.patch new file mode 100644 index 000000000..27ecc5a8b --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/401-MIPS-BCM63XX-register-ohci-device.patch @@ -0,0 +1,143 @@ +From ab96f20ca1c3c8e7e5acd82d1e50823a5d572675 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Tue, 24 May 2011 21:47:41 +0200 +Subject: [PATCH 24/63] MIPS: BCM63XX: register ohci device. + +--- + arch/mips/bcm63xx/Kconfig | 9 ++-- + arch/mips/bcm63xx/Makefile | 2 +- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 4 ++ + arch/mips/bcm63xx/dev-usb-ohci.c | 50 ++++++++++++++++++++ + .../asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h | 6 ++ + 5 files changed, 65 insertions(+), 6 deletions(-) + create mode 100644 arch/mips/bcm63xx/dev-usb-ohci.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h + +--- a/arch/mips/bcm63xx/Kconfig ++++ b/arch/mips/bcm63xx/Kconfig +@@ -8,22 +8,20 @@ config BCM63XX_CPU_6328 + config BCM63XX_CPU_6338 + bool "support 6338 CPU" + select HW_HAS_PCI +- select USB_ARCH_HAS_OHCI +- select USB_OHCI_BIG_ENDIAN_DESC +- select USB_OHCI_BIG_ENDIAN_MMIO ++ select USB_ARCH_HAS_OHCI if USB_SUPPORT + + config BCM63XX_CPU_6345 + bool "support 6345 CPU" +- select USB_OHCI_BIG_ENDIAN_DESC +- select USB_OHCI_BIG_ENDIAN_MMIO + + config BCM63XX_CPU_6348 + bool "support 6348 CPU" + select HW_HAS_PCI ++ select USB_ARCH_HAS_OHCI if USB_SUPPORT + + config BCM63XX_CPU_6358 + bool "support 6358 CPU" + select HW_HAS_PCI ++ select USB_ARCH_HAS_OHCI if USB_SUPPORT + + config BCM63XX_CPU_6362 + bool "support 6362 CPU" +@@ -32,6 +30,7 @@ config BCM63XX_CPU_6362 + config BCM63XX_CPU_6368 + bool "support 6368 CPU" + select HW_HAS_PCI ++ select USB_ARCH_HAS_OHCI if USB_SUPPORT + endmenu + + source "arch/mips/bcm63xx/boards/Kconfig" +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,6 +1,6 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ + dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ +- dev-spi.o dev-uart.o dev-wdt.o ++ dev-spi.o dev-uart.o dev-usb-ohci.o dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -27,6 +27,7 @@ + #include <bcm63xx_dev_flash.h> + #include <bcm63xx_dev_pcmcia.h> + #include <bcm63xx_dev_spi.h> ++#include <bcm63xx_dev_usb_ohci.h> + #include <board_bcm963xx.h> + #include <bcm_tag.h> + +@@ -916,6 +917,9 @@ int __init board_register_devices(void) + !board_get_mac_address(board.enet1.mac_addr)) + bcm63xx_enet_register(1, &board.enet1); + ++ if (board.has_ohci0) ++ bcm63xx_ohci_register(); ++ + if (board.has_dsp) + bcm63xx_dsp_register(&board.dsp); + +--- /dev/null ++++ b/arch/mips/bcm63xx/dev-usb-ohci.c +@@ -0,0 +1,50 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> ++ */ ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_dev_usb_ohci.h> ++ ++static struct resource ohci_resources[] = { ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = -1, /* filled at runtime */ ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 ohci_dmamask = ~(u32)0; ++ ++static struct platform_device bcm63xx_ohci_device = { ++ .name = "bcm63xx_ohci", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(ohci_resources), ++ .resource = ohci_resources, ++ .dev = { ++ .dma_mask = &ohci_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++}; ++ ++int __init bcm63xx_ohci_register(void) ++{ ++ if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368()) ++ return 0; ++ ++ ohci_resources[0].start = bcm63xx_regset_address(RSET_OHCI0); ++ ohci_resources[0].end = ohci_resources[0].start; ++ ohci_resources[0].end += RSET_OHCI_SIZE - 1; ++ ohci_resources[1].start = bcm63xx_get_irq_number(IRQ_OHCI0); ++ return platform_device_register(&bcm63xx_ohci_device); ++} +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h +@@ -0,0 +1,6 @@ ++#ifndef BCM63XX_DEV_USB_OHCI_H_ ++#define BCM63XX_DEV_USB_OHCI_H_ ++ ++int bcm63xx_ohci_register(void); ++ ++#endif /* BCM63XX_DEV_USB_OHCI_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/402-ehci-add-driver-for-bcm63xx-integrated-controller.patch b/target/linux/brcm63xx/patches-3.3/402-ehci-add-driver-for-bcm63xx-integrated-controller.patch new file mode 100644 index 000000000..42c85e991 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/402-ehci-add-driver-for-bcm63xx-integrated-controller.patch @@ -0,0 +1,241 @@ +From db58271d5152aa1d3894fdef13ca04379139d5d9 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Fri, 10 Jun 2011 19:15:47 +0200 +Subject: [PATCH 25/63] ehci: add driver for bcm63xx integrated controller. + +--- + drivers/usb/host/Kconfig | 10 ++- + drivers/usb/host/ehci-bcm63xx.c | 186 +++++++++++++++++++++++++++++++++++++++ + drivers/usb/host/ehci-hcd.c | 5 + + 3 files changed, 199 insertions(+), 1 deletions(-) + create mode 100644 drivers/usb/host/ehci-bcm63xx.c + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -106,7 +106,7 @@ config USB_EHCI_BIG_ENDIAN_MMIO + depends on USB_EHCI_HCD && (PPC_CELLEB || PPC_PS3 || 440EPX || \ + ARCH_IXP4XX || XPS_USB_HCD_XILINX || \ + PPC_MPC512x || CPU_CAVIUM_OCTEON || \ +- PMC_MSP || SPARC_LEON) ++ PMC_MSP || SPARC_LEON || BCM63XX) + default y + + config USB_EHCI_BIG_ENDIAN_DESC +@@ -129,6 +129,14 @@ config XPS_USB_HCD_XILINX + config USB_FSL_MPH_DR_OF + tristate + ++config USB_EHCI_BCM63XX ++ bool "Support for Broadcom 63xx on-chip EHCI USB controller" ++ depends on USB_EHCI_HCD && BCM63XX ++ select USB_EHCI_BIG_ENDIAN_MMIO ++ ---help--- ++ Enables support for the on-chip EHCI controller on ++ BCM6358 and later chips. ++ + config USB_EHCI_FSL + bool "Support for Freescale PPC on-chip EHCI USB controller" + depends on USB_EHCI_HCD && FSL_SOC +--- /dev/null ++++ b/drivers/usb/host/ehci-bcm63xx.c +@@ -0,0 +1,186 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> ++ */ ++ ++#include <linux/init.h> ++#include <linux/clk.h> ++#include <linux/platform_device.h> ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_regs.h> ++#include <bcm63xx_io.h> ++ ++static struct clk *usb_host_clock; ++ ++static int ehci_bcm63xx_setup(struct usb_hcd *hcd) ++{ ++ struct ehci_hcd *ehci = hcd_to_ehci(hcd); ++ int retval; ++ ++ retval = ehci_halt(ehci); ++ if (retval) ++ return retval; ++ ++ retval = ehci_init(hcd); ++ if (retval) ++ return retval; ++ ++ ehci_reset(ehci); ++ ehci_port_power(ehci, 0); ++ ++ return retval; ++} ++ ++ ++static const struct hc_driver ehci_bcm63xx_hc_driver = { ++ .description = hcd_name, ++ .product_desc = "BCM63XX integrated EHCI controller", ++ .hcd_priv_size = sizeof(struct ehci_hcd), ++ ++ .irq = ehci_irq, ++ .flags = HCD_MEMORY | HCD_USB2, ++ ++ .reset = ehci_bcm63xx_setup, ++ .start = ehci_run, ++ .stop = ehci_stop, ++ .shutdown = ehci_shutdown, ++ ++ .urb_enqueue = ehci_urb_enqueue, ++ .urb_dequeue = ehci_urb_dequeue, ++ .endpoint_disable = ehci_endpoint_disable, ++ ++ .get_frame_number = ehci_get_frame, ++ ++ .hub_status_data = ehci_hub_status_data, ++ .hub_control = ehci_hub_control, ++ .bus_suspend = ehci_bus_suspend, ++ .bus_resume = ehci_bus_resume, ++ .relinquish_port = ehci_relinquish_port, ++ .port_handed_over = ehci_port_handed_over, ++}; ++ ++static int __devinit ehci_hcd_bcm63xx_drv_probe(struct platform_device *pdev) ++{ ++ struct resource *res_mem; ++ struct usb_hcd *hcd; ++ struct ehci_hcd *ehci; ++ struct clk *clk; ++ u32 reg; ++ int ret, irq; ++ ++ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ irq = platform_get_irq(pdev, 0);; ++ if (!res_mem || irq < 0) ++ return -ENODEV; ++ ++ /* enable USB host clock */ ++ clk = clk_get(&pdev->dev, "usbh"); ++ if (IS_ERR(clk)) ++ return -ENODEV; ++ ++ clk_enable(clk); ++ usb_host_clock = clk; ++ msleep(100); ++ ++ if (BCMCPU_IS_6358()) { ++ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6358_REG); ++ reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK; ++ reg |= USBH_PRIV_SWAP_EHCI_ENDN_MASK; ++ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6358_REG); ++ ++ /* ++ * The magic value comes for the original vendor BSP ++ * and is needed for USB to work. Datasheet does not ++ * help, so the magic value is used as-is. ++ */ ++ bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, ++ USBH_PRIV_TEST_6358_REG); ++ ++ } else if (BCMCPU_IS_6368()) { ++ ++ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG); ++ reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK; ++ reg |= USBH_PRIV_SWAP_EHCI_ENDN_MASK; ++ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_6368_REG); ++ ++ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SETUP_6368_REG); ++ reg |= USBH_PRIV_SETUP_IOC_MASK; ++ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SETUP_6368_REG); ++ } ++ ++ hcd = usb_create_hcd(&ehci_bcm63xx_hc_driver, &pdev->dev, "bcm63xx"); ++ if (!hcd) ++ return -ENOMEM; ++ hcd->rsrc_start = res_mem->start; ++ hcd->rsrc_len = res_mem->end - res_mem->start + 1; ++ ++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { ++ pr_debug("request_mem_region failed\n"); ++ ret = -EBUSY; ++ goto out; ++ } ++ ++ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); ++ if (!hcd->regs) { ++ pr_debug("ioremap failed\n"); ++ ret = -EIO; ++ goto out1; ++ } ++ ++ ehci = hcd_to_ehci(hcd); ++ ehci->big_endian_mmio = 1; ++ ehci->big_endian_desc = 0; ++ ehci->caps = hcd->regs; ++ ehci->regs = hcd->regs + ++ HC_LENGTH(ehci, ehci_readl(ehci, &ehci->caps->hc_capbase)); ++ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); ++ ehci->sbrn = 0x20; ++ ehci->ignore_oc = 1; ++ ++ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED); ++ if (ret) ++ goto out2; ++ ++ platform_set_drvdata(pdev, hcd); ++ return 0; ++ ++out2: ++ iounmap(hcd->regs); ++out1: ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++out: ++ usb_put_hcd(hcd); ++ return ret; ++} ++ ++static int __devexit ehci_hcd_bcm63xx_drv_remove(struct platform_device *pdev) ++{ ++ struct usb_hcd *hcd; ++ ++ hcd = platform_get_drvdata(pdev); ++ usb_remove_hcd(hcd); ++ iounmap(hcd->regs); ++ usb_put_hcd(hcd); ++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len); ++ if (usb_host_clock) { ++ clk_disable(usb_host_clock); ++ clk_put(usb_host_clock); ++ } ++ platform_set_drvdata(pdev, NULL); ++ return 0; ++} ++ ++static struct platform_driver ehci_hcd_bcm63xx_driver = { ++ .probe = ehci_hcd_bcm63xx_drv_probe, ++ .remove = __devexit_p(ehci_hcd_bcm63xx_drv_remove), ++ .shutdown = usb_hcd_platform_shutdown, ++ .driver = { ++ .name = "bcm63xx_ehci", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++MODULE_ALIAS("platform:bcm63xx_ehci"); +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -1381,6 +1381,11 @@ MODULE_LICENSE ("GPL"); + #define PLATFORM_DRIVER ehci_mv_driver + #endif + ++#ifdef CONFIG_USB_EHCI_BCM63XX ++#include "ehci-bcm63xx.c" ++#define PLATFORM_DRIVER ehci_hcd_bcm63xx_driver ++#endif ++ + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ + !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ + !defined(XILINX_OF_PLATFORM_DRIVER) diff --git a/target/linux/brcm63xx/patches-3.3/403-MIPS-BCM63XX-register-ehci-device.patch b/target/linux/brcm63xx/patches-3.3/403-MIPS-BCM63XX-register-ehci-device.patch new file mode 100644 index 000000000..cd5eb73ce --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/403-MIPS-BCM63XX-register-ehci-device.patch @@ -0,0 +1,125 @@ +From a2d78246e4cb45b5978fc682aad19c0fff0cd20d Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Tue, 24 May 2011 21:50:33 +0200 +Subject: [PATCH 26/63] MIPS: BCM63XX: register ehci device. + +--- + arch/mips/bcm63xx/Kconfig | 2 + + arch/mips/bcm63xx/Makefile | 2 +- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 4 ++ + arch/mips/bcm63xx/dev-usb-ehci.c | 50 ++++++++++++++++++++ + .../asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h | 6 ++ + 5 files changed, 63 insertions(+), 1 deletions(-) + create mode 100644 arch/mips/bcm63xx/dev-usb-ehci.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h + +--- a/arch/mips/bcm63xx/Kconfig ++++ b/arch/mips/bcm63xx/Kconfig +@@ -22,6 +22,7 @@ config BCM63XX_CPU_6358 + bool "support 6358 CPU" + select HW_HAS_PCI + select USB_ARCH_HAS_OHCI if USB_SUPPORT ++ select USB_ARCH_HAS_EHCI if USB_SUPPORT + + config BCM63XX_CPU_6362 + bool "support 6362 CPU" +@@ -31,6 +32,7 @@ config BCM63XX_CPU_6368 + bool "support 6368 CPU" + select HW_HAS_PCI + select USB_ARCH_HAS_OHCI if USB_SUPPORT ++ select USB_ARCH_HAS_EHCI if USB_SUPPORT + endmenu + + source "arch/mips/bcm63xx/boards/Kconfig" +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,6 +1,6 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ + dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ +- dev-spi.o dev-uart.o dev-usb-ohci.o dev-wdt.o ++ dev-spi.o dev-uart.o dev-usb-ehci.o dev-usb-ohci.o dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -28,6 +28,7 @@ + #include <bcm63xx_dev_pcmcia.h> + #include <bcm63xx_dev_spi.h> + #include <bcm63xx_dev_usb_ohci.h> ++#include <bcm63xx_dev_usb_ehci.h> + #include <board_bcm963xx.h> + #include <bcm_tag.h> + +@@ -917,6 +918,9 @@ int __init board_register_devices(void) + !board_get_mac_address(board.enet1.mac_addr)) + bcm63xx_enet_register(1, &board.enet1); + ++ if (board.has_ehci0) ++ bcm63xx_ehci_register(); ++ + if (board.has_ohci0) + bcm63xx_ohci_register(); + +--- /dev/null ++++ b/arch/mips/bcm63xx/dev-usb-ehci.c +@@ -0,0 +1,50 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr> ++ */ ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_dev_usb_ehci.h> ++ ++static struct resource ehci_resources[] = { ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = -1, /* filled at runtime */ ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static u64 ehci_dmamask = ~(u32)0; ++ ++static struct platform_device bcm63xx_ehci_device = { ++ .name = "bcm63xx_ehci", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(ehci_resources), ++ .resource = ehci_resources, ++ .dev = { ++ .dma_mask = &ehci_dmamask, ++ .coherent_dma_mask = 0xffffffff, ++ }, ++}; ++ ++int __init bcm63xx_ehci_register(void) ++{ ++ if (!BCMCPU_IS_6358() && !BCMCPU_IS_6368()) ++ return 0; ++ ++ ehci_resources[0].start = bcm63xx_regset_address(RSET_EHCI0); ++ ehci_resources[0].end = ehci_resources[0].start; ++ ehci_resources[0].end += RSET_EHCI_SIZE - 1; ++ ehci_resources[1].start = bcm63xx_get_irq_number(IRQ_EHCI0); ++ return platform_device_register(&bcm63xx_ehci_device); ++} +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h +@@ -0,0 +1,6 @@ ++#ifndef BCM63XX_DEV_USB_EHCI_H_ ++#define BCM63XX_DEV_USB_EHCI_H_ ++ ++int bcm63xx_ehci_register(void); ++ ++#endif /* BCM63XX_DEV_USB_EHCI_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/404-bcm963xx_flashmap.patch b/target/linux/brcm63xx/patches-3.3/404-bcm963xx_flashmap.patch new file mode 100644 index 000000000..8338962e5 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/404-bcm963xx_flashmap.patch @@ -0,0 +1,65 @@ +From a4d005c91d403d9f3d0272db6cc46202c06ec774 Mon Sep 17 00:00:00 2001 +From: Axel Gembe <ago@bastart.eu.org> +Date: Mon, 12 May 2008 18:54:09 +0200 +Subject: [PATCH] bcm963xx: flashmap support + +Signed-off-by: Axel Gembe <ago@bastart.eu.org> +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 19 +---------------- + drivers/mtd/maps/bcm963xx-flash.c | 32 ++++++++++++++++++++++++---- + drivers/mtd/redboot.c | 13 +++++++++-- + 3 files changed, 38 insertions(+), 26 deletions(-) + +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -30,7 +30,7 @@ static struct mtd_partition mtd_partitio + } + }; + +-static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL }; ++static const char *bcm63xx_part_types[] = { "bcm63xxpart", "RedBoot", NULL }; + + static struct physmap_flash_data flash_data = { + .width = 2, +--- a/drivers/mtd/redboot.c ++++ b/drivers/mtd/redboot.c +@@ -75,6 +75,7 @@ static int parse_redboot_partitions(stru + int nulllen = 0; + int numslots; + unsigned long offset; ++ unsigned long fis_origin = 0; + #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + static char nullstring[] = "unallocated"; + #endif +@@ -181,6 +182,16 @@ static int parse_redboot_partitions(stru + goto out; + } + ++ if (data && data->origin) { ++ fis_origin = data->origin; ++ } else { ++ for (i = 0; i < numslots; i++) { ++ if (!strncmp(buf[i].name, "RedBoot", 8)) { ++ fis_origin = (buf[i].flash_base & (master->size << 1) - 1); ++ } ++ } ++ } ++ + for (i = 0; i < numslots; i++) { + struct fis_list *new_fl, **prev; + +@@ -201,10 +212,10 @@ static int parse_redboot_partitions(stru + goto out; + } + new_fl->img = &buf[i]; +- if (data && data->origin) +- buf[i].flash_base -= data->origin; +- else +- buf[i].flash_base &= master->size-1; ++ if (fis_origin) ++ buf[i].flash_base -= fis_origin; ++ ++ buf[i].flash_base &= (master->size << 1) - 1; + + /* I'm sure the JFFS2 code has done me permanent damage. + * I now think the following is _normal_ diff --git a/target/linux/brcm63xx/patches-3.3/405-bcm963xx_real_rootfs_length.patch b/target/linux/brcm63xx/patches-3.3/405-bcm963xx_real_rootfs_length.patch new file mode 100644 index 000000000..856b9e267 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/405-bcm963xx_real_rootfs_length.patch @@ -0,0 +1,27 @@ +--- a/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm963xx_tag.h +@@ -85,8 +85,10 @@ struct bcm_tag { + __u32 rootfs_crc; + /* 224-227: CRC32 of kernel partition */ + __u32 kernel_crc; +- /* 228-235: Unused at present */ +- char reserved1[8]; ++ /* 228-231: Image sequence number */ ++ char image_sequence[4]; ++ /* 222-235: Openwrt: real rootfs length */ ++ __u32 real_rootfs_length; + /* 236-239: CRC32 of header excluding last 20 bytes */ + __u32 header_crc; + /* 240-255: Unused at present */ +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -131,7 +131,8 @@ static int bcm63xx_parse_cfe_partitions( + } else { + /* OpenWrt layout */ + rootfsaddr = kerneladdr + kernellen; +- rootfslen = spareaddr - rootfsaddr; ++ rootfslen = buf->real_rootfs_length; ++ spareaddr = rootfsaddr + rootfslen; + } + } else { + pr_warn("CFE boot tag CRC invalid (expected %08x, actual %08x)\n", diff --git a/target/linux/brcm63xx/patches-3.3/406_bcm63xx_enet_vlan_incoming_fixed.patch b/target/linux/brcm63xx/patches-3.3/406_bcm63xx_enet_vlan_incoming_fixed.patch new file mode 100644 index 000000000..7d9f4a96d --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/406_bcm63xx_enet_vlan_incoming_fixed.patch @@ -0,0 +1,11 @@ +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -1515,7 +1515,7 @@ static int compute_hw_mtu(struct bcm_ene + actual_mtu = mtu; + + /* add ethernet header + vlan tag size */ +- actual_mtu += VLAN_ETH_HLEN; ++ actual_mtu += VLAN_ETH_HLEN + VLAN_HLEN; + + if (actual_mtu < 64 || actual_mtu > BCMENET_MAX_MTU) + return -EINVAL; diff --git a/target/linux/brcm63xx/patches-3.3/408-6358-enet1-external-mii-clk.patch b/target/linux/brcm63xx/patches-3.3/408-6358-enet1-external-mii-clk.patch new file mode 100644 index 000000000..3820e6323 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/408-6358-enet1-external-mii-clk.patch @@ -0,0 +1,22 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -855,6 +855,8 @@ void __init board_prom_init(void) + if (BCMCPU_IS_6348()) + val |= GPIO_MODE_6348_G3_EXT_MII | + GPIO_MODE_6348_G0_EXT_MII; ++ else if (BCMCPU_IS_6358()) ++ val |= GPIO_MODE_6358_ENET1_MII_CLK_INV; + } + + bcm_gpio_writel(val, GPIO_MODE_REG); +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -563,6 +563,8 @@ + #define GPIO_MODE_6358_EXTRA_SPI_SS (1 << 7) + #define GPIO_MODE_6358_SERIAL_LED (1 << 10) + #define GPIO_MODE_6358_UTOPIA (1 << 12) ++#define GPIO_MODE_6358_ENET1_MII_CLK_INV (1 << 30) ++#define GPIO_MODE_6358_ENET0_MII_CLK_INV (1 << 31) + + #define GPIO_MODE_6368_ANALOG_AFE_0 (1 << 0) + #define GPIO_MODE_6368_ANALOG_AFE_1 (1 << 1) diff --git a/target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch b/target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch new file mode 100644 index 000000000..2102db35e --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/410-NET-bcm63xx_enet-move-phy_-dis-connect-into-probe-re.patch @@ -0,0 +1,169 @@ +From b11218c750ab92cfab4408a0328f1b36ceec3f33 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Fri, 6 Jan 2012 12:24:18 +0100 +Subject: [PATCH 19/63] NET: bcm63xx_enet: move phy_(dis)connect into probe/remove + +Only connect/disconnect the phy during probe and remove, not during any +open/close. The phy seldom changes during the runtime, and disconnecting +the phy during close will prevent it from keeping any configuration over +a down/up cycle. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 84 +++++++++++++------------- + 1 files changed, 41 insertions(+), 43 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -784,10 +784,8 @@ static int bcm_enet_open(struct net_devi + struct bcm_enet_priv *priv; + struct sockaddr addr; + struct device *kdev; +- struct phy_device *phydev; + int i, ret; + unsigned int size; +- char phy_id[MII_BUS_ID_SIZE + 3]; + void *p; + u32 val; + +@@ -795,40 +793,10 @@ static int bcm_enet_open(struct net_devi + kdev = &priv->pdev->dev; + + if (priv->has_phy) { +- /* connect to PHY */ +- snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, +- priv->mii_bus->id, priv->phy_id); +- +- phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0, +- PHY_INTERFACE_MODE_MII); +- +- if (IS_ERR(phydev)) { +- dev_err(kdev, "could not attach to PHY\n"); +- return PTR_ERR(phydev); +- } +- +- /* mask with MAC supported features */ +- phydev->supported &= (SUPPORTED_10baseT_Half | +- SUPPORTED_10baseT_Full | +- SUPPORTED_100baseT_Half | +- SUPPORTED_100baseT_Full | +- SUPPORTED_Autoneg | +- SUPPORTED_Pause | +- SUPPORTED_MII); +- phydev->advertising = phydev->supported; +- +- if (priv->pause_auto && priv->pause_rx && priv->pause_tx) +- phydev->advertising |= SUPPORTED_Pause; +- else +- phydev->advertising &= ~SUPPORTED_Pause; +- +- dev_info(kdev, "attached PHY at address %d [%s]\n", +- phydev->addr, phydev->drv->name); +- ++ /* Reset state */ + priv->old_link = 0; + priv->old_duplex = -1; + priv->old_pause = -1; +- priv->phydev = phydev; + } + + /* mask all interrupts and request them */ +@@ -838,7 +806,7 @@ static int bcm_enet_open(struct net_devi + + ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev); + if (ret) +- goto out_phy_disconnect; ++ return ret; + + ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, IRQF_DISABLED, + dev->name, dev); +@@ -1025,9 +993,6 @@ out_freeirq_rx: + out_freeirq: + free_irq(dev->irq, dev); + +-out_phy_disconnect: +- phy_disconnect(priv->phydev); +- + return ret; + } + +@@ -1132,12 +1097,6 @@ static int bcm_enet_stop(struct net_devi + free_irq(priv->irq_rx, dev); + free_irq(dev->irq, dev); + +- /* release phy */ +- if (priv->has_phy) { +- phy_disconnect(priv->phydev); +- priv->phydev = NULL; +- } +- + return 0; + } + +@@ -1714,6 +1673,8 @@ static int __devinit bcm_enet_probe(stru + + /* MII bus registration */ + if (priv->has_phy) { ++ struct phy_device *phydev; ++ char phy_id[MII_BUS_ID_SIZE + 3]; + + priv->mii_bus = mdiobus_alloc(); + if (!priv->mii_bus) { +@@ -1750,6 +1711,38 @@ static int __devinit bcm_enet_probe(stru + dev_err(&pdev->dev, "unable to register mdio bus\n"); + goto out_free_mdio; + } ++ ++ /* connect to PHY */ ++ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, ++ priv->mii_bus->id, priv->phy_id); ++ ++ phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0, ++ PHY_INTERFACE_MODE_MII); ++ ++ if (IS_ERR(phydev)) { ++ dev_err(&pdev->dev, "could not attach to PHY\n"); ++ goto out_unregister_mdio; ++ } ++ ++ /* mask with MAC supported features */ ++ phydev->supported &= (SUPPORTED_10baseT_Half | ++ SUPPORTED_10baseT_Full | ++ SUPPORTED_100baseT_Half | ++ SUPPORTED_100baseT_Full | ++ SUPPORTED_Autoneg | ++ SUPPORTED_Pause | ++ SUPPORTED_MII); ++ phydev->advertising = phydev->supported; ++ ++ if (priv->pause_auto && priv->pause_rx && priv->pause_tx) ++ phydev->advertising |= SUPPORTED_Pause; ++ else ++ phydev->advertising &= ~SUPPORTED_Pause; ++ ++ dev_info(&pdev->dev, "attached PHY at address %d [%s]\n", ++ phydev->addr, phydev->drv->name); ++ ++ priv->phydev = phydev; + } else { + + /* run platform code to initialize PHY device */ +@@ -1795,6 +1788,9 @@ static int __devinit bcm_enet_probe(stru + return 0; + + out_unregister_mdio: ++ if (priv->phydev) ++ phy_disconnect(priv->phydev); ++ + if (priv->mii_bus) { + mdiobus_unregister(priv->mii_bus); + kfree(priv->mii_bus->irq); +@@ -1845,6 +1841,8 @@ static int __devexit bcm_enet_remove(str + enet_writel(priv, 0, ENET_MIISC_REG); + + if (priv->has_phy) { ++ phy_disconnect(priv->phydev); ++ priv->phydev = NULL; + mdiobus_unregister(priv->mii_bus); + kfree(priv->mii_bus->irq); + mdiobus_free(priv->mii_bus); diff --git a/target/linux/brcm63xx/patches-3.3/411-bcm63xx_enet-implement-reset_autoneg-ethtool.patch b/target/linux/brcm63xx/patches-3.3/411-bcm63xx_enet-implement-reset_autoneg-ethtool.patch new file mode 100644 index 000000000..d143b473d --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/411-bcm63xx_enet-implement-reset_autoneg-ethtool.patch @@ -0,0 +1,40 @@ +From accc558f334662c8b16c121b4819931c028e8eb0 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Mon, 8 Jun 2009 16:12:10 +0200 +Subject: [PATCH 27/63] bcm63xx_enet: implement reset_autoneg ethtool. + +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 15 +++++++++++++++ + 1 files changed, 15 insertions(+), 0 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -1290,6 +1290,20 @@ static void bcm_enet_get_ethtool_stats(s + mutex_unlock(&priv->mib_update_lock); + } + ++static int bcm_enet_nway_reset(struct net_device *dev) ++{ ++ struct bcm_enet_priv *priv; ++ ++ priv = netdev_priv(dev); ++ if (priv->has_phy) { ++ if (!priv->phydev) ++ return -ENODEV; ++ return genphy_restart_aneg(priv->phydev); ++ } ++ ++ return -EOPNOTSUPP; ++} ++ + static int bcm_enet_get_settings(struct net_device *dev, + struct ethtool_cmd *cmd) + { +@@ -1432,6 +1446,7 @@ static const struct ethtool_ops bcm_enet + .get_strings = bcm_enet_get_strings, + .get_sset_count = bcm_enet_get_sset_count, + .get_ethtool_stats = bcm_enet_get_ethtool_stats, ++ .nway_reset = bcm_enet_nway_reset, + .get_settings = bcm_enet_get_settings, + .set_settings = bcm_enet_set_settings, + .get_drvinfo = bcm_enet_get_drvinfo, diff --git a/target/linux/brcm63xx/patches-3.3/412-bcm63xx_enet-use-resource_size.patch b/target/linux/brcm63xx/patches-3.3/412-bcm63xx_enet-use-resource_size.patch new file mode 100644 index 000000000..11d035dd5 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/412-bcm63xx_enet-use-resource_size.patch @@ -0,0 +1,69 @@ +From dbd9b51204aa4114756b8659e180139ef3878032 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Thu, 21 Jan 2010 17:28:36 +0100 +Subject: [PATCH 28/63] bcm63xx_enet: use resource_size(). + +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 18 ++++++++---------- + 1 files changed, 8 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -1594,7 +1594,6 @@ static int __devinit bcm_enet_probe(stru + struct resource *res_mem, *res_irq, *res_irq_rx, *res_irq_tx; + struct mii_bus *bus; + const char *clk_name; +- unsigned int iomem_size; + int i, ret; + + /* stop if shared driver failed, assume driver->probe will be +@@ -1619,13 +1618,13 @@ static int __devinit bcm_enet_probe(stru + if (ret) + goto out; + +- iomem_size = resource_size(res_mem); +- if (!request_mem_region(res_mem->start, iomem_size, "bcm63xx_enet")) { ++ if (!request_mem_region(res_mem->start, resource_size(res_mem), ++ "bcm63xx_enet")) { + ret = -EBUSY; + goto out; + } + +- priv->base = ioremap(res_mem->start, iomem_size); ++ priv->base = ioremap(res_mem->start, resource_size(res_mem)); + if (priv->base == NULL) { + ret = -ENOMEM; + goto out_release_mem; +@@ -1831,7 +1830,7 @@ out_unmap: + iounmap(priv->base); + + out_release_mem: +- release_mem_region(res_mem->start, iomem_size); ++ release_mem_region(res_mem->start, resource_size(res_mem)); + out: + free_netdev(dev); + return ret; +@@ -1903,19 +1902,18 @@ struct platform_driver bcm63xx_enet_driv + static int __devinit bcm_enet_shared_probe(struct platform_device *pdev) + { + struct resource *res; +- unsigned int iomem_size; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + +- iomem_size = resource_size(res); +- if (!request_mem_region(res->start, iomem_size, "bcm63xx_enet_dma")) ++ if (!request_mem_region(res->start, resource_size(res), ++ "bcm63xx_enet_dma")) + return -EBUSY; + +- bcm_enet_shared_base = ioremap(res->start, iomem_size); ++ bcm_enet_shared_base = ioremap(res->start, resource_size(res)); + if (!bcm_enet_shared_base) { +- release_mem_region(res->start, iomem_size); ++ release_mem_region(res->start, resource_size(res)); + return -ENOMEM; + } + return 0; diff --git a/target/linux/brcm63xx/patches-3.3/413-bcm63xx_enet-disable-clock-when-uninitializing-devic.patch b/target/linux/brcm63xx/patches-3.3/413-bcm63xx_enet-disable-clock-when-uninitializing-devic.patch new file mode 100644 index 000000000..a98bea900 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/413-bcm63xx_enet-disable-clock-when-uninitializing-devic.patch @@ -0,0 +1,20 @@ +From fd15ecd10c95480be5635f8993b781fe3a1527c2 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Fri, 29 Apr 2011 16:54:50 +0200 +Subject: [PATCH 29/63] bcm63xx_enet: disable clock when uninitializing device. + +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -1870,6 +1870,8 @@ static int __devexit bcm_enet_remove(str + } + + /* release device resources */ ++ clk_disable(priv->mac_clk); ++ clk_put(priv->mac_clk); + iounmap(priv->base); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(res->start, resource_size(res)); diff --git a/target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch b/target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch new file mode 100644 index 000000000..90999fa95 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/414-bcm63xx_enet-split-dma-registers-access.patch @@ -0,0 +1,381 @@ +From 305579c1f946ed1aa6c125252ace21c53d47c11d Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Thu, 21 Jan 2010 17:50:54 +0100 +Subject: [PATCH 30/63] bcm63xx_enet: split dma registers access. + +--- + arch/mips/bcm63xx/dev-enet.c | 23 +++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 4 +- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 179 ++++++++++++++-------- + 3 files changed, 138 insertions(+), 68 deletions(-) + +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -19,6 +19,16 @@ static struct resource shared_res[] = { + .end = -1, /* filled at runtime */ + .flags = IORESOURCE_MEM, + }, ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, + }; + + static struct platform_device bcm63xx_enet_shared_device = { +@@ -110,10 +120,15 @@ int __init bcm63xx_enet_register(int uni + if (!shared_device_registered) { + shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA); + shared_res[0].end = shared_res[0].start; +- if (BCMCPU_IS_6338()) +- shared_res[0].end += (RSET_ENETDMA_SIZE / 2) - 1; +- else +- shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; ++ shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; ++ ++ shared_res[1].start = bcm63xx_regset_address(RSET_ENETDMAC); ++ shared_res[1].end = shared_res[1].start; ++ shared_res[1].end += RSET_ENETDMAC_SIZE(16) - 1; ++ ++ shared_res[2].start = bcm63xx_regset_address(RSET_ENETDMAS); ++ shared_res[2].end = shared_res[2].start; ++ shared_res[2].end += RSET_ENETDMAS_SIZE(16) - 1; + + ret = platform_device_register(&bcm63xx_enet_shared_device); + if (ret) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +@@ -172,7 +172,9 @@ enum bcm63xx_regs_set { + #define BCM_6358_RSET_SPI_SIZE 1804 + #define BCM_6368_RSET_SPI_SIZE 1804 + #define RSET_ENET_SIZE 2048 +-#define RSET_ENETDMA_SIZE 2048 ++#define RSET_ENETDMA_SIZE 256 ++#define RSET_ENETDMAC_SIZE(chans) (16 * (chans)) ++#define RSET_ENETDMAS_SIZE(chans) (16 * (chans)) + #define RSET_ENETSW_SIZE 65536 + #define RSET_UART_SIZE 24 + #define RSET_HSSPI_SIZE 1536 +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -41,8 +41,8 @@ static int copybreak __read_mostly = 128 + module_param(copybreak, int, 0); + MODULE_PARM_DESC(copybreak, "Receive copy threshold"); + +-/* io memory shared between all devices */ +-static void __iomem *bcm_enet_shared_base; ++/* io registers memory shared between all devices */ ++static void __iomem *bcm_enet_shared_base[3]; + + /* + * io helpers to access mac registers +@@ -63,13 +63,35 @@ static inline void enet_writel(struct bc + */ + static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off) + { +- return bcm_readl(bcm_enet_shared_base + off); ++ return bcm_readl(bcm_enet_shared_base[0] + off); + } + + static inline void enet_dma_writel(struct bcm_enet_priv *priv, + u32 val, u32 off) + { +- bcm_writel(val, bcm_enet_shared_base + off); ++ bcm_writel(val, bcm_enet_shared_base[0] + off); ++} ++ ++static inline u32 enet_dmac_readl(struct bcm_enet_priv *priv, u32 off) ++{ ++ return bcm_readl(bcm_enet_shared_base[1] + off); ++} ++ ++static inline void enet_dmac_writel(struct bcm_enet_priv *priv, ++ u32 val, u32 off) ++{ ++ bcm_writel(val, bcm_enet_shared_base[1] + off); ++} ++ ++static inline u32 enet_dmas_readl(struct bcm_enet_priv *priv, u32 off) ++{ ++ return bcm_readl(bcm_enet_shared_base[2] + off); ++} ++ ++static inline void enet_dmas_writel(struct bcm_enet_priv *priv, ++ u32 val, u32 off) ++{ ++ bcm_writel(val, bcm_enet_shared_base[2] + off); + } + + /* +@@ -353,8 +375,8 @@ static int bcm_enet_receive_queue(struct + bcm_enet_refill_rx(dev); + + /* kick rx dma */ +- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, +- ENETDMA_CHANCFG_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK, ++ ENETDMAC_CHANCFG_REG(priv->rx_chan)); + } + + return processed; +@@ -429,10 +451,10 @@ static int bcm_enet_poll(struct napi_str + dev = priv->net_dev; + + /* ack interrupts */ +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IR_REG(priv->rx_chan)); +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IR_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->tx_chan)); + + /* reclaim sent skb */ + tx_work_done = bcm_enet_tx_reclaim(dev, 0); +@@ -451,10 +473,10 @@ static int bcm_enet_poll(struct napi_str + napi_complete(napi); + + /* restore rx/tx interrupt */ +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->tx_chan)); + + return rx_work_done; + } +@@ -497,8 +519,8 @@ static irqreturn_t bcm_enet_isr_dma(int + priv = netdev_priv(dev); + + /* mask rx/tx interrupts */ +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan)); + + napi_schedule(&priv->napi); + +@@ -557,8 +579,8 @@ static int bcm_enet_start_xmit(struct sk + wmb(); + + /* kick tx dma */ +- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, +- ENETDMA_CHANCFG_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK, ++ ENETDMAC_CHANCFG_REG(priv->tx_chan)); + + /* stop queue if no more desc available */ + if (!priv->tx_desc_count) +@@ -801,8 +823,8 @@ static int bcm_enet_open(struct net_devi + + /* mask all interrupts and request them */ + enet_writel(priv, 0, ENET_IRMASK_REG); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan)); + + ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev); + if (ret) +@@ -891,28 +913,28 @@ static int bcm_enet_open(struct net_devi + } + + /* write rx & tx ring addresses */ +- enet_dma_writel(priv, priv->rx_desc_dma, +- ENETDMA_RSTART_REG(priv->rx_chan)); +- enet_dma_writel(priv, priv->tx_desc_dma, +- ENETDMA_RSTART_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, priv->rx_desc_dma, ++ ENETDMAS_RSTART_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, priv->tx_desc_dma, ++ ENETDMAS_RSTART_REG(priv->tx_chan)); + + /* clear remaining state ram for rx & tx channel */ +- enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM2_REG(priv->tx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM3_REG(priv->tx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_SRAM4_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->tx_chan)); + + /* set max rx/tx length */ + enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG); + enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG); + + /* set dma maximum burst len */ +- enet_dma_writel(priv, BCMENET_DMA_MAXBURST, +- ENETDMA_MAXBURST_REG(priv->rx_chan)); +- enet_dma_writel(priv, BCMENET_DMA_MAXBURST, +- ENETDMA_MAXBURST_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ ENETDMAC_MAXBURST_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ ENETDMAC_MAXBURST_REG(priv->tx_chan)); + + /* set correct transmit fifo watermark */ + enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG); +@@ -930,26 +952,26 @@ static int bcm_enet_open(struct net_devi + val |= ENET_CTL_ENABLE_MASK; + enet_writel(priv, val, ENET_CTL_REG); + enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); +- enet_dma_writel(priv, ENETDMA_CHANCFG_EN_MASK, +- ENETDMA_CHANCFG_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK, ++ ENETDMAC_CHANCFG_REG(priv->rx_chan)); + + /* watch "mib counters about to overflow" interrupt */ + enet_writel(priv, ENET_IR_MIB, ENET_IR_REG); + enet_writel(priv, ENET_IR_MIB, ENET_IRMASK_REG); + + /* watch "packet transferred" interrupt in rx and tx */ +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IR_REG(priv->rx_chan)); +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IR_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->tx_chan)); + + /* make sure we enable napi before rx interrupt */ + napi_enable(&priv->napi); + +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, ENETDMA_IR_PKTDONE_MASK, +- ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->tx_chan)); + + if (priv->has_phy) + phy_start(priv->phydev); +@@ -1026,14 +1048,14 @@ static void bcm_enet_disable_dma(struct + { + int limit; + +- enet_dma_writel(priv, 0, ENETDMA_CHANCFG_REG(chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_CHANCFG_REG(chan)); + + limit = 1000; + do { + u32 val; + +- val = enet_dma_readl(priv, ENETDMA_CHANCFG_REG(chan)); +- if (!(val & ENETDMA_CHANCFG_EN_MASK)) ++ val = enet_dmac_readl(priv, ENETDMAC_CHANCFG_REG(chan)); ++ if (!(val & ENETDMAC_CHANCFG_EN_MASK)) + break; + udelay(1); + } while (limit--); +@@ -1059,8 +1081,8 @@ static int bcm_enet_stop(struct net_devi + + /* mask all interrupts */ + enet_writel(priv, 0, ENET_IRMASK_REG); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->rx_chan)); +- enet_dma_writel(priv, 0, ENETDMA_IRMASK_REG(priv->tx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan)); + + /* make sure no mib update is scheduled */ + cancel_work_sync(&priv->mib_update_task); +@@ -1598,7 +1620,7 @@ static int __devinit bcm_enet_probe(stru + + /* stop if shared driver failed, assume driver->probe will be + * called in the same order we register devices (correct ?) */ +- if (!bcm_enet_shared_base) ++ if (!bcm_enet_shared_base[0]) + return -ENODEV; + + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); +@@ -1904,30 +1926,61 @@ struct platform_driver bcm63xx_enet_driv + static int __devinit bcm_enet_shared_probe(struct platform_device *pdev) + { + struct resource *res; ++ int ret, i, requested[3]; + +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- if (!res) +- return -ENODEV; ++ memset(bcm_enet_shared_base, 0, sizeof (bcm_enet_shared_base)); ++ memset(requested, 0, sizeof (requested)); + +- if (!request_mem_region(res->start, resource_size(res), +- "bcm63xx_enet_dma")) +- return -EBUSY; ++ for (i = 0; i < 3; i++) { ++ void __iomem *p; + +- bcm_enet_shared_base = ioremap(res->start, resource_size(res)); +- if (!bcm_enet_shared_base) { +- release_mem_region(res->start, resource_size(res)); +- return -ENOMEM; ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ if (!res) { ++ ret = -EINVAL; ++ goto fail; ++ } ++ ++ if (!request_mem_region(res->start, resource_size(res), ++ "bcm63xx_enet_dma")) { ++ ret = -EBUSY; ++ goto fail; ++ } ++ requested[i] = 0; ++ ++ p = ioremap(res->start, resource_size(res)); ++ if (!p) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ ++ bcm_enet_shared_base[i] = p; + } ++ + return 0; ++ ++fail: ++ for (i = 0; i < 3; i++) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ if (!res) ++ continue; ++ if (bcm_enet_shared_base[i]) ++ iounmap(bcm_enet_shared_base[i]); ++ if (requested[i]) ++ release_mem_region(res->start, resource_size(res)); ++ } ++ return ret; + } + + static int __devexit bcm_enet_shared_remove(struct platform_device *pdev) + { + struct resource *res; ++ int i; + +- iounmap(bcm_enet_shared_base); +- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); +- release_mem_region(res->start, resource_size(res)); ++ for (i = 0; i < 3; i++) { ++ iounmap(bcm_enet_shared_base[i]); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ release_mem_region(res->start, resource_size(res)); ++ } + return 0; + } + diff --git a/target/linux/brcm63xx/patches-3.3/415-bcm63xx_enet-add-support-for-bcm6368-internal-ethern.patch b/target/linux/brcm63xx/patches-3.3/415-bcm63xx_enet-add-support-for-bcm6368-internal-ethern.patch new file mode 100644 index 000000000..67bf01a3f --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/415-bcm63xx_enet-add-support-for-bcm6368-internal-ethern.patch @@ -0,0 +1,1490 @@ +From 1324bb5db6815d19b09c1b7bcac3cc2804412205 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Sat, 23 Jan 2010 03:01:02 +0100 +Subject: [PATCH 31/63] bcm63xx_enet: add support for bcm6368 internal ethernet switch. + +--- + arch/mips/bcm63xx/dev-enet.c | 106 ++- + .../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 25 + + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 50 + + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 1054 ++++++++++++++++++-- + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 71 ++ + 5 files changed, 1221 insertions(+), 85 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -920,6 +920,10 @@ int __init board_register_devices(void) + !board_get_mac_address(board.enet1.mac_addr)) + bcm63xx_enet_register(1, &board.enet1); + ++ if (board.has_enetsw && ++ !board_get_mac_address(board.enetsw.mac_addr)) ++ bcm63xx_enetsw_register(&board.enetsw); ++ + if (board.has_ehci0) + bcm63xx_ehci_register(); + +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -41,6 +41,7 @@ struct board_info { + /* enabled feature/device */ + unsigned int has_enet0:1; + unsigned int has_enet1:1; ++ unsigned int has_enetsw:1; + unsigned int has_pci:1; + unsigned int has_pccard:1; + unsigned int has_ohci0:1; +@@ -52,6 +53,7 @@ struct board_info { + /* ethernet config */ + struct bcm63xx_enet_platform_data enet0; + struct bcm63xx_enet_platform_data enet1; ++ struct bcm63xx_enetsw_platform_data enetsw; + + /* DSP config */ + struct bcm63xx_dsp_platform_data dsp; +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -104,6 +104,64 @@ static struct platform_device bcm63xx_en + }, + }; + ++static struct resource enetsw_res[] = { ++ { ++ /* start & end filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ /* start filled at runtime */ ++ .flags = IORESOURCE_IRQ, ++ }, ++ { ++ /* start filled at runtime */ ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct bcm63xx_enetsw_platform_data enetsw_pd; ++ ++static struct platform_device bcm63xx_enetsw_device = { ++ .name = "bcm63xx_enetsw", ++ .num_resources = ARRAY_SIZE(enetsw_res), ++ .resource = enetsw_res, ++ .dev = { ++ .platform_data = &enetsw_pd, ++ }, ++}; ++ ++static int __init register_shared(void) ++{ ++ int ret, chan_count; ++ ++ if (shared_device_registered) ++ return 0; ++ ++ shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA); ++ shared_res[0].end = shared_res[0].start; ++ shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; ++ ++ if (BCMCPU_IS_6368()) ++ chan_count = 32; ++ else ++ chan_count = 16; ++ ++ shared_res[1].start = bcm63xx_regset_address(RSET_ENETDMAC); ++ shared_res[1].end = shared_res[1].start; ++ shared_res[1].end += RSET_ENETDMAC_SIZE(chan_count) - 1; ++ ++ shared_res[2].start = bcm63xx_regset_address(RSET_ENETDMAS); ++ shared_res[2].end = shared_res[2].start; ++ shared_res[2].end += RSET_ENETDMAS_SIZE(chan_count) - 1; ++ ++ ret = platform_device_register(&bcm63xx_enet_shared_device); ++ if (ret) ++ return ret; ++ shared_device_registered = 1; ++ ++ return 0; ++} ++ + int __init bcm63xx_enet_register(int unit, + const struct bcm63xx_enet_platform_data *pd) + { +@@ -117,24 +175,9 @@ int __init bcm63xx_enet_register(int uni + if (unit == 1 && BCMCPU_IS_6338()) + return -ENODEV; + +- if (!shared_device_registered) { +- shared_res[0].start = bcm63xx_regset_address(RSET_ENETDMA); +- shared_res[0].end = shared_res[0].start; +- shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; +- +- shared_res[1].start = bcm63xx_regset_address(RSET_ENETDMAC); +- shared_res[1].end = shared_res[1].start; +- shared_res[1].end += RSET_ENETDMAC_SIZE(16) - 1; +- +- shared_res[2].start = bcm63xx_regset_address(RSET_ENETDMAS); +- shared_res[2].end = shared_res[2].start; +- shared_res[2].end += RSET_ENETDMAS_SIZE(16) - 1; +- +- ret = platform_device_register(&bcm63xx_enet_shared_device); +- if (ret) +- return ret; +- shared_device_registered = 1; +- } ++ ret = register_shared(); ++ if (ret) ++ return ret; + + if (unit == 0) { + enet0_res[0].start = bcm63xx_regset_address(RSET_ENET0); +@@ -175,3 +218,30 @@ int __init bcm63xx_enet_register(int uni + return ret; + return 0; + } ++ ++int __init ++bcm63xx_enetsw_register(const struct bcm63xx_enetsw_platform_data *pd) ++{ ++ int ret; ++ ++ if (!BCMCPU_IS_6368()) ++ return -ENODEV; ++ ++ ret = register_shared(); ++ if (ret) ++ return ret; ++ ++ enetsw_res[0].start = bcm63xx_regset_address(RSET_ENETSW); ++ enetsw_res[0].end = enetsw_res[0].start; ++ enetsw_res[0].end += RSET_ENETSW_SIZE - 1; ++ enetsw_res[1].start = bcm63xx_get_irq_number(IRQ_ENETSW_RXDMA0); ++ enetsw_res[2].start = bcm63xx_get_irq_number(IRQ_ENETSW_TXDMA0); ++ ++ memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof (*pd)); ++ ++ ret = platform_device_register(&bcm63xx_enetsw_device); ++ if (ret) ++ return ret; ++ ++ return 0; ++} +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +@@ -39,7 +39,32 @@ struct bcm63xx_enet_platform_data { + int phy_id, int reg, int val)); + }; + ++/* ++ * on board ethernet switch platform data ++ */ ++#define ENETSW_MAX_PORT 6 ++ ++struct bcm63xx_enetsw_port { ++ int used; ++ int external_phy; ++ int phy_id; ++ ++ int bypass_link; ++ int force_speed; ++ int force_duplex_full; ++ ++ const char *name; ++}; ++ ++struct bcm63xx_enetsw_platform_data { ++ char mac_addr[ETH_ALEN]; ++ struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; ++}; ++ + int __init bcm63xx_enet_register(int unit, + const struct bcm63xx_enet_platform_data *pd); + ++int __init ++bcm63xx_enetsw_register(const struct bcm63xx_enetsw_platform_data *pd); ++ + #endif /* ! BCM63XX_DEV_ENET_H_ */ +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -809,10 +809,60 @@ + * _REG relative to RSET_ENETSW + *************************************************************************/ + ++/* Port traffic control */ ++#define ENETSW_PTCTRL_REG(x) (0x0 + (x)) ++#define ENETSW_PTCTRL_RXDIS_MASK (1 << 0) ++#define ENETSW_PTCTRL_TXDIS_MASK (1 << 1) ++ ++/* Switch mode register */ ++#define ENETSW_SWMODE_REG (0xb) ++#define ENETSW_SWMODE_FWD_EN_MASK (1 << 1) ++ ++/* IMP override Register */ ++#define ENETSW_IMPOV_REG (0xe) ++#define ENETSW_IMPOV_FORCE_MASK (1 << 7) ++#define ENETSW_IMPOV_TXFLOW_MASK (1 << 5) ++#define ENETSW_IMPOV_RXFLOW_MASK (1 << 4) ++#define ENETSW_IMPOV_1000_MASK (1 << 3) ++#define ENETSW_IMPOV_100_MASK (1 << 2) ++#define ENETSW_IMPOV_FDX_MASK (1 << 1) ++#define ENETSW_IMPOV_LINKUP_MASK (1 << 0) ++ ++/* Port override Register */ ++#define ENETSW_PORTOV_REG(x) (0x58 + (x)) ++#define ENETSW_PORTOV_ENABLE_MASK (1 << 6) ++#define ENETSW_PORTOV_TXFLOW_MASK (1 << 5) ++#define ENETSW_PORTOV_RXFLOW_MASK (1 << 4) ++#define ENETSW_PORTOV_1000_MASK (1 << 3) ++#define ENETSW_PORTOV_100_MASK (1 << 2) ++#define ENETSW_PORTOV_FDX_MASK (1 << 1) ++#define ENETSW_PORTOV_LINKUP_MASK (1 << 0) ++ ++/* MDIO control register */ ++#define ENETSW_MDIOC_REG (0xb0) ++#define ENETSW_MDIOC_EXT_MASK (1 << 16) ++#define ENETSW_MDIOC_REG_SHIFT 20 ++#define ENETSW_MDIOC_PHYID_SHIFT 25 ++#define ENETSW_MDIOC_RD_MASK (1 << 30) ++#define ENETSW_MDIOC_WR_MASK (1 << 31) ++ ++/* MDIO data register */ ++#define ENETSW_MDIOD_REG (0xb4) ++ ++/* Global Management Configuration Register */ ++#define ENETSW_GMCR_REG (0x200) ++#define ENETSW_GMCR_RST_MIB_MASK (1 << 0) ++ + /* MIB register */ + #define ENETSW_MIB_REG(x) (0x2800 + (x) * 4) + #define ENETSW_MIB_REG_COUNT 47 + ++/* Jumbo control register port mask register */ ++#define ENETSW_JMBCTL_PORT_REG (0x4004) ++ ++/* Jumbo control mib good frame register */ ++#define ENETSW_JMBCTL_MAXSIZE_REG (0x4008) ++ + + /************************************************************************* + * _REG relative to RSET_OHCI_PRIV +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -59,6 +59,49 @@ static inline void enet_writel(struct bc + } + + /* ++ * io helpers to access switch registers ++ */ ++static inline u32 enetsw_readl(struct bcm_enet_priv *priv, u32 off) ++{ ++ /* printk("enetsw_readl at %p\n", priv->base + off); */ ++ return bcm_readl(priv->base + off); ++} ++ ++static inline void enetsw_writel(struct bcm_enet_priv *priv, ++ u32 val, u32 off) ++{ ++ /* printk("enetsw_writel %08x at %p\n", val, priv->base + off); */ ++ bcm_writel(val, priv->base + off); ++} ++ ++static inline u16 enetsw_readw(struct bcm_enet_priv *priv, u32 off) ++{ ++ /* printk("enetsw_readw at %p\n", priv->base + off); */ ++ return bcm_readw(priv->base + off); ++} ++ ++static inline void enetsw_writew(struct bcm_enet_priv *priv, ++ u16 val, u32 off) ++{ ++ /* printk("enetsw_writew %04x at %p\n", val, priv->base + off); */ ++ bcm_writew(val, priv->base + off); ++} ++ ++static inline u8 enetsw_readb(struct bcm_enet_priv *priv, u32 off) ++{ ++ /* printk("enetsw_readb at %p\n", priv->base + off); */ ++ return bcm_readb(priv->base + off); ++} ++ ++static inline void enetsw_writeb(struct bcm_enet_priv *priv, ++ u8 val, u32 off) ++{ ++ /* printk("enetsw_writeb %02x at %p\n", val, priv->base + off); */ ++ bcm_writeb(val, priv->base + off); ++} ++ ++ ++/* + * io helpers to access shared registers + */ + static inline u32 enet_dma_readl(struct bcm_enet_priv *priv, u32 off) +@@ -321,7 +364,8 @@ static int bcm_enet_receive_queue(struct + } + + /* recycle packet if it's marked as bad */ +- if (unlikely(len_stat & DMADESC_ERR_MASK)) { ++ if (!bcm_enet_is_sw(priv) && ++ unlikely(len_stat & DMADESC_ERR_MASK)) { + dev->stats.rx_errors++; + + if (len_stat & DMADESC_OVSIZE_MASK) +@@ -552,6 +596,26 @@ static int bcm_enet_start_xmit(struct sk + goto out_unlock; + } + ++ /* pad small packets sent on a switch device */ ++ if (bcm_enet_is_sw(priv) && skb->len < 64) { ++ int needed = 64 - skb->len; ++ char *data; ++ ++ if (unlikely(skb_tailroom(skb) < needed)) { ++ struct sk_buff *nskb; ++ ++ nskb = skb_copy_expand(skb, 0, needed, GFP_ATOMIC); ++ if (!nskb) { ++ ret = NETDEV_TX_BUSY; ++ goto out_unlock; ++ } ++ dev_kfree_skb(skb); ++ skb = nskb; ++ } ++ data = skb_put(skb, needed); ++ memset(data, 0, needed); ++ } ++ + /* point to the next available desc */ + desc = &priv->tx_desc_cpu[priv->tx_curr_desc]; + priv->tx_skb[priv->tx_curr_desc] = skb; +@@ -1921,96 +1985,951 @@ struct platform_driver bcm63xx_enet_driv + }; + + /* +- * reserve & remap memory space shared between all macs ++ * switch mii access callbacks + */ +-static int __devinit bcm_enet_shared_probe(struct platform_device *pdev) ++static int bcmenet_sw_mdio_read(struct bcm_enet_priv *priv, ++ int ext, int phy_id, int location) + { +- struct resource *res; +- int ret, i, requested[3]; ++ u32 reg; ++ int ret; + +- memset(bcm_enet_shared_base, 0, sizeof (bcm_enet_shared_base)); +- memset(requested, 0, sizeof (requested)); ++ spin_lock_bh(&priv->enetsw_mdio_lock); ++ enetsw_writel(priv, 0, ENETSW_MDIOC_REG); + +- for (i = 0; i < 3; i++) { +- void __iomem *p; ++ reg = ENETSW_MDIOC_RD_MASK | ++ (phy_id << ENETSW_MDIOC_PHYID_SHIFT) | ++ (location << ENETSW_MDIOC_REG_SHIFT); ++ ++ if (ext) ++ reg |= ENETSW_MDIOC_EXT_MASK; ++ ++ enetsw_writel(priv, reg, ENETSW_MDIOC_REG); ++ udelay(50); ++ ret = enetsw_readw(priv, ENETSW_MDIOD_REG); ++ spin_unlock_bh(&priv->enetsw_mdio_lock); ++ return ret; ++} + +- res = platform_get_resource(pdev, IORESOURCE_MEM, i); +- if (!res) { +- ret = -EINVAL; +- goto fail; +- } ++static void bcmenet_sw_mdio_write(struct bcm_enet_priv *priv, ++ int ext, int phy_id, int location, ++ uint16_t data) ++{ ++ u32 reg; + +- if (!request_mem_region(res->start, resource_size(res), +- "bcm63xx_enet_dma")) { +- ret = -EBUSY; +- goto fail; +- } +- requested[i] = 0; ++ spin_lock_bh(&priv->enetsw_mdio_lock); ++ enetsw_writel(priv, 0, ENETSW_MDIOC_REG); + +- p = ioremap(res->start, resource_size(res)); +- if (!p) { +- ret = -ENOMEM; +- goto fail; +- } ++ reg = ENETSW_MDIOC_WR_MASK | ++ (phy_id << ENETSW_MDIOC_PHYID_SHIFT) | ++ (location << ENETSW_MDIOC_REG_SHIFT); + +- bcm_enet_shared_base[i] = p; +- } ++ if (ext) ++ reg |= ENETSW_MDIOC_EXT_MASK; + +- return 0; ++ reg |= data; + +-fail: +- for (i = 0; i < 3; i++) { +- res = platform_get_resource(pdev, IORESOURCE_MEM, i); +- if (!res) +- continue; +- if (bcm_enet_shared_base[i]) +- iounmap(bcm_enet_shared_base[i]); +- if (requested[i]) +- release_mem_region(res->start, resource_size(res)); +- } +- return ret; ++ enetsw_writel(priv, reg, ENETSW_MDIOC_REG); ++ udelay(50); ++ spin_unlock_bh(&priv->enetsw_mdio_lock); + } + +-static int __devexit bcm_enet_shared_remove(struct platform_device *pdev) ++/* ++ * enet sw PHY polling ++ */ ++static void swphy_poll_timer(unsigned long data) + { +- struct resource *res; +- int i; ++ struct bcm_enet_priv *priv = (struct bcm_enet_priv *)data; ++ unsigned int i; + +- for (i = 0; i < 3; i++) { +- iounmap(bcm_enet_shared_base[i]); +- res = platform_get_resource(pdev, IORESOURCE_MEM, i); +- release_mem_region(res->start, resource_size(res)); ++ for (i = 0; i < ARRAY_SIZE(priv->used_ports); i++) { ++ struct bcm63xx_enetsw_port *port; ++ int val, j, up, advertise, lpa, lpa2, speed, duplex, media; ++ u8 override; ++ ++ port = &priv->used_ports[i]; ++ if (!port->used) ++ continue; ++ ++ if (port->bypass_link) ++ continue; ++ ++ /* dummy read to clear */ ++ for (j = 0; j < 2; j++) ++ val = bcmenet_sw_mdio_read(priv, port->external_phy, ++ port->phy_id, MII_BMSR); ++ ++ if (val == 0xffff) ++ continue; ++ ++ up = (val & BMSR_LSTATUS) ? 1 : 0; ++ if (!(up ^ priv->sw_port_link[i])) ++ continue; ++ ++ priv->sw_port_link[i] = up; ++ ++ /* link changed */ ++ if (!up) { ++ dev_info(&priv->pdev->dev, "link DOWN on %s\n", ++ port->name); ++ enetsw_writeb(priv, ENETSW_PORTOV_ENABLE_MASK, ++ ENETSW_PORTOV_REG(i)); ++ enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK | ++ ENETSW_PTCTRL_TXDIS_MASK, ++ ENETSW_PTCTRL_REG(i)); ++ continue; ++ } ++ ++ advertise = bcmenet_sw_mdio_read(priv, port->external_phy, ++ port->phy_id, MII_ADVERTISE); ++ ++ lpa = bcmenet_sw_mdio_read(priv, port->external_phy, ++ port->phy_id, MII_LPA); ++ ++ lpa2 = bcmenet_sw_mdio_read(priv, port->external_phy, ++ port->phy_id, MII_STAT1000); ++ ++ /* figure out media and duplex from advertise and LPA values */ ++ media = mii_nway_result(lpa & advertise); ++ duplex = (media & ADVERTISE_FULL) ? 1 : 0; ++ if (lpa2 & LPA_1000FULL) ++ duplex = 1; ++ ++ if (lpa2 & (LPA_1000FULL | LPA_1000HALF)) ++ speed = 1000; ++ else { ++ if (media & (ADVERTISE_100FULL | ADVERTISE_100HALF)) ++ speed = 100; ++ else ++ speed = 10; ++ } ++ ++ dev_info(&priv->pdev->dev, ++ "link UP on %s, %dMbps, %s-duplex\n", ++ port->name, speed, duplex ? "full" : "half"); ++ ++ override = ENETSW_PORTOV_ENABLE_MASK | ++ ENETSW_PORTOV_LINKUP_MASK; ++ ++ if (speed == 1000) ++ override |= ENETSW_IMPOV_1000_MASK; ++ else if (speed == 100) ++ override |= ENETSW_IMPOV_100_MASK; ++ if (duplex) ++ override |= ENETSW_IMPOV_FDX_MASK; ++ ++ enetsw_writeb(priv, override, ENETSW_PORTOV_REG(i)); ++ enetsw_writeb(priv, 0, ENETSW_PTCTRL_REG(i)); + } +- return 0; +-} + +-/* +- * this "shared" driver is needed because both macs share a single +- * address space +- */ +-struct platform_driver bcm63xx_enet_shared_driver = { +- .probe = bcm_enet_shared_probe, +- .remove = __devexit_p(bcm_enet_shared_remove), +- .driver = { +- .name = "bcm63xx_enet_shared", +- .owner = THIS_MODULE, +- }, +-}; ++ priv->swphy_poll.expires = jiffies + HZ; ++ add_timer(&priv->swphy_poll); ++} + + /* +- * entry point ++ * open callback, allocate dma rings & buffers and start rx operation + */ +-static int __init bcm_enet_init(void) ++static int bcm_enetsw_open(struct net_device *dev) + { +- int ret; ++ struct bcm_enet_priv *priv; ++ struct device *kdev; ++ int i, ret; ++ unsigned int size; ++ void *p; ++ u32 val; + +- ret = platform_driver_register(&bcm63xx_enet_shared_driver); ++ priv = netdev_priv(dev); ++ kdev = &priv->pdev->dev; ++ ++ /* mask all interrupts and request them */ ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan)); ++ ++ ret = request_irq(priv->irq_rx, bcm_enet_isr_dma, ++ IRQF_DISABLED, dev->name, dev); + if (ret) +- return ret; ++ goto out_freeirq; + +- ret = platform_driver_register(&bcm63xx_enet_driver); ++ ret = request_irq(priv->irq_tx, bcm_enet_isr_dma, ++ IRQF_DISABLED, dev->name, dev); + if (ret) +- platform_driver_unregister(&bcm63xx_enet_shared_driver); ++ goto out_freeirq_rx; ++ ++ /* allocate rx dma ring */ ++ size = priv->rx_ring_size * sizeof(struct bcm_enet_desc); ++ p = dma_alloc_coherent(kdev, size, &priv->rx_desc_dma, GFP_KERNEL); ++ if (!p) { ++ dev_err(kdev, "cannot allocate rx ring %u\n", size); ++ ret = -ENOMEM; ++ goto out_freeirq_tx; ++ } ++ ++ memset(p, 0, size); ++ priv->rx_desc_alloc_size = size; ++ priv->rx_desc_cpu = p; ++ ++ /* allocate tx dma ring */ ++ size = priv->tx_ring_size * sizeof(struct bcm_enet_desc); ++ p = dma_alloc_coherent(kdev, size, &priv->tx_desc_dma, GFP_KERNEL); ++ if (!p) { ++ dev_err(kdev, "cannot allocate tx ring\n"); ++ ret = -ENOMEM; ++ goto out_free_rx_ring; ++ } ++ ++ memset(p, 0, size); ++ priv->tx_desc_alloc_size = size; ++ priv->tx_desc_cpu = p; ++ ++ priv->tx_skb = kzalloc(sizeof(struct sk_buff *) * priv->tx_ring_size, ++ GFP_KERNEL); ++ if (!priv->tx_skb) { ++ dev_err(kdev, "cannot allocate rx skb queue\n"); ++ ret = -ENOMEM; ++ goto out_free_tx_ring; ++ } ++ ++ priv->tx_desc_count = priv->tx_ring_size; ++ priv->tx_dirty_desc = 0; ++ priv->tx_curr_desc = 0; ++ spin_lock_init(&priv->tx_lock); ++ ++ /* init & fill rx ring with skbs */ ++ priv->rx_skb = kzalloc(sizeof(struct sk_buff *) * priv->rx_ring_size, ++ GFP_KERNEL); ++ if (!priv->rx_skb) { ++ dev_err(kdev, "cannot allocate rx skb queue\n"); ++ ret = -ENOMEM; ++ goto out_free_tx_skb; ++ } ++ ++ priv->rx_desc_count = 0; ++ priv->rx_dirty_desc = 0; ++ priv->rx_curr_desc = 0; ++ ++ /* disable all ports */ ++ for (i = 0; i < 6; i++) { ++ enetsw_writeb(priv, ENETSW_PORTOV_ENABLE_MASK, ++ ENETSW_PORTOV_REG(i)); ++ enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK | ++ ENETSW_PTCTRL_TXDIS_MASK, ++ ENETSW_PTCTRL_REG(i)); ++ } ++ ++ /* reset mib */ ++ val = enetsw_readb(priv, ENETSW_GMCR_REG); ++ val |= ENETSW_GMCR_RST_MIB_MASK; ++ enetsw_writeb(priv, val, ENETSW_GMCR_REG); ++ mdelay(1); ++ val &= ~ENETSW_GMCR_RST_MIB_MASK; ++ enetsw_writeb(priv, val, ENETSW_GMCR_REG); ++ mdelay(1); ++ ++ /* force CPU port state */ ++ val = enetsw_readb(priv, ENETSW_IMPOV_REG); ++ val |= ENETSW_IMPOV_FORCE_MASK | ENETSW_IMPOV_LINKUP_MASK; ++ enetsw_writeb(priv, val, ENETSW_IMPOV_REG); ++ ++ /* enable switch forward engine */ ++ val = enetsw_readb(priv, ENETSW_SWMODE_REG); ++ val |= ENETSW_SWMODE_FWD_EN_MASK; ++ enetsw_writeb(priv, val, ENETSW_SWMODE_REG); ++ ++ /* enable jumbo on all ports */ ++ enetsw_writel(priv, 0x1ff, ENETSW_JMBCTL_PORT_REG); ++ enetsw_writew(priv, 9728, ENETSW_JMBCTL_MAXSIZE_REG); ++ ++ /* initialize flow control buffer allocation */ ++ enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0, ++ ENETDMA_BUFALLOC_REG(priv->rx_chan)); ++ ++ if (bcm_enet_refill_rx(dev)) { ++ dev_err(kdev, "cannot allocate rx skb queue\n"); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ /* write rx & tx ring addresses */ ++ enet_dmas_writel(priv, priv->rx_desc_dma, ++ ENETDMAS_RSTART_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, priv->tx_desc_dma, ++ ENETDMAS_RSTART_REG(priv->tx_chan)); ++ ++ /* clear remaining state ram for rx & tx channel */ ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM2_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM3_REG(priv->tx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->rx_chan)); ++ enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->tx_chan)); ++ ++ /* set dma maximum burst len */ ++ enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ ENETDMAC_MAXBURST_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ ENETDMAC_MAXBURST_REG(priv->tx_chan)); ++ ++ /* set flow control low/high threshold to 1/3 / 2/3 */ ++ val = priv->rx_ring_size / 3; ++ enet_dma_writel(priv, val, ENETDMA_FLOWCL_REG(priv->rx_chan)); ++ val = (priv->rx_ring_size * 2) / 3; ++ enet_dma_writel(priv, val, ENETDMA_FLOWCH_REG(priv->rx_chan)); ++ ++ /* all set, enable mac and interrupts, start dma engine and ++ * kick rx dma channel */ ++ wmb(); ++ enet_dma_writel(priv, ENETDMA_CFG_EN_MASK, ENETDMA_CFG_REG); ++ enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK, ++ ENETDMAC_CHANCFG_REG(priv->rx_chan)); ++ ++ /* watch "packet transferred" interrupt in rx and tx */ ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IR_REG(priv->tx_chan)); ++ ++ /* make sure we enable napi before rx interrupt */ ++ napi_enable(&priv->napi); ++ ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK, ++ ENETDMAC_IRMASK_REG(priv->tx_chan)); ++ ++ netif_carrier_on(dev); ++ netif_start_queue(dev); ++ ++ /* ++ * apply override config for bypass_link ports here. ++ */ ++ for (i = 0; i < ARRAY_SIZE(priv->used_ports); i++) { ++ struct bcm63xx_enetsw_port *port; ++ u8 override; ++ port = &priv->used_ports[i]; ++ if (!port->used) ++ continue; ++ ++ if (!port->bypass_link) ++ continue; ++ ++ override = ENETSW_PORTOV_ENABLE_MASK | ++ ENETSW_PORTOV_LINKUP_MASK; ++ ++ switch (port->force_speed) { ++ case 1000: ++ override |= ENETSW_IMPOV_1000_MASK; ++ break; ++ case 100: ++ override |= ENETSW_IMPOV_100_MASK; ++ break; ++ case 10: ++ break; ++ default: ++ printk(KERN_WARNING "invalid forced speed on port %s: " ++ "assume 10\n", ++ port->name); ++ break; ++ } ++ ++ if (port->force_duplex_full) ++ override = ENETSW_IMPOV_FDX_MASK; ++ ++ ++ enetsw_writeb(priv, override, ENETSW_PORTOV_REG(i)); ++ enetsw_writeb(priv, 0, ENETSW_PTCTRL_REG(i)); ++ } ++ ++ /* start phy polling timer */ ++ init_timer(&priv->swphy_poll); ++ priv->swphy_poll.function = swphy_poll_timer; ++ priv->swphy_poll.data = (unsigned long)priv; ++ priv->swphy_poll.expires = jiffies; ++ add_timer(&priv->swphy_poll); ++ return 0; ++ ++out: ++ for (i = 0; i < priv->rx_ring_size; i++) { ++ struct bcm_enet_desc *desc; ++ ++ if (!priv->rx_skb[i]) ++ continue; ++ ++ desc = &priv->rx_desc_cpu[i]; ++ dma_unmap_single(kdev, desc->address, priv->rx_skb_size, ++ DMA_FROM_DEVICE); ++ kfree_skb(priv->rx_skb[i]); ++ } ++ kfree(priv->rx_skb); ++ ++out_free_tx_skb: ++ kfree(priv->tx_skb); ++ ++out_free_tx_ring: ++ dma_free_coherent(kdev, priv->tx_desc_alloc_size, ++ priv->tx_desc_cpu, priv->tx_desc_dma); ++ ++out_free_rx_ring: ++ dma_free_coherent(kdev, priv->rx_desc_alloc_size, ++ priv->rx_desc_cpu, priv->rx_desc_dma); ++ ++out_freeirq_tx: ++ free_irq(priv->irq_tx, dev); ++ ++out_freeirq_rx: ++ free_irq(priv->irq_rx, dev); ++ ++out_freeirq: ++ return ret; ++} ++ ++/* ++ * stop callback ++ */ ++static int bcm_enetsw_stop(struct net_device *dev) ++{ ++ struct bcm_enet_priv *priv; ++ struct device *kdev; ++ int i; ++ ++ priv = netdev_priv(dev); ++ kdev = &priv->pdev->dev; ++ ++ del_timer_sync(&priv->swphy_poll); ++ netif_stop_queue(dev); ++ napi_disable(&priv->napi); ++ del_timer_sync(&priv->rx_timeout); ++ ++ /* mask all interrupts */ ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan)); ++ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan)); ++ ++ /* disable dma & mac */ ++ bcm_enet_disable_dma(priv, priv->tx_chan); ++ bcm_enet_disable_dma(priv, priv->rx_chan); ++ ++ /* force reclaim of all tx buffers */ ++ bcm_enet_tx_reclaim(dev, 1); ++ ++ /* free the rx skb ring */ ++ for (i = 0; i < priv->rx_ring_size; i++) { ++ struct bcm_enet_desc *desc; ++ ++ if (!priv->rx_skb[i]) ++ continue; ++ ++ desc = &priv->rx_desc_cpu[i]; ++ dma_unmap_single(kdev, desc->address, priv->rx_skb_size, ++ DMA_FROM_DEVICE); ++ kfree_skb(priv->rx_skb[i]); ++ } ++ ++ /* free remaining allocated memory */ ++ kfree(priv->rx_skb); ++ kfree(priv->tx_skb); ++ dma_free_coherent(kdev, priv->rx_desc_alloc_size, ++ priv->rx_desc_cpu, priv->rx_desc_dma); ++ dma_free_coherent(kdev, priv->tx_desc_alloc_size, ++ priv->tx_desc_cpu, priv->tx_desc_dma); ++ free_irq(priv->irq_tx, dev); ++ free_irq(priv->irq_rx, dev); ++ ++ return 0; ++} ++ ++/* ++ * try to sort out phy external status by walking the used_port field ++ * in the bcm_enet_priv structure. in case the phy address is not ++ * assigned to any physical port on the switch, assume it is external ++ * (and yell at the user). ++ */ ++static int bcm_enetsw_phy_is_external(struct bcm_enet_priv *priv, int phy_id) ++{ ++ int i; ++ ++ for (i = 0; i < (int)ARRAY_SIZE(priv->used_ports); ++i) { ++ if (!priv->used_ports[i].used) ++ continue; ++ if (priv->used_ports[i].phy_id == phy_id) ++ return priv->used_ports[i].external_phy; ++ } ++ ++ printk_once(KERN_WARNING "bcm63xx_enet: could not find a used port " ++ "with phy_id %i, assuming phy is external\n", phy_id); ++ return 1; ++} ++ ++/* ++ * can't use bcmenet_sw_mdio_read directly as we need to sort out ++ * external/internal status of the given phy_id first. ++ */ ++static int bcm_enetsw_mii_mdio_read(struct net_device *dev, int phy_id, ++ int location) ++{ ++ struct bcm_enet_priv *priv; ++ ++ priv = netdev_priv(dev); ++ return bcmenet_sw_mdio_read(priv, ++ bcm_enetsw_phy_is_external(priv, phy_id), ++ phy_id, location); ++} ++ ++/* ++ * can't use bcmenet_sw_mdio_write directly as we need to sort out ++ * external/internal status of the given phy_id first. ++ */ ++static void bcm_enetsw_mii_mdio_write(struct net_device *dev, int phy_id, ++ int location, ++ int val) ++{ ++ struct bcm_enet_priv *priv; ++ ++ priv = netdev_priv(dev); ++ bcmenet_sw_mdio_write(priv, bcm_enetsw_phy_is_external(priv, phy_id), ++ phy_id, location, val); ++} ++ ++static int bcm_enetsw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) ++{ ++ struct mii_if_info mii; ++ ++ mii.dev = dev; ++ mii.mdio_read = bcm_enetsw_mii_mdio_read; ++ mii.mdio_write = bcm_enetsw_mii_mdio_write; ++ mii.phy_id = 0; ++ mii.phy_id_mask = 0x3f; ++ mii.reg_num_mask = 0x1f; ++ return generic_mii_ioctl(&mii, if_mii(rq), cmd, NULL); ++ ++} ++ ++static const struct net_device_ops bcm_enetsw_ops = { ++ .ndo_open = bcm_enetsw_open, ++ .ndo_stop = bcm_enetsw_stop, ++ .ndo_start_xmit = bcm_enet_start_xmit, ++ .ndo_change_mtu = bcm_enet_change_mtu, ++ .ndo_do_ioctl = bcm_enetsw_ioctl, ++}; ++ ++ ++static const struct bcm_enet_stats bcm_enetsw_gstrings_stats[] = { ++ { "rx_packets", DEV_STAT(rx_packets), -1 }, ++ { "tx_packets", DEV_STAT(tx_packets), -1 }, ++ { "rx_bytes", DEV_STAT(rx_bytes), -1 }, ++ { "tx_bytes", DEV_STAT(tx_bytes), -1 }, ++ { "rx_errors", DEV_STAT(rx_errors), -1 }, ++ { "tx_errors", DEV_STAT(tx_errors), -1 }, ++ { "rx_dropped", DEV_STAT(rx_dropped), -1 }, ++ { "tx_dropped", DEV_STAT(tx_dropped), -1 }, ++ ++ { "tx_good_octets", GEN_STAT(mib.tx_gd_octets), ETHSW_MIB_RX_GD_OCT }, ++ { "tx_unicast", GEN_STAT(mib.tx_unicast), ETHSW_MIB_RX_BRDCAST }, ++ { "tx_broadcast", GEN_STAT(mib.tx_brdcast), ETHSW_MIB_RX_BRDCAST }, ++ { "tx_multicast", GEN_STAT(mib.tx_mult), ETHSW_MIB_RX_MULT }, ++ { "tx_64_octets", GEN_STAT(mib.tx_64), ETHSW_MIB_RX_64 }, ++ { "tx_65_127_oct", GEN_STAT(mib.tx_65_127), ETHSW_MIB_RX_65_127 }, ++ { "tx_128_255_oct", GEN_STAT(mib.tx_128_255), ETHSW_MIB_RX_128_255 }, ++ { "tx_256_511_oct", GEN_STAT(mib.tx_256_511), ETHSW_MIB_RX_256_511 }, ++ { "tx_512_1023_oct", GEN_STAT(mib.tx_512_1023), ETHSW_MIB_RX_512_1023}, ++ { "tx_1024_1522_oct", GEN_STAT(mib.tx_1024_max), ++ ETHSW_MIB_RX_1024_1522 }, ++ { "tx_1523_2047_oct", GEN_STAT(mib.tx_1523_2047), ++ ETHSW_MIB_RX_1523_2047 }, ++ { "tx_2048_4095_oct", GEN_STAT(mib.tx_2048_4095), ++ ETHSW_MIB_RX_2048_4095 }, ++ { "tx_4096_8191_oct", GEN_STAT(mib.tx_4096_8191), ++ ETHSW_MIB_RX_4096_8191 }, ++ { "tx_8192_9728_oct", GEN_STAT(mib.tx_8192_9728), ++ ETHSW_MIB_RX_8192_9728 }, ++ { "tx_oversize", GEN_STAT(mib.tx_ovr), ETHSW_MIB_RX_OVR }, ++ { "tx_oversize_drop", GEN_STAT(mib.tx_ovr), ETHSW_MIB_RX_OVR_DISC }, ++ { "tx_dropped", GEN_STAT(mib.tx_drop), ETHSW_MIB_RX_DROP }, ++ { "tx_undersize", GEN_STAT(mib.tx_underrun), ETHSW_MIB_RX_UND }, ++ { "tx_pause", GEN_STAT(mib.tx_pause), ETHSW_MIB_RX_PAUSE }, ++ ++ { "rx_good_octets", GEN_STAT(mib.rx_gd_octets), ETHSW_MIB_TX_ALL_OCT }, ++ { "rx_broadcast", GEN_STAT(mib.rx_brdcast), ETHSW_MIB_TX_BRDCAST }, ++ { "rx_multicast", GEN_STAT(mib.rx_mult), ETHSW_MIB_TX_MULT }, ++ { "rx_unicast", GEN_STAT(mib.rx_unicast), ETHSW_MIB_TX_MULT }, ++ { "rx_pause", GEN_STAT(mib.rx_pause), ETHSW_MIB_TX_PAUSE }, ++ { "rx_dropped", GEN_STAT(mib.rx_drop), ETHSW_MIB_TX_DROP_PKTS }, ++ ++}; ++ ++#define BCM_ENETSW_STATS_LEN \ ++ (sizeof(bcm_enetsw_gstrings_stats) / sizeof(struct bcm_enet_stats)) ++ ++static void bcm_enetsw_get_strings(struct net_device *netdev, ++ u32 stringset, u8 *data) ++{ ++ int i; ++ ++ switch (stringset) { ++ case ETH_SS_STATS: ++ for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) { ++ memcpy(data + i * ETH_GSTRING_LEN, ++ bcm_enetsw_gstrings_stats[i].stat_string, ++ ETH_GSTRING_LEN); ++ } ++ break; ++ } ++} ++ ++static int bcm_enetsw_get_sset_count(struct net_device *netdev, ++ int string_set) ++{ ++ switch (string_set) { ++ case ETH_SS_STATS: ++ return BCM_ENETSW_STATS_LEN; ++ default: ++ return -EINVAL; ++ } ++} ++ ++static void bcm_enetsw_get_drvinfo(struct net_device *netdev, ++ struct ethtool_drvinfo *drvinfo) ++{ ++ strncpy(drvinfo->driver, bcm_enet_driver_name, 32); ++ strncpy(drvinfo->version, bcm_enet_driver_version, 32); ++ strncpy(drvinfo->fw_version, "N/A", 32); ++ strncpy(drvinfo->bus_info, "bcm63xx", 32); ++ drvinfo->n_stats = BCM_ENETSW_STATS_LEN; ++} ++ ++static void bcm_enetsw_get_ethtool_stats(struct net_device *netdev, ++ struct ethtool_stats *stats, ++ u64 *data) ++{ ++ struct bcm_enet_priv *priv; ++ int i; ++ ++ priv = netdev_priv(netdev); ++ ++ for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) { ++ const struct bcm_enet_stats *s; ++ u32 lo, hi; ++ char *p; ++ int reg; ++ ++ s = &bcm_enetsw_gstrings_stats[i]; ++ ++ reg = s->mib_reg; ++ if (reg == -1) ++ continue; ++ ++ lo = enetsw_readl(priv, ENETSW_MIB_REG(reg)); ++ p = (char *)priv + s->stat_offset; ++ ++ if (s->sizeof_stat == sizeof(u64)) { ++ hi = enetsw_readl(priv, ENETSW_MIB_REG(reg + 1)); ++ *(u64 *)p = ((u64)hi << 32 | lo); ++ } else ++ *(u32 *)p = lo; ++ } ++ ++ for (i = 0; i < BCM_ENETSW_STATS_LEN; i++) { ++ const struct bcm_enet_stats *s; ++ char *p; ++ ++ s = &bcm_enetsw_gstrings_stats[i]; ++ ++ if (s->mib_reg == -1) ++ p = (char *)&netdev->stats + s->stat_offset; ++ else ++ p = (char *)priv + s->stat_offset; ++ ++ data[i] = (s->sizeof_stat == sizeof(u64)) ? ++ *(u64 *)p : *(u32 *)p; ++ } ++} ++ ++static void bcm_enetsw_get_ringparam(struct net_device *dev, ++ struct ethtool_ringparam *ering) ++{ ++ struct bcm_enet_priv *priv; ++ ++ priv = netdev_priv(dev); ++ ++ /* rx/tx ring is actually only limited by memory */ ++ ering->rx_max_pending = 8192; ++ ering->tx_max_pending = 8192; ++ ering->rx_mini_max_pending = 0; ++ ering->rx_jumbo_max_pending = 0; ++ ering->rx_pending = priv->rx_ring_size; ++ ering->tx_pending = priv->tx_ring_size; ++} ++ ++static int bcm_enetsw_set_ringparam(struct net_device *dev, ++ struct ethtool_ringparam *ering) ++{ ++ struct bcm_enet_priv *priv; ++ int was_running; ++ ++ priv = netdev_priv(dev); ++ ++ was_running = 0; ++ if (netif_running(dev)) { ++ bcm_enetsw_stop(dev); ++ was_running = 1; ++ } ++ ++ priv->rx_ring_size = ering->rx_pending; ++ priv->tx_ring_size = ering->tx_pending; ++ ++ if (was_running) { ++ int err; ++ ++ err = bcm_enetsw_open(dev); ++ if (err) ++ dev_close(dev); ++ } ++ return 0; ++} ++ ++static struct ethtool_ops bcm_enetsw_ethtool_ops = { ++ .get_strings = bcm_enetsw_get_strings, ++ .get_sset_count = bcm_enetsw_get_sset_count, ++ .get_ethtool_stats = bcm_enetsw_get_ethtool_stats, ++ .get_drvinfo = bcm_enetsw_get_drvinfo, ++ .get_ringparam = bcm_enetsw_get_ringparam, ++ .set_ringparam = bcm_enetsw_set_ringparam, ++}; ++ ++/* ++ * allocate netdevice, request register memory and register device. ++ */ ++static int __devinit bcm_enetsw_probe(struct platform_device *pdev) ++{ ++ struct bcm_enet_priv *priv; ++ struct net_device *dev; ++ struct bcm63xx_enetsw_platform_data *pd; ++ struct resource *res_mem; ++ int ret, irq_rx, irq_tx; ++ ++ /* stop if shared driver failed, assume driver->probe will be ++ * called in the same order we register devices (correct ?) */ ++ if (!bcm_enet_shared_base[0]) ++ return -ENODEV; ++ ++ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ irq_rx = platform_get_irq(pdev, 0); ++ irq_tx = platform_get_irq(pdev, 1); ++ if (!res_mem || irq_rx < 0 || irq_tx < 0) ++ return -ENODEV; ++ ++ ret = 0; ++ dev = alloc_etherdev(sizeof(*priv)); ++ if (!dev) ++ return -ENOMEM; ++ priv = netdev_priv(dev); ++ memset(priv, 0, sizeof(*priv)); ++ ++ /* initialize default and fetch platform data */ ++ priv->irq_rx = irq_rx; ++ priv->irq_tx = irq_tx; ++ priv->rx_ring_size = BCMENET_DEF_RX_DESC; ++ priv->tx_ring_size = BCMENET_DEF_TX_DESC; ++ ++ pd = pdev->dev.platform_data; ++ if (pd) { ++ memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN); ++ memcpy(priv->used_ports, pd->used_ports, ++ sizeof (pd->used_ports)); ++ } ++ ++ ret = compute_hw_mtu(priv, dev->mtu); ++ if (ret) ++ goto out; ++ ++ if (!request_mem_region(res_mem->start, resource_size(res_mem), ++ "bcm63xx_enetsw")) { ++ ret = -EBUSY; ++ goto out; ++ } ++ ++ priv->base = ioremap(res_mem->start, resource_size(res_mem)); ++ if (priv->base == NULL) { ++ ret = -ENOMEM; ++ goto out_release_mem; ++ } ++ ++ priv->mac_clk = clk_get(&pdev->dev, "enetsw"); ++ if (IS_ERR(priv->mac_clk)) { ++ ret = PTR_ERR(priv->mac_clk); ++ goto out_unmap; ++ } ++ clk_enable(priv->mac_clk); ++ ++ priv->rx_chan = 0; ++ priv->tx_chan = 1; ++ spin_lock_init(&priv->rx_lock); ++ ++ /* init rx timeout (used for oom) */ ++ init_timer(&priv->rx_timeout); ++ priv->rx_timeout.function = bcm_enet_refill_rx_timer; ++ priv->rx_timeout.data = (unsigned long)dev; ++ ++ /* register netdevice */ ++ dev->netdev_ops = &bcm_enetsw_ops; ++ netif_napi_add(dev, &priv->napi, bcm_enet_poll, 16); ++ SET_ETHTOOL_OPS(dev, &bcm_enetsw_ethtool_ops); ++ SET_NETDEV_DEV(dev, &pdev->dev); ++ ++ spin_lock_init(&priv->enetsw_mdio_lock); ++ ++ ret = register_netdev(dev); ++ if (ret) ++ goto out_put_clk; ++ ++ netif_carrier_off(dev); ++ platform_set_drvdata(pdev, dev); ++ priv->pdev = pdev; ++ priv->net_dev = dev; ++ ++ return 0; ++ ++out_put_clk: ++ clk_put(priv->mac_clk); ++ ++out_unmap: ++ iounmap(priv->base); ++ ++out_release_mem: ++ release_mem_region(res_mem->start, resource_size(res_mem)); ++out: ++ free_netdev(dev); ++ return ret; ++} ++ ++ ++/* ++ * exit func, stops hardware and unregisters netdevice ++ */ ++static int __devexit bcm_enetsw_remove(struct platform_device *pdev) ++{ ++ struct bcm_enet_priv *priv; ++ struct net_device *dev; ++ struct resource *res; ++ ++ /* stop netdevice */ ++ dev = platform_get_drvdata(pdev); ++ priv = netdev_priv(dev); ++ unregister_netdev(dev); ++ ++ /* release device resources */ ++ iounmap(priv->base); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ release_mem_region(res->start, resource_size(res)); ++ ++ platform_set_drvdata(pdev, NULL); ++ free_netdev(dev); ++ return 0; ++} ++ ++struct platform_driver bcm63xx_enetsw_driver = { ++ .probe = bcm_enetsw_probe, ++ .remove = __devexit_p(bcm_enetsw_remove), ++ .driver = { ++ .name = "bcm63xx_enetsw", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++/* ++ * reserve & remap memory space shared between all macs ++ */ ++static int __devinit bcm_enet_shared_probe(struct platform_device *pdev) ++{ ++ struct resource *res; ++ int ret, i, requested[3]; ++ ++ memset(bcm_enet_shared_base, 0, sizeof (bcm_enet_shared_base)); ++ memset(requested, 0, sizeof (requested)); ++ ++ for (i = 0; i < 3; i++) { ++ void __iomem *p; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ if (!res) { ++ ret = -EINVAL; ++ goto fail; ++ } ++ ++ if (!request_mem_region(res->start, resource_size(res), ++ "bcm63xx_enet_dma")) { ++ ret = -EBUSY; ++ goto fail; ++ } ++ requested[i] = 0; ++ ++ p = ioremap(res->start, resource_size(res)); ++ if (!p) { ++ ret = -ENOMEM; ++ goto fail; ++ } ++ ++ bcm_enet_shared_base[i] = p; ++ } ++ ++ return 0; ++ ++fail: ++ for (i = 0; i < 3; i++) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ if (!res) ++ continue; ++ if (bcm_enet_shared_base[i]) ++ iounmap(bcm_enet_shared_base[i]); ++ if (requested[i]) ++ release_mem_region(res->start, resource_size(res)); ++ } ++ return ret; ++} ++ ++static int __devexit bcm_enet_shared_remove(struct platform_device *pdev) ++{ ++ struct resource *res; ++ int i; ++ ++ for (i = 0; i < 3; i++) { ++ iounmap(bcm_enet_shared_base[i]); ++ res = platform_get_resource(pdev, IORESOURCE_MEM, i); ++ release_mem_region(res->start, resource_size(res)); ++ } ++ return 0; ++} ++ ++/* ++ * this "shared" driver is needed because both macs share a single ++ * address space ++ */ ++struct platform_driver bcm63xx_enet_shared_driver = { ++ .probe = bcm_enet_shared_probe, ++ .remove = __devexit_p(bcm_enet_shared_remove), ++ .driver = { ++ .name = "bcm63xx_enet_shared", ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++/* ++ * entry point ++ */ ++static int __init bcm_enet_init(void) ++{ ++ int ret; ++ ++ ret = platform_driver_register(&bcm63xx_enet_shared_driver); ++ if (ret) ++ return ret; ++ ++ ret = platform_driver_register(&bcm63xx_enet_driver); ++ if (ret) ++ platform_driver_unregister(&bcm63xx_enet_shared_driver); ++ ++ ret = platform_driver_register(&bcm63xx_enetsw_driver); ++ if (ret) { ++ platform_driver_unregister(&bcm63xx_enet_driver); ++ platform_driver_unregister(&bcm63xx_enet_shared_driver); ++ } + + return ret; + } +@@ -2018,6 +2937,7 @@ static int __init bcm_enet_init(void) + static void __exit bcm_enet_exit(void) + { + platform_driver_unregister(&bcm63xx_enet_driver); ++ platform_driver_unregister(&bcm63xx_enetsw_driver); + platform_driver_unregister(&bcm63xx_enet_shared_driver); + } + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -112,11 +112,60 @@ struct bcm_enet_desc { + #define ETH_MIB_RX_CNTRL 54 + + ++/* ++ * SW MIB Counters register definitions ++*/ ++#define ETHSW_MIB_TX_ALL_OCT 0 ++#define ETHSW_MIB_TX_DROP_PKTS 2 ++#define ETHSW_MIB_TX_QOS_PKTS 3 ++#define ETHSW_MIB_TX_BRDCAST 4 ++#define ETHSW_MIB_TX_MULT 5 ++#define ETHSW_MIB_TX_UNI 6 ++#define ETHSW_MIB_TX_COL 7 ++#define ETHSW_MIB_TX_1_COL 8 ++#define ETHSW_MIB_TX_M_COL 9 ++#define ETHSW_MIB_TX_DEF 10 ++#define ETHSW_MIB_TX_LATE 11 ++#define ETHSW_MIB_TX_EX_COL 12 ++#define ETHSW_MIB_TX_PAUSE 14 ++#define ETHSW_MIB_TX_QOS_OCT 15 ++ ++#define ETHSW_MIB_RX_ALL_OCT 17 ++#define ETHSW_MIB_RX_UND 19 ++#define ETHSW_MIB_RX_PAUSE 20 ++#define ETHSW_MIB_RX_64 21 ++#define ETHSW_MIB_RX_65_127 22 ++#define ETHSW_MIB_RX_128_255 23 ++#define ETHSW_MIB_RX_256_511 24 ++#define ETHSW_MIB_RX_512_1023 25 ++#define ETHSW_MIB_RX_1024_1522 26 ++#define ETHSW_MIB_RX_OVR 27 ++#define ETHSW_MIB_RX_JAB 28 ++#define ETHSW_MIB_RX_ALIGN 29 ++#define ETHSW_MIB_RX_CRC 30 ++#define ETHSW_MIB_RX_GD_OCT 31 ++#define ETHSW_MIB_RX_DROP 33 ++#define ETHSW_MIB_RX_UNI 34 ++#define ETHSW_MIB_RX_MULT 35 ++#define ETHSW_MIB_RX_BRDCAST 36 ++#define ETHSW_MIB_RX_SA_CHANGE 37 ++#define ETHSW_MIB_RX_FRAG 38 ++#define ETHSW_MIB_RX_OVR_DISC 39 ++#define ETHSW_MIB_RX_SYM 40 ++#define ETHSW_MIB_RX_QOS_PKTS 41 ++#define ETHSW_MIB_RX_QOS_OCT 42 ++#define ETHSW_MIB_RX_1523_2047 44 ++#define ETHSW_MIB_RX_2048_4095 45 ++#define ETHSW_MIB_RX_4096_8191 46 ++#define ETHSW_MIB_RX_8192_9728 47 ++ ++ + struct bcm_enet_mib_counters { + u64 tx_gd_octets; + u32 tx_gd_pkts; + u32 tx_all_octets; + u32 tx_all_pkts; ++ u32 tx_unicast; + u32 tx_brdcast; + u32 tx_mult; + u32 tx_64; +@@ -125,7 +174,12 @@ struct bcm_enet_mib_counters { + u32 tx_256_511; + u32 tx_512_1023; + u32 tx_1024_max; ++ u32 tx_1523_2047; ++ u32 tx_2048_4095; ++ u32 tx_4096_8191; ++ u32 tx_8192_9728; + u32 tx_jab; ++ u32 tx_drop; + u32 tx_ovr; + u32 tx_frag; + u32 tx_underrun; +@@ -142,6 +196,7 @@ struct bcm_enet_mib_counters { + u32 rx_all_octets; + u32 rx_all_pkts; + u32 rx_brdcast; ++ u32 rx_unicast; + u32 rx_mult; + u32 rx_64; + u32 rx_65_127; +@@ -297,6 +352,22 @@ struct bcm_enet_priv { + + /* maximum hardware transmit/receive size */ + unsigned int hw_mtu; ++ ++ /* port mapping for switch devices */ ++ struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; ++ int sw_port_link[ENETSW_MAX_PORT]; ++ ++ /* used to poll switch port state */ ++ struct timer_list swphy_poll; ++ spinlock_t enetsw_mdio_lock; + }; + ++static inline int bcm_enet_is_sw(struct bcm_enet_priv *priv) ++{ ++ if (BCMCPU_IS_6368()) ++ return 1; ++ else ++ return 0; ++} ++ + #endif /* ! BCM63XX_ENET_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch b/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch new file mode 100644 index 000000000..6d8e5a72d --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/416-bcm63xx_enet-reset-port-link-state-in-bcm_enetsw_ope.patch @@ -0,0 +1,28 @@ +From 6d5c5bb13db3fd8e3dd0b82742b3957f41a4a3ac Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 24 May 2012 20:38:58 +0200 +Subject: [PATCH] bcm63xx_enet: reset port link state in bcm_enetsw_open + +bcm_enetsw_open disables all ports, but does not reset their link state. +This results in connected ports staying disabled after a ifdown/ifup +cycle, since bcm_enetsw_phy_poll only enables them if their current state +is different from the stored link state. + +Fix this by also resetting the port link state. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2213,6 +2213,8 @@ static int bcm_enetsw_open(struct net_de + enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK | + ENETSW_PTCTRL_TXDIS_MASK, + ENETSW_PTCTRL_REG(i)); ++ ++ priv->sw_port_link[i] = 0; + } + + /* reset mib */ diff --git a/target/linux/brcm63xx/patches-3.3/417-bcm63xx_enet-don-t-overwrite-settings-when-setting-d.patch b/target/linux/brcm63xx/patches-3.3/417-bcm63xx_enet-don-t-overwrite-settings-when-setting-d.patch new file mode 100644 index 000000000..407c8169e --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/417-bcm63xx_enet-don-t-overwrite-settings-when-setting-d.patch @@ -0,0 +1,20 @@ +From e79bc74f76361020d820ed4611d28f70ebd845ca Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 10 Jul 2012 10:44:09 +0200 +Subject: [PATCH 34/84] bcm63xx_enet: don't overwrite settings when setting duplex on force + +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2333,7 +2333,7 @@ static int bcm_enetsw_open(struct net_de + } + + if (port->force_duplex_full) +- override = ENETSW_IMPOV_FDX_MASK; ++ override |= ENETSW_IMPOV_FDX_MASK; + + + enetsw_writeb(priv, override, ENETSW_PORTOV_REG(i)); diff --git a/target/linux/brcm63xx/patches-3.3/418-bcm63xx_enet-store-the-number-of-ports-instead-of-ha.patch b/target/linux/brcm63xx/patches-3.3/418-bcm63xx_enet-store-the-number-of-ports-instead-of-ha.patch new file mode 100644 index 000000000..232668b7c --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/418-bcm63xx_enet-store-the-number-of-ports-instead-of-ha.patch @@ -0,0 +1,98 @@ +From efe31ec8fca92162fc21630611971345014a81a0 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 10 Jul 2012 10:39:30 +0200 +Subject: [PATCH 33/84] bcm63xx_enet: store the number of ports instead of hardcoding them + +This will be needed for devices with a different number of ports +--- + arch/mips/bcm63xx/dev-enet.c | 2 ++ + .../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 2 ++ + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 9 +++++---- + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 1 + + 4 files changed, 10 insertions(+), 4 deletions(-) + +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -239,6 +239,8 @@ bcm63xx_enetsw_register(const struct bcm + + memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof (*pd)); + ++ enetsw_pd.num_ports = ENETSW_PORTS_6368; ++ + ret = platform_device_register(&bcm63xx_enetsw_device); + if (ret) + return ret; +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +@@ -43,6 +43,7 @@ struct bcm63xx_enet_platform_data { + * on board ethernet switch platform data + */ + #define ENETSW_MAX_PORT 6 ++#define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */ + + struct bcm63xx_enetsw_port { + int used; +@@ -58,6 +59,7 @@ struct bcm63xx_enetsw_port { + + struct bcm63xx_enetsw_platform_data { + char mac_addr[ETH_ALEN]; ++ int num_ports; + struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; + }; + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2041,7 +2041,7 @@ static void swphy_poll_timer(unsigned lo + struct bcm_enet_priv *priv = (struct bcm_enet_priv *)data; + unsigned int i; + +- for (i = 0; i < ARRAY_SIZE(priv->used_ports); i++) { ++ for (i = 0; i < priv->num_ports; i++) { + struct bcm63xx_enetsw_port *port; + int val, j, up, advertise, lpa, lpa2, speed, duplex, media; + u8 override; +@@ -2207,7 +2207,7 @@ static int bcm_enetsw_open(struct net_de + priv->rx_curr_desc = 0; + + /* disable all ports */ +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < priv->num_ports; i++) { + enetsw_writeb(priv, ENETSW_PORTOV_ENABLE_MASK, + ENETSW_PORTOV_REG(i)); + enetsw_writeb(priv, ENETSW_PTCTRL_RXDIS_MASK | +@@ -2303,7 +2303,7 @@ static int bcm_enetsw_open(struct net_de + /* + * apply override config for bypass_link ports here. + */ +- for (i = 0; i < ARRAY_SIZE(priv->used_ports); i++) { ++ for (i = 0; i < priv->num_ports; i++) { + struct bcm63xx_enetsw_port *port; + u8 override; + port = &priv->used_ports[i]; +@@ -2447,7 +2447,7 @@ static int bcm_enetsw_phy_is_external(st + { + int i; + +- for (i = 0; i < (int)ARRAY_SIZE(priv->used_ports); ++i) { ++ for (i = 0; i < priv->num_ports; ++i) { + if (!priv->used_ports[i].used) + continue; + if (priv->used_ports[i].phy_id == phy_id) +@@ -2735,6 +2735,7 @@ static int __devinit bcm_enetsw_probe(st + memcpy(dev->dev_addr, pd->mac_addr, ETH_ALEN); + memcpy(priv->used_ports, pd->used_ports, + sizeof (pd->used_ports)); ++ priv->num_ports = pd->num_ports; + } + + ret = compute_hw_mtu(priv, dev->mtu); +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -354,6 +354,7 @@ struct bcm_enet_priv { + unsigned int hw_mtu; + + /* port mapping for switch devices */ ++ int num_ports; + struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; + int sw_port_link[ENETSW_MAX_PORT]; + diff --git a/target/linux/brcm63xx/patches-3.3/419-bcm63xx_enet-store-is_sw-in-a-variable-instead-of-ch.patch b/target/linux/brcm63xx/patches-3.3/419-bcm63xx_enet-store-is_sw-in-a-variable-instead-of-ch.patch new file mode 100644 index 000000000..6f73477ab --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/419-bcm63xx_enet-store-is_sw-in-a-variable-instead-of-ch.patch @@ -0,0 +1,73 @@ +From ef581388c45dbc48f7bbe050e87deb1e3c63a698 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 10 Jul 2012 10:52:02 +0200 +Subject: [PATCH 35/84] bcm63xx_enet: store is_sw in a variable instead of checking the cpuid + +Reduces the number of changes needed for making enetsw work on new +chips. +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 7 +++++-- + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 10 ++-------- + 2 files changed, 7 insertions(+), 10 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -364,7 +364,7 @@ static int bcm_enet_receive_queue(struct + } + + /* recycle packet if it's marked as bad */ +- if (!bcm_enet_is_sw(priv) && ++ if (!priv->enet_is_sw && + unlikely(len_stat & DMADESC_ERR_MASK)) { + dev->stats.rx_errors++; + +@@ -597,7 +597,7 @@ static int bcm_enet_start_xmit(struct sk + } + + /* pad small packets sent on a switch device */ +- if (bcm_enet_is_sw(priv) && skb->len < 64) { ++ if (priv->enet_is_sw && skb->len < 64) { + int needed = 64 - skb->len; + char *data; + +@@ -1700,6 +1700,8 @@ static int __devinit bcm_enet_probe(stru + return -ENOMEM; + priv = netdev_priv(dev); + ++ priv->enet_is_sw = false; ++ + ret = compute_hw_mtu(priv, dev->mtu); + if (ret) + goto out; +@@ -2725,6 +2727,7 @@ static int __devinit bcm_enetsw_probe(st + memset(priv, 0, sizeof(*priv)); + + /* initialize default and fetch platform data */ ++ priv->enet_is_sw = true; + priv->irq_rx = irq_rx; + priv->irq_tx = irq_tx; + priv->rx_ring_size = BCMENET_DEF_RX_DESC; +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -353,6 +353,8 @@ struct bcm_enet_priv { + /* maximum hardware transmit/receive size */ + unsigned int hw_mtu; + ++ bool enet_is_sw; ++ + /* port mapping for switch devices */ + int num_ports; + struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT]; +@@ -363,12 +365,4 @@ struct bcm_enet_priv { + spinlock_t enetsw_mdio_lock; + }; + +-static inline int bcm_enet_is_sw(struct bcm_enet_priv *priv) +-{ +- if (BCMCPU_IS_6368()) +- return 1; +- else +- return 0; +-} +- + #endif /* ! BCM63XX_ENET_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/420-BCM63XX-allow-enetsw-without-tx-irq.patch b/target/linux/brcm63xx/patches-3.3/420-BCM63XX-allow-enetsw-without-tx-irq.patch new file mode 100644 index 000000000..6396b626d --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/420-BCM63XX-allow-enetsw-without-tx-irq.patch @@ -0,0 +1,69 @@ +From 625894c377ba266c0044675b53f05d65db6355b6 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sun, 8 Jul 2012 13:07:52 +0200 +Subject: [PATCH 38/84] BCM63XX: allow enetsw without tx irq + +--- + arch/mips/bcm63xx/dev-enet.c | 2 ++ + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 18 +++++++++++------- + 2 files changed, 13 insertions(+), 7 deletions(-) + +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -236,6 +236,8 @@ bcm63xx_enetsw_register(const struct bcm + enetsw_res[0].end += RSET_ENETSW_SIZE - 1; + enetsw_res[1].start = bcm63xx_get_irq_number(IRQ_ENETSW_RXDMA0); + enetsw_res[2].start = bcm63xx_get_irq_number(IRQ_ENETSW_TXDMA0); ++ if (!enetsw_res[2].start) ++ enetsw_res[2].start = -1; + + memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof (*pd)); + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2151,10 +2151,12 @@ static int bcm_enetsw_open(struct net_de + if (ret) + goto out_freeirq; + +- ret = request_irq(priv->irq_tx, bcm_enet_isr_dma, +- IRQF_DISABLED, dev->name, dev); +- if (ret) +- goto out_freeirq_rx; ++ if (priv->irq_tx != -1) { ++ ret = request_irq(priv->irq_tx, bcm_enet_isr_dma, ++ IRQF_DISABLED, dev->name, dev); ++ if (ret) ++ goto out_freeirq_rx; ++ } + + /* allocate rx dma ring */ + size = priv->rx_ring_size * sizeof(struct bcm_enet_desc); +@@ -2376,7 +2378,8 @@ out_free_rx_ring: + priv->rx_desc_cpu, priv->rx_desc_dma); + + out_freeirq_tx: +- free_irq(priv->irq_tx, dev); ++ if (priv->irq_tx != -1) ++ free_irq(priv->irq_tx, dev); + + out_freeirq_rx: + free_irq(priv->irq_rx, dev); +@@ -2433,7 +2436,8 @@ static int bcm_enetsw_stop(struct net_de + priv->rx_desc_cpu, priv->rx_desc_dma); + dma_free_coherent(kdev, priv->tx_desc_alloc_size, + priv->tx_desc_cpu, priv->tx_desc_dma); +- free_irq(priv->irq_tx, dev); ++ if (priv->irq_tx != -1) ++ free_irq(priv->irq_tx, dev); + free_irq(priv->irq_rx, dev); + + return 0; +@@ -2716,7 +2720,7 @@ static int __devinit bcm_enetsw_probe(st + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + irq_rx = platform_get_irq(pdev, 0); + irq_tx = platform_get_irq(pdev, 1); +- if (!res_mem || irq_rx < 0 || irq_tx < 0) ++ if (!res_mem || irq_rx < 0) + return -ENODEV; + + ret = 0; diff --git a/target/linux/brcm63xx/patches-3.3/421-BCM63XX-use-port-id-for-deciding-external-phy.patch b/target/linux/brcm63xx/patches-3.3/421-BCM63XX-use-port-id-for-deciding-external-phy.patch new file mode 100644 index 000000000..da7013d8f --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/421-BCM63XX-use-port-id-for-deciding-external-phy.patch @@ -0,0 +1,87 @@ +From 85e4551e033df7cb043e93042661fc1e58799efa Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sun, 8 Jul 2012 15:36:23 +0200 +Subject: [PATCH 52/84] BCM63XX: use port id for deciding external phy + +Ports 0-3 always use the internal phy, while 4+ always need an external +phy to work. +--- + .../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 3 ++- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 15 ++++++++------- + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 5 +++++ + 3 files changed, 15 insertions(+), 8 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +@@ -45,9 +45,10 @@ struct bcm63xx_enet_platform_data { + #define ENETSW_MAX_PORT 6 + #define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */ + ++#define ENETSW_RGMII_PORT0 4 ++ + struct bcm63xx_enetsw_port { + int used; +- int external_phy; + int phy_id; + + int bypass_link; +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2046,6 +2046,7 @@ static void swphy_poll_timer(unsigned lo + for (i = 0; i < priv->num_ports; i++) { + struct bcm63xx_enetsw_port *port; + int val, j, up, advertise, lpa, lpa2, speed, duplex, media; ++ int external_phy = bcm_enet_port_is_rgmii(i); + u8 override; + + port = &priv->used_ports[i]; +@@ -2057,7 +2058,7 @@ static void swphy_poll_timer(unsigned lo + + /* dummy read to clear */ + for (j = 0; j < 2; j++) +- val = bcmenet_sw_mdio_read(priv, port->external_phy, ++ val = bcmenet_sw_mdio_read(priv, external_phy, + port->phy_id, MII_BMSR); + + if (val == 0xffff) +@@ -2081,14 +2082,14 @@ static void swphy_poll_timer(unsigned lo + continue; + } + +- advertise = bcmenet_sw_mdio_read(priv, port->external_phy, ++ advertise = bcmenet_sw_mdio_read(priv, external_phy, + port->phy_id, MII_ADVERTISE); + +- lpa = bcmenet_sw_mdio_read(priv, port->external_phy, +- port->phy_id, MII_LPA); ++ lpa = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id, ++ MII_LPA); + +- lpa2 = bcmenet_sw_mdio_read(priv, port->external_phy, +- port->phy_id, MII_STAT1000); ++ lpa2 = bcmenet_sw_mdio_read(priv, external_phy, port->phy_id, ++ MII_STAT1000); + + /* figure out media and duplex from advertise and LPA values */ + media = mii_nway_result(lpa & advertise); +@@ -2457,7 +2458,7 @@ static int bcm_enetsw_phy_is_external(st + if (!priv->used_ports[i].used) + continue; + if (priv->used_ports[i].phy_id == phy_id) +- return priv->used_ports[i].external_phy; ++ return bcm_enet_port_is_rgmii(i); + } + + printk_once(KERN_WARNING "bcm63xx_enet: could not find a used port " +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -365,4 +365,9 @@ struct bcm_enet_priv { + spinlock_t enetsw_mdio_lock; + }; + ++static inline int bcm_enet_port_is_rgmii(int portid) ++{ ++ return portid >= ENETSW_RGMII_PORT0; ++} ++ + #endif /* ! BCM63XX_ENET_H_ */ diff --git a/target/linux/brcm63xx/patches-3.3/422-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch b/target/linux/brcm63xx/patches-3.3/422-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch new file mode 100644 index 000000000..7d1f3f3f8 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/422-bcm63xx_enet-enable-rgmii-clock-on-external-ports.patch @@ -0,0 +1,53 @@ +From d8237d704fc25eb2fc25ef4403608b78c6a6d4be Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sun, 15 Jul 2012 20:08:57 +0200 +Subject: [PATCH 54/81] bcm63xx_enet: enable rgmii clock on external ports + +--- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 13 +++++++++++++ + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 12 ++++++++++++ + 2 files changed, 25 insertions(+), 0 deletions(-) + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -838,6 +838,19 @@ + #define ENETSW_PORTOV_FDX_MASK (1 << 1) + #define ENETSW_PORTOV_LINKUP_MASK (1 << 0) + ++/* Port RGMII control register */ ++#define ENETSW_RGMII_CTRL_REG(x) (0x60 + (x)) ++#define ENETSW_RGMII_CTRL_GMII_CLK_EN (1 << 7) ++#define ENETSW_RGMII_CTRL_MII_OVERRIDE_EN (1 << 6) ++#define ENETSW_RGMII_CTRL_MII_MODE_MASK (3 << 4) ++#define ENETSW_RGMII_CTRL_RGMII_MODE (0 << 4) ++#define ENETSW_RGMII_CTRL_MII_MODE (1 << 4) ++#define ENETSW_RGMII_CTRL_RVMII_MODE (2 << 4) ++#define ENETSW_RGMII_CTRL_TIMING_SEL_EN (1 << 0) ++ ++/* Port RGMII timing register */ ++#define ENETSW_RGMII_TIMING_REG(x) (0x68 + (x)) ++ + /* MDIO control register */ + #define ENETSW_MDIOC_REG (0xb0) + #define ENETSW_MDIOC_EXT_MASK (1 << 16) +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -2222,6 +2222,18 @@ static int bcm_enetsw_open(struct net_de + priv->sw_port_link[i] = 0; + } + ++ /* enable external ports */ ++ for (i = ENETSW_RGMII_PORT0; i < priv->num_ports; i++) { ++ u8 rgmii_ctrl; ++ ++ if (!priv->used_ports[i].used) ++ continue; ++ ++ rgmii_ctrl = enetsw_readb(priv, ENETSW_RGMII_CTRL_REG(i)); ++ rgmii_ctrl |= ENETSW_RGMII_CTRL_GMII_CLK_EN; ++ enetsw_writeb(priv, rgmii_ctrl, ENETSW_RGMII_CTRL_REG(i)); ++ } ++ + /* reset mib */ + val = enetsw_readb(priv, ENETSW_GMCR_REG); + val |= ENETSW_GMCR_RST_MIB_MASK; diff --git a/target/linux/brcm63xx/patches-3.3/423-bcm63xx_enet-fix-lockup-on-BCM6328.patch b/target/linux/brcm63xx/patches-3.3/423-bcm63xx_enet-fix-lockup-on-BCM6328.patch new file mode 100644 index 000000000..4306ce753 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/423-bcm63xx_enet-fix-lockup-on-BCM6328.patch @@ -0,0 +1,93 @@ +From 382a0b0dc4cbd0e0fbfd6c2d132e972c3d1245b0 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sun, 13 Nov 2011 14:59:37 +0100 +Subject: [PATCH 39/84] bcm63xx_enet: fix lockup on BCM6328 + +BCM6328 locks up on a maxburst size of 16, reduce it to 8 for BCM6328 and +BCM6368. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + drivers/net/ethernet/broadcom/bcm63xx_enet.c | 13 +++++++------ + drivers/net/ethernet/broadcom/bcm63xx_enet.h | 4 ++++ + 2 files changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c +@@ -261,7 +261,6 @@ static int bcm_enet_refill_rx(struct net + if (!skb) + break; + priv->rx_skb[desc_idx] = skb; +- + p = dma_map_single(&priv->pdev->dev, skb->data, + priv->rx_skb_size, + DMA_FROM_DEVICE); +@@ -995,9 +994,9 @@ static int bcm_enet_open(struct net_devi + enet_writel(priv, priv->hw_mtu, ENET_TXMAXLEN_REG); + + /* set dma maximum burst len */ +- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ enet_dmac_writel(priv, priv->dma_maxburst, + ENETDMAC_MAXBURST_REG(priv->rx_chan)); +- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ enet_dmac_writel(priv, priv->dma_maxburst, + ENETDMAC_MAXBURST_REG(priv->tx_chan)); + + /* set correct transmit fifo watermark */ +@@ -1593,7 +1592,7 @@ static int compute_hw_mtu(struct bcm_ene + * it's appended + */ + priv->rx_skb_size = ALIGN(actual_mtu + ETH_FCS_LEN, +- BCMENET_DMA_MAXBURST * 4); ++ priv->dma_maxburst * 4); + return 0; + } + +@@ -1701,6 +1700,7 @@ static int __devinit bcm_enet_probe(stru + priv = netdev_priv(dev); + + priv->enet_is_sw = false; ++ priv->dma_maxburst = BCMENET_DMA_MAXBURST; + + ret = compute_hw_mtu(priv, dev->mtu); + if (ret) +@@ -2282,9 +2282,9 @@ static int bcm_enetsw_open(struct net_de + enet_dmas_writel(priv, 0, ENETDMAS_SRAM4_REG(priv->tx_chan)); + + /* set dma maximum burst len */ +- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ enet_dmac_writel(priv, priv->dma_maxburst, + ENETDMAC_MAXBURST_REG(priv->rx_chan)); +- enet_dmac_writel(priv, BCMENET_DMA_MAXBURST, ++ enet_dmac_writel(priv, priv->dma_maxburst, + ENETDMAC_MAXBURST_REG(priv->tx_chan)); + + /* set flow control low/high threshold to 1/3 / 2/3 */ +@@ -2749,6 +2749,7 @@ static int __devinit bcm_enetsw_probe(st + priv->irq_tx = irq_tx; + priv->rx_ring_size = BCMENET_DEF_RX_DESC; + priv->tx_ring_size = BCMENET_DEF_TX_DESC; ++ priv->dma_maxburst = BCMENETSW_DMA_MAXBURST; + + pd = pdev->dev.platform_data; + if (pd) { +--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h ++++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h +@@ -17,6 +17,7 @@ + + /* maximum burst len for dma (4 bytes unit) */ + #define BCMENET_DMA_MAXBURST 16 ++#define BCMENETSW_DMA_MAXBURST 8 + + /* tx transmit threshold (4 bytes unit), fifo is 256 bytes, the value + * must be low enough so that a DMA transfer of above burst length can +@@ -280,6 +281,9 @@ struct bcm_enet_priv { + /* number of dma desc in tx ring */ + int tx_ring_size; + ++ /* maximum dma burst size */ ++ int dma_maxburst; ++ + /* cpu view of rx dma ring */ + struct bcm_enet_desc *tx_desc_cpu; + diff --git a/target/linux/brcm63xx/patches-3.3/424-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch b/target/linux/brcm63xx/patches-3.3/424-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch new file mode 100644 index 000000000..e665249c5 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/424-MIPS-BCM63XX-add-support-for-BCM6328-in-bcm_enetsw.patch @@ -0,0 +1,103 @@ +From f1c1bfa89cdac76a215d0e21161da9f8f8373437 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 14 Jun 2011 21:14:39 +0200 +Subject: [PATCH 40/84] MIPS: BCM63XX: add support for BCM6328 in bcm_enetsw + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/clk.c | 34 ++++++++++++++----- + arch/mips/bcm63xx/dev-enet.c | 9 +++-- + .../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 1 + + 3 files changed, 32 insertions(+), 12 deletions(-) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -118,21 +118,37 @@ static struct clk clk_ephy = { + */ + static void enetsw_set(struct clk *clk, int enable) + { +- if (!BCMCPU_IS_6368()) ++ u32 mask; ++ ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368()) + return; +- bcm_hwclock_set(CKCTL_6368_ROBOSW_EN | +- CKCTL_6368_SWPKT_USB_EN | +- CKCTL_6368_SWPKT_SAR_EN, enable); ++ ++ if (BCMCPU_IS_6328()) ++ mask = CKCTL_6328_ROBOSW_EN; ++ else ++ mask = CKCTL_6368_ROBOSW_EN | CKCTL_6368_SWPKT_USB_EN | ++ CKCTL_6368_SWPKT_SAR_EN; ++ ++ bcm_hwclock_set(mask, enable); + if (enable) { ++ u32 reg; + u32 val; + ++ if (BCMCPU_IS_6328()) { ++ reg = PERF_SOFTRESET_6328_REG; ++ mask = SOFTRESET_6328_ENETSW_MASK; ++ } else { ++ reg = PERF_SOFTRESET_6368_REG; ++ mask = SOFTRESET_6368_ENETSW_MASK; ++ } ++ + /* reset switch core afer clock change */ +- val = bcm_perf_readl(PERF_SOFTRESET_6368_REG); +- val &= ~SOFTRESET_6368_ENETSW_MASK; +- bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); ++ val = bcm_perf_readl(reg); ++ val &= ~mask; ++ bcm_perf_writel(val, reg); + msleep(10); +- val |= SOFTRESET_6368_ENETSW_MASK; +- bcm_perf_writel(val, PERF_SOFTRESET_6368_REG); ++ val |= mask; ++ bcm_perf_writel(val, reg); + msleep(10); + } + } +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -141,7 +141,7 @@ static int __init register_shared(void) + shared_res[0].end = shared_res[0].start; + shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; + +- if (BCMCPU_IS_6368()) ++ if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) + chan_count = 32; + else + chan_count = 16; +@@ -224,7 +224,7 @@ bcm63xx_enetsw_register(const struct bcm + { + int ret; + +- if (!BCMCPU_IS_6368()) ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368()) + return -ENODEV; + + ret = register_shared(); +@@ -241,7 +241,10 @@ bcm63xx_enetsw_register(const struct bcm + + memcpy(bcm63xx_enetsw_device.dev.platform_data, pd, sizeof (*pd)); + +- enetsw_pd.num_ports = ENETSW_PORTS_6368; ++ if (BCMCPU_IS_6328()) ++ enetsw_pd.num_ports = ENETSW_PORTS_6328; ++ else if (BCMCPU_IS_6368()) ++ enetsw_pd.num_ports = ENETSW_PORTS_6368; + + ret = platform_device_register(&bcm63xx_enetsw_device); + if (ret) +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +@@ -43,6 +43,7 @@ struct bcm63xx_enet_platform_data { + * on board ethernet switch platform data + */ + #define ENETSW_MAX_PORT 6 ++#define ENETSW_PORTS_6328 5 /* 4 FE PHY + 1 RGMII */ + #define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */ + + #define ENETSW_RGMII_PORT0 4 diff --git a/target/linux/brcm63xx/patches-3.3/425-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch b/target/linux/brcm63xx/patches-3.3/425-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch new file mode 100644 index 000000000..5b2534467 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/425-MIPS-BCM63XX-add-HS-SPI-platform-device-and-register.patch @@ -0,0 +1,128 @@ +From 56be5a2d7e08faa7bb306faaf352ac4e6ac52c01 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sat, 12 Nov 2011 12:18:26 +0100 +Subject: [PATCH 26/60] MIPS: BCM63XX: add HS SPI platform device and register it + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/Makefile | 5 +- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 + + arch/mips/bcm63xx/dev-hsspi.c | 57 ++++++++++++++++++++ + .../include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h | 20 +++++++ + 4 files changed, 82 insertions(+), 2 deletions(-) + create mode 100644 arch/mips/bcm63xx/dev-hsspi.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,6 +1,7 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ +- dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \ +- dev-spi.o dev-uart.o dev-usb-ehci.o dev-usb-ohci.o dev-wdt.o ++ dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o dev-pcmcia.o \ ++ dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ ++ dev-usb-ohci.o dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -25,6 +25,7 @@ + #include <bcm63xx_dev_enet.h> + #include <bcm63xx_dev_dsp.h> + #include <bcm63xx_dev_flash.h> ++#include <bcm63xx_dev_hsspi.h> + #include <bcm63xx_dev_pcmcia.h> + #include <bcm63xx_dev_spi.h> + #include <bcm63xx_dev_usb_ohci.h> +@@ -945,6 +946,7 @@ int __init board_register_devices(void) + pr_err(PFX "failed to register fallback SPROM\n"); + } + #endif ++ bcm63xx_hsspi_register(); + + bcm63xx_spi_register(); + +--- /dev/null ++++ b/arch/mips/bcm63xx/dev-hsspi.c +@@ -0,0 +1,57 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com> ++ */ ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/platform_device.h> ++ ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_dev_hsspi.h> ++#include <bcm63xx_regs.h> ++ ++static struct resource spi_resources[] = { ++ { ++ .start = -1, /* filled at runtime */ ++ .end = -1, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ }, ++ { ++ .start = -1, /* filled at runtime */ ++ .flags = IORESOURCE_IRQ, ++ }, ++}; ++ ++static struct bcm63xx_hsspi_pdata spi_pdata = { ++ .bus_num = 0, ++}; ++ ++static struct platform_device bcm63xx_hsspi_device = { ++ .name = "bcm63xx-hsspi", ++ .id = 0, ++ .num_resources = ARRAY_SIZE(spi_resources), ++ .resource = spi_resources, ++ .dev = { ++ .platform_data = &spi_pdata, ++ }, ++}; ++ ++int __init bcm63xx_hsspi_register(void) ++{ ++ ++ if (!BCMCPU_IS_6328()) ++ return -ENODEV; ++ ++ spi_resources[0].start = bcm63xx_regset_address(RSET_HSSPI); ++ spi_resources[0].end = spi_resources[0].start; ++ spi_resources[0].end += RSET_HSSPI_SIZE - 1; ++ spi_resources[1].start = bcm63xx_get_irq_number(IRQ_HSSPI); ++ ++ spi_pdata.speed_hz = HSSPI_PLL_HZ_6328; ++ ++ return platform_device_register(&bcm63xx_hsspi_device); ++} +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h +@@ -0,0 +1,20 @@ ++#ifndef BCM63XX_DEV_HSSPI_H ++#define BCM63XX_DEV_HSSPI_H ++ ++#include <linux/types.h> ++#include <bcm63xx_io.h> ++#include <bcm63xx_regs.h> ++ ++int __init bcm63xx_hsspi_register(void); ++ ++struct bcm63xx_hsspi_pdata { ++ int bus_num; ++ u32 speed_hz; ++}; ++ ++#define bcm_hsspi_readl(o) bcm_rset_readl(RSET_HSSPI, (o)) ++#define bcm_hsspi_writel(v, o) bcm_rset_writel(RSET_HSSPI, (v), (o)) ++ ++#define HSSPI_PLL_HZ_6328 133333333 ++ ++#endif /* BCM63XX_DEV_HSSPI_H */ diff --git a/target/linux/brcm63xx/patches-3.3/426-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch b/target/linux/brcm63xx/patches-3.3/426-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch new file mode 100644 index 000000000..739c2c60f --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/426-SPI-MIPS-BCM63XX-Add-HS-SPI-driver.patch @@ -0,0 +1,481 @@ +From 4b27423676485d05bcd6fc6f3809164fb8f9d22d Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sat, 12 Nov 2011 12:19:55 +0100 +Subject: [PATCH 30/60] SPI: MIPS: BCM63XX: Add HSSPI driver + +Add a driver for the High Speed SPI controller found on newer BCM63XX SoCs. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + .../include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h | 2 + + drivers/spi/Kconfig | 7 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-bcm63xx-hsspi.c | 427 ++++++++++++++++++++ + 4 files changed, 437 insertions(+), 0 deletions(-) + create mode 100644 drivers/spi/spi-bcm63xx-hsspi.c + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h +@@ -17,4 +17,6 @@ struct bcm63xx_hsspi_pdata { + + #define HSSPI_PLL_HZ_6328 133333333 + ++#define HSSPI_BUFFER_LEN 512 ++ + #endif /* BCM63XX_DEV_HSSPI_H */ +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -100,6 +100,13 @@ config SPI_BCM63XX + help + Enable support for the SPI controller on the Broadcom BCM63xx SoCs. + ++config SPI_BCM63XX_HSSPI ++ tristate "Broadcom BCM63XX HS SPI controller driver" ++ depends on BCM63XX ++ help ++ This enables support for the High Speed SPI controller present on ++ newer Broadcom BCM63XX SoCs. ++ + config SPI_BITBANG + tristate "Utilities for Bitbanging SPI masters" + help +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o + obj-$(CONFIG_SPI_ATH79) += spi-ath79.o + obj-$(CONFIG_SPI_AU1550) += spi-au1550.o + obj-$(CONFIG_SPI_BCM63XX) += spi-bcm63xx.o ++obj-$(CONFIG_SPI_BCM63XX_HSSPI) += spi-bcm63xx-hsspi.o + obj-$(CONFIG_SPI_BFIN) += spi-bfin5xx.o + obj-$(CONFIG_SPI_BFIN_SPORT) += spi-bfin-sport.o + obj-$(CONFIG_SPI_BITBANG) += spi-bitbang.o +--- /dev/null ++++ b/drivers/spi/spi-bcm63xx-hsspi.c +@@ -0,0 +1,427 @@ ++/* ++ * Broadcom BCM63XX High Speed SPI Controller driver ++ * ++ * Copyright 2000-2010 Broadcom Corporation ++ * Copyright 2012 Jonas Gorski <jonas.gorski@gmail.com> ++ * ++ * Licensed under the GNU/GPL. See COPYING for details. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/io.h> ++#include <linux/clk.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/delay.h> ++#include <linux/dma-mapping.h> ++#include <linux/err.h> ++#include <linux/interrupt.h> ++#include <linux/spi/spi.h> ++#include <linux/workqueue.h> ++ ++#include <bcm63xx_regs.h> ++#include <bcm63xx_dev_hsspi.h> ++ ++#define HSSPI_OP_CODE_SHIFT 13 ++#define HSSPI_OP_SLEEP (0 << HSSPI_OP_CODE_SHIFT) ++#define HSSPI_OP_READ_WRITE (1 << HSSPI_OP_CODE_SHIFT) ++#define HSSPI_OP_WRITE (2 << HSSPI_OP_CODE_SHIFT) ++#define HSSPI_OP_READ (3 << HSSPI_OP_CODE_SHIFT) ++ ++#define HSSPI_MAX_PREPEND_LEN 15 ++ ++#define HSSPI_MAX_SYNC_CLOCK 30000000 ++ ++struct bcm63xx_hsspi { ++ struct completion done; ++ struct spi_transfer *curr_trans; ++ ++ struct platform_device *pdev; ++ struct clk *clk; ++ void __iomem *regs; ++ u8 __iomem *fifo; ++ ++ u32 speed_hz; ++ int irq; ++}; ++ ++static void bcm63xx_hsspi_set_clk(struct bcm63xx_hsspi *bs, int hz, ++ int profile) ++{ ++ u32 reg; ++ ++ reg = DIV_ROUND_UP(2048, DIV_ROUND_UP(bs->speed_hz, hz)); ++ bcm_hsspi_writel(CLK_CTRL_ACCUM_RST_ON_LOOP | reg, ++ HSSPI_PROFILE_CLK_CTRL_REG(profile)); ++ ++ reg = bcm_hsspi_readl(HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); ++ if (hz > HSSPI_MAX_SYNC_CLOCK) ++ reg |= SIGNAL_CTRL_ASYNC_INPUT_PATH; ++ else ++ reg &= ~SIGNAL_CTRL_ASYNC_INPUT_PATH; ++ bcm_hsspi_writel(reg, HSSPI_PROFILE_SIGNAL_CTRL_REG(profile)); ++} ++ ++static int bcm63xx_hsspi_do_txrx(struct spi_device *spi, ++ struct spi_transfer *t1, ++ struct spi_transfer *t2) ++{ ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(spi->master); ++ u8 chip_select = spi->chip_select; ++ u16 opcode = 0; ++ int len, prepend_size = 0; ++ ++ init_completion(&bs->done); ++ ++ bs->curr_trans = t2 ? t2 : t1; ++ bcm63xx_hsspi_set_clk(bs, bs->curr_trans->speed_hz, chip_select); ++ ++ if (t2 && !t2->tx_buf) ++ prepend_size = t1->len; ++ ++ bcm_hsspi_writel(prepend_size << MODE_CTRL_PREPENDBYTE_CNT_SHIFT | ++ 2 << MODE_CTRL_MULTIDATA_WR_STRT_SHIFT | ++ 2 << MODE_CTRL_MULTIDATA_RD_STRT_SHIFT | 0xff, ++ HSSPI_PROFILE_MODE_CTRL_REG(chip_select)); ++ ++ if (t1->rx_buf && t1->tx_buf) ++ opcode = HSSPI_OP_READ_WRITE; ++ else if (t1->rx_buf || (t2 && t2->rx_buf)) ++ opcode = HSSPI_OP_READ; ++ else if (t1->tx_buf) ++ opcode = HSSPI_OP_WRITE; ++ ++ if (opcode == HSSPI_OP_READ && t2) ++ len = t2->len; ++ else ++ len = t1->len; ++ ++ if (t1->tx_buf) { ++ memcpy_toio(bs->fifo + 2, t1->tx_buf, t1->len); ++ if (t2 && t2->tx_buf) { ++ memcpy_toio(bs->fifo + 2 + t1->len, ++ t2->tx_buf, t2->len); ++ len += t2->len; ++ } ++ } ++ ++ opcode |= len; ++ memcpy_toio(bs->fifo, &opcode, sizeof(opcode)); ++ ++ /* enable interrupt */ ++ bcm_hsspi_writel(HSSPI_PING0_CMD_DONE, HSSPI_INT_MASK_REG); ++ ++ /* start the transfer */ ++ bcm_hsspi_writel(chip_select << PINGPONG_CMD_SS_SHIFT | ++ chip_select << PINGPONG_CMD_PROFILE_SHIFT | ++ PINGPONG_COMMAND_START_NOW, ++ HSSPI_PINGPONG_COMMAND_REG(0)); ++ ++ if (wait_for_completion_timeout(&bs->done, HZ) == 0) { ++ dev_err(&bs->pdev->dev, "transfer timed out!\n"); ++ return -ETIMEDOUT; ++ } ++ ++ return t1->len + (t2 ? t2->len : 0); ++} ++ ++static int bcm63xx_hsspi_setup(struct spi_device *spi) ++{ ++ u32 reg; ++ ++ if (spi->bits_per_word != 8) ++ return -EINVAL; ++ ++ if (spi->max_speed_hz == 0) ++ return -EINVAL; ++ ++ reg = bcm_hsspi_readl(HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); ++ reg &= ~(SIGNAL_CTRL_LAUNCH_RISING | SIGNAL_CTRL_LATCH_RISING); ++ if (spi->mode & SPI_CPHA) ++ reg |= SIGNAL_CTRL_LAUNCH_RISING; ++ else ++ reg |= SIGNAL_CTRL_LATCH_RISING; ++ bcm_hsspi_writel(reg, HSSPI_PROFILE_SIGNAL_CTRL_REG(spi->chip_select)); ++ ++ return 0; ++} ++ ++static int bcm63xx_hsspi_transfer_one(struct spi_master *master, ++ struct spi_message *msg) ++{ ++ struct spi_transfer *t, *prev = NULL; ++ struct spi_device *spi = msg->spi; ++ u32 reg; ++ int ret = -EINVAL; ++ int len = 0; ++ ++ /* check if we are able to make these transfers */ ++ list_for_each_entry(t, &msg->transfers, transfer_list) { ++ if (!t->tx_buf && !t->rx_buf) ++ goto out; ++ ++ if (t->speed_hz == 0) ++ t->speed_hz = spi->max_speed_hz; ++ ++ if (t->speed_hz > spi->max_speed_hz) ++ goto out; ++ ++ if (t->len > HSSPI_BUFFER_LEN) ++ goto out; ++ ++ /* ++ * This controller does not support keeping the chip select ++ * active between transfers. ++ * This logic currently supports combining: ++ * write then read with no cs_change (e.g. m25p80 RDSR) ++ * write then write with no cs_change (e.g. m25p80 PP) ++ */ ++ if (prev && prev->tx_buf && !prev->cs_change && !t->cs_change) { ++ /* ++ * reject if we have to combine two tx transfers and ++ * their combined length is bigger than the buffer ++ */ ++ if (prev->tx_buf && t->tx_buf && ++ (prev->len + t->len) > HSSPI_BUFFER_LEN) ++ goto out; ++ /* ++ * reject if we need write more than 15 bytes in read ++ * then write. ++ */ ++ if (prev->tx_buf && t->rx_buf && ++ prev->len > HSSPI_MAX_PREPEND_LEN) ++ goto out; ++ } ++ ++ } ++ ++ /* setup clock polarity */ ++ reg = bcm_hsspi_readl(HSSPI_GLOBAL_CTRL_REG); ++ reg &= ~GLOBAL_CTRL_CLK_POLARITY; ++ if (spi->mode & SPI_CPOL) ++ reg |= GLOBAL_CTRL_CLK_POLARITY; ++ bcm_hsspi_writel(reg, HSSPI_GLOBAL_CTRL_REG); ++ ++ list_for_each_entry(t, &msg->transfers, transfer_list) { ++ if (prev && prev->tx_buf && !prev->cs_change && !t->cs_change) { ++ /* combine write with following transfer */ ++ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, t); ++ if (ret < 0) ++ goto out; ++ ++ len += ret; ++ prev = NULL; ++ continue; ++ } ++ ++ /* write the previous pending transfer */ ++ if (prev != NULL) { ++ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, NULL); ++ if (ret < 0) ++ goto out; ++ ++ len += ret; ++ } ++ ++ prev = t; ++ } ++ ++ /* do last pending transfer */ ++ if (prev != NULL) { ++ ret = bcm63xx_hsspi_do_txrx(msg->spi, prev, NULL); ++ if (ret < 0) ++ goto out; ++ len += ret; ++ } ++ ++ msg->actual_length = len; ++ ret = 0; ++out: ++ msg->status = ret; ++ spi_finalize_current_message(master); ++ return 0; ++} ++ ++static irqreturn_t bcm63xx_hsspi_interrupt(int irq, void *dev_id) ++{ ++ struct spi_master *master = (struct spi_master *)dev_id; ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); ++ ++ if (bcm_hsspi_readl(HSSPI_INT_STATUS_MASKED_REG) == 0) ++ return IRQ_NONE; ++ ++ bcm_hsspi_writel(HSSPI_INT_CLEAR_ALL, HSSPI_INT_STATUS_REG); ++ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); ++ ++ if (bs->curr_trans && bs->curr_trans->rx_buf) ++ memcpy_fromio(bs->curr_trans->rx_buf, bs->fifo, ++ bs->curr_trans->len); ++ complete(&bs->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int __devinit bcm63xx_hsspi_probe(struct platform_device *pdev) ++{ ++ ++ struct spi_master *master; ++ struct bcm63xx_hsspi *bs; ++ struct resource *res_mem; ++ void __iomem *regs; ++ struct device *dev = &pdev->dev; ++ struct bcm63xx_hsspi_pdata *pdata = pdev->dev.platform_data; ++ struct clk *clk; ++ int irq; ++ int ret; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(dev, "no irq\n"); ++ return -ENXIO; ++ } ++ ++ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ regs = devm_request_and_ioremap(dev, res_mem); ++ if (!regs) { ++ dev_err(dev, "unable to ioremap regs\n"); ++ return -ENXIO; ++ } ++ ++ clk = clk_get(dev, "hsspi"); ++ ++ if (IS_ERR(clk)) { ++ ret = PTR_ERR(clk); ++ goto out_release; ++ } ++ ++ clk_prepare_enable(clk); ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(*bs)); ++ if (!master) { ++ ret = -ENOMEM; ++ goto out_disable_clk; ++ } ++ ++ bs = spi_master_get_devdata(master); ++ bs->pdev = pdev; ++ bs->clk = clk; ++ bs->regs = regs; ++ ++ master->bus_num = pdata->bus_num; ++ master->num_chipselect = 8; ++ master->setup = bcm63xx_hsspi_setup; ++ master->transfer_one_message = bcm63xx_hsspi_transfer_one; ++ master->mode_bits = SPI_CPOL | SPI_CPHA; ++ ++ bs->speed_hz = pdata->speed_hz; ++ bs->fifo = (u8 __iomem *)(bs->regs + HSSPI_FIFO_REG(0)); ++ ++ platform_set_drvdata(pdev, master); ++ ++ bs->curr_trans = NULL; ++ ++ /* Initialize the hardware */ ++ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); ++ ++ /* clean up any pending interrupts */ ++ bcm_hsspi_writel(HSSPI_INT_CLEAR_ALL, HSSPI_INT_STATUS_REG); ++ ++ bcm_hsspi_writel(bcm_hsspi_readl(HSSPI_GLOBAL_CTRL_REG) | ++ GLOBAL_CTRL_CLK_GATE_SSOFF, ++ HSSPI_GLOBAL_CTRL_REG); ++ ++ ret = devm_request_irq(dev, irq, bcm63xx_hsspi_interrupt, IRQF_SHARED, ++ pdev->name, master); ++ ++ if (ret) ++ goto out_put_master; ++ ++ /* register and we are done */ ++ ret = spi_register_master(master); ++ if (ret) ++ goto out_free_irq; ++ ++ return 0; ++ ++out_free_irq: ++ devm_free_irq(dev, bs->irq, master); ++out_put_master: ++ spi_master_put(master); ++out_disable_clk: ++ clk_disable_unprepare(clk); ++ clk_put(clk); ++out_release: ++ devm_ioremap_release(dev, regs); ++ ++ return ret; ++} ++ ++ ++static int __exit bcm63xx_hsspi_remove(struct platform_device *pdev) ++{ ++ struct spi_master *master = platform_get_drvdata(pdev); ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); ++ ++ spi_unregister_master(master); ++ ++ /* reset the hardware and block queue progress */ ++ bcm_hsspi_writel(0, HSSPI_INT_MASK_REG); ++ clk_disable_unprepare(bs->clk); ++ clk_put(bs->clk); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM ++static int bcm63xx_hsspi_suspend(struct platform_device *pdev, ++ pm_message_t mesg) ++{ ++ struct spi_master *master = platform_get_drvdata(pdev); ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); ++ ++ spi_master_suspend(master); ++ clk_disable(bs->clk); ++ ++ return 0; ++} ++ ++static int bcm63xx_hsspi_resume(struct platform_device *pdev) ++{ ++ struct spi_master *master = platform_get_drvdata(pdev); ++ struct bcm63xx_hsspi *bs = spi_master_get_devdata(master); ++ ++ clk_enable(bs->clk); ++ spi_master_resume(master); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops bcm63xx_hsspi_pm_ops = { ++ .suspend = bcm63xx_hsspi_suspend, ++ .resume = bcm63xx_hsspi_resume, ++}; ++ ++#define BCM63XX_HSSPI_PM_OPS (&bcm63xx_hsspi_pm_ops) ++#else ++#define BCM63XX_HSSPI_PM_OPS NULL ++#endif ++ ++ ++ ++static struct platform_driver bcm63xx_hsspi_driver = { ++ .driver = { ++ .name = "bcm63xx-hsspi", ++ .owner = THIS_MODULE, ++ .pm = BCM63XX_HSSPI_PM_OPS, ++ }, ++ .probe = bcm63xx_hsspi_probe, ++ .remove = __exit_p(bcm63xx_hsspi_remove), ++}; ++ ++module_platform_driver(bcm63xx_hsspi_driver); ++ ++MODULE_ALIAS("platform:bcm63xx_hsspi"); ++MODULE_DESCRIPTION("Broadcom BCM63xx HS SPI Controller driver"); ++MODULE_AUTHOR("Jonas Gorski <jonas.gorski@gmail.com>"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-Register-SPI-flash-if-present.patch b/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-Register-SPI-flash-if-present.patch new file mode 100644 index 000000000..14776af76 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/427-MIPS-BCM63XX-Register-SPI-flash-if-present.patch @@ -0,0 +1,102 @@ +From d135d94b3d1fe599d13e7198d5f502912d694c13 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sun, 3 Jul 2011 15:00:38 +0200 +Subject: [PATCH 29/60] MIPS: BCM63XX: Register SPI flash if present + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/dev-flash.c | 33 +++++++++++++++++++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 2 + + 2 files changed, 33 insertions(+), 2 deletions(-) + +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -16,9 +16,12 @@ + #include <linux/mtd/mtd.h> + #include <linux/mtd/partitions.h> + #include <linux/mtd/physmap.h> ++#include <linux/spi/spi.h> ++#include <linux/spi/flash.h> + + #include <bcm63xx_cpu.h> + #include <bcm63xx_dev_flash.h> ++#include <bcm63xx_dev_hsspi.h> + #include <bcm63xx_regs.h> + #include <bcm63xx_io.h> + +@@ -55,6 +58,21 @@ static struct platform_device mtd_dev = + }, + }; + ++static struct flash_platform_data bcm63xx_flash_data = { ++ .part_probe_types = bcm63xx_part_types, ++}; ++ ++static struct spi_board_info bcm63xx_spi_flash_info[] = { ++ { ++ .bus_num = 0, ++ .chip_select = 0, ++ .mode = 0, ++ .max_speed_hz = 781000, ++ .modalias = "m25p80", ++ .platform_data = &bcm63xx_flash_data, ++ }, ++}; ++ + static int __init bcm63xx_detect_flash_type(void) + { + u32 val; +@@ -62,6 +80,11 @@ static int __init bcm63xx_detect_flash_t + switch (bcm63xx_get_cpu_id()) { + case BCM6328_CPU_ID: + val = bcm_misc_readl(MISC_STRAPBUS_6328_REG); ++ if (val & STRAPBUS_6328_HSSPI_CLK_FAST) ++ bcm63xx_spi_flash_info[0].max_speed_hz = 33333334; ++ else ++ bcm63xx_spi_flash_info[0].max_speed_hz = 16666667; ++ + if (val & STRAPBUS_6328_BOOT_SEL_SERIAL) + return BCM63XX_FLASH_TYPE_SERIAL; + else +@@ -79,6 +102,9 @@ static int __init bcm63xx_detect_flash_t + return BCM63XX_FLASH_TYPE_SERIAL; + case BCM6368_CPU_ID: + val = bcm_gpio_readl(GPIO_STRAPBUS_REG); ++ if (val & STRAPBUS_6368_SPI_CLK_FAST) ++ bcm63xx_spi_flash_info[0].max_speed_hz = 20000000; ++ + switch (val & STRAPBUS_6368_BOOT_SEL_MASK) { + case STRAPBUS_6368_BOOT_SEL_NAND: + return BCM63XX_FLASH_TYPE_NAND; +@@ -110,8 +136,11 @@ int __init bcm63xx_flash_register(void) + + return platform_device_register(&mtd_dev); + case BCM63XX_FLASH_TYPE_SERIAL: +- pr_warn("unsupported serial flash detected\n"); +- return -ENODEV; ++ if (BCMCPU_IS_6328()) ++ bcm63xx_flash_data.max_transfer_len = HSSPI_BUFFER_LEN; ++ ++ return spi_register_board_info(bcm63xx_spi_flash_info, ++ ARRAY_SIZE(bcm63xx_spi_flash_info)); + case BCM63XX_FLASH_TYPE_NAND: + pr_warn("unsupported NAND flash detected\n"); + return -ENODEV; +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -614,6 +614,7 @@ + #define GPIO_STRAPBUS_REG 0x40 + #define STRAPBUS_6358_BOOT_SEL_PARALLEL (1 << 1) + #define STRAPBUS_6358_BOOT_SEL_SERIAL (0 << 1) ++#define STRAPBUS_6368_SPI_CLK_FAST (1 << 6) + #define STRAPBUS_6368_BOOT_SEL_MASK 0x3 + #define STRAPBUS_6368_BOOT_SEL_NAND 0 + #define STRAPBUS_6368_BOOT_SEL_SERIAL 1 +@@ -1308,6 +1309,7 @@ + #define STRAPBUS_6362_BOOT_SEL_NAND (0 << 15) + + #define MISC_STRAPBUS_6328_REG 0x240 ++#define STRAPBUS_6328_HSSPI_CLK_FAST (1 << 4) + #define STRAPBUS_6328_FCVO_SHIFT 7 + #define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT) + #define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28) diff --git a/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-add-flash-detection-for-BCM6362.patch b/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-add-flash-detection-for-BCM6362.patch new file mode 100644 index 000000000..98a229b1a --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-add-flash-detection-for-BCM6362.patch @@ -0,0 +1,50 @@ +From d9666553a10ea85ea64e3e8784a42167a1709ed5 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Mon, 21 Nov 2011 00:48:52 +0100 +Subject: [PATCH 55/84] MIPS: BCM63XX: add flash detection for BCM6362 + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/dev-flash.c | 13 ++++++++++++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 1 + + 2 files changed, 13 insertions(+), 1 deletions(-) + +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -100,6 +100,17 @@ static int __init bcm63xx_detect_flash_t + return BCM63XX_FLASH_TYPE_PARALLEL; + else + return BCM63XX_FLASH_TYPE_SERIAL; ++ case BCM6362_CPU_ID: ++ val = bcm_misc_readl(MISC_STRAPBUS_6362_REG); ++ if (val & STRAPBUS_6362_HSSPI_CLK_FAST) ++ bcm63xx_spi_flash_info[0].max_speed_hz = 50000000; ++ else ++ bcm63xx_spi_flash_info[0].max_speed_hz = 20000000; ++ ++ if (val & STRAPBUS_6362_BOOT_SEL_SERIAL) ++ return BCM63XX_FLASH_TYPE_SERIAL; ++ else ++ return BCM63XX_FLASH_TYPE_NAND; + case BCM6368_CPU_ID: + val = bcm_gpio_readl(GPIO_STRAPBUS_REG); + if (val & STRAPBUS_6368_SPI_CLK_FAST) +@@ -136,7 +147,7 @@ int __init bcm63xx_flash_register(void) + + return platform_device_register(&mtd_dev); + case BCM63XX_FLASH_TYPE_SERIAL: +- if (BCMCPU_IS_6328()) ++ if (BCMCPU_IS_6328() || BCMCPU_IS_6362()) + bcm63xx_flash_data.max_transfer_len = HSSPI_BUFFER_LEN; + + return spi_register_board_info(bcm63xx_spi_flash_info, +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -1304,6 +1304,7 @@ + + #define MISC_STRAPBUS_6362_REG 0x14 + #define STRAPBUS_6362_FCVO_SHIFT 1 ++#define STRAPBUS_6362_HSSPI_CLK_FAST (1 << 13) + #define STRAPBUS_6362_FCVO_MASK (0x1f << STRAPBUS_6362_FCVO_SHIFT) + #define STRAPBUS_6362_BOOT_SEL_SERIAL (1 << 15) + #define STRAPBUS_6362_BOOT_SEL_NAND (0 << 15) diff --git a/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch b/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch new file mode 100644 index 000000000..ff2a831d8 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/428-MIPS-BCM63XX-move-nvram-related-functions-into-their.patch @@ -0,0 +1,351 @@ +From 5b753c1d01c6af23d7d37d37d9de30da8a971084 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sat, 12 May 2012 22:51:08 +0200 +Subject: [PATCH 60/79] MIPS: BCM63XX: move nvram related functions into their + own file + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/Makefile | 6 +- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 74 +++-------------- + arch/mips/bcm63xx/nvram.c | 84 ++++++++++++++++++++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 34 ++++++++ + .../mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 17 ---- + 5 files changed, 134 insertions(+), 81 deletions(-) + create mode 100644 arch/mips/bcm63xx/nvram.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,6 +1,6 @@ +-obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \ +- dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o dev-pcmcia.o \ +- dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ ++obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o setup.o \ ++ timer.o dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o \ ++ dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ + dev-usb-ohci.o dev-wdt.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -21,6 +21,7 @@ + #include <bcm63xx_dev_uart.h> + #include <bcm63xx_regs.h> + #include <bcm63xx_io.h> ++#include <bcm63xx_nvram.h> + #include <bcm63xx_dev_pci.h> + #include <bcm63xx_dev_enet.h> + #include <bcm63xx_dev_dsp.h> +@@ -41,8 +42,6 @@ + #define CFE_OFFSET_64K 0x10000 + #define CFE_OFFSET_128K 0x20000 + +-static struct bcm963xx_nvram nvram; +-static unsigned int mac_addr_used; + static struct board_info board; + + /* +@@ -696,50 +695,16 @@ const char *board_get_name(void) + return board.name; + } + +-/* +- * register & return a new board mac address +- */ +-static int board_get_mac_address(u8 *mac) +-{ +- u8 *p; +- int count; +- +- if (mac_addr_used >= nvram.mac_addr_count) { +- printk(KERN_ERR PFX "not enough mac address\n"); +- return -ENODEV; +- } +- +- memcpy(mac, nvram.mac_addr_base, ETH_ALEN); +- p = mac + ETH_ALEN - 1; +- count = mac_addr_used; +- +- while (count--) { +- do { +- (*p)++; +- if (*p != 0) +- break; +- p--; +- } while (p != mac); +- } +- +- if (p == mac) { +- printk(KERN_ERR PFX "unable to fetch mac address\n"); +- return -ENODEV; +- } +- +- mac_addr_used++; +- return 0; +-} +- + static void __init boardid_fixup(u8 *boot_addr) + { + struct bcm_tag *tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_64K); ++ char *board_name = (char *)bcm63xx_nvram_get_name(); + + /* check if bcm_tag is at 64k offset */ +- if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) { ++ if (strncmp(board_name, tag->boardid, BOARDID_LEN) != 0) { + /* else try 128k */ + tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_128K); +- if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) { ++ if (strncmp(board_name, tag->boardid, BOARDID_LEN) != 0) { + /* No tag found */ + printk(KERN_DEBUG "No bcm_tag found!\n"); + return; +@@ -749,9 +714,9 @@ static void __init boardid_fixup(u8 *boo + if (tag->information1[0] != '+') + return; + +- strncpy(nvram.name, &tag->information1[1], BOARDID_LEN); ++ strncpy(board_name, &tag->information1[1], BOARDID_LEN); + +- printk(KERN_INFO "Overriding boardid with '%s'\n", nvram.name); ++ printk(KERN_INFO "Overriding boardid with '%s'\n", board_name); + } + + /* +@@ -759,9 +724,10 @@ static void __init boardid_fixup(u8 *boo + */ + void __init board_prom_init(void) + { +- unsigned int check_len, i; +- u8 *boot_addr, *cfe, *p; ++ unsigned int i; ++ u8 *boot_addr, *cfe; + char cfe_version[32]; ++ char *board_name; + u32 val; + + /* read base address of boot chip select (0) +@@ -786,32 +752,19 @@ void __init board_prom_init(void) + strcpy(cfe_version, "unknown"); + printk(KERN_INFO PFX "CFE version: %s\n", cfe_version); + +- /* extract nvram data */ +- memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram)); +- +- /* check checksum before using data */ +- if (nvram.version <= 4) +- check_len = offsetof(struct bcm963xx_nvram, checksum_old); +- else +- check_len = sizeof(nvram); +- val = 0; +- p = (u8 *)&nvram; +- while (check_len--) +- val += *p; +- if (val) { +- printk(KERN_ERR PFX "invalid nvram checksum\n"); ++ if (bcm63xx_nvram_init(boot_addr + BCM963XX_NVRAM_OFFSET)) + return; +- } + + if (strcmp(cfe_version, "unknown") != 0) { + /* cfe present */ + boardid_fixup(boot_addr); + } + ++ board_name = bcm63xx_nvram_get_name(); + /* find board by name */ + for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) { +- if (strncmp(nvram.name, bcm963xx_boards[i]->name, +- sizeof(nvram.name))) ++ if (strncmp(board_name, bcm963xx_boards[i]->name, ++ BCM63XX_NVRAM_NAMELEN)) + continue; + /* copy, board desc array is marked initdata */ + memcpy(&board, bcm963xx_boards[i], sizeof(board)); +@@ -821,7 +774,7 @@ void __init board_prom_init(void) + /* bail out if board is not found, will complain later */ + if (!board.name[0]) { + char name[17]; +- memcpy(name, nvram.name, 16); ++ memcpy(name, board_name, 16); + name[16] = 0; + printk(KERN_ERR PFX "unknown bcm963xx board: %s\n", + name); +@@ -914,15 +867,15 @@ int __init board_register_devices(void) + bcm63xx_pcmcia_register(); + + if (board.has_enet0 && +- !board_get_mac_address(board.enet0.mac_addr)) ++ !bcm63xx_nvram_get_mac_address(board.enet0.mac_addr)) + bcm63xx_enet_register(0, &board.enet0); + + if (board.has_enet1 && +- !board_get_mac_address(board.enet1.mac_addr)) ++ !bcm63xx_nvram_get_mac_address(board.enet1.mac_addr)) + bcm63xx_enet_register(1, &board.enet1); + + if (board.has_enetsw && +- !board_get_mac_address(board.enetsw.mac_addr)) ++ !bcm63xx_nvram_get_mac_address(board.enetsw.mac_addr)) + bcm63xx_enetsw_register(&board.enetsw); + + if (board.has_ehci0) +@@ -938,7 +891,7 @@ int __init board_register_devices(void) + * do this after registering enet devices + */ + #ifdef CONFIG_SSB_PCIHOST +- if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { ++ if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { + memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); + memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); + if (ssb_arch_register_fallback_sprom( +--- /dev/null ++++ b/arch/mips/bcm63xx/nvram.c +@@ -0,0 +1,84 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com> ++ */ ++ ++#define pr_fmt(fmt) "bcm63xx_nvram: " fmt ++ ++#include <linux/init.h> ++#include <linux/export.h> ++#include <linux/kernel.h> ++ ++#include <bcm63xx_nvram.h> ++ ++static struct bcm963xx_nvram nvram; ++static int mac_addr_used; ++ ++int __init bcm63xx_nvram_init(void *addr) ++{ ++ unsigned int check_len; ++ u8 *p; ++ u32 val; ++ ++ /* extract nvram data */ ++ memcpy(&nvram, addr, sizeof(nvram)); ++ ++ /* check checksum before using data */ ++ if (nvram.version <= 4) ++ check_len = offsetof(struct bcm963xx_nvram, checksum_old); ++ else ++ check_len = sizeof(nvram); ++ val = 0; ++ p = (u8 *)&nvram; ++ ++ while (check_len--) ++ val += *p; ++ if (val) { ++ pr_err("invalid nvram checksum\n"); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++u8 *bcm63xx_nvram_get_name(void) ++{ ++ return nvram.name; ++} ++EXPORT_SYMBOL(bcm63xx_nvram_get_name); ++ ++int bcm63xx_nvram_get_mac_address(u8 *mac) ++{ ++ u8 *p; ++ int count; ++ ++ if (mac_addr_used >= nvram.mac_addr_count) { ++ pr_err("not enough mac address\n"); ++ return -ENODEV; ++ } ++ ++ memcpy(mac, nvram.mac_addr_base, ETH_ALEN); ++ p = mac + ETH_ALEN - 1; ++ count = mac_addr_used; ++ ++ while (count--) { ++ do { ++ (*p)++; ++ if (*p != 0) ++ break; ++ p--; ++ } while (p != mac); ++ } ++ ++ if (p == mac) { ++ pr_err("unable to fetch mac address\n"); ++ return -ENODEV; ++ } ++ ++ mac_addr_used++; ++ return 0; ++} ++EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +@@ -0,0 +1,34 @@ ++#ifndef BCM63XX_NVRAM_H ++#define BCM63XX_NVRAM_H ++ ++#include <linux/if_ether.h> ++ ++#define BCM63XX_NVRAM_NAMELEN 16 ++ ++/* ++ * nvram structure ++ */ ++struct bcm963xx_nvram { ++ u32 version; ++ u8 reserved1[256]; ++ u8 name[BCM63XX_NVRAM_NAMELEN]; ++ u32 main_tp_number; ++ u32 psi_size; ++ u32 mac_addr_count; ++ u8 mac_addr_base[ETH_ALEN]; ++ u8 reserved2[2]; ++ u32 checksum_old; ++ u8 reserved3[720]; ++ u32 checksum_high; ++}; ++ ++int __init bcm63xx_nvram_init(void *); ++ ++u8 *bcm63xx_nvram_get_name(void); ++ ++/* ++ * register & return a new board mac address ++ */ ++int bcm63xx_nvram_get_mac_address(u8 *mac); ++ ++#endif /* BCM63XX_NVRAM_H */ +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -15,23 +15,6 @@ + #define BCM963XX_NVRAM_OFFSET 0x580 + + /* +- * nvram structure +- */ +-struct bcm963xx_nvram { +- u32 version; +- u8 reserved1[256]; +- u8 name[16]; +- u32 main_tp_number; +- u32 psi_size; +- u32 mac_addr_count; +- u8 mac_addr_base[6]; +- u8 reserved2[2]; +- u32 checksum_old; +- u8 reserved3[720]; +- u32 checksum_high; +-}; +- +-/* + * board definition + */ + struct board_info { diff --git a/target/linux/brcm63xx/patches-3.3/429-MIPS-BCM63XX-export-PSI-size-from-nvram.patch b/target/linux/brcm63xx/patches-3.3/429-MIPS-BCM63XX-export-PSI-size-from-nvram.patch new file mode 100644 index 000000000..34966b27f --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/429-MIPS-BCM63XX-export-PSI-size-from-nvram.patch @@ -0,0 +1,44 @@ +From ffbeb183bf0e9e12fd607c5352f48420c32f588f Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sat, 12 May 2012 23:04:17 +0200 +Subject: [PATCH 61/79] MIPS: BCM63XX: export PSI size from nvram + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/nvram.c | 11 +++++++++++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h | 2 ++ + 2 files changed, 13 insertions(+) + +--- a/arch/mips/bcm63xx/nvram.c ++++ b/arch/mips/bcm63xx/nvram.c +@@ -14,6 +14,8 @@ + + #include <bcm63xx_nvram.h> + ++#define BCM63XX_DEFAULT_PSI_SIZE 64 ++ + static struct bcm963xx_nvram nvram; + static int mac_addr_used; + +@@ -82,3 +84,12 @@ int bcm63xx_nvram_get_mac_address(u8 *ma + return 0; + } + EXPORT_SYMBOL(bcm63xx_nvram_get_mac_address); ++ ++int bcm63xx_nvram_get_psi_size(void) ++{ ++ if (nvram.psi_size > 0) ++ return nvram.psi_size; ++ ++ return BCM63XX_DEFAULT_PSI_SIZE; ++} ++EXPORT_SYMBOL(bcm63xx_nvram_get_psi_size); +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_nvram.h +@@ -31,4 +31,6 @@ u8 *bcm63xx_nvram_get_name(void); + */ + int bcm63xx_nvram_get_mac_address(u8 *mac); + ++int bcm63xx_nvram_get_psi_size(void); ++ + #endif /* BCM63XX_NVRAM_H */ diff --git a/target/linux/brcm63xx/patches-3.3/430-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch b/target/linux/brcm63xx/patches-3.3/430-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch new file mode 100644 index 000000000..5ca6f4797 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/430-MTD-bcm63xxpart-use-nvram-for-PSI-size.patch @@ -0,0 +1,29 @@ +From 658afad639a9456e1bb6fe5bba0032f3c0c3f699 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 1 May 2012 14:10:39 +0200 +Subject: [PATCH 62/79] MTD: bcm63xxpart: use nvram for PSI size + +--- + drivers/mtd/bcm63xxpart.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -32,6 +32,7 @@ + #include <linux/mtd/mtd.h> + #include <linux/mtd/partitions.h> + ++#include <asm/mach-bcm63xx/bcm63xx_nvram.h> + #include <asm/mach-bcm63xx/bcm963xx_tag.h> + #include <asm/mach-bcm63xx/board_bcm963xx.h> + +@@ -90,7 +91,8 @@ static int bcm63xx_parse_cfe_partitions( + BCM63XX_CFE_BLOCK_SIZE); + + cfelen = cfe_erasesize; +- nvramlen = cfe_erasesize; ++ nvramlen = bcm63xx_nvram_get_psi_size() * 1024; ++ nvramlen = roundup(nvramlen, cfe_erasesize); + + /* Allocate memory for buffer */ + buf = vmalloc(sizeof(struct bcm_tag)); diff --git a/target/linux/brcm63xx/patches-3.3/431-MTD-physmap-allow-passing-pp_data.patch b/target/linux/brcm63xx/patches-3.3/431-MTD-physmap-allow-passing-pp_data.patch new file mode 100644 index 000000000..f869911d5 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/431-MTD-physmap-allow-passing-pp_data.patch @@ -0,0 +1,41 @@ +From 266c506f4b262bd6aba0776a03d82c98e65d9906 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 1 May 2012 17:32:36 +0200 +Subject: [PATCH 63/79] MTD: physmap: allow passing pp_data + +--- + drivers/mtd/maps/physmap.c | 4 +++- + include/linux/mtd/physmap.h | 1 + + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/mtd/maps/physmap.c ++++ b/drivers/mtd/maps/physmap.c +@@ -84,6 +84,7 @@ static int physmap_flash_probe(struct pl + { + struct physmap_flash_data *physmap_data; + struct physmap_flash_info *info; ++ struct mtd_part_parser_data *pp_data; + const char **probe_type; + const char **part_types; + int err = 0; +@@ -173,8 +174,9 @@ static int physmap_flash_probe(struct pl + goto err_out; + + part_types = physmap_data->part_probe_types ? : part_probe_types; ++ pp_data = physmap_data->pp_data ? physmap_data->pp_data : NULL; + +- mtd_device_parse_register(info->cmtd, part_types, 0, ++ mtd_device_parse_register(info->cmtd, part_types, pp_data, + physmap_data->parts, physmap_data->nr_parts); + return 0; + +--- a/include/linux/mtd/physmap.h ++++ b/include/linux/mtd/physmap.h +@@ -32,6 +32,7 @@ struct physmap_flash_data { + char *probe_type; + struct mtd_partition *parts; + const char **part_probe_types; ++ struct mtd_part_parser_data *pp_data; + }; + + #endif /* __LINUX_MTD_PHYSMAP__ */ diff --git a/target/linux/brcm63xx/patches-3.3/432-BCM63XX-allow-providing-fixup-data-in-board-data.patch b/target/linux/brcm63xx/patches-3.3/432-BCM63XX-allow-providing-fixup-data-in-board-data.patch new file mode 100644 index 000000000..742d11566 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/432-BCM63XX-allow-providing-fixup-data-in-board-data.patch @@ -0,0 +1,81 @@ +From 5131195413b62df73dfd394fea272830ea8c4e1a Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 3 May 2012 14:40:03 +0200 +Subject: [PATCH 67/80] BCM63XX: allow providing fixup data in board data + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 10 +++++++++- + arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 10 ++++++++++ + 2 files changed, 19 insertions(+), 1 deletion(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -33,6 +33,7 @@ + #include <bcm63xx_dev_usb_ehci.h> + #include <board_bcm963xx.h> + #include <bcm_tag.h> ++#include <pci_ath9k_fixup.h> + + #define PFX "board_bcm963xx: " + +@@ -856,6 +857,7 @@ int __init board_register_devices(void) + { + int button_count = 0; + int led_count = 0; ++ int i; + + if (board.has_uart0) + bcm63xx_uart_register(0); +@@ -891,7 +893,8 @@ int __init board_register_devices(void) + * do this after registering enet devices + */ + #ifdef CONFIG_SSB_PCIHOST +- if (!bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { ++ if (!board.has_caldata && ++ !bcm63xx_nvram_get_mac_address(bcm63xx_sprom.il0mac)) { + memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN); + memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN); + if (ssb_arch_register_fallback_sprom( +@@ -933,5 +936,9 @@ int __init board_register_devices(void) + platform_device_register(&bcm63xx_gpio_keys_device); + } + ++ /* register any fixups */ ++ for (i = 0; i < board.has_caldata; i++) ++ pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset); ++ + return 0; + } +--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h ++++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h +@@ -7,6 +7,7 @@ + #include <linux/leds.h> + #include <bcm63xx_dev_enet.h> + #include <bcm63xx_dev_dsp.h> ++#include <pci_ath9k_fixup.h> + + /* + * flash mapping +@@ -14,6 +15,11 @@ + #define BCM963XX_CFE_VERSION_OFFSET 0x570 + #define BCM963XX_NVRAM_OFFSET 0x580 + ++struct ath9k_caldata { ++ unsigned int slot; ++ u32 caldata_offset; ++}; ++ + /* + * board definition + */ +@@ -32,6 +38,10 @@ struct board_info { + unsigned int has_dsp:1; + unsigned int has_uart0:1; + unsigned int has_uart1:1; ++ unsigned int has_caldata:2; ++ ++ /* wifi calibration data config */ ++ struct ath9k_caldata caldata[2]; + + /* ethernet config */ + struct bcm63xx_enet_platform_data enet0; diff --git a/target/linux/brcm63xx/patches-3.3/433-MTD-m25p80-allow-passing-pp_data.patch b/target/linux/brcm63xx/patches-3.3/433-MTD-m25p80-allow-passing-pp_data.patch new file mode 100644 index 000000000..5fef3f3a2 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/433-MTD-m25p80-allow-passing-pp_data.patch @@ -0,0 +1,40 @@ +From 7f17dfe9009beb07a3de0e380932a725293829df Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 1 May 2012 17:33:03 +0200 +Subject: [PATCH 64/79] MTD: m25p80: allow passing pp_data + +--- + drivers/mtd/devices/m25p80.c | 3 +++ + include/linux/spi/flash.h | 2 ++ + 2 files changed, 5 insertions(+) + +--- a/drivers/mtd/devices/m25p80.c ++++ b/drivers/mtd/devices/m25p80.c +@@ -887,6 +887,9 @@ static int __devinit m25p_probe(struct s + dev_warn(&spi->dev, "unrecognized id %s\n", data->type); + } + ++ if (data && data->pp_data) ++ memcpy(&ppdata, data->pp_data, sizeof(ppdata)); ++ + info = (void *)id->driver_data; + + if (info->jedec_id) { +--- a/include/linux/spi/flash.h ++++ b/include/linux/spi/flash.h +@@ -12,6 +12,7 @@ struct mtd_part_parser_data; + * with chips that can't be queried for JEDEC or other IDs + * @part_probe_types: optional list of MTD parser names to use for + * partitioning ++ * @pp_data: optional partition parser data. + * + * @max_transfer_len: option maximum read/write length limitation for + * SPI controllers not able to transfer any length commands. +@@ -30,6 +31,7 @@ struct flash_platform_data { + char *type; + + const char **part_probe_types; ++ struct mtd_part_parser_data *pp_data; + + unsigned int max_transfer_len; + /* we'll likely add more ... use JEDEC IDs, etc */ diff --git a/target/linux/brcm63xx/patches-3.3/434-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch b/target/linux/brcm63xx/patches-3.3/434-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch new file mode 100644 index 000000000..703509820 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/434-MIPS-BCM63XX-store-the-flash-type-in-global-variable.patch @@ -0,0 +1,122 @@ +From f888824d352df894ab721a5ca067b0313500efe7 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 3 May 2012 12:17:54 +0200 +Subject: [PATCH 38/59] MIPS: BCM63XX: store the flash type in global variable + +--- + arch/mips/bcm63xx/dev-flash.c | 36 +++++++++++++------ + .../include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 2 + + 2 files changed, 26 insertions(+), 12 deletions(-) + +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -25,6 +25,8 @@ + #include <bcm63xx_regs.h> + #include <bcm63xx_io.h> + ++int bcm63xx_attached_flash = -1; ++ + static struct mtd_partition mtd_partitions[] = { + { + .name = "cfe", +@@ -86,20 +88,23 @@ static int __init bcm63xx_detect_flash_t + bcm63xx_spi_flash_info[0].max_speed_hz = 16666667; + + if (val & STRAPBUS_6328_BOOT_SEL_SERIAL) +- return BCM63XX_FLASH_TYPE_SERIAL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; + else +- return BCM63XX_FLASH_TYPE_NAND; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_NAND; ++ break; + case BCM6338_CPU_ID: + case BCM6345_CPU_ID: + case BCM6348_CPU_ID: + /* no way to auto detect so assume parallel */ +- return BCM63XX_FLASH_TYPE_PARALLEL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; ++ break; + case BCM6358_CPU_ID: + val = bcm_gpio_readl(GPIO_STRAPBUS_REG); + if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL) +- return BCM63XX_FLASH_TYPE_PARALLEL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; + else +- return BCM63XX_FLASH_TYPE_SERIAL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; ++ break; + case BCM6362_CPU_ID: + val = bcm_misc_readl(MISC_STRAPBUS_6362_REG); + if (val & STRAPBUS_6362_HSSPI_CLK_FAST) +@@ -108,9 +113,10 @@ static int __init bcm63xx_detect_flash_t + bcm63xx_spi_flash_info[0].max_speed_hz = 20000000; + + if (val & STRAPBUS_6362_BOOT_SEL_SERIAL) +- return BCM63XX_FLASH_TYPE_SERIAL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; + else +- return BCM63XX_FLASH_TYPE_NAND; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_NAND; ++ break; + case BCM6368_CPU_ID: + val = bcm_gpio_readl(GPIO_STRAPBUS_REG); + if (val & STRAPBUS_6368_SPI_CLK_FAST) +@@ -118,25 +124,32 @@ static int __init bcm63xx_detect_flash_t + + switch (val & STRAPBUS_6368_BOOT_SEL_MASK) { + case STRAPBUS_6368_BOOT_SEL_NAND: +- return BCM63XX_FLASH_TYPE_NAND; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_NAND; ++ break; + case STRAPBUS_6368_BOOT_SEL_SERIAL: +- return BCM63XX_FLASH_TYPE_SERIAL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_SERIAL; ++ break; + case STRAPBUS_6368_BOOT_SEL_PARALLEL: +- return BCM63XX_FLASH_TYPE_PARALLEL; ++ bcm63xx_attached_flash = BCM63XX_FLASH_TYPE_PARALLEL; ++ break; ++ default: ++ return -EINVAL; + } + default: + return -EINVAL; + } ++ ++ return 0; + } + + int __init bcm63xx_flash_register(void) + { +- int flash_type; + u32 val; + +- flash_type = bcm63xx_detect_flash_type(); + +- switch (flash_type) { ++ bcm63xx_detect_flash_type(); ++ ++ switch (bcm63xx_attached_flash) { + case BCM63XX_FLASH_TYPE_PARALLEL: + /* read base address of boot chip select (0) */ + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); +@@ -157,7 +170,7 @@ int __init bcm63xx_flash_register(void) + return -ENODEV; + default: + pr_err("flash detection failed for BCM%x: %d\n", +- bcm63xx_get_cpu_id(), flash_type); ++ bcm63xx_get_cpu_id(), bcm63xx_attached_flash); + return -ENODEV; + } + } +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h +@@ -7,6 +7,8 @@ enum { + BCM63XX_FLASH_TYPE_NAND, + }; + ++extern int bcm63xx_attached_flash; ++ + int __init bcm63xx_flash_register(void); + + #endif /* __BCM63XX_FLASH_H */ diff --git a/target/linux/brcm63xx/patches-3.3/435-BCM63XX-add-a-fixup-for-ath9k-devices.patch b/target/linux/brcm63xx/patches-3.3/435-BCM63XX-add-a-fixup-for-ath9k-devices.patch new file mode 100644 index 000000000..a3b30e444 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/435-BCM63XX-add-a-fixup-for-ath9k-devices.patch @@ -0,0 +1,227 @@ +From fb6f6f58db9ae9cf27ab01f5f09cfbc5c078a7b8 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 3 May 2012 14:36:11 +0200 +Subject: [PATCH 66/80] BCM63XX: add a fixup for ath9k devices + +--- + arch/mips/bcm63xx/Makefile | 2 +- + arch/mips/bcm63xx/pci-ath9k-fixup.c | 190 ++++++++++++++++++++ + .../include/asm/mach-bcm63xx/pci_ath9k_fixup.h | 7 + + 3 files changed, 198 insertions(+), 1 deletion(-) + create mode 100644 arch/mips/bcm63xx/pci-ath9k-fixup.c + create mode 100644 arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h + +--- a/arch/mips/bcm63xx/Makefile ++++ b/arch/mips/bcm63xx/Makefile +@@ -1,7 +1,7 @@ + obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o setup.o \ + timer.o dev-dsp.o dev-enet.o dev-flash.o dev-hsspi.o \ + dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o dev-usb-ehci.o \ +- dev-usb-ohci.o dev-wdt.o ++ dev-usb-ohci.o dev-wdt.o pci-ath9k-fixup.o + obj-$(CONFIG_EARLY_PRINTK) += early_printk.o + + obj-y += boards/ +--- /dev/null ++++ b/arch/mips/bcm63xx/pci-ath9k-fixup.c +@@ -0,0 +1,190 @@ ++/* ++ * Broadcom BCM63XX Ath9k EEPROM fixup helper. ++ * ++ * Copytight (C) 2012 Jonas Gorski <jonas.gorski@gmail.com> ++ * ++ * Based on ++ * ++ * Atheros AP94 reference board PCI initialization ++ * ++ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org> ++ * ++ * 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 <linux/pci.h> ++#include <linux/delay.h> ++#include <linux/ath9k_platform.h> ++ ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_io.h> ++#include <bcm63xx_nvram.h> ++#include <bcm63xx_dev_pci.h> ++#include <bcm63xx_dev_flash.h> ++#include <bcm63xx_dev_hsspi.h> ++#include <pci_ath9k_fixup.h> ++ ++struct ath9k_fixup { ++ unsigned slot; ++ u8 mac[ETH_ALEN]; ++ struct ath9k_platform_data pdata; ++}; ++ ++static int ath9k_num_fixups; ++static struct ath9k_fixup ath9k_fixups[2] = { ++ { ++ .slot = 255, ++ .pdata = { ++ .led_pin = -1, ++ }, ++ }, ++ { ++ .slot = 255, ++ .pdata = { ++ .led_pin = -1, ++ }, ++ }, ++}; ++ ++static u16 *bcm63xx_read_eeprom(u16 *eeprom, u32 offset) ++{ ++ u32 addr; ++ ++ if (BCMCPU_IS_6328()) { ++ addr = 0x18000000; ++ } else { ++ addr = bcm_mpi_readl(MPI_CSBASE_REG(0)); ++ addr &= MPI_CSBASE_BASE_MASK; ++ } ++ ++ switch (bcm63xx_attached_flash) { ++ case BCM63XX_FLASH_TYPE_PARALLEL: ++ memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); ++ return eeprom; ++ case BCM63XX_FLASH_TYPE_SERIAL: ++ /* the first megabyte is memory mapped */ ++ if (offset < 0x100000) { ++ memcpy(eeprom, (void *)KSEG1ADDR(addr + offset), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); ++ return eeprom; ++ } ++ ++ if (BCMCPU_IS_6328()) { ++ /* we can change the memory mapped megabyte */ ++ bcm_hsspi_writel(offset & 0xf00000, 0x18); ++ memcpy(eeprom, (void *)KSEG1ADDR(addr + (offset & 0xfffff)), ATH9K_PLAT_EEP_MAX_WORDS * sizeof(u16)); ++ bcm_hsspi_writel(0, 0x18); ++ return eeprom; ++ } ++ /* can't do anything here without talking to the SPI controller. */ ++ case BCM63XX_FLASH_TYPE_NAND: ++ default: ++ return NULL; ++ } ++} ++ ++static void ath9k_pci_fixup(struct pci_dev *dev) ++{ ++ void __iomem *mem; ++ struct ath9k_platform_data *pdata = NULL; ++ u16 *cal_data = NULL; ++ u16 cmd; ++ u32 bar0; ++ u32 val; ++ unsigned i; ++ ++ for (i = 0; i < ath9k_num_fixups; i++) { ++ if (ath9k_fixups[i].slot != PCI_SLOT(dev->devfn)) ++ continue; ++ ++ cal_data = ath9k_fixups[i].pdata.eeprom_data; ++ pdata = &ath9k_fixups[i].pdata; ++ break; ++ } ++ ++ if (cal_data == NULL) ++ return; ++ ++ if (*cal_data != 0xa55a) { ++ pr_err("pci %s: invalid calibration data\n", pci_name(dev)); ++ return; ++ } ++ ++ pr_info("pci %s: fixup device configuration\n", pci_name(dev)); ++ ++ switch (bcm63xx_get_cpu_id()) { ++ case BCM6328_CPU_ID: ++ val = BCM_PCIE_MEM_BASE_PA; ++ break; ++ case BCM6348_CPU_ID: ++ case BCM6358_CPU_ID: ++ case BCM6368_CPU_ID: ++ val = BCM_PCI_MEM_BASE_PA; ++ break; ++ default: ++ BUG(); ++ } ++ ++ mem = ioremap(val, 0x10000); ++ if (!mem) { ++ pr_err("pci %s: ioremap error\n", pci_name(dev)); ++ return; ++ } ++ ++ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); ++ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar0); ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, val); ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ++ /* set offset to first reg address */ ++ cal_data += 3; ++ while(*cal_data != 0xffff) { ++ u32 reg; ++ reg = *cal_data++; ++ val = *cal_data++; ++ val |= (*cal_data++) << 16; ++ ++ writel(val, mem + reg); ++ udelay(100); ++ } ++ ++ pci_read_config_dword(dev, PCI_VENDOR_ID, &val); ++ dev->vendor = val & 0xffff; ++ dev->device = (val >> 16) & 0xffff; ++ ++ pci_read_config_dword(dev, PCI_CLASS_REVISION, &val); ++ dev->revision = val & 0xff; ++ dev->class = val >> 8; /* upper 3 bytes */ ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ ++ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, bar0); ++ ++ iounmap(mem); ++ ++ dev->dev.platform_data = pdata; ++} ++DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup); ++ ++void __init pci_enable_ath9k_fixup(unsigned slot, u32 offset) ++{ ++ if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups)) ++ return; ++ ++ ath9k_fixups[ath9k_num_fixups].slot = slot; ++ ++ if (!bcm63xx_read_eeprom(ath9k_fixups[ath9k_num_fixups].pdata.eeprom_data, offset)) ++ return; ++ ++ if (bcm63xx_nvram_get_mac_address(ath9k_fixups[ath9k_num_fixups].mac)) ++ return; ++ ++ ath9k_fixups[ath9k_num_fixups].pdata.macaddr = ath9k_fixups[ath9k_num_fixups].mac; ++ ath9k_num_fixups++; ++} +--- /dev/null ++++ b/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h +@@ -0,0 +1,7 @@ ++#ifndef _PCI_ATH9K_FIXUP ++#define _PCI_ATH9K_FIXUP ++ ++ ++void pci_enable_ath9k_fixup(unsigned slot, u32 offset) __init; ++ ++#endif /* _PCI_ATH9K_FIXUP */ diff --git a/target/linux/brcm63xx/patches-3.3/436-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch b/target/linux/brcm63xx/patches-3.3/436-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch new file mode 100644 index 000000000..681bab248 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/436-MTD-bcm63xxpart-allow-passing-a-caldata-offset.patch @@ -0,0 +1,118 @@ +From 8ab86c5dc38ad4de1442e50e0adbc354d9184d71 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 1 May 2012 14:38:41 +0200 +Subject: [PATCH 68/79] MTD: bcm63xxpart: allow passing a caldata offset + +Allow bcm63xxpart to receive a caldata offset if calibration data is +contained in flash. +--- + drivers/mtd/bcm63xxpart.c | 47 ++++++++++++++++++++++++++++++++++++++-- + include/linux/mtd/partitions.h | 2 ++ + 2 files changed, 47 insertions(+), 2 deletions(-) + +--- a/drivers/mtd/bcm63xxpart.c ++++ b/drivers/mtd/bcm63xxpart.c +@@ -80,6 +80,8 @@ static int bcm63xx_parse_cfe_partitions( + unsigned int rootfslen, kernellen, sparelen, totallen; + unsigned int cfelen, nvramlen; + unsigned int cfe_erasesize; ++ unsigned int caldatalen1 = 0, caldataaddr1 = 0; ++ unsigned int caldatalen2 = 0, caldataaddr2 = 0; + int i; + u32 computed_crc; + bool rootfs_first = false; +@@ -94,6 +96,23 @@ static int bcm63xx_parse_cfe_partitions( + nvramlen = bcm63xx_nvram_get_psi_size() * 1024; + nvramlen = roundup(nvramlen, cfe_erasesize); + ++ if (data) { ++ if (data->caldata[0]) { ++ caldatalen1 = cfe_erasesize; ++ caldataaddr1 = rounddown(data->caldata[0], ++ cfe_erasesize); ++ } ++ if (data->caldata[1]) { ++ caldatalen2 = cfe_erasesize; ++ caldataaddr2 = rounddown(data->caldata[1], ++ cfe_erasesize); ++ } ++ if (caldataaddr1 == caldataaddr2) { ++ caldataaddr2 = 0; ++ caldatalen2 = 0; ++ } ++ } ++ + /* Allocate memory for buffer */ + buf = vmalloc(sizeof(struct bcm_tag)); + if (!buf) +@@ -144,7 +163,7 @@ static int bcm63xx_parse_cfe_partitions( + rootfsaddr = 0; + spareaddr = cfelen; + } +- sparelen = master->size - spareaddr - nvramlen; ++ sparelen = master->size - spareaddr - nvramlen - caldatalen1 - caldatalen2; + + /* Determine number of partitions */ + if (rootfslen > 0) +@@ -153,6 +172,12 @@ static int bcm63xx_parse_cfe_partitions( + if (kernellen > 0) + nrparts++; + ++ if (caldatalen1 > 0) ++ nrparts++; ++ ++ if (caldatalen2 > 0) ++ nrparts++; ++ + /* Ask kernel for more memory */ + parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); + if (!parts) { +@@ -190,6 +215,23 @@ static int bcm63xx_parse_cfe_partitions( + curpart++; + } + ++ if (caldatalen1 > 0) { ++ if (caldatalen2 > 0) ++ parts[curpart].name = "cal_data1"; ++ else ++ parts[curpart].name = "cal_data"; ++ parts[curpart].offset = caldataaddr1; ++ parts[curpart].size = caldatalen1; ++ curpart++; ++ } ++ ++ if (caldatalen2 > 0) { ++ parts[curpart].name = "cal_data2"; ++ parts[curpart].offset = caldataaddr2; ++ parts[curpart].size = caldatalen2; ++ curpart++; ++ } ++ + parts[curpart].name = "nvram"; + parts[curpart].offset = master->size - nvramlen; + parts[curpart].size = nvramlen; +@@ -198,7 +240,8 @@ static int bcm63xx_parse_cfe_partitions( + /* Global partition "linux" to make easy firmware upgrade */ + parts[curpart].name = "linux"; + parts[curpart].offset = cfelen; +- parts[curpart].size = master->size - cfelen - nvramlen; ++ parts[curpart].size = master->size - cfelen - nvramlen ++ - caldatalen1 - caldatalen2; + + for (i = 0; i < nrparts; i++) + pr_info("Partition %d is %s offset %llx and length %llx\n", i, +--- a/include/linux/mtd/partitions.h ++++ b/include/linux/mtd/partitions.h +@@ -58,10 +58,12 @@ struct device_node; + /** + * struct mtd_part_parser_data - used to pass data to MTD partition parsers. + * @origin: for RedBoot, start address of MTD device ++ * @caldata: for CFE, start address of wifi calibration data + * @of_node: for OF parsers, device node containing partitioning information + */ + struct mtd_part_parser_data { + unsigned long origin; ++ unsigned long caldata[2]; + struct device_node *of_node; + }; + diff --git a/target/linux/brcm63xx/patches-3.3/437-MIPS-BCM63XX-pass-caldata-info-to-flash.patch b/target/linux/brcm63xx/patches-3.3/437-MIPS-BCM63XX-pass-caldata-info-to-flash.patch new file mode 100644 index 000000000..541efd2eb --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/437-MIPS-BCM63XX-pass-caldata-info-to-flash.patch @@ -0,0 +1,82 @@ +From 977f8a30103b9c4992cab8f49357fe0d4274004f Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 3 May 2012 14:55:26 +0200 +Subject: [PATCH 69/80] MIPS: BCM63XX: pass caldata info to flash + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 2 +- + arch/mips/bcm63xx/dev-flash.c | 9 ++++++++- + arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 4 +++- + 3 files changed, 12 insertions(+), 3 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -912,7 +912,7 @@ int __init board_register_devices(void) + if (board.num_spis) + spi_register_board_info(board.spis, board.num_spis); + +- bcm63xx_flash_register(); ++ bcm63xx_flash_register(board.has_caldata, board.caldata); + + /* count number of LEDs defined by this device */ + while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name) +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -35,12 +35,15 @@ static struct mtd_partition mtd_partitio + } + }; + ++static struct mtd_part_parser_data bcm63xx_parser_data; ++ + static const char *bcm63xx_part_types[] = { "bcm63xxpart", "RedBoot", NULL }; + + static struct physmap_flash_data flash_data = { + .width = 2, + .parts = mtd_partitions, + .part_probe_types = bcm63xx_part_types, ++ .pp_data = &bcm63xx_parser_data, + }; + + static struct resource mtd_resources[] = { +@@ -62,6 +65,7 @@ static struct platform_device mtd_dev = + + static struct flash_platform_data bcm63xx_flash_data = { + .part_probe_types = bcm63xx_part_types, ++ .pp_data = &bcm63xx_parser_data, + }; + + static struct spi_board_info bcm63xx_spi_flash_info[] = { +@@ -142,10 +146,13 @@ static int __init bcm63xx_detect_flash_t + return 0; + } + +-int __init bcm63xx_flash_register(void) ++int __init bcm63xx_flash_register(int num_caldata, struct ath9k_caldata *caldata) + { + u32 val; ++ unsigned int i; + ++ for (i = 0; i < num_caldata; i++) ++ bcm63xx_parser_data.caldata[i] = caldata[i].caldata_offset; + + bcm63xx_detect_flash_type(); + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h +@@ -1,6 +1,8 @@ + #ifndef __BCM63XX_FLASH_H + #define __BCM63XX_FLASH_H + ++#include <board_bcm963xx.h> ++ + enum { + BCM63XX_FLASH_TYPE_PARALLEL, + BCM63XX_FLASH_TYPE_SERIAL, +@@ -9,6 +11,6 @@ enum { + + extern int bcm63xx_attached_flash; + +-int __init bcm63xx_flash_register(void); ++int __init bcm63xx_flash_register(int num_caldata, struct ath9k_caldata *caldata); + + #endif /* __BCM63XX_FLASH_H */ diff --git a/target/linux/brcm63xx/patches-3.3/438-MIPS-BCM63XX-enable-USB-for-BCM6328.patch b/target/linux/brcm63xx/patches-3.3/438-MIPS-BCM63XX-enable-USB-for-BCM6328.patch new file mode 100644 index 000000000..54673dcf3 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/438-MIPS-BCM63XX-enable-USB-for-BCM6328.patch @@ -0,0 +1,60 @@ +From 38c3f8d21da90f0833578a157e22ddabf4d576bd Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sun, 12 Feb 2012 14:28:34 +0100 +Subject: [PATCH 48/84] MIPS: BCM63XX: enable USB for BCM6328 + +The USB controller is the same as the one on BCM6368. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/dev-usb-ehci.c | 2 +- + arch/mips/bcm63xx/dev-usb-ohci.c | 3 ++- + drivers/usb/host/ehci-bcm63xx.c | 2 +- + drivers/usb/host/ohci-bcm63xx.c | 2 +- + 4 files changed, 5 insertions(+), 4 deletions(-) + +--- a/arch/mips/bcm63xx/dev-usb-ehci.c ++++ b/arch/mips/bcm63xx/dev-usb-ehci.c +@@ -39,7 +39,7 @@ static struct platform_device bcm63xx_eh + + int __init bcm63xx_ehci_register(void) + { +- if (!BCMCPU_IS_6358() && !BCMCPU_IS_6368()) ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368()) + return 0; + + ehci_resources[0].start = bcm63xx_regset_address(RSET_EHCI0); +--- a/arch/mips/bcm63xx/dev-usb-ohci.c ++++ b/arch/mips/bcm63xx/dev-usb-ohci.c +@@ -39,7 +39,8 @@ static struct platform_device bcm63xx_oh + + int __init bcm63xx_ohci_register(void) + { +- if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368()) ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6348() && !BCMCPU_IS_6358() && ++ !BCMCPU_IS_6368()) + return 0; + + ohci_resources[0].start = bcm63xx_regset_address(RSET_OHCI0); +--- a/drivers/usb/host/ehci-bcm63xx.c ++++ b/drivers/usb/host/ehci-bcm63xx.c +@@ -99,7 +99,7 @@ static int __devinit ehci_hcd_bcm63xx_dr + bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, + USBH_PRIV_TEST_6358_REG); + +- } else if (BCMCPU_IS_6368()) { ++ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) { + + reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG); + reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK; +--- a/drivers/usb/host/ohci-bcm63xx.c ++++ b/drivers/usb/host/ohci-bcm63xx.c +@@ -94,7 +94,7 @@ static int __devinit ohci_hcd_bcm63xx_dr + bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, + USBH_PRIV_TEST_6358_REG); + +- } else if (BCMCPU_IS_6368()) { ++ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) { + reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG); + reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK; + reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK; diff --git a/target/linux/brcm63xx/patches-3.3/439-MIPS-BCM63XX-wire-up-the-HS-SPI-controller-for-BCM63.patch b/target/linux/brcm63xx/patches-3.3/439-MIPS-BCM63XX-wire-up-the-HS-SPI-controller-for-BCM63.patch new file mode 100644 index 000000000..756156918 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/439-MIPS-BCM63XX-wire-up-the-HS-SPI-controller-for-BCM63.patch @@ -0,0 +1,56 @@ +From ed225910f0e062d9c28d5cf216f97b3cf457a8c5 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Mon, 21 Nov 2011 00:55:49 +0100 +Subject: [PATCH 58/81] MIPS: BCM63XX: wire up the HS SPI controller for BCM6362 + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/clk.c | 2 ++ + arch/mips/bcm63xx/dev-hsspi.c | 7 +++++-- + .../include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h | 1 + + 3 files changed, 8 insertions(+), 2 deletions(-) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -218,6 +218,8 @@ static void hsspi_set(struct clk *clk, i + + if (BCMCPU_IS_6328()) + mask = CKCTL_6328_HSSPI_EN; ++ else if (BCMCPU_IS_6362()) ++ mask = CKCTL_6362_HSSPI_EN; + else + return; + +--- a/arch/mips/bcm63xx/dev-hsspi.c ++++ b/arch/mips/bcm63xx/dev-hsspi.c +@@ -43,7 +43,7 @@ static struct platform_device bcm63xx_hs + int __init bcm63xx_hsspi_register(void) + { + +- if (!BCMCPU_IS_6328()) ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362()) + return -ENODEV; + + spi_resources[0].start = bcm63xx_regset_address(RSET_HSSPI); +@@ -51,7 +51,10 @@ int __init bcm63xx_hsspi_register(void) + spi_resources[0].end += RSET_HSSPI_SIZE - 1; + spi_resources[1].start = bcm63xx_get_irq_number(IRQ_HSSPI); + +- spi_pdata.speed_hz = HSSPI_PLL_HZ_6328; ++ if (BCMCPU_IS_6328()) ++ spi_pdata.speed_hz = HSSPI_PLL_HZ_6328; ++ else ++ spi_pdata.speed_hz = HSSPI_PLL_HZ; + + return platform_device_register(&bcm63xx_hsspi_device); + } +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_hsspi.h +@@ -16,6 +16,7 @@ struct bcm63xx_hsspi_pdata { + #define bcm_hsspi_writel(v, o) bcm_rset_writel(RSET_HSSPI, (v), (o)) + + #define HSSPI_PLL_HZ_6328 133333333 ++#define HSSPI_PLL_HZ 400000000 + + #define HSSPI_BUFFER_LEN 512 + diff --git a/target/linux/brcm63xx/patches-3.3/440-MIPS-BCM63XX-enable-SPI-controller-for-BCM6362.patch b/target/linux/brcm63xx/patches-3.3/440-MIPS-BCM63XX-enable-SPI-controller-for-BCM6362.patch new file mode 100644 index 000000000..f1f134286 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/440-MIPS-BCM63XX-enable-SPI-controller-for-BCM6362.patch @@ -0,0 +1,101 @@ +From eef84812bc7ffd590da6ad6b83bfeebaa43a7055 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Thu, 5 Jul 2012 21:19:20 +0200 +Subject: [PATCH 58/84] MIPS: BCM63XX: enable SPI controller for BCM6362 + +--- + arch/mips/bcm63xx/clk.c | 2 ++ + arch/mips/bcm63xx/dev-spi.c | 11 ++++++++++- + .../include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | 3 +++ + arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 16 ++++++++++++++++ + 4 files changed, 31 insertions(+), 1 deletions(-) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -199,6 +199,8 @@ static void spi_set(struct clk *clk, int + mask = CKCTL_6348_SPI_EN; + else if (BCMCPU_IS_6358()) + mask = CKCTL_6358_SPI_EN; ++ else if (BCMCPU_IS_6362()) ++ mask = CKCTL_6362_SPI_EN; + else + /* BCMCPU_IS_6368 */ + mask = CKCTL_6368_SPI_EN; +--- a/arch/mips/bcm63xx/dev-spi.c ++++ b/arch/mips/bcm63xx/dev-spi.c +@@ -34,6 +34,10 @@ static const unsigned long bcm6358_regs_ + __GEN_SPI_REGS_TABLE(6358) + }; + ++static const unsigned long bcm6362_regs_spi[] = { ++ __GEN_SPI_REGS_TABLE(6362) ++}; ++ + static const unsigned long bcm6368_regs_spi[] = { + __GEN_SPI_REGS_TABLE(6368) + }; +@@ -49,6 +53,8 @@ static __init void bcm63xx_spi_regs_init + bcm63xx_regs_spi = bcm6348_regs_spi; + if (BCMCPU_IS_6358()) + bcm63xx_regs_spi = bcm6358_regs_spi; ++ if (BCMCPU_IS_6362()) ++ bcm63xx_regs_spi = bcm6362_regs_spi; + if (BCMCPU_IS_6368()) + bcm63xx_regs_spi = bcm6368_regs_spi; + } +@@ -99,6 +105,9 @@ int __init bcm63xx_spi_register(void) + /* Set bus frequency */ + spi_pdata.speed_hz = clk_get_rate(periph_clk); + ++ if (BCMCPU_IS_6362()) ++ spi_pdata.bus_num = 1; ++ + spi_resources[0].start = bcm63xx_regset_address(RSET_SPI); + spi_resources[0].end = spi_resources[0].start; + spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI); +@@ -110,7 +119,7 @@ int __init bcm63xx_spi_register(void) + spi_pdata.msg_ctl_width = SPI_6338_MSG_CTL_WIDTH; + } + +- if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) { ++ if (BCMCPU_IS_6358() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) { + spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1; + spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE; + spi_pdata.msg_type_shift = SPI_6358_MSG_TYPE_SHIFT; +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +@@ -81,6 +81,9 @@ static inline unsigned long bcm63xx_spir + #ifdef CONFIG_BCM63XX_CPU_6358 + __GEN_SPI_RSET(6358) + #endif ++#ifdef CONFIG_BCM63XX_CPU_6362 ++ __GEN_SPI_RSET(6362) ++#endif + #ifdef CONFIG_BCM63XX_CPU_6368 + __GEN_SPI_RSET(6368) + #endif +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +@@ -1223,6 +1223,22 @@ + #define SPI_6358_MSG_TAIL 0x709 + #define SPI_6358_RX_TAIL 0x70B + ++/* BCM 6362 SPI core */ ++#define SPI_6362_MSG_CTL 0x00 /* 16-bits register */ ++#define SPI_6362_MSG_DATA 0x02 ++#define SPI_6362_MSG_DATA_SIZE 0x21e ++#define SPI_6362_RX_DATA 0x400 ++#define SPI_6362_RX_DATA_SIZE 0x220 ++#define SPI_6362_CMD 0x700 /* 16-bits register */ ++#define SPI_6362_INT_STATUS 0x702 ++#define SPI_6362_INT_MASK_ST 0x703 ++#define SPI_6362_INT_MASK 0x704 ++#define SPI_6362_ST 0x705 ++#define SPI_6362_CLK_CFG 0x706 ++#define SPI_6362_FILL_BYTE 0x707 ++#define SPI_6362_MSG_TAIL 0x709 ++#define SPI_6362_RX_TAIL 0x70B ++ + /* BCM 6358 SPI core */ + #define SPI_6368_MSG_CTL 0x00 /* 16-bits register */ + #define SPI_6368_MSG_CTL_WIDTH 16 diff --git a/target/linux/brcm63xx/patches-3.3/441-MIPS-BCM63XX-enable-USB-for-BCM6362.patch b/target/linux/brcm63xx/patches-3.3/441-MIPS-BCM63XX-enable-USB-for-BCM6362.patch new file mode 100644 index 000000000..04d540ffb --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/441-MIPS-BCM63XX-enable-USB-for-BCM6362.patch @@ -0,0 +1,84 @@ +From fb9e98936590637c26b66d60137a7b44b329a254 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sun, 12 Feb 2012 14:40:56 +0100 +Subject: [PATCH 59/84] MIPS: BCM63XX: enable USB for BCM6362 + +BCM6362 has the same USB controller as BCM6368. + +Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com> +--- + arch/mips/bcm63xx/Kconfig | 2 ++ + arch/mips/bcm63xx/clk.c | 4 ++++ + arch/mips/bcm63xx/dev-usb-ehci.c | 3 ++- + arch/mips/bcm63xx/dev-usb-ohci.c | 2 +- + drivers/usb/host/ehci-bcm63xx.c | 2 +- + drivers/usb/host/ohci-bcm63xx.c | 2 +- + 6 files changed, 11 insertions(+), 4 deletions(-) + +--- a/arch/mips/bcm63xx/Kconfig ++++ b/arch/mips/bcm63xx/Kconfig +@@ -27,6 +27,8 @@ config BCM63XX_CPU_6358 + config BCM63XX_CPU_6362 + bool "support 6362 CPU" + select HW_HAS_PCI ++ select USB_ARCH_HAS_OHCI if USB_SUPPORT ++ select USB_ARCH_HAS_EHCI if USB_SUPPORT + + config BCM63XX_CPU_6368 + bool "support 6368 CPU" +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -178,6 +178,8 @@ static void usbh_set(struct clk *clk, in + { + if (BCMCPU_IS_6348()) + bcm_hwclock_set(CKCTL_6348_USBH_EN, enable); ++ else if (BCMCPU_IS_6362()) ++ bcm_hwclock_set(CKCTL_6362_USBH_EN, enable); + else if (BCMCPU_IS_6368()) + bcm_hwclock_set(CKCTL_6368_USBH_EN, enable); + } +--- a/arch/mips/bcm63xx/dev-usb-ehci.c ++++ b/arch/mips/bcm63xx/dev-usb-ehci.c +@@ -39,7 +39,8 @@ static struct platform_device bcm63xx_eh + + int __init bcm63xx_ehci_register(void) + { +- if (!BCMCPU_IS_6328() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368()) ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6358() && !BCMCPU_IS_6362() && ++ !BCMCPU_IS_6368()) + return 0; + + ehci_resources[0].start = bcm63xx_regset_address(RSET_EHCI0); +--- a/arch/mips/bcm63xx/dev-usb-ohci.c ++++ b/arch/mips/bcm63xx/dev-usb-ohci.c +@@ -40,7 +40,7 @@ static struct platform_device bcm63xx_oh + int __init bcm63xx_ohci_register(void) + { + if (!BCMCPU_IS_6328() && !BCMCPU_IS_6348() && !BCMCPU_IS_6358() && +- !BCMCPU_IS_6368()) ++ !BCMCPU_IS_6362() && !BCMCPU_IS_6368()) + return 0; + + ohci_resources[0].start = bcm63xx_regset_address(RSET_OHCI0); +--- a/drivers/usb/host/ehci-bcm63xx.c ++++ b/drivers/usb/host/ehci-bcm63xx.c +@@ -99,7 +99,7 @@ static int __devinit ehci_hcd_bcm63xx_dr + bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, + USBH_PRIV_TEST_6358_REG); + +- } else if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) { ++ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) { + + reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG); + reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK; +--- a/drivers/usb/host/ohci-bcm63xx.c ++++ b/drivers/usb/host/ohci-bcm63xx.c +@@ -94,7 +94,7 @@ static int __devinit ohci_hcd_bcm63xx_dr + bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, + USBH_PRIV_TEST_6358_REG); + +- } else if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) { ++ } else if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) { + reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG); + reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK; + reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK; diff --git a/target/linux/brcm63xx/patches-3.3/442-MIPS-BCM63XX-enable-enetsw-for-BCM6362.patch b/target/linux/brcm63xx/patches-3.3/442-MIPS-BCM63XX-enable-enetsw-for-BCM6362.patch new file mode 100644 index 000000000..ae46ec406 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/442-MIPS-BCM63XX-enable-enetsw-for-BCM6362.patch @@ -0,0 +1,77 @@ +From bf9d506bd144b95f8bb4127350ab2db5fba9c12e Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Sun, 8 Jul 2012 21:07:12 +0200 +Subject: [PATCH 60/84] MIPS: BCM63XX: enable enetsw for BCM6362 + +--- + arch/mips/bcm63xx/clk.c | 7 ++++++- + arch/mips/bcm63xx/dev-enet.c | 6 ++++-- + .../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 1 + + 3 files changed, 11 insertions(+), 3 deletions(-) + +--- a/arch/mips/bcm63xx/clk.c ++++ b/arch/mips/bcm63xx/clk.c +@@ -120,11 +120,13 @@ static void enetsw_set(struct clk *clk, + { + u32 mask; + +- if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368()) ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362() && !BCMCPU_IS_6368()) + return; + + if (BCMCPU_IS_6328()) + mask = CKCTL_6328_ROBOSW_EN; ++ else if (BCMCPU_IS_6362()) ++ mask = CKCTL_6362_ROBOSW_EN; + else + mask = CKCTL_6368_ROBOSW_EN | CKCTL_6368_SWPKT_USB_EN | + CKCTL_6368_SWPKT_SAR_EN; +@@ -137,6 +139,9 @@ static void enetsw_set(struct clk *clk, + if (BCMCPU_IS_6328()) { + reg = PERF_SOFTRESET_6328_REG; + mask = SOFTRESET_6328_ENETSW_MASK; ++ } else if (BCMCPU_IS_6362()) { ++ reg = PERF_SOFTRESET_6362_REG; ++ mask = SOFTRESET_6362_ENETSW_MASK; + } else { + reg = PERF_SOFTRESET_6368_REG; + mask = SOFTRESET_6368_ENETSW_MASK; +--- a/arch/mips/bcm63xx/dev-enet.c ++++ b/arch/mips/bcm63xx/dev-enet.c +@@ -141,7 +141,7 @@ static int __init register_shared(void) + shared_res[0].end = shared_res[0].start; + shared_res[0].end += (RSET_ENETDMA_SIZE) - 1; + +- if (BCMCPU_IS_6328() || BCMCPU_IS_6368()) ++ if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368()) + chan_count = 32; + else + chan_count = 16; +@@ -224,7 +224,7 @@ bcm63xx_enetsw_register(const struct bcm + { + int ret; + +- if (!BCMCPU_IS_6328() && !BCMCPU_IS_6368()) ++ if (!BCMCPU_IS_6328() && !BCMCPU_IS_6362() && !BCMCPU_IS_6368()) + return -ENODEV; + + ret = register_shared(); +@@ -243,6 +243,8 @@ bcm63xx_enetsw_register(const struct bcm + + if (BCMCPU_IS_6328()) + enetsw_pd.num_ports = ENETSW_PORTS_6328; ++ else if (BCMCPU_IS_6362()) ++ enetsw_pd.num_ports = ENETSW_PORTS_6362; + else if (BCMCPU_IS_6368()) + enetsw_pd.num_ports = ENETSW_PORTS_6368; + +--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h ++++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +@@ -44,6 +44,7 @@ struct bcm63xx_enet_platform_data { + */ + #define ENETSW_MAX_PORT 6 + #define ENETSW_PORTS_6328 5 /* 4 FE PHY + 1 RGMII */ ++#define ENETSW_PORTS_6362 6 /* 4 FE PHY + 2 RGMII */ + #define ENETSW_PORTS_6368 6 /* 4 FE PHY + 2 RGMII */ + + #define ENETSW_RGMII_PORT0 4 diff --git a/target/linux/brcm63xx/patches-3.3/500-board-D4PW.patch b/target/linux/brcm63xx/patches-3.3/500-board-D4PW.patch new file mode 100644 index 000000000..d3d35d7a7 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/500-board-D4PW.patch @@ -0,0 +1,65 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -469,6 +469,54 @@ static struct board_info __initdata boar + + .has_ohci0 = 1, + }; ++ ++static struct board_info __initdata board_96348_D4PW = { ++ .name = "D-4P-W", ++ .expected_cpu_id = 0x6348, ++ ++ .has_enet1 = 1, ++ .has_pci = 1, ++ .has_uart0 = 1, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "D-4P-W:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ }, ++ { ++ .name = "D-4P-W::status", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { ++ .name = "D-4P-W:green:internet", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ { ++ .name = "D-4P-W:red:internet", ++ .gpio = 5, ++ .active_low = 1, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 7, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; + #endif + + /* +@@ -640,6 +688,7 @@ static const struct board_info __initdat + &board_DV201AMR, + &board_96348gw_a, + &board_rta1025w_16, ++ &board_96348_D4PW, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 diff --git a/target/linux/brcm63xx/patches-3.3/501-board-NB4.patch b/target/linux/brcm63xx/patches-3.3/501-board-NB4.patch new file mode 100644 index 000000000..2f96f4b1e --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/501-board-NB4.patch @@ -0,0 +1,640 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -15,6 +15,8 @@ + #include <linux/gpio_keys.h> + #include <linux/input.h> + #include <linux/spi/spi.h> ++#include <linux/spi/spi_gpio.h> ++#include <linux/spi/74x164.h> + #include <asm/addrspace.h> + #include <bcm63xx_board.h> + #include <bcm63xx_cpu.h> +@@ -43,6 +45,12 @@ + #define CFE_OFFSET_64K 0x10000 + #define CFE_OFFSET_128K 0x20000 + ++#define NB4_PID_OFFSET 0xff80 ++#define NB4_74X164_GPIO_BASE 64 ++#define NB4_SPI_GPIO_MOSI 7 ++#define NB4_SPI_GPIO_CLK 6 ++#define NB4_74HC64_GPIO(X) (NB4_74X164_GPIO_BASE + (X)) ++ + static struct board_info board; + + /* +@@ -666,6 +674,586 @@ static struct board_info __initdata boar + + .has_ohci0 = 1, + }; ++ ++struct spi_gpio_platform_data nb4_spi_gpio_data = { ++ .sck = NB4_SPI_GPIO_CLK, ++ .mosi = NB4_SPI_GPIO_MOSI, ++ .miso = SPI_GPIO_NO_MISO, ++ .num_chipselect = 1, ++}; ++ ++ ++static struct platform_device nb4_spi_gpio = { ++ .name = "spi_gpio", ++ .id = 1, ++ .dev = { ++ .platform_data = &nb4_spi_gpio_data, ++ }, ++}; ++ ++static struct platform_device * __initdata nb4_devices[] = { ++ &nb4_spi_gpio, ++}; ++ ++const struct gen_74x164_chip_platform_data nb4_74x164_platform_data = { ++ .base = NB4_74X164_GPIO_BASE ++}; ++ ++static struct spi_board_info nb4_spi_devices[] = { ++ { ++ .modalias = "74x164", ++ .max_speed_hz = 781000, ++ .bus_num = 1, ++ .controller_data = (void *) SPI_GPIO_NO_CHIPSELECT, ++ .mode = SPI_MODE_0, ++ .platform_data = &nb4_74x164_platform_data ++ } ++}; ++ ++static struct board_info __initdata board_nb4_ser_r0 = { ++ .name = "NB4-SER-r0", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "NB4-SER-r0:white:adsl", ++ .gpio = NB4_74HC64_GPIO(4), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r0:white:traffic", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r0:white:tel", ++ .gpio = NB4_74HC64_GPIO(3), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r0:white:tv", ++ .gpio = NB4_74HC64_GPIO(2), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r0:white:wifi", ++ .gpio = 15, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r0:white:alarm", ++ .gpio = NB4_74HC64_GPIO(0), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r0:red:service", ++ .gpio = 29, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r0:green:service", ++ .gpio = 30, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r0:blue:service", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 34, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 37, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "service", ++ .gpio = 27, ++ .type = EV_KEY, ++ .code = BTN_0, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "clip", ++ .gpio = 31, ++ .type = EV_KEY, ++ .code = BTN_1, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++ .devs = nb4_devices, ++ .num_devs = ARRAY_SIZE(nb4_devices), ++ .spis = nb4_spi_devices, ++ .num_spis = ARRAY_SIZE(nb4_spi_devices), ++}; ++ ++static struct board_info __initdata board_nb4_ser_r1 = { ++ .name = "NB4-SER-r1", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "NB4-SER-r1:white:adsl", ++ .gpio = NB4_74HC64_GPIO(4), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r1:white:traffic", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r1:white:tel", ++ .gpio = NB4_74HC64_GPIO(3), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r1:white:tv", ++ .gpio = NB4_74HC64_GPIO(2), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r1:white:wifi", ++ .gpio = 15, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r1:white:alarm", ++ .gpio = NB4_74HC64_GPIO(0), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r1:red:service", ++ .gpio = 29, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r1:green:service", ++ .gpio = 30, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r1:blue:service", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 34, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 37, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "service", ++ .gpio = 27, ++ .type = EV_KEY, ++ .code = BTN_0, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "clip", ++ .gpio = 31, ++ .type = EV_KEY, ++ .code = BTN_1, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++ .devs = nb4_devices, ++ .num_devs = ARRAY_SIZE(nb4_devices), ++ .spis = nb4_spi_devices, ++ .num_spis = ARRAY_SIZE(nb4_spi_devices), ++}; ++ ++static struct board_info __initdata board_nb4_ser_r2 = { ++ .name = "NB4-SER-r2", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "NB4-SER-r2:white:adsl", ++ .gpio = NB4_74HC64_GPIO(4), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r2:white:traffic", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r2:white:tel", ++ .gpio = NB4_74HC64_GPIO(3), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r2:white:tv", ++ .gpio = NB4_74HC64_GPIO(2), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r2:white:wifi", ++ .gpio = 15, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r2:white:alarm", ++ .gpio = NB4_74HC64_GPIO(0), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r2:red:service", ++ .gpio = 29, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r2:green:service", ++ .gpio = 30, ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-SER-r2:blue:service", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 34, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 37, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "service", ++ .gpio = 27, ++ .type = EV_KEY, ++ .code = BTN_0, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "clip", ++ .gpio = 31, ++ .type = EV_KEY, ++ .code = BTN_1, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++ .devs = nb4_devices, ++ .num_devs = ARRAY_SIZE(nb4_devices), ++ .spis = nb4_spi_devices, ++ .num_spis = ARRAY_SIZE(nb4_spi_devices), ++}; ++ ++static struct board_info __initdata board_nb4_fxc_r1 = { ++ .name = "NB4-FXC-r1", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "NB4-FXC-r1:white:adsl", ++ .gpio = NB4_74HC64_GPIO(4), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-FXC-r1:white:traffic", ++ .gpio = 2, ++ }, ++ { ++ .name = "NB4-FXC-r1:white:tel", ++ .gpio = NB4_74HC64_GPIO(3), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-FXC-r1:white:tv", ++ .gpio = NB4_74HC64_GPIO(2), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-FXC-r1:white:wifi", ++ .gpio = 15, ++ }, ++ { ++ .name = "NB4-FXC-r1:white:alarm", ++ .gpio = NB4_74HC64_GPIO(0), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-FXC-r1:red:service", ++ .gpio = 29, ++ }, ++ { ++ .name = "NB4-FXC-r1:green:service", ++ .gpio = 30, ++ }, ++ { ++ .name = "NB4-FXC-r1:blue:service", ++ .gpio = 4, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 34, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 37, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "service", ++ .gpio = 27, ++ .type = EV_KEY, ++ .code = BTN_0, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "clip", ++ .gpio = 31, ++ .type = EV_KEY, ++ .code = BTN_1, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++ .devs = nb4_devices, ++ .num_devs = ARRAY_SIZE(nb4_devices), ++ .spis = nb4_spi_devices, ++ .num_spis = ARRAY_SIZE(nb4_spi_devices), ++}; ++ ++static struct board_info __initdata board_nb4_fxc_r2 = { ++ .name = "NB4-FXC-r2", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "NB4-FXC-r2:white:adsl", ++ .gpio = NB4_74HC64_GPIO(4), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-FXC-r2:white:traffic", ++ .gpio = 2, ++ }, ++ { ++ .name = "NB4-FXC-r2:white:tel", ++ .gpio = NB4_74HC64_GPIO(3), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-FXC-r2:white:tv", ++ .gpio = NB4_74HC64_GPIO(2), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-FXC-r2:white:wifi", ++ .gpio = 15, ++ }, ++ { ++ .name = "NB4-FXC-r2:white:alarm", ++ .gpio = NB4_74HC64_GPIO(0), ++ .active_low = 1, ++ }, ++ { ++ .name = "NB4-FXC-r2:red:service", ++ .gpio = 29, ++ }, ++ { ++ .name = "NB4-FXC-r2:green:service", ++ .gpio = 30, ++ }, ++ { ++ .name = "NB4-FXC-r2:blue:service", ++ .gpio = 4, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 34, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 37, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "service", ++ .gpio = 27, ++ .type = EV_KEY, ++ .code = BTN_0, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "clip", ++ .gpio = 31, ++ .type = EV_KEY, ++ .code = BTN_1, ++ .active_low = 1, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++ .devs = nb4_devices, ++ .num_devs = ARRAY_SIZE(nb4_devices), ++ .spis = nb4_spi_devices, ++ .num_spis = ARRAY_SIZE(nb4_spi_devices), ++}; + #endif + + /* +@@ -696,6 +1284,11 @@ static const struct board_info __initdat + &board_96358vw2, + &board_AGPFS0, + &board_DWVS0, ++ &board_nb4_ser_r0, ++ &board_nb4_ser_r1, ++ &board_nb4_ser_r2, ++ &board_nb4_fxc_r1, ++ &board_nb4_fxc_r2, + #endif + }; + +@@ -750,6 +1343,16 @@ static void __init boardid_fixup(u8 *boo + struct bcm_tag *tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_64K); + char *board_name = (char *)bcm63xx_nvram_get_name(); + ++ if (BCMCPU_IS_6358() && (!strcmp(board_name, "96358VW"))) { ++ u8 *p = boot_addr + NB4_PID_OFFSET; ++ ++ /* Extract nb4 PID */ ++ if (!memcmp(p, "NB4-", 4)) { ++ memcpy(board_name, p, sizeof("NB4-XXX-rX")); ++ return; ++ } ++ } ++ + /* check if bcm_tag is at 64k offset */ + if (strncmp(board_name, tag->boardid, BOARDID_LEN) != 0) { + /* else try 128k */ diff --git a/target/linux/brcm63xx/patches-3.3/502-board-96338W2_E7T.patch b/target/linux/brcm63xx/patches-3.3/502-board-96338W2_E7T.patch new file mode 100644 index 000000000..12c7ac4f1 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/502-board-96338W2_E7T.patch @@ -0,0 +1,49 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -140,6 +140,38 @@ static struct board_info __initdata boar + }, + }, + }; ++ ++static struct board_info __initdata board_96338w2_e7t = { ++ .name = "96338W2_E7T", ++ .expected_cpu_id = 0x6338, ++ ++ .has_enet0 = 1, ++ ++ .enet0 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "96338W2_E7T:green:ppp", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ { ++ .name = "96338W2_E7T:green:ppp-fail", ++ .gpio = 5, ++ .active_low = 1, ++ }, ++ { ++ .name = "96338W2_E7T:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ ++ }, ++ }, ++}; + #endif + + /* +@@ -1263,6 +1295,7 @@ static const struct board_info __initdat + #ifdef CONFIG_BCM63XX_CPU_6338 + &board_96338gw, + &board_96338w, ++ &board_96338w2_e7t, + #endif + #ifdef CONFIG_BCM63XX_CPU_6345 + &board_96345gw2, diff --git a/target/linux/brcm63xx/patches-3.3/503-board-CPVA642.patch b/target/linux/brcm63xx/patches-3.3/503-board-CPVA642.patch new file mode 100644 index 000000000..98c9375d8 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/503-board-CPVA642.patch @@ -0,0 +1,107 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -663,6 +663,96 @@ static struct board_info __initdata boar + }, + }; + ++static struct board_info __initdata board_CPVA642 = { ++ .name = "CPVA642", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .has_ohci0 = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "CPVA642:red:power", ++ .gpio = 14, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA642:green:power", ++ .gpio = 11, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "CPVA642:red:wifi", ++ .gpio = 6, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA642:green:wifi", ++ .gpio = 28, ++ .active_low = 0, ++ }, ++ { ++ .name = "CPVA642:red:link", ++ .gpio = 9, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA642:green:link", ++ .gpio = 10, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA642:green:ether", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA642:green:phone1", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA642:green:phone2", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA642:green:usb", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 36, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 37, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; ++ ++ + static struct board_info __initdata board_AGPFS0 = { + .name = "AGPF-S0", + .expected_cpu_id = 0x6358, +@@ -1316,6 +1406,7 @@ static const struct board_info __initdat + &board_96358vw, + &board_96358vw2, + &board_AGPFS0, ++ &board_CPVA642, + &board_DWVS0, + &board_nb4_ser_r0, + &board_nb4_ser_r1, diff --git a/target/linux/brcm63xx/patches-3.3/504-board_dsl_274xb_rev_c.patch b/target/linux/brcm63xx/patches-3.3/504-board_dsl_274xb_rev_c.patch new file mode 100644 index 000000000..ea8ba5980 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/504-board_dsl_274xb_rev_c.patch @@ -0,0 +1,70 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -797,6 +797,59 @@ static struct board_info __initdata boar + .has_ohci0 = 1, + }; + ++/* D-Link DSL-274xB revison C2/C3 */ ++static struct board_info __initdata board_dsl_274xb_rev_c = { ++ .name = "AW4139", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "dsl-274xb:green:power", ++ .gpio = 5, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "dsl-274xb:red:power", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ { ++ .name = "dsl-274xb:green:adsl", ++ .gpio = 9, ++ .active_low = 1, ++ }, ++ { ++ .name = "dsl-274xb:green:internet", ++ .gpio = 2, ++ }, ++ { ++ .name = "dsl-274xb:red:internet", ++ .gpio = 10, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 34, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; ++ + struct spi_gpio_platform_data nb4_spi_gpio_data = { + .sck = NB4_SPI_GPIO_CLK, + .mosi = NB4_SPI_GPIO_MOSI, +@@ -1408,6 +1461,7 @@ static const struct board_info __initdat + &board_AGPFS0, + &board_CPVA642, + &board_DWVS0, ++ &board_dsl_274xb_rev_c, + &board_nb4_ser_r0, + &board_nb4_ser_r1, + &board_nb4_ser_r2, diff --git a/target/linux/brcm63xx/patches-3.3/505-board_spw500v.patch b/target/linux/brcm63xx/patches-3.3/505-board_spw500v.patch new file mode 100644 index 000000000..584efd1e9 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/505-board_spw500v.patch @@ -0,0 +1,78 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -557,6 +557,67 @@ static struct board_info __initdata boar + }, + }, + }; ++ ++static struct board_info __initdata board_spw500v = { ++ .name = "SPW500V", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .has_dsp = 1, ++ .dsp = { ++ .gpio_rst = 6, ++ .gpio_int = 34, ++ .ext_irq = 2, ++ .cs = 2, ++ }, ++ ++ .leds = { ++ { ++ .name = "SPW500V:red:power", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++ { ++ .name = "SPW500V:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "SPW500V:green:ppp", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { .name = "SPW500V:green:pstn", ++ .gpio = 28, ++ .active_low = 1, ++ }, ++ { ++ .name = "SPW500V:green:voip", ++ .gpio = 32, ++ .active_low = 1, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 33, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; + #endif + + /* +@@ -1453,6 +1514,7 @@ static const struct board_info __initdat + &board_96348gw_a, + &board_rta1025w_16, + &board_96348_D4PW, ++ &board_spw500v, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 diff --git a/target/linux/brcm63xx/patches-3.3/506-board_gw6200_gw6000.patch b/target/linux/brcm63xx/patches-3.3/506-board_gw6200_gw6000.patch new file mode 100644 index 000000000..78e06d842 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/506-board_gw6200_gw6000.patch @@ -0,0 +1,124 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -426,6 +426,112 @@ static struct board_info __initdata boar + }, + }; + ++static struct board_info __initdata board_gw6200 = { ++ .name = "GW6200", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .has_ohci0 = 1, ++ ++ .has_dsp = 1, ++ .dsp = { ++ .gpio_rst = 8, /* FIXME: What is real GPIO here? */ ++ .gpio_int = 34, ++ .ext_irq = 2, ++ .cs = 2, ++ }, ++ ++ .leds = { ++ { ++ .name = "GW6200:green:line1", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ { ++ .name = "GW6200:green:line2", ++ .gpio = 5, ++ .active_low = 1, ++ }, ++ { ++ .name = "GW6200:green:line3", ++ .gpio = 6, ++ .active_low = 1, ++ }, ++ { ++ .name = "GW6200:green:tel", ++ .gpio = 7, ++ .active_low = 1, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 36, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; ++ ++static struct board_info __initdata board_gw6000 = { ++ .name = "GW6000", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .has_ohci0 = 1, ++ ++ .has_dsp = 1, ++ .dsp = { ++ .gpio_rst = 6, ++ .gpio_int = 34, ++ .ext_irq = 2, ++ .cs = 2, ++ }, ++ ++ /* GW6000 has no GPIO-controlled leds */ ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 36, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; ++ ++ ++ + static struct board_info __initdata board_FAST2404 = { + .name = "F@ST2404", + .expected_cpu_id = 0x6348, +@@ -1507,6 +1613,8 @@ static const struct board_info __initdat + #ifdef CONFIG_BCM63XX_CPU_6348 + &board_96348r, + &board_96348gw, ++ &board_gw6000, ++ &board_gw6200, + &board_96348gw_10, + &board_96348gw_11, + &board_FAST2404, diff --git a/target/linux/brcm63xx/patches-3.3/507-board-MAGIC.patch b/target/linux/brcm63xx/patches-3.3/507-board-MAGIC.patch new file mode 100644 index 000000000..7b96f3211 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/507-board-MAGIC.patch @@ -0,0 +1,87 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -724,6 +724,76 @@ static struct board_info __initdata boar + }, + }, + }; ++ ++static struct board_info __initdata board_96348sv = { ++ .name = "MAGIC", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ .enet1 = { ++ /* it has BP_ENET_EXTERNAL_PHY */ ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++ ++ .has_dsp = 1, ++ .dsp = { ++ .gpio_rst = 25, ++ .gpio_int = 34, ++ .cs = 2, ++ .ext_irq = 2, ++ }, ++ ++ .leds = { ++ { ++ .name = "MAGIC:green:voip", ++ .gpio = 22, ++ .active_low = 1, ++ }, ++ { ++ .name = "MAGIC:green:adsl", ++ .gpio = 5, ++ .active_low = 1, ++ }, ++ { ++ .name = "MAGIC:green:wifi", ++ .gpio = 28, ++ }, ++ { ++ .name = "MAGIC:green:usb", ++ .gpio = 35, ++ .active_low = 1, ++ }, ++ { ++ .name = "MAGIC:green:hpna", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ { ++ .name = "MAGIC:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "MAGIC:green:stop", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++ }, ++}; + #endif + + /* +@@ -1623,6 +1693,7 @@ static const struct board_info __initdat + &board_rta1025w_16, + &board_96348_D4PW, + &board_spw500v, ++ &board_96348sv, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 diff --git a/target/linux/brcm63xx/patches-3.3/508-board_hw553.patch b/target/linux/brcm63xx/patches-3.3/508-board_hw553.patch new file mode 100644 index 000000000..dc9a744ef --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/508-board_hw553.patch @@ -0,0 +1,91 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -1666,6 +1666,80 @@ static struct board_info __initdata boar + .spis = nb4_spi_devices, + .num_spis = ARRAY_SIZE(nb4_spi_devices), + }; ++ ++static struct board_info __initdata board_HW553 = { ++ .name = "HW553", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .has_ohci0 = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "HW553:red:lan", ++ .gpio = 34, ++ .active_low = 1, ++ }, ++ { ++ .name = "HW553:blue:lan", ++ .gpio = 35, ++ .active_low = 1, ++ }, ++ { ++ .name = "HW553:red:adsl", ++ .gpio = 22, ++ .active_low = 1, ++ }, ++ { ++ .name = "HW553:blue:adsl", ++ .gpio = 23, ++ .active_low = 1, ++ }, ++ { ++ .name = "HW553:red:power", ++ .gpio = 5, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ ++ { ++ .name = "HW553:blue:power", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ { ++ .name = "HW553:red:wifi", ++ .gpio = 25, ++ .active_low = 1, ++ }, ++ { ++ .name = "HW553:red:internetkey", ++ .gpio = 12, ++ .active_low = 1, ++ }, ++ { ++ .name = "HW553:blue:internetkey", ++ .gpio = 13, ++ .active_low = 1, ++ }, ++ }, ++}; + #endif + + /* +@@ -1708,6 +1782,7 @@ static const struct board_info __initdat + &board_nb4_ser_r2, + &board_nb4_fxc_r1, + &board_nb4_fxc_r2, ++ &board_HW553, + #endif + }; + diff --git a/target/linux/brcm63xx/patches-3.3/509-board_rta1320_16m.patch b/target/linux/brcm63xx/patches-3.3/509-board_rta1320_16m.patch new file mode 100644 index 000000000..11c0903a9 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/509-board_rta1320_16m.patch @@ -0,0 +1,54 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -172,6 +172,43 @@ static struct board_info __initdata boar + }, + }, + }; ++ ++static struct board_info __initdata board_rta1320_16m = { ++ .name = "RTA1320_16M", ++ .expected_cpu_id = 0x6338, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ ++ .enet0 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "RTA1320_16M:green:adsl", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { ++ .name = "RTA1320_16M:green:ppp", ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ { ++ .name = "RTA1320_16M:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "RTA1320_16M:green:stop", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++ }, ++}; + #endif + + /* +@@ -1750,6 +1787,7 @@ static const struct board_info __initdat + &board_96338gw, + &board_96338w, + &board_96338w2_e7t, ++ &board_rta1320_16m, + #endif + #ifdef CONFIG_BCM63XX_CPU_6345 + &board_96345gw2, diff --git a/target/linux/brcm63xx/patches-3.3/510-board_spw303v.patch b/target/linux/brcm63xx/patches-3.3/510-board_spw303v.patch new file mode 100644 index 000000000..2ff60a4bc --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/510-board_spw303v.patch @@ -0,0 +1,83 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -1777,6 +1777,72 @@ static struct board_info __initdata boar + }, + }, + }; ++ ++ /* T-Home Speedport W 303V Typ B */ ++static struct board_info __initdata board_spw303v = { ++ .name = "96358-502V", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "spw303v:green:power+adsl", ++ .gpio = 22, ++ .active_low = 1, ++ }, ++ { ++ .name = "spw303v:red:power+adsl", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "spw303v:green:ppp", ++ .gpio = 5, ++ .active_low = 1, ++ }, ++ { ++ .name = "spw303v:green:ses", ++ .gpio = 0, ++ .active_low = 1, ++ }, ++ { ++ .name = "spw303v:green:voip", ++ .gpio = 27, ++ .active_low = 1, ++ }, ++ { ++ .name = "spw303v:green:pots", ++ .gpio = 31, ++ .active_low = 1, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 11, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "ses", ++ .gpio = 37, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ } ++}; + #endif + + /* +@@ -1821,6 +1887,7 @@ static const struct board_info __initdat + &board_nb4_fxc_r1, + &board_nb4_fxc_r2, + &board_HW553, ++ &board_spw303v, + #endif + }; + diff --git a/target/linux/brcm63xx/patches-3.3/511-board_V2500V.patch b/target/linux/brcm63xx/patches-3.3/511-board_V2500V.patch new file mode 100644 index 000000000..ff52497d4 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/511-board_V2500V.patch @@ -0,0 +1,122 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -831,6 +831,63 @@ static struct board_info __initdata boar + }, + }, + }; ++ ++static struct board_info __initdata board_V2500V_BB = { ++ .name = "V2500V_BB", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "V2500V_BB:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "V2500V_BB:red:power", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++ { ++ .name = "V2500V_BB:green:adsl", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { .name = "V2500V_BB:green:ppp", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { ++ .name = "V2500V_BB:green:wireless", ++ .gpio = 6, ++ .active_low = 1, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 31, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; + #endif + + /* +@@ -1872,6 +1929,7 @@ static const struct board_info __initdat + &board_96348_D4PW, + &board_spw500v, + &board_96348sv, ++ &board_V2500V_BB, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 +@@ -1992,6 +2050,23 @@ void __init board_prom_init(void) + val &= MPI_CSBASE_BASE_MASK; + } + boot_addr = (u8 *)KSEG1ADDR(val); ++ printk(KERN_INFO PFX "Boot address 0x%08x\n",(unsigned int)boot_addr); ++ ++ /* BT Voyager 2500V (RTA1046VW PCB) has 8 Meg flash used as two */ ++ /* banks of 4 Meg. The byte at 0xBF800000 identifies the back to use.*/ ++ /* Loading firmware from the CFE Prompt always loads to Bank 0 */ ++ /* Do an early check of CFE and then select bank 0 */ ++ ++ if (boot_addr == (u8 *)0xbf800000) { ++ unsigned char board_name[16]; ++ u8 *tmp_boot_addr; ++ tmp_boot_addr = (u8 *)0xbfc00000; // Address of Bank 0 ++ memcpy(board_name, tmp_boot_addr + BCM963XX_NVRAM_OFFSET + offsetof(struct bcm963xx_nvram, name), sizeof(board_name)); ++ if (!strcmp(board_name, "V2500V_BB")) { ++ printk(KERN_INFO PFX "V2500V: nvram bank 0\n"); ++ boot_addr = (u8 *)0xbfc00000; // Bank 0 ++ } ++ } + + /* dump cfe version */ + cfe = boot_addr + BCM963XX_CFE_VERSION_OFFSET; +--- a/arch/mips/bcm63xx/dev-flash.c ++++ b/arch/mips/bcm63xx/dev-flash.c +@@ -19,6 +19,7 @@ + #include <linux/spi/spi.h> + #include <linux/spi/flash.h> + ++#include <bcm63xx_board.h> + #include <bcm63xx_cpu.h> + #include <bcm63xx_dev_flash.h> + #include <bcm63xx_dev_hsspi.h> +@@ -162,6 +163,13 @@ int __init bcm63xx_flash_register(int nu + val = bcm_mpi_readl(MPI_CSBASE_REG(0)); + val &= MPI_CSBASE_BASE_MASK; + ++ /* BT Voyager 2500V has 8 Meg flash in two 4 Meg banks */ ++ /* Loading from CFE always uses Bank 0 */ ++ if (!strcmp(board_get_name(), "V2500V_BB")) { ++ pr_info("V2500V: Start in Bank 0\n"); ++ val = val + 0x400000; // Select Bank 0 start address ++ } ++ + mtd_resources[0].start = val; + mtd_resources[0].end = 0x1FFFFFFF; + diff --git a/target/linux/brcm63xx/patches-3.3/512-board_BTV2110.patch b/target/linux/brcm63xx/patches-3.3/512-board_BTV2110.patch new file mode 100644 index 000000000..03d9b4144 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/512-board_BTV2110.patch @@ -0,0 +1,73 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -395,6 +395,62 @@ static struct board_info __initdata boar + }, + }; + ++ ++/* BT Voyager 2110 */ ++static struct board_info __initdata board_V2110 = { ++ .name = "V2110", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "V2110:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "V2110:red:power", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++ { ++ .name = "V2110:green:adsl", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { .name = "V2110:green:ppp", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { ++ .name = "V2110:green:wireless", ++ .gpio = 6, ++ .active_low = 1, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 33, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; ++ ++ + static struct board_info __initdata board_96348gw = { + .name = "96348GW", + .expected_cpu_id = 0x6348, +@@ -1930,6 +1986,7 @@ static const struct board_info __initdat + &board_spw500v, + &board_96348sv, + &board_V2500V_BB, ++ &board_V2110, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 diff --git a/target/linux/brcm63xx/patches-3.3/513-board_livebox.patch b/target/linux/brcm63xx/patches-3.3/513-board_livebox.patch new file mode 100644 index 000000000..dc53d481b --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/513-board_livebox.patch @@ -0,0 +1,391 @@ +--- a/arch/mips/bcm63xx/boards/Kconfig ++++ b/arch/mips/bcm63xx/boards/Kconfig +@@ -8,4 +8,10 @@ config BOARD_BCM963XX + select SSB + help + ++config BOARD_LIVEBOX ++ bool "Inventel Livebox(es) boards" ++ select SSB ++ help ++ Inventel Livebox boards using the RedBoot bootloader. ++ + endchoice +--- a/arch/mips/bcm63xx/boards/Makefile ++++ b/arch/mips/bcm63xx/boards/Makefile +@@ -1,3 +1,4 @@ + obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o ++obj-$(CONFIG_BOARD_LIVEBOX) += board_livebox.o + + ccflags-y := -Werror +--- /dev/null ++++ b/arch/mips/bcm63xx/boards/board_livebox.c +@@ -0,0 +1,368 @@ ++/* ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org> ++ */ ++ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/string.h> ++#include <linux/platform_device.h> ++#include <linux/mtd/mtd.h> ++#include <linux/mtd/partitions.h> ++#include <linux/mtd/physmap.h> ++#include <linux/ssb/ssb.h> ++#include <linux/gpio_keys.h> ++#include <linux/input.h> ++#include <linux/spi/spi.h> ++#include <asm/addrspace.h> ++#include <bcm63xx_board.h> ++#include <bcm63xx_cpu.h> ++#include <bcm63xx_dev_uart.h> ++#include <bcm63xx_regs.h> ++#include <bcm63xx_io.h> ++#include <bcm63xx_dev_pci.h> ++#include <bcm63xx_dev_enet.h> ++#include <bcm63xx_dev_dsp.h> ++#include <bcm63xx_dev_pcmcia.h> ++#include <bcm63xx_dev_usb_ohci.h> ++#include <bcm63xx_dev_usb_ehci.h> ++#include <bcm63xx_dev_spi.h> ++#include <board_bcm963xx.h> ++ ++#define PFX "board_livebox: " ++ ++#define LIVEBOX_KEYS_POLL_INTERVAL 20 ++#define LIVEBOX_KEYS_DEBOUNCE_INTERVAL (LIVEBOX_KEYS_POLL_INTERVAL * 3) ++ ++static unsigned int mac_addr_used = 0; ++static struct board_info board; ++ ++/* ++ * known 6348 boards ++ */ ++#ifdef CONFIG_BCM63XX_CPU_6348 ++static struct board_info __initdata board_livebox_blue5g = { ++ .name = "Livebox-blue-5g", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ ++ .enet1 = { ++ .has_phy = 1, ++ .phy_id = 31, ++ }, ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ ++ .has_dsp = 0, /*TODO some Liveboxes have dsp*/ ++ .dsp = { ++ .gpio_rst = 6, /*FIXME eth1 shares gpio6 with dsp?*/ ++ .gpio_int = 35, ++ .cs = 2, ++ .ext_irq = 2, ++ }, ++ ++ .leds = { ++ { ++ .name = "Livebox-blue-5g::adsl-fail", ++ .gpio = 0, ++ .active_low = 0, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "Livebox-blue-5g::adsl", ++ .gpio = 1, ++ }, ++ { ++ .name = "Livebox-blue-5g::traffic", ++ .gpio = 2, ++ }, ++ { ++ .name = "Livebox-blue-5g::phone", ++ .gpio = 3, ++ }, ++ { ++ .name = "Livebox-blue-5g::wifi", ++ .gpio = 4, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "BTN_1", ++ .gpio = 36, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = BTN_1, ++ .debounce_interval = LIVEBOX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "BTN_2", ++ .gpio = 7, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = BTN_2, ++ .debounce_interval = LIVEBOX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ ++ }, ++}; ++#endif ++ ++/* ++ * all boards ++ */ ++static const struct board_info __initdata *bcm963xx_boards[] = { ++#ifdef CONFIG_BCM63XX_CPU_6348 ++ &board_livebox_blue5g ++#endif ++}; ++/* ++ * return board name for /proc/cpuinfo ++ */ ++const char *board_get_name(void) ++{ ++ return board.name; ++} ++ ++/* ++ * register & return a new board mac address ++ */ ++static int board_get_mac_address(u8 *mac) ++{ ++ u8 *p; ++ int count; ++ ++ memcpy(mac, (u8 *)0xBEBFF377, ETH_ALEN); ++ ++ p = mac + ETH_ALEN - 1; ++ count = mac_addr_used; ++ ++ while (count--) { ++ do { ++ (*p)++; ++ if (*p != 0) ++ break; ++ p--; ++ } while (p != mac); ++ } ++ ++ if (p == mac) { ++ printk(KERN_ERR PFX "unable to fetch mac address\n"); ++ return -ENODEV; ++ } ++ mac_addr_used++; ++ ++ return 0; ++} ++ ++/* ++ * early init callback ++ */ ++#define LIVEBOX_GPIO_DETECT_MASK 0x000000ff ++#define LIVEBOX_BOOT_ADDR 0x1e400000 ++ ++#define LIVEBOX_HW_BLUE5G_9 0x90 ++ ++void __init board_prom_init(void) ++{ ++ u32 val; ++ u8 hw_version; ++ ++ /* Get hardware version */ ++ val = bcm_gpio_readl(GPIO_CTL_LO_REG); ++ val &= ~LIVEBOX_GPIO_DETECT_MASK; ++ bcm_gpio_writel(val, GPIO_CTL_LO_REG); ++ ++ hw_version = bcm_gpio_readl(GPIO_DATA_LO_REG) & LIVEBOX_GPIO_DETECT_MASK; ++ switch (hw_version) { ++ case LIVEBOX_HW_BLUE5G_9: ++ printk(KERN_INFO PFX "Livebox BLUE5G.9\n"); ++ memcpy(&board, bcm963xx_boards[0], sizeof(board)); ++ break; ++ default: ++ printk(KERN_INFO PFX "Unknown livebox version: %02x\n", hw_version); ++ break; ++ } ++ ++ /* use default livebox configuration */ ++ memcpy(&board, bcm963xx_boards[0], sizeof(board)); ++ ++ /* setup pin multiplexing depending on board enabled device, ++ * this has to be done this early since PCI init is done ++ * inside arch_initcall */ ++ val = 0; ++ ++#ifdef CONFIG_PCI ++ if (board.has_pci) { ++ if (BCMCPU_IS_6348()) ++ val |= GPIO_MODE_6348_G2_PCI; ++ } ++#endif ++ if (board.has_pccard) { ++ if (BCMCPU_IS_6348()) ++ val |= GPIO_MODE_6348_G1_MII_PCCARD; ++ } ++ ++ if (board.has_enet0 && !board.enet0.use_internal_phy) { ++ if (BCMCPU_IS_6348()) ++ val |= GPIO_MODE_6348_G3_EXT_MII | ++ GPIO_MODE_6348_G0_EXT_MII; ++ } ++ ++ if (board.has_enet1 && !board.enet1.use_internal_phy) { ++ if (BCMCPU_IS_6348()) ++ val |= GPIO_MODE_6348_G3_EXT_MII | ++ GPIO_MODE_6348_G0_EXT_MII; ++ printk(KERN_INFO PFX "resetting gpio6 for eth1...\n"); ++ gpio_request(6, "dsp_eth_rst"); ++ gpio_direction_output(6, 0); ++ gpio_set_value(6, 1); ++ } ++ ++ bcm_gpio_writel(val, GPIO_MODE_REG); ++} ++ ++/* ++ * second stage init callback, good time to panic if we couldn't ++ * identify on which board we're running since early printk is working ++ */ ++void __init board_setup(void) ++{ ++ if (!board.name[0]) ++ panic("unable to detect bcm963xx board"); ++ printk(KERN_INFO PFX "board name: %s\n", board.name); ++ ++ /* make sure we're running on expected cpu */ ++ if (bcm63xx_get_cpu_id() != board.expected_cpu_id) ++ panic("unexpected CPU for bcm963xx board"); ++} ++ ++static struct physmap_flash_data flash_data = { ++ .width = 2, ++}; ++ ++static struct resource mtd_resources[] = { ++ { ++ .start = 0, /* filled at runtime */ ++ .end = 0, /* filled at runtime */ ++ .flags = IORESOURCE_MEM, ++ } ++}; ++ ++static struct platform_device mtd_dev = { ++ .name = "physmap-flash", ++ .resource = mtd_resources, ++ .num_resources = ARRAY_SIZE(mtd_resources), ++ .dev = { ++ .platform_data = &flash_data, ++ }, ++}; ++ ++static struct gpio_led_platform_data bcm63xx_led_data; ++ ++static struct platform_device bcm63xx_gpio_leds = { ++ .name = "leds-gpio", ++ .id = 0, ++ .dev.platform_data = &bcm63xx_led_data, ++}; ++ ++static struct gpio_keys_platform_data bcm63xx_gpio_keys_data = { ++ .poll_interval = LIVEBOX_KEYS_POLL_INTERVAL, ++}; ++ ++static struct platform_device bcm63xx_gpio_keys_device = { ++ .name = "gpio-keys-polled", ++ .id = 0, ++ .dev.platform_data = &bcm63xx_gpio_keys_data, ++}; ++ ++/* ++ * third stage init callback, register all board devices. ++ */ ++int __init board_register_devices(void) ++{ ++ u32 val; ++ int led_count = 0; ++ int button_count = 0; ++ ++ if (board.has_uart0) ++ bcm63xx_uart_register(0); ++ ++ if (board.has_uart1) ++ bcm63xx_uart_register(1); ++ ++ if (board.has_pccard) ++ bcm63xx_pcmcia_register(); ++ ++ if (board.has_enet0 && ++ !board_get_mac_address(board.enet0.mac_addr)) ++ bcm63xx_enet_register(0, &board.enet0); ++ ++ if (board.has_enet1 && ++ !board_get_mac_address(board.enet1.mac_addr)) ++ bcm63xx_enet_register(1, &board.enet1); ++ ++ if (board.has_ehci0) ++ bcm63xx_ehci_register(); ++ ++ if (board.has_ohci0) ++ bcm63xx_ohci_register(); ++ ++ if (board.has_dsp) ++ bcm63xx_dsp_register(&board.dsp); ++ ++ bcm63xx_spi_register(); ++ ++ if (board.num_devs) ++ platform_add_devices(board.devs, board.num_devs); ++ ++ if (board.num_spis) ++ spi_register_board_info(board.spis, board.num_spis); ++ ++ ++ /* read base address of boot chip select (0) */ ++ val = bcm_mpi_readl(MPI_CSBASE_REG(0)); ++ val &= MPI_CSBASE_BASE_MASK; ++ if (val != LIVEBOX_BOOT_ADDR) ++ printk(KERN_NOTICE PFX "flash address is: 0x%08x, forcing to: 0x%08x\n", ++ val, LIVEBOX_BOOT_ADDR); ++ mtd_resources[0].start = LIVEBOX_BOOT_ADDR; ++ mtd_resources[0].end = 0x1ebfffff; ++ ++ platform_device_register(&mtd_dev); ++ ++ /* count number of LEDs defined by this device */ ++ while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name) ++ led_count++; ++ ++ bcm63xx_led_data.num_leds = led_count; ++ bcm63xx_led_data.leds = board.leds; ++ ++ platform_device_register(&bcm63xx_gpio_leds); ++ ++ /* count number of BUTTONs defined by this device */ ++ while (button_count < ARRAY_SIZE(board.buttons) && board.buttons[button_count].desc) ++ button_count++; ++ ++ if (button_count) { ++ bcm63xx_gpio_keys_data.nbuttons = button_count; ++ bcm63xx_gpio_keys_data.buttons = board.buttons; ++ ++ platform_device_register(&bcm63xx_gpio_keys_device); ++ } ++ ++ return 0; ++} diff --git a/target/linux/brcm63xx/patches-3.3/514-board_ct536_ct5621.patch b/target/linux/brcm63xx/patches-3.3/514-board_ct536_ct5621.patch new file mode 100644 index 000000000..41e37c828 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/514-board_ct536_ct5621.patch @@ -0,0 +1,60 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -451,6 +451,49 @@ static struct board_info __initdata boar + }; + + ++static struct board_info __initdata board_ct536_ct5621 = { ++ .name = "CT536_CT5621", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 0, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "CT536_CT5621:green:adsl-fail", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "CT536_CT5621:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 33, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; ++ + static struct board_info __initdata board_96348gw = { + .name = "96348GW", + .expected_cpu_id = 0x6348, +@@ -1987,6 +2030,7 @@ static const struct board_info __initdat + &board_96348sv, + &board_V2500V_BB, + &board_V2110, ++ &board_ct536_ct5621, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 diff --git a/target/linux/brcm63xx/patches-3.3/515-board_DWV-S0_fixes.patch b/target/linux/brcm63xx/patches-3.3/515-board_DWV-S0_fixes.patch new file mode 100644 index 000000000..22d7a1836 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/515-board_DWV-S0_fixes.patch @@ -0,0 +1,19 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -1210,6 +1210,8 @@ static struct board_info __initdata boar + .name = "DWV-S0", + .expected_cpu_id = 0x6358, + ++ .has_uart0 = 1, ++ + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, +@@ -1225,6 +1227,7 @@ static struct board_info __initdata boar + }, + + .has_ohci0 = 1, ++ .has_ehci0 = 1, + }; + + /* D-Link DSL-274xB revison C2/C3 */ diff --git a/target/linux/brcm63xx/patches-3.3/516-board_96348A-122.patch b/target/linux/brcm63xx/patches-3.3/516-board_96348A-122.patch new file mode 100644 index 000000000..dbc9aeb33 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/516-board_96348A-122.patch @@ -0,0 +1,78 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -494,6 +494,67 @@ static struct board_info __initdata boar + }, + }; + ++static struct board_info __initdata board_96348A_122 = { ++ .name = "96348A-122", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .has_ohci0 = 1, ++ ++ .leds = { ++ { ++ .name = "96348A-122:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "96348A-122:red:alarm", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "96348A-122:green:wps", ++ .gpio = 6, ++ .active_low = 1, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 33, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wlan", ++ .gpio = 34, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_WLAN, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 35, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; ++ + static struct board_info __initdata board_96348gw = { + .name = "96348GW", + .expected_cpu_id = 0x6348, +@@ -2034,6 +2095,7 @@ static const struct board_info __initdat + &board_V2500V_BB, + &board_V2110, + &board_ct536_ct5621, ++ &board_96348A_122, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 diff --git a/target/linux/brcm63xx/patches-3.3/517-RTA1205W_16_uart_fixes.patch b/target/linux/brcm63xx/patches-3.3/517-RTA1205W_16_uart_fixes.patch new file mode 100644 index 000000000..63eccd26c --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/517-RTA1205W_16_uart_fixes.patch @@ -0,0 +1,10 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -757,6 +757,7 @@ static struct board_info __initdata boar + .name = "RTA1025W_16", + .expected_cpu_id = 0x6348, + ++ .has_uart0 = 1, + .has_enet0 = 1, + .has_enet1 = 1, + .has_pci = 1, diff --git a/target/linux/brcm63xx/patches-3.3/519_board_CPVA502plus.patch b/target/linux/brcm63xx/patches-3.3/519_board_CPVA502plus.patch new file mode 100644 index 000000000..07adb376f --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/519_board_CPVA502plus.patch @@ -0,0 +1,55 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -1049,6 +1049,44 @@ static struct board_info __initdata boar + }, + }, + }; ++ ++static struct board_info __initdata board_CPVA502plus = { ++ .name = "CPVA502+", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 1, ++ .use_internal_phy = 1, ++ }, ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "CPVA502+:green:phone", ++ .gpio = 0, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA502+:green:link", ++ .gpio = 5, ++ .active_low = 1, ++ }, ++ { ++ .name = "CPVA502+:green:feth1", /* FIXME:does gpio4 enable eth1 phy? */ ++ .gpio = 4, ++ .active_low = 1, ++ }, ++ }, ++}; ++ + #endif + + /* +@@ -2097,6 +2135,7 @@ static const struct board_info __initdat + &board_V2110, + &board_ct536_ct5621, + &board_96348A_122, ++ &board_CPVA502plus, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 diff --git a/target/linux/brcm63xx/patches-3.3/520-bcm63xx-add-support-for-96368MVWG-board.patch b/target/linux/brcm63xx/patches-3.3/520-bcm63xx-add-support-for-96368MVWG-board.patch new file mode 100644 index 000000000..f2e5dba04 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/520-bcm63xx-add-support-for-96368MVWG-board.patch @@ -0,0 +1,128 @@ +From eeacc2529942051504bc957726aa178671344421 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Wed, 20 Jan 2010 16:21:30 +0100 +Subject: [PATCH 32/63] bcm63xx: add support for 96368MVWG board. + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 95 ++++++++++++++++++++ + .../mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 2 + + 2 files changed, 97 insertions(+), 0 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -2105,6 +2105,78 @@ static struct board_info __initdata boar + #endif + + /* ++ * known 6368 boards ++ */ ++#ifdef CONFIG_BCM63XX_CPU_6368 ++static struct board_info __initdata board_96368mvwg = { ++ .name = "96368MVWG", ++ .expected_cpu_id = 0x6368, ++ ++ .has_uart0 = 1, ++ .has_pci = 1, ++ .has_enetsw = 1, ++ ++ .enetsw = { ++ .used_ports = { ++ [1] = { ++ .used = 1, ++ .phy_id = 2, ++ .name = "port1", ++ }, ++ ++ [2] = { ++ .used = 1, ++ .phy_id = 3, ++ .name = "port2", ++ }, ++ ++ [4] = { ++ .used = 1, ++ .phy_id = 0x12, ++ .name = "port0", ++ }, ++ ++ [5] = { ++ .used = 1, ++ .phy_id = 0x11, ++ .name = "port3", ++ }, ++ }, ++ }, ++ ++ .leds = { ++ { ++ .name = "96368MVWG:green:adsl", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "96368MVWG:green:ppp", ++ .gpio = 5, ++ }, ++ { ++ .name = "96368MVWG:green:power", ++ .gpio = 22, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "96368MVWG:green:wps", ++ .gpio = 23, ++ .active_low = 1, ++ }, ++ { ++ .name = "96368MVWG:green:ppp-fail", ++ .gpio = 31, ++ }, ++ }, ++ ++ .has_ohci0 = 1, ++ .has_ehci0 = 1, ++}; ++#endif ++ ++/* + * all boards + */ + static const struct board_info __initdata *bcm963xx_boards[] = { +@@ -2153,6 +2225,10 @@ static const struct board_info __initdat + &board_HW553, + &board_spw303v, + #endif ++ ++#ifdef CONFIG_BCM63XX_CPU_6368 ++ &board_96368mvwg, ++#endif + }; + + /* +@@ -2324,12 +2400,25 @@ void __init board_prom_init(void) + bcm63xx_pci_enabled = 1; + if (BCMCPU_IS_6348()) + val |= GPIO_MODE_6348_G2_PCI; ++ ++ if (BCMCPU_IS_6368()) ++ val |= GPIO_MODE_6368_PCI_REQ1 | ++ GPIO_MODE_6368_PCI_GNT1 | ++ GPIO_MODE_6368_PCI_INTB | ++ GPIO_MODE_6368_PCI_REQ0 | ++ GPIO_MODE_6368_PCI_GNT0; + } + #endif + + if (board.has_pccard) { + if (BCMCPU_IS_6348()) + val |= GPIO_MODE_6348_G1_MII_PCCARD; ++ ++ if (BCMCPU_IS_6368()) ++ val |= GPIO_MODE_6368_PCMCIA_CD1 | ++ GPIO_MODE_6368_PCMCIA_CD2 | ++ GPIO_MODE_6368_PCMCIA_VS1 | ++ GPIO_MODE_6368_PCMCIA_VS2; + } + + if (board.has_enet0 && !board.enet0.use_internal_phy) { diff --git a/target/linux/brcm63xx/patches-3.3/521-bcm63xx-add-support-for-96368MVNgr-board.patch b/target/linux/brcm63xx/patches-3.3/521-bcm63xx-add-support-for-96368MVNgr-board.patch new file mode 100644 index 000000000..8ddc6dbc5 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/521-bcm63xx-add-support-for-96368MVNgr-board.patch @@ -0,0 +1,92 @@ +From f457fc2eb9bb915b5a4d251c7c68d4694cf07b01 Mon Sep 17 00:00:00 2001 +From: Maxime Bizon <mbizon@freebox.fr> +Date: Fri, 4 Nov 2011 12:33:48 +0100 +Subject: [PATCH 33/63] bcm63xx: add support for 96368MVNgr board. + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 67 +++++++++++++++++++++++++++++ + 1 files changed, 67 insertions(+), 0 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -2174,6 +2174,72 @@ static struct board_info __initdata boar + .has_ohci0 = 1, + .has_ehci0 = 1, + }; ++ ++static struct board_info __initdata board_96368mvngr = { ++ .name = "96368MVNgr", ++ .expected_cpu_id = 0x6368, ++ ++ .has_uart0 = 1, ++ .has_pci = 1, ++ .has_enetsw = 1, ++ ++ .enetsw = { ++ .used_ports = { ++ [0] = { ++ .used = 1, ++ .phy_id = 1, ++ .name = "port1", ++ }, ++ ++ [1] = { ++ .used = 1, ++ .phy_id = 2, ++ .name = "port2", ++ }, ++ ++ [2] = { ++ .used = 1, ++ .phy_id = 3, ++ .name = "port3", ++ }, ++ ++ [3] = { ++ .used = 1, ++ .phy_id = 4, ++ .name = "port4", ++ }, ++ }, ++ }, ++ ++ .leds = { ++ { ++ .name = "96368MVNgr:green:adsl", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "96368MVNgr:green:inet", ++ .gpio = 5, ++ }, ++ { ++ .name = "96368MVNgr:green:power", ++ .gpio = 22, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "96368MVNgr:green:wps", ++ .gpio = 23, ++ .active_low = 1, ++ }, ++ { ++ .name = "96368MVNgr:green:inet-fail", ++ .gpio = 3, ++ }, ++ }, ++ ++ .has_ohci0 = 1, ++ .has_ehci0 = 1, ++}; + #endif + + /* +@@ -2228,6 +2294,7 @@ static const struct board_info __initdat + + #ifdef CONFIG_BCM63XX_CPU_6368 + &board_96368mvwg, ++ &board_96368mvngr, + #endif + }; + diff --git a/target/linux/brcm63xx/patches-3.3/522-MIPS-BCM63XX-add-96328avng-reference-board.patch b/target/linux/brcm63xx/patches-3.3/522-MIPS-BCM63XX-add-96328avng-reference-board.patch new file mode 100644 index 000000000..59c6fe285 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/522-MIPS-BCM63XX-add-96328avng-reference-board.patch @@ -0,0 +1,102 @@ +From c93c2bbf0cc96da5a47d77f01daf6c983cfe4216 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 29 May 2012 10:52:25 +0200 +Subject: [PATCH] MIPS: BCM63XX: add 96328avng reference board + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 77 +++++++++++++++++++++++++++++ + 1 files changed, 77 insertions(+), 0 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -54,6 +54,80 @@ + static struct board_info board; + + /* ++ * known 6328 boards ++ */ ++#ifdef CONFIG_BCM63XX_CPU_6328 ++static struct board_info __initdata board_96328avng = { ++ .name = "96328avng", ++ .expected_cpu_id = 0x6328, ++ ++ .has_uart0 = 1, ++ .has_pci = 1, ++ ++ .has_enetsw = 1, ++ ++ .enetsw = { ++ .used_ports = { ++ [0] = { ++ .used = 1, ++ .phy_id = 1, ++ .name = "Port 1", ++ }, ++ [1] = { ++ .used = 1, ++ .phy_id = 2, ++ .name = "Port 2", ++ }, ++ [2] = { ++ .used = 1, ++ .phy_id = 3, ++ .name = "Port 3", ++ }, ++ [3] = { ++ .used = 1, ++ .phy_id = 4, ++ .name = "Port 4", ++ }, ++ }, ++ }, ++ ++ .leds = { ++ { ++ .name = "96328avng::internet-fail", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "96328avng::dsl", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { ++ .name = "96328avng::power", ++ .gpio = 4, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "96328avng::power-fail", ++ .gpio = 8, ++ .active_low = 1, ++ }, ++ { ++ .name = "96328avng::wps", ++ .gpio = 9, ++ .active_low = 1, ++ }, ++ { ++ .name = "96328avng::internet", ++ .gpio = 11, ++ .active_low = 1, ++ }, ++ }, ++}; ++#endif ++ ++/* + * known 6338 boards + */ + #ifdef CONFIG_BCM63XX_CPU_6338 +@@ -2246,6 +2320,9 @@ static struct board_info __initdata boar + * all boards + */ + static const struct board_info __initdata *bcm963xx_boards[] = { ++#ifdef CONFIG_BCM63XX_CPU_6328 ++ &board_96328avng, ++#endif + #ifdef CONFIG_BCM63XX_CPU_6338 + &board_96338gw, + &board_96338w, diff --git a/target/linux/brcm63xx/patches-3.3/523-MIPS-BCM63XX-add-963281TAN-reference-board.patch b/target/linux/brcm63xx/patches-3.3/523-MIPS-BCM63XX-add-963281TAN-reference-board.patch new file mode 100644 index 000000000..1b5d369e8 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/523-MIPS-BCM63XX-add-963281TAN-reference-board.patch @@ -0,0 +1,96 @@ +From f0649f7b7c672cf452a1796a1422bf615e1973f8 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Tue, 29 May 2012 11:01:12 +0200 +Subject: [PATCH] MIPS: BCM63XX: add 963281TAN reference board + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 71 +++++++++++++++++++++++++++++ + 1 files changed, 71 insertions(+), 0 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -125,6 +125,76 @@ static struct board_info __initdata boar + }, + }, + }; ++ ++static struct board_info __initdata board_963281TAN = { ++ .name = "963281TAN", ++ .expected_cpu_id = 0x6328, ++ ++ .has_uart0 = 1, ++ .has_pci = 1, ++ ++ .has_enetsw = 1, ++ ++ .enetsw = { ++ .used_ports = { ++ [0] = { ++ .used = 1, ++ .phy_id = 1, ++ .name = "Port 1", ++ }, ++ [1] = { ++ .used = 1, ++ .phy_id = 2, ++ .name = "Port 2", ++ }, ++ [2] = { ++ .used = 1, ++ .phy_id = 3, ++ .name = "Port 3", ++ }, ++ [3] = { ++ .used = 1, ++ .phy_id = 4, ++ .name = "Port 4", ++ }, ++ }, ++ }, ++ ++ .leds = { ++ { ++ .name = "963281TAN::internet", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++ { ++ .name = "963281TAN::power", ++ .gpio = 4, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "963281TAN::internet-fail", ++ .gpio = 7, ++ .active_low = 1, ++ }, ++ { ++ .name = "963281TAN::power-fail", ++ .gpio = 8, ++ .active_low = 1, ++ }, ++ { ++ .name = "963281TAN::wps", ++ .gpio = 9, ++ .active_low = 1, ++ }, ++ { ++ .name = "963281TAN::dsl", ++ .gpio = 11, ++ .active_low = 1, ++ }, ++ ++ }, ++}; + #endif + + /* +@@ -2322,6 +2392,7 @@ static struct board_info __initdata boar + static const struct board_info __initdata *bcm963xx_boards[] = { + #ifdef CONFIG_BCM63XX_CPU_6328 + &board_96328avng, ++ &board_963281TAN, + #endif + #ifdef CONFIG_BCM63XX_CPU_6338 + &board_96338gw, diff --git a/target/linux/brcm63xx/patches-3.3/524-board_dsl_274xb_rev_f.patch b/target/linux/brcm63xx/patches-3.3/524-board_dsl_274xb_rev_f.patch new file mode 100644 index 000000000..b339d7476 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/524-board_dsl_274xb_rev_f.patch @@ -0,0 +1,130 @@ +From 66808f706b3dcd83a9f5157997ff478a880a2906 Mon Sep 17 00:00:00 2001 +From: Jonas Gorski <jonas.gorski@gmail.com> +Date: Mon, 30 Apr 2012 09:10:51 +0200 +Subject: [PATCH 70/79] MIPS: BCM63XX: Add board definition for D-Link + DSL-274xB rev F1 + +--- + arch/mips/bcm63xx/boards/board_bcm963xx.c | 104 +++++++++++++++++++++++++++++ + 1 files changed, 104 insertions(+), 0 deletions(-) + +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -195,6 +195,109 @@ static struct board_info __initdata boar + + }, + }; ++ ++static struct board_info __initdata board_dsl_274xb_f1 = { ++ .name = "AW4339U", ++ .expected_cpu_id = 0x6328, ++ ++ .has_uart0 = 1, ++ .has_pci = 1, ++ ++ .has_caldata = 1, ++ .caldata = { ++ { ++ .caldata_offset = 0x7d1000, ++ .slot = 0, ++ }, ++ }, ++ ++ .has_enetsw = 1, ++ ++ .enetsw = { ++ .used_ports = { ++ [0] = { ++ .used = 1, ++ .phy_id = 1, ++ .name = "Port 4", ++ }, ++ [1] = { ++ .used = 1, ++ .phy_id = 2, ++ .name = "Port 3", ++ }, ++ [2] = { ++ .used = 1, ++ .phy_id = 3, ++ .name = "Port 2", ++ }, ++ [3] = { ++ .used = 1, ++ .phy_id = 4, ++ .name = "Port 1", ++ }, ++ }, ++ }, ++ ++ .leds = { ++ { ++ .name = "dsl-274xb:red:internet", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "dsl-274xb:green:dsl", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { ++ .name = "dsl-274xb:green:power", ++ .gpio = 4, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "dsl-274xb:red:power", ++ .gpio = 8, ++ .active_low = 1, ++ }, ++ { ++ .name = "dsl-274xb:blue:wps", ++ .gpio = 9, ++ .active_low = 1, ++ }, ++ { ++ .name = "dsl-274xb:green:internet", ++ .gpio = 11, ++ .active_low = 1, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "wifi", ++ .gpio = 10, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = BTN_0, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "reset", ++ .gpio = 23, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 24, ++ .active_low = 1, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; + #endif + + /* +@@ -2393,6 +2496,7 @@ static const struct board_info __initdat + #ifdef CONFIG_BCM63XX_CPU_6328 + &board_96328avng, + &board_963281TAN, ++ &board_dsl_274xb_f1, + #endif + #ifdef CONFIG_BCM63XX_CPU_6338 + &board_96338gw, diff --git a/target/linux/brcm63xx/patches-3.3/525-board_96348w3.patch b/target/linux/brcm63xx/patches-3.3/525-board_96348w3.patch new file mode 100644 index 000000000..76425cd27 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/525-board_96348w3.patch @@ -0,0 +1,68 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -1334,6 +1334,57 @@ static struct board_info __initdata boar + }, + }; + ++/* NetGear DG834G v4 */ ++static struct board_info __initdata board_96348W3 = { ++ .name = "96348W3", ++ .expected_cpu_id = 0x6348, ++ ++ .has_uart0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .has_ohci0 = 1, ++ ++ .leds = { ++ { ++ .name = "96348W3:green:power", ++ .gpio = 0, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "96348W3:red:power", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++ { ++ .name = "96348W3::adsl", ++ .gpio = 2, ++ .active_low = 1, ++ }, ++ { ++ .name = "96348W3::internet", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ }, ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 6, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; ++ + #endif + + /* +@@ -2526,6 +2577,7 @@ static const struct board_info __initdat + &board_ct536_ct5621, + &board_96348A_122, + &board_CPVA502plus, ++ &board_96348W3, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6358 diff --git a/target/linux/brcm63xx/patches-3.3/526-board_CT6373-1.patch b/target/linux/brcm63xx/patches-3.3/526-board_CT6373-1.patch new file mode 100644 index 000000000..58b209ed3 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/526-board_CT6373-1.patch @@ -0,0 +1,136 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -51,6 +51,13 @@ + #define NB4_SPI_GPIO_CLK 6 + #define NB4_74HC64_GPIO(X) (NB4_74X164_GPIO_BASE + (X)) + ++#define CT6373_PID_OFFSET 0xff80 ++#define CT6373_74X164_GPIO_BASE 64 ++#define CT6373_SPI_GPIO_MOSI 7 ++#define CT6373_SPI_GPIO_CLK 6 ++#define CT6373_74HC64_GPIO(X) (CT6373_74X164_GPIO_BASE + (X)) ++ ++ + static struct board_info board; + + /* +@@ -2261,6 +2268,111 @@ static struct board_info __initdata boar + .num_spis = ARRAY_SIZE(nb4_spi_devices), + }; + ++ ++struct spi_gpio_platform_data ct6373_spi_gpio_data = { ++ .sck = CT6373_SPI_GPIO_CLK, ++ .mosi = CT6373_SPI_GPIO_MOSI, ++ .miso = SPI_GPIO_NO_MISO, ++ .num_chipselect = 1, ++}; ++ ++static struct platform_device ct6373_spi_gpio = { ++ .name = "spi_gpio", ++ .id = 1, ++ .dev = { ++ .platform_data = &ct6373_spi_gpio_data, ++ }, ++}; ++ ++static struct platform_device * __initdata ct6373_devices[] = { ++ &ct6373_spi_gpio, ++}; ++ ++const struct gen_74x164_chip_platform_data ct6373_74x164_platform_data = { ++ .base = CT6373_74X164_GPIO_BASE ++}; ++ ++static struct spi_board_info ct6373_spi_devices[] = { ++ { ++ .modalias = "74x164", ++ .max_speed_hz = 781000, ++ .bus_num = 1, ++ .controller_data = (void *) SPI_GPIO_NO_CHIPSELECT, ++ .mode = SPI_MODE_0, ++ .platform_data = &ct6373_74x164_platform_data ++ } ++}; ++ ++static struct board_info __initdata board_ct6373_1 = { ++ .name = "CT6373-1", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_pci = 1, ++ .has_ohci0 = 1, ++ .has_ehci0 = 1, ++ ++ .has_enet1 = 1, ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .leds = { ++ { ++ .name = "CT6373-1:green:power", ++ .gpio = 0, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "CT6373-1:green:usb", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { ++ .name = "CT6373-1:green:wlan", ++ .gpio = 9, ++ .active_low = 1, ++ }, ++ { ++ .name = "CT6373-1:green:adsl", ++ .gpio = CT6373_74HC64_GPIO(0), ++ .active_low = 1, ++ }, ++ { ++ .name = "CT6373-1:green:line", ++ .gpio = CT6373_74HC64_GPIO(1), ++ .active_low = 1, ++ }, ++ { ++ .name = "CT6373-1:green:fxs1", ++ .gpio = CT6373_74HC64_GPIO(2), ++ .active_low = 1, ++ }, ++ { ++ .name = "CT6373-1:green:fxs2", ++ .gpio = CT6373_74HC64_GPIO(3), ++ .active_low = 1, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 35, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++ ++ .devs = ct6373_devices, ++ .num_devs = ARRAY_SIZE(ct6373_devices), ++ .spis = ct6373_spi_devices, ++ .num_spis = ARRAY_SIZE(ct6373_spi_devices), ++}; ++ + static struct board_info __initdata board_HW553 = { + .name = "HW553", + .expected_cpu_id = 0x6358, +@@ -2592,6 +2704,7 @@ static const struct board_info __initdat + &board_nb4_ser_r2, + &board_nb4_fxc_r1, + &board_nb4_fxc_r2, ++ &board_ct6373_1, + &board_HW553, + &board_spw303v, + #endif diff --git a/target/linux/brcm63xx/patches-3.3/527-board_dva-g3810bn-tl-1.patch b/target/linux/brcm63xx/patches-3.3/527-board_dva-g3810bn-tl-1.patch new file mode 100644 index 000000000..fe47dc633 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/527-board_dva-g3810bn-tl-1.patch @@ -0,0 +1,82 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -2512,6 +2512,71 @@ static struct board_info __initdata boar + }, + } + }; ++ ++/* D-Link DVA-G3810BN/TL */ ++static struct board_info __initdata board_DVAG3810BN = { ++ .name = "DVAG3810BN", ++ .expected_cpu_id = 0x6358, ++ ++ .has_uart0 = 1, ++ .has_enet0 = 1, ++ .has_enet1 = 1, ++ .has_pci = 1, ++ ++ .enet0 = { ++ .has_phy = 0, ++ .use_internal_phy = 1, ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ .enet1 = { ++ .force_speed_100 = 1, ++ .force_duplex_full = 1, ++ }, ++ ++ ++ .has_ohci0 = 1, ++ .has_pccard = 1, ++ .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "DVAG3810BN::voip", ++ .gpio = 1, ++ }, ++ { ++ .name = "DVAG3810BN::dsl", ++ .gpio = 22, ++ .active_low = 1, ++ }, ++ { ++ .name = "DVAG3810BN::internet", ++ .gpio = 23, ++ .active_low = 1, ++ }, ++ { ++ .name = "DVAG3810BN::power", ++ .gpio = 4, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "DVAG3810BN::stop", ++ .gpio = 5, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 34, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, ++}; + #endif + + /* +@@ -2707,6 +2772,7 @@ static const struct board_info __initdat + &board_ct6373_1, + &board_HW553, + &board_spw303v, ++ &board_DVAG3810BN, + #endif + + #ifdef CONFIG_BCM63XX_CPU_6368 diff --git a/target/linux/brcm63xx/patches-3.3/528-board_nb6.patch b/target/linux/brcm63xx/patches-3.3/528-board_nb6.patch new file mode 100644 index 000000000..e3f9382c0 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/528-board_nb6.patch @@ -0,0 +1,146 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -17,6 +17,7 @@ + #include <linux/spi/spi.h> + #include <linux/spi/spi_gpio.h> + #include <linux/spi/74x164.h> ++#include <linux/rtl8367.h> + #include <asm/addrspace.h> + #include <bcm63xx_board.h> + #include <bcm63xx_cpu.h> +@@ -50,6 +51,8 @@ + #define NB4_SPI_GPIO_MOSI 7 + #define NB4_SPI_GPIO_CLK 6 + #define NB4_74HC64_GPIO(X) (NB4_74X164_GPIO_BASE + (X)) ++#define NB6_GPIO_RTL8367_SDA 18 ++#define NB6_GPIO_RTL8367_SCK 20 + + #define CT6373_PID_OFFSET 0xff80 + #define CT6373_74X164_GPIO_BASE 64 +@@ -2579,6 +2582,103 @@ static struct board_info __initdata boar + }; + #endif + ++#ifdef CONFIG_BCM63XX_CPU_6362 ++static struct rtl8367_extif_config nb6_rtl8367_extif0_cfg = { ++ .mode = RTL8367_EXTIF_MODE_RGMII, ++ .txdelay = 1, ++ .rxdelay = 5, ++ .ability = { ++ .force_mode = 1, ++ .txpause = 1, ++ .rxpause = 1, ++ .link = 1, ++ .duplex = 1, ++ .speed = RTL8367_PORT_SPEED_1000, ++ }, ++}; ++ ++static struct rtl8367_platform_data nb6_rtl8367_data = { ++ .gpio_sda = NB6_GPIO_RTL8367_SDA, ++ .gpio_sck = NB6_GPIO_RTL8367_SCK, ++ .extif0_cfg = &nb6_rtl8367_extif0_cfg, ++}; ++ ++static struct platform_device nb6_rtl8367_device = { ++ .name = RTL8367_DRIVER_NAME, ++ .id = -1, ++ .dev = { ++ .platform_data = &nb6_rtl8367_data, ++ } ++}; ++ ++static struct platform_device * __initdata nb6_devices[] = { ++ &nb6_rtl8367_device, ++}; ++ ++static struct board_info __initdata board_nb6 = { ++ .name = "NB6", ++ .expected_cpu_id = 0x6362, ++ ++ .has_uart0 = 1, ++ ++ .has_ohci0 = 1, ++ .has_ehci0 = 1, ++ ++ .has_enetsw = 1, ++ ++ .enetsw = { ++ .used_ports = { ++ [4] = { ++ .used = 1, ++ .phy_id = 0xff, ++ .bypass_link = 1, ++ .force_speed = 1000, ++ .force_duplex_full = 1, ++ .name = "RGMII", ++ }, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 24, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ .active_low = 1, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 25, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ .active_low = 1, ++ }, ++ { ++ .desc = "wlan", ++ .gpio = 12, ++ .type = EV_KEY, ++ .code = KEY_WLAN, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ .active_low = 1, ++ }, ++ { ++ .desc = "service", ++ .gpio = 10, ++ .type = EV_KEY, ++ .code = BTN_0, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ .active_low = 1, ++ }, ++ }, ++ ++ .devs = nb6_devices, ++ .num_devs = ARRAY_SIZE(nb6_devices), ++}; ++#endif ++ + /* + * known 6368 boards + */ +@@ -2775,6 +2875,10 @@ static const struct board_info __initdat + &board_DVAG3810BN, + #endif + ++#ifdef CONFIG_BCM63XX_CPU_6362 ++ &board_nb6, ++#endif ++ + #ifdef CONFIG_BCM63XX_CPU_6368 + &board_96368mvwg, + &board_96368mvngr, +@@ -2842,6 +2946,11 @@ static void __init boardid_fixup(u8 *boo + } + } + ++ if (BCMCPU_IS_6362() && (!strncmp(board_name, "NB6-", sizeof("NB6-") - 1))) { ++ board_name[sizeof("NB6") - 1] = '\0'; ++ return ; ++ } ++ + /* check if bcm_tag is at 64k offset */ + if (strncmp(board_name, tag->boardid, BOARDID_LEN) != 0) { + /* else try 128k */ diff --git a/target/linux/brcm63xx/patches-3.3/550-alice_gate2_leds.patch b/target/linux/brcm63xx/patches-3.3/550-alice_gate2_leds.patch new file mode 100644 index 000000000..98b988df1 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/550-alice_gate2_leds.patch @@ -0,0 +1,102 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -1612,6 +1612,99 @@ static struct board_info __initdata boar + + .has_ohci0 = 1, + .has_ehci0 = 1, ++ ++ .leds = { ++ { ++ .name = "AGPF-S0:red:power", ++ .gpio = 5, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:green:power", ++ .gpio = 4, ++ .active_low = 1, ++ .default_trigger = "default-on", ++ }, ++ { ++ .name = "AGPF-S0:red:service", ++ .gpio = 7, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:green:service", ++ .gpio = 6, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:green:adsl", ++ .gpio = 9, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:red:adsl", ++ .gpio = 10, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:red:wifi", ++ .gpio = 23, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:green:wifi", ++ .gpio = 22, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:green:internet", ++ .gpio = 25, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:red:internet", ++ .gpio = 24, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:red:usr1", ++ .gpio = 27, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:green:usr1", ++ .gpio = 26, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:red:usr2", ++ .gpio = 30, ++ .active_low = 1, ++ }, ++ { ++ .name = "AGPF-S0:green:usr2", ++ .gpio = 29, ++ .active_low = 1, ++ }, ++ }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 37, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ { ++ .desc = "wps", ++ .gpio = 34, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, + }; + + static struct board_info __initdata board_DWVS0 = { diff --git a/target/linux/brcm63xx/patches-3.3/551-96348gw_a_leds.patch b/target/linux/brcm63xx/patches-3.3/551-96348gw_a_leds.patch new file mode 100644 index 000000000..816e8164c --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/551-96348gw_a_leds.patch @@ -0,0 +1,22 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -1069,6 +1069,19 @@ static struct board_info __initdata boar + }, + + .has_ohci0 = 1, ++ ++ .leds = { ++ { ++ .name = "96348GW-A::adsl", ++ .gpio = 3, ++ .active_low = 1, ++ }, ++ { ++ .name = "96348GW-A::usb", ++ .gpio = 0, ++ .active_low = 1, ++ } ++ }, + }; + + static struct board_info __initdata board_96348_D4PW = { diff --git a/target/linux/brcm63xx/patches-3.3/552-board_96348gw-10_reset_button.patch b/target/linux/brcm63xx/patches-3.3/552-board_96348gw-10_reset_button.patch new file mode 100644 index 000000000..3c0fe8b9d --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/552-board_96348gw-10_reset_button.patch @@ -0,0 +1,20 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -586,6 +586,17 @@ static struct board_info __initdata boar + .active_low = 1, + }, + }, ++ ++ .buttons = { ++ { ++ .desc = "reset", ++ .gpio = 6, ++ .active_low = 1, ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = BCM963XX_KEYS_DEBOUNCE_INTERVAL, ++ }, ++ }, + }; + + static struct board_info __initdata board_96348gw_11 = { diff --git a/target/linux/brcm63xx/patches-3.3/800-wl_exports.patch b/target/linux/brcm63xx/patches-3.3/800-wl_exports.patch new file mode 100644 index 000000000..0fff4d0b1 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/800-wl_exports.patch @@ -0,0 +1,34 @@ +--- a/arch/mips/bcm63xx/nvram.c ++++ b/arch/mips/bcm63xx/nvram.c +@@ -19,6 +19,13 @@ + static struct bcm963xx_nvram nvram; + static int mac_addr_used; + ++/* ++ * Required export for WL ++ */ ++#define NVRAM_SPACE 0x8000 ++char nvram_buf[NVRAM_SPACE]; ++EXPORT_SYMBOL(nvram_buf); ++ + int __init bcm63xx_nvram_init(void *addr) + { + unsigned int check_len; +@@ -27,6 +34,7 @@ int __init bcm63xx_nvram_init(void *addr + + /* extract nvram data */ + memcpy(&nvram, addr, sizeof(nvram)); ++ memcpy(&nvram_buf, addr, NVRAM_SPACE); + + /* check checksum before using data */ + if (nvram.version <= 4) +--- a/arch/mips/mm/cache.c ++++ b/arch/mips/mm/cache.c +@@ -58,6 +58,7 @@ void (*_dma_cache_wback)(unsigned long s + void (*_dma_cache_inv)(unsigned long start, unsigned long size); + + EXPORT_SYMBOL(_dma_cache_wback_inv); ++EXPORT_SYMBOL(_dma_cache_inv); + + #endif /* CONFIG_DMA_NONCOHERENT */ + diff --git a/target/linux/brcm63xx/patches-3.3/801-ssb_export_fallback_sprom.patch b/target/linux/brcm63xx/patches-3.3/801-ssb_export_fallback_sprom.patch new file mode 100644 index 000000000..724c849b4 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/801-ssb_export_fallback_sprom.patch @@ -0,0 +1,27 @@ +--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c ++++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c +@@ -14,6 +14,7 @@ + #include <linux/ssb/ssb.h> + #include <linux/gpio_keys.h> + #include <linux/input.h> ++#include <linux/export.h> + #include <linux/spi/spi.h> + #include <linux/spi/spi_gpio.h> + #include <linux/spi/74x164.h> +@@ -3007,7 +3008,7 @@ static const struct board_info __initdat + * bcm4318 WLAN work + */ + #ifdef CONFIG_SSB_PCIHOST +-static struct ssb_sprom bcm63xx_sprom = { ++struct ssb_sprom bcm63xx_sprom = { + .revision = 0x02, + .board_rev = 0x17, + .country_code = 0x0, +@@ -3027,6 +3028,7 @@ static struct ssb_sprom bcm63xx_sprom = + .boardflags_lo = 0x2848, + .boardflags_hi = 0x0000, + }; ++EXPORT_SYMBOL(bcm63xx_sprom); + + int bcm63xx_get_fallback_sprom(struct ssb_bus *bus, struct ssb_sprom *out) + { diff --git a/target/linux/brcm63xx/patches-3.3/802-rtl8367r_fix_RGMII_support.patch b/target/linux/brcm63xx/patches-3.3/802-rtl8367r_fix_RGMII_support.patch new file mode 100644 index 000000000..285f3f744 --- /dev/null +++ b/target/linux/brcm63xx/patches-3.3/802-rtl8367r_fix_RGMII_support.patch @@ -0,0 +1,30 @@ +From e3208e6087642b95a5bab3101fc9c6e34892c861 Mon Sep 17 00:00:00 2001 +From: Miguel GAIO <miguel.gaio@efixo.com> +Date: Fri, 6 Jul 2012 14:12:33 +0200 +Subject: [PATCH 6/8] * [rtl8367r] Fix RGMII support + +--- + drivers/net/phy/rtl8367.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +--- a/drivers/net/phy/rtl8367.c ++++ b/drivers/net/phy/rtl8367.c +@@ -144,6 +144,10 @@ + #define RTL8367_EXT_RGMXF_TXDELAY_MASK 1 + #define RTL8367_EXT_RGMXF_RXDELAY_MASK 0x7 + ++#define RTL8367_PHY_AD_REG 0x130f ++#define RTL8370_PHY_AD_DUMMY_1_OFFSET 5 ++#define RTL8370_PHY_AD_DUMMY_1_MASK 0xe0 ++ + #define RTL8367_DI_FORCE_REG(_x) (0x1310 + (_x)) + #define RTL8367_DI_FORCE_MODE BIT(12) + #define RTL8367_DI_FORCE_NWAY BIT(7) +@@ -892,6 +896,7 @@ static int rtl8367_extif_set_mode(struct + case RTL8367_EXTIF_MODE_RGMII_33V: + REG_WR(smi, RTL8367_CHIP_DEBUG0_REG, 0x0367); + REG_WR(smi, RTL8367_CHIP_DEBUG1_REG, 0x7777); ++ REG_RMW(smi, RTL8367_PHY_AD_REG, BIT(5), 0); + break; + + case RTL8367_EXTIF_MODE_TMII_MAC: diff --git a/target/linux/brcm63xx/profiles/100-Broadcom.mk b/target/linux/brcm63xx/profiles/100-Broadcom.mk new file mode 100644 index 000000000..bc68f1493 --- /dev/null +++ b/target/linux/brcm63xx/profiles/100-Broadcom.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Broadcom + NAME:=Broadcom WiFi (default) + PACKAGES:=kmod-b43 wpad-mini +endef + +define Profile/Broadcom/Description + Package set compatible with hardware using Broadcom WiFi cards +endef +$(eval $(call Profile,Broadcom)) + diff --git a/target/linux/brcm63xx/profiles/101-Broadcom-wl.mk b/target/linux/brcm63xx/profiles/101-Broadcom-wl.mk new file mode 100644 index 000000000..4f2d605eb --- /dev/null +++ b/target/linux/brcm63xx/profiles/101-Broadcom-wl.mk @@ -0,0 +1,19 @@ +# +# Copyright (C) 2010 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Broadcom-wl + NAME:=Broadcom BCM43xx WiFi (wl, proprietary) + PACKAGES:= kmod-brcm-wl wlc nas +endef + +define Profile/Broadcom-wl/Description + Package set compatible with hardware using Broadcom BCM43xx cards + using the proprietary broadcom wireless "wl" driver. +endef + +$(eval $(call Profile,Broadcom-wl)) + diff --git a/target/linux/brcm63xx/profiles/102-Atheros.mk b/target/linux/brcm63xx/profiles/102-Atheros.mk new file mode 100644 index 000000000..b214185c5 --- /dev/null +++ b/target/linux/brcm63xx/profiles/102-Atheros.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Atheros + NAME:=Atheros WiFi (default) + PACKAGES:=kmod-ath5k kmod-ath9k wpad-mini +endef + +define Profile/Atheros/Description + Package set compatible with hardware using Atheros WiFi cards +endef +$(eval $(call Profile,Atheros)) + diff --git a/target/linux/brcm63xx/profiles/103-Ralink.mk b/target/linux/brcm63xx/profiles/103-Ralink.mk new file mode 100644 index 000000000..412c5a45a --- /dev/null +++ b/target/linux/brcm63xx/profiles/103-Ralink.mk @@ -0,0 +1,13 @@ +# +# Copyright (C) 2006 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Ralink + NAME:=Ralink WiFi + PACKAGES:=kmod-rt61-pci wpad-mini +endef +$(eval $(call Profile,Ralink)) + diff --git a/target/linux/brcm63xx/profiles/104-No-WiFi.mk b/target/linux/brcm63xx/profiles/104-No-WiFi.mk new file mode 100644 index 000000000..9d32da60b --- /dev/null +++ b/target/linux/brcm63xx/profiles/104-No-WiFi.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/NoWiFi + NAME:=No WiFi (BCM6338) + PACKAGES:=kmod-bcm63xx-spi +endef + +define Profile/NoWiFi/description + Package set compatible with BCM63xx routers without Wi-Fi (e.g: BCM6338-based). +endef + +$(eval $(call Profile,NoWiFi)) diff --git a/target/linux/brcm63xx/profiles/105-Broadcom-brcmsmac.mk b/target/linux/brcm63xx/profiles/105-Broadcom-brcmsmac.mk new file mode 100644 index 000000000..bb558d139 --- /dev/null +++ b/target/linux/brcm63xx/profiles/105-Broadcom-brcmsmac.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2012 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/Broadcom-brcmsmac + NAME:=Broadcom WiFi (brcmsmac) + PACKAGES:=kmod-brcmsmac wpad-mini +endef + +define Profile/Broadcom-brcmsmac/Description + Package set compatible with hardware using Broadcom WiFi cards +endef +$(eval $(call Profile,Broadcom-brcmsmac)) + diff --git a/target/linux/brcm63xx/profiles/200-GW6X00.mk b/target/linux/brcm63xx/profiles/200-GW6X00.mk new file mode 100644 index 000000000..b1c516a8b --- /dev/null +++ b/target/linux/brcm63xx/profiles/200-GW6X00.mk @@ -0,0 +1,21 @@ +# +# Copyright (C) 2009 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +define Profile/GW6X00 + NAME:=Tecom GW6X00 + PACKAGES:=kmod-brcm-wl kmod-usb-core kmod-usb-ohci kmod-usb-storage \ + kmod-fs-ext4 kmod-nls-cp437 kmod-nls-iso8859-1 e2fsprogs \ + kmod-bcm63xx-spi \ + kmod-ipt-nathelper-extra wlc +endef + +define Profile/GW6X00/Description + Package set compatible with the Tecom GW6000 and GW6200 based + on the BCM96348GW reference design. +endef +$(eval $(call Profile,GW6X00)) + |