1
0
Fork 0

Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus

* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (37 commits)
  MIPS: O32: Provide definition of registers ta0 .. ta3.
  MIPS: perf: Add Octeon support for hardware perf.
  MIPS: perf: Add support for 64-bit perf counters.
  MIPS: perf: Reorganize contents of perf support files.
  MIPS: perf: Cleanup formatting in arch/mips/kernel/perf_event.c
  MIPS: Add accessor macros for 64-bit performance counter registers.
  MIPS: Add probes for more Octeon II CPUs.
  MIPS: Add more CPU identifiers for Octeon II CPUs.
  MIPS: XLR, XLS: Add comment for smp setup
  MIPS: JZ4740: GPIO: Check correct IRQ in demux handler
  MIPS: JZ4740: GPIO: Simplify IRQ demuxer
  MIPS: JZ4740: Use generic irq chip
  MIPS: Alchemy: remove all CONFIG_SOC_AU1??? defines
  MIPS: Alchemy: kill au1xxx.h header
  MIPS: Alchemy: clean DMA code of CONFIG_SOC_AU1??? defines
  MIPS, IDE: Alchem, au1xxx-ide: Remove pb1200/db1200 header dep
  MIPS: Alchemy: Redo PCI as platform driver
  MIPS: Alchemy: more base address cleanup
  MIPS: Alchemy: rewrite USB platform setup.
  MIPS: Alchemy: abstract USB block control register access
  ...

Fix up trivial conflicts in:
	arch/mips/alchemy/devboards/db1x00/platform.c
	drivers/ide/Kconfig
	drivers/mmc/host/au1xmmc.c
	drivers/video/Kconfig
	sound/mips/Kconfig
hifive-unleashed-5.1
Linus Torvalds 2011-11-03 13:28:14 -07:00
commit d6748066ad
94 changed files with 3557 additions and 3123 deletions

View File

@ -47,6 +47,8 @@ config MIPS_ALCHEMY
select GENERIC_GPIO select GENERIC_GPIO
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
select SYS_SUPPORTS_ZBOOT select SYS_SUPPORTS_ZBOOT
select USB_ARCH_HAS_OHCI
select USB_ARCH_HAS_EHCI
config AR7 config AR7
bool "Texas Instruments AR7" bool "Texas Instruments AR7"
@ -206,6 +208,7 @@ config MACH_JZ4740
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
select HAVE_PWM select HAVE_PWM
select HAVE_CLK select HAVE_CLK
select GENERIC_IRQ_CHIP
config LANTIQ config LANTIQ
bool "Lantiq based platforms" bool "Lantiq based platforms"
@ -2092,7 +2095,7 @@ config NODES_SHIFT
config HW_PERF_EVENTS config HW_PERF_EVENTS
bool "Enable hardware performance counter support for perf events" bool "Enable hardware performance counter support for perf events"
depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && CPU_MIPS32 depends on PERF_EVENTS && !MIPS_MT_SMTC && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON)
default y default y
help help
Enable hardware performance counter support for perf events. If Enable hardware performance counter support for perf events. If

View File

@ -226,7 +226,7 @@ LDFLAGS += -m $(ld-emul)
ifdef CONFIG_MIPS ifdef CONFIG_MIPS
CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \ CHECKFLAGS += $(shell $(CC) $(KBUILD_CFLAGS) -dM -E -xc /dev/null | \
egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \ egrep -vw '__GNUC_(|MINOR_|PATCHLEVEL_)_' | \
sed -e 's/^\#define /-D/' -e "s/ /='/" -e "s/$$/'/") sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/")
ifdef CONFIG_64BIT ifdef CONFIG_64BIT
CHECKFLAGS += -m64 CHECKFLAGS += -m64
endif endif
@ -295,7 +295,9 @@ endif
install: install:
$(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) $(Q)install -D -m 755 vmlinux $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE)
ifdef CONFIG_SYS_SUPPORTS_ZBOOT
$(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE) $(Q)install -D -m 755 vmlinuz $(INSTALL_PATH)/vmlinuz-$(KERNELRELEASE)
endif
$(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE) $(Q)install -D -m 644 .config $(INSTALL_PATH)/config-$(KERNELRELEASE)
$(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE) $(Q)install -D -m 644 System.map $(INSTALL_PATH)/System.map-$(KERNELRELEASE)

View File

@ -18,20 +18,20 @@ config MIPS_MTX1
bool "4G Systems MTX-1 board" bool "4G Systems MTX-1 board"
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select SOC_AU1500 select ALCHEMY_GPIOINT_AU1000
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
config MIPS_BOSPORUS config MIPS_BOSPORUS
bool "Alchemy Bosporus board" bool "Alchemy Bosporus board"
select SOC_AU1500 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
config MIPS_DB1000 config MIPS_DB1000
bool "Alchemy DB1000 board" bool "Alchemy DB1000 board"
select SOC_AU1000 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
@ -39,14 +39,14 @@ config MIPS_DB1000
config MIPS_DB1100 config MIPS_DB1100
bool "Alchemy DB1100 board" bool "Alchemy DB1100 board"
select SOC_AU1100 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
config MIPS_DB1200 config MIPS_DB1200
bool "Alchemy DB1200 board" bool "Alchemy DB1200 board"
select SOC_AU1200 select ALCHEMY_GPIOINT_AU1000
select DMA_COHERENT select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
@ -54,7 +54,7 @@ config MIPS_DB1200
config MIPS_DB1500 config MIPS_DB1500
bool "Alchemy DB1500 board" bool "Alchemy DB1500 board"
select SOC_AU1500 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select MIPS_DISABLE_OBSOLETE_IDE select MIPS_DISABLE_OBSOLETE_IDE
@ -64,7 +64,7 @@ config MIPS_DB1500
config MIPS_DB1550 config MIPS_DB1550
bool "Alchemy DB1550 board" bool "Alchemy DB1550 board"
select SOC_AU1550 select ALCHEMY_GPIOINT_AU1000
select HW_HAS_PCI select HW_HAS_PCI
select DMA_NONCOHERENT select DMA_NONCOHERENT
select MIPS_DISABLE_OBSOLETE_IDE select MIPS_DISABLE_OBSOLETE_IDE
@ -74,13 +74,13 @@ config MIPS_DB1550
config MIPS_MIRAGE config MIPS_MIRAGE
bool "Alchemy Mirage board" bool "Alchemy Mirage board"
select DMA_NONCOHERENT select DMA_NONCOHERENT
select SOC_AU1500 select ALCHEMY_GPIOINT_AU1000
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
config MIPS_PB1000 config MIPS_PB1000
bool "Alchemy PB1000 board" bool "Alchemy PB1000 board"
select SOC_AU1000 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select SWAP_IO_SPACE select SWAP_IO_SPACE
@ -89,7 +89,7 @@ config MIPS_PB1000
config MIPS_PB1100 config MIPS_PB1100
bool "Alchemy PB1100 board" bool "Alchemy PB1100 board"
select SOC_AU1100 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select SWAP_IO_SPACE select SWAP_IO_SPACE
@ -98,7 +98,7 @@ config MIPS_PB1100
config MIPS_PB1200 config MIPS_PB1200
bool "Alchemy PB1200 board" bool "Alchemy PB1200 board"
select SOC_AU1200 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select MIPS_DISABLE_OBSOLETE_IDE select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
@ -106,7 +106,7 @@ config MIPS_PB1200
config MIPS_PB1500 config MIPS_PB1500
bool "Alchemy PB1500 board" bool "Alchemy PB1500 board"
select SOC_AU1500 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
@ -114,7 +114,7 @@ config MIPS_PB1500
config MIPS_PB1550 config MIPS_PB1550
bool "Alchemy PB1550 board" bool "Alchemy PB1550 board"
select SOC_AU1550 select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT select DMA_NONCOHERENT
select HW_HAS_PCI select HW_HAS_PCI
select MIPS_DISABLE_OBSOLETE_IDE select MIPS_DISABLE_OBSOLETE_IDE
@ -124,13 +124,13 @@ config MIPS_PB1550
config MIPS_XXS1500 config MIPS_XXS1500
bool "MyCable XXS1500 board" bool "MyCable XXS1500 board"
select DMA_NONCOHERENT select DMA_NONCOHERENT
select SOC_AU1500 select ALCHEMY_GPIOINT_AU1000
select SYS_SUPPORTS_LITTLE_ENDIAN select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
config MIPS_GPR config MIPS_GPR
bool "Trapeze ITS GPR board" bool "Trapeze ITS GPR board"
select SOC_AU1550 select ALCHEMY_GPIOINT_AU1000
select HW_HAS_PCI select HW_HAS_PCI
select DMA_NONCOHERENT select DMA_NONCOHERENT
select MIPS_DISABLE_OBSOLETE_IDE select MIPS_DISABLE_OBSOLETE_IDE
@ -138,23 +138,3 @@ config MIPS_GPR
select SYS_HAS_EARLY_PRINTK select SYS_HAS_EARLY_PRINTK
endchoice endchoice
config SOC_AU1000
bool
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1100
bool
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1500
bool
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1550
bool
select ALCHEMY_GPIOINT_AU1000
config SOC_AU1200
bool
select ALCHEMY_GPIOINT_AU1000

View File

@ -12,9 +12,5 @@ obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o
# optional gpiolib support # optional gpiolib support
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
ifeq ($(CONFIG_GPIOLIB),y) obj-$(CONFIG_GPIOLIB) += gpiolib.o
obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += gpiolib-au1000.o
endif
endif endif
obj-$(CONFIG_PCI) += pci.o

View File

