bcm63xx: add support for linux 3.8

Based on 3.8-rc6

Signed-off-by: Jonas Gorski <jogo@openwrt.org>

SVN-Revision: 35482
This commit is contained in:
Jonas Gorski 2013-02-04 10:19:55 +00:00
parent 3b4fced67d
commit 8506964e6d
112 changed files with 13610 additions and 0 deletions

View file

@ -0,0 +1,182 @@
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_ARCH_DISCARD_MEMBLOCK=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_AUDIT=y
CONFIG_AUDIT_GENERIC=y
CONFIG_B53=y
CONFIG_B53_MMAP_DRIVER=y
CONFIG_B53_PHY_DRIVER=y
CONFIG_B53_PHY_FIXUP=y
CONFIG_B53_SPI_DRIVER=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_EHCI=y
CONFIG_BCM63XX_ENET=y
CONFIG_BCM63XX_OHCI=y
CONFIG_BCM63XX_PHY=y
CONFIG_BCM63XX_WDT=y
CONFIG_BOARD_BCM963XX=y
# CONFIG_BOARD_LIVEBOX is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_CEVT_R4K=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_GENERIC_DUMP_TLB=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_R4K_CACHE_TLB=y
CONFIG_CPU_R4K_FPU=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CRAMFS=y
CONFIG_CSRC_R4K=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_EARLY_PRINTK=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_IO=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_74X164=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_ARCH_TRANSPARENT_HUGEPAGE=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=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_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=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_HUGE_TLB_SUPPORT is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_MIPS_MACHINE is not set
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_SEAD3 is not set
CONFIG_MODULES_USE_ELF_REL=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_PERCPU_RWSEM=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_RELAY=y
CONFIG_RTL8366_SMI=y
CONFIG_RTL8367_PHY=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=y
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_TICK_CPU_ACCOUNTING=y
CONFIG_UIDGID_CONVERTED=y
CONFIG_USB_ARCH_HAS_XHCI=y
# CONFIG_USB_HCD_SSB is not set
CONFIG_USB_SUPPORT=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_ZONE_DMA_FLAG=0

View file

@ -0,0 +1,162 @@
From 243970ea035623f70431a80ece802f572cd446be Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 9 Dec 2012 00:10:00 +0100
Subject: [PATCH V2 1/2] spi/bcm63xx: reject transfers unable to transfer
The hardware does not support keeping CS asserted after sending one
FIFO buffer worth of data, so reject transfers requiring CS being kept
asserted, either between transers or for a certain time after it,
or exceeding the FIFO size.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
drivers/spi/spi-bcm63xx.c | 91 +++++++++++++++++++++------------------------
1 file changed, 42 insertions(+), 49 deletions(-)
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -49,16 +49,10 @@ struct bcm63xx_spi {
unsigned int msg_type_shift;
unsigned int msg_ctl_width;
- /* 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;
};
@@ -175,24 +169,13 @@ static int bcm63xx_spi_setup(struct spi_
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 unsigned int bcm63xx_txrx_bufs(struct spi_device *spi,
- struct spi_transfer *t)
+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;
+ u8 rx_tail;
+ unsigned int timeout = 0;
/* Disable the CMD_DONE interrupt */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
@@ -200,14 +183,8 @@ static unsigned int bcm63xx_txrx_bufs(st
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;
-
- if (t->tx_buf) {
- bs->remaining_bytes = t->len;
- bcm63xx_spi_fill_tx_fifo(bs);
- }
+ if (t->tx_buf)
+ memcpy_toio(bs->tx_io, t->tx_buf, t->len);
init_completion(&bs->done);
@@ -239,7 +216,18 @@ static unsigned int bcm63xx_txrx_bufs(st
/* Enable the CMD_DONE interrupt */
bcm_spi_writeb(bs, SPI_INTR_CMD_DONE, SPI_INT_MASK);
- return t->len - bs->remaining_bytes;
+ timeout = wait_for_completion_timeout(&bs->done, HZ);
+ if (!timeout)
+ return -ETIMEDOUT;
+
+ /* read out all data */
+ rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
+
+ /* Read out all the data */
+ if (rx_tail)
+ memcpy_fromio(t->rx_ptr, bs->rx_io, rx_tail);
+
+ return 0;
}
static int bcm63xx_spi_prepare_transfer(struct spi_master *master)
@@ -267,36 +255,41 @@ static int bcm63xx_spi_transfer_one(stru
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) {
- unsigned int len = t->len;
- u8 rx_tail;
-
status = bcm63xx_spi_check_transfer(spi, t);
if (status < 0)
goto exit;
+ /* we can only transfer one fifo worth of data */
+ if (t->len > bs->fifo_size) {
+ dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
+ t->len, bs->fifo_size);
+ status = -EINVAL;
+ goto exit;
+ }
+
+ /* CS will be deasserted directly after transfer */
+ if (t->delay_usecs) {
+ dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
+ status = -EINVAL;
+ goto exit;
+ }
+
+ if (!t->cs_change &&
+ !list_is_last(&t->transfer_list, &m->transfers)) {
+ dev_err(&spi->dev, "unable to keep CS asserted between transfers\n");
+ status = -EINVAL;
+ 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);
- }
+ /* send the data */
+ status = bcm63xx_txrx_bufs(spi, t);
+ if (status)
+ goto exit;
m->actual_length += t->len;
}

View file

