fix SPI register switch and prepare for UDC, thanks to Henk Vergonet (#4783)

SVN-Revision: 14914
This commit is contained in:
Florian Fainelli 2009-03-17 11:28:54 +00:00
parent fb5b85c7c8
commit 32c29f1aaf
9 changed files with 134 additions and 19 deletions

View file

@ -4,6 +4,7 @@ menu "CPU support"
config BCM63XX_CPU_6338 config BCM63XX_CPU_6338
bool "support 6338 CPU" bool "support 6338 CPU"
select USB_ARCH_HAS_OHCI select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_UDC
select USB_OHCI_BIG_ENDIAN_DESC select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO select USB_OHCI_BIG_ENDIAN_MMIO
@ -11,6 +12,7 @@ config BCM63XX_CPU_6348
bool "support 6348 CPU" bool "support 6348 CPU"
select HW_HAS_PCI select HW_HAS_PCI
select USB_ARCH_HAS_OHCI select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_UDC
select USB_OHCI_BIG_ENDIAN_DESC select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO select USB_OHCI_BIG_ENDIAN_MMIO

View file

@ -3,6 +3,7 @@ obj-y += dev-uart.o
obj-y += dev-pcmcia.o obj-y += dev-pcmcia.o
obj-y += dev-usb-ohci.o obj-y += dev-usb-ohci.o
obj-y += dev-usb-ehci.o obj-y += dev-usb-ehci.o
obj-y += dev-usb-udc.o
obj-y += dev-enet.o obj-y += dev-enet.o
obj-y += dev-wdt.o obj-y += dev-wdt.o
obj-y += dev-spi.o obj-y += dev-spi.o

View file

@ -27,6 +27,7 @@
#include <bcm63xx_dev_pcmcia.h> #include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_usb_ohci.h> #include <bcm63xx_dev_usb_ohci.h>
#include <bcm63xx_dev_usb_ehci.h> #include <bcm63xx_dev_usb_ehci.h>
#include <bcm63xx_dev_usb_udc.h>
#include <bcm63xx_dev_spi.h> #include <bcm63xx_dev_spi.h>
#include <board_bcm963xx.h> #include <board_bcm963xx.h>
@ -163,27 +164,23 @@ static struct board_info __initdata board_FAST2404 = {
}; };
static struct board_info __initdata board_DV201AMR = { static struct board_info __initdata board_DV201AMR = {
.name = "DV201AMR", .name = "DV201AMR",
.expected_cpu_id = 0x6348, .expected_cpu_id = 0x6348,
.has_enet0 = 1, .has_pci = 1,
.has_enet1 = 1, .has_ohci0 = 1,
.has_pci = 1, .has_udc0 = 1,
.has_enet0 = 1,
.has_enet1 = 1,
.enet0 = { .enet0 = {
.has_phy = 1, .has_phy = 1,
.use_internal_phy = 1, .use_internal_phy = 1,
}, },
.enet1 = {
.enet1 = { .force_speed_100 = 1,
.force_speed_100 = 1, .force_duplex_full = 1,
.force_duplex_full = 1, },
},
.has_ohci0 = 1,
.has_pccard = 1,
.has_ehci0 = 1,
}; };
static struct board_info __initdata board_96348gw_a = { static struct board_info __initdata board_96348gw_a = {
@ -525,6 +522,8 @@ int __init board_register_devices(void)
if (board.has_ehci0) if (board.has_ehci0)
bcm63xx_ehci_register(); bcm63xx_ehci_register();
if (board.has_udc0)
bcm63xx_udc_register();
/* Generate MAC address for WLAN and /* Generate MAC address for WLAN and
* register our SPROM */ * register our SPROM */
if (!board_get_mac_address(bcm63xx_sprom.il0mac)) { if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {

View file

@ -136,6 +136,26 @@ static struct clk clk_usbh = {
.set = usbh_set, .set = usbh_set,
}; };
/*
* USB slave clock
*/
static void usbs_set(struct clk *clk, int enable)
{
u32 mask;
switch(bcm63xx_get_cpu_id()) {
case BCM6338_CPU_ID: mask = CKCTL_6338_USBS_EN; break;
case BCM6348_CPU_ID: mask = CKCTL_6348_USBS_EN; break;
default:
return;
}
bcm_hwclock_set(mask, enable);
}
static struct clk clk_usbs = {
.set = usbs_set,
};
/* /*
* SPI clock * SPI clock
*/ */
@ -202,6 +222,8 @@ struct clk *clk_get(struct device *dev, const char *id)
return &clk_ephy; return &clk_ephy;
if (!strcmp(id, "usbh")) if (!strcmp(id, "usbh"))
return &clk_usbh; return &clk_usbh;
if (!strcmp(id, "usbs"))
return &clk_usbs;
if (!strcmp(id, "spi")) if (!strcmp(id, "spi"))
return &clk_spi; return &clk_spi;
if (!strcmp(id, "periph")) if (!strcmp(id, "periph"))

View file

@ -37,6 +37,7 @@ static const unsigned long bcm96338_regs_base[] = {
[RSET_PERF] = BCM_6338_PERF_BASE, [RSET_PERF] = BCM_6338_PERF_BASE,
[RSET_TIMER] = BCM_6338_TIMER_BASE, [RSET_TIMER] = BCM_6338_TIMER_BASE,
[RSET_WDT] = BCM_6338_WDT_BASE, [RSET_WDT] = BCM_6338_WDT_BASE,
[RSET_UDC0] = BCM_6338_UDC0_BASE,
[RSET_UART0] = BCM_6338_UART0_BASE, [RSET_UART0] = BCM_6338_UART0_BASE,
[RSET_GPIO] = BCM_6338_GPIO_BASE, [RSET_GPIO] = BCM_6338_GPIO_BASE,
[RSET_SPI] = BCM_6338_SPI_BASE, [RSET_SPI] = BCM_6338_SPI_BASE,
@ -48,6 +49,7 @@ static const int bcm96338_irqs[] = {
[IRQ_SPI] = BCM_6338_SPI_IRQ, [IRQ_SPI] = BCM_6338_SPI_IRQ,
[IRQ_UART0] = BCM_6338_UART0_IRQ, [IRQ_UART0] = BCM_6338_UART0_IRQ,
[IRQ_DSL] = BCM_6338_DSL_IRQ, [IRQ_DSL] = BCM_6338_DSL_IRQ,
[IRQ_UDC0] = BCM_6338_UDC0_IRQ,
[IRQ_ENET0] = BCM_6338_ENET0_IRQ, [IRQ_ENET0] = BCM_6338_ENET0_IRQ,
[IRQ_ENET_PHY] = BCM_6338_ENET_PHY_IRQ, [IRQ_ENET_PHY] = BCM_6338_ENET_PHY_IRQ,
[IRQ_ENET0_RXDMA] = BCM_6338_ENET0_RXDMA_IRQ, [IRQ_ENET0_RXDMA] = BCM_6338_ENET0_RXDMA_IRQ,
@ -83,6 +85,7 @@ static const unsigned long bcm96348_regs_base[] = {
[RSET_OHCI0] = BCM_6348_OHCI0_BASE, [RSET_OHCI0] = BCM_6348_OHCI0_BASE,
[RSET_OHCI_PRIV] = BCM_6348_OHCI_PRIV_BASE, [RSET_OHCI_PRIV] = BCM_6348_OHCI_PRIV_BASE,
[RSET_USBH_PRIV] = BCM_6348_USBH_PRIV_BASE, [RSET_USBH_PRIV] = BCM_6348_USBH_PRIV_BASE,
[RSET_UDC0] = BCM_6348_UDC0_BASE,
[RSET_MPI] = BCM_6348_MPI_BASE, [RSET_MPI] = BCM_6348_MPI_BASE,
[RSET_PCMCIA] = BCM_6348_PCMCIA_BASE, [RSET_PCMCIA] = BCM_6348_PCMCIA_BASE,
[RSET_SDRAM] = BCM_6348_SDRAM_BASE, [RSET_SDRAM] = BCM_6348_SDRAM_BASE,
@ -99,6 +102,7 @@ static const int bcm96348_irqs[] = {
[IRQ_SPI] = BCM_6348_SPI_IRQ, [IRQ_SPI] = BCM_6348_SPI_IRQ,
[IRQ_UART0] = BCM_6348_UART0_IRQ, [IRQ_UART0] = BCM_6348_UART0_IRQ,
[IRQ_DSL] = BCM_6348_DSL_IRQ, [IRQ_DSL] = BCM_6348_DSL_IRQ,
[IRQ_UDC0] = BCM_6348_UDC0_IRQ,
[IRQ_ENET0] = BCM_6348_ENET0_IRQ, [IRQ_ENET0] = BCM_6348_ENET0_IRQ,
[IRQ_ENET1] = BCM_6348_ENET1_IRQ, [IRQ_ENET1] = BCM_6348_ENET1_IRQ,
[IRQ_ENET_PHY] = BCM_6348_ENET_PHY_IRQ, [IRQ_ENET_PHY] = BCM_6348_ENET_PHY_IRQ,

View file

@ -0,0 +1,58 @@
/*
* Copyright (C) 2009 Henk Vergonet <Henk.Vergonet@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <bcm63xx_cpu.h>
static struct resource udc_resources[] = {
{
.start = -1, /* filled at runtime */
.end = -1, /* filled at runtime */
.flags = IORESOURCE_MEM,
},
{
.start = -1, /* filled at runtime */
.flags = IORESOURCE_IRQ,
},
};
static u64 udc_dmamask = ~(u32)0;
static struct platform_device bcm63xx_udc_device = {
.name = "bcm63xx-udc",
.id = 0,
.num_resources = ARRAY_SIZE(udc_resources),
.resource = udc_resources,
.dev = {
.dma_mask = &udc_dmamask,
.coherent_dma_mask = 0xffffffff,
},
};
int __init bcm63xx_udc_register(void)
{
if (!BCMCPU_IS_6338() && !BCMCPU_IS_6348())
return 0;
udc_resources[0].start = bcm63xx_regset_address(RSET_UDC0);
udc_resources[0].end = udc_resources[0].start;
udc_resources[0].end += RSET_UDC_SIZE - 1;
udc_resources[1].start = bcm63xx_get_irq_number(IRQ_UDC0);
return platform_device_register(&bcm63xx_udc_device);
}

View file

@ -4,6 +4,8 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
#include <bcm63xx_regs.h>
/* /*
* Macro to fetch bcm63xx cpu id and revision, should be optimized at * Macro to fetch bcm63xx cpu id and revision, should be optimized at
* compile time if only one CPU support is enabled (idea stolen from * compile time if only one CPU support is enabled (idea stolen from
@ -106,12 +108,18 @@ enum bcm63xx_regs_set {
*/ */
#define BCM_6338_PERF_BASE (0xfffe0000) #define BCM_6338_PERF_BASE (0xfffe0000)
#define BCM_6338_TIMER_BASE (0xfffe0000) #define BCM_6338_BB_BASE (0xfffe0100) /* bus bridge registers */
#define BCM_6338_WDT_BASE (0xfffe001c) #define BCM_6338_TIMER_BASE (0xfffe0200)
#define BCM_6338_WDT_BASE (0xfffe021c)
#define BCM_6338_UART0_BASE (0xfffe0300) #define BCM_6338_UART0_BASE (0xfffe0300)
#define BCM_6338_GPIO_BASE (0xfffe0400) #define BCM_6338_GPIO_BASE (0xfffe0400)
#define BCM_6338_SPI_BASE (0xfffe0c00) #define BCM_6338_SPI_BASE (0xfffe0c00)
#define BCM_6338_DSL_BASE (0xfffe1000)
#define BCM_6338_SAR_BASE (0xfffe2000) #define BCM_6338_SAR_BASE (0xfffe2000)
#define BCM_6338_ENETDMA_BASE (0xfffe2400)
#define BCM_6338_USBDMA_BASE (0xfffe2400)
#define BCM_6338_ENET0_BASE (0xfffe2800)
#define BCM_6338_UDC0_BASE (0xfffe3000) /* USB_CTL_BASE */
#define BCM_6338_MEMC_BASE (0xfffe3100) #define BCM_6338_MEMC_BASE (0xfffe3100)
/* /*
@ -119,12 +127,14 @@ enum bcm63xx_regs_set {
*/ */
#define BCM_6348_DSL_LMEM_BASE (0xfff00000) #define BCM_6348_DSL_LMEM_BASE (0xfff00000)
#define BCM_6348_PERF_BASE (0xfffe0000) #define BCM_6348_PERF_BASE (0xfffe0000)
#define BCM_6348_BB_BASE (0xfffe0100) /* bus bridge registers */
#define BCM_6348_TIMER_BASE (0xfffe0200) #define BCM_6348_TIMER_BASE (0xfffe0200)
#define BCM_6348_WDT_BASE (0xfffe021c) #define BCM_6348_WDT_BASE (0xfffe021c)
#define BCM_6348_UART0_BASE (0xfffe0300) #define BCM_6348_UART0_BASE (0xfffe0300)
#define BCM_6348_GPIO_BASE (0xfffe0400) #define BCM_6348_GPIO_BASE (0xfffe0400)
#define BCM_6348_SPI_BASE (0xfffe0c00) #define BCM_6348_SPI_BASE (0xfffe0c00)
#define BCM_6348_UDC0_BASE (0xfffe1000) #define BCM_6348_UDC0_BASE (0xfffe1000)
#define BCM_6348_USBDMA_BASE (0xfffe1400)
#define BCM_6348_OHCI0_BASE (0xfffe1b00) #define BCM_6348_OHCI0_BASE (0xfffe1b00)
#define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00) #define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00)
#define BCM_6348_USBH_PRIV_BASE (0xdeadbeef) #define BCM_6348_USBH_PRIV_BASE (0xdeadbeef)
@ -132,6 +142,8 @@ enum bcm63xx_regs_set {
#define BCM_6348_PCMCIA_BASE (0xfffe2054) #define BCM_6348_PCMCIA_BASE (0xfffe2054)
#define BCM_6348_SDRAM_REGS_BASE (0xfffe2300) #define BCM_6348_SDRAM_REGS_BASE (0xfffe2300)
#define BCM_6348_DSL_BASE (0xfffe3000) #define BCM_6348_DSL_BASE (0xfffe3000)
#define BCM_6348_SAR_BASE (0xfffe4000)
#define BCM_6348_UBUS_BASE (0xfffe5000)
#define BCM_6348_ENET0_BASE (0xfffe6000) #define BCM_6348_ENET0_BASE (0xfffe6000)
#define BCM_6348_ENET1_BASE (0xfffe6800) #define BCM_6348_ENET1_BASE (0xfffe6800)
#define BCM_6348_ENETDMA_BASE (0xfffe7000) #define BCM_6348_ENETDMA_BASE (0xfffe7000)
@ -351,6 +363,8 @@ switch (reg) {
return SPI_BCM_6348_SPI_CMD; return SPI_BCM_6348_SPI_CMD;
case SPI_INT_MASK_ST: case SPI_INT_MASK_ST:
return SPI_BCM_6348_SPI_MASK_INT_ST; return SPI_BCM_6348_SPI_MASK_INT_ST;
case SPI_INT_MASK:
return SPI_BCM_6348_SPI_INT_MASK;
case SPI_INT_STATUS: case SPI_INT_STATUS:
return SPI_BCM_6348_SPI_INT_STATUS; return SPI_BCM_6348_SPI_INT_STATUS;
case SPI_ST: case SPI_ST:
@ -367,7 +381,7 @@ switch (reg) {
return SPI_BCM_6348_SPI_MSG_CTL; return SPI_BCM_6348_SPI_MSG_CTL;
case SPI_MSG_DATA: case SPI_MSG_DATA:
return SPI_BCM_6348_SPI_MSG_DATA; return SPI_BCM_6348_SPI_MSG_DATA;
case SPI_BCM_6348_SPI_RX_DATA: case SPI_RX_DATA:
return SPI_BCM_6348_SPI_RX_DATA; return SPI_BCM_6348_SPI_RX_DATA;
} }
#endif #endif
@ -411,6 +425,7 @@ enum bcm63xx_irq {
IRQ_UART0, IRQ_UART0,
IRQ_SPI, IRQ_SPI,
IRQ_DSL, IRQ_DSL,
IRQ_UDC0,
IRQ_ENET0, IRQ_ENET0,
IRQ_ENET1, IRQ_ENET1,
IRQ_ENET_PHY, IRQ_ENET_PHY,
@ -434,7 +449,7 @@ enum bcm63xx_irq {
#define BCM_6338_DG_IRQ (IRQ_INTERNAL_BASE + 4) #define BCM_6338_DG_IRQ (IRQ_INTERNAL_BASE + 4)
#define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5) #define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6338_ATM_IRQ (IRQ_INTERNAL_BASE + 6) #define BCM_6338_ATM_IRQ (IRQ_INTERNAL_BASE + 6)
#define BCM_6338_USBS_IRQ (IRQ_INTERNAL_BASE + 7) #define BCM_6338_UDC0_IRQ (IRQ_INTERNAL_BASE + 7)
#define BCM_6338_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) #define BCM_6338_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_6338_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) #define BCM_6338_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_6338_SDRAM_IRQ (IRQ_INTERNAL_BASE + 10) #define BCM_6338_SDRAM_IRQ (IRQ_INTERNAL_BASE + 10)
@ -453,10 +468,17 @@ enum bcm63xx_irq {
#define BCM_6348_SPI_IRQ (IRQ_INTERNAL_BASE + 1) #define BCM_6348_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2) #define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4) #define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
#define BCM_6348_UDC0_IRQ (IRQ_INTERNAL_BASE + 6)
#define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7) #define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7)
#define BCM_6348_ENET0_IRQ (IRQ_INTERNAL_BASE + 8) #define BCM_6348_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9) #define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12) #define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12)
#define BCM_6348_USB_CNTL_RX_DMA (IRQ_INTERNAL_BASE + 14)
#define BCM_6348_USB_CNTL_TX_DMA (IRQ_INTERNAL_BASE + 15)
#define BCM_6348_USB_BULK_RX_DMA (IRQ_INTERNAL_BASE + 16)
#define BCM_6348_USB_BULK_TX_DMA (IRQ_INTERNAL_BASE + 17)
#define BCM_6348_USB_ISO_RX_DMA (IRQ_INTERNAL_BASE + 18)
#define BCM_6348_USB_ISO_TX_DMA (IRQ_INTERNAL_BASE + 19)
#define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20) #define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20)
#define BCM_6348_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 21) #define BCM_6348_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 21)
#define BCM_6348_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 22) #define BCM_6348_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 22)

View file

@ -0,0 +1,6 @@
#ifndef BCM63XX_DEV_USB_UDC_H_
#define BCM63XX_DEV_USB_UDC_H_
int bcm63xx_udc_register(void);
#endif /* BCM63XX_DEV_USB_UDC_H_ */

View file

@ -41,6 +41,7 @@ struct board_info {
unsigned int has_pccard:1; unsigned int has_pccard:1;
unsigned int has_ohci0:1; unsigned int has_ohci0:1;
unsigned int has_ehci0:1; unsigned int has_ehci0:1;
unsigned int has_udc0:1;
/* ethernet config */ /* ethernet config */
struct bcm63xx_enet_platform_data enet0; struct bcm63xx_enet_platform_data enet0;