@ -40,8 +40,6 @@
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h> #include <asm/mach-au1x00/au1xxx_dbdma.h>
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
/* /*
* The Descriptor Based DMA supports up to 16 channels. * The Descriptor Based DMA supports up to 16 channels.
* *
@ -62,120 +60,96 @@ static dbdma_global_t *dbdma_gptr =
(dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR); (dbdma_global_t *)KSEG1ADDR(AU1550_DBDMA_CONF_PHYS_ADDR);
static int dbdma_initialized; static int dbdma_initialized;
static dbdev_tab_t dbdev_tab[] = { static dbdev_tab_t *dbdev_tab;
#ifdef CONFIG_SOC_AU1550
static dbdev_tab_t au1550_dbdev_tab[] __initdata = {
/* UARTS */ /* UARTS */
{ DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 }, { AU1550_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
{ DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 }, { AU1550_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
{ DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 }, { AU1550_DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x11400004, 0, 0 },
{ DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 }, { AU1550_DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x11400000, 0, 0 },
/* EXT DMA */ /* EXT DMA */
{ DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 }, { AU1550_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 }, { AU1550_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 }, { AU1550_DSCR_CMD0_DMA_REQ2, 0, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 }, { AU1550_DSCR_CMD0_DMA_REQ3, 0, 0, 0, 0x00000000, 0, 0 },
/* USB DEV */ /* USB DEV */
{ DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 }, { AU1550_DSCR_CMD0_USBDEV_RX0, DEV_FLAGS_IN, 4, 8, 0x10200000, 0, 0 },
{ DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 }, { AU1550_DSCR_CMD0_USBDEV_TX0, DEV_FLAGS_OUT, 4, 8, 0x10200004, 0, 0 },
{ DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 }, { AU1550_DSCR_CMD0_USBDEV_TX1, DEV_FLAGS_OUT, 4, 8, 0x10200008, 0, 0 },
{ DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 }, { AU1550_DSCR_CMD0_USBDEV_TX2, DEV_FLAGS_OUT, 4, 8, 0x1020000c, 0, 0 },
{ DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 }, { AU1550_DSCR_CMD0_USBDEV_RX3, DEV_FLAGS_IN, 4, 8, 0x10200010, 0, 0 },
{ DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 }, { AU1550_DSCR_CMD0_USBDEV_RX4, DEV_FLAGS_IN, 4, 8, 0x10200014, 0, 0 },
/* PSC 0 */ /* PSCs */
{ DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 }, { AU1550_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 0, 0x11a0001c, 0, 0 },
{ DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 }, { AU1550_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 0, 0x11a0001c, 0, 0 },
{ AU1550_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 },
{ AU1550_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
{ AU1550_DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 },
{ AU1550_DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 },
{ AU1550_DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 },
{ AU1550_DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 },
/* PSC 1 */ { AU1550_DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */
{ DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 0, 0x11b0001c, 0, 0 }, { AU1550_DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */
{ DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 0, 0x11b0001c, 0, 0 },
/* PSC 2 */
{ DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 0, 0x10a0001c, 0, 0 },
{ DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 0, 0x10a0001c, 0, 0 },
/* PSC 3 */
{ DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 0, 0x10b0001c, 0, 0 },
{ DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 0, 0x10b0001c, 0, 0 },
{ DSCR_CMD0_PCI_WRITE, 0, 0, 0, 0x00000000, 0, 0 }, /* PCI */
{ DSCR_CMD0_NAND_FLASH, 0, 0, 0, 0x00000000, 0, 0 }, /* NAND */
/* MAC 0 */ /* MAC 0 */
{ DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, { AU1550_DSCR_CMD0_MAC0_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, { AU1550_DSCR_CMD0_MAC0_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
/* MAC 1 */ /* MAC 1 */
{ DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 }, { AU1550_DSCR_CMD0_MAC1_RX, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 }, { AU1550_DSCR_CMD0_MAC1_TX, DEV_FLAGS_OUT, 0, 0, 0x00000000, 0, 0 },
#endif /* CONFIG_SOC_AU1550 */
#ifdef CONFIG_SOC_AU1200
{ DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
{ DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
{ DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 },
{ DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 },
{ DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
{ DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
{ DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 },
{ DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
{ DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
{ DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
{ DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 },
{ DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 },
{ DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 },
{ DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 },
{ DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
{ DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
{ DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
{ DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
#endif /* CONFIG_SOC_AU1200 */
{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 }, { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
/* Provide 16 user definable device types */
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
{ ~0, 0, 0, 0, 0, 0, 0 },
}; };
#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab) static dbdev_tab_t au1200_dbdev_tab[] __initdata = {
{ AU1200_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x11100004, 0, 0 },
{ AU1200_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x11100000, 0, 0 },
{ AU1200_DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x11200004, 0, 0 },
{ AU1200_DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x11200000, 0, 0 },
{ AU1200_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_MAE_BE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_MAE_FE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_MAE_BOTH, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
{ AU1200_DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
{ AU1200_DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 4, 8, 0x10680000, 0, 0 },
{ AU1200_DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 4, 8, 0x10680004, 0, 0 },
{ AU1200_DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
{ AU1200_DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
{ AU1200_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x11a0001c, 0, 0 },
{ AU1200_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x11a0001c, 0, 0 },
{ AU1200_DSCR_CMD0_PSC0_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x11b0001c, 0, 0 },
{ AU1200_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x11b0001c, 0, 0 },
{ AU1200_DSCR_CMD0_PSC1_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_CIM_RXA, DEV_FLAGS_IN, 0, 32, 0x14004020, 0, 0 },
{ AU1200_DSCR_CMD0_CIM_RXB, DEV_FLAGS_IN, 0, 32, 0x14004040, 0, 0 },
{ AU1200_DSCR_CMD0_CIM_RXC, DEV_FLAGS_IN, 0, 32, 0x14004060, 0, 0 },
{ AU1200_DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ AU1200_DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
};
/* 32 predefined plus 32 custom */
#define DBDEV_TAB_SIZE 64
static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS]; static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
@ -1028,38 +1002,43 @@ static struct syscore_ops alchemy_dbdma_syscore_ops = {
.resume = alchemy_dbdma_resume, .resume = alchemy_dbdma_resume,
}; };
static int __init au1xxx_dbdma_init(void) static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable)
{ {
int irq_nr, ret; int ret;
dbdev_tab = kzalloc(sizeof(dbdev_tab_t) * DBDEV_TAB_SIZE, GFP_KERNEL);
if (!dbdev_tab)
return -ENOMEM;
memcpy(dbdev_tab, idtable, 32 * sizeof(dbdev_tab_t));
for (ret = 32; ret < DBDEV_TAB_SIZE; ret++)
dbdev_tab[ret].dev_id = ~0;
dbdma_gptr->ddma_config = 0; dbdma_gptr->ddma_config = 0;
dbdma_gptr->ddma_throttle = 0; dbdma_gptr->ddma_throttle = 0;
dbdma_gptr->ddma_inten = 0xffff; dbdma_gptr->ddma_inten = 0xffff;
au_sync(); au_sync();
switch (alchemy_get_cputype()) { ret = request_irq(irq, dbdma_interrupt, IRQF_DISABLED, "dbdma",
case ALCHEMY_CPU_AU1550: (void *)dbdma_gptr);
irq_nr = AU1550_DDMA_INT;
break;
case ALCHEMY_CPU_AU1200:
irq_nr = AU1200_DDMA_INT;
break;
default:
return -ENODEV;
}
ret = request_irq(irq_nr, dbdma_interrupt, IRQF_DISABLED,
"Au1xxx dbdma", (void *)dbdma_gptr);
if (ret) if (ret)
printk(KERN_ERR "Cannot grab DBDMA interrupt!\n"); printk(KERN_ERR "Cannot grab DBDMA interrupt!\n");
else { else {
dbdma_initialized = 1; dbdma_initialized = 1;
printk(KERN_INFO "Alchemy DBDMA initialized\n");
register_syscore_ops(&alchemy_dbdma_syscore_ops); register_syscore_ops(&alchemy_dbdma_syscore_ops);
} }
return ret; return ret;
} }
subsys_initcall(au1xxx_dbdma_init);
#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */ static int __init alchemy_dbdma_init(void)
{
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1550:
return dbdma_setup(AU1550_DDMA_INT, au1550_dbdev_tab);
case ALCHEMY_CPU_AU1200:
return dbdma_setup(AU1200_DDMA_INT, au1200_dbdev_tab);
}
return 0;
}
subsys_initcall(alchemy_dbdma_init);

View File

@ -40,8 +40,6 @@
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h> #include <asm/mach-au1x00/au1000_dma.h>
#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
defined(CONFIG_SOC_AU1100)
/* /*
* A note on resource allocation: * A note on resource allocation:
* *
@ -88,12 +86,12 @@ static const struct dma_dev {
{ AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */ { AU1000_AC97_PHYS_ADDR + 0x08, DMA_DW16 | DMA_DR }, /* AC97 RX c */
{ AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */ { AU1000_UART3_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* UART3_TX */
{ AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */ { AU1000_UART3_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* UART3_RX */
{ AU1000_USBD_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */ { AU1000_USB_UDC_PHYS_ADDR + 0x00, DMA_DW8 | DMA_NC | DMA_DR }, /* EP0RD */
{ AU1000_USBD_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */ { AU1000_USB_UDC_PHYS_ADDR + 0x04, DMA_DW8 | DMA_NC }, /* EP0WR */
{ AU1000_USBD_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */ { AU1000_USB_UDC_PHYS_ADDR + 0x08, DMA_DW8 | DMA_NC }, /* EP2WR */
{ AU1000_USBD_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */ { AU1000_USB_UDC_PHYS_ADDR + 0x0c, DMA_DW8 | DMA_NC }, /* EP3WR */
{ AU1000_USBD_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */ { AU1000_USB_UDC_PHYS_ADDR + 0x10, DMA_DW8 | DMA_NC | DMA_DR }, /* EP4RD */
{ AU1000_USBD_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */ { AU1000_USB_UDC_PHYS_ADDR + 0x14, DMA_DW8 | DMA_NC | DMA_DR }, /* EP5RD */
/* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */ /* on Au1500, these 2 are DMA_REQ2/3 (GPIO208/209) instead! */
{ AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */ { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC}, /* I2S TX */
{ AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */ { AU1000_I2S_PHYS_ADDR + 0x00, DMA_DW32 | DMA_NC | DMA_DR}, /* I2S RX */
@ -170,13 +168,13 @@ int request_au1000_dma(int dev_id, const char *dev_str,
const struct dma_dev *dev; const struct dma_dev *dev;
int i, ret; int i, ret;
#if defined(CONFIG_SOC_AU1100) if (alchemy_get_cputype() == ALCHEMY_CPU_AU1100) {
if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2)) if (dev_id < 0 || dev_id >= (DMA_NUM_DEV + DMA_NUM_DEV_BANK2))
return -EINVAL; return -EINVAL;
#else } else {
if (dev_id < 0 || dev_id >= DMA_NUM_DEV) if (dev_id < 0 || dev_id >= DMA_NUM_DEV)
return -EINVAL; return -EINVAL;
#endif }
for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
if (au1000_dma_table[i].dev_id < 0) if (au1000_dma_table[i].dev_id < 0)
@ -239,30 +237,28 @@ EXPORT_SYMBOL(free_au1000_dma);
static int __init au1000_dma_init(void) static int __init au1000_dma_init(void)
{ {
int base, i; int base, i;
switch (alchemy_get_cputype()) { switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000: case ALCHEMY_CPU_AU1000:
base = AU1000_DMA_INT_BASE; base = AU1000_DMA_INT_BASE;
break; break;
case ALCHEMY_CPU_AU1500: case ALCHEMY_CPU_AU1500:
base = AU1500_DMA_INT_BASE; base = AU1500_DMA_INT_BASE;
break; break;
case ALCHEMY_CPU_AU1100: case ALCHEMY_CPU_AU1100:
base = AU1100_DMA_INT_BASE; base = AU1100_DMA_INT_BASE;
break; break;
default: default:
goto out; goto out;
} }
for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++) for (i = 0; i < NUM_AU1000_DMA_CHANNELS; i++)
au1000_dma_table[i].irq = base + i; au1000_dma_table[i].irq = base + i;
printk(KERN_INFO "Alchemy DMA initialized\n"); printk(KERN_INFO "Alchemy DMA initialized\n");
out: out:
return 0; return 0;
} }
arch_initcall(au1000_dma_init); arch_initcall(au1000_dma_init);
#endif /* AU1000 AU1500 AU1100 */

View File

@ -1,6 +1,6 @@
/* /*
* Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org> * Copyright (C) 2007-2009, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
* GPIOLIB support for Au1000, Au1500, Au1100, Au1550 and Au12x0. * GPIOLIB support for Alchemy chips.
* *
* This program is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU General Public License as published by the
@ -23,18 +23,18 @@
* 675 Mass Ave, Cambridge, MA 02139, USA. * 675 Mass Ave, Cambridge, MA 02139, USA.
* *
* Notes : * Notes :
* au1000 SoC have only one GPIO block : GPIO1 * This file must ONLY be built when CONFIG_GPIOLIB=y and
* Au1100, Au15x0, Au12x0 have a second one : GPIO2 * CONFIG_ALCHEMY_GPIO_INDIRECT=n, otherwise compilation will fail!
* au1000 SoC have only one GPIO block : GPIO1
* Au1100, Au15x0, Au12x0 have a second one : GPIO2
*/ */
#include <linux/init.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/platform_device.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <asm/mach-au1x00/gpio-au1000.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/gpio.h>
static int gpio2_get(struct gpio_chip *chip, unsigned offset) static int gpio2_get(struct gpio_chip *chip, unsigned offset)
{ {
@ -115,12 +115,19 @@ struct gpio_chip alchemy_gpio_chip[] = {
}, },
}; };
static int __init alchemy_gpiolib_init(void) static int __init alchemy_gpiochip_init(void)
{ {
gpiochip_add(&alchemy_gpio_chip[0]); int ret = 0;
if (alchemy_get_cputype() != ALCHEMY_CPU_AU1000)
gpiochip_add(&alchemy_gpio_chip[1]);
return 0; switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
ret = gpiochip_add(&alchemy_gpio_chip[0]);
break;
case ALCHEMY_CPU_AU1500...ALCHEMY_CPU_AU1200:
ret = gpiochip_add(&alchemy_gpio_chip[0]);
ret |= gpiochip_add(&alchemy_gpio_chip[1]);
break;
}
return ret;
} }
arch_initcall(alchemy_gpiolib_init); arch_initcall(alchemy_gpiochip_init);

View File

@ -1,104 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Alchemy/AMD Au1x00 PCI support.
*
* Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* Copyright (C) 2004 by Ralf Baechle (ralf@linux-mips.org)
*
* Support for all devices (greater than 16) added by David Gathright.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/mach-au1x00/au1000.h>
/* TBD */
static struct resource pci_io_resource = {
.start = PCI_IO_START,
.end = PCI_IO_END,
.name = "PCI IO space",
.flags = IORESOURCE_IO
};
static struct resource pci_mem_resource = {
.start = PCI_MEM_START,
.end = PCI_MEM_END,
.name = "PCI memory space",
.flags = IORESOURCE_MEM
};
extern struct pci_ops au1x_pci_ops;
static struct pci_controller au1x_controller = {
.pci_ops = &au1x_pci_ops,
.io_resource = &pci_io_resource,
.mem_resource = &pci_mem_resource,
};
#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
static unsigned long virt_io_addr;
#endif
static int __init au1x_pci_setup(void)
{
extern void au1x_pci_cfg_init(void);
#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
virt_io_addr = (unsigned long)ioremap(Au1500_PCI_IO_START,
Au1500_PCI_IO_END - Au1500_PCI_IO_START + 1);
if (!virt_io_addr) {
printk(KERN_ERR "Unable to ioremap pci space\n");
return 1;
}
au1x_controller.io_map_base = virt_io_addr;
#ifdef CONFIG_DMA_NONCOHERENT
{
/*
* Set the NC bit in controller for Au1500 pre-AC silicon
*/
u32 prid = read_c0_prid();
if ((prid & 0xFF000000) == 0x01000000 && prid < 0x01030202) {
au_writel((1 << 16) | au_readl(Au1500_PCI_CFG),
Au1500_PCI_CFG);
printk(KERN_INFO "Non-coherent PCI accesses enabled\n");
}
}
#endif
set_io_port_base(virt_io_addr);
#endif
au1x_pci_cfg_init();
register_pci_controller(&au1x_controller);
return 0;
}
arch_initcall(au1x_pci_setup);

View File

@ -18,7 +18,7 @@
#include <linux/serial_8250.h> #include <linux/serial_8250.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/mach-au1x00/au1xxx.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h> #include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1100_mmc.h> #include <asm/mach-au1x00/au1100_mmc.h>
#include <asm/mach-au1x00/au1xxx_eth.h> #include <asm/mach-au1x00/au1xxx_eth.h>
@ -111,270 +111,87 @@ static void __init alchemy_setup_uarts(int ctype)
printk(KERN_INFO "Alchemy: failed to register UARTs\n"); printk(KERN_INFO "Alchemy: failed to register UARTs\n");
} }
/* OHCI (USB full speed host controller) */
static struct resource au1xxx_usb_ohci_resources[] = { /* The dmamask must be set for OHCI/EHCI to work */
[0] = { static u64 alchemy_ohci_dmamask = DMA_BIT_MASK(32);
.start = USB_OHCI_BASE, static u64 __maybe_unused alchemy_ehci_dmamask = DMA_BIT_MASK(32);
.end = USB_OHCI_BASE + USB_OHCI_LEN - 1,
.flags = IORESOURCE_MEM, static unsigned long alchemy_ohci_data[][2] __initdata = {
}, [ALCHEMY_CPU_AU1000] = { AU1000_USB_OHCI_PHYS_ADDR, AU1000_USB_HOST_INT },
[1] = { [ALCHEMY_CPU_AU1500] = { AU1000_USB_OHCI_PHYS_ADDR, AU1500_USB_HOST_INT },
.start = FOR_PLATFORM_C_USB_HOST_INT, [ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT },
.end = FOR_PLATFORM_C_USB_HOST_INT, [ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT },
.flags = IORESOURCE_IRQ, [ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT },
},
}; };
/* The dmamask must be set for OHCI to work */ static unsigned long alchemy_ehci_data[][2] __initdata = {
static u64 ohci_dmamask = DMA_BIT_MASK(32); [ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT },
static struct platform_device au1xxx_usb_ohci_device = {
.name = "au1xxx-ohci",
.id = 0,
.dev = {
.dma_mask = &ohci_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1xxx_usb_ohci_resources),
.resource = au1xxx_usb_ohci_resources,
}; };
/*** AU1100 LCD controller ***/ static int __init _new_usbres(struct resource **r, struct platform_device **d)
{
#ifdef CONFIG_FB_AU1100 *r = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
static struct resource au1100_lcd_resources[] = { if (!*r)
[0] = { return -ENOMEM;
.start = LCD_PHYS_ADDR, *d = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
.end = LCD_PHYS_ADDR + 0x800 - 1, if (!*d) {
.flags = IORESOURCE_MEM, kfree(*r);
}, return -ENOMEM;
[1] = {
.start = AU1100_LCD_INT,
.end = AU1100_LCD_INT,
.flags = IORESOURCE_IRQ,
} }
};
static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32); (*d)->dev.coherent_dma_mask = DMA_BIT_MASK(32);
(*d)->num_resources = 2;
(*d)->resource = *r;
static struct platform_device au1100_lcd_device = { return 0;
.name = "au1100-lcd", }
.id = 0,
.dev = {
.dma_mask = &au1100_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1100_lcd_resources),
.resource = au1100_lcd_resources,
};
#endif
#ifdef CONFIG_SOC_AU1200 static void __init alchemy_setup_usb(int ctype)
/* EHCI (USB high speed host controller) */ {
static struct resource au1xxx_usb_ehci_resources[] = { struct resource *res;
[0] = { struct platform_device *pdev;
.start = USB_EHCI_BASE,
.end = USB_EHCI_BASE + USB_EHCI_LEN - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_USB_INT,
.end = AU1200_USB_INT,
.flags = IORESOURCE_IRQ,
},
};
static u64 ehci_dmamask = DMA_BIT_MASK(32); /* setup OHCI0. Every variant has one */
if (_new_usbres(&res, &pdev))
return;
static struct platform_device au1xxx_usb_ehci_device = { res[0].start = alchemy_ohci_data[ctype][0];
.name = "au1xxx-ehci", res[0].end = res[0].start + 0x100 - 1;
.id = 0, res[0].flags = IORESOURCE_MEM;
.dev = { res[1].start = alchemy_ohci_data[ctype][1];
.dma_mask = &ehci_dmamask, res[1].end = res[1].start;
.coherent_dma_mask = DMA_BIT_MASK(32), res[1].flags = IORESOURCE_IRQ;
}, pdev->name = "au1xxx-ohci";
.num_resources = ARRAY_SIZE(au1xxx_usb_ehci_resources), pdev->id = 0;
.resource = au1xxx_usb_ehci_resources, pdev->dev.dma_mask = &alchemy_ohci_dmamask;
};
/* Au1200 UDC (USB gadget controller) */ if (platform_device_register(pdev))
static struct resource au1xxx_usb_gdt_resources[] = { printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
[0] = {
.start = USB_UDC_BASE,
.end = USB_UDC_BASE + USB_UDC_LEN - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_USB_INT,
.end = AU1200_USB_INT,
.flags = IORESOURCE_IRQ,
},
};
static u64 udc_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1xxx_usb_gdt_device = { /* setup EHCI0: Au1200 */
.name = "au1xxx-udc", if (ctype == ALCHEMY_CPU_AU1200) {
.id = 0, if (_new_usbres(&res, &pdev))
.dev = { return;
.dma_mask = &udc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1xxx_usb_gdt_resources),
.resource = au1xxx_usb_gdt_resources,
};
/* Au1200 UOC (USB OTG controller) */ res[0].start = alchemy_ehci_data[ctype][0];
static struct resource au1xxx_usb_otg_resources[] = { res[0].end = res[0].start + 0x100 - 1;
[0] = { res[0].flags = IORESOURCE_MEM;
.start = USB_UOC_BASE, res[1].start = alchemy_ehci_data[ctype][1];
.end = USB_UOC_BASE + USB_UOC_LEN - 1, res[1].end = res[1].start;
.flags = IORESOURCE_MEM, res[1].flags = IORESOURCE_IRQ;
}, pdev->name = "au1xxx-ehci";
[1] = { pdev->id = 0;
.start = AU1200_USB_INT, pdev->dev.dma_mask = &alchemy_ehci_dmamask;
.end = AU1200_USB_INT,
.flags = IORESOURCE_IRQ,
},
};
static u64 uoc_dmamask = DMA_BIT_MASK(32); if (platform_device_register(pdev))
printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
static struct platform_device au1xxx_usb_otg_device = {
.name = "au1xxx-uoc",
.id = 0,
.dev = {
.dma_mask = &uoc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1xxx_usb_otg_resources),
.resource = au1xxx_usb_otg_resources,
};
static struct resource au1200_lcd_resources[] = {
[0] = {
.start = LCD_PHYS_ADDR,
.end = LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_LCD_INT,
.end = AU1200_LCD_INT,
.flags = IORESOURCE_IRQ,
} }
}; }
static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1200_lcd_device = {
.name = "au1200-lcd",
.id = 0,
.dev = {
.dma_mask = &au1200_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1200_lcd_resources),
.resource = au1200_lcd_resources,
};
static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
extern struct au1xmmc_platform_data au1xmmc_platdata[2];
static struct resource au1200_mmc0_resources[] = {
[0] = {
.start = AU1100_SD0_PHYS_ADDR,
.end = AU1100_SD0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_SD_INT,
.end = AU1200_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = DSCR_CMD0_SDMS_TX0,
.end = DSCR_CMD0_SDMS_TX0,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DSCR_CMD0_SDMS_RX0,
.end = DSCR_CMD0_SDMS_RX0,
.flags = IORESOURCE_DMA,
}
};
static struct platform_device au1200_mmc0_device = {
.name = "au1xxx-mmc",
.id = 0,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &au1xmmc_platdata[0],
},
.num_resources = ARRAY_SIZE(au1200_mmc0_resources),
.resource = au1200_mmc0_resources,
};
#ifndef CONFIG_MIPS_DB1200
static struct resource au1200_mmc1_resources[] = {
[0] = {
.start = AU1100_SD1_PHYS_ADDR,
.end = AU1100_SD1_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_SD_INT,
.end = AU1200_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = DSCR_CMD0_SDMS_TX1,
.end = DSCR_CMD0_SDMS_TX1,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = DSCR_CMD0_SDMS_RX1,
.end = DSCR_CMD0_SDMS_RX1,
.flags = IORESOURCE_DMA,
}
};
static struct platform_device au1200_mmc1_device = {
.name = "au1xxx-mmc",
.id = 1,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &au1xmmc_platdata[1],
},
.num_resources = ARRAY_SIZE(au1200_mmc1_resources),
.resource = au1200_mmc1_resources,
};
#endif /* #ifndef CONFIG_MIPS_DB1200 */
#endif /* #ifdef CONFIG_SOC_AU1200 */
/* All Alchemy demoboards with I2C have this #define in their headers */
#ifdef SMBUS_PSC_BASE
static struct resource pbdb_smbus_resources[] = {
{
.start = CPHYSADDR(SMBUS_PSC_BASE),
.end = CPHYSADDR(SMBUS_PSC_BASE + 0xfffff),
.flags = IORESOURCE_MEM,
},
};
static struct platform_device pbdb_smbus_device = {
.name = "au1xpsc_smbus",
.id = 0, /* bus number */
.num_resources = ARRAY_SIZE(pbdb_smbus_resources),
.resource = pbdb_smbus_resources,
};
#endif
/* Macro to help defining the Ethernet MAC resources */ /* Macro to help defining the Ethernet MAC resources */
#define MAC_RES_COUNT 3 /* MAC regs base, MAC enable reg, MAC INT */ #define MAC_RES_COUNT 4 /* MAC regs, MAC en, MAC INT, MACDMA regs */
#define MAC_RES(_base, _enable, _irq) \ #define MAC_RES(_base, _enable, _irq, _macdma) \
{ \ { \
.start = _base, \ .start = _base, \
.end = _base + 0xffff, \ .end = _base + 0xffff, \
@ -389,28 +206,37 @@ static struct platform_device pbdb_smbus_device = {
.start = _irq, \ .start = _irq, \
.end = _irq, \ .end = _irq, \
.flags = IORESOURCE_IRQ \ .flags = IORESOURCE_IRQ \
}, \
{ \
.start = _macdma, \
.end = _macdma + 0x1ff, \
.flags = IORESOURCE_MEM, \
} }
static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = { static struct resource au1xxx_eth0_resources[][MAC_RES_COUNT] __initdata = {
[ALCHEMY_CPU_AU1000] = { [ALCHEMY_CPU_AU1000] = {
MAC_RES(AU1000_MAC0_PHYS_ADDR, MAC_RES(AU1000_MAC0_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR, AU1000_MACEN_PHYS_ADDR,
AU1000_MAC0_DMA_INT) AU1000_MAC0_DMA_INT,
AU1000_MACDMA0_PHYS_ADDR)
}, },
[ALCHEMY_CPU_AU1500] = { [ALCHEMY_CPU_AU1500] = {
MAC_RES(AU1500_MAC0_PHYS_ADDR, MAC_RES(AU1500_MAC0_PHYS_ADDR,
AU1500_MACEN_PHYS_ADDR, AU1500_MACEN_PHYS_ADDR,
AU1500_MAC0_DMA_INT) AU1500_MAC0_DMA_INT,
AU1000_MACDMA0_PHYS_ADDR)
}, },
[ALCHEMY_CPU_AU1100] = { [ALCHEMY_CPU_AU1100] = {
MAC_RES(AU1000_MAC0_PHYS_ADDR, MAC_RES(AU1000_MAC0_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR, AU1000_MACEN_PHYS_ADDR,
AU1100_MAC0_DMA_INT) AU1100_MAC0_DMA_INT,
AU1000_MACDMA0_PHYS_ADDR)
}, },
[ALCHEMY_CPU_AU1550] = { [ALCHEMY_CPU_AU1550] = {
MAC_RES(AU1000_MAC0_PHYS_ADDR, MAC_RES(AU1000_MAC0_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR, AU1000_MACEN_PHYS_ADDR,
AU1550_MAC0_DMA_INT) AU1550_MAC0_DMA_INT,
AU1000_MACDMA0_PHYS_ADDR)
}, },
}; };
@ -429,17 +255,20 @@ static struct resource au1xxx_eth1_resources[][MAC_RES_COUNT] __initdata = {
[ALCHEMY_CPU_AU1000] = { [ALCHEMY_CPU_AU1000] = {
MAC_RES(AU1000_MAC1_PHYS_ADDR, MAC_RES(AU1000_MAC1_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR + 4, AU1000_MACEN_PHYS_ADDR + 4,
AU1000_MAC1_DMA_INT) AU1000_MAC1_DMA_INT,
AU1000_MACDMA1_PHYS_ADDR)
}, },
[ALCHEMY_CPU_AU1500] = { [ALCHEMY_CPU_AU1500] = {
MAC_RES(AU1500_MAC1_PHYS_ADDR, MAC_RES(AU1500_MAC1_PHYS_ADDR,
AU1500_MACEN_PHYS_ADDR + 4, AU1500_MACEN_PHYS_ADDR + 4,
AU1500_MAC1_DMA_INT) AU1500_MAC1_DMA_INT,
AU1000_MACDMA1_PHYS_ADDR)
}, },
[ALCHEMY_CPU_AU1550] = { [ALCHEMY_CPU_AU1550] = {
MAC_RES(AU1000_MAC1_PHYS_ADDR, MAC_RES(AU1000_MAC1_PHYS_ADDR,
AU1000_MACEN_PHYS_ADDR + 4, AU1000_MACEN_PHYS_ADDR + 4,
AU1550_MAC1_DMA_INT) AU1550_MAC1_DMA_INT,
AU1000_MACDMA1_PHYS_ADDR)
}, },
}; };
@ -521,36 +350,15 @@ static void __init alchemy_setup_macs(int ctype)
} }
} }
static struct platform_device *au1xxx_platform_devices[] __initdata = {
&au1xxx_usb_ohci_device,
#ifdef CONFIG_FB_AU1100
&au1100_lcd_device,
#endif
#ifdef CONFIG_SOC_AU1200
&au1xxx_usb_ehci_device,
&au1xxx_usb_gdt_device,
&au1xxx_usb_otg_device,
&au1200_lcd_device,
&au1200_mmc0_device,
#ifndef CONFIG_MIPS_DB1200
&au1200_mmc1_device,
#endif
#endif
#ifdef SMBUS_PSC_BASE
&pbdb_smbus_device,
#endif
};
static int __init au1xxx_platform_init(void) static int __init au1xxx_platform_init(void)
{ {
int err, ctype = alchemy_get_cputype(); int ctype = alchemy_get_cputype();
alchemy_setup_uarts(ctype); alchemy_setup_uarts(ctype);
alchemy_setup_macs(ctype); alchemy_setup_macs(ctype);
alchemy_setup_usb(ctype);
err = platform_add_devices(au1xxx_platform_devices, return 0;
ARRAY_SIZE(au1xxx_platform_devices));
return err;
} }
arch_initcall(au1xxx_platform_init); arch_initcall(au1xxx_platform_init);

View File

@ -37,8 +37,6 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_PM
/* /*
* We need to save/restore a bunch of core registers that are * We need to save/restore a bunch of core registers that are
* either volatile or reset to some state across a processor sleep. * either volatile or reset to some state across a processor sleep.
@ -49,7 +47,6 @@
* We only have to save/restore registers that aren't otherwise * We only have to save/restore registers that aren't otherwise
* done as part of a driver pm_* function. * done as part of a driver pm_* function.
*/ */
static unsigned int sleep_usb[2];
static unsigned int sleep_sys_clocks[5]; static unsigned int sleep_sys_clocks[5];
static unsigned int sleep_sys_pinfunc; static unsigned int sleep_sys_pinfunc;
static unsigned int sleep_static_memctlr[4][3]; static unsigned int sleep_static_memctlr[4][3];
@ -57,31 +54,6 @@ static unsigned int sleep_static_memctlr[4][3];
static void save_core_regs(void) static void save_core_regs(void)
{ {
#ifndef CONFIG_SOC_AU1200
/* Shutdown USB host/device. */
sleep_usb[0] = au_readl(USB_HOST_CONFIG);
/* There appears to be some undocumented reset register.... */
au_writel(0, 0xb0100004);
au_sync();
au_writel(0, USB_HOST_CONFIG);
au_sync();
sleep_usb[1] = au_readl(USBD_ENABLE);
au_writel(0, USBD_ENABLE);
au_sync();
#else /* AU1200 */
/* enable access to OTG mmio so we can save OTG CAP/MUX.
* FIXME: write an OTG driver and move this stuff there!
*/
au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
au_sync();
sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */
sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */
#endif
/* Clocks and PLLs. */ /* Clocks and PLLs. */
sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0);
sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1);
@ -125,22 +97,6 @@ static void restore_core_regs(void)
au_writel(sleep_sys_pinfunc, SYS_PINFUNC); au_writel(sleep_sys_pinfunc, SYS_PINFUNC);
au_sync(); au_sync();
#ifndef CONFIG_SOC_AU1200
au_writel(sleep_usb[0], USB_HOST_CONFIG);
au_writel(sleep_usb[1], USBD_ENABLE);
au_sync();
#else
/* enable access to OTG memory */
au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
au_sync();
/* restore OTG caps and port mux. */
au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */
au_sync();
au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */
au_sync();
#endif
/* Restore the static memory controller configuration. */ /* Restore the static memory controller configuration. */
au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
@ -174,5 +130,3 @@ void au_sleep(void)
restore_core_regs(); restore_core_regs();
} }
#endif /* CONFIG_PM */

View File

@ -73,8 +73,8 @@ void __init plat_mem_setup(void)
/* This routine should be valid for all Au1x based boards */ /* This routine should be valid for all Au1x based boards */
phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size) phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
{ {
u32 start = (u32)Au1500_PCI_MEM_START; unsigned long start = ALCHEMY_PCI_MEMWIN_START;
u32 end = (u32)Au1500_PCI_MEM_END; unsigned long end = ALCHEMY_PCI_MEMWIN_END;
/* Don't fixup 36-bit addresses */ /* Don't fixup 36-bit addresses */
if ((phys_addr >> 32) != 0) if ((phys_addr >> 32) != 0)
@ -82,7 +82,7 @@ phys_t __fixup_bigphys_addr(phys_t phys_addr, phys_t size)
/* Check for PCI memory window */ /* Check for PCI memory window */
if (phys_addr >= start && (phys_addr + size - 1) <= end) if (phys_addr >= start && (phys_addr + size - 1) <= end)
return (phys_t)((phys_addr - start) + Au1500_PCI_MEM_START); return (phys_t)(AU1500_PCI_MEM_PHYS_ADDR + phys_addr);
/* default nop */ /* default nop */
return phys_addr; return phys_addr;

View File

@ -213,7 +213,12 @@ static struct resource db1200_ide_res[] = {
.start = DB1200_IDE_INT, .start = DB1200_IDE_INT,
.end = DB1200_IDE_INT, .end = DB1200_IDE_INT,
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
} },
[2] = {
.start = AU1200_DSCR_CMD0_DMA_REQ1,
.end = AU1200_DSCR_CMD0_DMA_REQ1,
.flags = IORESOURCE_DMA,
},
}; };
static u64 ide_dmamask = DMA_BIT_MASK(32); static u64 ide_dmamask = DMA_BIT_MASK(32);
@ -328,23 +333,85 @@ static struct led_classdev db1200_mmc_led = {
.brightness_set = db1200_mmcled_set, .brightness_set = db1200_mmcled_set,
}; };
/* needed by arch/mips/alchemy/common/platform.c */ static struct au1xmmc_platform_data db1200mmc_platdata = {
struct au1xmmc_platform_data au1xmmc_platdata[] = { .cd_setup = db1200_mmc_cd_setup,
.set_power = db1200_mmc_set_power,
.card_inserted = db1200_mmc_card_inserted,
.card_readonly = db1200_mmc_card_readonly,
.led = &db1200_mmc_led,
};
static struct resource au1200_mmc0_resources[] = {
[0] = { [0] = {
.cd_setup = db1200_mmc_cd_setup, .start = AU1100_SD0_PHYS_ADDR,
.set_power = db1200_mmc_set_power, .end = AU1100_SD0_PHYS_ADDR + 0xfff,
.card_inserted = db1200_mmc_card_inserted, .flags = IORESOURCE_MEM,
.card_readonly = db1200_mmc_card_readonly,
.led = &db1200_mmc_led,
}, },
[1] = {
.start = AU1200_SD_INT,
.end = AU1200_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1200_DSCR_CMD0_SDMS_TX0,
.end = AU1200_DSCR_CMD0_SDMS_TX0,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1200_DSCR_CMD0_SDMS_RX0,
.end = AU1200_DSCR_CMD0_SDMS_RX0,
.flags = IORESOURCE_DMA,
}
};
static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
static struct platform_device db1200_mmc0_dev = {
.name = "au1xxx-mmc",
.id = 0,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &db1200mmc_platdata,
},
.num_resources = ARRAY_SIZE(au1200_mmc0_resources),
.resource = au1200_mmc0_resources,
};
/**********************************************************************/
static struct resource au1200_lcd_res[] = {
[0] = {
.start = AU1200_LCD_PHYS_ADDR,
.end = AU1200_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_LCD_INT,
.end = AU1200_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1200_lcd_dev = {
.name = "au1200-lcd",
.id = 0,
.dev = {
.dma_mask = &au1200_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1200_lcd_res),
.resource = au1200_lcd_res,
}; };
/**********************************************************************/ /**********************************************************************/
static struct resource au1200_psc0_res[] = { static struct resource au1200_psc0_res[] = {
[0] = { [0] = {
.start = PSC0_PHYS_ADDR, .start = AU1550_PSC0_PHYS_ADDR,
.end = PSC0_PHYS_ADDR + 0x000fffff, .end = AU1550_PSC0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
[1] = { [1] = {
@ -353,13 +420,13 @@ static struct resource au1200_psc0_res[] = {
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
[2] = { [2] = {
.start = DSCR_CMD0_PSC0_TX, .start = AU1200_DSCR_CMD0_PSC0_TX,
.end = DSCR_CMD0_PSC0_TX, .end = AU1200_DSCR_CMD0_PSC0_TX,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
[3] = { [3] = {
.start = DSCR_CMD0_PSC0_RX, .start = AU1200_DSCR_CMD0_PSC0_RX,
.end = DSCR_CMD0_PSC0_RX, .end = AU1200_DSCR_CMD0_PSC0_RX,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
}; };
@ -401,8 +468,8 @@ static struct platform_device db1200_spi_dev = {
static struct resource au1200_psc1_res[] = { static struct resource au1200_psc1_res[] = {
[0] = { [0] = {
.start = PSC1_PHYS_ADDR, .start = AU1550_PSC1_PHYS_ADDR,
.end = PSC1_PHYS_ADDR + 0x000fffff, .end = AU1550_PSC1_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
[1] = { [1] = {
@ -411,13 +478,13 @@ static struct resource au1200_psc1_res[] = {
.flags = IORESOURCE_IRQ, .flags = IORESOURCE_IRQ,
}, },
[2] = { [2] = {
.start = DSCR_CMD0_PSC1_TX, .start = AU1200_DSCR_CMD0_PSC1_TX,
.end = DSCR_CMD0_PSC1_TX, .end = AU1200_DSCR_CMD0_PSC1_TX,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
[3] = { [3] = {
.start = DSCR_CMD0_PSC1_RX, .start = AU1200_DSCR_CMD0_PSC1_RX,
.end = DSCR_CMD0_PSC1_RX, .end = AU1200_DSCR_CMD0_PSC1_RX,
.flags = IORESOURCE_DMA, .flags = IORESOURCE_DMA,
}, },
}; };
@ -449,6 +516,8 @@ static struct platform_device db1200_audiodma_dev = {
static struct platform_device *db1200_devs[] __initdata = { static struct platform_device *db1200_devs[] __initdata = {
NULL, /* PSC0, selected by S6.8 */ NULL, /* PSC0, selected by S6.8 */
&db1200_ide_dev, &db1200_ide_dev,
&db1200_mmc0_dev,
&au1200_lcd_dev,
&db1200_eth_dev, &db1200_eth_dev,
&db1200_rtc_dev, &db1200_rtc_dev,
&db1200_nand_dev, &db1200_nand_dev,
@ -526,32 +595,28 @@ static int __init db1200_dev_init(void)
/* Audio PSC clock is supplied externally. (FIXME: platdata!!) */ /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
__raw_writel(PSC_SEL_CLK_SERCLK, __raw_writel(PSC_SEL_CLK_SERCLK,
(void __iomem *)KSEG1ADDR(PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb(); wmb();
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR,
DB1200_PC0_INT, AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
DB1200_PC0_INSERT_INT, DB1200_PC0_INT, DB1200_PC0_INSERT_INT,
/*DB1200_PC0_STSCHG_INT*/0, /*DB1200_PC0_STSCHG_INT*/0, DB1200_PC0_EJECT_INT, 0);
DB1200_PC0_EJECT_INT,
0);
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
PCMCIA_MEM_PHYS_ADDR + 0x004000000, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
PCMCIA_IO_PHYS_ADDR + 0x004000000, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
DB1200_PC1_INT, AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
DB1200_PC1_INSERT_INT, DB1200_PC1_INT, DB1200_PC1_INSERT_INT,
/*DB1200_PC1_STSCHG_INT*/0, /*DB1200_PC1_STSCHG_INT*/0, DB1200_PC1_EJECT_INT, 1);
DB1200_PC1_EJECT_INT,
1);
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
db1x_register_norflash(64 << 20, 2, swapped); db1x_register_norflash(64 << 20, 2, swapped);

View File

@ -40,24 +40,6 @@
#include <prom.h> #include <prom.h>
#ifdef CONFIG_MIPS_DB1500
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT371 */
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
};
#endif
#ifdef CONFIG_MIPS_DB1550
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, AU1550_PCI_INTC, 0xff, 0xff, 0xff }, /* IDSEL 11 - on-board HPT371 */
[12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
#endif
#ifdef CONFIG_MIPS_BOSPORUS #ifdef CONFIG_MIPS_BOSPORUS
char irq_tab_alchemy[][5] __initdata = { char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */ [11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */
@ -91,12 +73,6 @@ const char *get_system_type(void)
#ifdef CONFIG_MIPS_MIRAGE #ifdef CONFIG_MIPS_MIRAGE
char irq_tab_alchemy[][5] __initdata = {
[11] = { -1, AU1500_PCI_INTD, 0xff, 0xff, 0xff }, /* IDSEL 11 - SMI VGX */
[12] = { -1, 0xff, 0xff, AU1500_PCI_INTC, 0xff }, /* IDSEL 12 - PNX1300 */
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 13 - miniPCI */
};
static void mirage_power_off(void) static void mirage_power_off(void)
{ {
alchemy_gpio_direction_output(210, 1); alchemy_gpio_direction_output(210, 1);
@ -158,9 +134,7 @@ void __init board_setup(void)
/* initialize board register space */ /* initialize board register space */
bcsr_init(bcsr1, bcsr2); bcsr_init(bcsr1, bcsr2);
/* Not valid for Au1550 */ #if defined(CONFIG_IRDA) && defined(CONFIG_AU1000_FIR)
#if defined(CONFIG_IRDA) && \
(defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
{ {
u32 pin_func; u32 pin_func;

View File

@ -20,14 +20,16 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1000_dma.h> #include <asm/mach-au1x00/au1000_dma.h>
#include <asm/mach-au1x00/au1xxx.h>
#include <asm/mach-db1x00/bcsr.h> #include <asm/mach-db1x00/bcsr.h>
#include "../platform.h" #include "../platform.h"
struct pci_dev;
/* DB1xxx PCMCIA interrupt sources: /* DB1xxx PCMCIA interrupt sources:
* CD0/1 GPIO0/3 * CD0/1 GPIO0/3
* STSCHG0/1 GPIO1/4 * STSCHG0/1 GPIO1/4
@ -88,6 +90,155 @@
#endif #endif
#endif #endif
#ifdef CONFIG_PCI
#ifdef CONFIG_MIPS_DB1500
static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
if ((slot < 12) || (slot > 13) || pin == 0)
return -1;
if (slot == 12)
return (pin == 1) ? AU1500_PCI_INTA : 0xff;
if (slot == 13) {
switch (pin) {
case 1: return AU1500_PCI_INTA;
case 2: return AU1500_PCI_INTB;
case 3: return AU1500_PCI_INTC;
case 4: return AU1500_PCI_INTD;
}
}
return -1;
}
#endif
#ifdef CONFIG_MIPS_DB1550
static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
if ((slot < 11) || (slot > 13) || pin == 0)
return -1;
if (slot == 11)
return (pin == 1) ? AU1550_PCI_INTC : 0xff;
if (slot == 12) {
switch (pin) {
case 1: return AU1550_PCI_INTB;
case 2: return AU1550_PCI_INTC;
case 3: return AU1550_PCI_INTD;
case 4: return AU1550_PCI_INTA;
}
}
if (slot == 13) {
switch (pin) {
case 1: return AU1550_PCI_INTA;
case 2: return AU1550_PCI_INTB;
case 3: return AU1550_PCI_INTC;
case 4: return AU1550_PCI_INTD;
}
}
return -1;
}
#endif
#ifdef CONFIG_MIPS_BOSPORUS
static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
if ((slot < 11) || (slot > 13) || pin == 0)
return -1;
if (slot == 12)
return (pin == 1) ? AU1500_PCI_INTA : 0xff;
if (slot == 11) {
switch (pin) {
case 1: return AU1500_PCI_INTA;
case 2: return AU1500_PCI_INTB;
default: return 0xff;
}
}
if (slot == 13) {
switch (pin) {
case 1: return AU1500_PCI_INTA;
case 2: return AU1500_PCI_INTB;
case 3: return AU1500_PCI_INTC;
case 4: return AU1500_PCI_INTD;
}
}
return -1;
}
#endif
#ifdef CONFIG_MIPS_MIRAGE
static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
if ((slot < 11) || (slot > 13) || pin == 0)
return -1;
if (slot == 11)
return (pin == 1) ? AU1500_PCI_INTD : 0xff;
if (slot == 12)
return (pin == 3) ? AU1500_PCI_INTC : 0xff;
if (slot == 13) {
switch (pin) {
case 1: return AU1500_PCI_INTA;
case 2: return AU1500_PCI_INTB;
default: return 0xff;
}
}
return -1;
}
#endif
static struct resource alchemy_pci_host_res[] = {
[0] = {
.start = AU1500_PCI_PHYS_ADDR,
.end = AU1500_PCI_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static struct alchemy_pci_platdata db1xxx_pci_pd = {
.board_map_irq = db1xxx_map_pci_irq,
};
static struct platform_device db1xxx_pci_host_dev = {
.dev.platform_data = &db1xxx_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
static int __init db15x0_pci_init(void)
{
return platform_device_register(&db1xxx_pci_host_dev);
}
/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
arch_initcall(db15x0_pci_init);
#endif
#ifdef CONFIG_MIPS_DB1100
static struct resource au1100_lcd_resources[] = {
[0] = {
.start = AU1100_LCD_PHYS_ADDR,
.end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1100_LCD_INT,
.end = AU1100_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1100_lcd_device = {
.name = "au1100-lcd",
.id = 0,
.dev = {
.dma_mask = &au1100_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1100_lcd_resources),
.resource = au1100_lcd_resources,
};
#endif
static struct resource alchemy_ac97c_res[] = { static struct resource alchemy_ac97c_res[] = {
[0] = { [0] = {
.start = AU1000_AC97_PHYS_ADDR, .start = AU1000_AC97_PHYS_ADDR,
@ -130,29 +281,28 @@ static struct platform_device db1x00_audio_dev = {
static int __init db1xxx_dev_init(void) static int __init db1xxx_dev_init(void)
{ {
#ifdef DB1XXX_HAS_PCMCIA #ifdef DB1XXX_HAS_PCMCIA
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR,
DB1XXX_PCMCIA_CARD0, AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
DB1XXX_PCMCIA_CD0, DB1XXX_PCMCIA_CARD0, DB1XXX_PCMCIA_CD0,
/*DB1XXX_PCMCIA_STSCHG0*/0, /*DB1XXX_PCMCIA_STSCHG0*/0, 0, 0);
0,
0);
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x004000000, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
PCMCIA_MEM_PHYS_ADDR + 0x004000000, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
PCMCIA_IO_PHYS_ADDR + 0x004000000, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
DB1XXX_PCMCIA_CARD1, AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
DB1XXX_PCMCIA_CD1, DB1XXX_PCMCIA_CARD1, DB1XXX_PCMCIA_CD1,
/*DB1XXX_PCMCIA_STSCHG1*/0, /*DB1XXX_PCMCIA_STSCHG1*/0, 0, 1);
0, #endif
1); #ifdef CONFIG_MIPS_DB1100
platform_device_register(&au1100_lcd_device);
#endif #endif
db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED); db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);

View File

@ -19,31 +19,58 @@
*/ */
#include <linux/init.h> #include <linux/init.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h> #include <asm/mach-db1x00/bcsr.h>
#include "../platform.h" #include "../platform.h"
static struct resource au1100_lcd_resources[] = {
[0] = {
.start = AU1100_LCD_PHYS_ADDR,
.end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1100_LCD_INT,
.end = AU1100_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1100_lcd_device = {
.name = "au1100-lcd",
.id = 0,
.dev = {
.dma_mask = &au1100_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1100_lcd_resources),
.resource = au1100_lcd_resources,
};
static int __init pb1100_dev_init(void) static int __init pb1100_dev_init(void)
{ {
int swapped; int swapped;
/* PCMCIA. single socket, identical to Pb1500 */ /* PCMCIA. single socket, identical to Pb1500 */
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR,
AU1100_GPIO11_INT, /* card */ AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1100_GPIO9_INT, /* insert */ AU1100_GPIO11_INT, AU1100_GPIO9_INT, /* card / insert */
/*AU1100_GPIO10_INT*/0, /* stschg */ /*AU1100_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
0, /* eject */
0); /* id */
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(64 * 1024 * 1024, 4, swapped); db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
platform_device_register(&au1100_lcd_device);
return 0; return 0;
} }

View File

@ -24,9 +24,11 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/smc91x.h> #include <linux/smc91x.h>
#include <asm/mach-au1x00/au1xxx.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1100_mmc.h> #include <asm/mach-au1x00/au1100_mmc.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-db1x00/bcsr.h> #include <asm/mach-db1x00/bcsr.h>
#include <asm/mach-pb1x00/pb1200.h>
#include "../platform.h" #include "../platform.h"
@ -88,7 +90,7 @@ static int pb1200mmc1_card_inserted(void *mmc_host)
return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0; return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
} }
const struct au1xmmc_platform_data au1xmmc_platdata[2] = { static struct au1xmmc_platform_data pb1200mmc_platdata[2] = {
[0] = { [0] = {
.set_power = pb1200mmc0_set_power, .set_power = pb1200mmc0_set_power,
.card_inserted = pb1200mmc0_card_inserted, .card_inserted = pb1200mmc0_card_inserted,
@ -105,6 +107,79 @@ const struct au1xmmc_platform_data au1xmmc_platdata[2] = {
}, },
}; };
static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
static struct resource au1200_mmc0_res[] = {
[0] = {
.start = AU1100_SD0_PHYS_ADDR,
.end = AU1100_SD0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_SD_INT,
.end = AU1200_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1200_DSCR_CMD0_SDMS_TX0,
.end = AU1200_DSCR_CMD0_SDMS_TX0,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1200_DSCR_CMD0_SDMS_RX0,
.end = AU1200_DSCR_CMD0_SDMS_RX0,
.flags = IORESOURCE_DMA,
}
};
static struct platform_device pb1200_mmc0_dev = {
.name = "au1xxx-mmc",
.id = 0,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &pb1200mmc_platdata[0],
},
.num_resources = ARRAY_SIZE(au1200_mmc0_res),
.resource = au1200_mmc0_res,
};
static struct resource au1200_mmc1_res[] = {
[0] = {
.start = AU1100_SD1_PHYS_ADDR,
.end = AU1100_SD1_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_SD_INT,
.end = AU1200_SD_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1200_DSCR_CMD0_SDMS_TX1,
.end = AU1200_DSCR_CMD0_SDMS_TX1,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1200_DSCR_CMD0_SDMS_RX1,
.end = AU1200_DSCR_CMD0_SDMS_RX1,
.flags = IORESOURCE_DMA,
}
};
static struct platform_device pb1200_mmc1_dev = {
.name = "au1xxx-mmc",
.id = 1,
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
.platform_data = &pb1200mmc_platdata[1],
},
.num_resources = ARRAY_SIZE(au1200_mmc1_res),
.resource = au1200_mmc1_res,
};
static struct resource ide_resources[] = { static struct resource ide_resources[] = {
[0] = { [0] = {
.start = IDE_PHYS_ADDR, .start = IDE_PHYS_ADDR,
@ -115,7 +190,12 @@ static struct resource ide_resources[] = {
.start = IDE_INT, .start = IDE_INT,
.end = IDE_INT, .end = IDE_INT,
.flags = IORESOURCE_IRQ .flags = IORESOURCE_IRQ
} },
[2] = {
.start = AU1200_DSCR_CMD0_DMA_REQ1,
.end = AU1200_DSCR_CMD0_DMA_REQ1,
.flags = IORESOURCE_DMA,
},
}; };
static u64 ide_dmamask = DMA_BIT_MASK(32); static u64 ide_dmamask = DMA_BIT_MASK(32);
@ -161,38 +241,94 @@ static struct platform_device smc91c111_device = {
.resource = smc91c111_resources .resource = smc91c111_resources
}; };
static struct resource au1200_psc0_res[] = {
[0] = {
.start = AU1550_PSC0_PHYS_ADDR,
.end = AU1550_PSC0_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_PSC0_INT,
.end = AU1200_PSC0_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1200_DSCR_CMD0_PSC0_TX,
.end = AU1200_DSCR_CMD0_PSC0_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1200_DSCR_CMD0_PSC0_RX,
.end = AU1200_DSCR_CMD0_PSC0_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device pb1200_i2c_dev = {
.name = "au1xpsc_smbus",
.id = 0, /* bus number */
.num_resources = ARRAY_SIZE(au1200_psc0_res),
.resource = au1200_psc0_res,
};
static struct resource au1200_lcd_res[] = {
[0] = {
.start = AU1200_LCD_PHYS_ADDR,
.end = AU1200_LCD_PHYS_ADDR + 0x800 - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1200_LCD_INT,
.end = AU1200_LCD_INT,
.flags = IORESOURCE_IRQ,
}
};
static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
static struct platform_device au1200_lcd_dev = {
.name = "au1200-lcd",
.id = 0,
.dev = {
.dma_mask = &au1200_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(au1200_lcd_res),
.resource = au1200_lcd_res,
};
static struct platform_device *board_platform_devices[] __initdata = { static struct platform_device *board_platform_devices[] __initdata = {
&ide_device, &ide_device,
&smc91c111_device &smc91c111_device,
&pb1200_i2c_dev,
&pb1200_mmc0_dev,
&pb1200_mmc1_dev,
&au1200_lcd_dev,
}; };
static int __init board_register_devices(void) static int __init board_register_devices(void)
{ {
int swapped; int swapped;
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR,
PB1200_PC0_INT, AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
PB1200_PC0_INSERT_INT, PB1200_PC0_INT, PB1200_PC0_INSERT_INT,
/*PB1200_PC0_STSCHG_INT*/0, /*PB1200_PC0_STSCHG_INT*/0, PB1200_PC0_EJECT_INT, 0);
PB1200_PC0_EJECT_INT,
0);
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
PCMCIA_MEM_PHYS_ADDR + 0x008000000, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
PCMCIA_IO_PHYS_ADDR + 0x008000000, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
PB1200_PC1_INT, AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
PB1200_PC1_INSERT_INT, PB1200_PC1_INT, PB1200_PC1_INSERT_INT,
/*PB1200_PC1_STSCHG_INT*/0, /*PB1200_PC1_STSCHG_INT*/0, PB1200_PC1_EJECT_INT, 1);
PB1200_PC1_EJECT_INT,
1);
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT; swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
db1x_register_norflash(128 * 1024 * 1024, 2, swapped); db1x_register_norflash(128 * 1024 * 1024, 2, swapped);

View File

@ -33,13 +33,6 @@
#include <prom.h> #include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - HPT370 */
[13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
};
const char *get_system_type(void) const char *get_system_type(void)
{ {
return "Alchemy Pb1500"; return "Alchemy Pb1500";
@ -101,20 +94,18 @@ void __init board_setup(void)
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
/* Setup PCI bus controller */ {
au_writel(0, Au1500_PCI_CMEM); void __iomem *base =
au_writel(0x00003fff, Au1500_CFG_BASE); (void __iomem *)KSEG1ADDR(AU1500_PCI_PHYS_ADDR);
#if defined(__MIPSEB__) /* Setup PCI bus controller */
au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG); __raw_writel(0x00003fff, base + PCI_REG_CMEM);
#else __raw_writel(0xf0000000, base + PCI_REG_MWMASK_DEV);
au_writel(0xf, Au1500_PCI_CFG); __raw_writel(0, base + PCI_REG_MWBASE_REV_CCL);
#endif __raw_writel(0x02a00356, base + PCI_REG_STATCMD);
au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV); __raw_writel(0x00003c04, base + PCI_REG_PARAM);
au_writel(0, Au1500_PCI_MWBASE_REV_CCL); __raw_writel(0x00000008, base + PCI_REG_MBAR);
au_writel(0x02a00356, Au1500_PCI_STATCMD); wmb();
au_writel(0x00003c04, Au1500_PCI_HDRTYPE); }
au_writel(0x00000008, Au1500_PCI_MBAR);
au_sync();
#endif #endif
/* Enable sys bus clock divider when IDLE state or no bus activity. */ /* Enable sys bus clock divider when IDLE state or no bus activity. */

View File

@ -18,32 +18,77 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <linux/dma-mapping.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h> #include <asm/mach-db1x00/bcsr.h>
#include "../platform.h" #include "../platform.h"
static int pb1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
if ((slot < 12) || (slot > 13) || pin == 0)
return -1;
if (slot == 12)
return (pin == 1) ? AU1500_PCI_INTA : 0xff;
if (slot == 13) {
switch (pin) {
case 1: return AU1500_PCI_INTA;
case 2: return AU1500_PCI_INTB;
case 3: return AU1500_PCI_INTC;
case 4: return AU1500_PCI_INTD;
}
}
return -1;
}
static struct resource alchemy_pci_host_res[] = {
[0] = {
.start = AU1500_PCI_PHYS_ADDR,
.end = AU1500_PCI_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static struct alchemy_pci_platdata pb1500_pci_pd = {
.board_map_irq = pb1500_map_pci_irq,
.pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
PCI_CONFIG_CH |
#if defined(__MIPSEB__)
PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
#else
0,
#endif
};
static struct platform_device pb1500_pci_host = {
.dev.platform_data = &pb1500_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
static int __init pb1500_dev_init(void) static int __init pb1500_dev_init(void)
{ {
int swapped; int swapped;
/* PCMCIA. single socket, identical to Pb1500 */ /* PCMCIA. single socket, identical to Pb1100 */
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR,
AU1500_GPIO11_INT, /* card */ AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1500_GPIO9_INT, /* insert */ AU1500_GPIO11_INT, AU1500_GPIO9_INT, /* card / insert */
/*AU1500_GPIO10_INT*/0, /* stschg */ /*AU1500_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
0, /* eject */
0); /* id */
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT; swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
db1x_register_norflash(64 * 1024 * 1024, 4, swapped); db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
platform_device_register(&pb1500_pci_host);
return 0; return 0;
} }
device_initcall(pb1500_dev_init); arch_initcall(pb1500_dev_init);

View File

@ -37,12 +37,6 @@
#include <prom.h> #include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD, AU1550_PCI_INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, AU1550_PCI_INTA, AU1550_PCI_INTB, AU1550_PCI_INTC, AU1550_PCI_INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
const char *get_system_type(void) const char *get_system_type(void)
{ {
return "Alchemy Pb1550"; return "Alchemy Pb1550";

View File

@ -18,14 +18,89 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <linux/dma-mapping.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-pb1x00/pb1550.h> #include <asm/mach-pb1x00/pb1550.h>
#include <asm/mach-db1x00/bcsr.h> #include <asm/mach-db1x00/bcsr.h>
#include "../platform.h" #include "../platform.h"
static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
if ((slot < 12) || (slot > 13) || pin == 0)
return -1;
if (slot == 12) {
switch (pin) {
case 1: return AU1500_PCI_INTB;
case 2: return AU1500_PCI_INTC;
case 3: return AU1500_PCI_INTD;
case 4: return AU1500_PCI_INTA;
}
}
if (slot == 13) {
switch (pin) {
case 1: return AU1500_PCI_INTA;
case 2: return AU1500_PCI_INTB;
case 3: return AU1500_PCI_INTC;
case 4: return AU1500_PCI_INTD;
}
}
return -1;
}
static struct resource alchemy_pci_host_res[] = {
[0] = {
.start = AU1500_PCI_PHYS_ADDR,
.end = AU1500_PCI_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static struct alchemy_pci_platdata pb1550_pci_pd = {
.board_map_irq = pb1550_map_pci_irq,
};
static struct platform_device pb1550_pci_host = {
.dev.platform_data = &pb1550_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
static struct resource au1550_psc2_res[] = {
[0] = {
.start = AU1550_PSC2_PHYS_ADDR,
.end = AU1550_PSC2_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AU1550_PSC2_INT,
.end = AU1550_PSC2_INT,
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = AU1550_DSCR_CMD0_PSC2_TX,
.end = AU1550_DSCR_CMD0_PSC2_TX,
.flags = IORESOURCE_DMA,
},
[3] = {
.start = AU1550_DSCR_CMD0_PSC2_RX,
.end = AU1550_DSCR_CMD0_PSC2_RX,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device pb1550_i2c_dev = {
.name = "au1xpsc_smbus",
.id = 0, /* bus number */
.num_resources = ARRAY_SIZE(au1550_psc2_res),
.resource = au1550_psc2_res,
};
static int __init pb1550_dev_init(void) static int __init pb1550_dev_init(void)
{ {
int swapped; int swapped;
@ -37,33 +112,29 @@ static int __init pb1550_dev_init(void)
* drivers are used to shared irqs and b) statuschange isn't really use- * drivers are used to shared irqs and b) statuschange isn't really use-
* ful anyway. * ful anyway.
*/ */
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR,
PCMCIA_MEM_PHYS_ADDR, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR,
PCMCIA_IO_PHYS_ADDR, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR,
AU1550_GPIO201_205_INT, AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
AU1550_GPIO0_INT, AU1550_GPIO201_205_INT, AU1550_GPIO0_INT, 0, 0, 0);
0,
0,
0);
db1x_register_pcmcia_socket(PCMCIA_ATTR_PHYS_ADDR + 0x008000000, db1x_register_pcmcia_socket(
PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
PCMCIA_MEM_PHYS_ADDR + 0x008000000, AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
PCMCIA_IO_PHYS_ADDR + 0x008000000, AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1, AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
AU1550_GPIO201_205_INT, AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
AU1550_GPIO1_INT, AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1);
0,
0,
1);
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT; swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
db1x_register_norflash(128 * 1024 * 1024, 4, swapped); db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
platform_device_register(&pb1550_pci_host);
platform_device_register(&pb1550_i2c_dev);
return 0; return 0;
} }
device_initcall(pb1550_dev_init); arch_initcall(pb1550_dev_init);

View File

@ -36,10 +36,6 @@
#include <prom.h> #include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff },
};
static void gpr_reset(char *c) static void gpr_reset(char *c)
{ {
/* switch System-LED to orange (red# and green# on) */ /* switch System-LED to orange (red# and green# on) */
@ -76,12 +72,4 @@ void __init board_setup(void)
/* Take away Reset of UMTS-card */ /* Take away Reset of UMTS-card */
alchemy_gpio_direction_output(215, 1); alchemy_gpio_direction_output(215, 1);
#ifdef CONFIG_PCI
#if defined(__MIPSEB__)
au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
#else
au_writel(0xf, Au1500_PCI_CFG);
#endif
#endif
} }

View File

@ -167,6 +167,45 @@ static struct i2c_board_info gpr_i2c_info[] __initdata = {
} }
}; };
static struct resource alchemy_pci_host_res[] = {
[0] = {
.start = AU1500_PCI_PHYS_ADDR,
.end = AU1500_PCI_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static int gpr_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
if ((slot == 0) && (pin == 1))
return AU1550_PCI_INTA;
else if ((slot == 0) && (pin == 2))
return AU1550_PCI_INTB;
return -1;
}
static struct alchemy_pci_platdata gpr_pci_pd = {
.board_map_irq = gpr_map_pci_irq,
.pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
PCI_CONFIG_CH |
#if defined(__MIPSEB__)
PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
#else
0,
#endif
};
static struct platform_device gpr_pci_host_dev = {
.dev.platform_data = &gpr_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
static struct platform_device *gpr_devices[] __initdata = { static struct platform_device *gpr_devices[] __initdata = {
&gpr_wdt_device, &gpr_wdt_device,
&gpr_mtd_device, &gpr_mtd_device,
@ -174,6 +213,14 @@ static struct platform_device *gpr_devices[] __initdata = {
&gpr_led_devices, &gpr_led_devices,
}; };
static int __init gpr_pci_init(void)
{
return platform_device_register(&gpr_pci_host_dev);
}
/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
arch_initcall(gpr_pci_init);
static int __init gpr_dev_init(void) static int __init gpr_dev_init(void)
{ {
i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info)); i2c_register_board_info(0, gpr_i2c_info, ARRAY_SIZE(gpr_i2c_info));

View File

@ -38,20 +38,6 @@
#include <prom.h> #include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
[1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
[2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
[3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
[4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
[5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
[6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
[7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
};
extern int (*board_pci_idsel)(unsigned int devsel, int assert);
int mtx1_pci_idsel(unsigned int devsel, int assert);
static void mtx1_reset(char *c) static void mtx1_reset(char *c)
{ {
/* Jump to the reset vector */ /* Jump to the reset vector */
@ -74,15 +60,6 @@ void __init board_setup(void)
alchemy_gpio_direction_output(204, 0); alchemy_gpio_direction_output(204, 0);
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */ #endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
#ifdef CONFIG_PCI
#if defined(__MIPSEB__)
au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
#else
au_writel(0xf, Au1500_PCI_CFG);
#endif
board_pci_idsel = mtx1_pci_idsel;
#endif
/* Initialize sys_pinfunc */ /* Initialize sys_pinfunc */
au_writel(SYS_PF_NI2, SYS_PINFUNC); au_writel(SYS_PF_NI2, SYS_PINFUNC);
@ -104,23 +81,6 @@ void __init board_setup(void)
printk(KERN_INFO "4G Systems MTX-1 Board\n"); printk(KERN_INFO "4G Systems MTX-1 Board\n");
} }
int
mtx1_pci_idsel(unsigned int devsel, int assert)
{
/* This function is only necessary to support a proprietary Cardbus
* adapter on the mtx-1 "singleboard" variant. It triggers a custom
* logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.
*/
if (assert && devsel != 0)
/* Suppress signal to Cardbus */
alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */
else
alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */
udelay(1);
return 1;
}
static int __init mtx1_init_irq(void) static int __init mtx1_init_irq(void)
{ {
irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH); irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);

View File

@ -135,7 +135,69 @@ static struct platform_device mtx1_mtd = {
.resource = &mtx1_mtd_resource, .resource = &mtx1_mtd_resource,
}; };
static struct resource alchemy_pci_host_res[] = {
[0] = {
.start = AU1500_PCI_PHYS_ADDR,
.end = AU1500_PCI_PHYS_ADDR + 0xfff,
.flags = IORESOURCE_MEM,
},
};
static int mtx1_pci_idsel(unsigned int devsel, int assert)
{
/* This function is only necessary to support a proprietary Cardbus
* adapter on the mtx-1 "singleboard" variant. It triggers a custom
* logic chip connected to EXT_IO3 (GPIO1) to suppress IDSEL signals.
*/
if (assert && devsel != 0)
/* Suppress signal to Cardbus */
alchemy_gpio_set_value(1, 0); /* set EXT_IO3 OFF */
else
alchemy_gpio_set_value(1, 1); /* set EXT_IO3 ON */
udelay(1);
return 1;
}
static const char mtx1_irqtab[][5] = {
[0] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 00 - AdapterA-Slot0 (top) */
[1] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 01 - AdapterA-Slot1 (bottom) */
[2] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 02 - AdapterB-Slot0 (top) */
[3] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 03 - AdapterB-Slot1 (bottom) */
[4] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 04 - AdapterC-Slot0 (top) */
[5] = { -1, AU1500_PCI_INTB, AU1500_PCI_INTA, 0xff, 0xff }, /* IDSEL 05 - AdapterC-Slot1 (bottom) */
[6] = { -1, AU1500_PCI_INTC, AU1500_PCI_INTD, 0xff, 0xff }, /* IDSEL 06 - AdapterD-Slot0 (top) */
[7] = { -1, AU1500_PCI_INTD, AU1500_PCI_INTC, 0xff, 0xff }, /* IDSEL 07 - AdapterD-Slot1 (bottom) */
};
static int mtx1_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
return mtx1_irqtab[slot][pin];
}
static struct alchemy_pci_platdata mtx1_pci_pd = {
.board_map_irq = mtx1_map_pci_irq,
.board_pci_idsel = mtx1_pci_idsel,
.pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
PCI_CONFIG_CH |
#if defined(__MIPSEB__)
PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
#else
0,
#endif
};
static struct platform_device mtx1_pci_host = {
.dev.platform_data = &mtx1_pci_pd,
.name = "alchemy-pci",
.id = 0,
.num_resources = ARRAY_SIZE(alchemy_pci_host_res),
.resource = alchemy_pci_host_res,
};
static struct __initdata platform_device * mtx1_devs[] = { static struct __initdata platform_device * mtx1_devs[] = {
&mtx1_pci_host,
&mtx1_gpio_leds, &mtx1_gpio_leds,
&mtx1_wdt, &mtx1_wdt,
&mtx1_button, &mtx1_button,

View File

@ -70,14 +70,6 @@ void __init board_setup(void)
/* Enable DTR (MCR bit 0) = USB power up */ /* Enable DTR (MCR bit 0) = USB power up */
__raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18)); __raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18));
wmb(); wmb();
#ifdef CONFIG_PCI
#if defined(__MIPSEB__)
au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
#else
au_writel(0xf, Au1500_PCI_CFG);
#endif
#endif
} }
static int __init xxs1500_init_irq(void) static int __init xxs1500_init_irq(void)

View File

@ -27,20 +27,20 @@ static struct resource xxs1500_pcmcia_res[] = {
{ {
.name = "pcmcia-io", .name = "pcmcia-io",
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
.start = PCMCIA_IO_PHYS_ADDR, .start = AU1000_PCMCIA_IO_PHYS_ADDR,
.end = PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1, .end = AU1000_PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1,
}, },
{ {
.name = "pcmcia-attr", .name = "pcmcia-attr",
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
.start = PCMCIA_ATTR_PHYS_ADDR, .start = AU1000_PCMCIA_ATTR_PHYS_ADDR,
.end = PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1, .end = AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
}, },
{ {
.name = "pcmcia-mem", .name = "pcmcia-mem",
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
.start = PCMCIA_MEM_PHYS_ADDR, .start = AU1000_PCMCIA_MEM_PHYS_ADDR,
.end = PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1, .end = AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
}, },
}; };

View File

@ -114,4 +114,28 @@ unsigned long run_uncached(void *func);
extern void *kmap_coherent(struct page *page, unsigned long addr); extern void *kmap_coherent(struct page *page, unsigned long addr);
extern void kunmap_coherent(void); extern void kunmap_coherent(void);
#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE
static inline void flush_kernel_dcache_page(struct page *page)
{
BUG_ON(cpu_has_dc_aliases && PageHighMem(page));
}
/*
* For now flush_kernel_vmap_range and invalidate_kernel_vmap_range both do a
* cache writeback and invalidate operation.
*/
extern void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
static inline void flush_kernel_vmap_range(void *vaddr, int size)
{
if (cpu_has_dc_aliases)
__flush_kernel_vmap_range((unsigned long) vaddr, size);
}
static inline void invalidate_kernel_vmap_range(void *vaddr, int size)
{
if (cpu_has_dc_aliases)
__flush_kernel_vmap_range((unsigned long) vaddr, size);
}
#endif /* _ASM_CACHEFLUSH_H */ #endif /* _ASM_CACHEFLUSH_H */

View File

@ -135,6 +135,9 @@
#define PRID_IMP_CAVIUM_CN50XX 0x0600 #define PRID_IMP_CAVIUM_CN50XX 0x0600
#define PRID_IMP_CAVIUM_CN52XX 0x0700 #define PRID_IMP_CAVIUM_CN52XX 0x0700
#define PRID_IMP_CAVIUM_CN63XX 0x9000 #define PRID_IMP_CAVIUM_CN63XX 0x9000
#define PRID_IMP_CAVIUM_CN68XX 0x9100
#define PRID_IMP_CAVIUM_CN66XX 0x9200
#define PRID_IMP_CAVIUM_CN61XX 0x9300
/* /*
* These are the PRID's for when 23:16 == PRID_COMP_INGENIC * These are the PRID's for when 23:16 == PRID_COMP_INGENIC

View File

@ -329,14 +329,10 @@ static inline void pfx##write##bwlq(type val, \
"dsrl32 %L0, %L0, 0" "\n\t" \ "dsrl32 %L0, %L0, 0" "\n\t" \
"dsll32 %M0, %M0, 0" "\n\t" \ "dsll32 %M0, %M0, 0" "\n\t" \
"or %L0, %L0, %M0" "\n\t" \ "or %L0, %L0, %M0" "\n\t" \
".set push" "\n\t" \
".set noreorder" "\n\t" \
".set nomacro" "\n\t" \
"sd %L0, %2" "\n\t" \ "sd %L0, %2" "\n\t" \
".set pop" "\n\t" \
".set mips0" "\n" \ ".set mips0" "\n" \
: "=r" (__tmp) \ : "=r" (__tmp) \
: "0" (__val), "R" (*__mem)); \ : "0" (__val), "m" (*__mem)); \
if (irq) \ if (irq) \
local_irq_restore(__flags); \ local_irq_restore(__flags); \
} else \ } else \
@ -359,16 +355,12 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \
local_irq_save(__flags); \ local_irq_save(__flags); \
__asm__ __volatile__( \ __asm__ __volatile__( \
".set mips3" "\t\t# __readq" "\n\t" \ ".set mips3" "\t\t# __readq" "\n\t" \
".set push" "\n\t" \
".set noreorder" "\n\t" \
".set nomacro" "\n\t" \
"ld %L0, %1" "\n\t" \ "ld %L0, %1" "\n\t" \
".set pop" "\n\t" \
"dsra32 %M0, %L0, 0" "\n\t" \ "dsra32 %M0, %L0, 0" "\n\t" \
"sll %L0, %L0, 0" "\n\t" \ "sll %L0, %L0, 0" "\n\t" \
".set mips0" "\n" \ ".set mips0" "\n" \
: "=r" (__val) \ : "=r" (__val) \
: "R" (*__mem)); \ : "m" (*__mem)); \
if (irq) \ if (irq) \
local_irq_restore(__flags); \ local_irq_restore(__flags); \
} else { \ } else { \

View File

@ -245,6 +245,23 @@ void alchemy_sleep_au1000(void);
void alchemy_sleep_au1550(void); void alchemy_sleep_au1550(void);
void au_sleep(void); void au_sleep(void);
/* USB: drivers/usb/host/alchemy-common.c */
enum alchemy_usb_block {
ALCHEMY_USB_OHCI0,
ALCHEMY_USB_UDC0,
ALCHEMY_USB_EHCI0,
ALCHEMY_USB_OTG0,
};
int alchemy_usb_control(int block, int enable);
/* PCI controller platform data */
struct alchemy_pci_platdata {
int (*board_map_irq)(const struct pci_dev *d, u8 slot, u8 pin);
int (*board_pci_idsel)(unsigned int devsel, int assert);
/* bits to set/clear in PCI_CONFIG register */
unsigned long pci_cfg_set;
unsigned long pci_cfg_clr;
};
/* SOC Interrupt numbers */ /* SOC Interrupt numbers */
@ -575,38 +592,95 @@ enum soc_au1200_ints {
#endif /* !defined (_LANGUAGE_ASSEMBLY) */ #endif /* !defined (_LANGUAGE_ASSEMBLY) */
/* /*
* SDRAM register offsets * Physical base addresses for integrated peripherals
* 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200
*/ */
#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1500) || \
defined(CONFIG_SOC_AU1100)
#define MEM_SDMODE0 0x0000
#define MEM_SDMODE1 0x0004
#define MEM_SDMODE2 0x0008
#define MEM_SDADDR0 0x000C
#define MEM_SDADDR1 0x0010
#define MEM_SDADDR2 0x0014
#define MEM_SDREFCFG 0x0018
#define MEM_SDPRECMD 0x001C
#define MEM_SDAUTOREF 0x0020
#define MEM_SDWRMD0 0x0024
#define MEM_SDWRMD1 0x0028
#define MEM_SDWRMD2 0x002C
#define MEM_SDSLEEP 0x0030
#define MEM_SDSMCKE 0x0034
/* #define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */
* MEM_SDMODE register content definitions #define AU1000_USB_OHCI_PHYS_ADDR 0x10100000 /* 012 */
*/ #define AU1000_USB_UDC_PHYS_ADDR 0x10200000 /* 0123 */
#define AU1000_IRDA_PHYS_ADDR 0x10300000 /* 02 */
#define AU1200_AES_PHYS_ADDR 0x10300000 /* 4 */
#define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */
#define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */
#define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */
#define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */
#define AU1100_SD0_PHYS_ADDR 0x10600000 /* 24 */
#define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */
#define AU1550_PSC2_PHYS_ADDR 0x10A00000 /* 3 */
#define AU1550_PSC3_PHYS_ADDR 0x10B00000 /* 3 */
#define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */
#define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */
#define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */
#define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */
#define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */
#define AU1200_SWCNT_PHYS_ADDR 0x1110010C /* 4 */
#define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */
#define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */
#define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */
#define AU1000_SSI0_PHYS_ADDR 0x11600000 /* 02 */
#define AU1000_SSI1_PHYS_ADDR 0x11680000 /* 02 */
#define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */
#define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */
#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */
#define AU1550_PSC0_PHYS_ADDR 0x11A00000 /* 34 */
#define AU1550_PSC1_PHYS_ADDR 0x11B00000 /* 34 */
#define AU1000_MEM_PHYS_ADDR 0x14000000 /* 01234 */
#define AU1000_STATIC_MEM_PHYS_ADDR 0x14001000 /* 01234 */
#define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */
#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */
#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */
#define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */
#define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */
#define AU1200_CIM_PHYS_ADDR 0x14004000 /* 4 */
#define AU1500_PCI_PHYS_ADDR 0x14005000 /* 13 */
#define AU1550_PE_PHYS_ADDR 0x14008000 /* 3 */
#define AU1200_MAEBE_PHYS_ADDR 0x14010000 /* 4 */
#define AU1200_MAEFE_PHYS_ADDR 0x14012000 /* 4 */
#define AU1550_USB_OHCI_PHYS_ADDR 0x14020000 /* 3 */
#define AU1200_USB_CTL_PHYS_ADDR 0x14020000 /* 4 */
#define AU1200_USB_OTG_PHYS_ADDR 0x14020020 /* 4 */
#define AU1200_USB_OHCI_PHYS_ADDR 0x14020100 /* 4 */
#define AU1200_USB_EHCI_PHYS_ADDR 0x14020200 /* 4 */
#define AU1200_USB_UDC_PHYS_ADDR 0x14022000 /* 4 */
#define AU1100_LCD_PHYS_ADDR 0x15000000 /* 2 */
#define AU1200_LCD_PHYS_ADDR 0x15000000 /* 4 */
#define AU1500_PCI_MEM_PHYS_ADDR 0x400000000ULL /* 13 */
#define AU1500_PCI_IO_PHYS_ADDR 0x500000000ULL /* 13 */
#define AU1500_PCI_CONFIG0_PHYS_ADDR 0x600000000ULL /* 13 */
#define AU1500_PCI_CONFIG1_PHYS_ADDR 0x680000000ULL /* 13 */
#define AU1000_PCMCIA_IO_PHYS_ADDR 0xF00000000ULL /* 01234 */
#define AU1000_PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL /* 01234 */
#define AU1000_PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL /* 01234 */
/* Au1000 SDRAM memory controller register offsets */
#define AU1000_MEM_SDMODE0 0x0000
#define AU1000_MEM_SDMODE1 0x0004
#define AU1000_MEM_SDMODE2 0x0008
#define AU1000_MEM_SDADDR0 0x000C
#define AU1000_MEM_SDADDR1 0x0010
#define AU1000_MEM_SDADDR2 0x0014
#define AU1000_MEM_SDREFCFG 0x0018
#define AU1000_MEM_SDPRECMD 0x001C
#define AU1000_MEM_SDAUTOREF 0x0020
#define AU1000_MEM_SDWRMD0 0x0024
#define AU1000_MEM_SDWRMD1 0x0028
#define AU1000_MEM_SDWRMD2 0x002C
#define AU1000_MEM_SDSLEEP 0x0030
#define AU1000_MEM_SDSMCKE 0x0034
/* MEM_SDMODE register content definitions */
#define MEM_SDMODE_F (1 << 22) #define MEM_SDMODE_F (1 << 22)
#define MEM_SDMODE_SR (1 << 21) #define MEM_SDMODE_SR (1 << 21)
#define MEM_SDMODE_BS (1 << 20) #define MEM_SDMODE_BS (1 << 20)
#define MEM_SDMODE_RS (3 << 18) #define MEM_SDMODE_RS (3 << 18)
#define MEM_SDMODE_CS (7 << 15) #define MEM_SDMODE_CS (7 << 15)
#define MEM_SDMODE_TRAS (15 << 11) #define MEM_SDMODE_TRAS (15 << 11)
#define MEM_SDMODE_TMRD (3 << 9) #define MEM_SDMODE_TMRD (3 << 9)
#define MEM_SDMODE_TWR (3 << 7) #define MEM_SDMODE_TWR (3 << 7)
#define MEM_SDMODE_TRP (3 << 5) #define MEM_SDMODE_TRP (3 << 5)
#define MEM_SDMODE_TRCD (3 << 3) #define MEM_SDMODE_TRCD (3 << 3)
#define MEM_SDMODE_TCL (7 << 0) #define MEM_SDMODE_TCL (7 << 0)
#define MEM_SDMODE_BS_2Bank (0 << 20) #define MEM_SDMODE_BS_2Bank (0 << 20)
@ -628,173 +702,43 @@ enum soc_au1200_ints {
#define MEM_SDMODE_TRCD_N(N) ((N) << 3) #define MEM_SDMODE_TRCD_N(N) ((N) << 3)
#define MEM_SDMODE_TCL_N(N) ((N) << 0) #define MEM_SDMODE_TCL_N(N) ((N) << 0)
/* /* MEM_SDADDR register contents definitions */
* MEM_SDADDR register contents definitions
*/
#define MEM_SDADDR_E (1 << 20) #define MEM_SDADDR_E (1 << 20)
#define MEM_SDADDR_CSBA (0x03FF << 10) #define MEM_SDADDR_CSBA (0x03FF << 10)
#define MEM_SDADDR_CSMASK (0x03FF << 0) #define MEM_SDADDR_CSMASK (0x03FF << 0)
#define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12) #define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12)
#define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22) #define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22)
/* /* MEM_SDREFCFG register content definitions */
* MEM_SDREFCFG register content definitions
*/
#define MEM_SDREFCFG_TRC (15 << 28) #define MEM_SDREFCFG_TRC (15 << 28)
#define MEM_SDREFCFG_TRPM (3 << 26) #define MEM_SDREFCFG_TRPM (3 << 26)
#define MEM_SDREFCFG_E (1 << 25) #define MEM_SDREFCFG_E (1 << 25)
#define MEM_SDREFCFG_RE (0x1ffffff << 0) #define MEM_SDREFCFG_RE (0x1ffffff << 0)
#define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC) #define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC)
#define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM) #define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM)
#define MEM_SDREFCFG_REF_N(N) (N) #define MEM_SDREFCFG_REF_N(N) (N)
#endif
/***********************************************************************/ /* Au1550 SDRAM Register Offsets */
#define AU1550_MEM_SDMODE0 0x0800
/* #define AU1550_MEM_SDMODE1 0x0808
* Au1550 SDRAM Register Offsets #define AU1550_MEM_SDMODE2 0x0810
*/ #define AU1550_MEM_SDADDR0 0x0820
#define AU1550_MEM_SDADDR1 0x0828
/***********************************************************************/ #define AU1550_MEM_SDADDR2 0x0830
#define AU1550_MEM_SDCONFIGA 0x0840
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) #define AU1550_MEM_SDCONFIGB 0x0848
#define MEM_SDMODE0 0x0800 #define AU1550_MEM_SDSTAT 0x0850
#define MEM_SDMODE1 0x0808 #define AU1550_MEM_SDERRADDR 0x0858
#define MEM_SDMODE2 0x0810 #define AU1550_MEM_SDSTRIDE0 0x0860
#define MEM_SDADDR0 0x0820 #define AU1550_MEM_SDSTRIDE1 0x0868
#define MEM_SDADDR1 0x0828 #define AU1550_MEM_SDSTRIDE2 0x0870
#define MEM_SDADDR2 0x0830 #define AU1550_MEM_SDWRMD0 0x0880
#define MEM_SDCONFIGA 0x0840 #define AU1550_MEM_SDWRMD1 0x0888
#define MEM_SDCONFIGB 0x0848 #define AU1550_MEM_SDWRMD2 0x0890
#define MEM_SDSTAT 0x0850 #define AU1550_MEM_SDPRECMD 0x08C0
#define MEM_SDERRADDR 0x0858 #define AU1550_MEM_SDAUTOREF 0x08C8
#define MEM_SDSTRIDE0 0x0860 #define AU1550_MEM_SDSREF 0x08D0
#define MEM_SDSTRIDE1 0x0868 #define AU1550_MEM_SDSLEEP MEM_SDSREF
#define MEM_SDSTRIDE2 0x0870
#define MEM_SDWRMD0 0x0880
#define MEM_SDWRMD1 0x0888
#define MEM_SDWRMD2 0x0890
#define MEM_SDPRECMD 0x08C0
#define MEM_SDAUTOREF 0x08C8
#define MEM_SDSREF 0x08D0
#define MEM_SDSLEEP MEM_SDSREF
#endif
/*
* Physical base addresses for integrated peripherals
* 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200
*/
#define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */
#define AU1000_USBD_PHYS_ADDR 0x10200000 /* 0123 */
#define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */
#define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */
#define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */
#define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */
#define AU1100_SD0_PHYS_ADDR 0x10600000 /* 24 */
#define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */
#define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */
#define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */
#define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */
#define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */
#define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */
#define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */
#define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */
#define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */
#define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */
#define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */
#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */
#define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */
#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */
#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */
#define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */
#define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */
#ifdef CONFIG_SOC_AU1000
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define USBH_PHYS_ADDR 0x10100000
#define IRDA_PHYS_ADDR 0x10300000
#define SSI0_PHYS_ADDR 0x11600000
#define SSI1_PHYS_ADDR 0x11680000
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
#endif
/********************************************************************/
#ifdef CONFIG_SOC_AU1500
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define USBH_PHYS_ADDR 0x10100000
#define PCI_PHYS_ADDR 0x14005000
#define PCI_MEM_PHYS_ADDR 0x400000000ULL
#define PCI_IO_PHYS_ADDR 0x500000000ULL
#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
#endif
/********************************************************************/
#ifdef CONFIG_SOC_AU1100
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define USBH_PHYS_ADDR 0x10100000
#define IRDA_PHYS_ADDR 0x10300000
#define SSI0_PHYS_ADDR 0x11600000
#define SSI1_PHYS_ADDR 0x11680000
#define LCD_PHYS_ADDR 0x15000000
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
#endif
/***********************************************************************/
#ifdef CONFIG_SOC_AU1550
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define USBH_PHYS_ADDR 0x14020000
#define PCI_PHYS_ADDR 0x14005000
#define PE_PHYS_ADDR 0x14008000
#define PSC0_PHYS_ADDR 0x11A00000
#define PSC1_PHYS_ADDR 0x11B00000
#define PSC2_PHYS_ADDR 0x10A00000
#define PSC3_PHYS_ADDR 0x10B00000
#define PCI_MEM_PHYS_ADDR 0x400000000ULL
#define PCI_IO_PHYS_ADDR 0x500000000ULL
#define PCI_CONFIG0_PHYS_ADDR 0x600000000ULL
#define PCI_CONFIG1_PHYS_ADDR 0x680000000ULL
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
#endif
/***********************************************************************/
#ifdef CONFIG_SOC_AU1200
#define MEM_PHYS_ADDR 0x14000000
#define STATIC_MEM_PHYS_ADDR 0x14001000
#define AES_PHYS_ADDR 0x10300000
#define CIM_PHYS_ADDR 0x14004000
#define USBM_PHYS_ADDR 0x14020000
#define USBH_PHYS_ADDR 0x14020100
#define PSC0_PHYS_ADDR 0x11A00000
#define PSC1_PHYS_ADDR 0x11B00000
#define LCD_PHYS_ADDR 0x15000000
#define SWCNT_PHYS_ADDR 0x1110010C
#define MAEFE_PHYS_ADDR 0x14012000
#define MAEBE_PHYS_ADDR 0x14010000
#define PCMCIA_IO_PHYS_ADDR 0xF00000000ULL
#define PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL
#define PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL
#endif
/* Static Bus Controller */ /* Static Bus Controller */
#define MEM_STCFG0 0xB4001000 #define MEM_STCFG0 0xB4001000
@ -813,81 +757,14 @@ enum soc_au1200_ints {
#define MEM_STTIME3 0xB4001034 #define MEM_STTIME3 0xB4001034
#define MEM_STADDR3 0xB4001038 #define MEM_STADDR3 0xB4001038
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
#define MEM_STNDCTL 0xB4001100 #define MEM_STNDCTL 0xB4001100
#define MEM_STSTAT 0xB4001104 #define MEM_STSTAT 0xB4001104
#define MEM_STNAND_CMD 0x0 #define MEM_STNAND_CMD 0x0
#define MEM_STNAND_ADDR 0x4 #define MEM_STNAND_ADDR 0x4
#define MEM_STNAND_DATA 0x20 #define MEM_STNAND_DATA 0x20
#endif
/* Au1000 */
#ifdef CONFIG_SOC_AU1000
#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
#define USB_HOST_CONFIG 0xB017FFFC
#define FOR_PLATFORM_C_USB_HOST_INT AU1000_USB_HOST_INT
#endif /* CONFIG_SOC_AU1000 */
/* Au1500 */
#ifdef CONFIG_SOC_AU1500
#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
#define USB_HOST_CONFIG 0xB017fffc
#define FOR_PLATFORM_C_USB_HOST_INT AU1500_USB_HOST_INT
#endif /* CONFIG_SOC_AU1500 */
/* Au1100 */
#ifdef CONFIG_SOC_AU1100
#define USB_OHCI_BASE 0x10100000 /* phys addr for ioremap */
#define USB_HOST_CONFIG 0xB017FFFC
#define FOR_PLATFORM_C_USB_HOST_INT AU1100_USB_HOST_INT
#endif /* CONFIG_SOC_AU1100 */
#ifdef CONFIG_SOC_AU1550
#define USB_OHCI_BASE 0x14020000 /* phys addr for ioremap */
#define USB_OHCI_LEN 0x00060000
#define USB_HOST_CONFIG 0xB4027ffc
#define FOR_PLATFORM_C_USB_HOST_INT AU1550_USB_HOST_INT
#endif /* CONFIG_SOC_AU1550 */
#ifdef CONFIG_SOC_AU1200
#define USB_UOC_BASE 0x14020020
#define USB_UOC_LEN 0x20
#define USB_OHCI_BASE 0x14020100
#define USB_OHCI_LEN 0x100
#define USB_EHCI_BASE 0x14020200
#define USB_EHCI_LEN 0x100
#define USB_UDC_BASE 0x14022000
#define USB_UDC_LEN 0x2000
#define USB_MSR_BASE 0xB4020000
#define USB_MSR_MCFG 4
#define USBMSRMCFG_OMEMEN 0
#define USBMSRMCFG_OBMEN 1
#define USBMSRMCFG_EMEMEN 2
#define USBMSRMCFG_EBMEN 3
#define USBMSRMCFG_DMEMEN 4
#define USBMSRMCFG_DBMEN 5
#define USBMSRMCFG_GMEMEN 6
#define USBMSRMCFG_OHCCLKEN 16
#define USBMSRMCFG_EHCCLKEN 17
#define USBMSRMCFG_UDCCLKEN 18
#define USBMSRMCFG_PHYPLLEN 19
#define USBMSRMCFG_RDCOMB 30
#define USBMSRMCFG_PFEN 31
#define FOR_PLATFORM_C_USB_HOST_INT AU1200_USB_INT
#endif /* CONFIG_SOC_AU1200 */
/* Programmable Counters 0 and 1 */ /* Programmable Counters 0 and 1 */
#define SYS_BASE 0xB1900000 #define SYS_BASE 0xB1900000
#define SYS_COUNTER_CNTRL (SYS_BASE + 0x14) #define SYS_COUNTER_CNTRL (SYS_BASE + 0x14)
@ -958,56 +835,6 @@ enum soc_au1200_ints {
# define I2S_CONTROL_D (1 << 1) # define I2S_CONTROL_D (1 << 1)
# define I2S_CONTROL_CE (1 << 0) # define I2S_CONTROL_CE (1 << 0)
/* USB Host Controller */
#ifndef USB_OHCI_LEN
#define USB_OHCI_LEN 0x00100000
#endif
#ifndef CONFIG_SOC_AU1200
/* USB Device Controller */
#define USBD_EP0RD 0xB0200000
#define USBD_EP0WR 0xB0200004
#define USBD_EP2WR 0xB0200008
#define USBD_EP3WR 0xB020000C
#define USBD_EP4RD 0xB0200010
#define USBD_EP5RD 0xB0200014
#define USBD_INTEN 0xB0200018
#define USBD_INTSTAT 0xB020001C
# define USBDEV_INT_SOF (1 << 12)
# define USBDEV_INT_HF_BIT 6
# define USBDEV_INT_HF_MASK (0x3f << USBDEV_INT_HF_BIT)
# define USBDEV_INT_CMPLT_BIT 0
# define USBDEV_INT_CMPLT_MASK (0x3f << USBDEV_INT_CMPLT_BIT)
#define USBD_CONFIG 0xB0200020
#define USBD_EP0CS 0xB0200024
#define USBD_EP2CS 0xB0200028
#define USBD_EP3CS 0xB020002C
#define USBD_EP4CS 0xB0200030
#define USBD_EP5CS 0xB0200034
# define USBDEV_CS_SU (1 << 14)
# define USBDEV_CS_NAK (1 << 13)
# define USBDEV_CS_ACK (1 << 12)
# define USBDEV_CS_BUSY (1 << 11)
# define USBDEV_CS_TSIZE_BIT 1
# define USBDEV_CS_TSIZE_MASK (0x3ff << USBDEV_CS_TSIZE_BIT)
# define USBDEV_CS_STALL (1 << 0)
#define USBD_EP0RDSTAT 0xB0200040
#define USBD_EP0WRSTAT 0xB0200044
#define USBD_EP2WRSTAT 0xB0200048
#define USBD_EP3WRSTAT 0xB020004C
#define USBD_EP4RDSTAT 0xB0200050
#define USBD_EP5RDSTAT 0xB0200054
# define USBDEV_FSTAT_FLUSH (1 << 6)
# define USBDEV_FSTAT_UF (1 << 5)
# define USBDEV_FSTAT_OF (1 << 4)
# define USBDEV_FSTAT_FCNT_BIT 0
# define USBDEV_FSTAT_FCNT_MASK (0x0f << USBDEV_FSTAT_FCNT_BIT)
#define USBD_ENABLE 0xB0200058
# define USBDEV_ENABLE (1 << 1)
# define USBDEV_CE (1 << 0)
#endif /* !CONFIG_SOC_AU1200 */
/* Ethernet Controllers */ /* Ethernet Controllers */
@ -1322,7 +1149,6 @@ enum soc_au1200_ints {
# define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) # define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2))
/* Au1200 only */ /* Au1200 only */
#ifdef CONFIG_SOC_AU1200
#define SYS_PINFUNC_DMA (1 << 31) #define SYS_PINFUNC_DMA (1 << 31)
#define SYS_PINFUNC_S0A (1 << 30) #define SYS_PINFUNC_S0A (1 << 30)
#define SYS_PINFUNC_S1A (1 << 29) #define SYS_PINFUNC_S1A (1 << 29)
@ -1350,7 +1176,6 @@ enum soc_au1200_ints {
#define SYS_PINFUNC_P0B (1 << 4) #define SYS_PINFUNC_P0B (1 << 4)
#define SYS_PINFUNC_U0T (1 << 3) #define SYS_PINFUNC_U0T (1 << 3)
#define SYS_PINFUNC_S1B (1 << 2) #define SYS_PINFUNC_S1B (1 << 2)
#endif
/* Power Management */ /* Power Management */
#define SYS_SCRATCH0 0xB1900018 #define SYS_SCRATCH0 0xB1900018
@ -1406,12 +1231,12 @@ enum soc_au1200_ints {
# define SYS_CS_MI2_MASK (0x7 << SYS_CS_MI2_BIT) # define SYS_CS_MI2_MASK (0x7 << SYS_CS_MI2_BIT)
# define SYS_CS_DI2 (1 << 16) # define SYS_CS_DI2 (1 << 16)
# define SYS_CS_CI2 (1 << 15) # define SYS_CS_CI2 (1 << 15)
#ifdef CONFIG_SOC_AU1100
# define SYS_CS_ML_BIT 7 # define SYS_CS_ML_BIT 7
# define SYS_CS_ML_MASK (0x7 << SYS_CS_ML_BIT) # define SYS_CS_ML_MASK (0x7 << SYS_CS_ML_BIT)
# define SYS_CS_DL (1 << 6) # define SYS_CS_DL (1 << 6)
# define SYS_CS_CL (1 << 5) # define SYS_CS_CL (1 << 5)
#else
# define SYS_CS_MUH_BIT 12 # define SYS_CS_MUH_BIT 12
# define SYS_CS_MUH_MASK (0x7 << SYS_CS_MUH_BIT) # define SYS_CS_MUH_MASK (0x7 << SYS_CS_MUH_BIT)
# define SYS_CS_DUH (1 << 11) # define SYS_CS_DUH (1 << 11)
@ -1420,7 +1245,7 @@ enum soc_au1200_ints {
# define SYS_CS_MUD_MASK (0x7 << SYS_CS_MUD_BIT) # define SYS_CS_MUD_MASK (0x7 << SYS_CS_MUD_BIT)
# define SYS_CS_DUD (1 << 6) # define SYS_CS_DUD (1 << 6)
# define SYS_CS_CUD (1 << 5) # define SYS_CS_CUD (1 << 5)
#endif
# define SYS_CS_MIR_BIT 2 # define SYS_CS_MIR_BIT 2
# define SYS_CS_MIR_MASK (0x7 << SYS_CS_MIR_BIT) # define SYS_CS_MIR_MASK (0x7 << SYS_CS_MIR_BIT)
# define SYS_CS_DIR (1 << 1) # define SYS_CS_DIR (1 << 1)
@ -1467,58 +1292,30 @@ enum soc_au1200_ints {
# define AC97C_RS (1 << 1) # define AC97C_RS (1 << 1)
# define AC97C_CE (1 << 0) # define AC97C_CE (1 << 0)
#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
/* Au1500 PCI Controller */
#define Au1500_CFG_BASE 0xB4005000 /* virtual, KSEG1 addr */
#define Au1500_PCI_CMEM (Au1500_CFG_BASE + 0)
#define Au1500_PCI_CFG (Au1500_CFG_BASE + 4)
# define PCI_ERROR ((1 << 22) | (1 << 23) | (1 << 24) | \
(1 << 25) | (1 << 26) | (1 << 27))
#define Au1500_PCI_B2BMASK_CCH (Au1500_CFG_BASE + 8)
#define Au1500_PCI_B2B0_VID (Au1500_CFG_BASE + 0xC)
#define Au1500_PCI_B2B1_ID (Au1500_CFG_BASE + 0x10)
#define Au1500_PCI_MWMASK_DEV (Au1500_CFG_BASE + 0x14)
#define Au1500_PCI_MWBASE_REV_CCL (Au1500_CFG_BASE + 0x18)
#define Au1500_PCI_ERR_ADDR (Au1500_CFG_BASE + 0x1C)
#define Au1500_PCI_SPEC_INTACK (Au1500_CFG_BASE + 0x20)
#define Au1500_PCI_ID (Au1500_CFG_BASE + 0x100)
#define Au1500_PCI_STATCMD (Au1500_CFG_BASE + 0x104)
#define Au1500_PCI_CLASSREV (Au1500_CFG_BASE + 0x108)
#define Au1500_PCI_HDRTYPE (Au1500_CFG_BASE + 0x10C)
#define Au1500_PCI_MBAR (Au1500_CFG_BASE + 0x110)
#define Au1500_PCI_HDR 0xB4005100 /* virtual, KSEG1 addr */ /* The PCI chip selects are outside the 32bit space, and since we can't
* just program the 36bit addresses into BARs, we have to take a chunk
/* * out of the 32bit space and reserve it for PCI. When these addresses
* All of our structures, like PCI resource, have 32-bit members. * are ioremap()ed, they'll be fixed up to the real 36bit address before
* Drivers are expected to do an ioremap on the PCI MEM resource, but it's * being passed to the real ioremap function.
* hard to store 0x4 0000 0000 in a 32-bit type. We require a small patch
* to __ioremap to check for addresses between (u32)Au1500_PCI_MEM_START and
* (u32)Au1500_PCI_MEM_END and change those to the full 36-bit PCI MEM
* addresses. For PCI I/O, it's simpler because we get to do the ioremap
* ourselves and then adjust the device's resources.
*/ */
#define Au1500_EXT_CFG 0x600000000ULL #define ALCHEMY_PCI_MEMWIN_START (AU1500_PCI_MEM_PHYS_ADDR >> 4)
#define Au1500_EXT_CFG_TYPE1 0x680000000ULL #define ALCHEMY_PCI_MEMWIN_END (ALCHEMY_PCI_MEMWIN_START + 0x0FFFFFFF)
#define Au1500_PCI_IO_START 0x500000000ULL
#define Au1500_PCI_IO_END 0x5000FFFFFULL
#define Au1500_PCI_MEM_START 0x440000000ULL
#define Au1500_PCI_MEM_END 0x44FFFFFFFULL
#define PCI_IO_START 0x00001000 /* for PCI IO it's simpler because we get to do the ioremap ourselves and then
#define PCI_IO_END 0x000FFFFF * adjust the device's resources.
#define PCI_MEM_START 0x40000000 */
#define PCI_MEM_END 0x4FFFFFFF #define ALCHEMY_PCI_IOWIN_START 0x00001000
#define ALCHEMY_PCI_IOWIN_END 0x0000FFFF
#define PCI_FIRST_DEVFN (0 << 3) #ifdef CONFIG_PCI
#define PCI_LAST_DEVFN (19 << 3)
#define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */ #define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */
#define IOPORT_RESOURCE_END 0xffffffff #define IOPORT_RESOURCE_END 0xffffffff
#define IOMEM_RESOURCE_START 0x10000000 #define IOMEM_RESOURCE_START 0x10000000
#define IOMEM_RESOURCE_END 0xfffffffffULL #define IOMEM_RESOURCE_END 0xfffffffffULL
#else /* Au1000 and Au1100 and Au1200 */ #else
/* Don't allow any legacy ports probing */ /* Don't allow any legacy ports probing */
#define IOPORT_RESOURCE_START 0x10000000 #define IOPORT_RESOURCE_START 0x10000000
@ -1526,13 +1323,77 @@ enum soc_au1200_ints {
#define IOMEM_RESOURCE_START 0x10000000 #define IOMEM_RESOURCE_START 0x10000000
#define IOMEM_RESOURCE_END 0xfffffffffULL #define IOMEM_RESOURCE_END 0xfffffffffULL
#define PCI_IO_START 0
#define PCI_IO_END 0
#define PCI_MEM_START 0
#define PCI_MEM_END 0
#define PCI_FIRST_DEVFN 0
#define PCI_LAST_DEVFN 0
#endif #endif
/* PCI controller block register offsets */
#define PCI_REG_CMEM 0x0000
#define PCI_REG_CONFIG 0x0004
#define PCI_REG_B2BMASK_CCH 0x0008
#define PCI_REG_B2BBASE0_VID 0x000C
#define PCI_REG_B2BBASE1_SID 0x0010
#define PCI_REG_MWMASK_DEV 0x0014
#define PCI_REG_MWBASE_REV_CCL 0x0018
#define PCI_REG_ERR_ADDR 0x001C
#define PCI_REG_SPEC_INTACK 0x0020
#define PCI_REG_ID 0x0100
#define PCI_REG_STATCMD 0x0104
#define PCI_REG_CLASSREV 0x0108
#define PCI_REG_PARAM 0x010C
#define PCI_REG_MBAR 0x0110
#define PCI_REG_TIMEOUT 0x0140
/* PCI controller block register bits */
#define PCI_CMEM_E (1 << 28) /* enable cacheable memory */
#define PCI_CMEM_CMBASE(x) (((x) & 0x3fff) << 14)
#define PCI_CMEM_CMMASK(x) ((x) & 0x3fff)
#define PCI_CONFIG_ERD (1 << 27) /* pci error during R/W */
#define PCI_CONFIG_ET (1 << 26) /* error in target mode */
#define PCI_CONFIG_EF (1 << 25) /* fatal error */
#define PCI_CONFIG_EP (1 << 24) /* parity error */
#define PCI_CONFIG_EM (1 << 23) /* multiple errors */
#define PCI_CONFIG_BM (1 << 22) /* bad master error */
#define PCI_CONFIG_PD (1 << 20) /* PCI Disable */
#define PCI_CONFIG_BME (1 << 19) /* Byte Mask Enable for reads */
#define PCI_CONFIG_NC (1 << 16) /* mark mem access non-coherent */
#define PCI_CONFIG_IA (1 << 15) /* INTA# enabled (target mode) */
#define PCI_CONFIG_IP (1 << 13) /* int on PCI_PERR# */
#define PCI_CONFIG_IS (1 << 12) /* int on PCI_SERR# */
#define PCI_CONFIG_IMM (1 << 11) /* int on master abort */
#define PCI_CONFIG_ITM (1 << 10) /* int on target abort (as master) */
#define PCI_CONFIG_ITT (1 << 9) /* int on target abort (as target) */
#define PCI_CONFIG_IPB (1 << 8) /* int on PERR# in bus master acc */
#define PCI_CONFIG_SIC_NO (0 << 6) /* no byte mask changes */
#define PCI_CONFIG_SIC_BA_ADR (1 << 6) /* on byte/hw acc, invert adr bits */
#define PCI_CONFIG_SIC_HWA_DAT (2 << 6) /* on halfword acc, swap data */
#define PCI_CONFIG_SIC_ALL (3 << 6) /* swap data bytes on all accesses */
#define PCI_CONFIG_ST (1 << 5) /* swap data by target transactions */
#define PCI_CONFIG_SM (1 << 4) /* swap data from PCI ctl */
#define PCI_CONFIG_AEN (1 << 3) /* enable internal arbiter */
#define PCI_CONFIG_R2H (1 << 2) /* REQ2# to hi-prio arbiter */
#define PCI_CONFIG_R1H (1 << 1) /* REQ1# to hi-prio arbiter */
#define PCI_CONFIG_CH (1 << 0) /* PCI ctl to hi-prio arbiter */
#define PCI_B2BMASK_B2BMASK(x) (((x) & 0xffff) << 16)
#define PCI_B2BMASK_CCH(x) ((x) & 0xffff) /* 16 upper bits of class code */
#define PCI_B2BBASE0_VID_B0(x) (((x) & 0xffff) << 16)
#define PCI_B2BBASE0_VID_SV(x) ((x) & 0xffff)
#define PCI_B2BBASE1_SID_B1(x) (((x) & 0xffff) << 16)
#define PCI_B2BBASE1_SID_SI(x) ((x) & 0xffff)
#define PCI_MWMASKDEV_MWMASK(x) (((x) & 0xffff) << 16)
#define PCI_MWMASKDEV_DEVID(x) ((x) & 0xffff)
#define PCI_MWBASEREVCCL_BASE(x) (((x) & 0xffff) << 16)
#define PCI_MWBASEREVCCL_REV(x) (((x) & 0xff) << 8)
#define PCI_MWBASEREVCCL_CCL(x) ((x) & 0xff)
#define PCI_ID_DID(x) (((x) & 0xffff) << 16)
#define PCI_ID_VID(x) ((x) & 0xffff)
#define PCI_STATCMD_STATUS(x) (((x) & 0xffff) << 16)
#define PCI_STATCMD_CMD(x) ((x) & 0xffff)
#define PCI_CLASSREV_CLASS(x) (((x) & 0x00ffffff) << 8)
#define PCI_CLASSREV_REV(x) ((x) & 0xff)
#define PCI_PARAM_BIST(x) (((x) & 0xff) << 24)
#define PCI_PARAM_HT(x) (((x) & 0xff) << 16)
#define PCI_PARAM_LT(x) (((x) & 0xff) << 8)
#define PCI_PARAM_CLS(x) ((x) & 0xff)
#define PCI_TIMEOUT_RETRIES(x) (((x) & 0xff) << 8) /* max retries */
#define PCI_TIMEOUT_TO(x) ((x) & 0xff) /* target ready timeout */
#endif #endif

View File

@ -1,43 +0,0 @@
/*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef _AU1XXX_H_
#define _AU1XXX_H_
#include <asm/mach-au1x00/au1000.h>
#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100) || \
defined(CONFIG_MIPS_DB1500) || defined(CONFIG_MIPS_DB1550)
#include <asm/mach-db1x00/db1x00.h>
#elif defined(CONFIG_MIPS_PB1550)
#include <asm/mach-pb1x00/pb1550.h>
#elif defined(CONFIG_MIPS_PB1200)
#include <asm/mach-pb1x00/pb1200.h>
#elif defined(CONFIG_MIPS_DB1200)
#include <asm/mach-db1x00/db1200.h>
#endif
#endif /* _AU1XXX_H_ */

View File

@ -126,66 +126,62 @@ typedef volatile struct au1xxx_ddma_desc {
#define SW_STATUS_INUSE (1 << 0) #define SW_STATUS_INUSE (1 << 0)
/* Command 0 device IDs. */ /* Command 0 device IDs. */
#ifdef CONFIG_SOC_AU1550 #define AU1550_DSCR_CMD0_UART0_TX 0
#define DSCR_CMD0_UART0_TX 0 #define AU1550_DSCR_CMD0_UART0_RX 1
#define DSCR_CMD0_UART0_RX 1 #define AU1550_DSCR_CMD0_UART3_TX 2
#define DSCR_CMD0_UART3_TX 2 #define AU1550_DSCR_CMD0_UART3_RX 3
#define DSCR_CMD0_UART3_RX 3 #define AU1550_DSCR_CMD0_DMA_REQ0 4
#define DSCR_CMD0_DMA_REQ0 4 #define AU1550_DSCR_CMD0_DMA_REQ1 5
#define DSCR_CMD0_DMA_REQ1 5 #define AU1550_DSCR_CMD0_DMA_REQ2 6
#define DSCR_CMD0_DMA_REQ2 6 #define AU1550_DSCR_CMD0_DMA_REQ3 7
#define DSCR_CMD0_DMA_REQ3 7 #define AU1550_DSCR_CMD0_USBDEV_RX0 8
#define DSCR_CMD0_USBDEV_RX0 8 #define AU1550_DSCR_CMD0_USBDEV_TX0 9
#define DSCR_CMD0_USBDEV_TX0 9 #define AU1550_DSCR_CMD0_USBDEV_TX1 10
#define DSCR_CMD0_USBDEV_TX1 10 #define AU1550_DSCR_CMD0_USBDEV_TX2 11
#define DSCR_CMD0_USBDEV_TX2 11 #define AU1550_DSCR_CMD0_USBDEV_RX3 12
#define DSCR_CMD0_USBDEV_RX3 12 #define AU1550_DSCR_CMD0_USBDEV_RX4 13
#define DSCR_CMD0_USBDEV_RX4 13 #define AU1550_DSCR_CMD0_PSC0_TX 14
#define DSCR_CMD0_PSC0_TX 14 #define AU1550_DSCR_CMD0_PSC0_RX 15
#define DSCR_CMD0_PSC0_RX 15 #define AU1550_DSCR_CMD0_PSC1_TX 16
#define DSCR_CMD0_PSC1_TX 16 #define AU1550_DSCR_CMD0_PSC1_RX 17
#define DSCR_CMD0_PSC1_RX 17 #define AU1550_DSCR_CMD0_PSC2_TX 18
#define DSCR_CMD0_PSC2_TX 18 #define AU1550_DSCR_CMD0_PSC2_RX 19
#define DSCR_CMD0_PSC2_RX 19 #define AU1550_DSCR_CMD0_PSC3_TX 20
#define DSCR_CMD0_PSC3_TX 20 #define AU1550_DSCR_CMD0_PSC3_RX 21
#define DSCR_CMD0_PSC3_RX 21 #define AU1550_DSCR_CMD0_PCI_WRITE 22
#define DSCR_CMD0_PCI_WRITE 22 #define AU1550_DSCR_CMD0_NAND_FLASH 23
#define DSCR_CMD0_NAND_FLASH 23 #define AU1550_DSCR_CMD0_MAC0_RX 24
#define DSCR_CMD0_MAC0_RX 24 #define AU1550_DSCR_CMD0_MAC0_TX 25
#define DSCR_CMD0_MAC0_TX 25 #define AU1550_DSCR_CMD0_MAC1_RX 26
#define DSCR_CMD0_MAC1_RX 26 #define AU1550_DSCR_CMD0_MAC1_TX 27
#define DSCR_CMD0_MAC1_TX 27
#endif /* CONFIG_SOC_AU1550 */
#ifdef CONFIG_SOC_AU1200 #define AU1200_DSCR_CMD0_UART0_TX 0
#define DSCR_CMD0_UART0_TX 0 #define AU1200_DSCR_CMD0_UART0_RX 1
#define DSCR_CMD0_UART0_RX 1 #define AU1200_DSCR_CMD0_UART1_TX 2
#define DSCR_CMD0_UART1_TX 2 #define AU1200_DSCR_CMD0_UART1_RX 3
#define DSCR_CMD0_UART1_RX 3 #define AU1200_DSCR_CMD0_DMA_REQ0 4
#define DSCR_CMD0_DMA_REQ0 4 #define AU1200_DSCR_CMD0_DMA_REQ1 5
#define DSCR_CMD0_DMA_REQ1 5 #define AU1200_DSCR_CMD0_MAE_BE 6
#define DSCR_CMD0_MAE_BE 6 #define AU1200_DSCR_CMD0_MAE_FE 7
#define DSCR_CMD0_MAE_FE 7 #define AU1200_DSCR_CMD0_SDMS_TX0 8
#define DSCR_CMD0_SDMS_TX0 8 #define AU1200_DSCR_CMD0_SDMS_RX0 9
#define DSCR_CMD0_SDMS_RX0 9 #define AU1200_DSCR_CMD0_SDMS_TX1 10
#define DSCR_CMD0_SDMS_TX1 10 #define AU1200_DSCR_CMD0_SDMS_RX1 11
#define DSCR_CMD0_SDMS_RX1 11 #define AU1200_DSCR_CMD0_AES_TX 13
#define DSCR_CMD0_AES_TX 13 #define AU1200_DSCR_CMD0_AES_RX 12
#define DSCR_CMD0_AES_RX 12 #define AU1200_DSCR_CMD0_PSC0_TX 14
#define DSCR_CMD0_PSC0_TX 14 #define AU1200_DSCR_CMD0_PSC0_RX 15
#define DSCR_CMD0_PSC0_RX 15 #define AU1200_DSCR_CMD0_PSC1_TX 16
#define DSCR_CMD0_PSC1_TX 16 #define AU1200_DSCR_CMD0_PSC1_RX 17
#define DSCR_CMD0_PSC1_RX 17 #define AU1200_DSCR_CMD0_CIM_RXA 18
#define DSCR_CMD0_CIM_RXA 18 #define AU1200_DSCR_CMD0_CIM_RXB 19
#define DSCR_CMD0_CIM_RXB 19 #define AU1200_DSCR_CMD0_CIM_RXC 20
#define DSCR_CMD0_CIM_RXC 20 #define AU1200_DSCR_CMD0_MAE_BOTH 21
#define DSCR_CMD0_MAE_BOTH 21 #define AU1200_DSCR_CMD0_LCD 22
#define DSCR_CMD0_LCD 22 #define AU1200_DSCR_CMD0_NAND_FLASH 23
#define DSCR_CMD0_NAND_FLASH 23 #define AU1200_DSCR_CMD0_PSC0_SYNC 24
#define DSCR_CMD0_PSC0_SYNC 24 #define AU1200_DSCR_CMD0_PSC1_SYNC 25
#define DSCR_CMD0_PSC1_SYNC 25 #define AU1200_DSCR_CMD0_CIM_SYNC 26
#define DSCR_CMD0_CIM_SYNC 26
#endif /* CONFIG_SOC_AU1200 */
#define DSCR_CMD0_THROTTLE 30 #define DSCR_CMD0_THROTTLE 30
#define DSCR_CMD0_ALWAYS 31 #define DSCR_CMD0_ALWAYS 31

View File

@ -58,6 +58,7 @@ typedef struct {
#endif #endif
int irq; int irq;
u32 regbase; u32 regbase;
int ddma_id;
} _auide_hwif; } _auide_hwif;
/******************************************************************************/ /******************************************************************************/

View File

@ -33,19 +33,6 @@
#ifndef _AU1000_PSC_H_ #ifndef _AU1000_PSC_H_
#define _AU1000_PSC_H_ #define _AU1000_PSC_H_
/* The PSC base addresses. */
#ifdef CONFIG_SOC_AU1550
#define PSC0_BASE_ADDR 0xb1a00000
#define PSC1_BASE_ADDR 0xb1b00000
#define PSC2_BASE_ADDR 0xb0a00000
#define PSC3_BASE_ADDR 0xb0b00000
#endif
#ifdef CONFIG_SOC_AU1200
#define PSC0_BASE_ADDR 0xb1a00000
#define PSC1_BASE_ADDR 0xb1b00000
#endif
/* /*
* The PSC select and control registers are common to all protocols. * The PSC select and control registers are common to all protocols.
*/ */
@ -80,19 +67,6 @@
#define PSC_AC97GPO_OFFSET 0x00000028 #define PSC_AC97GPO_OFFSET 0x00000028
#define PSC_AC97GPI_OFFSET 0x0000002c #define PSC_AC97GPI_OFFSET 0x0000002c
#define AC97_PSC_SEL (AC97_PSC_BASE + PSC_SEL_OFFSET)
#define AC97_PSC_CTRL (AC97_PSC_BASE + PSC_CTRL_OFFSET)
#define PSC_AC97CFG (AC97_PSC_BASE + PSC_AC97CFG_OFFSET)
#define PSC_AC97MSK (AC97_PSC_BASE + PSC_AC97MSK_OFFSET)
#define PSC_AC97PCR (AC97_PSC_BASE + PSC_AC97PCR_OFFSET)
#define PSC_AC97STAT (AC97_PSC_BASE + PSC_AC97STAT_OFFSET)
#define PSC_AC97EVNT (AC97_PSC_BASE + PSC_AC97EVNT_OFFSET)
#define PSC_AC97TXRX (AC97_PSC_BASE + PSC_AC97TXRX_OFFSET)
#define PSC_AC97CDC (AC97_PSC_BASE + PSC_AC97CDC_OFFSET)
#define PSC_AC97RST (AC97_PSC_BASE + PSC_AC97RST_OFFSET)
#define PSC_AC97GPO (AC97_PSC_BASE + PSC_AC97GPO_OFFSET)
#define PSC_AC97GPI (AC97_PSC_BASE + PSC_AC97GPI_OFFSET)
/* AC97 Config Register. */ /* AC97 Config Register. */
#define PSC_AC97CFG_RT_MASK (3 << 30) #define PSC_AC97CFG_RT_MASK (3 << 30)
#define PSC_AC97CFG_RT_FIFO1 (0 << 30) #define PSC_AC97CFG_RT_FIFO1 (0 << 30)

View File

@ -347,17 +347,6 @@ static inline int alchemy_gpio2_to_irq(int gpio)
/**********************************************************************/ /**********************************************************************/
/* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before
* SYS_PININPUTEN is written to at least once. On Au1550/Au1200 this
* register enables use of GPIOs as wake source.
*/
static inline void alchemy_gpio1_input_enable(void)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
__raw_writel(0, base + SYS_PININPUTEN); /* the write op is key */
wmb();
}
/* GPIO2 shared interrupts and control */ /* GPIO2 shared interrupts and control */
static inline void __alchemy_gpio2_mod_int(int gpio2, int en) static inline void __alchemy_gpio2_mod_int(int gpio2, int en)
@ -561,6 +550,7 @@ static inline int alchemy_irq_to_gpio(int irq)
#ifndef CONFIG_GPIOLIB #ifndef CONFIG_GPIOLIB
#ifdef CONFIG_ALCHEMY_GPIOINT_AU1000
#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */ #ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */
@ -665,24 +655,7 @@ static inline void gpio_unexport(unsigned gpio)
#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */ #endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
#endif /* CONFIG_ALCHEMY_GPIOINT_AU1000 */
#else /* CONFIG GPIOLIB */
/* using gpiolib to provide up to 2 gpio_chips for on-chip gpios */
#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (2) */
/* get everything through gpiolib */
#define gpio_to_irq __gpio_to_irq
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
#define gpio_cansleep __gpio_cansleep
#define irq_to_gpio alchemy_irq_to_gpio
#include <asm-generic/gpio.h>
#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
#endif /* !CONFIG_GPIOLIB */ #endif /* !CONFIG_GPIOLIB */

View File

@ -1,10 +1,83 @@
/*
* Alchemy GPIO support.
*
* With CONFIG_GPIOLIB=y different types of on-chip GPIO can be supported within
* the same kernel image.
* With CONFIG_GPIOLIB=n, your board must select ALCHEMY_GPIOINT_AU1XXX for the
* appropriate CPU type (AU1000 currently).
*/
#ifndef _ALCHEMY_GPIO_H_ #ifndef _ALCHEMY_GPIO_H_
#define _ALCHEMY_GPIO_H_ #define _ALCHEMY_GPIO_H_
#if defined(CONFIG_ALCHEMY_GPIOINT_AU1000) #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/gpio-au1000.h> #include <asm/mach-au1x00/gpio-au1000.h>
#endif /* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before
* SYS_PININPUTEN is written to at least once. On Au1550/Au1200/Au1300 this
* register enables use of GPIOs as wake source.
*/
static inline void alchemy_gpio1_input_enable(void)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR);
__raw_writel(0, base + 0x110); /* the write op is key */
wmb();
}
/* Linux gpio framework integration.
*
* 4 use cases of Alchemy GPIOS:
*(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y:
* Board must register gpiochips.
*(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n:
* A gpiochip for the 75 GPIOs is registered.
*
*(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y:
* the boards' gpio.h must provide the linux gpio wrapper functions,
*
*(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n:
* inlinable gpio functions are provided which enable access to the
* Au1300 gpios only by using the numbers straight out of the data-
* sheets.
* Cases 1 and 3 are intended for boards which want to provide their own
* GPIO namespace and -operations (i.e. for example you have 8 GPIOs
* which are in part provided by spare Au1300 GPIO pins and in part by
* an external FPGA but you still want them to be accssible in linux
* as gpio0-7. The board can of course use the alchemy_gpioX_* functions
* as required).
*/
#ifdef CONFIG_GPIOLIB
/* wraps the cpu-dependent irq_to_gpio functions */
/* FIXME: gpiolib needs an irq_to_gpio hook */
static inline int __au_irq_to_gpio(unsigned int irq)
{
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200:
return alchemy_irq_to_gpio(irq);
}
return -EINVAL;
}
/* using gpiolib to provide up to 2 gpio_chips for on-chip gpios */
#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (2) */
/* get everything through gpiolib */
#define gpio_to_irq __gpio_to_irq
#define gpio_get_value __gpio_get_value
#define gpio_set_value __gpio_set_value
#define gpio_cansleep __gpio_cansleep
#define irq_to_gpio __au_irq_to_gpio
#include <asm-generic/gpio.h>
#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
#endif /* CONFIG_GPIOLIB */
#endif /* _ALCHEMY_GPIO_H_ */ #endif /* _ALCHEMY_GPIO_H_ */

View File

@ -46,8 +46,6 @@
#define IDE_PHYS_ADDR 0x18800000 #define IDE_PHYS_ADDR 0x18800000
#define IDE_REG_SHIFT 5 #define IDE_REG_SHIFT 5
#define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1
#define IDE_RQSIZE 128
#define DB1200_IDE_PHYS_ADDR IDE_PHYS_ADDR #define DB1200_IDE_PHYS_ADDR IDE_PHYS_ADDR
#define DB1200_IDE_PHYS_LEN (16 << IDE_REG_SHIFT) #define DB1200_IDE_PHYS_LEN (16 << IDE_REG_SHIFT)

View File

@ -31,15 +31,15 @@
#ifdef CONFIG_MIPS_DB1550 #ifdef CONFIG_MIPS_DB1550
#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX #define DBDMA_AC97_TX_CHAN AU1550_DSCR_CMD0_PSC1_TX
#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX #define DBDMA_AC97_RX_CHAN AU1550_DSCR_CMD0_PSC1_RX
#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX #define DBDMA_I2S_TX_CHAN AU1550_DSCR_CMD0_PSC3_TX
#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX #define DBDMA_I2S_RX_CHAN AU1550_DSCR_CMD0_PSC3_RX
#define SPI_PSC_BASE PSC0_BASE_ADDR #define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR
#define AC97_PSC_BASE PSC1_BASE_ADDR #define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR
#define SMBUS_PSC_BASE PSC2_BASE_ADDR #define SMBUS_PSC_BASE AU1550_PSC2_PHYS_ADDR
#define I2S_PSC_BASE PSC3_BASE_ADDR #define I2S_PSC_BASE AU1550_PSC3_PHYS_ADDR
#define NAND_PHYS_ADDR 0x20000000 #define NAND_PHYS_ADDR 0x20000000

View File

@ -28,23 +28,23 @@
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_psc.h> #include <asm/mach-au1x00/au1xxx_psc.h>
#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX #define DBDMA_AC97_TX_CHAN AU1200_DSCR_CMD0_PSC1_TX
#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX #define DBDMA_AC97_RX_CHAN AU1200_DSCR_CMD0_PSC1_RX
#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC1_TX #define DBDMA_I2S_TX_CHAN AU1200_DSCR_CMD0_PSC1_TX
#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC1_RX #define DBDMA_I2S_RX_CHAN AU1200_DSCR_CMD0_PSC1_RX
/* /*
* SPI and SMB are muxed on the Pb1200 board. * SPI and SMB are muxed on the Pb1200 board.
* Refer to board documentation. * Refer to board documentation.
*/ */
#define SPI_PSC_BASE PSC0_BASE_ADDR #define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR
#define SMBUS_PSC_BASE PSC0_BASE_ADDR #define SMBUS_PSC_BASE AU1550_PSC0_PHYS_ADDR
/* /*
* AC97 and I2S are muxed on the Pb1200 board. * AC97 and I2S are muxed on the Pb1200 board.
* Refer to board documentation. * Refer to board documentation.
*/ */
#define AC97_PSC_BASE PSC1_BASE_ADDR #define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR
#define I2S_PSC_BASE PSC1_BASE_ADDR #define I2S_PSC_BASE AU1550_PSC1_PHYS_ADDR
#define BCSR_SYSTEM_VDDI 0x001F #define BCSR_SYSTEM_VDDI 0x001F
@ -76,8 +76,6 @@
#define IDE_REG_SHIFT 5 #define IDE_REG_SHIFT 5
#define IDE_PHYS_LEN (16 << IDE_REG_SHIFT) #define IDE_PHYS_LEN (16 << IDE_REG_SHIFT)
#define IDE_INT PB1200_IDE_INT #define IDE_INT PB1200_IDE_INT
#define IDE_DDMA_REQ DSCR_CMD0_DMA_REQ1
#define IDE_RQSIZE 128
#define NAND_PHYS_ADDR 0x1C000000 #define NAND_PHYS_ADDR 0x1C000000

View File

@ -30,15 +30,15 @@
#include <linux/types.h> #include <linux/types.h>
#include <asm/mach-au1x00/au1xxx_psc.h> #include <asm/mach-au1x00/au1xxx_psc.h>
#define DBDMA_AC97_TX_CHAN DSCR_CMD0_PSC1_TX #define DBDMA_AC97_TX_CHAN AU1550_DSCR_CMD0_PSC1_TX
#define DBDMA_AC97_RX_CHAN DSCR_CMD0_PSC1_RX #define DBDMA_AC97_RX_CHAN AU1550_DSCR_CMD0_PSC1_RX
#define DBDMA_I2S_TX_CHAN DSCR_CMD0_PSC3_TX #define DBDMA_I2S_TX_CHAN AU1550_DSCR_CMD0_PSC3_TX
#define DBDMA_I2S_RX_CHAN DSCR_CMD0_PSC3_RX #define DBDMA_I2S_RX_CHAN AU1550_DSCR_CMD0_PSC3_RX
#define SPI_PSC_BASE PSC0_BASE_ADDR #define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR
#define AC97_PSC_BASE PSC1_BASE_ADDR #define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR
#define SMBUS_PSC_BASE PSC2_BASE_ADDR #define SMBUS_PSC_BASE AU1550_PSC2_PHYS_ADDR
#define I2S_PSC_BASE PSC3_BASE_ADDR #define I2S_PSC_BASE AU1550_PSC3_PHYS_ADDR
/* /*
* Timing values as described in databook, * ns value stripped of * Timing values as described in databook, * ns value stripped of

View File

@ -1,5 +1,5 @@
#ifndef __ASM_MIPS_PROM_H #ifndef __ASM_MIPSPROM_H
#define __ASM_MIPS_PROM_H #define __ASM_MIPSPROM_H
#define PROM_RESET 0 #define PROM_RESET 0
#define PROM_EXEC 1 #define PROM_EXEC 1
@ -73,4 +73,4 @@
extern char *prom_getenv(char *); extern char *prom_getenv(char *);
#endif /* __ASM_MIPS_PROM_H */ #endif /* __ASM_MIPSPROM_H */

View File

@ -1006,18 +1006,26 @@ do { \
#define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val) #define write_c0_perfctrl0(val) __write_32bit_c0_register($25, 0, val)
#define read_c0_perfcntr0() __read_32bit_c0_register($25, 1) #define read_c0_perfcntr0() __read_32bit_c0_register($25, 1)
#define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val) #define write_c0_perfcntr0(val) __write_32bit_c0_register($25, 1, val)
#define read_c0_perfcntr0_64() __read_64bit_c0_register($25, 1)
#define write_c0_perfcntr0_64(val) __write_64bit_c0_register($25, 1, val)
#define read_c0_perfctrl1() __read_32bit_c0_register($25, 2) #define read_c0_perfctrl1() __read_32bit_c0_register($25, 2)
#define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val) #define write_c0_perfctrl1(val) __write_32bit_c0_register($25, 2, val)
#define read_c0_perfcntr1() __read_32bit_c0_register($25, 3) #define read_c0_perfcntr1() __read_32bit_c0_register($25, 3)
#define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val) #define write_c0_perfcntr1(val) __write_32bit_c0_register($25, 3, val)
#define read_c0_perfcntr1_64() __read_64bit_c0_register($25, 3)
#define write_c0_perfcntr1_64(val) __write_64bit_c0_register($25, 3, val)
#define read_c0_perfctrl2() __read_32bit_c0_register($25, 4) #define read_c0_perfctrl2() __read_32bit_c0_register($25, 4)
#define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val) #define write_c0_perfctrl2(val) __write_32bit_c0_register($25, 4, val)
#define read_c0_perfcntr2() __read_32bit_c0_register($25, 5) #define read_c0_perfcntr2() __read_32bit_c0_register($25, 5)
#define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val) #define write_c0_perfcntr2(val) __write_32bit_c0_register($25, 5, val)
#define read_c0_perfcntr2_64() __read_64bit_c0_register($25, 5)
#define write_c0_perfcntr2_64(val) __write_64bit_c0_register($25, 5, val)
#define read_c0_perfctrl3() __read_32bit_c0_register($25, 6) #define read_c0_perfctrl3() __read_32bit_c0_register($25, 6)
#define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val) #define write_c0_perfctrl3(val) __write_32bit_c0_register($25, 6, val)
#define read_c0_perfcntr3() __read_32bit_c0_register($25, 7) #define read_c0_perfcntr3() __read_32bit_c0_register($25, 7)
#define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val) #define write_c0_perfcntr3(val) __write_32bit_c0_register($25, 7, val)
#define read_c0_perfcntr3_64() __read_64bit_c0_register($25, 7)
#define write_c0_perfcntr3_64(val) __write_64bit_c0_register($25, 7, val)
/* RM9000 PerfCount performance counter register */ /* RM9000 PerfCount performance counter register */
#define read_c0_perfcount() __read_64bit_c0_register($25, 0) #define read_c0_perfcount() __read_64bit_c0_register($25, 0)

View File

@ -8,8 +8,8 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
* *
*/ */
#ifndef __ASM_MIPS_PROM_H #ifndef __ASM_PROM_H
#define __ASM_MIPS_PROM_H #define __ASM_PROM_H
#ifdef CONFIG_OF #ifdef CONFIG_OF
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
@ -25,4 +25,4 @@ extern void device_tree_init(void);
static inline void device_tree_init(void) { } static inline void device_tree_init(void) { }
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
#endif /* _ASM_MIPS_PROM_H */ #endif /* __ASM_PROM_H */

View File

@ -6,6 +6,8 @@
* Copyright (C) 1985 MIPS Computer Systems, Inc. * Copyright (C) 1985 MIPS Computer Systems, Inc.
* Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle * Copyright (C) 1994, 95, 99, 2003 by Ralf Baechle
* Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc. * Copyright (C) 1990 - 1992, 1999 Silicon Graphics, Inc.
* Copyright (C) 2011 Wind River Systems,
* written by Ralf Baechle <ralf@linux-mips.org>
*/ */
#ifndef _ASM_REGDEF_H #ifndef _ASM_REGDEF_H
#define _ASM_REGDEF_H #define _ASM_REGDEF_H
@ -30,9 +32,13 @@
#define t2 $10 #define t2 $10
#define t3 $11 #define t3 $11
#define t4 $12 #define t4 $12
#define ta0 $12
#define t5 $13 #define t5 $13
#define ta1 $13
#define t6 $14 #define t6 $14
#define ta2 $14
#define t7 $15 #define t7 $15
#define ta3 $15
#define s0 $16 /* callee saved */ #define s0 $16 /* callee saved */
#define s1 $17 #define s1 $17
#define s2 $18 #define s2 $18

View File

@ -17,8 +17,6 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/spinlock.h>
#include <linux/syscore_ops.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/delay.h> #include <linux/delay.h>
@ -30,6 +28,8 @@
#include <asm/mach-jz4740/base.h> #include <asm/mach-jz4740/base.h>
#include "irq.h"
#define JZ4740_GPIO_BASE_A (32*0) #define JZ4740_GPIO_BASE_A (32*0)
#define JZ4740_GPIO_BASE_B (32*1) #define JZ4740_GPIO_BASE_B (32*1)
#define JZ4740_GPIO_BASE_C (32*2) #define JZ4740_GPIO_BASE_C (32*2)
@ -77,14 +77,10 @@
struct jz_gpio_chip { struct jz_gpio_chip {
unsigned int irq; unsigned int irq;
unsigned int irq_base; unsigned int irq_base;
uint32_t wakeup;
uint32_t suspend_mask;
uint32_t edge_trigger_both; uint32_t edge_trigger_both;
void __iomem *base; void __iomem *base;
spinlock_t lock;
struct gpio_chip gpio_chip; struct gpio_chip gpio_chip;
}; };
@ -102,7 +98,8 @@ static inline struct jz_gpio_chip *gpio_chip_to_jz_gpio_chip(struct gpio_chip *g
static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data) static inline struct jz_gpio_chip *irq_to_jz_gpio_chip(struct irq_data *data)
{ {
return irq_data_get_irq_chip_data(data); struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
return gc->private;
} }
static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg) static inline void jz_gpio_write_bit(unsigned int gpio, unsigned int reg)
@ -304,21 +301,15 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
{ {
uint32_t flag; uint32_t flag;
unsigned int gpio_irq; unsigned int gpio_irq;
unsigned int gpio_bank;
struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc); struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc);
gpio_bank = JZ4740_IRQ_GPIO0 - irq;
flag = readl(chip->base + JZ_REG_GPIO_FLAG); flag = readl(chip->base + JZ_REG_GPIO_FLAG);
if (!flag) if (!flag)
return; return;
gpio_irq = __fls(flag); gpio_irq = chip->irq_base + __fls(flag);
jz_gpio_check_trigger_both(chip, irq); jz_gpio_check_trigger_both(chip, gpio_irq);
gpio_irq += (gpio_bank << 5) + JZ4740_IRQ_GPIO(0);
generic_handle_irq(gpio_irq); generic_handle_irq(gpio_irq);
}; };
@ -329,18 +320,12 @@ static inline void jz_gpio_set_irq_bit(struct irq_data *data, unsigned int reg)
writel(IRQ_TO_BIT(data->irq), chip->base + reg); writel(IRQ_TO_BIT(data->irq), chip->base + reg);
} }
static void jz_gpio_irq_mask(struct irq_data *data)
{
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_SET);
};
static void jz_gpio_irq_unmask(struct irq_data *data) static void jz_gpio_irq_unmask(struct irq_data *data)
{ {
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
jz_gpio_check_trigger_both(chip, data->irq); jz_gpio_check_trigger_both(chip, data->irq);
irq_gc_unmask_enable_reg(data);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_MASK_CLEAR);
}; };
/* TODO: Check if function is gpio */ /* TODO: Check if function is gpio */
@ -353,18 +338,13 @@ static unsigned int jz_gpio_irq_startup(struct irq_data *data)
static void jz_gpio_irq_shutdown(struct irq_data *data) static void jz_gpio_irq_shutdown(struct irq_data *data)
{ {
jz_gpio_irq_mask(data); irq_gc_mask_disable_reg(data);
/* Set direction to input */ /* Set direction to input */
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR); jz_gpio_set_irq_bit(data, JZ_REG_GPIO_DIRECTION_CLEAR);
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR); jz_gpio_set_irq_bit(data, JZ_REG_GPIO_SELECT_CLEAR);
} }
static void jz_gpio_irq_ack(struct irq_data *data)
{
jz_gpio_set_irq_bit(data, JZ_REG_GPIO_FLAG_CLEAR);
};
static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type) static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
{ {
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
@ -408,35 +388,13 @@ static int jz_gpio_irq_set_type(struct irq_data *data, unsigned int flow_type)
static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on) static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
{ {
struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data); struct jz_gpio_chip *chip = irq_to_jz_gpio_chip(data);
spin_lock(&chip->lock);
if (on)
chip->wakeup |= IRQ_TO_BIT(data->irq);
else
chip->wakeup &= ~IRQ_TO_BIT(data->irq);
spin_unlock(&chip->lock);
irq_gc_set_wake(data, on);
irq_set_irq_wake(chip->irq, on); irq_set_irq_wake(chip->irq, on);
return 0; return 0;
} }
static struct irq_chip jz_gpio_irq_chip = {
.name = "GPIO",
.irq_mask = jz_gpio_irq_mask,
.irq_unmask = jz_gpio_irq_unmask,
.irq_ack = jz_gpio_irq_ack,
.irq_startup = jz_gpio_irq_startup,
.irq_shutdown = jz_gpio_irq_shutdown,
.irq_set_type = jz_gpio_irq_set_type,
.irq_set_wake = jz_gpio_irq_set_wake,
.flags = IRQCHIP_SET_TYPE_MASKED,
};
/*
* This lock class tells lockdep that GPIO irqs are in a different
* category than their parents, so it won't report false recursion.
*/
static struct lock_class_key gpio_lock_class;
#define JZ4740_GPIO_CHIP(_bank) { \ #define JZ4740_GPIO_CHIP(_bank) { \
.irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \ .irq_base = JZ4740_IRQ_GPIO_BASE_ ## _bank, \
.gpio_chip = { \ .gpio_chip = { \
@ -458,64 +416,44 @@ static struct jz_gpio_chip jz4740_gpio_chips[] = {
JZ4740_GPIO_CHIP(D), JZ4740_GPIO_CHIP(D),
}; };
static void jz4740_gpio_suspend_chip(struct jz_gpio_chip *chip)
{
chip->suspend_mask = readl(chip->base + JZ_REG_GPIO_MASK);
writel(~(chip->wakeup), chip->base + JZ_REG_GPIO_MASK_SET);
writel(chip->wakeup, chip->base + JZ_REG_GPIO_MASK_CLEAR);
}
static int jz4740_gpio_suspend(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); i++)
jz4740_gpio_suspend_chip(&jz4740_gpio_chips[i]);
return 0;
}
static void jz4740_gpio_resume_chip(struct jz_gpio_chip *chip)
{
uint32_t mask = chip->suspend_mask;
writel(~mask, chip->base + JZ_REG_GPIO_MASK_CLEAR);
writel(mask, chip->base + JZ_REG_GPIO_MASK_SET);
}
static void jz4740_gpio_resume(void)
{
int i;
for (i = ARRAY_SIZE(jz4740_gpio_chips) - 1; i >= 0 ; i--)
jz4740_gpio_resume_chip(&jz4740_gpio_chips[i]);
}
static struct syscore_ops jz4740_gpio_syscore_ops = {
.suspend = jz4740_gpio_suspend,
.resume = jz4740_gpio_resume,
};
static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id) static void jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
{ {
int irq; struct irq_chip_generic *gc;
struct irq_chip_type *ct;
spin_lock_init(&chip->lock);
chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100); chip->base = ioremap(JZ4740_GPIO_BASE_ADDR + (id * 0x100), 0x100);
gpiochip_add(&chip->gpio_chip);
chip->irq = JZ4740_IRQ_INTC_GPIO(id); chip->irq = JZ4740_IRQ_INTC_GPIO(id);
irq_set_handler_data(chip->irq, chip); irq_set_handler_data(chip->irq, chip);
irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler); irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) { gc = irq_alloc_generic_chip(chip->gpio_chip.label, 1, chip->irq_base,
irq_set_lockdep_class(irq, &gpio_lock_class); chip->base, handle_level_irq);
irq_set_chip_data(irq, chip);
irq_set_chip_and_handler(irq, &jz_gpio_irq_chip, gc->wake_enabled = IRQ_MSK(chip->gpio_chip.ngpio);
handle_level_irq); gc->private = chip;
}
ct = gc->chip_types;
ct->regs.enable = JZ_REG_GPIO_MASK_CLEAR;
ct->regs.disable = JZ_REG_GPIO_MASK_SET;
ct->regs.ack = JZ_REG_GPIO_FLAG_CLEAR;
ct->chip.name = "GPIO";
ct->chip.irq_mask = irq_gc_mask_disable_reg;
ct->chip.irq_unmask = jz_gpio_irq_unmask;
ct->chip.irq_ack = irq_gc_ack_set_bit;
ct->chip.irq_suspend = jz4740_irq_suspend;
ct->chip.irq_resume = jz4740_irq_resume;
ct->chip.irq_startup = jz_gpio_irq_startup;
ct->chip.irq_shutdown = jz_gpio_irq_shutdown;
ct->chip.irq_set_type = jz_gpio_irq_set_type;
ct->chip.irq_set_wake = jz_gpio_irq_set_wake;
ct->chip.flags = IRQCHIP_SET_TYPE_MASKED;
irq_setup_generic_chip(gc, IRQ_MSK(chip->gpio_chip.ngpio),
IRQ_GC_INIT_NESTED_LOCK, 0, IRQ_NOPROBE | IRQ_LEVEL);
gpiochip_add(&chip->gpio_chip);
} }
static int __init jz4740_gpio_init(void) static int __init jz4740_gpio_init(void)
@ -525,8 +463,6 @@ static int __init jz4740_gpio_init(void)
for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i)
jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i);
register_syscore_ops(&jz4740_gpio_syscore_ops);
printk(KERN_INFO "JZ4740 GPIO initialized\n"); printk(KERN_INFO "JZ4740 GPIO initialized\n");
return 0; return 0;

View File

@ -32,8 +32,6 @@
#include <asm/mach-jz4740/base.h> #include <asm/mach-jz4740/base.h>
static void __iomem *jz_intc_base; static void __iomem *jz_intc_base;
static uint32_t jz_intc_wakeup;
static uint32_t jz_intc_saved;
#define JZ_REG_INTC_STATUS 0x00 #define JZ_REG_INTC_STATUS 0x00
#define JZ_REG_INTC_MASK 0x04 #define JZ_REG_INTC_MASK 0x04
@ -41,41 +39,6 @@ static uint32_t jz_intc_saved;
#define JZ_REG_INTC_CLEAR_MASK 0x0c #define JZ_REG_INTC_CLEAR_MASK 0x0c
#define JZ_REG_INTC_PENDING 0x10 #define JZ_REG_INTC_PENDING 0x10
#define IRQ_BIT(x) BIT((x) - JZ4740_IRQ_BASE)
static inline unsigned long intc_irq_bit(struct irq_data *data)
{
return (unsigned long)irq_data_get_irq_chip_data(data);
}
static void intc_irq_unmask(struct irq_data *data)
{
writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
}
static void intc_irq_mask(struct irq_data *data)
{
writel(intc_irq_bit(data), jz_intc_base + JZ_REG_INTC_SET_MASK);
}
static int intc_irq_set_wake(struct irq_data *data, unsigned int on)
{
if (on)
jz_intc_wakeup |= intc_irq_bit(data);
else
jz_intc_wakeup &= ~intc_irq_bit(data);
return 0;
}
static struct irq_chip intc_irq_type = {
.name = "INTC",
.irq_mask = intc_irq_mask,
.irq_mask_ack = intc_irq_mask,
.irq_unmask = intc_irq_unmask,
.irq_set_wake = intc_irq_set_wake,
};
static irqreturn_t jz4740_cascade(int irq, void *data) static irqreturn_t jz4740_cascade(int irq, void *data)
{ {
uint32_t irq_reg; uint32_t irq_reg;
@ -88,6 +51,26 @@ static irqreturn_t jz4740_cascade(int irq, void *data)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static void jz4740_irq_set_mask(struct irq_chip_generic *gc, uint32_t mask)
{
struct irq_chip_regs *regs = &gc->chip_types->regs;
writel(mask, gc->reg_base + regs->enable);
writel(~mask, gc->reg_base + regs->disable);
}
void jz4740_irq_suspend(struct irq_data *data)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
jz4740_irq_set_mask(gc, gc->wake_active);
}
void jz4740_irq_resume(struct irq_data *data)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(data);
jz4740_irq_set_mask(gc, gc->mask_cache);
}
static struct irqaction jz4740_cascade_action = { static struct irqaction jz4740_cascade_action = {
.handler = jz4740_cascade, .handler = jz4740_cascade,
.name = "JZ4740 cascade interrupt", .name = "JZ4740 cascade interrupt",
@ -95,7 +78,9 @@ static struct irqaction jz4740_cascade_action = {
void __init arch_init_irq(void) void __init arch_init_irq(void)
{ {
int i; struct irq_chip_generic *gc;
struct irq_chip_type *ct;
mips_cpu_irq_init(); mips_cpu_irq_init();
jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14); jz_intc_base = ioremap(JZ4740_INTC_BASE_ADDR, 0x14);
@ -103,10 +88,22 @@ void __init arch_init_irq(void)
/* Mask all irqs */ /* Mask all irqs */
writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK); writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) { gc = irq_alloc_generic_chip("INTC", 1, JZ4740_IRQ_BASE, jz_intc_base,
irq_set_chip_data(i, (void *)IRQ_BIT(i)); handle_level_irq);
irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq);
} gc->wake_enabled = IRQ_MSK(32);
ct = gc->chip_types;
ct->regs.enable = JZ_REG_INTC_CLEAR_MASK;
ct->regs.disable = JZ_REG_INTC_SET_MASK;
ct->chip.irq_unmask = irq_gc_unmask_enable_reg;
ct->chip.irq_mask = irq_gc_mask_disable_reg;
ct->chip.irq_mask_ack = irq_gc_mask_disable_reg;
ct->chip.irq_set_wake = irq_gc_set_wake;
ct->chip.irq_suspend = jz4740_irq_suspend;
ct->chip.irq_resume = jz4740_irq_resume;
irq_setup_generic_chip(gc, IRQ_MSK(32), 0, 0, IRQ_NOPROBE | IRQ_LEVEL);
setup_irq(2, &jz4740_cascade_action); setup_irq(2, &jz4740_cascade_action);
} }
@ -122,19 +119,6 @@ asmlinkage void plat_irq_dispatch(void)
spurious_interrupt(); spurious_interrupt();
} }
void jz4740_intc_suspend(void)
{
jz_intc_saved = readl(jz_intc_base + JZ_REG_INTC_MASK);
writel(~jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_SET_MASK);
writel(jz_intc_wakeup, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
}
void jz4740_intc_resume(void)
{
writel(~jz_intc_saved, jz_intc_base + JZ_REG_INTC_CLEAR_MASK);
writel(jz_intc_saved, jz_intc_base + JZ_REG_INTC_SET_MASK);
}
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
static inline void intc_seq_reg(struct seq_file *s, const char *name, static inline void intc_seq_reg(struct seq_file *s, const char *name,

View File

@ -15,7 +15,9 @@
#ifndef __MIPS_JZ4740_IRQ_H__ #ifndef __MIPS_JZ4740_IRQ_H__
#define __MIPS_JZ4740_IRQ_H__ #define __MIPS_JZ4740_IRQ_H__
extern void jz4740_intc_suspend(void); #include <linux/irq.h>
extern void jz4740_intc_resume(void);
extern void jz4740_irq_suspend(struct irq_data *data);
extern void jz4740_irq_resume(struct irq_data *data);
#endif #endif

View File

@ -21,11 +21,9 @@
#include <asm/mach-jz4740/clock.h> #include <asm/mach-jz4740/clock.h>
#include "clock.h" #include "clock.h"
#include "irq.h"
static int jz4740_pm_enter(suspend_state_t state) static int jz4740_pm_enter(suspend_state_t state)
{ {
jz4740_intc_suspend();
jz4740_clock_suspend(); jz4740_clock_suspend();
jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP); jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_SLEEP);
@ -37,7 +35,6 @@ static int jz4740_pm_enter(suspend_state_t state)
jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE); jz4740_clock_set_wait_mode(JZ4740_WAIT_MODE_IDLE);
jz4740_clock_resume(); jz4740_clock_resume();
jz4740_intc_resume();
return 0; return 0;
} }

View File

@ -11,6 +11,8 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
ifdef CONFIG_FUNCTION_TRACER ifdef CONFIG_FUNCTION_TRACER
CFLAGS_REMOVE_ftrace.o = -pg CFLAGS_REMOVE_ftrace.o = -pg
CFLAGS_REMOVE_early_printk.o = -pg CFLAGS_REMOVE_early_printk.o = -pg
CFLAGS_REMOVE_perf_event.o = -pg
CFLAGS_REMOVE_perf_event_mipsxx.o = -pg
endif endif
obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
@ -106,7 +108,8 @@ obj-$(CONFIG_HAVE_STD_PC_SERIAL_PORT) += 8250-platform.o
obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/ obj-$(CONFIG_MIPS_CPUFREQ) += cpufreq/
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o obj-$(CONFIG_PERF_EVENTS) += perf_event.o
obj-$(CONFIG_HW_PERF_EVENTS) += perf_event_mipsxx.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o obj-$(CONFIG_JUMP_LABEL) += jump_label.o

View File

@ -978,7 +978,10 @@ static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
platform: platform:
set_elf_platform(cpu, "octeon"); set_elf_platform(cpu, "octeon");
break; break;
case PRID_IMP_CAVIUM_CN61XX:
case PRID_IMP_CAVIUM_CN63XX: case PRID_IMP_CAVIUM_CN63XX:
case PRID_IMP_CAVIUM_CN66XX:
case PRID_IMP_CAVIUM_CN68XX:
c->cputype = CPU_CAVIUM_OCTEON2; c->cputype = CPU_CAVIUM_OCTEON2;
__cpu_name[cpu] = "Cavium Octeon II"; __cpu_name[cpu] = "Cavium Octeon II";
set_elf_platform(cpu, "octeon2"); set_elf_platform(cpu, "octeon2");

View File

@ -14,533 +14,16 @@
* published by the Free Software Foundation. * published by the Free Software Foundation.
*/ */
#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/smp.h>
#include <linux/kernel.h>
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/uaccess.h>
#include <asm/irq.h>
#include <asm/irq_regs.h>
#include <asm/stacktrace.h> #include <asm/stacktrace.h>
#include <asm/time.h> /* For perf_irq */
/* These are for 32bit counters. For 64bit ones, define them accordingly. */
#define MAX_PERIOD ((1ULL << 32) - 1)
#define VALID_COUNT 0x7fffffff
#define TOTAL_BITS 32
#define HIGHEST_BIT 31
#define MIPS_MAX_HWEVENTS 4
struct cpu_hw_events {
/* Array of events on this cpu. */
struct perf_event *events[MIPS_MAX_HWEVENTS];
/*
* Set the bit (indexed by the counter number) when the counter
* is used for an event.
*/
unsigned long used_mask[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
/*
* The borrowed MSB for the performance counter. A MIPS performance
* counter uses its bit 31 (for 32bit counters) or bit 63 (for 64bit
* counters) as a factor of determining whether a counter overflow
* should be signaled. So here we use a separate MSB for each
* counter to make things easy.
*/
unsigned long msbs[BITS_TO_LONGS(MIPS_MAX_HWEVENTS)];
/*
* Software copy of the control register for each performance counter.
* MIPS CPUs vary in performance counters. They use this differently,
* and even may not use it.
*/
unsigned int saved_ctrl[MIPS_MAX_HWEVENTS];
};
DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = {
.saved_ctrl = {0},
};
/* The description of MIPS performance events. */
struct mips_perf_event {
unsigned int event_id;
/*
* MIPS performance counters are indexed starting from 0.
* CNTR_EVEN indicates the indexes of the counters to be used are
* even numbers.
*/
unsigned int cntr_mask;
#define CNTR_EVEN 0x55555555
#define CNTR_ODD 0xaaaaaaaa
#ifdef CONFIG_MIPS_MT_SMP
enum {
T = 0,
V = 1,
P = 2,
} range;
#else
#define T
#define V
#define P
#endif
};
static struct mips_perf_event raw_event;
static DEFINE_MUTEX(raw_event_mutex);
#define UNSUPPORTED_PERF_EVENT_ID 0xffffffff
#define C(x) PERF_COUNT_HW_CACHE_##x
struct mips_pmu {
const char *name;
int irq;
irqreturn_t (*handle_irq)(int irq, void *dev);
int (*handle_shared_irq)(void);
void (*start)(void);
void (*stop)(void);
int (*alloc_counter)(struct cpu_hw_events *cpuc,
struct hw_perf_event *hwc);
u64 (*read_counter)(unsigned int idx);
void (*write_counter)(unsigned int idx, u64 val);
void (*enable_event)(struct hw_perf_event *evt, int idx);
void (*disable_event)(int idx);
const struct mips_perf_event *(*map_raw_event)(u64 config);
const struct mips_perf_event (*general_event_map)[PERF_COUNT_HW_MAX];
const struct mips_perf_event (*cache_event_map)
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX];
unsigned int num_counters;
};
static const struct mips_pmu *mipspmu;
static int
mipspmu_event_set_period(struct perf_event *event,
struct hw_perf_event *hwc,
int idx)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
s64 left = local64_read(&hwc->period_left);
s64 period = hwc->sample_period;
int ret = 0;
u64 uleft;
unsigned long flags;
if (unlikely(left <= -period)) {
left = period;
local64_set(&hwc->period_left, left);
hwc->last_period = period;
ret = 1;
}
if (unlikely(left <= 0)) {
left += period;
local64_set(&hwc->period_left, left);
hwc->last_period = period;
ret = 1;
}
if (left > (s64)MAX_PERIOD)
left = MAX_PERIOD;
local64_set(&hwc->prev_count, (u64)-left);
local_irq_save(flags);
uleft = (u64)(-left) & MAX_PERIOD;
uleft > VALID_COUNT ?
set_bit(idx, cpuc->msbs) : clear_bit(idx, cpuc->msbs);
mipspmu->write_counter(idx, (u64)(-left) & VALID_COUNT);
local_irq_restore(flags);
perf_event_update_userpage(event);
return ret;
}
static void mipspmu_event_update(struct perf_event *event,
struct hw_perf_event *hwc,
int idx)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
unsigned long flags;
int shift = 64 - TOTAL_BITS;
s64 prev_raw_count, new_raw_count;
u64 delta;
again:
prev_raw_count = local64_read(&hwc->prev_count);
local_irq_save(flags);
/* Make the counter value be a "real" one. */
new_raw_count = mipspmu->read_counter(idx);
if (new_raw_count & (test_bit(idx, cpuc->msbs) << HIGHEST_BIT)) {
new_raw_count &= VALID_COUNT;
clear_bit(idx, cpuc->msbs);
} else
new_raw_count |= (test_bit(idx, cpuc->msbs) << HIGHEST_BIT);
local_irq_restore(flags);
if (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
new_raw_count) != prev_raw_count)
goto again;
delta = (new_raw_count << shift) - (prev_raw_count << shift);
delta >>= shift;
local64_add(delta, &event->count);
local64_sub(delta, &hwc->period_left);
}
static void mipspmu_start(struct perf_event *event, int flags)
{
struct hw_perf_event *hwc = &event->hw;
if (!mipspmu)
return;
if (flags & PERF_EF_RELOAD)
WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
hwc->state = 0;
/* Set the period for the event. */
mipspmu_event_set_period(event, hwc, hwc->idx);
/* Enable the event. */
mipspmu->enable_event(hwc, hwc->idx);
}
static void mipspmu_stop(struct perf_event *event, int flags)
{
struct hw_perf_event *hwc = &event->hw;
if (!mipspmu)
return;
if (!(hwc->state & PERF_HES_STOPPED)) {
/* We are working on a local event. */
mipspmu->disable_event(hwc->idx);
barrier();
mipspmu_event_update(event, hwc, hwc->idx);
hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
}
}
static int mipspmu_add(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
int idx;
int err = 0;
perf_pmu_disable(event->pmu);
/* To look for a free counter for this event. */
idx = mipspmu->alloc_counter(cpuc, hwc);
if (idx < 0) {
err = idx;
goto out;
}
/*
* If there is an event in the counter we are going to use then
* make sure it is disabled.
*/
event->hw.idx = idx;
mipspmu->disable_event(idx);
cpuc->events[idx] = event;
hwc->state = PERF_HES_STOPPED | PERF_HES_UPTODATE;
if (flags & PERF_EF_START)
mipspmu_start(event, PERF_EF_RELOAD);
/* Propagate our changes to the userspace mapping. */
perf_event_update_userpage(event);
out:
perf_pmu_enable(event->pmu);
return err;
}
static void mipspmu_del(struct perf_event *event, int flags)
{
struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
struct hw_perf_event *hwc = &event->hw;
int idx = hwc->idx;
WARN_ON(idx < 0 || idx >= mipspmu->num_counters);
mipspmu_stop(event, PERF_EF_UPDATE);
cpuc->events[idx] = NULL;
clear_bit(idx, cpuc->used_mask);
perf_event_update_userpage(event);
}
static void mipspmu_read(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
/* Don't read disabled counters! */
if (hwc->idx < 0)
return;
mipspmu_event_update(event, hwc, hwc->idx);
}
static void mipspmu_enable(struct pmu *pmu)
{
if (mipspmu)
mipspmu->start();
}
static void mipspmu_disable(struct pmu *pmu)
{
if (mipspmu)
mipspmu->stop();
}
static atomic_t active_events = ATOMIC_INIT(0);
static DEFINE_MUTEX(pmu_reserve_mutex);
static int (*save_perf_irq)(void);
static int mipspmu_get_irq(void)
{
int err;
if (mipspmu->irq >= 0) {
/* Request my own irq handler. */
err = request_irq(mipspmu->irq, mipspmu->handle_irq,
IRQF_DISABLED | IRQF_NOBALANCING,
"mips_perf_pmu", NULL);
if (err) {
pr_warning("Unable to request IRQ%d for MIPS "
"performance counters!\n", mipspmu->irq);
}
} else if (cp0_perfcount_irq < 0) {
/*
* We are sharing the irq number with the timer interrupt.
*/
save_perf_irq = perf_irq;
perf_irq = mipspmu->handle_shared_irq;
err = 0;
} else {
pr_warning("The platform hasn't properly defined its "
"interrupt controller.\n");
err = -ENOENT;
}
return err;
}
static void mipspmu_free_irq(void)
{
if (mipspmu->irq >= 0)
free_irq(mipspmu->irq, NULL);
else if (cp0_perfcount_irq < 0)
perf_irq = save_perf_irq;
}
/*
* mipsxx/rm9000/loongson2 have different performance counters, they have
* specific low-level init routines.
*/
static void reset_counters(void *arg);
static int __hw_perf_event_init(struct perf_event *event);
static void hw_perf_event_destroy(struct perf_event *event)
{
if (atomic_dec_and_mutex_lock(&active_events,
&pmu_reserve_mutex)) {
/*
* We must not call the destroy function with interrupts
* disabled.
*/
on_each_cpu(reset_counters,
(void *)(long)mipspmu->num_counters, 1);
mipspmu_free_irq();
mutex_unlock(&pmu_reserve_mutex);
}
}
static int mipspmu_event_init(struct perf_event *event)
{
int err = 0;
switch (event->attr.type) {
case PERF_TYPE_RAW:
case PERF_TYPE_HARDWARE:
case PERF_TYPE_HW_CACHE:
break;
default:
return -ENOENT;
}
if (!mipspmu || event->cpu >= nr_cpumask_bits ||
(event->cpu >= 0 && !cpu_online(event->cpu)))
return -ENODEV;
if (!atomic_inc_not_zero(&active_events)) {
if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
atomic_dec(&active_events);
return -ENOSPC;
}
mutex_lock(&pmu_reserve_mutex);
if (atomic_read(&active_events) == 0)
err = mipspmu_get_irq();
if (!err)
atomic_inc(&active_events);
mutex_unlock(&pmu_reserve_mutex);
}
if (err)
return err;
err = __hw_perf_event_init(event);
if (err)
hw_perf_event_destroy(event);
return err;
}
static struct pmu pmu = {
.pmu_enable = mipspmu_enable,
.pmu_disable = mipspmu_disable,
.event_init = mipspmu_event_init,
.add = mipspmu_add,
.del = mipspmu_del,
.start = mipspmu_start,
.stop = mipspmu_stop,
.read = mipspmu_read,
};
static inline unsigned int
mipspmu_perf_event_encode(const struct mips_perf_event *pev)
{
/*
* Top 8 bits for range, next 16 bits for cntr_mask, lowest 8 bits for
* event_id.
*/
#ifdef CONFIG_MIPS_MT_SMP
return ((unsigned int)pev->range << 24) |
(pev->cntr_mask & 0xffff00) |
(pev->event_id & 0xff);
#else
return (pev->cntr_mask & 0xffff00) |
(pev->event_id & 0xff);
#endif
}
static const struct mips_perf_event *
mipspmu_map_general_event(int idx)
{
const struct mips_perf_event *pev;
pev = ((*mipspmu->general_event_map)[idx].event_id ==
UNSUPPORTED_PERF_EVENT_ID ? ERR_PTR(-EOPNOTSUPP) :
&(*mipspmu->general_event_map)[idx]);
return pev;
}
static const struct mips_perf_event *
mipspmu_map_cache_event(u64 config)
{
unsigned int cache_type, cache_op, cache_result;
const struct mips_perf_event *pev;
cache_type = (config >> 0) & 0xff;
if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
return ERR_PTR(-EINVAL);
cache_op = (config >> 8) & 0xff;
if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
return ERR_PTR(-EINVAL);
cache_result = (config >> 16) & 0xff;
if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
return ERR_PTR(-EINVAL);
pev = &((*mipspmu->cache_event_map)
[cache_type]
[cache_op]
[cache_result]);
if (pev->event_id == UNSUPPORTED_PERF_EVENT_ID)
return ERR_PTR(-EOPNOTSUPP);
return pev;
}
static int validate_event(struct cpu_hw_events *cpuc,
struct perf_event *event)
{
struct hw_perf_event fake_hwc = event->hw;
/* Allow mixed event group. So return 1 to pass validation. */
if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF)
return 1;
return mipspmu->alloc_counter(cpuc, &fake_hwc) >= 0;
}
static int validate_group(struct perf_event *event)
{
struct perf_event *sibling, *leader = event->group_leader;
struct cpu_hw_events fake_cpuc;
memset(&fake_cpuc, 0, sizeof(fake_cpuc));
if (!validate_event(&fake_cpuc, leader))
return -ENOSPC;
list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
if (!validate_event(&fake_cpuc, sibling))
return -ENOSPC;
}
if (!validate_event(&fake_cpuc, event))
return -ENOSPC;
return 0;
}
/* This is needed by specific irq handlers in perf_event_*.c */
static void
handle_associated_event(struct cpu_hw_events *cpuc,
int idx, struct perf_sample_data *data, struct pt_regs *regs)
{
struct perf_event *event = cpuc->events[idx];
struct hw_perf_event *hwc = &event->hw;
mipspmu_event_update(event, hwc, idx);
data->period = event->hw.last_period;
if (!mipspmu_event_set_period(event, hwc, idx))
return;
if (perf_event_overflow(event, data, regs))
mipspmu->disable_event(idx);
}
#include "perf_event_mipsxx.c"
/* Callchain handling code. */ /* Callchain handling code. */
/* /*
* Leave userspace callchain empty for now. When we find a way to trace * Leave userspace callchain empty for now. When we find a way to trace
* the user stack callchains, we add here. * the user stack callchains, we will add it here.
*/ */
void perf_callchain_user(struct perf_callchain_entry *entry,
struct pt_regs *regs)
{
}
static void save_raw_perf_callchain(struct perf_callchain_entry *entry, static void save_raw_perf_callchain(struct perf_callchain_entry *entry,
unsigned long reg29) unsigned long reg29)

File diff suppressed because it is too large Load Diff

View File

@ -496,7 +496,7 @@ einval: li v0, -ENOSYS
sys sys_lookup_dcookie 4 sys sys_lookup_dcookie 4
sys sys_epoll_create 1 sys sys_epoll_create 1
sys sys_epoll_ctl 4 sys sys_epoll_ctl 4
sys sys_epoll_wait 3 /* 4250 */ sys sys_epoll_wait 4 /* 4250 */
sys sys_remap_file_pages 5 sys sys_remap_file_pages 5
sys sys_set_tid_address 1 sys sys_set_tid_address 1
sys sys_restart_syscall 0 sys sys_restart_syscall 0

View File

@ -169,6 +169,10 @@ static void octeon_flush_cache_page(struct vm_area_struct *vma,
octeon_flush_icache_all_cores(vma); octeon_flush_icache_all_cores(vma);
} }
static void octeon_flush_kernel_vmap_range(unsigned long vaddr, int size)
{
BUG();
}
/** /**
* Probe Octeon's caches * Probe Octeon's caches
@ -273,6 +277,8 @@ void __cpuinit octeon_cache_init(void)
flush_icache_range = octeon_flush_icache_range; flush_icache_range = octeon_flush_icache_range;
local_flush_icache_range = local_octeon_flush_icache_range; local_flush_icache_range = local_octeon_flush_icache_range;
__flush_kernel_vmap_range = octeon_flush_kernel_vmap_range;
build_clear_page(); build_clear_page();
build_copy_page(); build_copy_page();
} }

View File

@ -299,6 +299,11 @@ static void r3k_flush_cache_sigtramp(unsigned long addr)
write_c0_status(flags); write_c0_status(flags);
} }
static void r3k_flush_kernel_vmap_range(unsigned long vaddr, int size)
{
BUG();
}
static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size) static void r3k_dma_cache_wback_inv(unsigned long start, unsigned long size)
{ {
/* Catch bad driver code */ /* Catch bad driver code */
@ -323,6 +328,8 @@ void __cpuinit r3k_cache_init(void)
flush_icache_range = r3k_flush_icache_range; flush_icache_range = r3k_flush_icache_range;
local_flush_icache_range = r3k_flush_icache_range; local_flush_icache_range = r3k_flush_icache_range;
__flush_kernel_vmap_range = r3k_flush_kernel_vmap_range;
flush_cache_sigtramp = r3k_flush_cache_sigtramp; flush_cache_sigtramp = r3k_flush_cache_sigtramp;
local_flush_data_cache_page = local_r3k_flush_data_cache_page; local_flush_data_cache_page = local_r3k_flush_data_cache_page;
flush_data_cache_page = r3k_flush_data_cache_page; flush_data_cache_page = r3k_flush_data_cache_page;

View File

@ -722,6 +722,39 @@ static void r4k_flush_icache_all(void)
r4k_blast_icache(); r4k_blast_icache();
} }
struct flush_kernel_vmap_range_args {
unsigned long vaddr;
int size;
};
static inline void local_r4k_flush_kernel_vmap_range(void *args)
{
struct flush_kernel_vmap_range_args *vmra = args;
unsigned long vaddr = vmra->vaddr;
int size = vmra->size;
/*
* Aliases only affect the primary caches so don't bother with
* S-caches or T-caches.
*/
if (cpu_has_safe_index_cacheops && size >= dcache_size)
r4k_blast_dcache();
else {
R4600_HIT_CACHEOP_WAR_IMPL;
blast_dcache_range(vaddr, vaddr + size);
}
}
static void r4k_flush_kernel_vmap_range(unsigned long vaddr, int size)
{
struct flush_kernel_vmap_range_args args;
args.vaddr = (unsigned long) vaddr;
args.size = size;
r4k_on_each_cpu(local_r4k_flush_kernel_vmap_range, &args);
}
static inline void rm7k_erratum31(void) static inline void rm7k_erratum31(void)
{ {
const unsigned long ic_lsize = 32; const unsigned long ic_lsize = 32;
@ -1403,6 +1436,8 @@ void __cpuinit r4k_cache_init(void)
flush_cache_page = r4k_flush_cache_page; flush_cache_page = r4k_flush_cache_page;
flush_cache_range = r4k_flush_cache_range; flush_cache_range = r4k_flush_cache_range;
__flush_kernel_vmap_range = r4k_flush_kernel_vmap_range;
flush_cache_sigtramp = r4k_flush_cache_sigtramp; flush_cache_sigtramp = r4k_flush_cache_sigtramp;
flush_icache_all = r4k_flush_icache_all; flush_icache_all = r4k_flush_icache_all;
local_flush_data_cache_page = local_r4k_flush_data_cache_page; local_flush_data_cache_page = local_r4k_flush_data_cache_page;

View File

@ -253,6 +253,11 @@ static void tx39_flush_icache_range(unsigned long start, unsigned long end)
} }
} }
static void tx39_flush_kernel_vmap_range(unsigned long vaddr, int size)
{
BUG();
}
static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size) static void tx39_dma_cache_wback_inv(unsigned long addr, unsigned long size)
{ {
unsigned long end; unsigned long end;
@ -394,6 +399,8 @@ void __cpuinit tx39_cache_init(void)
flush_icache_range = tx39_flush_icache_range; flush_icache_range = tx39_flush_icache_range;
local_flush_icache_range = tx39_flush_icache_range; local_flush_icache_range = tx39_flush_icache_range;
__flush_kernel_vmap_range = tx39_flush_kernel_vmap_range;
flush_cache_sigtramp = tx39_flush_cache_sigtramp; flush_cache_sigtramp = tx39_flush_cache_sigtramp;
local_flush_data_cache_page = local_tx39_flush_data_cache_page; local_flush_data_cache_page = local_tx39_flush_data_cache_page;
flush_data_cache_page = tx39_flush_data_cache_page; flush_data_cache_page = tx39_flush_data_cache_page;

View File

@ -35,6 +35,11 @@ void (*local_flush_icache_range)(unsigned long start, unsigned long end);
void (*__flush_cache_vmap)(void); void (*__flush_cache_vmap)(void);
void (*__flush_cache_vunmap)(void); void (*__flush_cache_vunmap)(void);
void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
/* MIPS specific cache operations */ /* MIPS specific cache operations */
void (*flush_cache_sigtramp)(unsigned long addr); void (*flush_cache_sigtramp)(unsigned long addr);
void (*local_flush_data_cache_page)(void * addr); void (*local_flush_data_cache_page)(void * addr);

View File

@ -223,8 +223,8 @@ void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
local_irq_restore(flags); local_irq_restore(flags);
} }
void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
unsigned long entryhi, unsigned long pagemask) unsigned long entryhi, unsigned long pagemask)
{ {
unsigned long flags; unsigned long flags;
unsigned long old_ctx; unsigned long old_ctx;

View File

@ -337,8 +337,8 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte)
EXIT_CRITICAL(flags); EXIT_CRITICAL(flags);
} }
void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
unsigned long entryhi, unsigned long pagemask) unsigned long entryhi, unsigned long pagemask)
{ {
unsigned long flags; unsigned long flags;
unsigned long wired; unsigned long wired;

View File

@ -4,6 +4,11 @@
cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic
cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic
#
# use mips64 if xlr is not available
#
cflags-$(CONFIG_NLM_XLR) += $(call cc-option,-march=xlr,-march=mips64)
# #
# NETLOGIC XLR/XLS SoC, Simulator and boards # NETLOGIC XLR/XLS SoC, Simulator and boards
# #

View File

@ -53,7 +53,7 @@ unsigned long netlogic_io_base = (unsigned long)(DEFAULT_NETLOGIC_IO_BASE);
unsigned long nlm_common_ebase = 0x0; unsigned long nlm_common_ebase = 0x0;
struct psb_info nlm_prom_info; struct psb_info nlm_prom_info;
static void nlm_early_serial_setup(void) static void __init nlm_early_serial_setup(void)
{ {
struct uart_port s; struct uart_port s;
nlm_reg_t *uart_base; nlm_reg_t *uart_base;
@ -101,7 +101,7 @@ void __init prom_free_prom_memory(void)
/* Nothing yet */ /* Nothing yet */
} }
static void build_arcs_cmdline(int *argv) static void __init build_arcs_cmdline(int *argv)
{ {
int i, remain, len; int i, remain, len;
char *arg; char *arg;

View File

@ -158,6 +158,10 @@ void __init nlm_smp_setup(void)
num_cpus = 1; num_cpus = 1;
for (i = 0; i < NR_CPUS; i++) { for (i = 0; i < NR_CPUS; i++) {
/*
* BSP is not set in nlm_cpu_ready array, it is only for
* ASPs (goto see smpboot.S)
*/
if (nlm_cpu_ready[i]) { if (nlm_cpu_ready[i]) {
cpu_set(i, phys_cpu_present_map); cpu_set(i, phys_cpu_present_map);
__cpu_number_map[i] = num_cpus; __cpu_number_map[i] = num_cpus;
@ -191,7 +195,7 @@ struct plat_smp_ops nlm_smp_ops = {
unsigned long secondary_entry_point; unsigned long secondary_entry_point;
int nlm_wakeup_secondary_cpus(u32 wakeup_mask) int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
{ {
unsigned int tid, pid, ipi, i, boot_cpu; unsigned int tid, pid, ipi, i, boot_cpu;
void *reset_vec; void *reset_vec;

View File

@ -32,17 +32,19 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include <linux/init.h>
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/asm-offsets.h> #include <asm/asm-offsets.h>
#include <asm/regdef.h> #include <asm/regdef.h>
#include <asm/mipsregs.h> #include <asm/mipsregs.h>
/*
/* Don't jump to linux function from Bootloader stack. Change it * Early code for secondary CPUs. This will get them out of the bootloader
* here. Kernel might allocate bootloader memory before all the CPUs are * code and into linux. Needed because the bootloader area will be taken
* brought up (eg: Inode cache region) and we better don't overwrite this * and initialized by linux.
* memory
*/ */
__CPUINIT
NESTED(prom_pre_boot_secondary_cpus, 16, sp) NESTED(prom_pre_boot_secondary_cpus, 16, sp)
.set mips64 .set mips64
mfc0 t0, $15, 1 # read ebase mfc0 t0, $15, 1 # read ebase
@ -73,7 +75,11 @@ NESTED(prom_pre_boot_secondary_cpus, 16, sp)
jr t0 jr t0
nop nop
END(prom_pre_boot_secondary_cpus) END(prom_pre_boot_secondary_cpus)
__FINIT
/*
* NMI code, used for CPU wakeup, copied to reset entry
*/
NESTED(nlm_boot_smp_nmi, 0, sp) NESTED(nlm_boot_smp_nmi, 0, sp)
.set push .set push
.set noat .set noat

View File

@ -18,14 +18,13 @@ obj-$(CONFIG_PCI_TX4927) += ops-tx4927.o
obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
ops-bcm63xx.o ops-bcm63xx.o
obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
# #
# These are still pretty much in the old state, watch, go blind. # These are still pretty much in the old state, watch, go blind.
# #
obj-$(CONFIG_LASAT) += pci-lasat.o obj-$(CONFIG_LASAT) += pci-lasat.o
obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o
obj-$(CONFIG_SOC_AU1500) += fixup-au1000.o ops-au1000.o
obj-$(CONFIG_SOC_AU1550) += fixup-au1000.o ops-au1000.o
obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o obj-$(CONFIG_SOC_PNX8550) += fixup-pnx8550.o ops-pnx8550.o
obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o
obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o

View File

@ -1,43 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Board specific PCI fixups.
*
* Copyright 2001-2003, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/pci.h>
#include <linux/init.h>
extern char irq_tab_alchemy[][5];
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
return irq_tab_alchemy[slot][pin];
}
/* Do platform specific device initialization at pci_enable_device() time */
int pcibios_plat_dev_init(struct pci_dev *dev)
{
return 0;
}

View File

@ -1,308 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Alchemy/AMD Au1xx0 PCI support.
*
* Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* Support for all devices (greater than 16) added by David Gathright.
*
* 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* 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.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <asm/mach-au1x00/au1000.h>
#undef DEBUG
#ifdef DEBUG
#define DBG(x...) printk(KERN_DEBUG x)
#else
#define DBG(x...)
#endif
#define PCI_ACCESS_READ 0
#define PCI_ACCESS_WRITE 1
int (*board_pci_idsel)(unsigned int devsel, int assert);
void mod_wired_entry(int entry, unsigned long entrylo0,
unsigned long entrylo1, unsigned long entryhi,
unsigned long pagemask)
{
unsigned long old_pagemask;
unsigned long old_ctx;
/* Save old context and create impossible VPN2 value */
old_ctx = read_c0_entryhi() & 0xff;
old_pagemask = read_c0_pagemask();
write_c0_index(entry);
write_c0_pagemask(pagemask);
write_c0_entryhi(entryhi);
write_c0_entrylo0(entrylo0);
write_c0_entrylo1(entrylo1);
tlb_write_indexed();
write_c0_entryhi(old_ctx);
write_c0_pagemask(old_pagemask);
}
static struct vm_struct *pci_cfg_vm;
static int pci_cfg_wired_entry;
static unsigned long last_entryLo0, last_entryLo1;
/*
* We can't ioremap the entire pci config space because it's too large.
* Nor can we call ioremap dynamically because some device drivers use
* the PCI config routines from within interrupt handlers and that
* becomes a problem in get_vm_area(). We use one wired TLB to handle
* all config accesses for all busses.
*/
void __init au1x_pci_cfg_init(void)
{
/* Reserve a wired entry for PCI config accesses */
pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP);
if (!pci_cfg_vm)
panic(KERN_ERR "PCI unable to get vm area\n");
pci_cfg_wired_entry = read_c0_wired();
add_wired_entry(0, 0, (unsigned long)pci_cfg_vm->addr, PM_4K);
last_entryLo0 = last_entryLo1 = 0xffffffff;
}
static int config_access(unsigned char access_type, struct pci_bus *bus,
unsigned int dev_fn, unsigned char where, u32 *data)
{
#if defined(CONFIG_SOC_AU1500) || defined(CONFIG_SOC_AU1550)
unsigned int device = PCI_SLOT(dev_fn);
unsigned int function = PCI_FUNC(dev_fn);
unsigned long offset, status;
unsigned long cfg_base;
unsigned long flags;
int error = PCIBIOS_SUCCESSFUL;
unsigned long entryLo0, entryLo1;
if (device > 19) {
*data = 0xffffffff;
return -1;
}
local_irq_save(flags);
au_writel(((0x2000 << 16) | (au_readl(Au1500_PCI_STATCMD) & 0xffff)),
Au1500_PCI_STATCMD);
au_sync_udelay(1);
/*
* Allow board vendors to implement their own off-chip IDSEL.
* If it doesn't succeed, may as well bail out at this point.
*/
if (board_pci_idsel && board_pci_idsel(device, 1) == 0) {
*data = 0xffffffff;
local_irq_restore(flags);
return -1;
}
/* Setup the config window */
if (bus->number == 0)
cfg_base = (1 << device) << 11;
else
cfg_base = 0x80000000 | (bus->number << 16) | (device << 11);
/* Setup the lower bits of the 36-bit address */
offset = (function << 8) | (where & ~0x3);
/* Pick up any address that falls below the page mask */
offset |= cfg_base & ~PAGE_MASK;
/* Page boundary */
cfg_base = cfg_base & PAGE_MASK;
/*
* To improve performance, if the current device is the same as
* the last device accessed, we don't touch the TLB.
*/
entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7;
entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
if ((entryLo0 != last_entryLo0) || (entryLo1 != last_entryLo1)) {
mod_wired_entry(pci_cfg_wired_entry, entryLo0, entryLo1,
(unsigned long)pci_cfg_vm->addr, PM_4K);
last_entryLo0 = entryLo0;
last_entryLo1 = entryLo1;
}
if (access_type == PCI_ACCESS_WRITE)
au_writel(*data, (int)(pci_cfg_vm->addr + offset));
else
*data = au_readl((int)(pci_cfg_vm->addr + offset));
au_sync_udelay(2);
DBG("cfg_access %d bus->number %u dev %u at %x *data %x conf %lx\n",
access_type, bus->number, device, where, *data, offset);
/* Check master abort */
status = au_readl(Au1500_PCI_STATCMD);
if (status & (1 << 29)) {
*data = 0xffffffff;
error = -1;
DBG("Au1x Master Abort\n");
} else if ((status >> 28) & 0xf) {
DBG("PCI ERR detected: device %u, status %lx\n",
device, (status >> 28) & 0xf);
/* Clear errors */
au_writel(status & 0xf000ffff, Au1500_PCI_STATCMD);
*data = 0xffffffff;
error = -1;
}
/* Take away the IDSEL. */
if (board_pci_idsel)
(void)board_pci_idsel(device, 0);
local_irq_restore(flags);
return error;
#endif
}
static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
int where, u8 *val)
{
u32 data;
int ret;
ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
if (where & 1)
data >>= 8;
if (where & 2)
data >>= 16;
*val = data & 0xff;
return ret;
}
static int read_config_word(struct pci_bus *bus, unsigned int devfn,
int where, u16 *val)
{
u32 data;
int ret;
ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
if (where & 2)
data >>= 16;
*val = data & 0xffff;
return ret;
}
static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
int where, u32 *val)
{
int ret;
ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
return ret;
}
static int write_config_byte(struct pci_bus *bus, unsigned int devfn,
int where, u8 val)
{
u32 data = 0;
if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
data = (data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int write_config_word(struct pci_bus *bus, unsigned int devfn,
int where, u16 val)
{
u32 data = 0;
if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
data = (data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int write_config_dword(struct pci_bus *bus, unsigned int devfn,
int where, u32 val)
{
if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int config_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
switch (size) {
case 1: {
u8 _val;
int rc = read_config_byte(bus, devfn, where, &_val);
*val = _val;
return rc;
}
case 2: {
u16 _val;
int rc = read_config_word(bus, devfn, where, &_val);
*val = _val;
return rc;
}
default:
return read_config_dword(bus, devfn, where, val);
}
}
static int config_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
switch (size) {
case 1:
return write_config_byte(bus, devfn, where, (u8) val);
case 2:
return write_config_word(bus, devfn, where, (u16) val);
default:
return write_config_dword(bus, devfn, where, val);
}
}
struct pci_ops au1x_pci_ops = {
config_read,
config_write
};

View File

@ -0,0 +1,516 @@
/*
* Alchemy PCI host mode support.
*
* Copyright 2001-2003, 2007-2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* Support for all devices (greater than 16) added by David Gathright.
*/
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_DEBUG_PCI
#define DBG(x...) printk(KERN_DEBUG x)
#else
#define DBG(x...) do {} while (0)
#endif
#define PCI_ACCESS_READ 0
#define PCI_ACCESS_WRITE 1
struct alchemy_pci_context {
struct pci_controller alchemy_pci_ctrl; /* leave as first member! */
void __iomem *regs; /* ctrl base */
/* tools for wired entry for config space access */
unsigned long last_elo0;
unsigned long last_elo1;
int wired_entry;
struct vm_struct *pci_cfg_vm;
unsigned long pm[12];
int (*board_map_irq)(const struct pci_dev *d, u8 slot, u8 pin);
int (*board_pci_idsel)(unsigned int devsel, int assert);
};
/* IO/MEM resources for PCI. Keep the memres in sync with __fixup_bigphys_addr
* in arch/mips/alchemy/common/setup.c
*/
static struct resource alchemy_pci_def_memres = {
.start = ALCHEMY_PCI_MEMWIN_START,
.end = ALCHEMY_PCI_MEMWIN_END,
.name = "PCI memory space",
.flags = IORESOURCE_MEM
};
static struct resource alchemy_pci_def_iores = {
.start = ALCHEMY_PCI_IOWIN_START,
.end = ALCHEMY_PCI_IOWIN_END,
.name = "PCI IO space",
.flags = IORESOURCE_IO
};
static void mod_wired_entry(int entry, unsigned long entrylo0,
unsigned long entrylo1, unsigned long entryhi,
unsigned long pagemask)
{
unsigned long old_pagemask;
unsigned long old_ctx;
/* Save old context and create impossible VPN2 value */
old_ctx = read_c0_entryhi() & 0xff;
old_pagemask = read_c0_pagemask();
write_c0_index(entry);
write_c0_pagemask(pagemask);
write_c0_entryhi(entryhi);
write_c0_entrylo0(entrylo0);
write_c0_entrylo1(entrylo1);
tlb_write_indexed();
write_c0_entryhi(old_ctx);
write_c0_pagemask(old_pagemask);
}
static void alchemy_pci_wired_entry(struct alchemy_pci_context *ctx)
{
ctx->wired_entry = read_c0_wired();
add_wired_entry(0, 0, (unsigned long)ctx->pci_cfg_vm->addr, PM_4K);
ctx->last_elo0 = ctx->last_elo1 = ~0;
}
static int config_access(unsigned char access_type, struct pci_bus *bus,
unsigned int dev_fn, unsigned char where, u32 *data)
{
struct alchemy_pci_context *ctx = bus->sysdata;
unsigned int device = PCI_SLOT(dev_fn);
unsigned int function = PCI_FUNC(dev_fn);
unsigned long offset, status, cfg_base, flags, entryLo0, entryLo1, r;
int error = PCIBIOS_SUCCESSFUL;
if (device > 19) {
*data = 0xffffffff;
return -1;
}
/* YAMON on all db1xxx boards wipes the TLB and writes zero to C0_wired
* on resume, clearing our wired entry. Unfortunately the ->resume()
* callback is called way way way too late (and ->suspend() too early)
* to have them destroy and recreate it. Instead just test if c0_wired
* is now lower than the index we retrieved before suspending and then
* recreate the entry if necessary. Of course this is totally bonkers
* and breaks as soon as someone else adds another wired entry somewhere
* else. Anyone have any ideas how to handle this better?
*/
if (unlikely(read_c0_wired() < ctx->wired_entry))
alchemy_pci_wired_entry(ctx);
local_irq_save(flags);
r = __raw_readl(ctx->regs + PCI_REG_STATCMD) & 0x0000ffff;
r |= PCI_STATCMD_STATUS(0x2000);
__raw_writel(r, ctx->regs + PCI_REG_STATCMD);
wmb();
/* Allow board vendors to implement their own off-chip IDSEL.
* If it doesn't succeed, may as well bail out at this point.
*/
if (ctx->board_pci_idsel(device, 1) == 0) {
*data = 0xffffffff;
local_irq_restore(flags);
return -1;
}
/* Setup the config window */
if (bus->number == 0)
cfg_base = (1 << device) << 11;
else
cfg_base = 0x80000000 | (bus->number << 16) | (device << 11);
/* Setup the lower bits of the 36-bit address */
offset = (function << 8) | (where & ~0x3);
/* Pick up any address that falls below the page mask */
offset |= cfg_base & ~PAGE_MASK;
/* Page boundary */
cfg_base = cfg_base & PAGE_MASK;
/* To improve performance, if the current device is the same as
* the last device accessed, we don't touch the TLB.
*/
entryLo0 = (6 << 26) | (cfg_base >> 6) | (2 << 3) | 7;
entryLo1 = (6 << 26) | (cfg_base >> 6) | (0x1000 >> 6) | (2 << 3) | 7;
if ((entryLo0 != ctx->last_elo0) || (entryLo1 != ctx->last_elo1)) {
mod_wired_entry(ctx->wired_entry, entryLo0, entryLo1,
(unsigned long)ctx->pci_cfg_vm->addr, PM_4K);
ctx->last_elo0 = entryLo0;
ctx->last_elo1 = entryLo1;
}
if (access_type == PCI_ACCESS_WRITE)
__raw_writel(*data, ctx->pci_cfg_vm->addr + offset);
else
*data = __raw_readl(ctx->pci_cfg_vm->addr + offset);
wmb();
DBG("alchemy-pci: cfg access %d bus %u dev %u at %x dat %x conf %lx\n",
access_type, bus->number, device, where, *data, offset);
/* check for errors, master abort */
status = __raw_readl(ctx->regs + PCI_REG_STATCMD);
if (status & (1 << 29)) {
*data = 0xffffffff;
error = -1;
DBG("alchemy-pci: master abort on cfg access %d bus %d dev %d",
access_type, bus->number, device);
} else if ((status >> 28) & 0xf) {
DBG("alchemy-pci: PCI ERR detected: dev %d, status %lx\n",
device, (status >> 28) & 0xf);
/* clear errors */
__raw_writel(status & 0xf000ffff, ctx->regs + PCI_REG_STATCMD);
*data = 0xffffffff;
error = -1;
}
/* Take away the IDSEL. */
(void)ctx->board_pci_idsel(device, 0);
local_irq_restore(flags);
return error;
}
static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
int where, u8 *val)
{
u32 data;
int ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
if (where & 1)
data >>= 8;
if (where & 2)
data >>= 16;
*val = data & 0xff;
return ret;
}
static int read_config_word(struct pci_bus *bus, unsigned int devfn,
int where, u16 *val)
{
u32 data;
int ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
if (where & 2)
data >>= 16;
*val = data & 0xffff;
return ret;
}
static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
int where, u32 *val)
{
return config_access(PCI_ACCESS_READ, bus, devfn, where, val);
}
static int write_config_byte(struct pci_bus *bus, unsigned int devfn,
int where, u8 val)
{
u32 data = 0;
if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
data = (data & ~(0xff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int write_config_word(struct pci_bus *bus, unsigned int devfn,
int where, u16 val)
{
u32 data = 0;
if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
return -1;
data = (data & ~(0xffff << ((where & 3) << 3))) |
(val << ((where & 3) << 3));
if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
return -1;
return PCIBIOS_SUCCESSFUL;
}
static int write_config_dword(struct pci_bus *bus, unsigned int devfn,
int where, u32 val)
{
return config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val);
}
static int alchemy_pci_read(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
switch (size) {
case 1: {
u8 _val;
int rc = read_config_byte(bus, devfn, where, &_val);
*val = _val;
return rc;
}
case 2: {
u16 _val;
int rc = read_config_word(bus, devfn, where, &_val);
*val = _val;
return rc;
}
default:
return read_config_dword(bus, devfn, where, val);
}
}
static int alchemy_pci_write(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 val)
{
switch (size) {
case 1:
return write_config_byte(bus, devfn, where, (u8) val);
case 2:
return write_config_word(bus, devfn, where, (u16) val);
default:
return write_config_dword(bus, devfn, where, val);
}
}
static struct pci_ops alchemy_pci_ops = {
.read = alchemy_pci_read,
.write = alchemy_pci_write,
};
static int alchemy_pci_def_idsel(unsigned int devsel, int assert)
{
return 1; /* success */
}
static int __devinit alchemy_pci_probe(struct platform_device *pdev)
{
struct alchemy_pci_platdata *pd = pdev->dev.platform_data;
struct alchemy_pci_context *ctx;
void __iomem *virt_io;
unsigned long val;
struct resource *r;
int ret;
/* need at least PCI IRQ mapping table */
if (!pd) {
dev_err(&pdev->dev, "need platform data for PCI setup\n");
ret = -ENODEV;
goto out;
}
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
dev_err(&pdev->dev, "no memory for pcictl context\n");
ret = -ENOMEM;
goto out;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r) {
dev_err(&pdev->dev, "no pcictl ctrl regs resource\n");
ret = -ENODEV;
goto out1;
}
if (!request_mem_region(r->start, resource_size(r), pdev->name)) {
dev_err(&pdev->dev, "cannot claim pci regs\n");
ret = -ENODEV;
goto out1;
}
ctx->regs = ioremap_nocache(r->start, resource_size(r));
if (!ctx->regs) {
dev_err(&pdev->dev, "cannot map pci regs\n");
ret = -ENODEV;
goto out2;
}
/* map parts of the PCI IO area */
/* REVISIT: if this changes with a newer variant (doubt it) make this
* a platform resource.
*/
virt_io = ioremap(AU1500_PCI_IO_PHYS_ADDR, 0x00100000);
if (!virt_io) {
dev_err(&pdev->dev, "cannot remap pci io space\n");
ret = -ENODEV;
goto out3;
}
ctx->alchemy_pci_ctrl.io_map_base = (unsigned long)virt_io;
#ifdef CONFIG_DMA_NONCOHERENT
/* Au1500 revisions older than AD have borked coherent PCI */
if ((alchemy_get_cputype() == ALCHEMY_CPU_AU1500) &&
(read_c0_prid() < 0x01030202)) {
val = __raw_readl(ctx->regs + PCI_REG_CONFIG);
val |= PCI_CONFIG_NC;
__raw_writel(val, ctx->regs + PCI_REG_CONFIG);
wmb();
dev_info(&pdev->dev, "non-coherent PCI on Au1500 AA/AB/AC\n");
}
#endif
if (pd->board_map_irq)
ctx->board_map_irq = pd->board_map_irq;
if (pd->board_pci_idsel)
ctx->board_pci_idsel = pd->board_pci_idsel;
else
ctx->board_pci_idsel = alchemy_pci_def_idsel;
/* fill in relevant pci_controller members */
ctx->alchemy_pci_ctrl.pci_ops = &alchemy_pci_ops;
ctx->alchemy_pci_ctrl.mem_resource = &alchemy_pci_def_memres;
ctx->alchemy_pci_ctrl.io_resource = &alchemy_pci_def_iores;
/* we can't ioremap the entire pci config space because it's too large,
* nor can we dynamically ioremap it because some drivers use the
* PCI config routines from within atomic contex and that becomes a
* problem in get_vm_area(). Instead we use one wired TLB entry to
* handle all config accesses for all busses.
*/
ctx->pci_cfg_vm = get_vm_area(0x2000, VM_IOREMAP);
if (!ctx->pci_cfg_vm) {
dev_err(&pdev->dev, "unable to get vm area\n");
ret = -ENOMEM;
goto out4;
}
ctx->wired_entry = 8192; /* impossibly high value */
set_io_port_base((unsigned long)ctx->alchemy_pci_ctrl.io_map_base);
/* board may want to modify bits in the config register, do it now */
val = __raw_readl(ctx->regs + PCI_REG_CONFIG);
val &= ~pd->pci_cfg_clr;
val |= pd->pci_cfg_set;
val &= ~PCI_CONFIG_PD; /* clear disable bit */
__raw_writel(val, ctx->regs + PCI_REG_CONFIG);
wmb();
platform_set_drvdata(pdev, ctx);
register_pci_controller(&ctx->alchemy_pci_ctrl);
return 0;
out4:
iounmap(virt_io);
out3:
iounmap(ctx->regs);
out2:
release_mem_region(r->start, resource_size(r));
out1:
kfree(ctx);
out:
return ret;
}
#ifdef CONFIG_PM
/* save PCI controller register contents. */
static int alchemy_pci_suspend(struct device *dev)
{
struct alchemy_pci_context *ctx = dev_get_drvdata(dev);
ctx->pm[0] = __raw_readl(ctx->regs + PCI_REG_CMEM);
ctx->pm[1] = __raw_readl(ctx->regs + PCI_REG_CONFIG) & 0x0009ffff;
ctx->pm[2] = __raw_readl(ctx->regs + PCI_REG_B2BMASK_CCH);
ctx->pm[3] = __raw_readl(ctx->regs + PCI_REG_B2BBASE0_VID);
ctx->pm[4] = __raw_readl(ctx->regs + PCI_REG_B2BBASE1_SID);
ctx->pm[5] = __raw_readl(ctx->regs + PCI_REG_MWMASK_DEV);
ctx->pm[6] = __raw_readl(ctx->regs + PCI_REG_MWBASE_REV_CCL);
ctx->pm[7] = __raw_readl(ctx->regs + PCI_REG_ID);
ctx->pm[8] = __raw_readl(ctx->regs + PCI_REG_CLASSREV);
ctx->pm[9] = __raw_readl(ctx->regs + PCI_REG_PARAM);
ctx->pm[10] = __raw_readl(ctx->regs + PCI_REG_MBAR);
ctx->pm[11] = __raw_readl(ctx->regs + PCI_REG_TIMEOUT);
return 0;
}
static int alchemy_pci_resume(struct device *dev)
{
struct alchemy_pci_context *ctx = dev_get_drvdata(dev);
__raw_writel(ctx->pm[0], ctx->regs + PCI_REG_CMEM);
__raw_writel(ctx->pm[2], ctx->regs + PCI_REG_B2BMASK_CCH);
__raw_writel(ctx->pm[3], ctx->regs + PCI_REG_B2BBASE0_VID);
__raw_writel(ctx->pm[4], ctx->regs + PCI_REG_B2BBASE1_SID);
__raw_writel(ctx->pm[5], ctx->regs + PCI_REG_MWMASK_DEV);
__raw_writel(ctx->pm[6], ctx->regs + PCI_REG_MWBASE_REV_CCL);
__raw_writel(ctx->pm[7], ctx->regs + PCI_REG_ID);
__raw_writel(ctx->pm[8], ctx->regs + PCI_REG_CLASSREV);
__raw_writel(ctx->pm[9], ctx->regs + PCI_REG_PARAM);
__raw_writel(ctx->pm[10], ctx->regs + PCI_REG_MBAR);
__raw_writel(ctx->pm[11], ctx->regs + PCI_REG_TIMEOUT);
wmb();
__raw_writel(ctx->pm[1], ctx->regs + PCI_REG_CONFIG);
wmb();
return 0;
}
static const struct dev_pm_ops alchemy_pci_pmops = {
.suspend = alchemy_pci_suspend,
.resume = alchemy_pci_resume,
};
#define ALCHEMY_PCICTL_PM (&alchemy_pci_pmops)
#else
#define ALCHEMY_PCICTL_PM NULL
#endif
static struct platform_driver alchemy_pcictl_driver = {
.probe = alchemy_pci_probe,
.driver = {
.name = "alchemy-pci",
.owner = THIS_MODULE,
.pm = ALCHEMY_PCICTL_PM,
},
};
static int __init alchemy_pci_init(void)
{
/* Au1500/Au1550 have PCI */
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1550:
return platform_driver_register(&alchemy_pcictl_driver);
}
return 0;
}
arch_initcall(alchemy_pci_init);
int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
struct alchemy_pci_context *ctx = dev->sysdata;
if (ctx && ctx->board_map_irq)
return ctx->board_map_irq(dev, slot, pin);
return -1;
}
int pcibios_plat_dev_init(struct pci_dev *dev)
{
return 0;
}

View File

@ -14,6 +14,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/r4kcache.h> #include <asm/r4kcache.h>
#include <asm/reboot.h> #include <asm/reboot.h>
#include <asm/smp-ops.h>
#include <asm/time.h> #include <asm/time.h>
#include <msp_prom.h> #include <msp_prom.h>

View File

@ -65,15 +65,11 @@ static unsigned char readb_outer_space(unsigned long long phys)
__asm__ __volatile__ ( __asm__ __volatile__ (
" .set mips3 \n" " .set mips3 \n"
" .set push \n"
" .set noreorder \n"
" .set nomacro \n"
" ld %0, %1 \n" " ld %0, %1 \n"
" .set pop \n"
" lbu %0, (%0) \n" " lbu %0, (%0) \n"
" .set mips0 \n" " .set mips0 \n"
: "=r" (res) : "=r" (res)
: "R" (vaddr)); : "m" (vaddr));
write_c0_status(sr); write_c0_status(sr);
ssnop_4(); ssnop_4();
@ -93,15 +89,11 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c)
__asm__ __volatile__ ( __asm__ __volatile__ (
" .set mips3 \n" " .set mips3 \n"
" .set push \n"
" .set noreorder \n"
" .set nomacro \n"
" ld %0, %1 \n" " ld %0, %1 \n"
" .set pop \n"
" sb %2, (%0) \n" " sb %2, (%0) \n"
" .set mips0 \n" " .set mips0 \n"
: "=&r" (tmp) : "=&r" (tmp)
: "R" (vaddr), "r" (c)); : "m" (vaddr), "r" (c));
write_c0_status(sr); write_c0_status(sr);
ssnop_4(); ssnop_4();

View File

@ -30,7 +30,7 @@ typedef struct
}t_env_var; }t_env_var;
char * prom_getcmdline(void) char * __init prom_getcmdline(void)
{ {
return &(arcs_cmdline[0]); return &(arcs_cmdline[0]);
} }

View File

@ -337,12 +337,12 @@ static struct irq_chip bridge_irq_type = {
.irq_unmask = enable_bridge_irq, .irq_unmask = enable_bridge_irq,
}; };
void __devinit register_bridge_irq(unsigned int irq) void register_bridge_irq(unsigned int irq)
{ {
irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq); irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
} }
int __devinit request_bridge_irq(struct bridge_controller *bc) int request_bridge_irq(struct bridge_controller *bc)
{ {
int irq = allocate_irqno(); int irq = allocate_irqno();
int swlevel, cpu; int swlevel, cpu;

View File

@ -300,7 +300,7 @@ config I2C_AT91
config I2C_AU1550 config I2C_AU1550
tristate "Au1550/Au1200 SMBus interface" tristate "Au1550/Au1200 SMBus interface"
depends on SOC_AU1550 || SOC_AU1200 depends on MIPS_ALCHEMY
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
Au1550 and Au1200 SMBus interface. Au1550 and Au1200 SMBus interface.

View File

@ -36,7 +36,7 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/mach-au1x00/au1xxx.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_psc.h> #include <asm/mach-au1x00/au1xxx_psc.h>
#define PSC_SEL 0x00 #define PSC_SEL 0x00

View File

@ -677,19 +677,19 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST
config BLK_DEV_IDE_AU1XXX config BLK_DEV_IDE_AU1XXX
bool "IDE for AMD Alchemy Au1200" bool "IDE for AMD Alchemy Au1200"
depends on SOC_AU1200 depends on MIPS_ALCHEMY
select IDE_XFER_MODE select IDE_XFER_MODE
choice choice
prompt "IDE Mode for AMD Alchemy Au1200" prompt "IDE Mode for AMD Alchemy Au1200"
default BLK_DEV_IDE_AU1XXX_PIO_DBDMA default BLK_DEV_IDE_AU1XXX_PIO_DBDMA
depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX depends on BLK_DEV_IDE_AU1XXX
config BLK_DEV_IDE_AU1XXX_PIO_DBDMA config BLK_DEV_IDE_AU1XXX_PIO_DBDMA
bool "PIO+DbDMA IDE for AMD Alchemy Au1200" bool "PIO+DbDMA IDE for AMD Alchemy Au1200"
config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA config BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
bool "MDMA2+DbDMA IDE for AMD Alchemy Au1200" bool "MDMA2+DbDMA IDE for AMD Alchemy Au1200"
depends on SOC_AU1200 && BLK_DEV_IDE_AU1XXX depends on BLK_DEV_IDE_AU1XXX
endchoice endchoice
config BLK_DEV_IDE_TX4938 config BLK_DEV_IDE_TX4938

View File

@ -36,13 +36,17 @@
#include <linux/ide.h> #include <linux/ide.h>
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#include <asm/mach-au1x00/au1xxx.h> #include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h> #include <asm/mach-au1x00/au1xxx_dbdma.h>
#include <asm/mach-au1x00/au1xxx_ide.h> #include <asm/mach-au1x00/au1xxx_ide.h>
#define DRV_NAME "au1200-ide" #define DRV_NAME "au1200-ide"
#define DRV_AUTHOR "Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>" #define DRV_AUTHOR "Enrico Walther <enrico.walther@amd.com> / Pete Popov <ppopov@embeddedalley.com>"
#ifndef IDE_REG_SHIFT
#define IDE_REG_SHIFT 5
#endif
/* enable the burstmode in the dbdma */ /* enable the burstmode in the dbdma */
#define IDE_AU1XXX_BURSTMODE 1 #define IDE_AU1XXX_BURSTMODE 1
@ -317,10 +321,11 @@ static void auide_ddma_rx_callback(int irq, void *param)
} }
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ #endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags) static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize,
u32 devwidth, u32 flags, u32 regbase)
{ {
dev->dev_id = dev_id; dev->dev_id = dev_id;
dev->dev_physaddr = (u32)IDE_PHYS_ADDR; dev->dev_physaddr = CPHYSADDR(regbase);
dev->dev_intlevel = 0; dev->dev_intlevel = 0;
dev->dev_intpolarity = 0; dev->dev_intpolarity = 0;
dev->dev_tsize = tsize; dev->dev_tsize = tsize;
@ -344,7 +349,7 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
dbdev_tab_t source_dev_tab, target_dev_tab; dbdev_tab_t source_dev_tab, target_dev_tab;
u32 dev_id, tsize, devwidth, flags; u32 dev_id, tsize, devwidth, flags;
dev_id = IDE_DDMA_REQ; dev_id = hwif->ddma_id;
tsize = 8; /* 1 */ tsize = 8; /* 1 */
devwidth = 32; /* 16 */ devwidth = 32; /* 16 */
@ -356,20 +361,17 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
#endif #endif
/* setup dev_tab for tx channel */ /* setup dev_tab for tx channel */
auide_init_dbdma_dev( &source_dev_tab, auide_init_dbdma_dev(&source_dev_tab, dev_id, tsize, devwidth,
dev_id, DEV_FLAGS_OUT | flags, auide->regbase);
tsize, devwidth, DEV_FLAGS_OUT | flags);
auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
auide_init_dbdma_dev( &source_dev_tab, auide_init_dbdma_dev(&source_dev_tab, dev_id, tsize, devwidth,
dev_id, DEV_FLAGS_IN | flags, auide->regbase);
tsize, devwidth, DEV_FLAGS_IN | flags);
auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
/* We also need to add a target device for the DMA */ /* We also need to add a target device for the DMA */
auide_init_dbdma_dev( &target_dev_tab, auide_init_dbdma_dev(&target_dev_tab, (u32)DSCR_CMD0_ALWAYS, tsize,
(u32)DSCR_CMD0_ALWAYS, devwidth, DEV_FLAGS_ANYUSE, auide->regbase);
tsize, devwidth, DEV_FLAGS_ANYUSE);
auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab); auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab);
/* Get a channel for TX */ /* Get a channel for TX */
@ -411,14 +413,12 @@ static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
#endif #endif
/* setup dev_tab for tx channel */ /* setup dev_tab for tx channel */
auide_init_dbdma_dev( &source_dev_tab, auide_init_dbdma_dev(&source_dev_tab, (u32)DSCR_CMD0_ALWAYS, 8, 32,
(u32)DSCR_CMD0_ALWAYS, DEV_FLAGS_OUT | flags, auide->regbase);
8, 32, DEV_FLAGS_OUT | flags);
auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
auide_init_dbdma_dev( &source_dev_tab, auide_init_dbdma_dev(&source_dev_tab, (u32)DSCR_CMD0_ALWAYS, 8, 32,
(u32)DSCR_CMD0_ALWAYS, DEV_FLAGS_IN | flags, auide->regbase);
8, 32, DEV_FLAGS_IN | flags);
auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab );
/* Get a channel for TX */ /* Get a channel for TX */
@ -540,6 +540,14 @@ static int au_ide_probe(struct platform_device *dev)
goto out; goto out;
} }
res = platform_get_resource(dev, IORESOURCE_DMA, 0);
if (!res) {
pr_debug("%s: no DDMA ID resource\n", DRV_NAME);
ret = -ENODEV;
goto out;
}
ahwif->ddma_id = res->start;
memset(&hw, 0, sizeof(hw)); memset(&hw, 0, sizeof(hw));
auide_setup_ports(&hw, ahwif); auide_setup_ports(&hw, ahwif);
hw.irq = ahwif->irq; hw.irq = ahwif->irq;