@ -0,0 +1,240 @@
From 725e81d507b1098cd275d4e3333c77c4b750fa79 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Sun, 9 Dec 2012 01:53:05 +0100
Subject: [PATCH V2 2/2] spi/bcm63xx: work around inability to keep CS up
This SPI controller does not support keeping CS asserted after sending
a transfer.
Since messages expected on this SPI controller are rather short, we can
work around it for normal use cases by sending all transfers at once in
a big full duplex stream.
This means that we cannot change the speed between transfers if they
require CS to be kept asserted, but these would have been rejected
before anyway because of the inability of keeping CS asserted.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
V1 -> V2:
* split out rejection logic into separate patch
* fixed return type of bcm63xx_txrx_bufs()
* slightly reworked bcm63xx_txrx_bufs, obsoleting one local variable
drivers/spi/spi-bcm63xx.c | 134 +++++++++++++++++++++++++++++++++++----------
1 file changed, 106 insertions(+), 28 deletions(-)
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -37,6 +37,8 @@
#define PFX KBUILD_MODNAME
+#define BCM63XX_SPI_MAX_PREPEND 15
+
struct bcm63xx_spi {
struct completion done;
@@ -169,13 +171,17 @@ static int bcm63xx_spi_setup(struct spi_
return 0;
}
-static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
+static int bcm63xx_txrx_bufs(struct spi_device *spi, struct spi_transfer *first,
+ unsigned int num_transfers)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(spi->master);
u16 msg_ctl;
u16 cmd;
u8 rx_tail;
- unsigned int timeout = 0;
+ unsigned int i, timeout = 0, prepend_len = 0, len = 0;
+ struct spi_transfer *t = first;
+ bool do_rx = false;
+ bool do_tx = false;
/* Disable the CMD_DONE interrupt */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
@@ -183,19 +189,45 @@ static int bcm63xx_txrx_bufs(struct spi_
dev_dbg(&spi->dev, "txrx: tx %p, rx %p, len %d\n",
t->tx_buf, t->rx_buf, t->len);
- if (t->tx_buf)
- memcpy_toio(bs->tx_io, t->tx_buf, t->len);
+ if (num_transfers > 1 && t->tx_buf && t->len <= BCM63XX_SPI_MAX_PREPEND)
+ prepend_len = t->len;
+
+ /* prepare the buffer */
+ for (i = 0; i < num_transfers; i++) {
+ if (t->tx_buf) {
+ do_tx = true;
+ memcpy_toio(bs->tx_io + len, t->tx_buf, t->len);
+
+ /* don't prepend more than one tx */
+ if (t != first)
+ prepend_len = 0;
+ }
+
+ if (t->rx_buf) {
+ do_rx = true;
+ /* prepend is half-duplex write only */
+ if (t == first)
+ prepend_len = 0;
+ }
+
+ len += t->len;
+
+ t = list_entry(t->transfer_list.next, struct spi_transfer,
+ transfer_list);
+ }
+
+ len -= prepend_len;
init_completion(&bs->done);
/* Fill in the Message control register */
- msg_ctl = (t->len << SPI_BYTE_CNT_SHIFT);
+ msg_ctl = (len << SPI_BYTE_CNT_SHIFT);
- if (t->rx_buf && t->tx_buf)
+ if (do_rx && do_tx && prepend_len == 0)
msg_ctl |= (SPI_FD_RW << bs->msg_type_shift);
- else if (t->rx_buf)
+ else if (do_rx)
msg_ctl |= (SPI_HD_R << bs->msg_type_shift);
- else if (t->tx_buf)
+ else if (do_tx)
msg_ctl |= (SPI_HD_W << bs->msg_type_shift);
switch (bs->msg_ctl_width) {
@@ -209,7 +241,7 @@ static int bcm63xx_txrx_bufs(struct spi_
/* Issue the transfer */
cmd = SPI_CMD_START_IMMEDIATE;
- cmd |= (0 << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
+ cmd |= (prepend_len << SPI_CMD_PREPEND_BYTE_CNT_SHIFT);
cmd |= (spi->chip_select << SPI_CMD_DEVICE_ID_SHIFT);
bcm_spi_writew(bs, cmd, SPI_CMD);
@@ -223,9 +255,25 @@ static int bcm63xx_txrx_bufs(struct spi_
/* read out all data */
rx_tail = bcm_spi_readb(bs, SPI_RX_TAIL);
+ if (do_rx && rx_tail != len)
+ return -EIO;
+
+ if (!rx_tail)
+ return 0;
+
+ len = 0;
+ t = first;
/* Read out all the data */
- if (rx_tail)
- memcpy_fromio(t->rx_ptr, bs->rx_io, rx_tail);
+ for (i = 0; i < num_transfers; i++) {
+ if (t->rx_buf)
+ memcpy_fromio(t->rx_buf, bs->rx_io + len, t->len);
+
+ if (t != first || prepend_len == 0)
+ len += t->len;
+
+ t = list_entry(t->transfer_list.next, struct spi_transfer,
+ transfer_list);
+ }
return 0;
}
@@ -252,46 +300,76 @@ static int bcm63xx_spi_transfer_one(stru
struct spi_message *m)
{
struct bcm63xx_spi *bs = spi_master_get_devdata(master);
- struct spi_transfer *t;
+ struct spi_transfer *t, *first = NULL;
struct spi_device *spi = m->spi;
int status = 0;
+ unsigned int n_transfers = 0, total_len = 0;
+ bool can_use_prepend = false;
+ /*
+ * This SPI controller does not support keeping CS active after a
+ * transfer.
+ * Work around this by merging as many transfers we can into one big
+ * full-duplex transfers.
+ */
list_for_each_entry(t, &m->transfers, transfer_list) {
status = bcm63xx_spi_check_transfer(spi, t);
if (status < 0)
goto exit;
+ if (!first)
+ first = t;
+
+ n_transfers++;
+ total_len += t->len;
+
+ if (n_transfers == 2 && !first->rx_buf && !t->tx_buf &&
+ first->len <= BCM63XX_SPI_MAX_PREPEND)
+ can_use_prepend = true;
+ else if (can_use_prepend && t->tx_buf)
+ can_use_prepend = false;
+
/* we can only transfer one fifo worth of data */
- if (t->len > bs->fifo_size) {
+ if ((can_use_prepend &&
+ total_len > (bs->fifo_size + BCM63XX_SPI_MAX_PREPEND)) ||
+ (!can_use_prepend && total_len > bs->fifo_size)) {
dev_err(&spi->dev, "unable to do transfers larger than FIFO size (%i > %i)\n",
- t->len, bs->fifo_size);
+ total_len, bs->fifo_size);
status = -EINVAL;
goto exit;
}
- /* CS will be deasserted directly after transfer */
- if (t->delay_usecs) {
- dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
+ /* all combined transfers have to have the same speed */
+ if (t->speed_hz != first->speed_hz) {
+ dev_err(&spi->dev, "unable to change speed between transfers\n");
status = -EINVAL;
goto exit;
}
- if (!t->cs_change &&
- !list_is_last(&t->transfer_list, &m->transfers)) {
- dev_err(&spi->dev, "unable to keep CS asserted between transfers\n");
+ /* CS will be deasserted directly after transfer */
+ if (t->delay_usecs) {
+ dev_err(&spi->dev, "unable to keep CS asserted after transfer\n");
status = -EINVAL;
goto exit;
}
- /* configure adapter for a new transfer */
- bcm63xx_spi_setup_transfer(spi, t);
-
- /* send the data */
- status = bcm63xx_txrx_bufs(spi, t);
- if (status)
- goto exit;
-
- m->actual_length += t->len;
+ if (t->cs_change ||
+ list_is_last(&t->transfer_list, &m->transfers)) {
+ /* configure adapter for a new transfer */
+ bcm63xx_spi_setup_transfer(spi, first);
+
+ /* send the data */
+ status = bcm63xx_txrx_bufs(spi, first, n_transfers);
+ if (status)
+ goto exit;
+
+ m->actual_length += total_len;
+
+ first = NULL;
+ n_transfers = 0;
+ total_len = 0;
+ can_use_prepend = false;
+ }
}
exit:
m->status = status;

View file

@ -0,0 +1,28 @@
From 80a2f983e9f44dbc3e01ae31c62d877846a7f791 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:19 +0100
Subject: [PATCH 01/11] MIPS: BCM63XX: add USB host clock enable delay
Knowledge of the clock setup delay should remain at the clock level (so
it can be clock specific and CPU specific). Add the 100 milliseconds
required clock delay for the USB host clock when it gets enabled.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/clk.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -162,6 +162,11 @@ static void usbh_set(struct clk *clk, in
bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
else if (BCMCPU_IS_6368())
bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
+ else
+ return;
+
+ if (enable)
+ msleep(100);
}
static struct clk clk_usbh = {

View file

@ -0,0 +1,41 @@
From 8e9bf528a122741f0171b89c297b63041116d704 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:20 +0100
Subject: [PATCH 02/11] MIPS: BCM63XX: add USB device clock enable delay to
clock code
This patch adds the required 10 micro seconds delay to the USB device
clock enable operation. Put this where the correct clock knowledege is,
which is in the clock code, and remove this delay from the bcm63xx_udc
gadget driver where it was before.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/clk.c | 5 +++++
drivers/usb/gadget/bcm63xx_udc.c | 1 -
2 files changed, 5 insertions(+), 1 deletion(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -182,6 +182,11 @@ static void usbd_set(struct clk *clk, in
bcm_hwclock_set(CKCTL_6328_USBD_EN, enable);
else if (BCMCPU_IS_6368())
bcm_hwclock_set(CKCTL_6368_USBD_EN, enable);
+ else
+ return;
+
+ if (enable)
+ udelay(10);
}
static struct clk clk_usbd = {
--- a/drivers/usb/gadget/bcm63xx_udc.c
+++ b/drivers/usb/gadget/bcm63xx_udc.c
@@ -386,7 +386,6 @@ static inline void set_clocks(struct bcm
if (is_enabled) {
clk_enable(udc->usbh_clk);
clk_enable(udc->usbd_clk);
- udelay(10);
} else {
clk_disable(udc->usbd_clk);
clk_disable(udc->usbh_clk);

View file

@ -0,0 +1,151 @@
From ac9b0b574d54be28b300bf99ffe092a2c589484f Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:21 +0100
Subject: [PATCH 03/11] MIPS: BCM63XX: move code touching the USB private
register
This patch moves the code touching the USB private register in the
bcm63xx USB gadget driver to arch/mips/bcm63xx/usb-common.c in
preparation for adding support for OHCI and EHCI host controllers which
will also touch the USB private register.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/Makefile | 2 +-
arch/mips/bcm63xx/usb-common.c | 53 ++++++++++++++++++++
.../include/asm/mach-bcm63xx/bcm63xx_usb_priv.h | 9 ++++
drivers/usb/gadget/bcm63xx_udc.c | 27 ++--------
4 files changed, 67 insertions(+), 24 deletions(-)
create mode 100644 arch/mips/bcm63xx/usb-common.c
create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_usb_priv.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 reset.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-usb-usbd.o
+ dev-usb-usbd.o usb-common.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
--- /dev/null
+++ b/arch/mips/bcm63xx/usb-common.c
@@ -0,0 +1,53 @@
+/*
+ * Broadcom BCM63xx common USB device configuration code
+ *
+ * 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 Kevin Cernekee <cernekee@gmail.com>
+ * Copyright (C) 2012 Broadcom Corporation
+ *
+ */
+#include <linux/export.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_usb_priv.h>
+
+void bcm63xx_usb_priv_select_phy_mode(u32 portmask, bool is_device)
+{
+ u32 val;
+
+ val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG);
+ if (is_device) {
+ val |= (portmask << USBH_PRIV_UTMI_CTL_HOSTB_SHIFT);
+ val |= (portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
+ } else {
+ val &= ~(portmask << USBH_PRIV_UTMI_CTL_HOSTB_SHIFT);
+ val &= ~(portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
+ }
+ bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_UTMI_CTL_6368_REG);
+
+ val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
+ if (is_device)
+ val |= USBH_PRIV_SWAP_USBD_MASK;
+ else
+ val &= ~USBH_PRIV_SWAP_USBD_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_SWAP_6368_REG);
+}
+EXPORT_SYMBOL(bcm63xx_usb_priv_select_phy_mode);
+
+void bcm63xx_usb_priv_select_pullup(u32 portmask, bool is_on)
+{
+ u32 val;
+
+ val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG);
+ if (is_on)
+ val &= ~(portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
+ else
+ val |= (portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
+ bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_UTMI_CTL_6368_REG);
+}
+EXPORT_SYMBOL(bcm63xx_usb_priv_select_pullup);
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_usb_priv.h
@@ -0,0 +1,9 @@
+#ifndef BCM63XX_USB_PRIV_H_
+#define BCM63XX_USB_PRIV_H_
+
+#include <linux/types.h>
+
+void bcm63xx_usb_priv_select_phy_mode(u32 portmask, bool is_device);
+void bcm63xx_usb_priv_select_pullup(u32 portmask, bool is_on);
+
+#endif /* BCM63XX_USB_PRIV_H_ */
--- a/drivers/usb/gadget/bcm63xx_udc.c
+++ b/drivers/usb/gadget/bcm63xx_udc.c
@@ -41,6 +41,7 @@
#include <bcm63xx_dev_usb_usbd.h>
#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>
+#include <bcm63xx_usb_priv.h>
#define DRV_MODULE_NAME "bcm63xx_udc"
@@ -863,22 +864,7 @@ static void bcm63xx_select_phy_mode(stru
bcm_gpio_writel(val, GPIO_PINMUX_OTHR_REG);
}
- val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG);
- if (is_device) {
- val |= (portmask << USBH_PRIV_UTMI_CTL_HOSTB_SHIFT);
- val |= (portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
- } else {
- val &= ~(portmask << USBH_PRIV_UTMI_CTL_HOSTB_SHIFT);
- val &= ~(portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
- }
- bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_UTMI_CTL_6368_REG);
-
- val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
- if (is_device)
- val |= USBH_PRIV_SWAP_USBD_MASK;
- else
- val &= ~USBH_PRIV_SWAP_USBD_MASK;
- bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_SWAP_6368_REG);
+ bcm63xx_usb_priv_select_phy_mode(portmask, is_device);
}
/**
@@ -892,14 +878,9 @@ static void bcm63xx_select_phy_mode(stru
*/
static void bcm63xx_select_pullup(struct bcm63xx_udc *udc, bool is_on)
{
- u32 val, portmask = BIT(udc->pd->port_no);
+ u32 portmask = BIT(udc->pd->port_no);
- val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG);
- if (is_on)
- val &= ~(portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
- else
- val |= (portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
- bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_UTMI_CTL_6368_REG);
+ bcm63xx_usb_priv_select_pullup(portmask, is_on);
}
/**

View file

@ -0,0 +1,169 @@
From 28758a9da77954ed323f86123ef448c6a563c037 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:22 +0100
Subject: [PATCH 04/11] MIPS: BCM63XX: add OHCI/EHCI configuration bits to
common USB code
This patch updates the common USB code touching the USB private
registers with the specific bits to properly enable OHCI and EHCI
controllers on BCM63xx SoCs. As a result we now need to protect access
to Read Modify Write sequences using a spinlock because we cannot
guarantee that any of the exposed helper will not be called
concurrently.
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/usb-common.c | 97 ++++++++++++++++++++
.../include/asm/mach-bcm63xx/bcm63xx_usb_priv.h | 2 +
2 files changed, 99 insertions(+)
--- a/arch/mips/bcm63xx/usb-common.c
+++ b/arch/mips/bcm63xx/usb-common.c
@@ -5,10 +5,12 @@
* 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) 2012 Kevin Cernekee <cernekee@gmail.com>
* Copyright (C) 2012 Broadcom Corporation
*
*/
+#include <linux/spinlock.h>
#include <linux/export.h>
#include <bcm63xx_cpu.h>
@@ -16,9 +18,14 @@
#include <bcm63xx_io.h>
#include <bcm63xx_usb_priv.h>
+static DEFINE_SPINLOCK(usb_priv_reg_lock);
+
void bcm63xx_usb_priv_select_phy_mode(u32 portmask, bool is_device)
{
u32 val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_priv_reg_lock, flags);
val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG);
if (is_device) {
@@ -36,12 +43,17 @@ void bcm63xx_usb_priv_select_phy_mode(u3
else
val &= ~USBH_PRIV_SWAP_USBD_MASK;
bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_SWAP_6368_REG);
+
+ spin_unlock_irqrestore(&usb_priv_reg_lock, flags);
}
EXPORT_SYMBOL(bcm63xx_usb_priv_select_phy_mode);
void bcm63xx_usb_priv_select_pullup(u32 portmask, bool is_on)
{
u32 val;
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_priv_reg_lock, flags);
val = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_UTMI_CTL_6368_REG);
if (is_on)
@@ -49,5 +61,90 @@ void bcm63xx_usb_priv_select_pullup(u32
else
val |= (portmask << USBH_PRIV_UTMI_CTL_NODRIV_SHIFT);
bcm_rset_writel(RSET_USBH_PRIV, val, USBH_PRIV_UTMI_CTL_6368_REG);
+
+ spin_unlock_irqrestore(&usb_priv_reg_lock, flags);
}
EXPORT_SYMBOL(bcm63xx_usb_priv_select_pullup);
+
+/* The following array represents the meaning of the DESC/DATA
+ * endian swapping with respect to the CPU configured endianness
+ *
+ * DATA ENDN mmio descriptor
+ * 0 0 BE invalid
+ * 0 1 BE LE
+ * 1 0 BE BE
+ * 1 1 BE invalid
+ *
+ * Since BCM63XX SoCs are configured to be in big-endian mode
+ * we want configuration at line 3.
+ */
+void bcm63xx_usb_priv_ohci_cfg_set(void)
+{
+ u32 reg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_priv_reg_lock, flags);
+
+ 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_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;
+ 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);
+ }
+
+ spin_unlock_irqrestore(&usb_priv_reg_lock, flags);
+}
+
+void bcm63xx_usb_priv_ehci_cfg_set(void)
+{
+ u32 reg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&usb_priv_reg_lock, flags);
+
+ if (BCMCPU_IS_6358()) {
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6358_REG);
+ reg &= ~USBH_PRIV_SWAP_EHCI_ENDN_MASK;
+ reg |= USBH_PRIV_SWAP_EHCI_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_6328() || BCMCPU_IS_6368()) {
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_6368_REG);
+ reg &= ~USBH_PRIV_SWAP_EHCI_ENDN_MASK;
+ reg |= USBH_PRIV_SWAP_EHCI_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);
+ }
+
+ spin_unlock_irqrestore(&usb_priv_reg_lock, flags);
+}
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_usb_priv.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_usb_priv.h
@@ -5,5 +5,7 @@
void bcm63xx_usb_priv_select_phy_mode(u32 portmask, bool is_device);
void bcm63xx_usb_priv_select_pullup(u32 portmask, bool is_on);
+void bcm63xx_usb_priv_ohci_cfg_set(void);
+void bcm63xx_usb_priv_ehci_cfg_set(void);
#endif /* BCM63XX_USB_PRIV_H_ */

View file

@ -0,0 +1,62 @@
From 94ec618bd1a6b07fafbbfc9bcc54e7f9360ff9a0 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:23 +0100
Subject: [PATCH 05/11] MIPS: BCM63XX: introduce BCM63XX_OHCI configuration
symbol
This configuration symbol can be used by CPUs supporting the on-chip
OHCI controller, and ensures that all relevant OHCI-related
configuration options are correctly selected. So far, OHCI support is
available for the 6328, 6348, 6358 and 6358 SoCs.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/Kconfig | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -1,33 +1,38 @@
menu "CPU support"
depends on BCM63XX
+config BCM63XX_OHCI
+ bool
+ select USB_ARCH_HAS_OHCI
+ select USB_OHCI_BIG_ENDIAN_DESC if USB_OHCI_HCD
+ select USB_OHCI_BIG_ENDIAN_MMIO if USB_OHCI_HCD
+
config BCM63XX_CPU_6328
bool "support 6328 CPU"
select HW_HAS_PCI
+ select BCM63XX_OHCI
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
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 BCM63XX_OHCI
config BCM63XX_CPU_6358
bool "support 6358 CPU"
select HW_HAS_PCI
+ select BCM63XX_OHCI
config BCM63XX_CPU_6368
bool "support 6368 CPU"
select HW_HAS_PCI
+ select BCM63XX_OHCI
endmenu
source "arch/mips/bcm63xx/boards/Kconfig"

View file

@ -0,0 +1,138 @@
From 30d22baef255c99a12c4858ce4ab0d45f0d8c9ae Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:24 +0100
Subject: [PATCH 06/11] MIPS: BCM63XX: add support for the on-chip OHCI
controller
Broadcom BCM63XX SoCs include an on-chip OHCI controller which can be
driven by the ohci-platform generic driver by using specific power
on/off/suspend callback to manage clocks and hardware specific
configuration.
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/Makefile | 2 +-
arch/mips/bcm63xx/dev-usb-ohci.c | 94 ++++++++++++++++++++
.../asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h | 6 ++
3 files changed, 101 insertions(+), 1 deletion(-)
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/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 reset.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-usb-usbd.o usb-common.o
+ dev-usb-ohci.o dev-usb-usbd.o usb-common.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-ohci.c
@@ -0,0 +1,94 @@
+/*
+ * 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) 2013 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/usb/ohci_pdriver.h>
+#include <linux/dma-mapping.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_usb_priv.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 = DMA_BIT_MASK(32);
+
+static struct clk *usb_host_clock;
+
+static int bcm63xx_ohci_power_on(struct platform_device *pdev)
+{
+ usb_host_clock = clk_get(&pdev->dev, "usbh");
+ if (IS_ERR_OR_NULL(usb_host_clock))
+ return -ENODEV;
+
+ clk_prepare_enable(usb_host_clock);
+
+ bcm63xx_usb_priv_ohci_cfg_set();
+
+ return 0;
+}
+
+static void bcm63xx_ohci_power_off(struct platform_device *pdev)
+{
+ if (!IS_ERR_OR_NULL(usb_host_clock)) {
+ clk_disable_unprepare(usb_host_clock);
+ clk_put(usb_host_clock);
+ }
+}
+
+static struct usb_ohci_pdata bcm63xx_ohci_pdata = {
+ .big_endian_desc = 1,
+ .big_endian_mmio = 1,
+ .no_big_frame_no = 1,
+ .num_ports = 1,
+ .power_on = bcm63xx_ohci_power_on,
+ .power_off = bcm63xx_ohci_power_off,
+ .power_suspend = bcm63xx_ohci_power_off,
+};
+
+static struct platform_device bcm63xx_ohci_device = {
+ .name = "ohci-platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+ .dev = {
+ .platform_data = &bcm63xx_ohci_pdata,
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+int __init bcm63xx_ohci_register(void)
+{
+ if (BCMCPU_IS_6345() || BCMCPU_IS_6338())
+ return -ENODEV;
+
+ 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_ */

View file

@ -0,0 +1,36 @@
From 33ef960aed15f9a98a2c51d8d794cd72418e0be4 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:25 +0100
Subject: [PATCH 07/11] MIPS: BCM63XX: register OHCI controller if board
enables it
BCM63XX-based boards can control the registration of the OHCI controller
by setting their has_ohci0 flag to 1. Handle this in the generic
code dealing with board registration and call the actual helper to
register the OHCI controller.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/boards/board_bcm963xx.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -25,6 +25,7 @@
#include <bcm63xx_dev_flash.h>
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
+#include <bcm63xx_dev_usb_ohci.h>
#include <bcm63xx_dev_usb_usbd.h>
#include <board_bcm963xx.h>
@@ -851,6 +852,9 @@ int __init board_register_devices(void)
if (board.has_usbd)
bcm63xx_usbd_register(&board.usbd);
+ if (board.has_ohci0)
+ bcm63xx_ohci_register();
+
if (board.has_dsp)
bcm63xx_dsp_register(&board.dsp);

View file

@ -0,0 +1,73 @@
From 00da1683364e58c6430a4577123d01037f8faddc Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:26 +0100
Subject: [PATCH 08/11] MIPS: BCM63XX: introduce BCM63XX_EHCI configuration
symbol
This configuration symbol can be used by CPUs supporting the on-chip
EHCI controller, and ensures that all relevant EHCI-related
configuration options are selected. So far BCM6328, BCM6358 and BCM6368
have an EHCI controller and do select this symbol. Update
drivers/usb/host/Kconfig with BCM63XX to update direct unmet
dependencies.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/Kconfig | 9 +++++++++
drivers/usb/host/Kconfig | 5 +++--
2 files changed, 12 insertions(+), 2 deletions(-)
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -7,10 +7,17 @@ config BCM63XX_OHCI
select USB_OHCI_BIG_ENDIAN_DESC if USB_OHCI_HCD
select USB_OHCI_BIG_ENDIAN_MMIO if USB_OHCI_HCD
+config BCM63XX_EHCI
+ bool
+ select USB_ARCH_HAS_EHCI
+ select USB_EHCI_BIG_ENDIAN_DESC if USB_EHCI_HCD
+ select USB_EHCI_BIG_ENDIAN_MMIO if USB_EHCI_HCD
+
config BCM63XX_CPU_6328
bool "support 6328 CPU"
select HW_HAS_PCI
select BCM63XX_OHCI
+ select BCM63XX_EHCI
config BCM63XX_CPU_6338
bool "support 6338 CPU"
@@ -28,11 +35,13 @@ config BCM63XX_CPU_6358
bool "support 6358 CPU"
select HW_HAS_PCI
select BCM63XX_OHCI
+ select BCM63XX_EHCI
config BCM63XX_CPU_6368
bool "support 6368 CPU"
select HW_HAS_PCI
select BCM63XX_OHCI
+ select BCM63XX_EHCI
endmenu
source "arch/mips/bcm63xx/boards/Kconfig"
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -115,14 +115,15 @@ 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 || MIPS_SEAD3)
+ PMC_MSP || SPARC_LEON || MIPS_SEAD3 || \
+ BCM63XX)
default y
config USB_EHCI_BIG_ENDIAN_DESC
bool
depends on USB_EHCI_HCD && (440EPX || ARCH_IXP4XX || XPS_USB_HCD_XILINX || \
PPC_MPC512x || PMC_MSP || SPARC_LEON || \
- MIPS_SEAD3)
+ MIPS_SEAD3 || BCM63XX)
default y
config XPS_USB_HCD_XILINX

View file

@ -0,0 +1,136 @@
From e38f13bd6408769c0b565bb1079024f496eee121 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:27 +0100
Subject: [PATCH 09/11] MIPS: BCM63XX: add support for the on-chip EHCI
controller
Broadcom BCM63XX SoCs include an on-chip EHCI controller which can be
driven by the generic ehci-platform driver by using specific power
on/off/suspend callbacks to manage clocks and hardware specific
configuration.
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/Makefile | 2 +-
arch/mips/bcm63xx/dev-usb-ehci.c | 92 ++++++++++++++++++++
.../asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h | 6 ++
3 files changed, 99 insertions(+), 1 deletion(-)
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/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 reset.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-usb-ohci.o dev-usb-usbd.o usb-common.o
+ dev-usb-ehci.o dev-usb-ohci.o dev-usb-usbd.o usb-common.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-ehci.c
@@ -0,0 +1,92 @@
+/*
+ * 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) 2013 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/usb/ehci_pdriver.h>
+#include <linux/dma-mapping.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_usb_priv.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 = DMA_BIT_MASK(32);
+
+static struct clk *usb_host_clock;
+
+static int bcm63xx_ehci_power_on(struct platform_device *pdev)
+{
+ usb_host_clock = clk_get(&pdev->dev, "usbh");
+ if (IS_ERR_OR_NULL(usb_host_clock))
+ return -ENODEV;
+
+ clk_prepare_enable(usb_host_clock);
+
+ bcm63xx_usb_priv_ehci_cfg_set();
+
+ return 0;
+}
+
+static void bcm63xx_ehci_power_off(struct platform_device *pdev)
+{
+ if (!IS_ERR_OR_NULL(usb_host_clock)) {
+ clk_disable_unprepare(usb_host_clock);
+ clk_put(usb_host_clock);
+ }
+}
+
+static struct usb_ehci_pdata bcm63xx_ehci_pdata = {
+ .big_endian_desc = 1,
+ .big_endian_mmio = 1,
+ .power_on = bcm63xx_ehci_power_on,
+ .power_off = bcm63xx_ehci_power_off,
+ .power_suspend = bcm63xx_ehci_power_off,
+};
+
+static struct platform_device bcm63xx_ehci_device = {
+ .name = "ehci-platform",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ehci_resources),
+ .resource = ehci_resources,
+ .dev = {
+ .platform_data = &bcm63xx_ehci_pdata,
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+int __init bcm63xx_ehci_register(void)
+{
+ if (!BCMCPU_IS_6328() && !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_ */

View file

@ -0,0 +1,36 @@
From 709ef2034f5ba06da35f89856ad7baf2b7a41287 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:28 +0100
Subject: [PATCH 10/11] MIPS: BCM63XX: register EHCI controller if board
enables it
BCM63XX-based board can control the registration of the EHCI controller
by setting their has_ehci0 flag to 1. Handle this in the generic
code dealing with board registration and call the actual helper to register
the EHCI controller.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/boards/board_bcm963xx.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -25,6 +25,7 @@
#include <bcm63xx_dev_flash.h>
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_spi.h>
+#include <bcm63xx_dev_usb_ehci.h>
#include <bcm63xx_dev_usb_ohci.h>
#include <bcm63xx_dev_usb_usbd.h>
#include <board_bcm963xx.h>
@@ -852,6 +853,9 @@ int __init board_register_devices(void)
if (board.has_usbd)
bcm63xx_usbd_register(&board.usbd);
+ if (board.has_ehci0)
+ bcm63xx_ehci_register();
+
if (board.has_ohci0)
bcm63xx_ohci_register();

View file

@ -0,0 +1,24 @@
From 111bbd770441ab34f9da5bb1d85767a9b75227b4 Mon Sep 17 00:00:00 2001
From: Florian Fainelli <florian@openwrt.org>
Date: Mon, 28 Jan 2013 20:06:30 +0100
Subject: [PATCH 12/12] MIPS: BCM63XX: EHCI controller does not support
overcurrent
This patch sets the ignore_oc flag for the BCM63XX EHCI controller as it
does not support proper overcurrent reporting.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
arch/mips/bcm63xx/dev-usb-ehci.c | 1 +
1 file changed, 1 insertion(+)
--- a/arch/mips/bcm63xx/dev-usb-ehci.c
+++ b/arch/mips/bcm63xx/dev-usb-ehci.c
@@ -61,6 +61,7 @@ static void bcm63xx_ehci_power_off(struc
static struct usb_ehci_pdata bcm63xx_ehci_pdata = {
.big_endian_desc = 1,
.big_endian_mmio = 1,
+ .ignore_oc = 1,
.power_on = bcm63xx_ehci_power_on,
.power_off = bcm63xx_ehci_power_off,
.power_suspend = bcm63xx_ehci_power_off,

View file

@ -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 */
};

View file

@ -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
@@ -987,7 +987,8 @@ static int m25p_probe(struct spi_device
/* 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);
}

View file

@ -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
@@ -93,6 +93,7 @@ struct m25p {
u8 erase_opcode;
u8 *command;
bool fast_read;
+ int max_transfer_len;
};
static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd)
@@ -337,10 +338,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;
uint8_t opcode;
@@ -392,6 +392,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
@@ -888,6 +910,9 @@ static int m25p_probe(struct spi_device
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 */
};

View file

@ -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>
@@ -32,6 +34,9 @@
#define PFX "board_bcm963xx: "
+#define BCM963XX_KEYS_POLL_INTERVAL 20
+#define BCM963XX_KEYS_DEBOUNCE_INTERVAL (BCM963XX_KEYS_POLL_INTERVAL * 3)
+
static struct board_info board;
/*
@@ -343,6 +348,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 = {
@@ -401,6 +416,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 = {
@@ -828,11 +853,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);
@@ -884,5 +921,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_usb_usbd.h>
@@ -45,6 +46,9 @@ struct board_info {
/* GPIO LEDs */
struct gpio_led leds[5];
+
+ /* Buttons */
+ struct gpio_keys_button buttons[4];
};
#endif /* ! BOARD_BCM963XX_H_ */

View file

@ -0,0 +1,41 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -869,6 +869,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);
@@ -916,10 +917,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
@@ -45,7 +45,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];

View file

@ -0,0 +1,25 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -915,6 +915,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
@@ -49,6 +49,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_ */

View file

@ -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>
@@ -918,6 +919,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
@@ -53,6 +53,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_ */

View file

@ -0,0 +1,62 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -33,11 +33,16 @@
#include <bcm63xx_dev_usb_usbd.h>
#include <board_bcm963xx.h>
+#include <uapi/linux/bcm963xx_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 board_info board;
/*
@@ -742,6 +747,30 @@ const char *board_get_name(void)
return board.name;
}
+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(board_name, tag->board_id, BOARDID_LEN) != 0) {
+ /* else try 128k */
+ tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_128K);
+ if (strncmp(board_name, tag->board_id, 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(board_name, &tag->information1[1], BOARDID_LEN);
+
+ printk(KERN_INFO "Overriding boardid with '%s'\n", board_name);
+}
+
/*
* early init callback, read nvram data from flash and checksum it
*/
@@ -778,6 +807,11 @@ void __init board_prom_init(void)
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++) {

View file

@ -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);

View file

@ -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) {

View file

@ -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
@@ -217,6 +217,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)
@@ -319,6 +339,8 @@ struct clk *clk_get(struct device *dev,
return &clk_usbd;
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"))

View file

@ -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,
@@ -161,6 +162,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
@@ -186,6 +188,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 (0xb000c000)
#define BCM_6328_OHCI0_BASE (0xb0002600)
@@ -232,6 +235,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)
@@ -279,6 +283,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)
@@ -325,6 +330,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_USBDMA_BASE (0xdeadbeef)
#define BCM_6348_OHCI0_BASE (0xfffe1b00)
@@ -370,6 +376,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_USBDMA_BASE (0xdeadbeef)
#define BCM_6358_OHCI0_BASE (0xfffe1400)
@@ -416,6 +423,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_USBDMA_BASE (0xb0004800)
#define BCM_6368_OHCI0_BASE (0xb0001600)
@@ -467,6 +475,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) \
@@ -510,6 +519,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, \
@@ -584,6 +594,7 @@ enum bcm63xx_irq {
IRQ_ENET0,
IRQ_ENET1,
IRQ_ENET_PHY,
+ IRQ_HSSPI,
IRQ_OHCI0,
IRQ_EHCI0,
IRQ_USBD,
@@ -626,6 +637,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_USBD_IRQ (IRQ_INTERNAL_BASE + 4)
@@ -671,6 +683,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_USBD_IRQ 0
@@ -709,6 +722,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_USBD_IRQ 0
@@ -747,6 +761,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_USBD_IRQ 0
@@ -785,6 +800,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_USBD_IRQ 0
@@ -832,6 +848,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_USBD_IRQ (IRQ_INTERNAL_BASE + 8)
@@ -879,6 +896,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_USBD] = BCM_## __cpu ##_USBD_IRQ, \
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -1409,4 +1409,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_ */

View file