View File

@ -263,7 +263,7 @@ config MMC_WBSD
config MMC_AU1X config MMC_AU1X
tristate "Alchemy AU1XX0 MMC Card Interface support" tristate "Alchemy AU1XX0 MMC Card Interface support"
depends on SOC_AU1200 depends on MIPS_ALCHEMY
help help
This selects the AMD Alchemy(R) Multimedia card interface. This selects the AMD Alchemy(R) Multimedia card interface.
If you have a Alchemy platform with a MMC slot, say Y or M here. If you have a Alchemy platform with a MMC slot, say Y or M here.

View File

@ -64,11 +64,8 @@
#define AU1XMMC_DESCRIPTOR_COUNT 1 #define AU1XMMC_DESCRIPTOR_COUNT 1
/* max DMA seg size: 64KB on Au1100, 4MB on Au1200 */ /* max DMA seg size: 64KB on Au1100, 4MB on Au1200 */
#ifdef CONFIG_SOC_AU1100 #define AU1100_MMC_DESCRIPTOR_SIZE 0x0000ffff
#define AU1XMMC_DESCRIPTOR_SIZE 0x0000ffff #define AU1200_MMC_DESCRIPTOR_SIZE 0x003fffff
#else /* Au1200 */
#define AU1XMMC_DESCRIPTOR_SIZE 0x003fffff
#endif
#define AU1XMMC_OCR (MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \ #define AU1XMMC_OCR (MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 | \
MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \ MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 | \
@ -127,6 +124,7 @@ struct au1xmmc_host {
#define HOST_F_XMIT 0x0001 #define HOST_F_XMIT 0x0001
#define HOST_F_RECV 0x0002 #define HOST_F_RECV 0x0002
#define HOST_F_DMA 0x0010 #define HOST_F_DMA 0x0010
#define HOST_F_DBDMA 0x0020
#define HOST_F_ACTIVE 0x0100 #define HOST_F_ACTIVE 0x0100
#define HOST_F_STOP 0x1000 #define HOST_F_STOP 0x1000
@ -151,6 +149,16 @@ struct au1xmmc_host {
#define DMA_CHANNEL(h) \ #define DMA_CHANNEL(h) \
(((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan) (((h)->flags & HOST_F_XMIT) ? (h)->tx_chan : (h)->rx_chan)
static inline int has_dbdma(void)
{
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1200:
return 1;
default:
return 0;
}
}
static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask) static inline void IRQ_ON(struct au1xmmc_host *host, u32 mask)
{ {
u32 val = au_readl(HOST_CONFIG(host)); u32 val = au_readl(HOST_CONFIG(host));
@ -353,14 +361,12 @@ static void au1xmmc_data_complete(struct au1xmmc_host *host, u32 status)
data->bytes_xfered = 0; data->bytes_xfered = 0;
if (!data->error) { if (!data->error) {
if (host->flags & HOST_F_DMA) { if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) {
#ifdef CONFIG_SOC_AU1200 /* DBDMA */
u32 chan = DMA_CHANNEL(host); u32 chan = DMA_CHANNEL(host);
chan_tab_t *c = *((chan_tab_t **)chan); chan_tab_t *c = *((chan_tab_t **)chan);
au1x_dma_chan_t *cp = c->chan_ptr; au1x_dma_chan_t *cp = c->chan_ptr;
data->bytes_xfered = cp->ddma_bytecnt; data->bytes_xfered = cp->ddma_bytecnt;
#endif
} else } else
data->bytes_xfered = data->bytes_xfered =
(data->blocks * data->blksz) - host->pio.len; (data->blocks * data->blksz) - host->pio.len;
@ -570,11 +576,10 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
host->status = HOST_S_DATA; host->status = HOST_S_DATA;
if (host->flags & HOST_F_DMA) { if ((host->flags & (HOST_F_DMA | HOST_F_DBDMA))) {
#ifdef CONFIG_SOC_AU1200 /* DBDMA */
u32 channel = DMA_CHANNEL(host); u32 channel = DMA_CHANNEL(host);
/* Start the DMA as soon as the buffer gets something in it */ /* Start the DBDMA as soon as the buffer gets something in it */
if (host->flags & HOST_F_RECV) { if (host->flags & HOST_F_RECV) {
u32 mask = SD_STATUS_DB | SD_STATUS_NE; u32 mask = SD_STATUS_DB | SD_STATUS_NE;
@ -584,7 +589,6 @@ static void au1xmmc_cmd_complete(struct au1xmmc_host *host, u32 status)
} }
au1xxx_dbdma_start(channel); au1xxx_dbdma_start(channel);
#endif
} }
} }
@ -633,8 +637,7 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host,
au_writel(data->blksz - 1, HOST_BLKSIZE(host)); au_writel(data->blksz - 1, HOST_BLKSIZE(host));
if (host->flags & HOST_F_DMA) { if (host->flags & (HOST_F_DMA | HOST_F_DBDMA)) {
#ifdef CONFIG_SOC_AU1200 /* DBDMA */
int i; int i;
u32 channel = DMA_CHANNEL(host); u32 channel = DMA_CHANNEL(host);
@ -663,7 +666,6 @@ static int au1xmmc_prepare_data(struct au1xmmc_host *host,
datalen -= len; datalen -= len;
} }
#endif
} else { } else {
host->pio.index = 0; host->pio.index = 0;
host->pio.offset = 0; host->pio.offset = 0;
@ -838,7 +840,6 @@ static irqreturn_t au1xmmc_irq(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#ifdef CONFIG_SOC_AU1200
/* 8bit memory DMA device */ /* 8bit memory DMA device */
static dbdev_tab_t au1xmmc_mem_dbdev = { static dbdev_tab_t au1xmmc_mem_dbdev = {
.dev_id = DSCR_CMD0_ALWAYS, .dev_id = DSCR_CMD0_ALWAYS,
@ -905,7 +906,7 @@ static int au1xmmc_dbdma_init(struct au1xmmc_host *host)
au1xxx_dbdma_ring_alloc(host->rx_chan, AU1XMMC_DESCRIPTOR_COUNT); au1xxx_dbdma_ring_alloc(host->rx_chan, AU1XMMC_DESCRIPTOR_COUNT);
/* DBDMA is good to go */ /* DBDMA is good to go */
host->flags |= HOST_F_DMA; host->flags |= HOST_F_DMA | HOST_F_DBDMA;
return 0; return 0;
} }
@ -918,7 +919,6 @@ static void au1xmmc_dbdma_shutdown(struct au1xmmc_host *host)
au1xxx_dbdma_chan_free(host->rx_chan); au1xxx_dbdma_chan_free(host->rx_chan);
} }
} }
#endif
static void au1xmmc_enable_sdio_irq(struct mmc_host *mmc, int en) static void au1xmmc_enable_sdio_irq(struct mmc_host *mmc, int en)
{ {
@ -997,8 +997,16 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
mmc->f_min = 450000; mmc->f_min = 450000;
mmc->f_max = 24000000; mmc->f_max = 24000000;
mmc->max_seg_size = AU1XMMC_DESCRIPTOR_SIZE; switch (alchemy_get_cputype()) {
mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT; case ALCHEMY_CPU_AU1100:
mmc->max_seg_size = AU1100_MMC_DESCRIPTOR_SIZE;
mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT;
break;
case ALCHEMY_CPU_AU1200:
mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE;
mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT;
break;
}
mmc->max_blk_size = 2048; mmc->max_blk_size = 2048;
mmc->max_blk_count = 512; mmc->max_blk_count = 512;
@ -1028,11 +1036,11 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
tasklet_init(&host->finish_task, au1xmmc_tasklet_finish, tasklet_init(&host->finish_task, au1xmmc_tasklet_finish,
(unsigned long)host); (unsigned long)host);
#ifdef CONFIG_SOC_AU1200 if (has_dbdma()) {
ret = au1xmmc_dbdma_init(host); ret = au1xmmc_dbdma_init(host);
if (ret) if (ret)
pr_info(DRIVER_NAME ": DBDMA init failed; using PIO\n"); pr_info(DRIVER_NAME ": DBDMA init failed; using PIO\n");
#endif }
#ifdef CONFIG_LEDS_CLASS #ifdef CONFIG_LEDS_CLASS
if (host->platdata && host->platdata->led) { if (host->platdata && host->platdata->led) {
@ -1073,9 +1081,8 @@ out5:
au_writel(0, HOST_CONFIG2(host)); au_writel(0, HOST_CONFIG2(host));
au_sync(); au_sync();
#ifdef CONFIG_SOC_AU1200 if (host->flags & HOST_F_DBDMA)
au1xmmc_dbdma_shutdown(host); au1xmmc_dbdma_shutdown(host);
#endif
tasklet_kill(&host->data_task); tasklet_kill(&host->data_task);
tasklet_kill(&host->finish_task); tasklet_kill(&host->finish_task);
@ -1120,9 +1127,9 @@ static int __devexit au1xmmc_remove(struct platform_device *pdev)
tasklet_kill(&host->data_task); tasklet_kill(&host->data_task);
tasklet_kill(&host->finish_task); tasklet_kill(&host->finish_task);
#ifdef CONFIG_SOC_AU1200 if (host->flags & HOST_F_DBDMA)
au1xmmc_dbdma_shutdown(host); au1xmmc_dbdma_shutdown(host);
#endif
au1xmmc_set_power(host, 0); au1xmmc_set_power(host, 0);
free_irq(host->irq, host); free_irq(host->irq, host);
@ -1181,24 +1188,23 @@ static struct platform_driver au1xmmc_driver = {
static int __init au1xmmc_init(void) static int __init au1xmmc_init(void)
{ {
#ifdef CONFIG_SOC_AU1200 if (has_dbdma()) {
/* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride /* DSCR_CMD0_ALWAYS has a stride of 32 bits, we need a stride
* of 8 bits. And since devices are shared, we need to create * of 8 bits. And since devices are shared, we need to create
* our own to avoid freaking out other devices. * our own to avoid freaking out other devices.
*/ */
memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev); memid = au1xxx_ddma_add_device(&au1xmmc_mem_dbdev);
if (!memid) if (!memid)
pr_err("au1xmmc: cannot add memory dbdma dev\n"); pr_err("au1xmmc: cannot add memory dbdma\n");
#endif }
return platform_driver_register(&au1xmmc_driver); return platform_driver_register(&au1xmmc_driver);
} }
static void __exit au1xmmc_exit(void) static void __exit au1xmmc_exit(void)
{ {
#ifdef CONFIG_SOC_AU1200 if (has_dbdma() && memid)
if (memid)
au1xxx_ddma_del_device(memid); au1xxx_ddma_del_device(memid);
#endif
platform_driver_unregister(&au1xmmc_driver); platform_driver_unregister(&au1xmmc_driver);
} }

View File

@ -182,7 +182,7 @@ ltq_mtd_probe(struct platform_device *pdev)
parts = ltq_mtd_data->parts; parts = ltq_mtd_data->parts;
} }
err = add_mtd_partitions(ltq_mtd->mtd, parts, nr_parts); err = mtd_device_register(ltq_mtd->mtd, parts, nr_parts);
if (err) { if (err) {
dev_err(&pdev->dev, "failed to add partitions\n"); dev_err(&pdev->dev, "failed to add partitions\n");
goto err_destroy; goto err_destroy;
@ -208,7 +208,7 @@ ltq_mtd_remove(struct platform_device *pdev)
if (ltq_mtd) { if (ltq_mtd) {
if (ltq_mtd->mtd) { if (ltq_mtd->mtd) {
del_mtd_partitions(ltq_mtd->mtd); mtd_device_unregister(ltq_mtd->mtd);
map_destroy(ltq_mtd->mtd); map_destroy(ltq_mtd->mtd);
} }
if (ltq_mtd->map->virt) if (ltq_mtd->map->virt)

View File

@ -138,7 +138,7 @@ config MTD_NAND_RICOH
config MTD_NAND_AU1550 config MTD_NAND_AU1550
tristate "Au1550/1200 NAND support" tristate "Au1550/1200 NAND support"
depends on SOC_AU1200 || SOC_AU1550 depends on MIPS_ALCHEMY
help help
This enables the driver for the NAND flash controller on the This enables the driver for the NAND flash controller on the
AMD/Alchemy 1550 SOC. AMD/Alchemy 1550 SOC.

View File

@ -19,7 +19,11 @@
#include <linux/mtd/partitions.h> #include <linux/mtd/partitions.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/mach-au1x00/au1xxx.h> #ifdef CONFIG_MIPS_PB1550
#include <asm/mach-pb1x00/pb1550.h>
#elif defined(CONFIG_MIPS_DB1550)
#include <asm/mach-db1x00/db1x00.h>
#endif
#include <asm/mach-db1x00/bcsr.h> #include <asm/mach-db1x00/bcsr.h>
/* /*

View File

@ -541,19 +541,17 @@ static void au1000_reset_mac(struct net_device *dev)
* these are not descriptors sitting in memory. * these are not descriptors sitting in memory.
*/ */
static void static void
au1000_setup_hw_rings(struct au1000_private *aup, u32 rx_base, u32 tx_base) au1000_setup_hw_rings(struct au1000_private *aup, void __iomem *tx_base)
{ {
int i; int i;
for (i = 0; i < NUM_RX_DMA; i++) { for (i = 0; i < NUM_RX_DMA; i++) {
aup->rx_dma_ring[i] = aup->rx_dma_ring[i] = (struct rx_dma *)
(struct rx_dma *) (tx_base + 0x100 + sizeof(struct rx_dma) * i);
(rx_base + sizeof(struct rx_dma)*i);
} }
for (i = 0; i < NUM_TX_DMA; i++) { for (i = 0; i < NUM_TX_DMA; i++) {
aup->tx_dma_ring[i] = aup->tx_dma_ring[i] = (struct tx_dma *)
(struct tx_dma *) (tx_base + sizeof(struct tx_dma) * i);
(tx_base + sizeof(struct tx_dma)*i);
} }
} }
@ -1026,7 +1024,7 @@ static int __devinit au1000_probe(struct platform_device *pdev)
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct db_dest *pDB, *pDBfree; struct db_dest *pDB, *pDBfree;
int irq, i, err = 0; int irq, i, err = 0;
struct resource *base, *macen; struct resource *base, *macen, *macdma;
base = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!base) { if (!base) {
@ -1049,6 +1047,13 @@ static int __devinit au1000_probe(struct platform_device *pdev)
goto out; goto out;
} }
macdma = platform_get_resource(pdev, IORESOURCE_MEM, 2);
if (!macdma) {
dev_err(&pdev->dev, "failed to retrieve MACDMA registers\n");
err = -ENODEV;
goto out;
}
if (!request_mem_region(base->start, resource_size(base), if (!request_mem_region(base->start, resource_size(base),
pdev->name)) { pdev->name)) {
dev_err(&pdev->dev, "failed to request memory region for base registers\n"); dev_err(&pdev->dev, "failed to request memory region for base registers\n");
@ -1063,6 +1068,13 @@ static int __devinit au1000_probe(struct platform_device *pdev)
goto err_request; goto err_request;
} }
if (!request_mem_region(macdma->start, resource_size(macdma),
pdev->name)) {
dev_err(&pdev->dev, "failed to request MACDMA memory region\n");
err = -ENXIO;
goto err_macdma;
}
dev = alloc_etherdev(sizeof(struct au1000_private)); dev = alloc_etherdev(sizeof(struct au1000_private));
if (!dev) { if (!dev) {
dev_err(&pdev->dev, "alloc_etherdev failed\n"); dev_err(&pdev->dev, "alloc_etherdev failed\n");
@ -1109,10 +1121,14 @@ static int __devinit au1000_probe(struct platform_device *pdev)
} }
aup->mac_id = pdev->id; aup->mac_id = pdev->id;
if (pdev->id == 0) aup->macdma = ioremap_nocache(macdma->start, resource_size(macdma));
au1000_setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR); if (!aup->macdma) {
else if (pdev->id == 1) dev_err(&pdev->dev, "failed to ioremap MACDMA registers\n");
au1000_setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR); err = -ENXIO;
goto err_remap3;
}
au1000_setup_hw_rings(aup, aup->macdma);
/* set a random MAC now in case platform_data doesn't provide one */ /* set a random MAC now in case platform_data doesn't provide one */
random_ether_addr(dev->dev_addr); random_ether_addr(dev->dev_addr);
@ -1252,6 +1268,8 @@ err_out:
err_mdiobus_reg: err_mdiobus_reg:
mdiobus_free(aup->mii_bus); mdiobus_free(aup->mii_bus);
err_mdiobus_alloc: err_mdiobus_alloc:
iounmap(aup->macdma);
err_remap3:
iounmap(aup->enable); iounmap(aup->enable);
err_remap2: err_remap2:
iounmap(aup->mac); iounmap(aup->mac);
@ -1261,6 +1279,8 @@ err_remap1:
err_vaddr: err_vaddr:
free_netdev(dev); free_netdev(dev);
err_alloc: err_alloc:
release_mem_region(macdma->start, resource_size(macdma));
err_macdma:
release_mem_region(macen->start, resource_size(macen)); release_mem_region(macen->start, resource_size(macen));
err_request: err_request:
release_mem_region(base->start, resource_size(base)); release_mem_region(base->start, resource_size(base));
@ -1293,9 +1313,13 @@ static int __devexit au1000_remove(struct platform_device *pdev)
(NUM_TX_BUFFS + NUM_RX_BUFFS), (NUM_TX_BUFFS + NUM_RX_BUFFS),
(void *)aup->vaddr, aup->dma_addr); (void *)aup->vaddr, aup->dma_addr);
iounmap(aup->macdma);
iounmap(aup->mac); iounmap(aup->mac);
iounmap(aup->enable); iounmap(aup->enable);
base = platform_get_resource(pdev, IORESOURCE_MEM, 2);
release_mem_region(base->start, resource_size(base));
base = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
release_mem_region(base->start, resource_size(base)); release_mem_region(base->start, resource_size(base));

View File

@ -124,7 +124,7 @@ struct au1000_private {
*/ */
struct mac_reg *mac; /* mac registers */ struct mac_reg *mac; /* mac registers */
u32 *enable; /* address of MAC Enable Register */ u32 *enable; /* address of MAC Enable Register */
void __iomem *macdma; /* base of MAC DMA port */
u32 vaddr; /* virtual address of rx/tx buffers */ u32 vaddr; /* virtual address of rx/tx buffers */
dma_addr_t dma_addr; /* dma address of rx/tx buffers */ dma_addr_t dma_addr; /* dma address of rx/tx buffers */

View File

@ -314,7 +314,7 @@ config TOSHIBA_FIR
config AU1000_FIR config AU1000_FIR
tristate "Alchemy Au1000 SIR/FIR" tristate "Alchemy Au1000 SIR/FIR"
depends on SOC_AU1000 && IRDA depends on IRDA && MIPS_ALCHEMY
config SMC_IRCC_FIR config SMC_IRCC_FIR
tristate "SMSC IrCC (EXPERIMENTAL)" tristate "SMSC IrCC (EXPERIMENTAL)"

View File

@ -88,7 +88,7 @@ config SPI_BFIN_SPORT
config SPI_AU1550 config SPI_AU1550
tristate "Au1550/Au12x0 SPI Controller" tristate "Au1550/Au12x0 SPI Controller"
depends on (SOC_AU1550 || SOC_AU1200) && EXPERIMENTAL depends on MIPS_ALCHEMY && EXPERIMENTAL
select SPI_BITBANG select SPI_BITBANG
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the

View File

@ -62,7 +62,6 @@ config USB_ARCH_HAS_EHCI
boolean boolean
default y if FSL_SOC default y if FSL_SOC
default y if PPC_MPC512x default y if PPC_MPC512x
default y if SOC_AU1200
default y if ARCH_IXP4XX default y if ARCH_IXP4XX
default y if ARCH_W90X900 default y if ARCH_W90X900
default y if ARCH_AT91SAM9G45 default y if ARCH_AT91SAM9G45

View File

@ -36,3 +36,4 @@ obj-$(CONFIG_USB_HWA_HCD) += hwa-hc.o
obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o obj-$(CONFIG_USB_IMX21_HCD) += imx21-hcd.o
obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o obj-$(CONFIG_USB_FSL_MPH_DR_OF) += fsl-mph-dr-of.o
obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o obj-$(CONFIG_USB_OCTEON2_COMMON) += octeon2-common.o
obj-$(CONFIG_MIPS_ALCHEMY) += alchemy-common.o

View File

@ -0,0 +1,337 @@
/*
* USB block power/access management abstraction.
*
* Au1000+: The OHCI block control register is at the far end of the OHCI memory
* area. Au1550 has OHCI on different base address. No need to handle
* UDC here.
* Au1200: one register to control access and clocks to O/EHCI, UDC and OTG
* as well as the PHY for EHCI and UDC.
*
*/
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/syscore_ops.h>
#include <asm/mach-au1x00/au1000.h>
/* control register offsets */
#define AU1000_OHCICFG 0x7fffc
#define AU1550_OHCICFG 0x07ffc
#define AU1200_USBCFG 0x04
/* Au1000 USB block config bits */
#define USBHEN_RD (1 << 4) /* OHCI reset-done indicator */
#define USBHEN_CE (1 << 3) /* OHCI block clock enable */
#define USBHEN_E (1 << 2) /* OHCI block enable */
#define USBHEN_C (1 << 1) /* OHCI block coherency bit */
#define USBHEN_BE (1 << 0) /* OHCI Big-Endian */
/* Au1200 USB config bits */
#define USBCFG_PFEN (1 << 31) /* prefetch enable (undoc) */
#define USBCFG_RDCOMB (1 << 30) /* read combining (undoc) */
#define USBCFG_UNKNOWN (5 << 20) /* unknown, leave this way */
#define USBCFG_SSD (1 << 23) /* serial short detect en */
#define USBCFG_PPE (1 << 19) /* HS PHY PLL */
#define USBCFG_UCE (1 << 18) /* UDC clock enable */
#define USBCFG_ECE (1 << 17) /* EHCI clock enable */
#define USBCFG_OCE (1 << 16) /* OHCI clock enable */
#define USBCFG_FLA(x) (((x) & 0x3f) << 8)
#define USBCFG_UCAM (1 << 7) /* coherent access (undoc) */
#define USBCFG_GME (1 << 6) /* OTG mem access */
#define USBCFG_DBE (1 << 5) /* UDC busmaster enable */
#define USBCFG_DME (1 << 4) /* UDC mem enable */
#define USBCFG_EBE (1 << 3) /* EHCI busmaster enable */
#define USBCFG_EME (1 << 2) /* EHCI mem enable */
#define USBCFG_OBE (1 << 1) /* OHCI busmaster enable */
#define USBCFG_OME (1 << 0) /* OHCI mem enable */
#define USBCFG_INIT_AU1200 (USBCFG_PFEN | USBCFG_RDCOMB | USBCFG_UNKNOWN |\
USBCFG_SSD | USBCFG_FLA(0x20) | USBCFG_UCAM | \
USBCFG_GME | USBCFG_DBE | USBCFG_DME | \
USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \
USBCFG_OME)
static DEFINE_SPINLOCK(alchemy_usb_lock);
static inline void __au1200_ohci_control(void __iomem *base, int enable)
{
unsigned long r = __raw_readl(base + AU1200_USBCFG);
if (enable) {
__raw_writel(r | USBCFG_OCE, base + AU1200_USBCFG);
wmb();
udelay(2000);
} else {
__raw_writel(r & ~USBCFG_OCE, base + AU1200_USBCFG);
wmb();
udelay(1000);
}
}
static inline void __au1200_ehci_control(void __iomem *base, int enable)
{
unsigned long r = __raw_readl(base + AU1200_USBCFG);
if (enable) {
__raw_writel(r | USBCFG_ECE | USBCFG_PPE, base + AU1200_USBCFG);
wmb();
udelay(1000);
} else {
if (!(r & USBCFG_UCE)) /* UDC also off? */
r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
__raw_writel(r & ~USBCFG_ECE, base + AU1200_USBCFG);
wmb();
udelay(1000);
}
}
static inline void __au1200_udc_control(void __iomem *base, int enable)
{
unsigned long r = __raw_readl(base + AU1200_USBCFG);
if (enable) {
__raw_writel(r | USBCFG_UCE | USBCFG_PPE, base + AU1200_USBCFG);
wmb();
} else {
if (!(r & USBCFG_ECE)) /* EHCI also off? */
r &= ~USBCFG_PPE; /* yes: disable HS PHY PLL */
__raw_writel(r & ~USBCFG_UCE, base + AU1200_USBCFG);
wmb();
}
}
static inline int au1200_coherency_bug(void)
{
#if defined(CONFIG_DMA_COHERENT)
/* Au1200 AB USB does not support coherent memory */
if (!(read_c0_prid() & 0xff)) {
printk(KERN_INFO "Au1200 USB: this is chip revision AB !!\n");
printk(KERN_INFO "Au1200 USB: update your board or re-configure"
" the kernel\n");
return -ENODEV;
}
#endif
return 0;
}
static inline int au1200_usb_control(int block, int enable)
{
void __iomem *base =
(void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
int ret = 0;
switch (block) {
case ALCHEMY_USB_OHCI0:
ret = au1200_coherency_bug();
if (ret && enable)
goto out;
__au1200_ohci_control(base, enable);
break;
case ALCHEMY_USB_UDC0:
__au1200_udc_control(base, enable);
break;
case ALCHEMY_USB_EHCI0:
ret = au1200_coherency_bug();
if (ret && enable)
goto out;
__au1200_ehci_control(base, enable);
break;
default:
ret = -ENODEV;
}
out:
return ret;
}
/* initialize USB block(s) to a known working state */
static inline void au1200_usb_init(void)
{
void __iomem *base =
(void __iomem *)KSEG1ADDR(AU1200_USB_CTL_PHYS_ADDR);
__raw_writel(USBCFG_INIT_AU1200, base + AU1200_USBCFG);
wmb();
udelay(1000);
}
static inline void au1000_usb_init(unsigned long rb, int reg)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg);
unsigned long r = __raw_readl(base);
#if defined(__BIG_ENDIAN)
r |= USBHEN_BE;
#endif
r |= USBHEN_C;
__raw_writel(r, base);
wmb();
udelay(1000);
}
static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(rb);
unsigned long r = __raw_readl(base + creg);
if (enable) {
__raw_writel(r | USBHEN_CE, base + creg);
wmb();
udelay(1000);
__raw_writel(r | USBHEN_CE | USBHEN_E, base + creg);
wmb();
udelay(1000);
/* wait for reset complete (read reg twice: au1500 erratum) */
while (__raw_readl(base + creg),
!(__raw_readl(base + creg) & USBHEN_RD))
udelay(1000);
} else {
__raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg);
wmb();
}
}
static inline int au1000_usb_control(int block, int enable, unsigned long rb,
int creg)
{
int ret = 0;
switch (block) {
case ALCHEMY_USB_OHCI0:
__au1xx0_ohci_control(enable, rb, creg);
break;
default:
ret = -ENODEV;
}
return ret;
}
/*
* alchemy_usb_control - control Alchemy on-chip USB blocks
* @block: USB block to target
* @enable: set 1 to enable a block, 0 to disable
*/
int alchemy_usb_control(int block, int enable)
{
unsigned long flags;
int ret;
spin_lock_irqsave(&alchemy_usb_lock, flags);
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1100:
ret = au1000_usb_control(block, enable,
AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
break;
case ALCHEMY_CPU_AU1550:
ret = au1000_usb_control(block, enable,
AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
break;
case ALCHEMY_CPU_AU1200:
ret = au1200_usb_control(block, enable);
break;
default:
ret = -ENODEV;
}
spin_unlock_irqrestore(&alchemy_usb_lock, flags);
return ret;
}
EXPORT_SYMBOL_GPL(alchemy_usb_control);
static unsigned long alchemy_usb_pmdata[2];
static void au1000_usb_pm(unsigned long br, int creg, int susp)
{
void __iomem *base = (void __iomem *)KSEG1ADDR(br);
if (susp) {
alchemy_usb_pmdata[0] = __raw_readl(base + creg);
/* There appears to be some undocumented reset register.... */
__raw_writel(0, base + 0x04);
wmb();
__raw_writel(0, base + creg);
wmb();
} else {
__raw_writel(alchemy_usb_pmdata[0], base + creg);
wmb();
}
}
static void au1200_usb_pm(int susp)
{
void __iomem *base =
(void __iomem *)KSEG1ADDR(AU1200_USB_OTG_PHYS_ADDR);
if (susp) {
/* save OTG_CAP/MUX registers which indicate port routing */
/* FIXME: write an OTG driver to do that */
alchemy_usb_pmdata[0] = __raw_readl(base + 0x00);
alchemy_usb_pmdata[1] = __raw_readl(base + 0x04);
} else {
/* restore access to all MMIO areas */
au1200_usb_init();
/* restore OTG_CAP/MUX registers */
__raw_writel(alchemy_usb_pmdata[0], base + 0x00);
__raw_writel(alchemy_usb_pmdata[1], base + 0x04);
wmb();
}
}
static void alchemy_usb_pm(int susp)
{
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1100:
au1000_usb_pm(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG, susp);
break;
case ALCHEMY_CPU_AU1550:
au1000_usb_pm(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG, susp);
break;
case ALCHEMY_CPU_AU1200:
au1200_usb_pm(susp);
break;
}
}
static int alchemy_usb_suspend(void)
{
alchemy_usb_pm(1);
return 0;
}
static void alchemy_usb_resume(void)
{
alchemy_usb_pm(0);
}
static struct syscore_ops alchemy_usb_pm_ops = {
.suspend = alchemy_usb_suspend,
.resume = alchemy_usb_resume,
};
static int __init alchemy_usb_init(void)
{
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000:
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1100:
au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG);
break;
case ALCHEMY_CPU_AU1550:
au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG);
break;
case ALCHEMY_CPU_AU1200:
au1200_usb_init();
break;
}
register_syscore_ops(&alchemy_usb_pm_ops);
return 0;
}
arch_initcall(alchemy_usb_init);