@ -0,0 +1,267 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -112,28 +112,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,
}
@@ -153,28 +153,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,
},
@@ -213,29 +213,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,
},
@@ -274,28 +274,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,
},
@@ -328,28 +328,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,
},
@@ -396,28 +396,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,
},
@@ -549,27 +549,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,
},
},
@@ -601,22 +601,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,
},

View file

@ -0,0 +1,26 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -798,6 +798,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;

View file

@ -0,0 +1,556 @@
From 2665f554de21676a4cf609b1e1bb39d0597a1985 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 28/72] 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/reset.c | 28 +++++
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 +
11 files changed, 309 insertions(+), 2 deletions(-)
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -37,6 +37,10 @@ config BCM63XX_CPU_6358
select BCM63XX_OHCI
select BCM63XX_EHCI
+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
@@ -785,7 +785,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;
@@ -458,6 +476,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/reset.c
+++ b/arch/mips/bcm63xx/reset.c
@@ -85,6 +85,20 @@
#define BCM6358_RESET_PCIE 0
#define BCM6358_RESET_PCIE_EXT 0
+#define BCM6362_RESET_SPI SOFTRESET_6362_SPI_MASK
+#define BCM6362_RESET_ENET 0
+#define BCM6362_RESET_USBH SOFTRESET_6362_USBH_MASK
+#define BCM6362_RESET_USBD SOFTRESET_6362_USBS_MASK
+#define BCM6362_RESET_DSL 0
+#define BCM6362_RESET_SAR SOFTRESET_6362_SAR_MASK
+#define BCM6362_RESET_EPHY SOFTRESET_6362_EPHY_MASK
+#define BCM6362_RESET_ENETSW SOFTRESET_6362_ENETSW_MASK
+#define BCM6362_RESET_PCM SOFTRESET_6362_PCM_MASK
+#define BCM6362_RESET_MPI 0
+#define BCM6362_RESET_PCIE (SOFTRESET_6362_PCIE_MASK | \
+ SOFTRESET_6362_PCIE_CORE_MASK)
+#define BCM6362_RESET_PCIE_EXT SOFTRESET_6362_PCIE_EXT_MASK
+
#define BCM6368_RESET_SPI SOFTRESET_6368_SPI_MASK
#define BCM6368_RESET_ENET 0
#define BCM6368_RESET_USBH SOFTRESET_6368_USBH_MASK
@@ -119,6 +133,10 @@ static const u32 bcm6358_reset_bits[] =
__GEN_RESET_BITS_TABLE(6358)
};
+static const u32 bcm6362_reset_bits[] = {
+ __GEN_RESET_BITS_TABLE(6362)
+};
+
static const u32 bcm6368_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6368)
};
@@ -140,6 +158,9 @@ static int __init bcm63xx_reset_bits_ini
} else if (BCMCPU_IS_6358()) {
reset_reg = PERF_SOFTRESET_6358_REG;
bcm63xx_reset_bits = bcm6358_reset_bits;
+ } else if (BCMCPU_IS_6362()) {
+ reset_reg = PERF_SOFTRESET_6362_REG;
+ bcm63xx_reset_bits = bcm6362_reset_bits;
} else if (BCMCPU_IS_6368()) {
reset_reg = PERF_SOFTRESET_6368_REG;
bcm63xx_reset_bits = bcm6368_reset_bits;
@@ -182,6 +203,13 @@ static const u32 bcm63xx_reset_bits[] =
#define reset_reg PERF_SOFTRESET_6358_REG
#endif
+#ifdef CONFIG_BCM63XX_CPU_6362
+static const u32 bcm63xx_reset_bits[] = {
+ __GEN_RESET_BITS_TABLE(6362)
+};
+#define reset_reg PERF_SOFTRESET_6362_REG
+#endif
+
#ifdef CONFIG_BCM63XX_CPU_6368
static const u32 bcm63xx_reset_bits[] = {
__GEN_RESET_BITS_TABLE(6368)
--- 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
@@ -413,6 +428,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)
@@ -574,6 +645,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
@@ -836,6 +910,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
@@ -112,6 +112,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)
@@ -153,6 +186,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 */
@@ -161,6 +195,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 */
@@ -169,6 +204,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
@@ -197,6 +233,7 @@
#define PERF_SOFTRESET_REG 0x28
#define PERF_SOFTRESET_6328_REG 0x10
#define PERF_SOFTRESET_6358_REG 0x34
+#define PERF_SOFTRESET_6362_REG 0x10
#define PERF_SOFTRESET_6368_REG 0x10
#define SOFTRESET_6328_SPI_MASK (1 << 0)
@@ -259,6 +296,22 @@
#define SOFTRESET_6358_PCM_MASK (1 << 13)
#define SOFTRESET_6358_ADSL_MASK (1 << 14)
+#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)
@@ -1352,6 +1405,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;

View file

@ -0,0 +1,52 @@
From 2f94c414e554531e2a65a7c4a7fa2d1ba0380c0a 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 29/72] MIPS: BCM63XX: enable pcie for BCM6362
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/pci/pci-bcm63xx.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -1401,7 +1401,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
@@ -121,11 +121,17 @@ void __iomem *pci_iospace_start;
static void __init bcm63xx_reset_pcie(void)
{
u32 val;
+ u32 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 */
bcm63xx_core_set_reset(BCM63XX_RESET_PCIE, 1);
@@ -330,6 +336,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:

View file

@ -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
@@ -72,6 +72,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
@@ -176,6 +177,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;
@@ -196,10 +207,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_

View file

@ -0,0 +1,27 @@
--- a/include/uapi/linux/bcm963xx_tag.h
+++ b/include/uapi/linux/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",

View file

@ -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;

View file

@ -0,0 +1,22 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -862,6 +862,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
@@ -578,6 +578,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)

View file

@ -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 bcm_enet_probe(struct platfor
/* 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 bcm_enet_probe(struct platfor
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 bcm_enet_probe(struct platfor
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 bcm_enet_remove(struct platfo
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);

View file

@ -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,

View file

@ -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 bcm_enet_probe(struct platfor
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 bcm_enet_probe(struct platfor
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 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;

View file

@ -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 bcm_enet_remove(struct platfo
}
/* 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));

View file

@ -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
@@ -174,7 +174,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 bcm_enet_probe(struct platfor
/* 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 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 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;
}

View file

@ -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 */

View file

@ -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));

View file

@ -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 bcm_enetsw_probe(struct platf
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
@@ -326,6 +326,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];

View file

@ -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 bcm_enet_probe(struct platfor
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 bcm_enetsw_probe(struct platf
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
@@ -325,6 +325,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];
@@ -335,12 +337,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_ */

View file

@ -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 bcm_enetsw_probe(struct platf
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;

View file

@ -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
@@ -337,4 +337,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_ */

View file

@ -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
@@ -861,6 +861,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;

View file

@ -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 bcm_enet_probe(struct platfor
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 bcm_enetsw_probe(struct platf
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
@@ -18,6 +18,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
@@ -252,6 +253,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;

View file

@ -0,0 +1,79 @@
From a1bd0479a1ddac4f21afd4ebfe8f667b9fa5eff2 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 50/72] MIPS: BCM63XX: add support for BCM6328 in bcm_enetsw
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/clk.c | 15 +++++++++++----
arch/mips/bcm63xx/dev-enet.c | 9 ++++++---
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 1 +
3 files changed, 18 insertions(+), 7 deletions(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -119,11 +119,18 @@ 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) {
/* reset switch core afer clock change */
bcm63xx_core_set_reset(BCM63XX_RESET_ENETSW, 1);
--- 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

View file

@ -0,0 +1,130 @@
From 261ee140e75615351128eee497e6bbd76686784b 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 51/72] MIPS: BCM63XX: add HS SPI platform device and register
it
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
---
arch/mips/bcm63xx/Makefile | 4 +-
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, 81 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,7 +1,8 @@
obj-y += clk.o cpu.o cs.o gpio.o irq.o nvram.o prom.o reset.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-usb-ehci.o dev-usb-ohci.o dev-usb-usbd.o usb-common.o
+ dev-hsspi.o dev-pcmcia.o dev-rng.o dev-spi.o dev-uart.o \
+ dev-wdt.o dev-usb-ehci.o dev-usb-ohci.o dev-usb-usbd.o \
+ usb-common.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
@@ -26,6 +26,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_ehci.h>
@@ -955,6 +956,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 */

View file

@ -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_BFIN5XX) += 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 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");

View file

@ -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
@@ -629,6 +629,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
@@ -1478,6 +1479,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)

View file

@ -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
@@ -1474,6 +1474,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)

View file

@ -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
@@ -35,6 +35,8 @@ struct bcm963xx_nvram {
u32 checksum_high;
};
+#define BCM63XX_DEFAULT_PSI_SIZE 64
+
static struct bcm963xx_nvram nvram;
static int mac_addr_used;
@@ -105,3 +107,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
@@ -32,4 +32,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 */

View file

@ -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 <linux/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));

View file

@ -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
@@ -100,6 +100,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;
@@ -191,8 +192,9 @@ static int physmap_flash_probe(struct pl
spin_lock_init(&info->vpp_lock);
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, NULL,
+ 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__ */

View file

@ -0,0 +1,81 @@
From 8879e209111192c5e9752d7bd203cf7582693328 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 58/72] BCM63XX: allow providing fixup data in board data
---
arch/mips/bcm63xx/boards/board_bcm963xx.c | 9 ++++++++-
arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 10 ++++++++++
2 files changed, 18 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_ohci.h>
#include <bcm63xx_dev_usb_usbd.h>
#include <board_bcm963xx.h>
+#include <pci_ath9k_fixup.h>
#include <uapi/linux/bcm963xx_tag.h>
@@ -910,6 +911,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);
@@ -948,7 +950,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(
@@ -990,5 +993,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
@@ -8,6 +8,7 @@
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_usb_usbd.h>
#include <bcm63xx_dev_dsp.h>
+#include <pci_ath9k_fixup.h>
/*
* flash mapping
@@ -15,6 +16,11 @@
#define BCM963XX_CFE_VERSION_OFFSET 0x570
#define BCM963XX_NVRAM_OFFSET 0x580
+struct ath9k_caldata {
+ unsigned int slot;
+ u32 caldata_offset;
+};
+
/*
* board definition
*/
@@ -34,6 +40,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;

View file

@ -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
@@ -877,6 +877,9 @@ static int m25p_probe(struct spi_device
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 */

View file

@ -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 */

View file

@ -0,0 +1,227 @@
From bbebbf735a02b6d044ed928978ab4bd5f1833364 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 61/72] BCM63XX: add a fixup for ath9k devices
---
arch/mips/bcm63xx/Makefile | 3 +-
arch/mips/bcm63xx/pci-ath9k-fixup.c | 190 ++++++++++++++++++++
.../include/asm/mach-bcm63xx/pci_ath9k_fixup.h | 7 +
3 files changed, 199 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
@@ -2,7 +2,7 @@ obj-y += clk.o cpu.o cs.o gpio.o irq.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-wdt.o dev-usb-ehci.o dev-usb-ohci.o dev-usb-usbd.o \
- usb-common.o
+ pci-ath9k-fixup.o usb-common.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 */

View file

@ -0,0 +1,120 @@
Allow bcm63xxpart to receive a caldata offset if calibration data is
contained in flash.
---
drivers/mtd/bcm63xxpart.c | 51 ++++++++++++++++++++++++++++++++++++---
include/linux/mtd/partitions.h | 2 +
2 files changed, 49 insertions(+), 4 deletions(-)
--- a/drivers/mtd/bcm63xxpart.c
+++ b/drivers/mtd/bcm63xxpart.c
@@ -76,10 +76,12 @@ static int bcm63xx_parse_cfe_partitions(
struct mtd_partition *parts;
int ret;
size_t retlen;
- unsigned int rootfsaddr, kerneladdr, spareaddr;
+ unsigned int rootfsaddr, kerneladdr, spareaddr, nvramaddr;
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;
@@ -93,6 +95,24 @@ static int bcm63xx_parse_cfe_partitions(
cfelen = cfe_erasesize;
nvramlen = bcm63xx_nvram_get_psi_size() * 1024;
nvramlen = roundup(nvramlen, cfe_erasesize);
+ nvramaddr = master->size - nvramlen;
+
+ 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));
@@ -144,7 +164,7 @@ static int bcm63xx_parse_cfe_partitions(
rootfsaddr = 0;
spareaddr = cfelen;
}
- sparelen = master->size - spareaddr - nvramlen;
+ sparelen = min_not_zero(nvramaddr, caldataaddr1) - spareaddr;
/* Determine number of partitions */
if (rootfslen > 0)
@@ -153,6 +173,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,15 +216,32 @@ 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].offset = nvramaddr;
parts[curpart].size = nvramlen;
curpart++;
/* 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 = min_not_zero(nvramaddr, caldataaddr1) - cfelen;
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;
};

View file

@ -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
@@ -969,7 +969,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 */

View file

@ -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
@@ -232,6 +232,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

View file

@ -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
@@ -213,6 +213,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
@@ -1393,6 +1393,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

View file

@ -0,0 +1,71 @@
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
@@ -40,6 +40,8 @@ config BCM63XX_CPU_6358
config BCM63XX_CPU_6362
bool "support 6362 CPU"
select HW_HAS_PCI
+ select BCM63XX_OHCI
+ select BCM63XX_EHCI
config BCM63XX_CPU_6368
bool "support 6368 CPU"
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -167,6 +167,8 @@ static void usbh_set(struct clk *clk, in
bcm_hwclock_set(CKCTL_6328_USBH_EN, enable);
else 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);
else
--- a/arch/mips/bcm63xx/dev-usb-ehci.c
+++ b/arch/mips/bcm63xx/dev-usb-ehci.c
@@ -81,7 +81,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/usb-common.c
+++ b/arch/mips/bcm63xx/usb-common.c
@@ -100,7 +100,7 @@ void bcm63xx_usb_priv_ohci_cfg_set(void)
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;
@@ -135,7 +135,7 @@ void bcm63xx_usb_priv_ehci_cfg_set(void)
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_ENDN_MASK;
reg |= USBH_PRIV_SWAP_EHCI_DATA_MASK;

View file

@ -0,0 +1,67 @@
From eac04ec501cac3069c279ccaa72fce4f530a4071 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 68/72] MIPS: BCM63XX: enable enetsw for BCM6362
---
arch/mips/bcm63xx/clk.c | 4 +++-
arch/mips/bcm63xx/dev-enet.c | 6 ++++--
arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 1 +
3 files changed, 8 insertions(+), 3 deletions(-)
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -121,11 +121,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;
--- 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

View file

@ -0,0 +1,802 @@
From 1b0b5d325d0cc50cade62afd6a9416fb3cd1e658 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Mon, 7 Jan 2013 17:42:45 +0100
Subject: [PATCH 69/72] 443-MIPS-BCM63XX-enable-enet-for-BCM6345.patch
---
arch/mips/bcm63xx/dev-enet.c | 63 ++++++-
arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | 3 +-
.../include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | 88 +++++++++
arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | 43 ++++-
drivers/net/ethernet/broadcom/bcm63xx_enet.c | 199 ++++++++++++--------
drivers/net/ethernet/broadcom/bcm63xx_enet.h | 15 ++
6 files changed, 320 insertions(+), 91 deletions(-)
--- a/arch/mips/bcm63xx/dev-enet.c
+++ b/arch/mips/bcm63xx/dev-enet.c
@@ -9,10 +9,44 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/export.h>
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>
+#ifdef BCMCPU_RUNTIME_DETECT
+static const unsigned long bcm6xxx_regs_enetdmac[] = {
+ [ENETDMAC_CHANCFG] = ENETDMAC_CHANCFG_REG,
+ [ENETDMAC_IR] = ENETDMAC_IR_REG,
+ [ENETDMAC_IRMASK] = ENETDMAC_IRMASK_REG,
+ [ENETDMAC_MAXBURST] = ENETDMAC_MAXBURST_REG,
+};
+
+static const unsigned long bcm6345_regs_enetdmac[] = {
+ [ENETDMAC_CHANCFG] = ENETDMA_6345_CHANCFG_REG,
+ [ENETDMAC_IR] = ENETDMA_6345_IR_REG,
+ [ENETDMAC_IRMASK] = ENETDMA_6345_IRMASK_REG,
+ [ENETDMAC_MAXBURST] = ENETDMA_6345_MAXBURST_REG,
+ [ENETDMAC_BUFALLOC] = ENETDMA_6345_BUFALLOC_REG,
+ [ENETDMAC_RSTART] = ENETDMA_6345_RSTART_REG,
+ [ENETDMAC_FC] = ENETDMA_6345_FC_REG,
+ [ENETDMAC_LEN] = ENETDMA_6345_LEN_REG,
+};
+
+const unsigned long *bcm63xx_regs_enetdmac;
+EXPORT_SYMBOL(bcm63xx_regs_enetdmac);
+
+static __init void bcm63xx_enetdmac_regs_init(void)
+{
+ if (BCMCPU_IS_6345())
+ bcm63xx_regs_enetdmac = bcm6345_regs_enetdmac;
+ else
+ bcm63xx_regs_enetdmac = bcm6xxx_regs_enetdmac;
+}
+#else
+static __init void bcm63xx_enetdmac_regs_init(void) { }
+#endif
+
static struct resource shared_res[] = {
{
.start = -1, /* filled at runtime */
@@ -137,12 +171,19 @@ static int __init register_shared(void)
if (shared_device_registered)
return 0;
+ bcm63xx_enetdmac_regs_init();
+
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_6345())
+ shared_res[0].end += (RSET_6345_ENETDMA_SIZE) - 1;
+ else
+ shared_res[0].end += (RSET_ENETDMA_SIZE) - 1;
if (BCMCPU_IS_6328() || BCMCPU_IS_6362() || BCMCPU_IS_6368())
chan_count = 32;
+ else if (BCMCPU_IS_6345())
+ chan_count = 8;
else
chan_count = 16;
@@ -172,7 +213,7 @@ int __init bcm63xx_enet_register(int uni
if (unit > 1)
return -ENODEV;
- if (unit == 1 && BCMCPU_IS_6338())
+ if (unit == 1 && (BCMCPU_IS_6338() || BCMCPU_IS_6345()))
return -ENODEV;
ret = register_shared();
@@ -213,6 +254,20 @@ int __init bcm63xx_enet_register(int uni
dpd->phy_interrupt = bcm63xx_get_irq_number(IRQ_ENET_PHY);
}
+ dpd->dma_chan_en_mask = ENETDMAC_CHANCFG_EN_MASK;
+ dpd->dma_chan_int_mask = ENETDMAC_IR_PKTDONE_MASK;
+ if (BCMCPU_IS_6345()) {
+ dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_CHAINING_MASK;
+ dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_WRAP_EN_MASK;
+ dpd->dma_chan_en_mask |= ENETDMAC_CHANCFG_FLOWC_EN_MASK;
+ dpd->dma_chan_int_mask |= ENETDMA_IR_BUFDONE_MASK;
+ dpd->dma_chan_int_mask |= ENETDMA_IR_NOTOWNER_MASK;
+ dpd->dma_chan_width = ENETDMA_6345_CHAN_WIDTH;
+ dpd->dma_no_sram = 1;
+ dpd->dma_desc_shift = ENETDMA_6345_DESC_SHIFT;
+ } else
+ dpd->dma_chan_width = ENETDMA_CHAN_WIDTH;
+
ret = platform_device_register(pdev);
if (ret)
return ret;
@@ -248,6 +303,10 @@ bcm63xx_enetsw_register(const struct bcm
else if (BCMCPU_IS_6368())
enetsw_pd.num_ports = ENETSW_PORTS_6368;
+ enetsw_pd.dma_chan_width = ENETDMA_CHAN_WIDTH;
+ enetsw_pd.dma_chan_en_mask = ENETDMAC_CHANCFG_EN_MASK;
+ enetsw_pd.dma_chan_int_mask = ENETDMAC_IR_PKTDONE_MASK;
+
ret = platform_device_register(&bcm63xx_enetsw_device);
if (ret)
return ret;
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -175,6 +175,7 @@ enum bcm63xx_regs_set {
#define BCM_6368_RSET_SPI_SIZE 1804
#define RSET_ENET_SIZE 2048
#define RSET_ENETDMA_SIZE 256
+#define RSET_6345_ENETDMA_SIZE 64
#define RSET_ENETDMAC_SIZE(chans) (16 * (chans))
#define RSET_ENETDMAS_SIZE(chans) (16 * (chans))
#define RSET_ENETSW_SIZE 65536
@@ -305,7 +306,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_USBDMA_BASE (0xfffe2800)
#define BCM_6345_ENET0_BASE (0xfffe1800)
#define BCM_6345_ENETDMA_BASE (0xfffe2800)
-#define BCM_6345_ENETDMAC_BASE (0xfffe2900)
+#define BCM_6345_ENETDMAC_BASE (0xfffe2840)
#define BCM_6345_ENETDMAS_BASE (0xfffe2a00)
#define BCM_6345_ENETSW_BASE (0xdeadbeef)
#define BCM_6345_PCMCIA_BASE (0xfffe2028)
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h
@@ -4,6 +4,8 @@
#include <linux/if_ether.h>
#include <linux/init.h>
+#include <bcm63xx_regs.h>
+
/*
* on board ethernet platform data
*/
@@ -37,6 +39,21 @@ struct bcm63xx_enet_platform_data {
int phy_id, int reg),
void (*mii_write)(struct net_device *dev,
int phy_id, int reg, int val));
+
+ /* DMA channel enable mask */
+ u32 dma_chan_en_mask;
+
+ /* DMA channel interrupt mask */
+ u32 dma_chan_int_mask;
+
+ /* Set to one if DMA engine has *no* SRAM */
+ unsigned int dma_no_sram;
+
+ /* DMA channel register width */
+ unsigned int dma_chan_width;
+
+ /* DMA descriptor shift */
+ unsigned int dma_desc_shift;
};
/*
@@ -64,6 +81,15 @@ struct bcm63xx_enetsw_platform_data {
char mac_addr[ETH_ALEN];
int num_ports;
struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
+
+ /* DMA channel enable mask */
+ u32 dma_chan_en_mask;
+
+ /* DMA channel interrupt mask */
+ u32 dma_chan_int_mask;
+
+ /* DMA channel register width */
+ unsigned int dma_chan_width;
};
int __init bcm63xx_enet_register(int unit,
@@ -72,4 +98,66 @@ int __init bcm63xx_enet_register(int uni
int __init
bcm63xx_enetsw_register(const struct bcm63xx_enetsw_platform_data *pd);
+enum bcm63xx_regs_enetdmac {
+ ENETDMAC_CHANCFG,
+ ENETDMAC_IR,
+ ENETDMAC_IRMASK,
+ ENETDMAC_MAXBURST,
+ ENETDMAC_BUFALLOC,
+ ENETDMAC_RSTART,
+ ENETDMAC_FC,
+ ENETDMAC_LEN,
+};
+
+static inline unsigned long bcm63xx_enetdmacreg(enum bcm63xx_regs_enetdmac reg)
+{
+#ifdef BCMCPU_RUNTIME_DETECT
+ extern const unsigned long *bcm63xx_regs_enetdmac;
+
+ return bcm63xx_regs_enetdmac[reg];
+#else
+#ifdef CONFIG_BCM63XX_CPU_6345
+ switch (reg) {
+ case ENETDMAC_CHANCFG:
+ return ENETDMA_6345_CHANCFG_REG;
+ case ENETDMAC_IR:
+ return ENETDMA_6345_IR_REG;
+ case ENETDMAC_IRMASK:
+ return ENETDMA_6345_IRMASK_REG;
+ case ENETDMAC_MAXBURST:
+ return ENETDMA_6345_MAXBURST_REG;
+ case ENETDMAC_BUFALLOC:
+ return ENETDMA_6345_BUFALLOC_REG;
+ case ENETDMAC_RSTART:
+ return ENETDMA_6345_RSTART_REG;
+ case ENETDMAC_FC:
+ return ENETDMA_6345_FC_REG;
+ case ENETDMAC_LEN:
+ return ENETDMA_6345_LEN_REG;
+ }
+#endif
+#if defined(CONFIG_BCM6XX_CPU_6338) || defined(CONFIG_BCM63XX_CPU_6348) \
+ defined(CONFIG_BCM63XX_CPU_6358) || defined(CONFIG_BCM63XX_CPU_6362) \
+ defined(CONFIG_BCM63XX_CPU_6368)
+ switch (reg) {
+ case ENETDMAC_CHANCFG:
+ return ENETDMAC_CHANCFG_REG;
+ case ENETDMAC_IR:
+ return ENETDMAC_IR_REG;
+ case ENETDMAC_IRMASK:
+ return ENETDMAC_IRMASK_REG;
+ case ENETDMAC_MAXBURST:
+ return ENETDMAC_MAXBURST_REG;
+ case ENETDMAC_BUFALLOC:
+ case ENETDMAC_RSTART:
+ case ENETDMAC_FC:
+ case ENETDMAC_LEN:
+ return 0;
+ }
+#endif
+#endif
+ return 0;
+}
+
+
#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
@@ -730,6 +730,8 @@
/*************************************************************************
* _REG relative to RSET_ENETDMA
*************************************************************************/
+#define ENETDMA_CHAN_WIDTH 0x10
+#define ENETDMA_6345_CHAN_WIDTH 0x40
/* Controller Configuration Register */
#define ENETDMA_CFG_REG (0x0)
@@ -785,31 +787,56 @@
/* State Ram Word 4 */
#define ENETDMA_SRAM4_REG(x) (0x20c + (x) * 0x10)
+/* Broadcom 6345 ENET DMA definitions */
+#define ENETDMA_6345_CHANCFG_REG (0x00)
+
+#define ENETDMA_6345_MAXBURST_REG (0x40)
+
+#define ENETDMA_6345_RSTART_REG (0x08)
+
+#define ENETDMA_6345_LEN_REG (0x0C)
+
+#define ENETDMA_6345_IR_REG (0x14)
+
+#define ENETDMA_6345_IRMASK_REG (0x18)
+
+#define ENETDMA_6345_FC_REG (0x1C)
+
+#define ENETDMA_6345_BUFALLOC_REG (0x20)
+
+/* Shift down for EOP, SOP and WRAP bits */
+#define ENETDMA_6345_DESC_SHIFT (3)
/*************************************************************************
* _REG relative to RSET_ENETDMAC
*************************************************************************/
/* Channel Configuration register */
-#define ENETDMAC_CHANCFG_REG(x) ((x) * 0x10)
+#define ENETDMAC_CHANCFG_REG (0x0)
#define ENETDMAC_CHANCFG_EN_SHIFT 0
#define ENETDMAC_CHANCFG_EN_MASK (1 << ENETDMAC_CHANCFG_EN_SHIFT)
#define ENETDMAC_CHANCFG_PKTHALT_SHIFT 1
#define ENETDMAC_CHANCFG_PKTHALT_MASK (1 << ENETDMAC_CHANCFG_PKTHALT_SHIFT)
#define ENETDMAC_CHANCFG_BUFHALT_SHIFT 2
#define ENETDMAC_CHANCFG_BUFHALT_MASK (1 << ENETDMAC_CHANCFG_BUFHALT_SHIFT)
+#define ENETDMAC_CHANCFG_CHAINING_SHIFT 2
+#define ENETDMAC_CHANCFG_CHAINING_MASK (1 << ENETDMAC_CHANCFG_CHAINING_SHIFT)
+#define ENETDMAC_CHANCFG_WRAP_EN_SHIFT 3
+#define ENETDMAC_CHANCFG_WRAP_EN_MASK (1 << ENETDMAC_CHANCFG_WRAP_EN_SHIFT)
+#define ENETDMAC_CHANCFG_FLOWC_EN_SHIFT 4
+#define ENETDMAC_CHANCFG_FLOWC_EN_MASK (1 << ENETDMAC_CHANCFG_FLOWC_EN_SHIFT)
/* Interrupt Control/Status register */
-#define ENETDMAC_IR_REG(x) (0x4 + (x) * 0x10)
+#define ENETDMAC_IR_REG (0x4)
#define ENETDMAC_IR_BUFDONE_MASK (1 << 0)
#define ENETDMAC_IR_PKTDONE_MASK (1 << 1)
#define ENETDMAC_IR_NOTOWNER_MASK (1 << 2)
/* Interrupt Mask register */
-#define ENETDMAC_IRMASK_REG(x) (0x8 + (x) * 0x10)
+#define ENETDMAC_IRMASK_REG (0x8)
/* Maximum Burst Length */
-#define ENETDMAC_MAXBURST_REG(x) (0xc + (x) * 0x10)
+#define ENETDMAC_MAXBURST_REG (0xc)
/*************************************************************************
@@ -817,16 +844,16 @@
*************************************************************************/
/* Ring Start Address register */
-#define ENETDMAS_RSTART_REG(x) ((x) * 0x10)
+#define ENETDMAS_RSTART_REG (0x0)
/* State Ram Word 2 */
-#define ENETDMAS_SRAM2_REG(x) (0x4 + (x) * 0x10)
+#define ENETDMAS_SRAM2_REG (0x4)
/* State Ram Word 3 */
-#define ENETDMAS_SRAM3_REG(x) (0x8 + (x) * 0x10)
+#define ENETDMAS_SRAM3_REG (0x8)
/* State Ram Word 4 */
-#define ENETDMAS_SRAM4_REG(x) (0xc + (x) * 0x10)
+#define ENETDMAS_SRAM4_REG (0xc)
/*************************************************************************
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -115,26 +115,28 @@ static inline void enet_dma_writel(struc
bcm_writel(val, bcm_enet_shared_base[0] + off);
}
-static inline u32 enet_dmac_readl(struct bcm_enet_priv *priv, u32 off)
+static inline u32 enet_dmac_readl(struct bcm_enet_priv *priv, u32 off, int chan)
{
- return bcm_readl(bcm_enet_shared_base[1] + off);
+ return bcm_readl(bcm_enet_shared_base[1] +
+ (bcm63xx_enetdmacreg(off) + (chan * priv->dma_chan_width)));
}
static inline void enet_dmac_writel(struct bcm_enet_priv *priv,
- u32 val, u32 off)
+ u32 val, u32 off, int chan)
{
- bcm_writel(val, bcm_enet_shared_base[1] + off);
+ bcm_writel(val, bcm_enet_shared_base[1] +
+ (bcm63xx_enetdmacreg(off) + (chan * priv->dma_chan_width)));
}
-static inline u32 enet_dmas_readl(struct bcm_enet_priv *priv, u32 off)
+static inline u32 enet_dmas_readl(struct bcm_enet_priv *priv, u32 off, int chan)
{
- return bcm_readl(bcm_enet_shared_base[2] + off);
+ return bcm_readl(bcm_enet_shared_base[2] + (off + (chan * priv->dma_chan_width)));
}
static inline void enet_dmas_writel(struct bcm_enet_priv *priv,
- u32 val, u32 off)
+ u32 val, u32 off, int chan)
{
- bcm_writel(val, bcm_enet_shared_base[2] + off);
+ bcm_writel(val, bcm_enet_shared_base[2] + (off + (chan * priv->dma_chan_width)));
}
/*
@@ -270,7 +272,7 @@ static int bcm_enet_refill_rx(struct net
len_stat = priv->rx_skb_size << DMADESC_LENGTH_SHIFT;
len_stat |= DMADESC_OWNER_MASK;
if (priv->rx_dirty_desc == priv->rx_ring_size - 1) {
- len_stat |= DMADESC_WRAP_MASK;
+ len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift);
priv->rx_dirty_desc = 0;
} else {
priv->rx_dirty_desc++;
@@ -281,7 +283,10 @@ static int bcm_enet_refill_rx(struct net
priv->rx_desc_count++;
/* tell dma engine we allocated one buffer */
- enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan));
+ if (!priv->dma_no_sram)
+ enet_dma_writel(priv, 1, ENETDMA_BUFALLOC_REG(priv->rx_chan));
+ else
+ enet_dmac_writel(priv, 1, ENETDMAC_BUFALLOC, priv->rx_chan);
}
/* If rx ring is still empty, set a timer to try allocating
@@ -357,7 +362,8 @@ static int bcm_enet_receive_queue(struct
/* if the packet does not have start of packet _and_
* end of packet flag set, then just recycle it */
- if ((len_stat & DMADESC_ESOP_MASK) != DMADESC_ESOP_MASK) {
+ if ((len_stat & (DMADESC_ESOP_MASK >> priv->dma_desc_shift)) !=
+ (DMADESC_ESOP_MASK >> priv->dma_desc_shift)) {
dev->stats.rx_dropped++;
continue;
}
@@ -418,8 +424,8 @@ static int bcm_enet_receive_queue(struct
bcm_enet_refill_rx(dev);
/* kick rx dma */
- enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK,
- ENETDMAC_CHANCFG_REG(priv->rx_chan));
+ enet_dmac_writel(priv, priv->dma_chan_en_mask,
+ ENETDMAC_CHANCFG, priv->rx_chan);
}
return processed;
@@ -494,10 +500,10 @@ static int bcm_enet_poll(struct napi_str
dev = priv->net_dev;
/* ack interrupts */
- 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));
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IR, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IR, priv->tx_chan);
/* reclaim sent skb */
tx_work_done = bcm_enet_tx_reclaim(dev, 0);
@@ -516,10 +522,10 @@ static int bcm_enet_poll(struct napi_str
napi_complete(napi);
/* restore rx/tx interrupt */
- 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));
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IRMASK, priv->tx_chan);
return rx_work_done;
}
@@ -562,8 +568,8 @@ static irqreturn_t bcm_enet_isr_dma(int
priv = netdev_priv(dev);
/* mask rx/tx interrupts */
- enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan));
- enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
napi_schedule(&priv->napi);
@@ -624,14 +630,14 @@ static int bcm_enet_start_xmit(struct sk
DMA_TO_DEVICE);
len_stat = (skb->len << DMADESC_LENGTH_SHIFT) & DMADESC_LENGTH_MASK;
- len_stat |= DMADESC_ESOP_MASK |
+ len_stat |= (DMADESC_ESOP_MASK >> priv->dma_desc_shift) |
DMADESC_APPEND_CRC |
DMADESC_OWNER_MASK;
priv->tx_curr_desc++;
if (priv->tx_curr_desc == priv->tx_ring_size) {
priv->tx_curr_desc = 0;
- len_stat |= DMADESC_WRAP_MASK;
+ len_stat |= (DMADESC_WRAP_MASK >> priv->dma_desc_shift);
}
priv->tx_desc_count--;
@@ -642,8 +648,8 @@ static int bcm_enet_start_xmit(struct sk
wmb();
/* kick tx dma */
- enet_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK,
- ENETDMAC_CHANCFG_REG(priv->tx_chan));
+ enet_dmac_writel(priv, priv->dma_chan_en_mask,
+ ENETDMAC_CHANCFG, priv->tx_chan);
/* stop queue if no more desc available */
if (!priv->tx_desc_count)
@@ -771,6 +777,9 @@ static void bcm_enet_set_flow(struct bcm
val &= ~ENET_RXCFG_ENFLOW_MASK;
enet_writel(priv, val, ENET_RXCFG_REG);
+ if (priv->dma_no_sram)
+ return;
+
/* tx flow control (pause frame generation) */
val = enet_dma_readl(priv, ENETDMA_CFG_REG);
if (tx_en)
@@ -886,8 +895,8 @@ static int bcm_enet_open(struct net_devi
/* mask all interrupts and request them */
enet_writel(priv, 0, ENET_IRMASK_REG);
- enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan));
- enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
ret = request_irq(dev->irq, bcm_enet_isr_mac, 0, dev->name, dev);
if (ret)
@@ -966,8 +975,12 @@ static int bcm_enet_open(struct net_devi
priv->rx_curr_desc = 0;
/* initialize flow control buffer allocation */
- enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
- ENETDMA_BUFALLOC_REG(priv->rx_chan));
+ if (!priv->dma_no_sram)
+ enet_dma_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+ ENETDMA_BUFALLOC_REG(priv->rx_chan));
+ else
+ enet_dmac_writel(priv, ENETDMA_BUFALLOC_FORCE_MASK | 0,
+ ENETDMAC_BUFALLOC, priv->rx_chan);
if (bcm_enet_refill_rx(dev)) {
dev_err(kdev, "cannot allocate rx skb queue\n");
@@ -976,18 +989,30 @@ static int bcm_enet_open(struct net_devi
}
/* 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));
+ if (!priv->dma_no_sram) {
+ 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);
+ } else {
+ enet_dmac_writel(priv, priv->rx_desc_dma,
+ ENETDMAC_RSTART, priv->rx_chan);
+ enet_dmac_writel(priv, priv->tx_desc_dma,
+ ENETDMAC_RSTART, 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));
+ if (!priv->dma_no_sram) {
+ 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);
+ } else {
+ enet_dmac_writel(priv, 0, ENETDMAC_FC, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_FC, priv->tx_chan);
+ }
/* set max rx/tx length */
enet_writel(priv, priv->hw_mtu, ENET_RXMAXLEN_REG);
@@ -995,18 +1020,24 @@ static int bcm_enet_open(struct net_devi
/* set dma maximum burst len */
enet_dmac_writel(priv, priv->dma_maxburst,
- ENETDMAC_MAXBURST_REG(priv->rx_chan));
+ ENETDMAC_MAXBURST, priv->rx_chan);
enet_dmac_writel(priv, priv->dma_maxburst,
- ENETDMAC_MAXBURST_REG(priv->tx_chan));
+ ENETDMAC_MAXBURST, priv->tx_chan);
/* set correct transmit fifo watermark */
enet_writel(priv, BCMENET_TX_FIFO_TRESH, ENET_TXWMARK_REG);
/* 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));
+ if (!priv->dma_no_sram) {
+ 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));
+ } else {
+ enet_dmac_writel(priv, 5, ENETDMAC_FC, priv->rx_chan);
+ enet_dmac_writel(priv, priv->rx_ring_size, ENETDMAC_LEN, priv->rx_chan);
+ enet_dmac_writel(priv, priv->tx_ring_size, ENETDMAC_LEN, priv->tx_chan);
+ }
/* all set, enable mac and interrupts, start dma engine and
* kick rx dma channel */
@@ -1015,26 +1046,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_dmac_writel(priv, ENETDMAC_CHANCFG_EN_MASK,
- ENETDMAC_CHANCFG_REG(priv->rx_chan));
+ enet_dmac_writel(priv, priv->dma_chan_en_mask,
+ ENETDMAC_CHANCFG, 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_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));
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IR, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IR, 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));
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, priv->dma_chan_int_mask,
+ ENETDMAC_IRMASK, priv->tx_chan);
if (priv->has_phy)
phy_start(priv->phydev);
@@ -1111,13 +1142,13 @@ static void bcm_enet_disable_dma(struct
{
int limit;
- enet_dmac_writel(priv, 0, ENETDMAC_CHANCFG_REG(chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_CHANCFG, chan);
limit = 1000;
do {
u32 val;
- val = enet_dmac_readl(priv, ENETDMAC_CHANCFG_REG(chan));
+ val = enet_dmac_readl(priv, ENETDMAC_CHANCFG, chan);
if (!(val & ENETDMAC_CHANCFG_EN_MASK))
break;
udelay(1);
@@ -1144,8 +1175,8 @@ static int bcm_enet_stop(struct net_devi
/* mask all interrupts */
enet_writel(priv, 0, ENET_IRMASK_REG);
- enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->rx_chan));
- enet_dmac_writel(priv, 0, ENETDMAC_IRMASK_REG(priv->tx_chan));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
/* make sure no mib update is scheduled */
cancel_work_sync(&priv->mib_update_task);
@@ -1757,6 +1788,11 @@ static int bcm_enet_probe(struct platfor
priv->pause_tx = pd->pause_tx;
priv->force_duplex_full = pd->force_duplex_full;
priv->force_speed_100 = pd->force_speed_100;
+ priv->dma_chan_en_mask = pd->dma_chan_en_mask;
+ priv->dma_chan_int_mask = pd->dma_chan_int_mask;
+ priv->dma_chan_width = pd->dma_chan_width;
+ priv->dma_no_sram = pd->dma_no_sram;
+ priv->dma_desc_shift = pd->dma_desc_shift;
}
if (priv->mac_id == 0 && priv->has_phy && !priv->use_external_mii) {
@@ -2144,8 +2180,8 @@ static int bcm_enetsw_open(struct net_de
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));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
ret = request_irq(priv->irq_rx, bcm_enet_isr_dma,
IRQF_DISABLED, dev->name, dev);
@@ -2269,23 +2305,23 @@ static int bcm_enetsw_open(struct net_de
/* write rx & tx ring addresses */
enet_dmas_writel(priv, priv->rx_desc_dma,
- ENETDMAS_RSTART_REG(priv->rx_chan));
+ ENETDMAS_RSTART_REG, priv->rx_chan);
enet_dmas_writel(priv, priv->tx_desc_dma,
- ENETDMAS_RSTART_REG(priv->tx_chan));
+ 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));
+ 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, priv->dma_maxburst,
- ENETDMAC_MAXBURST_REG(priv->rx_chan));
+ ENETDMAC_MAXBURST, priv->rx_chan);
enet_dmac_writel(priv, priv->dma_maxburst,
- ENETDMAC_MAXBURST_REG(priv->tx_chan));
+ ENETDMAC_MAXBURST, priv->tx_chan);
/* set flow control low/high threshold to 1/3 / 2/3 */
val = priv->rx_ring_size / 3;
@@ -2298,21 +2334,21 @@ static int bcm_enetsw_open(struct net_de
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));
+ ENETDMAC_CHANCFG, 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));
+ ENETDMAC_IR, priv->rx_chan);
enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
- ENETDMAC_IR_REG(priv->tx_chan));
+ ENETDMAC_IR, 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));
+ ENETDMAC_IRMASK, priv->rx_chan);
enet_dmac_writel(priv, ENETDMAC_IR_PKTDONE_MASK,
- ENETDMAC_IRMASK_REG(priv->tx_chan));
+ ENETDMAC_IRMASK, priv->tx_chan);
netif_carrier_on(dev);
netif_start_queue(dev);
@@ -2419,8 +2455,8 @@ static int bcm_enetsw_stop(struct net_de
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));
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->rx_chan);
+ enet_dmac_writel(priv, 0, ENETDMAC_IRMASK, priv->tx_chan);
/* disable dma & mac */
bcm_enet_disable_dma(priv, priv->tx_chan);
@@ -2757,6 +2793,9 @@ static int bcm_enetsw_probe(struct platf
memcpy(priv->used_ports, pd->used_ports,
sizeof (pd->used_ports));
priv->num_ports = pd->num_ports;
+ priv->dma_chan_en_mask = pd->dma_chan_en_mask;
+ priv->dma_chan_int_mask = pd->dma_chan_int_mask;
+ priv->dma_chan_width = pd->dma_chan_width;
}
ret = compute_hw_mtu(priv, dev->mtu);
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
@@ -339,6 +339,21 @@ struct bcm_enet_priv {
/* used to poll switch port state */
struct timer_list swphy_poll;
spinlock_t enetsw_mdio_lock;
+
+ /* dma channel enable mask */
+ u32 dma_chan_en_mask;
+
+ /* dma channel interrupt mask */
+ u32 dma_chan_int_mask;
+
+ /* dma engine has *no* internal SRAM */
+ unsigned int dma_no_sram;
+
+ /* dma channel width */
+ unsigned int dma_chan_width;
+
+ /* dma descriptor shift value */
+ unsigned int dma_desc_shift;
};
static inline int bcm_enet_port_is_rgmii(int portid)