View File

@ -14,61 +14,9 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)
#define USB_MCFG_PFEN (1<<31)
#define USB_MCFG_RDCOMB (1<<30)
#define USB_MCFG_SSDEN (1<<23)
#define USB_MCFG_PHYPLLEN (1<<19)
#define USB_MCFG_UCECLKEN (1<<18)
#define USB_MCFG_EHCCLKEN (1<<17)
#ifdef CONFIG_DMA_COHERENT
#define USB_MCFG_UCAM (1<<7)
#else
#define USB_MCFG_UCAM (0)
#endif
#define USB_MCFG_EBMEN (1<<3)
#define USB_MCFG_EMEMEN (1<<2)
#define USBH_ENABLE_CE (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN)
#define USBH_ENABLE_INIT (USB_MCFG_PFEN | USB_MCFG_RDCOMB | \
USBH_ENABLE_CE | USB_MCFG_SSDEN | \
USB_MCFG_UCAM | USB_MCFG_EBMEN | \
USB_MCFG_EMEMEN)
#define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
extern int usb_disabled(void); extern int usb_disabled(void);
static void au1xxx_start_ehc(void)
{
/* enable clock to EHCI block and HS PHY PLL*/
au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG);
au_sync();
udelay(1000);
/* enable EHCI mmio */
au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG);
au_sync();
udelay(1000);
}
static void au1xxx_stop_ehc(void)
{
unsigned long c;
/* Disable mem */
au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG);
au_sync();
udelay(1000);
/* Disable EHC clock. If the HS PHY is unused disable it too. */
c = au_readl(USB_HOST_CONFIG) & ~USB_MCFG_EHCCLKEN;
if (!(c & USB_MCFG_UCECLKEN)) /* UDC disabled? */
c &= ~USB_MCFG_PHYPLLEN; /* yes: disable HS PHY PLL */
au_writel(c, USB_HOST_CONFIG);
au_sync();
}
static int au1xxx_ehci_setup(struct usb_hcd *hcd) static int au1xxx_ehci_setup(struct usb_hcd *hcd)
{ {
struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct ehci_hcd *ehci = hcd_to_ehci(hcd);
@ -136,16 +84,6 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
if (usb_disabled()) if (usb_disabled())
return -ENODEV; return -ENODEV;
#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
/* Au1200 AB USB does not support coherent memory */
if (!(read_c0_prid() & 0xff)) {
printk(KERN_INFO "%s: this is chip revision AB!\n", pdev->name);
printk(KERN_INFO "%s: update your board or re-configure"
" the kernel\n", pdev->name);
return -ENODEV;
}
#endif
if (pdev->resource[1].flags != IORESOURCE_IRQ) { if (pdev->resource[1].flags != IORESOURCE_IRQ) {
pr_debug("resource[1] is not IORESOURCE_IRQ"); pr_debug("resource[1] is not IORESOURCE_IRQ");
return -ENOMEM; return -ENOMEM;
@ -171,7 +109,11 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
goto err2; goto err2;
} }
au1xxx_start_ehc(); if (alchemy_usb_control(ALCHEMY_USB_EHCI0, 1)) {
printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
ret = -ENODEV;
goto err3;
}
ehci = hcd_to_ehci(hcd); ehci = hcd_to_ehci(hcd);
ehci->caps = hcd->regs; ehci->caps = hcd->regs;
@ -187,7 +129,8 @@ static int ehci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
return ret; return ret;
} }
au1xxx_stop_ehc(); alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
err3:
iounmap(hcd->regs); iounmap(hcd->regs);
err2: err2:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len); release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@ -201,10 +144,10 @@ static int ehci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev); struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_remove_hcd(hcd); usb_remove_hcd(hcd);
alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
iounmap(hcd->regs); iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len); release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd); usb_put_hcd(hcd);
au1xxx_stop_ehc();
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
return 0; return 0;
@ -236,7 +179,7 @@ static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
// could save FLADJ in case of Vaux power loss // could save FLADJ in case of Vaux power loss
// ... we'd only use it to handle clock skew // ... we'd only use it to handle clock skew
au1xxx_stop_ehc(); alchemy_usb_control(ALCHEMY_USB_EHCI0, 0);
return rc; return rc;
} }
@ -246,7 +189,7 @@ static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_hcd *hcd = dev_get_drvdata(dev);
struct ehci_hcd *ehci = hcd_to_ehci(hcd); struct ehci_hcd *ehci = hcd_to_ehci(hcd);
au1xxx_start_ehc(); alchemy_usb_control(ALCHEMY_USB_EHCI0, 1);
// maybe restore FLADJ // maybe restore FLADJ