View file

@ -0,0 +1,51 @@
--- a/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h
+++ b/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h
@@ -2,6 +2,7 @@
#define _PCI_ATH9K_FIXUP
-void pci_enable_ath9k_fixup(unsigned slot, u32 offset) __init;
+void pci_enable_ath9k_fixup(unsigned slot, u32 offset,
+ unsigned endian_check) __init;
#endif /* _PCI_ATH9K_FIXUP */
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -19,6 +19,7 @@
struct ath9k_caldata {
unsigned int slot;
u32 caldata_offset;
+ unsigned int endian_check:1;
};
/*
--- a/arch/mips/bcm63xx/pci-ath9k-fixup.c
+++ b/arch/mips/bcm63xx/pci-ath9k-fixup.c
@@ -172,12 +172,14 @@ static void ath9k_pci_fixup(struct pci_d
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup);
-void __init pci_enable_ath9k_fixup(unsigned slot, u32 offset)
+void __init pci_enable_ath9k_fixup(unsigned slot, u32 offset,
+ unsigned endian_check)
{
if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups))
return;
ath9k_fixups[ath9k_num_fixups].slot = slot;
+ ath9k_fixups[ath9k_num_fixups].pdata.endian_check = endian_check;
if (!bcm63xx_read_eeprom(ath9k_fixups[ath9k_num_fixups].pdata.eeprom_data, offset))
return;
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -995,7 +995,8 @@ int __init board_register_devices(void)
/* register any fixups */
for (i = 0; i < board.has_caldata; i++)
- pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset);
+ pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset,
+ board.caldata[i].endian_check);
return 0;
}

View file

@ -0,0 +1,49 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -996,7 +996,7 @@ int __init board_register_devices(void)
/* register any fixups */
for (i = 0; i < board.has_caldata; i++)
pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset,
- board.caldata[i].endian_check);
+ board.caldata[i].endian_check, board.caldata[i].led_pin);
return 0;
}
--- a/arch/mips/bcm63xx/pci-ath9k-fixup.c
+++ b/arch/mips/bcm63xx/pci-ath9k-fixup.c
@@ -173,13 +173,14 @@ static void ath9k_pci_fixup(struct pci_d
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ath9k_pci_fixup);
void __init pci_enable_ath9k_fixup(unsigned slot, u32 offset,
- unsigned endian_check)
+ unsigned endian_check, int led_pin)
{
if (ath9k_num_fixups >= ARRAY_SIZE(ath9k_fixups))
return;
ath9k_fixups[ath9k_num_fixups].slot = slot;
ath9k_fixups[ath9k_num_fixups].pdata.endian_check = endian_check;
+ ath9k_fixups[ath9k_num_fixups].pdata.led_pin = led_pin;
if (!bcm63xx_read_eeprom(ath9k_fixups[ath9k_num_fixups].pdata.eeprom_data, offset))
return;
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -20,6 +20,7 @@ struct ath9k_caldata {
unsigned int slot;
u32 caldata_offset;
unsigned int endian_check:1;
+ int led_pin;
};
/*
--- a/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h
+++ b/arch/mips/include/asm/mach-bcm63xx/pci_ath9k_fixup.h
@@ -3,6 +3,6 @@
void pci_enable_ath9k_fixup(unsigned slot, u32 offset,
- unsigned endian_check) __init;
+ unsigned endian_check, int led_pin) __init;
#endif /* _PCI_ATH9K_FIXUP */

View file

@ -0,0 +1,205 @@
From 5ed5b5e9614fa5b02da699ab565af76c7e63d64d Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Mon, 7 Jan 2013 17:45:39 +0100
Subject: [PATCH 72/72] 446-BCM63XX-add-a-fixup-for-rt2x00-devices
---
arch/mips/bcm63xx/Makefile | 2 +-
arch/mips/bcm63xx/boards/board_bcm963xx.c | 17 ++++-
arch/mips/bcm63xx/dev-flash.c | 2 +-
arch/mips/bcm63xx/pci-rt2x00-fixup.c | 71 ++++++++++++++++++++
.../include/asm/mach-bcm63xx/bcm63xx_dev_flash.h | 2 +-
.../mips/include/asm/mach-bcm63xx/board_bcm963xx.h | 9 ++-
.../include/asm/mach-bcm63xx/pci_rt2x00_fixup.h | 9 +++
7 files changed, 104 insertions(+), 8 deletions(-)
create mode 100644 arch/mips/bcm63xx/pci-rt2x00-fixup.c
create mode 100644 arch/mips/include/asm/mach-bcm63xx/pci_rt2x00_fixup.h
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -2,7 +2,7 @@ obj-y += clk.o cpu.o cs.o gpio.o irq.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-wdt.o dev-usb-ehci.o dev-usb-ohci.o dev-usb-usbd.o \
- pci-ath9k-fixup.o usb-common.o
+ pci-ath9k-fixup.o pci-rt2x00-fixup.o usb-common.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
@@ -34,6 +34,7 @@
#include <bcm63xx_dev_usb_usbd.h>
#include <board_bcm963xx.h>
#include <pci_ath9k_fixup.h>
+#include <pci_rt2x00_fixup.h>
#include <uapi/linux/bcm963xx_tag.h>
@@ -994,9 +995,19 @@ int __init board_register_devices(void)
}
/* register any fixups */
- for (i = 0; i < board.has_caldata; i++)
- pci_enable_ath9k_fixup(board.caldata[i].slot, board.caldata[i].caldata_offset,
- board.caldata[i].endian_check, board.caldata[i].led_pin);
+ for (i = 0; i < board.has_caldata; i++) {
+ switch (board.caldata[i].vendor) {
+ case PCI_VENDOR_ID_ATHEROS:
+ pci_enable_ath9k_fixup(board.caldata[i].slot,
+ board.caldata[i].caldata_offset, board.caldata[i].endian_check,
+ board.caldata[i].led_pin);
+ break;
+ case PCI_VENDOR_ID_RALINK:
+ pci_enable_rt2x00_fixup(board.caldata[i].slot,
+ board.caldata[i].eeprom);
+ break;
+ }
+ }
return 0;
}
--- a/arch/mips/bcm63xx/dev-flash.c
+++ b/arch/mips/bcm63xx/dev-flash.c
@@ -146,7 +146,7 @@ static int __init bcm63xx_detect_flash_t
return 0;
}
-int __init bcm63xx_flash_register(int num_caldata, struct ath9k_caldata *caldata)
+int __init bcm63xx_flash_register(int num_caldata, struct bcm63xx_caldata *caldata)
{
u32 val;
unsigned int i;
--- /dev/null
+++ b/arch/mips/bcm63xx/pci-rt2x00-fixup.c
@@ -0,0 +1,72 @@
+/*
+ * Broadcom BCM63XX RT2x00 EEPROM fixup helper.
+ *
+ * Copyright (C) 2012 Álvaro Fernández Rojas <noltari@gmail.com>
+ *
+ * Based on
+ *
+ * Broadcom BCM63XX Ath9k EEPROM fixup helper.
+ *
+ * Copyright (C) 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 version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/if_ether.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+#include <linux/rt2x00_platform.h>
+
+#include <bcm63xx_nvram.h>
+#include <pci_rt2x00_fixup.h>
+
+struct rt2x00_fixup {
+ unsigned slot;
+ u8 mac[ETH_ALEN];
+ struct rt2x00_platform_data pdata;
+};
+
+static int rt2x00_num_fixups;
+static struct rt2x00_fixup rt2x00_fixups[2] = {
+ {
+ .slot = 255,
+ },
+ {
+ .slot = 255,
+ },
+};
+
+static void rt2x00_pci_fixup(struct pci_dev *dev)
+{
+ unsigned i;
+ struct rt2x00_platform_data *pdata = NULL;
+
+ for (i = 0; i < rt2x00_num_fixups; i++) {
+ if (rt2x00_fixups[i].slot != PCI_SLOT(dev->devfn))
+ continue;
+
+ pdata = &rt2x00_fixups[i].pdata;
+ break;
+ }
+
+ dev->dev.platform_data = pdata;
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_RALINK, PCI_ANY_ID, rt2x00_pci_fixup);
+
+void __init pci_enable_rt2x00_fixup(unsigned slot, char* eeprom)
+{
+ if (rt2x00_num_fixups >= ARRAY_SIZE(rt2x00_fixups))
+ return;
+
+ rt2x00_fixups[rt2x00_num_fixups].slot = slot;
+ rt2x00_fixups[rt2x00_num_fixups].pdata.eeprom_file_name = kstrdup(eeprom, GFP_KERNEL);
+
+ if (bcm63xx_nvram_get_mac_address(rt2x00_fixups[rt2x00_num_fixups].mac))
+ return;
+
+ rt2x00_fixups[rt2x00_num_fixups].pdata.mac_address = rt2x00_fixups[rt2x00_num_fixups].mac;
+ rt2x00_num_fixups++;
+}
+
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h
@@ -11,6 +11,6 @@ enum {
extern int bcm63xx_attached_flash;
-int __init bcm63xx_flash_register(int num_caldata, struct ath9k_caldata *caldata);
+int __init bcm63xx_flash_register(int num_caldata, struct bcm63xx_caldata *caldata);
#endif /* __BCM63XX_FLASH_H */
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -9,6 +9,7 @@
#include <bcm63xx_dev_usb_usbd.h>
#include <bcm63xx_dev_dsp.h>
#include <pci_ath9k_fixup.h>
+#include <pci_rt2x00_fixup.h>
/*
* flash mapping
@@ -16,11 +17,15 @@
#define BCM963XX_CFE_VERSION_OFFSET 0x570
#define BCM963XX_NVRAM_OFFSET 0x580
-struct ath9k_caldata {
+struct bcm63xx_caldata {
+ unsigned int vendor;
unsigned int slot;
u32 caldata_offset;
+ /* Atheros */
unsigned int endian_check:1;
int led_pin;
+ /* Ralink */
+ char* eeprom;
};
/*
@@ -45,7 +50,7 @@ struct board_info {
unsigned int has_caldata:2;
/* wifi calibration data config */
- struct ath9k_caldata caldata[2];
+ struct bcm63xx_caldata caldata[2];
/* ethernet config */
struct bcm63xx_enet_platform_data enet0;
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/pci_rt2x00_fixup.h
@@ -0,0 +1,9 @@
+#ifndef _PCI_RT2X00_FIXUP
+#define _PCI_RT2X00_FIXUP
+
+#define PCI_VENDOR_ID_RALINK 0x1814
+
+void pci_enable_rt2x00_fixup(unsigned slot, char* eeprom) __init;
+
+#endif /* _PCI_RT2X00_FIXUP */
+

View file