View File

@ -1224,7 +1224,7 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_hcd_sh_driver #define PLATFORM_DRIVER ehci_hcd_sh_driver
#endif #endif
#ifdef CONFIG_SOC_AU1200 #ifdef CONFIG_MIPS_ALCHEMY
#include "ehci-au1xxx.c" #include "ehci-au1xxx.c"
#define PLATFORM_DRIVER ehci_hcd_au1xxx_driver #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver
#endif #endif

View File

@ -23,92 +23,9 @@
#include <asm/mach-au1x00/au1000.h> #include <asm/mach-au1x00/au1000.h>
#ifndef CONFIG_SOC_AU1200
#define USBH_ENABLE_BE (1<<0)
#define USBH_ENABLE_C (1<<1)
#define USBH_ENABLE_E (1<<2)
#define USBH_ENABLE_CE (1<<3)
#define USBH_ENABLE_RD (1<<4)
#ifdef __LITTLE_ENDIAN
#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C)
#elif defined(__BIG_ENDIAN)
#define USBH_ENABLE_INIT (USBH_ENABLE_CE | USBH_ENABLE_E | USBH_ENABLE_C | \
USBH_ENABLE_BE)
#else
#error not byte order defined
#endif
#else /* Au1200 */
#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)
#define USB_MCFG_PFEN (1<<31)
#define USB_MCFG_RDCOMB (1<<30)
#define USB_MCFG_SSDEN (1<<23)
#define USB_MCFG_OHCCLKEN (1<<16)
#ifdef CONFIG_DMA_COHERENT
#define USB_MCFG_UCAM (1<<7)
#else
#define USB_MCFG_UCAM (0)
#endif
#define USB_MCFG_OBMEN (1<<1)
#define USB_MCFG_OMEMEN (1<<0)
#define USBH_ENABLE_CE USB_MCFG_OHCCLKEN
#define USBH_ENABLE_INIT (USB_MCFG_PFEN | USB_MCFG_RDCOMB | \
USBH_ENABLE_CE | USB_MCFG_SSDEN | \
USB_MCFG_UCAM | \
USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
#define USBH_DISABLE (USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
#endif /* Au1200 */
extern int usb_disabled(void); extern int usb_disabled(void);
static void au1xxx_start_ohc(void)
{
/* enable host controller */
#ifndef CONFIG_SOC_AU1200
au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
au_sync();
udelay(1000);
au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG);
au_sync();
udelay(1000);
/* wait for reset complete (read register twice; see au1500 errata) */
while (au_readl(USB_HOST_CONFIG),
!(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
udelay(1000);
#else /* Au1200 */
au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_CE, USB_HOST_CONFIG);
au_sync();
udelay(1000);
au_writel(au_readl(USB_HOST_CONFIG) | USBH_ENABLE_INIT, USB_HOST_CONFIG);
au_sync();
udelay(2000);
#endif /* Au1200 */
}
static void au1xxx_stop_ohc(void)
{
#ifdef CONFIG_SOC_AU1200
/* Disable mem */
au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_DISABLE, USB_HOST_CONFIG);
au_sync();
udelay(1000);
#endif
/* Disable clock */
au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
au_sync();
}
static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd) static int __devinit ohci_au1xxx_start(struct usb_hcd *hcd)
{ {
struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct ohci_hcd *ohci = hcd_to_ohci(hcd);
@ -178,17 +95,6 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
if (usb_disabled()) if (usb_disabled())
return -ENODEV; return -ENODEV;
#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
/* Au1200 AB USB does not support coherent memory */
if (!(read_c0_prid() & 0xff)) {
printk(KERN_INFO "%s: this is chip revision AB !!\n",
pdev->name);
printk(KERN_INFO "%s: update your board or re-configure "
"the kernel\n", pdev->name);
return -ENODEV;
}
#endif
if (pdev->resource[1].flags != IORESOURCE_IRQ) { if (pdev->resource[1].flags != IORESOURCE_IRQ) {
pr_debug("resource[1] is not IORESOURCE_IRQ\n"); pr_debug("resource[1] is not IORESOURCE_IRQ\n");
return -ENOMEM; return -ENOMEM;
@ -214,7 +120,12 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
goto err2; goto err2;
} }
au1xxx_start_ohc(); if (alchemy_usb_control(ALCHEMY_USB_OHCI0, 1)) {
printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
ret = -ENODEV;
goto err3;
}
ohci_hcd_init(hcd_to_ohci(hcd)); ohci_hcd_init(hcd_to_ohci(hcd));
ret = usb_add_hcd(hcd, pdev->resource[1].start, ret = usb_add_hcd(hcd, pdev->resource[1].start,
@ -224,7 +135,8 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
return ret; return ret;
} }
au1xxx_stop_ohc(); alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
err3:
iounmap(hcd->regs); iounmap(hcd->regs);
err2: err2:
release_mem_region(hcd->rsrc_start, hcd->rsrc_len); release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
@ -238,7 +150,7 @@ static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
struct usb_hcd *hcd = platform_get_drvdata(pdev); struct usb_hcd *hcd = platform_get_drvdata(pdev);
usb_remove_hcd(hcd); usb_remove_hcd(hcd);
au1xxx_stop_ohc(); alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
iounmap(hcd->regs); iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len); release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd); usb_put_hcd(hcd);
@ -275,7 +187,7 @@ static int ohci_hcd_au1xxx_drv_suspend(struct device *dev)
clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
au1xxx_stop_ohc(); alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
bail: bail:
spin_unlock_irqrestore(&ohci->lock, flags); spin_unlock_irqrestore(&ohci->lock, flags);
@ -286,7 +198,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct device *dev)
{ {
struct usb_hcd *hcd = dev_get_drvdata(dev); struct usb_hcd *hcd = dev_get_drvdata(dev);
au1xxx_start_ohc(); alchemy_usb_control(ALCHEMY_USB_OHCI0, 1);
set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
ohci_finish_controller_resume(hcd); ohci_finish_controller_resume(hcd);

View File

@ -1753,7 +1753,7 @@ endchoice
config FB_AU1100 config FB_AU1100
bool "Au1100 LCD Driver" bool "Au1100 LCD Driver"
depends on (FB = y) && MIPS && SOC_AU1100 depends on (FB = y) && MIPS_ALCHEMY
select FB_CFB_FILLRECT select FB_CFB_FILLRECT
select FB_CFB_COPYAREA select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT select FB_CFB_IMAGEBLIT
@ -1764,7 +1764,7 @@ config FB_AU1100
config FB_AU1200 config FB_AU1200
bool "Au1200 LCD Driver" bool "Au1200 LCD Driver"
depends on (FB = y) && MIPS && SOC_AU1200 depends on (FB = y) && MIPS_ALCHEMY
select FB_SYS_FILLRECT select FB_SYS_FILLRECT
select FB_SYS_COPYAREA select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT select FB_SYS_IMAGEBLIT

View File

@ -24,7 +24,7 @@ config SND_SGI_HAL2
config SND_AU1X00 config SND_AU1X00
tristate "Au1x00 AC97 Port Driver (DEPRECATED)" tristate "Au1x00 AC97 Port Driver (DEPRECATED)"
depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500 depends on MIPS_ALCHEMY
select SND_PCM select SND_PCM
select SND_AC97_CODEC select SND_AC97_CODEC
help help

View File

@ -3,7 +3,7 @@
## ##
config SND_SOC_AU1XPSC config SND_SOC_AU1XPSC
tristate "SoC Audio for Au1200/Au1250/Au1550" tristate "SoC Audio for Au1200/Au1250/Au1550"
depends on SOC_AU1200 || SOC_AU1550 depends on MIPS_ALCHEMY
help help
This option enables support for the Programmable Serial This option enables support for the Programmable Serial
Controllers in AC97 and I2S mode, and the Descriptor-Based DMA Controllers in AC97 and I2S mode, and the Descriptor-Based DMA