@ -0,0 +1,169 @@
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.h
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.h
@@ -336,6 +336,9 @@ struct bcm_enet_priv {
struct bcm63xx_enetsw_port used_ports[ENETSW_MAX_PORT];
int sw_port_link[ENETSW_MAX_PORT];
+ /* platform device for associated switch */
+ struct platform_device *b53_device;
+
/* used to poll switch port state */
struct timer_list swphy_poll;
spinlock_t enetsw_mdio_lock;
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -30,6 +30,7 @@
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/if_vlan.h>
+#include <linux/platform_data/b53.h>
#include <bcm63xx_dev_enet.h>
#include "bcm63xx_enet.h"
@@ -2013,7 +2014,8 @@ static int bcm_enet_remove(struct platfo
return 0;
}
-struct platform_driver bcm63xx_enet_driver = {
+
+static struct platform_driver bcm63xx_enet_driver = {
.probe = bcm_enet_probe,
.remove = bcm_enet_remove,
.driver = {
@@ -2022,6 +2024,42 @@ struct platform_driver bcm63xx_enet_driv
},
};
+struct b53_platform_data bcm63xx_b53_pdata = {
+ .chip_id = 0x6300,
+ .big_endian = 1,
+};
+
+struct platform_device bcm63xx_b53_dev = {
+ .name = "b53-switch",
+ .id = -1,
+ .dev = {
+ .platform_data = &bcm63xx_b53_pdata,
+ },
+};
+
+static int bcmenet_switch_register(struct bcm_enet_priv *priv, u16 port_mask)
+{
+ int ret;
+
+ bcm63xx_b53_pdata.regs = priv->base;
+ bcm63xx_b53_pdata.enabled_ports = port_mask;
+ bcm63xx_b53_pdata.alias = priv->net_dev->name;
+
+ ret = platform_device_register(&bcm63xx_b53_dev);
+ if (!ret)
+ priv->b53_device = &bcm63xx_b53_dev;
+
+ return ret;
+}
+
+static void bcmenet_switch_unregister(struct bcm_enet_priv *priv)
+{
+ if (priv->b53_device)
+ platform_device_unregister(&bcm63xx_b53_dev);
+
+ priv->b53_device = NULL;
+}
+
/*
* switch mii access callbacks
*/
@@ -2270,29 +2308,6 @@ static int bcm_enetsw_open(struct net_de
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;
- 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));
@@ -2760,6 +2775,9 @@ static int bcm_enetsw_probe(struct platf
struct bcm63xx_enetsw_platform_data *pd;
struct resource *res_mem;
int ret, irq_rx, irq_tx;
+ unsigned i, num_ports = 0;
+ u16 port_mask = BIT(8);
+ u8 val;
/* stop if shared driver failed, assume driver->probe will be
* called in the same order we register devices (correct ?) */
@@ -2847,6 +2865,43 @@ static int bcm_enetsw_probe(struct platf
priv->pdev = pdev;
priv->net_dev = dev;
+ /* 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);
+
+ for (i = 0; i < priv->num_ports; i++) {
+ struct bcm63xx_enetsw_port *port = &priv->used_ports[i];
+
+ if (!port->used)
+ continue;
+
+ num_ports++;
+ port_mask |= BIT(i);
+ }
+
+ /* only register if there is more than one external port */
+ if (num_ports > 1)
+ bcmenet_switch_register(priv, port_mask);
+
return 0;
out_put_clk:
@@ -2877,6 +2932,9 @@ static int bcm_enetsw_remove(struct plat
priv = netdev_priv(dev);
unregister_netdev(dev);
+ /* remove switch */
+ bcmenet_switch_unregister(priv);
+
/* release device resources */
iounmap(priv->base);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);

View file

@ -0,0 +1,67 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -520,6 +520,56 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -694,6 +744,7 @@ static const struct board_info __initcon
&board_DV201AMR,
&board_96348gw_a,
&board_rta1025w_16,
+ &board_96348_D4PW,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

View file

@ -0,0 +1,650 @@
--- 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>
@@ -46,6 +48,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;
/*
@@ -719,6 +727,596 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -752,6 +1350,11 @@ static const struct board_info __initcon
&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
};
@@ -806,6 +1409,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->board_id, BOARDID_LEN) != 0) {
/* else try 128k */

View file

@ -0,0 +1,51 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -191,6 +191,40 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -1329,6 +1363,7 @@ static const struct board_info __initcon
#ifdef CONFIG_BCM63XX_CPU_6338
&board_96338gw,
&board_96338w,
+ &board_96338w2_e7t,
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
&board_96345gw2,

View file

@ -0,0 +1,109 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -718,6 +718,98 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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,
@@ -1384,6 +1476,7 @@ static const struct board_info __initcon
&board_96358vw,
&board_96358vw2,
&board_AGPFS0,
+ &board_CPVA642,
&board_DWVS0,
&board_nb4_ser_r0,
&board_nb4_ser_r1,

View file

@ -0,0 +1,72 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -854,6 +854,61 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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,
@@ -1478,6 +1533,7 @@ static const struct board_info __initcon
&board_AGPFS0,
&board_CPVA642,
&board_DWVS0,
+ &board_dsl_274xb_rev_c,
&board_nb4_ser_r0,
&board_nb4_ser_r1,
&board_nb4_ser_r2,

View file

@ -0,0 +1,78 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -612,6 +612,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
/*
@@ -1525,6 +1586,7 @@ static const struct board_info __initcon
&board_96348gw_a,
&board_rta1025w_16,
&board_96348_D4PW,
+ &board_spw500v,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

View file

@ -0,0 +1,124 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -479,6 +479,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,
@@ -1579,6 +1685,8 @@ static const struct board_info __initcon
#ifdef CONFIG_BCM63XX_CPU_6348
&board_96348r,
&board_96348gw,
+ &board_gw6000,
+ &board_gw6200,
&board_96348gw_10,
&board_96348gw_11,
&board_FAST2404,

View file

@ -0,0 +1,89 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -779,6 +779,78 @@ 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 */
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -1695,6 +1767,7 @@ static const struct board_info __initcon
&board_rta1025w_16,
&board_96348_D4PW,
&board_spw500v,
+ &board_96348sv,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

View file

@ -0,0 +1,93 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1737,6 +1737,82 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -1782,6 +1858,7 @@ static const struct board_info __initcon
&board_nb4_ser_r2,
&board_nb4_fxc_r1,
&board_nb4_fxc_r2,
+ &board_HW553,
#endif
};

View file

@ -0,0 +1,56 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -225,6 +225,45 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -1826,6 +1865,7 @@ static const struct board_info __initcon
&board_96338gw,
&board_96338w,
&board_96338w2_e7t,
+ &board_rta1320_16m,
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
&board_96345gw2,

View file

@ -0,0 +1,83 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1852,6 +1852,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
/*
@@ -1899,6 +1965,7 @@ static const struct board_info __initcon
&board_nb4_fxc_r1,
&board_nb4_fxc_r2,
&board_HW553,
+ &board_spw303v,
#endif
};

View file

@ -0,0 +1,123 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -890,6 +890,65 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -1950,6 +2009,7 @@ static const struct board_info __initcon
&board_96348_D4PW,
&board_spw500v,
&board_96348sv,
+ &board_V2500V_BB,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
@@ -2070,6 +2130,22 @@ 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) {
+ u8 *tmp_boot_addr = (u8*)0xbfc00000;
+
+ if (!bcm63xx_nvram_init(tmp_boot_addr + BCM963XX_NVRAM_OFFSET) &&
+ !strcmp(bcm63xx_nvram_get_name(), "V2500V_BB")) {
+ printk(KERN_INFO PFX "V2500V: nvram bank 0\n");
+ boot_addr = tmp_boot_addr;
+ }
+ }
/* 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;

View file

@ -0,0 +1,75 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -450,6 +450,64 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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,
@@ -2010,6 +2068,7 @@ static const struct board_info __initcon
&board_spw500v,
&board_96348sv,
&board_V2500V_BB,
+ &board_V2110,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

View file

@ -0,0 +1,389 @@
--- 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 +1,2 @@
obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o
+obj-$(CONFIG_BOARD_LIVEBOX) += board_livebox.o
--- /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;
+}

View file

@ -0,0 +1,62 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -508,6 +508,51 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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,
@@ -2069,6 +2114,7 @@ static const struct board_info __initcon
&board_96348sv,
&board_V2500V_BB,
&board_V2110,
+ &board_ct536_ct5621,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

View file

@ -0,0 +1,19 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1277,6 +1277,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,
@@ -1292,6 +1294,7 @@ static struct board_info __initdata boar
},
.has_ohci0 = 1,
+ .has_ehci0 = 1,
};
/* D-Link DSL-274xB revison C2/C3 */

View file

@ -0,0 +1,80 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -553,6 +553,69 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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,
@@ -2118,6 +2181,7 @@ static const struct board_info __initcon
&board_V2500V_BB,
&board_V2110,
&board_ct536_ct5621,
+ &board_96348A_122,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

View file

@ -0,0 +1,10 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -818,6 +818,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,

View file

@ -0,0 +1,57 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1116,6 +1116,46 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -2183,6 +2223,7 @@ static const struct board_info __initcon
&board_V2110,
&board_ct536_ct5621,
&board_96348A_122,
+ &board_CPVA502plus,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

View file

@ -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
@@ -2190,6 +2190,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 __initconst *bcm963xx_boards[] = {
@@ -2241,6 +2313,10 @@ static const struct board_info __initcon
&board_HW553,
&board_spw303v,
#endif
+
+#ifdef CONFIG_BCM63XX_CPU_6368
+ &board_96368mvwg,
+#endif
};
/*
@@ -2412,12 +2488,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) {

View file

@ -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
@@ -2259,6 +2259,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
/*
@@ -2316,6 +2382,7 @@ static const struct board_info __initcon
#ifdef CONFIG_BCM63XX_CPU_6368
&board_96368mvwg,
+ &board_96368mvngr,
#endif
};

View file

@ -0,0 +1,67 @@
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
@@ -73,13 +73,45 @@ static struct board_info __initdata boar
.port_no = 0,
},
+ .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::ppp-fail",
+ .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,
@@ -96,7 +128,7 @@ static struct board_info __initdata boar
.active_low = 1,
},
{
- .name = "96328avng::ppp",
+ .name = "96328avng::internet",
.gpio = 11,
.active_low = 1,
},

View file

@ -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
@@ -134,6 +134,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
/*
@@ -2365,6 +2435,7 @@ static struct board_info __initdata boar
static const struct board_info __initconst *bcm963xx_boards[] = {
#ifdef CONFIG_BCM63XX_CPU_6328
&board_96328avng,
+ &board_963281TAN,
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
&board_96338gw,

View file

@ -0,0 +1,132 @@
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
@@ -204,6 +204,111 @@ 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 = {
+ {
+ .vendor = PCI_VENDOR_ID_ATHEROS,
+ .caldata_offset = 0x7d1000,
+ .slot = 0,
+ .led_pin = -1,
+ },
+ },
+
+ .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
/*
@@ -2436,6 +2541,7 @@ static const struct board_info __initcon
#ifdef CONFIG_BCM63XX_CPU_6328
&board_96328avng,
&board_963281TAN,
+ &board_dsl_274xb_f1,
#endif
#ifdef CONFIG_BCM63XX_CPU_6338
&board_96338gw,

View file

@ -0,0 +1,70 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1363,6 +1363,59 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -2571,6 +2624,7 @@ static const struct board_info __initcon
&board_ct536_ct5621,
&board_96348A_122,
&board_CPVA502plus,
+ &board_96348W3,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

View file

@ -0,0 +1,138 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -54,6 +54,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;
/*
@@ -2306,6 +2313,113 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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,
@@ -2639,6 +2753,7 @@ static const struct board_info __initcon
&board_nb4_ser_r2,
&board_nb4_fxc_r1,
&board_nb4_fxc_r2,
+ &board_ct6373_1,
&board_HW553,
&board_spw303v,
#endif

View file

@ -0,0 +1,84 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -2561,6 +2561,73 @@ 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 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .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
/*
@@ -2756,6 +2823,7 @@ static const struct board_info __initcon
&board_ct6373_1,
&board_HW553,
&board_spw303v,
+ &board_DVAG3810BN,
#endif
#ifdef CONFIG_BCM63XX_CPU_6368

View file

@ -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>
@@ -53,6 +54,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
@@ -2630,6 +2633,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
*/
@@ -2826,6 +2926,10 @@ static const struct board_info __initcon
&board_DVAG3810BN,
#endif
+#ifdef CONFIG_BCM63XX_CPU_6362
+ &board_nb6,
+#endif
+
#ifdef CONFIG_BCM63XX_CPU_6368
&board_96368mvwg,
&board_96368mvngr,
@@ -2893,6 +2997,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->board_id, BOARDID_LEN) != 0) {
/* else try 128k */

View file

@ -0,0 +1,68 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1031,6 +1031,57 @@ static struct board_info __initdata boar
.has_ehci0 = 1,
};
+static struct board_info __initdata board_FAST2604 = {
+ .name = "F@ST2604",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_pci = 1,
+ .has_ohci0 = 1,
+
+ .has_enet1 = 1,
+ .enet1 = {
+ .has_phy = 1,
+ .phy_id = 0,
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .leds = {
+ {
+ .name = "F@ST2604:green:power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "F@ST2604:red:power",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ {
+ .name = "F@ST2604:red:inet",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "F@ST2604:green:wps",
+ .gpio = 5,
+ .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_rta1025w_16 = {
.name = "RTA1025W_16",
.expected_cpu_id = 0x6348,
@@ -2894,6 +2945,7 @@ static const struct board_info __initcon
&board_96348gw_10,
&board_96348gw_11,
&board_FAST2404,
+ &board_FAST2604,
&board_DV201AMR,
&board_96348gw_a,
&board_rta1025w_16,

Some files were not shown because too many files have changed in this diff Show more