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

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus: (37 commits)
  MIPS: Only write c0_framemask on CPUs which have this register.
  MIPS: Alchemy: new userspace suspend interface for development boards.
  MIPS: Alchemy: dbdma suspend/resume support.
  MIPS: Alchemy: Fix up PM code on Au1550/Au1200
  MIPS: Alchemy: move calc_clock function.
  MIPS: Alchemy: RTC counter clocksource / clockevent support.
  MIPS: make cp0 counter clocksource/event usable as fallback.
  MIPS: Alchemy: remove cpu_table.
  MIPS: Alchemy: remove get/set_au1x00_lcd_clock().
  MIPS: Print irq handler description
  MIPS: Alchemy: pb1200: update CPLD cascade irq handler.
  MIPS: Alchemy: update core interrupt code.
  MIPS: Alchemy: move commandline mangling out of common code
  MIPS: Alchemy: devboards: consolidate files
  MIPS: Alchemy: Move development board code to common subdirectory
  MIPS: Add Cavium OCTEON to arch/mips/Kconfig
  MIPS: Add defconfig for Cavium OCTEON.
  MIPS: Adjust the dma-common.c platform hooks.
  MIPS: Add Cavium OCTEON slot into proper tlb category.
  MIPS:  Compute branch returns for Cavium OCTEON specific branch instructions.
  ...
This commit is contained in:
Linus Torvalds 2009-01-12 16:25:35 -08:00
commit 9219a3b988
126 changed files with 18981 additions and 2038 deletions

View file

@ -595,6 +595,44 @@ config WR_PPMC
This enables support for the Wind River MIPS32 4KC PPMC evaluation
board, which is based on GT64120 bridge chip.
config CAVIUM_OCTEON_SIMULATOR
bool "Support for the Cavium Networks Octeon Simulator"
select CEVT_R4K
select 64BIT_PHYS_ADDR
select DMA_COHERENT
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_HIGHMEM
select CPU_CAVIUM_OCTEON
help
The Octeon simulator is software performance model of the Cavium
Octeon Processor. It supports simulating Octeon processors on x86
hardware.
config CAVIUM_OCTEON_REFERENCE_BOARD
bool "Support for the Cavium Networks Octeon reference board"
select CEVT_R4K
select 64BIT_PHYS_ADDR
select DMA_COHERENT
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_HIGHMEM
select SYS_HAS_EARLY_PRINTK
select CPU_CAVIUM_OCTEON
select SWAP_IO_SPACE
help
This option supports all of the Octeon reference boards from Cavium
Networks. It builds a kernel that dynamically determines the Octeon
CPU type and supports all known board reference implementations.
Some of the supported boards are:
EBT3000
EBH3000
EBH3100
Thunder
Kodama
Hikari
Say Y here for most Octeon reference boards.
endchoice
source "arch/mips/alchemy/Kconfig"
@ -607,6 +645,7 @@ source "arch/mips/sgi-ip27/Kconfig"
source "arch/mips/sibyte/Kconfig"
source "arch/mips/txx9/Kconfig"
source "arch/mips/vr41xx/Kconfig"
source "arch/mips/cavium-octeon/Kconfig"
endmenu
@ -682,7 +721,11 @@ config CEVT_DS1287
config CEVT_GT641XX
bool
config CEVT_R4K_LIB
bool
config CEVT_R4K
select CEVT_R4K_LIB
bool
config CEVT_SB1250
@ -697,7 +740,11 @@ config CSRC_BCM1480
config CSRC_IOASIC
bool
config CSRC_R4K_LIB
bool
config CSRC_R4K
select CSRC_R4K_LIB
bool
config CSRC_SB1250
@ -835,6 +882,9 @@ config IRQ_GT641XX
config IRQ_GIC
bool
config IRQ_CPU_OCTEON
bool
config MIPS_BOARDS_GEN
bool
@ -924,7 +974,7 @@ config BOOT_ELF32
config MIPS_L1_CACHE_SHIFT
int
default "4" if MACH_DECSTATION || MIKROTIK_RB532
default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM
default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
default "4" if PMC_MSP4200_EVAL
default "5"
@ -1185,6 +1235,23 @@ config CPU_SB1
select CPU_SUPPORTS_HIGHMEM
select WEAK_ORDERING
config CPU_CAVIUM_OCTEON
bool "Cavium Octeon processor"
select IRQ_CPU
select IRQ_CPU_OCTEON
select CPU_HAS_PREFETCH
select CPU_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_SMP
select NR_CPUS_DEFAULT_16
select WEAK_ORDERING
select WEAK_REORDERING_BEYOND_LLSC
select CPU_SUPPORTS_HIGHMEM
help
The Cavium Octeon processor is a highly integrated chip containing
many ethernet hardware widgets for networking tasks. The processor
can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
Full details can be found at http://www.caviumnetworks.com.
endchoice
config SYS_HAS_CPU_LOONGSON2
@ -1285,7 +1352,7 @@ config CPU_MIPSR1
config CPU_MIPSR2
bool
default y if CPU_MIPS32_R2 || CPU_MIPS64_R2
default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON
config SYS_SUPPORTS_32BIT_KERNEL
bool

View file

@ -144,6 +144,10 @@ cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \
cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap
cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \
-Wa,--trap
cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
endif
cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
@ -184,84 +188,84 @@ cflags-$(CONFIG_SOC_AU1X00) += -I$(srctree)/arch/mips/include/asm/mach-au1x00
#
# AMD Alchemy Pb1000 eval board
#
libs-$(CONFIG_MIPS_PB1000) += arch/mips/alchemy/pb1000/
core-$(CONFIG_MIPS_PB1000) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1000) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1000) += 0xffffffff80100000
#
# AMD Alchemy Pb1100 eval board
#
libs-$(CONFIG_MIPS_PB1100) += arch/mips/alchemy/pb1100/
core-$(CONFIG_MIPS_PB1100) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1100) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1100) += 0xffffffff80100000
#
# AMD Alchemy Pb1500 eval board
#
libs-$(CONFIG_MIPS_PB1500) += arch/mips/alchemy/pb1500/
core-$(CONFIG_MIPS_PB1500) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1500) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1500) += 0xffffffff80100000
#
# AMD Alchemy Pb1550 eval board
#
libs-$(CONFIG_MIPS_PB1550) += arch/mips/alchemy/pb1550/
core-$(CONFIG_MIPS_PB1550) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1550) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000
#
# AMD Alchemy Pb1200 eval board
#
libs-$(CONFIG_MIPS_PB1200) += arch/mips/alchemy/pb1200/
core-$(CONFIG_MIPS_PB1200) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1200) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000
#
# AMD Alchemy Db1000 eval board
#
libs-$(CONFIG_MIPS_DB1000) += arch/mips/alchemy/db1x00/
core-$(CONFIG_MIPS_DB1000) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000
#
# AMD Alchemy Db1100 eval board
#
libs-$(CONFIG_MIPS_DB1100) += arch/mips/alchemy/db1x00/
core-$(CONFIG_MIPS_DB1100) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1100) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1100) += 0xffffffff80100000
#
# AMD Alchemy Db1500 eval board
#
libs-$(CONFIG_MIPS_DB1500) += arch/mips/alchemy/db1x00/
core-$(CONFIG_MIPS_DB1500) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1500) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1500) += 0xffffffff80100000
#
# AMD Alchemy Db1550 eval board
#
libs-$(CONFIG_MIPS_DB1550) += arch/mips/alchemy/db1x00/
core-$(CONFIG_MIPS_DB1550) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
#
# AMD Alchemy Db1200 eval board
#
libs-$(CONFIG_MIPS_DB1200) += arch/mips/alchemy/pb1200/
core-$(CONFIG_MIPS_DB1200) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1200) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
#
# AMD Alchemy Bosporus eval board
#
libs-$(CONFIG_MIPS_BOSPORUS) += arch/mips/alchemy/db1x00/
core-$(CONFIG_MIPS_BOSPORUS) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_BOSPORUS) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_BOSPORUS) += 0xffffffff80100000
#
# AMD Alchemy Mirage eval board
#
libs-$(CONFIG_MIPS_MIRAGE) += arch/mips/alchemy/db1x00/
core-$(CONFIG_MIPS_MIRAGE) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_MIRAGE) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_MIRAGE) += 0xffffffff80100000
@ -586,6 +590,18 @@ core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/txx9/rbtx4927/
core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/rbtx4938/
core-$(CONFIG_TOSHIBA_RBTX4939) += arch/mips/txx9/rbtx4939/
#
# Cavium Octeon
#
core-$(CONFIG_CPU_CAVIUM_OCTEON) += arch/mips/cavium-octeon/
cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
core-$(CONFIG_CPU_CAVIUM_OCTEON) += arch/mips/cavium-octeon/executive/
ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff84100000
else
load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
endif
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/

View file

@ -128,9 +128,10 @@ config SOC_AU1200
config SOC_AU1X00
bool
select 64BIT_PHYS_ADDR
select CEVT_R4K
select CSRC_R4K
select CEVT_R4K_LIB
select CSRC_R4K_LIB
select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_APM_EMULATION
select GENERIC_HARDIRQS_NO__DO_IRQ

View file

@ -6,8 +6,8 @@
#
obj-y += prom.o irq.o puts.o time.o reset.o \
au1xxx_irqmap.o clocks.o platform.o power.o setup.o \
sleeper.o cputable.o dma.o dbdma.o gpio.o
clocks.o platform.o power.o setup.o \
sleeper.o dma.o dbdma.o gpio.o
obj-$(CONFIG_PCI) += pci.o

View file

@ -1,205 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Au1xxx processor specific IRQ tables
*
* Copyright 2004 Embedded Edge, LLC
* dan@embeddededge.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/init.h>
#include <linux/kernel.h>
#include <au1000.h>
/* The IC0 interrupt table. This is processor, rather than
* board dependent, so no reason to keep this info in the board
* dependent files.
*
* Careful if you change match 2 request!
* The interrupt handler is called directly from the low level dispatch code.
*/
struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
#if defined(CONFIG_SOC_AU1000)
{ AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
#elif defined(CONFIG_SOC_AU1500)
{ AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
#elif defined(CONFIG_SOC_AU1100)
{ AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
/* { AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0 }, */
{ AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
#elif defined(CONFIG_SOC_AU1550)
{ AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
{ AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
{ AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
{ AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
{ AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 },
{ AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1550_NAND_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1550_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
{ AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
#elif defined(CONFIG_SOC_AU1200)
{ AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1000_TOY_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_TOY_MATCH2_INT, INTC_INT_RISE_EDGE, 1 },
{ AU1000_RTC_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH0_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH1_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1000_RTC_MATCH2_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1200_NAND_INT, INTC_INT_RISE_EDGE, 0 },
{ AU1200_USB_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
{ AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0 },
#else
#error "Error: Unknown Alchemy SOC"
#endif
};
int __initdata au1xxx_ic0_nr_irqs = ARRAY_SIZE(au1xxx_ic0_map);

View file

@ -27,12 +27,21 @@
*/
#include <linux/module.h>
#include <linux/spinlock.h>
#include <asm/time.h>
#include <asm/mach-au1x00/au1000.h>
/*
* I haven't found anyone that doesn't use a 12 MHz source clock,
* but just in case.....
*/
#define AU1000_SRC_CLK 12000000
static unsigned int au1x00_clock; /* Hz */
static unsigned int lcd_clock; /* KHz */
static unsigned long uart_baud_base;
static DEFINE_SPINLOCK(time_lock);
/*
* Set the au1000_clock
*/
@ -63,31 +72,45 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base)
}
/*
* Calculate the Au1x00's LCD clock based on the current
* cpu clock and the system bus clock, and try to keep it
* below 40 MHz (the Pb1000 board can lock-up if the LCD
* clock is over 40 MHz).
* We read the real processor speed from the PLL. This is important
* because it is more accurate than computing it from the 32 KHz
* counter, if it exists. If we don't have an accurate processor
* speed, all of the peripherals that derive their clocks based on
* this advertised speed will introduce error and sometimes not work
* properly. This function is futher convoluted to still allow configurations
* to do that in case they have really, really old silicon with a
* write-only PLL register. -- Dan
*/
void set_au1x00_lcd_clock(void)
unsigned long au1xxx_calc_clock(void)
{
unsigned int static_cfg0;
unsigned int sys_busclk = (get_au1x00_speed() / 1000) /
((int)(au_readl(SYS_POWERCTRL) & 0x03) + 2);
unsigned long cpu_speed;
unsigned long flags;
static_cfg0 = au_readl(MEM_STCFG0);
spin_lock_irqsave(&time_lock, flags);
if (static_cfg0 & (1 << 11))
lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
/*
* On early Au1000, sys_cpupll was write-only. Since these
* silicon versions of Au1000 are not sold by AMD, we don't bend
* over backwards trying to determine the frequency.
*/
if (au1xxx_cpu_has_pll_wo())
#ifdef CONFIG_SOC_AU1000_FREQUENCY
cpu_speed = CONFIG_SOC_AU1000_FREQUENCY;
#else
cpu_speed = 396000000;
#endif
else
lcd_clock = sys_busclk / 4;
cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
if (lcd_clock > 50000) /* Epson MAX */
printk(KERN_WARNING "warning: LCD clock too high (%u KHz)\n",
lcd_clock);
}
/* On Alchemy CPU:counter ratio is 1:1 */
mips_hpt_frequency = cpu_speed;
/* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
& 0x03) + 2) * 16));
unsigned int get_au1x00_lcd_clock(void)
{
return lcd_clock;
spin_unlock_irqrestore(&time_lock, flags);
set_au1x00_speed(cpu_speed);
return cpu_speed;
}
EXPORT_SYMBOL(get_au1x00_lcd_clock);

View file

@ -1,52 +0,0 @@
/*
* arch/mips/au1000/common/cputable.c
*
* Copyright (C) 2004 Dan Malek (dan@embeddededge.com)
* Copied from PowerPC and updated for Alchemy Au1xxx processors.
*
* Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
*
* 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.
*/
#include <asm/mach-au1x00/au1000.h>
struct cpu_spec *cur_cpu_spec[NR_CPUS];
/* With some thought, we can probably use the mask to reduce the
* size of the table.
*/
struct cpu_spec cpu_specs[] = {
{ 0xffffffff, 0x00030100, "Au1000 DA", 1, 0, 1 },
{ 0xffffffff, 0x00030201, "Au1000 HA", 1, 0, 1 },
{ 0xffffffff, 0x00030202, "Au1000 HB", 1, 0, 1 },
{ 0xffffffff, 0x00030203, "Au1000 HC", 1, 1, 0 },
{ 0xffffffff, 0x00030204, "Au1000 HD", 1, 1, 0 },
{ 0xffffffff, 0x01030200, "Au1500 AB", 1, 1, 0 },
{ 0xffffffff, 0x01030201, "Au1500 AC", 0, 1, 0 },
{ 0xffffffff, 0x01030202, "Au1500 AD", 0, 1, 0 },
{ 0xffffffff, 0x02030200, "Au1100 AB", 1, 1, 0 },
{ 0xffffffff, 0x02030201, "Au1100 BA", 1, 1, 0 },
{ 0xffffffff, 0x02030202, "Au1100 BC", 1, 1, 0 },
{ 0xffffffff, 0x02030203, "Au1100 BD", 0, 1, 0 },
{ 0xffffffff, 0x02030204, "Au1100 BE", 0, 1, 0 },
{ 0xffffffff, 0x03030200, "Au1550 AA", 0, 1, 0 },
{ 0xffffffff, 0x04030200, "Au1200 AB", 0, 0, 0 },
{ 0xffffffff, 0x04030201, "Au1200 AC", 1, 0, 0 },
{ 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 }
};
void set_cpuspec(void)
{
struct cpu_spec *sp;
u32 prid;
prid = read_c0_prid();
sp = cpu_specs;
while ((prid & sp->prid_mask) != sp->prid_value)
sp++;
cur_cpu_spec[0] = sp;
}

View file

@ -174,6 +174,11 @@ static dbdev_tab_t dbdev_tab[] = {
#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab)
#ifdef CONFIG_PM
static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][8];
#endif
static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
static dbdev_tab_t *find_dbdev_id(u32 id)
@ -975,4 +980,64 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
return nbytes;
}
#ifdef CONFIG_PM
void au1xxx_dbdma_suspend(void)
{
int i;
u32 addr;
addr = DDMA_GLOBAL_BASE;
au1xxx_dbdma_pm_regs[0][0] = au_readl(addr + 0x00);
au1xxx_dbdma_pm_regs[0][1] = au_readl(addr + 0x04);
au1xxx_dbdma_pm_regs[0][2] = au_readl(addr + 0x08);
au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c);
/* save channel configurations */
for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) {
au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00);
au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04);
au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08);
au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c);
au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10);
au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14);
au1xxx_dbdma_pm_regs[i][6] = au_readl(addr + 0x18);
/* halt channel */
au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00);
au_sync();
while (!(au_readl(addr + 0x14) & 1))
au_sync();
addr += 0x100; /* next channel base */
}
/* disable channel interrupts */
au_writel(0, DDMA_GLOBAL_BASE + 0x0c);
au_sync();
}
void au1xxx_dbdma_resume(void)
{
int i;
u32 addr;
addr = DDMA_GLOBAL_BASE;
au_writel(au1xxx_dbdma_pm_regs[0][0], addr + 0x00);
au_writel(au1xxx_dbdma_pm_regs[0][1], addr + 0x04);
au_writel(au1xxx_dbdma_pm_regs[0][2], addr + 0x08);
au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c);
/* restore channel configurations */
for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) {
au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00);
au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04);
au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08);
au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c);
au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10);
au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14);
au_writel(au1xxx_dbdma_pm_regs[i][6], addr + 0x18);
au_sync();
addr += 0x100; /* next channel base */
}
}
#endif /* CONFIG_PM */
#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */

View file

@ -24,6 +24,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@ -36,15 +37,172 @@
#include <asm/mach-pb1x00/pb1000.h>
#endif
#define EXT_INTC0_REQ0 2 /* IP 2 */
#define EXT_INTC0_REQ1 3 /* IP 3 */
#define EXT_INTC1_REQ0 4 /* IP 4 */
#define EXT_INTC1_REQ1 5 /* IP 5 */
#define MIPS_TIMER_IP 7 /* IP 7 */
static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
void (*board_init_irq)(void) __initdata = NULL;
/* per-processor fixed function irqs */
struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = {
#if defined(CONFIG_SOC_AU1000)
{ AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
#elif defined(CONFIG_SOC_AU1500)
{ AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1000_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1000_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
#elif defined(CONFIG_SOC_AU1100)
{ AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
#elif defined(CONFIG_SOC_AU1550)
{ AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
{ AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
#elif defined(CONFIG_SOC_AU1200)
{ AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
{ AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
{ AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
{ AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
#else
#error "Error: Unknown Alchemy SOC"
#endif
};
static DEFINE_SPINLOCK(irq_lock);
#ifdef CONFIG_PM
@ -130,67 +288,47 @@ void restore_au1xxx_intctl(void)
#endif /* CONFIG_PM */
inline void local_enable_irq(unsigned int irq_nr)
static void au1x_ic0_unmask(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
if (bit >= 32) {
au_writel(1 << (bit - 32), IC1_MASKSET);
au_writel(1 << (bit - 32), IC1_WAKESET);
} else {
au_writel(1 << bit, IC0_MASKSET);
au_writel(1 << bit, IC0_WAKESET);
}
au_writel(1 << bit, IC0_MASKSET);
au_writel(1 << bit, IC0_WAKESET);
au_sync();
}
inline void local_disable_irq(unsigned int irq_nr)
static void au1x_ic1_unmask(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_MASKSET);
au_writel(1 << bit, IC1_WAKESET);
if (bit >= 32) {
au_writel(1 << (bit - 32), IC1_MASKCLR);
au_writel(1 << (bit - 32), IC1_WAKECLR);
} else {
au_writel(1 << bit, IC0_MASKCLR);
au_writel(1 << bit, IC0_WAKECLR);
}
/* very hacky. does the pb1000 cpld auto-disable this int?
* nowhere in the current kernel sources is it disabled. --mlau
*/
#if defined(CONFIG_MIPS_PB1000)
if (irq_nr == AU1000_GPIO_15)
au_writel(0x4000, PB1000_MDR); /* enable int */
#endif
au_sync();
}
static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
static void au1x_ic0_mask(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
if (bit >= 32) {
au_writel(1 << (bit - 32), IC1_RISINGCLR);
au_writel(1 << (bit - 32), IC1_MASKCLR);
} else {
au_writel(1 << bit, IC0_RISINGCLR);
au_writel(1 << bit, IC0_MASKCLR);
}
au_writel(1 << bit, IC0_MASKCLR);
au_writel(1 << bit, IC0_WAKECLR);
au_sync();
}
static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
static void au1x_ic1_mask(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
if (bit >= 32) {
au_writel(1 << (bit - 32), IC1_FALLINGCLR);
au_writel(1 << (bit - 32), IC1_MASKCLR);
} else {
au_writel(1 << bit, IC0_FALLINGCLR);
au_writel(1 << bit, IC0_MASKCLR);
}
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
au_writel(1 << bit, IC1_MASKCLR);
au_writel(1 << bit, IC1_WAKECLR);
au_sync();
}
static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
static void au1x_ic0_ack(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
@ -198,349 +336,229 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
* This may assume that we don't get interrupts from
* both edges at once, or if we do, that we don't care.
*/
if (bit >= 32) {
au_writel(1 << (bit - 32), IC1_FALLINGCLR);
au_writel(1 << (bit - 32), IC1_RISINGCLR);
au_writel(1 << (bit - 32), IC1_MASKCLR);
} else {
au_writel(1 << bit, IC0_FALLINGCLR);
au_writel(1 << bit, IC0_RISINGCLR);
au_writel(1 << bit, IC0_MASKCLR);
}
au_writel(1 << bit, IC0_FALLINGCLR);
au_writel(1 << bit, IC0_RISINGCLR);
au_sync();
}
static inline void mask_and_ack_level_irq(unsigned int irq_nr)
static void au1x_ic1_ack(unsigned int irq_nr)
{
local_disable_irq(irq_nr);
unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
/*
* This may assume that we don't get interrupts from
* both edges at once, or if we do, that we don't care.
*/
au_writel(1 << bit, IC1_FALLINGCLR);
au_writel(1 << bit, IC1_RISINGCLR);
au_sync();
#if defined(CONFIG_MIPS_PB1000)
if (irq_nr == AU1000_GPIO_15) {
au_writel(0x8000, PB1000_MDR); /* ack int */
au_sync();
}
#endif
}
static void end_irq(unsigned int irq_nr)
static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
{
if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
local_enable_irq(irq_nr);
unsigned int bit = irq - AU1000_INTC1_INT_BASE;
unsigned long wakemsk, flags;
#if defined(CONFIG_MIPS_PB1000)
if (irq_nr == AU1000_GPIO_15) {
au_writel(0x4000, PB1000_MDR); /* enable int */
au_sync();
}
#endif
}
/* only GPIO 0-7 can act as wakeup source: */
if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7))
return -EINVAL;
unsigned long save_local_and_disable(int controller)
{
int i;
unsigned long flags, mask;
spin_lock_irqsave(&irq_lock, flags);
if (controller) {
mask = au_readl(IC1_MASKSET);
for (i = 32; i < 64; i++)
local_disable_irq(i);
} else {
mask = au_readl(IC0_MASKSET);
for (i = 0; i < 32; i++)
local_disable_irq(i);
}
spin_unlock_irqrestore(&irq_lock, flags);
return mask;
}
void restore_local_and_enable(int controller, unsigned long mask)
{
int i;
unsigned long flags, new_mask;
spin_lock_irqsave(&irq_lock, flags);
for (i = 0; i < 32; i++)
if (mask & (1 << i)) {
if (controller)
local_enable_irq(i + 32);
else
local_enable_irq(i);
}
if (controller)
new_mask = au_readl(IC1_MASKSET);
local_irq_save(flags);
wakemsk = au_readl(SYS_WAKEMSK);
if (on)
wakemsk |= 1 << bit;
else
new_mask = au_readl(IC0_MASKSET);
spin_unlock_irqrestore(&irq_lock, flags);
}
static struct irq_chip rise_edge_irq_type = {
.name = "Au1000 Rise Edge",
.ack = mask_and_ack_rise_edge_irq,
.mask = local_disable_irq,
.mask_ack = mask_and_ack_rise_edge_irq,
.unmask = local_enable_irq,
.end = end_irq,
};
static struct irq_chip fall_edge_irq_type = {
.name = "Au1000 Fall Edge",
.ack = mask_and_ack_fall_edge_irq,
.mask = local_disable_irq,
.mask_ack = mask_and_ack_fall_edge_irq,
.unmask = local_enable_irq,
.end = end_irq,
};
static struct irq_chip either_edge_irq_type = {
.name = "Au1000 Rise or Fall Edge",
.ack = mask_and_ack_either_edge_irq,
.mask = local_disable_irq,
.mask_ack = mask_and_ack_either_edge_irq,
.unmask = local_enable_irq,
.end = end_irq,
};
static struct irq_chip level_irq_type = {
.name = "Au1000 Level",
.ack = mask_and_ack_level_irq,
.mask = local_disable_irq,
.mask_ack = mask_and_ack_level_irq,
.unmask = local_enable_irq,
.end = end_irq,
};
static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
if (irq_nr > AU1000_MAX_INTR)
return;
/* Config2[n], Config1[n], Config0[n] */
if (bit >= 32) {
switch (type) {
case INTC_INT_RISE_EDGE: /* 0:0:1 */
au_writel(1 << (bit - 32), IC1_CFG2CLR);
au_writel(1 << (bit - 32), IC1_CFG1CLR);
au_writel(1 << (bit - 32), IC1_CFG0SET);
set_irq_chip(irq_nr, &rise_edge_irq_type);
break;
case INTC_INT_FALL_EDGE: /* 0:1:0 */
au_writel(1 << (bit - 32), IC1_CFG2CLR);
au_writel(1 << (bit - 32), IC1_CFG1SET);
au_writel(1 << (bit - 32), IC1_CFG0CLR);
set_irq_chip(irq_nr, &fall_edge_irq_type);
break;
case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
au_writel(1 << (bit - 32), IC1_CFG2CLR);
au_writel(1 << (bit - 32), IC1_CFG1SET);
au_writel(1 << (bit - 32), IC1_CFG0SET);
set_irq_chip(irq_nr, &either_edge_irq_type);
break;
case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
au_writel(1 << (bit - 32), IC1_CFG2SET);
au_writel(1 << (bit - 32), IC1_CFG1CLR);
au_writel(1 << (bit - 32), IC1_CFG0SET);
set_irq_chip(irq_nr, &level_irq_type);
break;
case INTC_INT_LOW_LEVEL: /* 1:1:0 */
au_writel(1 << (bit - 32), IC1_CFG2SET);
au_writel(1 << (bit - 32), IC1_CFG1SET);
au_writel(1 << (bit - 32), IC1_CFG0CLR);
set_irq_chip(irq_nr, &level_irq_type);
break;
case INTC_INT_DISABLED: /* 0:0:0 */
au_writel(1 << (bit - 32), IC1_CFG0CLR);
au_writel(1 << (bit - 32), IC1_CFG1CLR);
au_writel(1 << (bit - 32), IC1_CFG2CLR);
break;
default: /* disable the interrupt */
printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
type, irq_nr);
au_writel(1 << (bit - 32), IC1_CFG0CLR);
au_writel(1 << (bit - 32), IC1_CFG1CLR);
au_writel(1 << (bit - 32), IC1_CFG2CLR);
return;
}
if (int_req) /* assign to interrupt request 1 */
au_writel(1 << (bit - 32), IC1_ASSIGNCLR);
else /* assign to interrupt request 0 */
au_writel(1 << (bit - 32), IC1_ASSIGNSET);
au_writel(1 << (bit - 32), IC1_SRCSET);
au_writel(1 << (bit - 32), IC1_MASKCLR);
au_writel(1 << (bit - 32), IC1_WAKECLR);
} else {
switch (type) {
case INTC_INT_RISE_EDGE: /* 0:0:1 */
au_writel(1 << bit, IC0_CFG2CLR);
au_writel(1 << bit, IC0_CFG1CLR);
au_writel(1 << bit, IC0_CFG0SET);
set_irq_chip(irq_nr, &rise_edge_irq_type);
break;
case INTC_INT_FALL_EDGE: /* 0:1:0 */
au_writel(1 << bit, IC0_CFG2CLR);
au_writel(1 << bit, IC0_CFG1SET);
au_writel(1 << bit, IC0_CFG0CLR);
set_irq_chip(irq_nr, &fall_edge_irq_type);
break;
case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
au_writel(1 << bit, IC0_CFG2CLR);
au_writel(1 << bit, IC0_CFG1SET);
au_writel(1 << bit, IC0_CFG0SET);
set_irq_chip(irq_nr, &either_edge_irq_type);
break;
case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
au_writel(1 << bit, IC0_CFG2SET);
au_writel(1 << bit, IC0_CFG1CLR);
au_writel(1 << bit, IC0_CFG0SET);
set_irq_chip(irq_nr, &level_irq_type);
break;
case INTC_INT_LOW_LEVEL: /* 1:1:0 */
au_writel(1 << bit, IC0_CFG2SET);
au_writel(1 << bit, IC0_CFG1SET);
au_writel(1 << bit, IC0_CFG0CLR);
set_irq_chip(irq_nr, &level_irq_type);
break;
case INTC_INT_DISABLED: /* 0:0:0 */
au_writel(1 << bit, IC0_CFG0CLR);
au_writel(1 << bit, IC0_CFG1CLR);
au_writel(1 << bit, IC0_CFG2CLR);
break;
default: /* disable the interrupt */
printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
type, irq_nr);
au_writel(1 << bit, IC0_CFG0CLR);
au_writel(1 << bit, IC0_CFG1CLR);
au_writel(1 << bit, IC0_CFG2CLR);
return;
}
if (int_req) /* assign to interrupt request 1 */
au_writel(1 << bit, IC0_ASSIGNCLR);
else /* assign to interrupt request 0 */
au_writel(1 << bit, IC0_ASSIGNSET);
au_writel(1 << bit, IC0_SRCSET);
au_writel(1 << bit, IC0_MASKCLR);
au_writel(1 << bit, IC0_WAKECLR);
}
wakemsk &= ~(1 << bit);
au_writel(wakemsk, SYS_WAKEMSK);
au_sync();
local_irq_restore(flags);
return 0;
}
/*
* Interrupts are nested. Even if an interrupt handler is registered
* as "fast", we might get another interrupt before we return from
* intcX_reqX_irqdispatch().
* irq_chips for both ICs; this way the mask handlers can be
* as short as possible.
*
* NOTE: the ->ack() callback is used by the handle_edge_irq
* flowhandler only, the ->mask_ack() one by handle_level_irq,
* so no need for an irq_chip for each type of irq (level/edge).
*/
static struct irq_chip au1x_ic0_chip = {
.name = "Alchemy-IC0",
.ack = au1x_ic0_ack, /* edge */
.mask = au1x_ic0_mask,
.mask_ack = au1x_ic0_mask, /* level */
.unmask = au1x_ic0_unmask,
.set_type = au1x_ic_settype,
};
static void intc0_req0_irqdispatch(void)
static struct irq_chip au1x_ic1_chip = {
.name = "Alchemy-IC1",
.ack = au1x_ic1_ack, /* edge */
.mask = au1x_ic1_mask,
.mask_ack = au1x_ic1_mask, /* level */
.unmask = au1x_ic1_unmask,
.set_type = au1x_ic_settype,
.set_wake = au1x_ic1_setwake,
};
static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
{
static unsigned long intc0_req0;
unsigned int bit;
struct irq_chip *chip;
unsigned long icr[6];
unsigned int bit, ic;
int ret;
intc0_req0 |= au_readl(IC0_REQ0INT);
if (irq >= AU1000_INTC1_INT_BASE) {
bit = irq - AU1000_INTC1_INT_BASE;
chip = &au1x_ic1_chip;
ic = 1;
} else {
bit = irq - AU1000_INTC0_INT_BASE;
chip = &au1x_ic0_chip;
ic = 0;
}
if (!intc0_req0)
if (bit > 31)
return -EINVAL;
icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET;
icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET;
icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET;
icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR;
icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR;
icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR;
ret = 0;
switch (flow_type) { /* cfgregs 2:1:0 */
case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[0]);
set_irq_chip_and_handler_name(irq, chip,
handle_edge_irq, "riseedge");
break;
case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[3]);
set_irq_chip_and_handler_name(irq, chip,
handle_edge_irq, "falledge");
break;
case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[0]);
set_irq_chip_and_handler_name(irq, chip,
handle_edge_irq, "bothedge");
break;
case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */
au_writel(1 << bit, icr[2]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[0]);
set_irq_chip_and_handler_name(irq, chip,
handle_level_irq, "hilevel");
break;
case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */
au_writel(1 << bit, icr[2]);
au_writel(1 << bit, icr[1]);
au_writel(1 << bit, icr[3]);
set_irq_chip_and_handler_name(irq, chip,
handle_level_irq, "lowlevel");
break;
case IRQ_TYPE_NONE: /* 0:0:0 */
au_writel(1 << bit, icr[5]);
au_writel(1 << bit, icr[4]);
au_writel(1 << bit, icr[3]);
/* set at least chip so we can call set_irq_type() on it */
set_irq_chip(irq, chip);
break;
default:
ret = -EINVAL;
}
au_sync();
return ret;
}
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending = read_c0_status() & read_c0_cause();
unsigned long s, off, bit;
if (pending & CAUSEF_IP7) {
do_IRQ(MIPS_CPU_IRQ_BASE + 7);
return;
} else if (pending & CAUSEF_IP2) {
s = IC0_REQ0INT;
off = AU1000_INTC0_INT_BASE;
} else if (pending & CAUSEF_IP3) {
s = IC0_REQ1INT;
off = AU1000_INTC0_INT_BASE;
} else if (pending & CAUSEF_IP4) {
s = IC1_REQ0INT;
off = AU1000_INTC1_INT_BASE;
} else if (pending & CAUSEF_IP5) {
s = IC1_REQ1INT;
off = AU1000_INTC1_INT_BASE;
} else
goto spurious;
bit = 0;
s = au_readl(s);
if (unlikely(!s)) {
spurious:
spurious_interrupt();
return;
}
#ifdef AU1000_USB_DEV_REQ_INT
/*
* Because of the tight timing of SETUP token to reply
* transactions, the USB devices-side packet complete
* interrupt needs the highest priority.
*/
if ((intc0_req0 & (1 << AU1000_USB_DEV_REQ_INT))) {
intc0_req0 &= ~(1 << AU1000_USB_DEV_REQ_INT);
bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE);
if ((pending & CAUSEF_IP2) && (s & bit)) {
do_IRQ(AU1000_USB_DEV_REQ_INT);
return;
}
#endif
bit = __ffs(intc0_req0);
intc0_req0 &= ~(1 << bit);
do_IRQ(AU1000_INTC0_INT_BASE + bit);
do_IRQ(__ffs(s) + off);
}
static void intc0_req1_irqdispatch(void)
/* setup edge/level and assign request 0/1 */
void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count)
{
static unsigned long intc0_req1;
unsigned int bit;
unsigned int bit, irq_nr;
intc0_req1 |= au_readl(IC0_REQ1INT);
while (count--) {
irq_nr = map[count].im_irq;
if (!intc0_req1)
return;
if (((irq_nr < AU1000_INTC0_INT_BASE) ||
(irq_nr >= AU1000_INTC0_INT_BASE + 32)) &&
((irq_nr < AU1000_INTC1_INT_BASE) ||
(irq_nr >= AU1000_INTC1_INT_BASE + 32)))
continue;
bit = __ffs(intc0_req1);
intc0_req1 &= ~(1 << bit);
do_IRQ(AU1000_INTC0_INT_BASE + bit);
}
if (irq_nr >= AU1000_INTC1_INT_BASE) {
bit = irq_nr - AU1000_INTC1_INT_BASE;
if (map[count].im_request)
au_writel(1 << bit, IC1_ASSIGNCLR);
} else {
bit = irq_nr - AU1000_INTC0_INT_BASE;
if (map[count].im_request)
au_writel(1 << bit, IC0_ASSIGNCLR);
}
/*
* Interrupt Controller 1:
* interrupts 32 - 63
*/
static void intc1_req0_irqdispatch(void)
{
static unsigned long intc1_req0;
unsigned int bit;
intc1_req0 |= au_readl(IC1_REQ0INT);
if (!intc1_req0)
return;
bit = __ffs(intc1_req0);
intc1_req0 &= ~(1 << bit);
do_IRQ(AU1000_INTC1_INT_BASE + bit);
}
static void intc1_req1_irqdispatch(void)
{
static unsigned long intc1_req1;
unsigned int bit;
intc1_req1 |= au_readl(IC1_REQ1INT);
if (!intc1_req1)
return;
bit = __ffs(intc1_req1);
intc1_req1 &= ~(1 << bit);
do_IRQ(AU1000_INTC1_INT_BASE + bit);
}
asmlinkage void plat_irq_dispatch(void)
{
unsigned int pending = read_c0_status() & read_c0_cause();
if (pending & CAUSEF_IP7)
do_IRQ(MIPS_CPU_IRQ_BASE + 7);
else if (pending & CAUSEF_IP2)
intc0_req0_irqdispatch();
else if (pending & CAUSEF_IP3)
intc0_req1_irqdispatch();
else if (pending & CAUSEF_IP4)
intc1_req0_irqdispatch();
else if (pending & CAUSEF_IP5)
intc1_req1_irqdispatch();
else
spurious_interrupt();
au1x_ic_settype(irq_nr, map[count].im_type);
}
}
void __init arch_init_irq(void)
{
int i;
struct au1xxx_irqmap *imp;
extern struct au1xxx_irqmap au1xxx_irq_map[];
extern struct au1xxx_irqmap au1xxx_ic0_map[];
extern int au1xxx_nr_irqs;
extern int au1xxx_ic0_nr_irqs;
/*
* Initialize interrupt controllers to a safe state.
@ -569,28 +587,25 @@ void __init arch_init_irq(void)
mips_cpu_irq_init();
/* register all 64 possible IC0+IC1 irq sources as type "none".
* Use set_irq_type() to set edge/level behaviour at runtime.
*/
for (i = AU1000_INTC0_INT_BASE;
(i < AU1000_INTC0_INT_BASE + 32); i++)
au1x_ic_settype(i, IRQ_TYPE_NONE);
for (i = AU1000_INTC1_INT_BASE;
(i < AU1000_INTC1_INT_BASE + 32); i++)
au1x_ic_settype(i, IRQ_TYPE_NONE);
/*
* Initialize IC0, which is fixed per processor.
*/
imp = au1xxx_ic0_map;
for (i = 0; i < au1xxx_ic0_nr_irqs; i++) {
setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
imp++;
}
au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map));
/*
* Now set up the irq mapping for the board.
*/
imp = au1xxx_irq_map;
for (i = 0; i < au1xxx_nr_irqs; i++) {
setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
imp++;
}
set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
/* Board specific IRQ initialization.
/* Boards can register additional (GPIO-based) IRQs.
*/
if (board_init_irq)
board_init_irq();
board_init_irq();
set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
}

View file

@ -35,25 +35,12 @@
#include <linux/jiffies.h>
#include <asm/uaccess.h>
#include <asm/cacheflush.h>
#include <asm/mach-au1x00/au1000.h>
#ifdef CONFIG_PM
#define DEBUG 1
#ifdef DEBUG
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__, ## args)
#else
#define DPRINTK(fmt, args...)
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
#include <asm/mach-au1x00/au1xxx_dbdma.h>
#endif
static void au1000_calibrate_delay(void);
extern unsigned long save_local_and_disable(int controller);
extern void restore_local_and_enable(int controller, unsigned long mask);
extern void local_enable_irq(unsigned int irq_nr);
static DEFINE_SPINLOCK(pm_lock);
#ifdef CONFIG_PM
/*
* We need to save/restore a bunch of core registers that are
@ -65,29 +52,16 @@ static DEFINE_SPINLOCK(pm_lock);
* We only have to save/restore registers that aren't otherwise
* done as part of a driver pm_* function.
*/
static unsigned int sleep_aux_pll_cntrl;
static unsigned int sleep_cpu_pll_cntrl;
static unsigned int sleep_pin_function;
static unsigned int sleep_uart0_inten;
static unsigned int sleep_uart0_fifoctl;
static unsigned int sleep_uart0_linectl;
static unsigned int sleep_uart0_clkdiv;
static unsigned int sleep_uart0_enable;
static unsigned int sleep_usbhost_enable;
static unsigned int sleep_usbdev_enable;
static unsigned int sleep_static_memctlr[4][3];
static unsigned int sleep_uart0_inten;
static unsigned int sleep_uart0_fifoctl;
static unsigned int sleep_uart0_linectl;
static unsigned int sleep_uart0_clkdiv;
static unsigned int sleep_uart0_enable;
static unsigned int sleep_usb[2];
static unsigned int sleep_sys_clocks[5];
static unsigned int sleep_sys_pinfunc;
static unsigned int sleep_static_memctlr[4][3];
/*
* Define this to cause the value you write to /proc/sys/pm/sleep to
* set the TOY timer for the amount of time you want to sleep.
* This is done mainly for testing, but may be useful in other cases.
* The value is number of 32KHz ticks to sleep.
*/
#define SLEEP_TEST_TIMEOUT 1
#ifdef SLEEP_TEST_TIMEOUT
static int sleep_ticks;
void wakeup_counter0_set(int ticks);
#endif
static void save_core_regs(void)
{
@ -105,31 +79,45 @@ static void save_core_regs(void)
sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
au_sync();
#ifndef CONFIG_SOC_AU1200
/* Shutdown USB host/device. */
sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
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();
au_writel(0, 0xb0100004);
au_sync();
au_writel(0, USB_HOST_CONFIG);
au_sync();
sleep_usbdev_enable = au_readl(USBD_ENABLE);
au_writel(0, USBD_ENABLE); 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
/* Save interrupt controller state. */
save_au1xxx_intctl();
/* Clocks and PLLs. */
sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);
sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0);
sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1);
sleep_sys_clocks[2] = au_readl(SYS_CLKSRC);
sleep_sys_clocks[3] = au_readl(SYS_CPUPLL);
sleep_sys_clocks[4] = au_readl(SYS_AUXPLL);
/*
* We don't really need to do this one, but unless we
* write it again it won't have a valid value if we
* happen to read it.
*/
sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL);
sleep_pin_function = au_readl(SYS_PINFUNC);
/* pin mux config */
sleep_sys_pinfunc = au_readl(SYS_PINFUNC);
/* Save the static memory controller configuration. */
sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
@ -144,16 +132,45 @@ static void save_core_regs(void)
sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
au1xxx_dbdma_suspend();
#endif
}
static void restore_core_regs(void)
{
extern void restore_au1xxx_intctl(void);
extern void wakeup_counter0_adjust(void);
/* restore clock configuration. Writing CPUPLL last will
* stall a bit and stabilize other clocks (unless this is
* one of those Au1000 with a write-only PLL, where we dont
* have a valid value)
*/
au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0);
au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1);
au_writel(sleep_sys_clocks[2], SYS_CLKSRC);
au_writel(sleep_sys_clocks[4], SYS_AUXPLL);
if (!au1xxx_cpu_has_pll_wo())
au_writel(sleep_sys_clocks[3], SYS_CPUPLL);
au_sync();
au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync();
au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync();
au_writel(sleep_pin_function, SYS_PINFUNC); au_sync();
au_writel(sleep_sys_pinfunc, SYS_PINFUNC);
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 accces 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. */
au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
@ -184,282 +201,17 @@ static void restore_core_regs(void)
}
restore_au1xxx_intctl();
wakeup_counter0_adjust();
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
au1xxx_dbdma_resume();
#endif
}
unsigned long suspend_mode;
void wakeup_from_suspend(void)
void au_sleep(void)
{
suspend_mode = 0;
}
int au_sleep(void)
{
unsigned long wakeup, flags;
extern void save_and_sleep(void);
spin_lock_irqsave(&pm_lock, flags);
save_core_regs();
flush_cache_all();
/**
** The code below is all system dependent and we should probably
** have a function call out of here to set this up. You need
** to configure the GPIO or timer interrupts that will bring
** you out of sleep.
** For testing, the TOY counter wakeup is useful.
**/
#if 0
au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
/* GPIO 6 can cause a wake up event */
wakeup = au_readl(SYS_WAKEMSK);
wakeup &= ~(1 << 8); /* turn off match20 wakeup */
wakeup |= 1 << 6; /* turn on GPIO 6 wakeup */
#else
/* For testing, allow match20 to wake us up. */
#ifdef SLEEP_TEST_TIMEOUT
wakeup_counter0_set(sleep_ticks);
#endif
wakeup = 1 << 8; /* turn on match20 wakeup */
wakeup = 0;
#endif
au_writel(1, SYS_WAKESRC); /* clear cause */
au_sync();
au_writel(wakeup, SYS_WAKEMSK);
au_sync();
save_and_sleep();
/*
* After a wakeup, the cpu vectors back to 0x1fc00000, so
* it's up to the boot code to get us back here.
*/
au1xxx_save_and_sleep();
restore_core_regs();
spin_unlock_irqrestore(&pm_lock, flags);
return 0;
}
static int pm_do_sleep(ctl_table *ctl, int write, struct file *file,
void __user *buffer, size_t *len, loff_t *ppos)
{
#ifdef SLEEP_TEST_TIMEOUT
#define TMPBUFLEN2 16
char buf[TMPBUFLEN2], *p;
#endif
if (!write)
*len = 0;
else {
#ifdef SLEEP_TEST_TIMEOUT
if (*len > TMPBUFLEN2 - 1)
return -EFAULT;
if (copy_from_user(buf, buffer, *len))
return -EFAULT;
buf[*len] = 0;
p = buf;
sleep_ticks = simple_strtoul(p, &p, 0);
#endif
au_sleep();
}
return 0;
}
static int pm_do_freq(ctl_table *ctl, int write, struct file *file,
void __user *buffer, size_t *len, loff_t *ppos)
{
int retval = 0, i;
unsigned long val, pll;
#define TMPBUFLEN 64
#define MAX_CPU_FREQ 396
char buf[TMPBUFLEN], *p;
unsigned long flags, intc0_mask, intc1_mask;
unsigned long old_baud_base, old_cpu_freq, old_clk, old_refresh;
unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
unsigned long baud_rate;
spin_lock_irqsave(&pm_lock, flags);
if (!write)
*len = 0;
else {
/* Parse the new frequency */
if (*len > TMPBUFLEN - 1) {
spin_unlock_irqrestore(&pm_lock, flags);
return -EFAULT;
}
if (copy_from_user(buf, buffer, *len)) {
spin_unlock_irqrestore(&pm_lock, flags);
return -EFAULT;
}
buf[*len] = 0;
p = buf;
val = simple_strtoul(p, &p, 0);
if (val > MAX_CPU_FREQ) {
spin_unlock_irqrestore(&pm_lock, flags);
return -EFAULT;
}
pll = val / 12;
if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */
/* Revisit this for higher speed CPUs */
spin_unlock_irqrestore(&pm_lock, flags);
return -EFAULT;
}
old_baud_base = get_au1x00_uart_baud_base();
old_cpu_freq = get_au1x00_speed();
new_cpu_freq = pll * 12 * 1000000;
new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)
& 0x03) + 2) * 16));
set_au1x00_speed(new_cpu_freq);
set_au1x00_uart_baud_base(new_baud_base);
old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
new_refresh = ((old_refresh * new_cpu_freq) / old_cpu_freq) |
(au_readl(MEM_SDREFCFG) & ~0x1ffffff);
au_writel(pll, SYS_CPUPLL);
au_sync_delay(1);
au_writel(new_refresh, MEM_SDREFCFG);
au_sync_delay(1);
for (i = 0; i < 4; i++)
if (au_readl(UART_BASE + UART_MOD_CNTRL +
i * 0x00100000) == 3) {
old_clk = au_readl(UART_BASE + UART_CLK +
i * 0x00100000);
baud_rate = old_baud_base / old_clk;
/*
* We won't get an exact baud rate and the error
* could be significant enough that our new
* calculation will result in a clock that will
* give us a baud rate that's too far off from
* what we really want.
*/
if (baud_rate > 100000)
baud_rate = 115200;
else if (baud_rate > 50000)
baud_rate = 57600;
else if (baud_rate > 30000)
baud_rate = 38400;
else if (baud_rate > 17000)
baud_rate = 19200;
else
baud_rate = 9600;
new_clk = new_baud_base / baud_rate;
au_writel(new_clk, UART_BASE + UART_CLK +
i * 0x00100000);
au_sync_delay(10);
}
}
/*
* We don't want _any_ interrupts other than match20. Otherwise our
* au1000_calibrate_delay() calculation will be off, potentially a lot.
*/
intc0_mask = save_local_and_disable(0);
intc1_mask = save_local_and_disable(1);
local_enable_irq(AU1000_TOY_MATCH2_INT);
spin_unlock_irqrestore(&pm_lock, flags);
au1000_calibrate_delay();
restore_local_and_enable(0, intc0_mask);
restore_local_and_enable(1, intc1_mask);
return retval;
}
static struct ctl_table pm_table[] = {
{
.ctl_name = CTL_UNNUMBERED,
.procname = "sleep",
.data = NULL,
.maxlen = 0,
.mode = 0600,
.proc_handler = &pm_do_sleep
},
{
.ctl_name = CTL_UNNUMBERED,
.procname = "freq",
.data = NULL,
.maxlen = 0,
.mode = 0600,
.proc_handler = &pm_do_freq
},
{}
};
static struct ctl_table pm_dir_table[] = {
{
.ctl_name = CTL_UNNUMBERED,
.procname = "pm",
.mode = 0555,
.child = pm_table
},
{}
};
/*
* Initialize power interface
*/
static int __init pm_init(void)
{
register_sysctl_table(pm_dir_table);
return 0;
}
__initcall(pm_init);
/*
* This is right out of init/main.c
*/
/*
* This is the number of bits of precision for the loops_per_jiffy.
* Each bit takes on average 1.5/HZ seconds. This (like the original)
* is a little better than 1%.
*/
#define LPS_PREC 8
static void au1000_calibrate_delay(void)
{
unsigned long ticks, loopbit;
int lps_precision = LPS_PREC;
loops_per_jiffy = 1 << 12;
while (loops_per_jiffy <<= 1) {
/* Wait for "start of" clock tick */
ticks = jiffies;
while (ticks == jiffies)
/* nothing */ ;
/* Go ... */
ticks = jiffies;
__delay(loops_per_jiffy);
ticks = jiffies - ticks;
if (ticks)
break;
}
/*
* Do a binary approximation to get loops_per_jiffy set to be equal
* one clock (up to lps_precision bits)
*/
loops_per_jiffy >>= 1;
loopbit = loops_per_jiffy;
while (lps_precision-- && (loopbit >>= 1)) {
loops_per_jiffy |= loopbit;
ticks = jiffies;
while (ticks == jiffies);
ticks = jiffies;
__delay(loops_per_jiffy);
if (jiffies != ticks) /* longer than 1 tick */
loops_per_jiffy &= ~loopbit;
}
}
#endif /* CONFIG_PM */

View file

@ -31,8 +31,6 @@
#include <asm/mach-au1x00/au1000.h>
extern int au_sleep(void);
void au1000_restart(char *command)
{
/* Set all integrated peripherals to disabled states */

View file

@ -35,7 +35,6 @@
#include <asm/time.h>
#include <au1000.h>
#include <prom.h>
extern void __init board_setup(void);
extern void au1000_restart(char *);
@ -45,80 +44,34 @@ extern void set_cpuspec(void);
void __init plat_mem_setup(void)
{
struct cpu_spec *sp;
char *argptr;
unsigned long prid, cpufreq, bclk;
unsigned long est_freq;
set_cpuspec();
sp = cur_cpu_spec[0];
/* determine core clock */
est_freq = au1xxx_calc_clock();
est_freq += 5000; /* round */
est_freq -= est_freq % 10000;
printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(),
est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
_machine_restart = au1000_restart;
_machine_halt = au1000_halt;
pm_power_off = au1000_power_off;
board_setup(); /* board specific setup */
prid = read_c0_prid();
if (sp->cpu_pll_wo)
#ifdef CONFIG_SOC_AU1000_FREQUENCY
cpufreq = CONFIG_SOC_AU1000_FREQUENCY / 1000000;
#else
cpufreq = 396;
#endif
else
cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12;
printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq);
if (sp->cpu_bclk) {
/* Enable BCLK switching */
bclk = au_readl(SYS_POWERCTRL);
au_writel(bclk | 0x60, SYS_POWERCTRL);
printk(KERN_INFO "BCLK switching enabled!\n");
}
if (sp->cpu_od)
if (au1xxx_cpu_needs_config_od())
/* Various early Au1xx0 errata corrected by this */
set_c0_config(1 << 19); /* Set Config[OD] */
else
/* Clear to obtain best system bus performance */
clear_c0_config(1 << 19); /* Clear Config[OD] */
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#ifdef CONFIG_FB_AU1100
argptr = strstr(argptr, "video=");
if (argptr == NULL) {
argptr = prom_getcmdline();
/* default panel */
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
}
#endif
#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
/* au1000 does not support vra, au1500 and au1100 do */
strcat(argptr, " au1000_audio=vra");
argptr = prom_getcmdline();
#endif
_machine_restart = au1000_restart;
_machine_halt = au1000_halt;
pm_power_off = au1000_power_off;
/* IO/MEM resources. */
set_io_port_base(0);
ioport_resource.start = IOPORT_RESOURCE_START;
ioport_resource.end = IOPORT_RESOURCE_END;
iomem_resource.start = IOMEM_RESOURCE_START;
iomem_resource.end = IOMEM_RESOURCE_END;
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
au_writel(0, SYS_TOYTRIM);
}
#if defined(CONFIG_64BIT_PHYS_ADDR)

View file

@ -15,16 +15,17 @@
#include <asm/regdef.h>
#include <asm/stackframe.h>
.extern __flush_cache_all
.text
.set macro
.set noat
.set noreorder
.set noat
.align 5
/* Save all of the processor general registers and go to sleep.
* A wakeup condition will get us back here to restore the registers.
*/
LEAF(save_and_sleep)
LEAF(au1xxx_save_and_sleep)
subu sp, PT_SIZE
sw $1, PT_R1(sp)
sw $2, PT_R2(sp)
@ -33,14 +34,6 @@ LEAF(save_and_sleep)
sw $5, PT_R5(sp)
sw $6, PT_R6(sp)
sw $7, PT_R7(sp)
sw $8, PT_R8(sp)
sw $9, PT_R9(sp)
sw $10, PT_R10(sp)
sw $11, PT_R11(sp)
sw $12, PT_R12(sp)
sw $13, PT_R13(sp)
sw $14, PT_R14(sp)
sw $15, PT_R15(sp)
sw $16, PT_R16(sp)
sw $17, PT_R17(sp)
sw $18, PT_R18(sp)
@ -49,12 +42,9 @@ LEAF(save_and_sleep)
sw $21, PT_R21(sp)
sw $22, PT_R22(sp)
sw $23, PT_R23(sp)
sw $24, PT_R24(sp)
sw $25, PT_R25(sp)
sw $26, PT_R26(sp)
sw $27, PT_R27(sp)
sw $28, PT_R28(sp)
sw $29, PT_R29(sp)
sw $30, PT_R30(sp)
sw $31, PT_R31(sp)
mfc0 k0, CP0_STATUS
@ -66,20 +56,26 @@ LEAF(save_and_sleep)
mfc0 k0, CP0_CONFIG
sw k0, 0x14(sp)
/* flush caches to make sure context is in memory */
la t1, __flush_cache_all
lw t0, 0(t1)
jalr t0
nop
/* Now set up the scratch registers so the boot rom will
* return to this point upon wakeup.
* sys_scratch0 : SP
* sys_scratch1 : RA
*/
la k0, 1f
lui k1, 0xb190
ori k1, 0x18
sw sp, 0(k1)
ori k1, 0x1c
sw k0, 0(k1)
lui t3, 0xb190 /* sys_xxx */
sw sp, 0x0018(t3)
la k0, 3f /* resume path */
sw k0, 0x001c(t3)
/* Put SDRAM into self refresh. Preload instructions into cache,
* issue a precharge, then auto refresh, then sleep commands to it.
*/
la t0, sdsleep
/* Put SDRAM into self refresh: Preload instructions into cache,
* issue a precharge, auto/self refresh, then sleep commands to it.
*/
la t0, 1f
.set mips3
cache 0x14, 0(t0)
cache 0x14, 32(t0)
@ -87,24 +83,57 @@ LEAF(save_and_sleep)
cache 0x14, 96(t0)
.set mips0
sdsleep:
lui k0, 0xb400
sw zero, 0x001c(k0) /* Precharge */
sw zero, 0x0020(k0) /* Auto refresh */
sw zero, 0x0030(k0) /* SDRAM sleep */
1: lui a0, 0xb400 /* mem_xxx */
#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || \
defined(CONFIG_SOC_AU1500)
sw zero, 0x001c(a0) /* Precharge */
sync
sw zero, 0x0020(a0) /* Auto Refresh */
sync
sw zero, 0x0030(a0) /* Sleep */
sync
#endif
#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
sw zero, 0x08c0(a0) /* Precharge */
sync
sw zero, 0x08d0(a0) /* Self Refresh */
sync
lui k1, 0xb190
sw zero, 0x0078(k1) /* get ready to sleep */
/* wait for sdram to enter self-refresh mode */
lui t0, 0x0100
2: lw t1, 0x0850(a0) /* mem_sdstat */
and t2, t1, t0
beq t2, zero, 2b
nop
/* disable SDRAM clocks */
lui t0, 0xcfff
ori t0, t0, 0xffff
lw t1, 0x0840(a0) /* mem_sdconfiga */
and t1, t0, t1 /* clear CE[1:0] */
sw t1, 0x0840(a0) /* mem_sdconfiga */
sync
sw zero, 0x007c(k1) /* Put processor to sleep */
#endif
/* put power supply and processor to sleep */
sw zero, 0x0078(t3) /* sys_slppwr */
sync
sw zero, 0x007c(t3) /* sys_sleep */
sync
nop
nop
nop
nop
nop
nop
nop
nop
/* This is where we return upon wakeup.
* Reload all of the registers and return.
*/
1: nop
lw k0, 0x20(sp)
3: lw k0, 0x20(sp)
mtc0 k0, CP0_STATUS
lw k0, 0x1c(sp)
mtc0 k0, CP0_CONTEXT
@ -113,10 +142,11 @@ sdsleep:
lw k0, 0x14(sp)
mtc0 k0, CP0_CONFIG
/* We need to catch the ealry Alchemy SOCs with
/* We need to catch the early Alchemy SOCs with
* the write-only Config[OD] bit and set it back to one...
*/
jal au1x00_fixup_config_od
nop
lw $1, PT_R1(sp)
lw $2, PT_R2(sp)
lw $3, PT_R3(sp)
@ -124,14 +154,6 @@ sdsleep:
lw $5, PT_R5(sp)
lw $6, PT_R6(sp)
lw $7, PT_R7(sp)
lw $8, PT_R8(sp)
lw $9, PT_R9(sp)
lw $10, PT_R10(sp)
lw $11, PT_R11(sp)
lw $12, PT_R12(sp)
lw $13, PT_R13(sp)
lw $14, PT_R14(sp)
lw $15, PT_R15(sp)
lw $16, PT_R16(sp)
lw $17, PT_R17(sp)
lw $18, PT_R18(sp)
@ -140,15 +162,11 @@ sdsleep:
lw $21, PT_R21(sp)
lw $22, PT_R22(sp)
lw $23, PT_R23(sp)
lw $24, PT_R24(sp)
lw $25, PT_R25(sp)
lw $26, PT_R26(sp)
lw $27, PT_R27(sp)
lw $28, PT_R28(sp)
lw $29, PT_R29(sp)
lw $30, PT_R30(sp)
lw $31, PT_R31(sp)
addiu sp, PT_SIZE
jr ra
END(save_and_sleep)
addiu sp, PT_SIZE
END(au1xxx_save_and_sleep)

View file

@ -1,5 +1,7 @@
/*
* Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
*
* Previous incarnations were:
* Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com>
* Copied and modified Carsten Langgaard's time.c
*
@ -23,244 +25,141 @@
*
* ########################################################################
*
* Setting up the clock on the MIPS boards.
*
* We provide the clock interrupt processing and the timer offset compute
* functions. If CONFIG_PM is selected, we also ensure the 32KHz timer is
* available. -- Dan
* Clocksource/event using the 32.768kHz-clocked Counter1 ('RTC' in the
* databooks). Firmware/Board init code must enable the counters in the
* counter control register, otherwise the CP0 counter clocksource/event
* will be installed instead (and use of 'wait' instruction is prohibited).
*/
#include <linux/types.h>
#include <linux/init.h>
#include <linux/clockchips.h>
#include <linux/clocksource.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <asm/mipsregs.h>
#include <asm/time.h>
#include <asm/mach-au1x00/au1000.h>
static int no_au1xxx_32khz;
/* 32kHz clock enabled and detected */
#define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
extern int allow_au1k_wait; /* default off for CP0 Counter */
#ifdef CONFIG_PM
#if HZ < 100 || HZ > 1000
#error "unsupported HZ value! Must be in [100,1000]"
#endif
#define MATCH20_INC (328 * 100 / HZ) /* magic number 328 is for HZ=100... */
static unsigned long last_pc0, last_match20;
#endif
static DEFINE_SPINLOCK(time_lock);
unsigned long wtimer;
#ifdef CONFIG_PM
static irqreturn_t counter0_irq(int irq, void *dev_id)
static cycle_t au1x_counter1_read(void)
{
unsigned long pc0;
int time_elapsed;
static int jiffie_drift;
return au_readl(SYS_RTCREAD);
}
if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
/* should never happen! */
printk(KERN_WARNING "counter 0 w status error\n");
return IRQ_NONE;
}
static struct clocksource au1x_counter1_clocksource = {
.name = "alchemy-counter1",
.read = au1x_counter1_read,
.mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
.rating = 100,
};
pc0 = au_readl(SYS_TOYREAD);
if (pc0 < last_match20)
/* counter overflowed */
time_elapsed = (0xffffffff - last_match20) + pc0;
else
time_elapsed = pc0 - last_match20;
while (time_elapsed > 0) {
do_timer(1);
#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));
#endif
time_elapsed -= MATCH20_INC;
last_match20 += MATCH20_INC;
jiffie_drift++;
}
last_pc0 = pc0;
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
static int au1x_rtcmatch2_set_next_event(unsigned long delta,
struct clock_event_device *cd)
{
delta += au_readl(SYS_RTCREAD);
/* wait for register access */
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M21)
;
au_writel(delta, SYS_RTCMATCH2);
au_sync();
/*
* Our counter ticks at 10.009765625 ms/tick, we we're running
* almost 10 uS too slow per tick.
*/
return 0;
}
if (jiffie_drift >= 999) {
jiffie_drift -= 999;
do_timer(1); /* increment jiffies by one */
#ifndef CONFIG_SMP
update_process_times(user_mode(get_irq_regs()));
#endif
}
static void au1x_rtcmatch2_set_mode(enum clock_event_mode mode,
struct clock_event_device *cd)
{
}
static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id)
{
struct clock_event_device *cd = dev_id;
cd->event_handler(cd);
return IRQ_HANDLED;
}
struct irqaction counter0_action = {
.handler = counter0_irq,
.flags = IRQF_DISABLED,
.name = "alchemy-toy",
.dev_id = NULL,
static struct clock_event_device au1x_rtcmatch2_clockdev = {
.name = "rtcmatch2",
.features = CLOCK_EVT_FEAT_ONESHOT,
.rating = 100,
.irq = AU1000_RTC_MATCH2_INT,
.set_next_event = au1x_rtcmatch2_set_next_event,
.set_mode = au1x_rtcmatch2_set_mode,
.cpumask = CPU_MASK_ALL,
};
/* When we wakeup from sleep, we have to "catch up" on all of the
* timer ticks we have missed.
*/
void wakeup_counter0_adjust(void)
{
unsigned long pc0;
int time_elapsed;
pc0 = au_readl(SYS_TOYREAD);
if (pc0 < last_match20)
/* counter overflowed */
time_elapsed = (0xffffffff - last_match20) + pc0;
else
time_elapsed = pc0 - last_match20;
while (time_elapsed > 0) {
time_elapsed -= MATCH20_INC;
last_match20 += MATCH20_INC;
}
last_pc0 = pc0;
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
au_sync();
}
/* This is just for debugging to set the timer for a sleep delay. */
void wakeup_counter0_set(int ticks)
{
unsigned long pc0;
pc0 = au_readl(SYS_TOYREAD);
last_pc0 = pc0;
au_writel(last_match20 + (MATCH20_INC * ticks), SYS_TOYMATCH2);
au_sync();
}
#endif
/*
* I haven't found anyone that doesn't use a 12 MHz source clock,
* but just in case.....
*/
#define AU1000_SRC_CLK 12000000
/*
* We read the real processor speed from the PLL. This is important
* because it is more accurate than computing it from the 32 KHz
* counter, if it exists. If we don't have an accurate processor
* speed, all of the peripherals that derive their clocks based on
* this advertised speed will introduce error and sometimes not work
* properly. This function is futher convoluted to still allow configurations
* to do that in case they have really, really old silicon with a
* write-only PLL register, that we need the 32 KHz when power management
* "wait" is enabled, and we need to detect if the 32 KHz isn't present
* but requested......got it? :-) -- Dan
*/
unsigned long calc_clock(void)
{
unsigned long cpu_speed;
unsigned long flags;
unsigned long counter;
spin_lock_irqsave(&time_lock, flags);
/* Power management cares if we don't have a 32 KHz counter. */
no_au1xxx_32khz = 0;
counter = au_readl(SYS_COUNTER_CNTRL);
if (counter & SYS_CNTRL_E0) {
int trim_divide = 16;
au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
/* RTC now ticks at 32.768/16 kHz */
au_writel(trim_divide - 1, SYS_RTCTRIM);
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
au_writel(0, SYS_TOYWRITE);
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
} else
no_au1xxx_32khz = 1;
/*
* On early Au1000, sys_cpupll was write-only. Since these
* silicon versions of Au1000 are not sold by AMD, we don't bend
* over backwards trying to determine the frequency.
*/
if (cur_cpu_spec[0]->cpu_pll_wo)
#ifdef CONFIG_SOC_AU1000_FREQUENCY
cpu_speed = CONFIG_SOC_AU1000_FREQUENCY;
#else
cpu_speed = 396000000;
#endif
else
cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
/* On Alchemy CPU:counter ratio is 1:1 */
mips_hpt_frequency = cpu_speed;
/* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
& 0x03) + 2) * 16));
spin_unlock_irqrestore(&time_lock, flags);
return cpu_speed;
}
static struct irqaction au1x_rtcmatch2_irqaction = {
.handler = au1x_rtcmatch2_irq,
.flags = IRQF_DISABLED | IRQF_TIMER,
.name = "timer",
.dev_id = &au1x_rtcmatch2_clockdev,
};
void __init plat_time_init(void)
{
unsigned int est_freq = calc_clock();
struct clock_event_device *cd = &au1x_rtcmatch2_clockdev;
unsigned long t;
est_freq += 5000; /* round */
est_freq -= est_freq%10000;
printk(KERN_INFO "CPU frequency %u.%02u MHz\n",
est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
set_au1x00_speed(est_freq);
set_au1x00_lcd_clock(); /* program the LCD clock */
#ifdef CONFIG_PM
/*
* setup counter 0, since it keeps ticking after a
* 'wait' instruction has been executed. The CP0 timer and
* counter 1 do NOT continue running after 'wait'
*
* It's too early to call request_irq() here, so we handle
* counter 0 interrupt as a special irq and it doesn't show
* up under /proc/interrupts.
*
* Check to ensure we really have a 32 KHz oscillator before
* we do this.
/* Check if firmware (YAMON, ...) has enabled 32kHz and clock
* has been detected. If so install the rtcmatch2 clocksource,
* otherwise don't bother. Note that both bits being set is by
* no means a definite guarantee that the counters actually work
* (the 32S bit seems to be stuck set to 1 once a single clock-
* edge is detected, hence the timeouts).
*/
if (no_au1xxx_32khz)
printk(KERN_WARNING "WARNING: no 32KHz clock found.\n");
else {
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
au_writel(0, SYS_TOYWRITE);
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
if (CNTR_OK != (au_readl(SYS_COUNTER_CNTRL) & CNTR_OK))
goto cntr_err;
au_writel(au_readl(SYS_WAKEMSK) | (1 << 8), SYS_WAKEMSK);
au_writel(~0, SYS_WAKESRC);
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
/*
* setup counter 1 (RTC) to tick at full speed
*/
t = 0xffffff;
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && t--)
asm volatile ("nop");
if (!t)
goto cntr_err;
/* Setup match20 to interrupt once every HZ */
last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
au_sync();
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
au_writel(0, SYS_RTCTRIM); /* 32.768 kHz */
au_sync();
/* We can use the real 'wait' instruction. */
allow_au1k_wait = 1;
}
t = 0xffffff;
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--)
asm volatile ("nop");
if (!t)
goto cntr_err;
au_writel(0, SYS_RTCWRITE);
au_sync();
#endif
t = 0xffffff;
while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--)
asm volatile ("nop");
if (!t)
goto cntr_err;
/* register counter1 clocksource and event device */
clocksource_set_clock(&au1x_counter1_clocksource, 32768);
clocksource_register(&au1x_counter1_clocksource);
cd->shift = 32;
cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift);
cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */
clockevents_register_device(cd);
setup_irq(AU1000_RTC_MATCH2_INT, &au1x_rtcmatch2_irqaction);
printk(KERN_INFO "Alchemy clocksource installed\n");
/* can now use 'wait' */
allow_au1k_wait = 1;
return;
cntr_err:
/* counters unusable, use C0 counter */
r4k_clockevent_init();
init_r4k_clocksource();
allow_au1k_wait = 0;
}

View file

@ -1,62 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* PB1000 board setup
*
* Copyright 2001, 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/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{
#ifdef CONFIG_MIPS_BOSPORUS
return "Alchemy Bosporus Gateway Reference";
#else
return "Alchemy Db1x00";
#endif
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtol(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}

View file

@ -0,0 +1,18 @@
#
# Alchemy Develboards
#
obj-y += prom.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_MIPS_PB1000) += pb1000/
obj-$(CONFIG_MIPS_PB1100) += pb1100/
obj-$(CONFIG_MIPS_PB1200) += pb1200/
obj-$(CONFIG_MIPS_PB1500) += pb1500/
obj-$(CONFIG_MIPS_PB1550) += pb1550/
obj-$(CONFIG_MIPS_DB1000) += db1x00/
obj-$(CONFIG_MIPS_DB1100) += db1x00/
obj-$(CONFIG_MIPS_DB1200) += pb1200/
obj-$(CONFIG_MIPS_DB1500) += db1x00/
obj-$(CONFIG_MIPS_DB1550) += db1x00/
obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/
obj-$(CONFIG_MIPS_MIRAGE) += db1x00/

View file

@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
#
lib-y := init.o board_setup.o irqmap.o
obj-y := board_setup.o irqmap.o

View file

@ -32,8 +32,20 @@
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/db1x00.h>
#include <prom.h>
static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
const char *get_system_type(void)
{
#ifdef CONFIG_MIPS_BOSPORUS
return "Alchemy Bosporus Gateway Reference";
#else
return "Alchemy Db1x00";
#endif
}
void board_reset(void)
{
/* Hit BCSR.SW_RESET[RESET] */
@ -43,6 +55,31 @@ void board_reset(void)
void __init board_setup(void)
{
u32 pin_func = 0;
char *argptr;
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#ifdef CONFIG_FB_AU1100
argptr = strstr(argptr, "video=");
if (argptr == NULL) {
argptr = prom_getcmdline();
/* default panel */
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
}
#endif
#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
/* au1000 does not support vra, au1500 and au1100 do */
strcat(argptr, " au1000_audio=vra");
argptr = prom_getcmdline();
#endif
/* Not valid for Au1550 */
#if defined(CONFIG_IRDA) && \

View file

@ -27,6 +27,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
@ -66,21 +67,24 @@ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
#ifndef CONFIG_MIPS_MIRAGE
#ifdef CONFIG_MIPS_DB1550
{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */
{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */
{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
#else
{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 Fully_Interted# */
{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 STSCHG# */
{ AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */
{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 Fully_Interted# */
{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 STSCHG# */
{ AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 Fully_Interted# */
{ AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 STSCHG# */
{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */
{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 Fully_Interted# */
{ AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 STSCHG# */
{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
#endif
#else
{ AU1000_GPIO_7, INTC_INT_RISE_EDGE, 0 }, /* touchscreen pen down */
{ AU1000_GPIO_7, IRQF_TRIGGER_RISING, 0 }, /* touchscreen pen down */
#endif
};
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}

View file

@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1000 board.
#
lib-y := init.o board_setup.o irqmap.o
obj-y := board_setup.o

View file

@ -23,22 +23,48 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1000.h>
#include <prom.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_15, IRQF_TRIGGER_LOW, 0 },
};
const char *get_system_type(void)
{
return "Alchemy Pb1000";
}
void board_reset(void)
{
}
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}
void __init board_setup(void)
{
u32 pin_func, static_cfg0;
u32 sys_freqctrl, sys_clksrc;
u32 prid = read_c0_prid();
#ifdef CONFIG_SERIAL_8250_CONSOLE
char *argptr = prom_getcmdline();
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
au_writel(0, SYS_PINSTATERD);

View file

@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1100 board.
#
lib-y := init.o board_setup.o irqmap.o
obj-y := board_setup.o

View file

@ -25,19 +25,66 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1100.h>
#include <prom.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_9, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card Fully_Inserted# */
{ AU1000_GPIO_10, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card STSCHG# */
{ AU1000_GPIO_11, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card IRQ# */
{ AU1000_GPIO_13, IRQF_TRIGGER_LOW, 0 }, /* DC_IRQ# */
};
const char *get_system_type(void)
{
return "Alchemy Pb1100";
}
void board_reset(void)
{
/* Hit BCSR.RST_VDDI[SOFT_RESET] */
au_writel(0x00000000, PB1100_RST_VDDI);
}
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}
void __init board_setup(void)
{
volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
char *argptr;
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#ifdef CONFIG_FB_AU1100
argptr = strstr(argptr, "video=");
if (argptr == NULL) {
argptr = prom_getcmdline();
/* default panel */
/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
}
#endif
#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
/* au1000 does not support vra, au1500 and au1100 do */
strcat(argptr, " au1000_audio=vra");
argptr = prom_getcmdline();
#endif
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);

View file

@ -2,7 +2,6 @@
# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
#
lib-y := init.o board_setup.o irqmap.o
obj-y += platform.o
obj-y := board_setup.o irqmap.o platform.o
EXTRA_CFLAGS += -Werror

View file

@ -30,8 +30,11 @@
#include <prom.h>
#include <au1xxx.h>
extern void _board_init_irq(void);
extern void (*board_init_irq)(void);
const char *get_system_type(void)
{
return "Alchemy Pb1200";
}
void board_reset(void)
{
@ -41,7 +44,19 @@ void board_reset(void)
void __init board_setup(void)
{
char *argptr = NULL;
char *argptr;
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#ifdef CONFIG_FB_AU1200
strcat(argptr, " video=au1200fb:panel:bs");
#endif
#if 0
{
@ -99,16 +114,6 @@ void __init board_setup(void)
}
#endif
#ifdef CONFIG_FB_AU1200
argptr = prom_getcmdline();
#ifdef CONFIG_MIPS_PB1200
strcat(argptr, " video=au1200fb:panel:bs");
#endif
#ifdef CONFIG_MIPS_DB1200
strcat(argptr, " video=au1200fb:panel:bs");
#endif
#endif
/*
* The Pb1200 development board uses external MUX for PSC0 to
* support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
@ -124,9 +129,6 @@ void __init board_setup(void)
#ifdef CONFIG_MIPS_DB1200
printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
#endif
/* Setup Pb1200 External Interrupt Controller */
board_init_irq = _board_init_irq;
}
int board_au1200fb_panel(void)

View file

@ -40,91 +40,65 @@
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
/* This is external interrupt cascade */
{ AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_7, IRQF_TRIGGER_LOW, 0 },
};
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
/*
* Support for External interrupts on the Pb1200 Development platform.
*/
static volatile int pb1200_cascade_en;
irqreturn_t pb1200_cascade_handler(int irq, void *dev_id)
static void pb1200_cascade_handler(unsigned int irq, struct irq_desc *d)
{
unsigned short bisr = bcsr->int_status;
int extirq_nr = 0;
/* Clear all the edge interrupts. This has no effect on level. */
bcsr->int_status = bisr;
for ( ; bisr; bisr &= bisr - 1) {
extirq_nr = PB1200_INT_BEGIN + __ffs(bisr);
/* Ack and dispatch IRQ */
do_IRQ(extirq_nr);
}
return IRQ_RETVAL(1);
for ( ; bisr; bisr &= bisr - 1)
generic_handle_irq(PB1200_INT_BEGIN + __ffs(bisr));
}
inline void pb1200_enable_irq(unsigned int irq_nr)
{
bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
}
inline void pb1200_disable_irq(unsigned int irq_nr)
/* NOTE: both the enable and mask bits must be cleared, otherwise the
* CPLD generates tons of spurious interrupts (at least on the DB1200).
*/
static void pb1200_mask_irq(unsigned int irq_nr)
{
bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
au_sync();
}
static unsigned int pb1200_setup_cascade(void)
static void pb1200_maskack_irq(unsigned int irq_nr)
{
return request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
0, "Pb1200 Cascade", &pb1200_cascade_handler);
bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->int_status = 1 << (irq_nr - PB1200_INT_BEGIN); /* ack */
au_sync();
}
static unsigned int pb1200_startup_irq(unsigned int irq)
static void pb1200_unmask_irq(unsigned int irq_nr)
{
if (++pb1200_cascade_en == 1) {
int res;
res = pb1200_setup_cascade();
if (res)
return res;
}
pb1200_enable_irq(irq);
return 0;
bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
au_sync();
}
static void pb1200_shutdown_irq(unsigned int irq)
{
pb1200_disable_irq(irq);
if (--pb1200_cascade_en == 0)
free_irq(AU1000_GPIO_7, &pb1200_cascade_handler);
}
static struct irq_chip external_irq_type = {
static struct irq_chip pb1200_cpld_irq_type = {
#ifdef CONFIG_MIPS_PB1200
.name = "Pb1200 Ext",
#endif
#ifdef CONFIG_MIPS_DB1200
.name = "Db1200 Ext",
#endif
.startup = pb1200_startup_irq,
.shutdown = pb1200_shutdown_irq,
.ack = pb1200_disable_irq,
.mask = pb1200_disable_irq,
.mask_ack = pb1200_disable_irq,
.unmask = pb1200_enable_irq,
.mask = pb1200_mask_irq,
.mask_ack = pb1200_maskack_irq,
.unmask = pb1200_unmask_irq,
};
void _board_init_irq(void)
void __init board_init_irq(void)
{
unsigned int irq;
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
#ifdef CONFIG_MIPS_PB1200
/* We have a problem with CPLD rev 3. */
if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
@ -146,15 +120,15 @@ void _board_init_irq(void)
panic("Game over. Your score is 0.");
}
#endif
/* mask & disable & ack all */
bcsr->intclr_mask = 0xffff;
bcsr->intclr = 0xffff;
bcsr->int_status = 0xffff;
au_sync();
for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++) {
set_irq_chip_and_handler(irq, &external_irq_type,
handle_level_irq);
pb1200_disable_irq(irq);
}
for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++)
set_irq_chip_and_handler_name(irq, &pb1200_cpld_irq_type,
handle_level_irq, "level");
/*
* GPIO_7 can not be hooked here, so it is hooked upon first
* request of any source attached to the cascade.
*/
set_irq_chained_handler(AU1000_GPIO_7, pb1200_cascade_handler);
}

View file

@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1500 board.
#
lib-y := init.o board_setup.o irqmap.o
obj-y := board_setup.o

View file

@ -25,20 +25,64 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1500.h>
#include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT370 */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
{ AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
};
const char *get_system_type(void)
{
return "Alchemy Pb1500";
}
void board_reset(void)
{
/* Hit BCSR.RST_VDDI[SOFT_RESET] */
au_writel(0x00000000, PB1500_RST_VDDI);
}
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}
void __init board_setup(void)
{
u32 pin_func;
u32 sys_freqctrl, sys_clksrc;
char *argptr;
argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
/* au1000 does not support vra, au1500 and au1100 do */
strcat(argptr, " au1000_audio=vra");
argptr = prom_getcmdline();
#endif
sys_clksrc = sys_freqctrl = pin_func = 0;
/* Set AUX clock to 12 MHz * 8 = 96 MHz */

View file

@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1550 board.
#
lib-y := init.o board_setup.o irqmap.o
obj-y := board_setup.o

View file

@ -28,20 +28,54 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1550.h>
#include <prom.h>
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
};
const char *get_system_type(void)
{
return "Alchemy Pb1550";
}
void board_reset(void)
{
/* Hit BCSR.SYSTEM[RESET] */
au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C);
}
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}
void __init board_setup(void)
{
u32 pin_func;
#ifdef CONFIG_SERIAL_8250_CONSOLE
char *argptr;
argptr = prom_getcmdline();
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
/*
* Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
* but it is board specific code, so put it here.

View file

@ -0,0 +1,229 @@
/*
* Alchemy Development Board example suspend userspace interface.
*
* (c) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
*/
#include <linux/init.h>
#include <linux/kobject.h>
#include <linux/suspend.h>
#include <linux/sysfs.h>
#include <asm/mach-au1x00/au1000.h>
/*
* Generic suspend userspace interface for Alchemy development boards.
* This code exports a few sysfs nodes under /sys/power/db1x/ which
* can be used by userspace to en/disable all au1x-provided wakeup
* sources and configure the timeout after which the the TOYMATCH2 irq
* is to trigger a wakeup.
*/
static unsigned long db1x_pm_sleep_secs;
static unsigned long db1x_pm_wakemsk;
static unsigned long db1x_pm_last_wakesrc;
static int db1x_pm_enter(suspend_state_t state)
{
/* enable GPIO based wakeup */
au_writel(1, SYS_PININPUTEN);
/* clear and setup wake cause and source */
au_writel(0, SYS_WAKEMSK);
au_sync();
au_writel(0, SYS_WAKESRC);
au_sync();
au_writel(db1x_pm_wakemsk, SYS_WAKEMSK);
au_sync();
/* setup 1Hz-timer-based wakeup: wait for reg access */
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
asm volatile ("nop");
au_writel(au_readl(SYS_TOYREAD) + db1x_pm_sleep_secs, SYS_TOYMATCH2);
au_sync();
/* wait for value to really hit the register */
while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
asm volatile ("nop");
/* ...and now the sandman can come! */
au_sleep();
return 0;
}
static int db1x_pm_begin(suspend_state_t state)
{
if (!db1x_pm_wakemsk) {
printk(KERN_ERR "db1x: no wakeup source activated!\n");
return -EINVAL;
}
return 0;
}
static void db1x_pm_end(void)
{
/* read and store wakeup source, the clear the register. To
* be able to clear it, WAKEMSK must be cleared first.
*/
db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC);
au_writel(0, SYS_WAKEMSK);
au_writel(0, SYS_WAKESRC);
au_sync();
}
static struct platform_suspend_ops db1x_pm_ops = {
.valid = suspend_valid_only_mem,
.begin = db1x_pm_begin,
.enter = db1x_pm_enter,
.end = db1x_pm_end,
};
#define ATTRCMP(x) (0 == strcmp(attr->attr.name, #x))
static ssize_t db1x_pmattr_show(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
int idx;
if (ATTRCMP(timer_timeout))
return sprintf(buf, "%lu\n", db1x_pm_sleep_secs);
else if (ATTRCMP(timer))
return sprintf(buf, "%u\n",
!!(db1x_pm_wakemsk & SYS_WAKEMSK_M2));
else if (ATTRCMP(wakesrc))
return sprintf(buf, "%lu\n", db1x_pm_last_wakesrc);
else if (ATTRCMP(gpio0) || ATTRCMP(gpio1) || ATTRCMP(gpio2) ||
ATTRCMP(gpio3) || ATTRCMP(gpio4) || ATTRCMP(gpio5) ||
ATTRCMP(gpio6) || ATTRCMP(gpio7)) {
idx = (attr->attr.name)[4] - '0';
return sprintf(buf, "%d\n",
!!(db1x_pm_wakemsk & SYS_WAKEMSK_GPIO(idx)));
} else if (ATTRCMP(wakemsk)) {
return sprintf(buf, "%08lx\n", db1x_pm_wakemsk);
}
return -ENOENT;
}
static ssize_t db1x_pmattr_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *instr,
size_t bytes)
{
unsigned long l;
int tmp;
if (ATTRCMP(timer_timeout)) {
tmp = strict_strtoul(instr, 0, &l);
if (tmp)
return tmp;
db1x_pm_sleep_secs = l;
} else if (ATTRCMP(timer)) {
if (instr[0] != '0')
db1x_pm_wakemsk |= SYS_WAKEMSK_M2;
else
db1x_pm_wakemsk &= ~SYS_WAKEMSK_M2;
} else if (ATTRCMP(gpio0) || ATTRCMP(gpio1) || ATTRCMP(gpio2) ||
ATTRCMP(gpio3) || ATTRCMP(gpio4) || ATTRCMP(gpio5) ||
ATTRCMP(gpio6) || ATTRCMP(gpio7)) {
tmp = (attr->attr.name)[4] - '0';
if (instr[0] != '0') {
db1x_pm_wakemsk |= SYS_WAKEMSK_GPIO(tmp);
} else {
db1x_pm_wakemsk &= ~SYS_WAKEMSK_GPIO(tmp);
}
} else if (ATTRCMP(wakemsk)) {
tmp = strict_strtoul(instr, 0, &l);
if (tmp)
return tmp;
db1x_pm_wakemsk = l & 0x0000003f;
} else
bytes = -ENOENT;
return bytes;
}
#define ATTR(x) \
static struct kobj_attribute x##_attribute = \
__ATTR(x, 0664, db1x_pmattr_show, \
db1x_pmattr_store);
ATTR(gpio0) /* GPIO-based wakeup enable */
ATTR(gpio1)
ATTR(gpio2)
ATTR(gpio3)
ATTR(gpio4)
ATTR(gpio5)
ATTR(gpio6)
ATTR(gpio7)
ATTR(timer) /* TOYMATCH2-based wakeup enable */
ATTR(timer_timeout) /* timer-based wakeup timeout value, in seconds */
ATTR(wakesrc) /* contents of SYS_WAKESRC after last wakeup */
ATTR(wakemsk) /* direct access to SYS_WAKEMSK */
#define ATTR_LIST(x) & x ## _attribute.attr
static struct attribute *db1x_pmattrs[] = {
ATTR_LIST(gpio0),
ATTR_LIST(gpio1),
ATTR_LIST(gpio2),
ATTR_LIST(gpio3),
ATTR_LIST(gpio4),
ATTR_LIST(gpio5),
ATTR_LIST(gpio6),
ATTR_LIST(gpio7),
ATTR_LIST(timer),
ATTR_LIST(timer_timeout),
ATTR_LIST(wakesrc),
ATTR_LIST(wakemsk),
NULL, /* terminator */
};
static struct attribute_group db1x_pmattr_group = {
.name = "db1x",
.attrs = db1x_pmattrs,
};
/*
* Initialize suspend interface
*/
static int __init pm_init(void)
{
/* init TOY to tick at 1Hz if not already done. No need to wait
* for confirmation since there's plenty of time from here to
* the next suspend cycle.
*/
if (au_readl(SYS_TOYTRIM) != 32767) {
au_writel(32767, SYS_TOYTRIM);
au_sync();
}
db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC);
au_writel(0, SYS_WAKESRC);
au_sync();
au_writel(0, SYS_WAKEMSK);
au_sync();
suspend_set_ops(&db1x_pm_ops);
return sysfs_create_group(power_kobj, &db1x_pmattr_group);
}
late_initcall(pm_init);

View file

@ -1,9 +1,9 @@
/*
* Common code used by all Alchemy develboards.
*
* BRIEF MODULE DESCRIPTION
* Pb1550 board setup
* Extracted from files which had this to say:
*
* Copyright 2001, 2008 MontaVista Software Inc.
* Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or modify it
@ -29,15 +29,19 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
const char *get_system_type(void)
{
return "Alchemy Pb1550";
}
#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_DB1000) || \
defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || \
defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_DB1500) || \
defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000
#else /* Au1550/Au1200-based develboards */
#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x08000000
#endif
void __init prom_init(void)
{
@ -51,8 +55,8 @@ void __init prom_init(void)
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x08000000;
memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
else
strict_strtol(memsize_str, 0, &memsize);
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}

View file

@ -32,6 +32,8 @@
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
extern int (*board_pci_idsel)(unsigned int devsel, int assert);
int mtx1_pci_idsel(unsigned int devsel, int assert);
@ -43,6 +45,16 @@ void board_reset(void)
void __init board_setup(void)
{
#ifdef CONFIG_SERIAL_8250_CONSOLE
char *argptr;
argptr = prom_getcmdline();
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
/* Enable USB power switch */
au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR);

View file

@ -55,6 +55,6 @@ void __init prom_init(void)
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtol(memsize_str, 0, &memsize);
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}

View file

@ -27,7 +27,7 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
char irq_tab_alchemy[][5] __initdata = {
@ -42,11 +42,15 @@ char irq_tab_alchemy[][5] __initdata = {
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
{ AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
};
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}

View file

@ -1,57 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Pb1000 board setup
*
* Copyright 2001, 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/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{
return "Alchemy Pb1000";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = (int)fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtol(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}

View file

@ -1,38 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Au1xxx irq map table
*
* Copyright 2003 Embedded Edge, LLC
* dan@embeddededge.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/init.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 },
};
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);

View file

@ -1,60 +0,0 @@
/*
*
* BRIEF MODULE DESCRIPTION
* Pb1100 board setup
*
* Copyright 2002, 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/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{
return "Alchemy Pb1100";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg3;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtol(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}

View file

@ -1,40 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Au1xx0 IRQ map table
*
* Copyright 2003 Embedded Edge, LLC
* dan@embeddededge.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/init.h>
#include <asm/mach-au1x00/au1000.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card Fully_Inserted# */
{ AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card STSCHG# */
{ AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card IRQ# */
{ AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, /* DC_IRQ# */
};
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);

View file

@ -1,58 +0,0 @@
/*
*
* BRIEF MODULE DESCRIPTION
* PB1200 board setup
*
* Copyright 2001, 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/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{
return "Alchemy Pb1200";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = (int)fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x08000000;
else
strict_strtol(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}

View file

@ -1,58 +0,0 @@
/*
*
* BRIEF MODULE DESCRIPTION
* Pb1500 board setup
*
* Copyright 2001, 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/init.h>
#include <linux/kernel.h>
#include <asm/bootinfo.h>
#include <prom.h>
const char *get_system_type(void)
{
return "Alchemy Pb1500";
}
void __init prom_init(void)
{
unsigned char *memsize_str;
unsigned long memsize;
prom_argc = (int)fw_arg0;
prom_argv = (char **)fw_arg1;
prom_envp = (char **)fw_arg2;
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtol(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}

View file

@ -1,46 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Au1xxx irq map table
*
* Copyright 2003 Embedded Edge, LLC
* dan@embeddededge.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/init.h>
#include <asm/mach-au1x00/au1000.h>
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, INTA, INTX, INTX, INTX }, /* IDSEL 12 - HPT370 */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot */
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
};
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);

View file

@ -1,43 +0,0 @@
/*
* BRIEF MODULE DESCRIPTION
* Au1xx0 IRQ map table
*
* Copyright 2003 Embedded Edge, LLC
* dan@embeddededge.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/init.h>
#include <asm/mach-au1x00/au1000.h>
char irq_tab_alchemy[][5] __initdata = {
[12] = { -1, INTB, INTC, INTD, INTA }, /* IDSEL 12 - PCI slot 2 (left) */
[13] = { -1, INTA, INTB, INTC, INTD }, /* IDSEL 13 - PCI slot 1 (right) */
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
};
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);

View file

@ -28,6 +28,8 @@
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
void board_reset(void)
{
/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
@ -38,6 +40,16 @@ void __init board_setup(void)
{
u32 pin_func;
#ifdef CONFIG_SERIAL_8250_CONSOLE
char *argptr;
argptr = prom_getcmdline();
argptr = strstr(argptr, "console=");
if (argptr == NULL) {
argptr = prom_getcmdline();
strcat(argptr, " console=ttyS0,115200");
}
#endif
/* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
pin_func |= SYS_PF_UR3;

View file

@ -53,6 +53,6 @@ void __init prom_init(void)
if (!memsize_str)
memsize = 0x04000000;
else
strict_strtol(memsize_str, 0, &memsize);
strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}

View file

@ -27,23 +27,26 @@
*/
#include <linux/init.h>
#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
{ AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
{ AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 },
{ AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
{ AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
{ AU1500_GPIO_207, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* CF interrupt */
{ AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 },
{ AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 },
{ AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* CF interrupt */
{ AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 },
};
int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
void __init board_init_irq(void)
{
au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
}

View file

@ -0,0 +1,85 @@
config CAVIUM_OCTEON_SPECIFIC_OPTIONS
bool "Enable Octeon specific options"
depends on CPU_CAVIUM_OCTEON
default "y"
config CAVIUM_OCTEON_2ND_KERNEL
bool "Build the kernel to be used as a 2nd kernel on the same chip"
depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
default "n"
help
This option configures this kernel to be linked at a different
address and use the 2nd uart for output. This allows a kernel built
with this option to be run at the same time as one built without this
option.
config CAVIUM_OCTEON_HW_FIX_UNALIGNED
bool "Enable hardware fixups of unaligned loads and stores"
depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
default "y"
help
Configure the Octeon hardware to automatically fix unaligned loads
and stores. Normally unaligned accesses are fixed using a kernel
exception handler. This option enables the hardware automatic fixups,
which requires only an extra 3 cycles. Disable this option if you
are running code that relies on address exceptions on unaligned
accesses.
config CAVIUM_OCTEON_CVMSEG_SIZE
int "Number of L1 cache lines reserved for CVMSEG memory"
depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
range 0 54
default 1
help
CVMSEG LM is a segment that accesses portions of the dcache as a
local memory; the larger CVMSEG is, the smaller the cache is.
This selects the size of CVMSEG LM, which is in cache blocks. The
legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
between zero and 6192 bytes).
config CAVIUM_OCTEON_LOCK_L2
bool "Lock often used kernel code in the L2"
depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
default "y"
help
Enable locking parts of the kernel into the L2 cache.
config CAVIUM_OCTEON_LOCK_L2_TLB
bool "Lock the TLB handler in L2"
depends on CAVIUM_OCTEON_LOCK_L2
default "y"
help
Lock the low level TLB fast path into L2.
config CAVIUM_OCTEON_LOCK_L2_EXCEPTION
bool "Lock the exception handler in L2"
depends on CAVIUM_OCTEON_LOCK_L2
default "y"
help
Lock the low level exception handler into L2.
config CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT
bool "Lock the interrupt handler in L2"
depends on CAVIUM_OCTEON_LOCK_L2
default "y"
help
Lock the low level interrupt handler into L2.
config CAVIUM_OCTEON_LOCK_L2_INTERRUPT
bool "Lock the 2nd level interrupt handler in L2"
depends on CAVIUM_OCTEON_LOCK_L2
default "y"
help
Lock the 2nd level interrupt handler in L2.
config CAVIUM_OCTEON_LOCK_L2_MEMCPY
bool "Lock memcpy() in L2"
depends on CAVIUM_OCTEON_LOCK_L2
default "y"
help
Lock the kernel's implementation of memcpy() into L2.
config ARCH_SPARSEMEM_ENABLE
def_bool y
select SPARSEMEM_STATIC
depends on CPU_CAVIUM_OCTEON

View file

@ -0,0 +1,16 @@
#
# Makefile for the Cavium Octeon specific kernel interface routines
# under Linux.
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 2005-2008 Cavium Networks
#
obj-y := setup.o serial.o octeon-irq.o csrc-octeon.o
obj-y += dma-octeon.o flash_setup.o
obj-y += octeon-memcpy.o
obj-$(CONFIG_SMP) += smp.o

View file

@ -0,0 +1,58 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2007 by Ralf Baechle
*/
#include <linux/clocksource.h>
#include <linux/init.h>
#include <asm/time.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-ipd-defs.h>
/*
* Set the current core's cvmcount counter to the value of the
* IPD_CLK_COUNT. We do this on all cores as they are brought
* on-line. This allows for a read from a local cpu register to
* access a synchronized counter.
*
*/
void octeon_init_cvmcount(void)
{
unsigned long flags;
unsigned loops = 2;
/* Clobber loops so GCC will not unroll the following while loop. */
asm("" : "+r" (loops));
local_irq_save(flags);
/*
* Loop several times so we are executing from the cache,
* which should give more deterministic timing.
*/
while (loops--)
write_c0_cvmcount(cvmx_read_csr(CVMX_IPD_CLK_COUNT));
local_irq_restore(flags);
}
static cycle_t octeon_cvmcount_read(void)
{
return read_c0_cvmcount();
}
static struct clocksource clocksource_mips = {
.name = "OCTEON_CVMCOUNT",
.read = octeon_cvmcount_read,
.mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
void __init plat_time_init(void)
{
clocksource_mips.rating = 300;
clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
clocksource_register(&clocksource_mips);
}

View file

@ -0,0 +1,32 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2000 Ani Joshi <ajoshi@unixbox.com>
* Copyright (C) 2000, 2001 Ralf Baechle <ralf@gnu.org>
* Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
* swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
* IP32 changes by Ilya.
* Cavium Networks: Create new dma setup for Cavium Networks Octeon based on
* the kernels original.
*/
#include <linux/types.h>
#include <linux/mm.h>
#include <dma-coherence.h>
dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
{
/* Without PCI/PCIe this function can be called for Octeon internal
devices such as USB. These devices all support 64bit addressing */
mb();
return virt_to_phys(ptr);
}
void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
/* Without PCI/PCIe this function can be called for Octeon internal
* devices such as USB. These devices all support 64bit addressing */
return;
}

View file

@ -0,0 +1,13 @@
#
# Makefile for the Cavium Octeon specific kernel interface routines
# under Linux.
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
# Copyright (C) 2005-2008 Cavium Networks
#
obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o

View file

@ -0,0 +1,586 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* Simple allocate only memory allocator. Used to allocate memory at
* application start time.
*/
#include <linux/kernel.h>
#include <asm/octeon/cvmx.h>
#include <asm/octeon/cvmx-spinlock.h>
#include <asm/octeon/cvmx-bootmem.h>
/*#define DEBUG */
static struct cvmx_bootmem_desc *cvmx_bootmem_desc;
/* See header file for descriptions of functions */
/*
* Wrapper functions are provided for reading/writing the size and
* next block values as these may not be directly addressible (in 32
* bit applications, for instance.) Offsets of data elements in
* bootmem list, must match cvmx_bootmem_block_header_t.
*/
#define NEXT_OFFSET 0
#define SIZE_OFFSET 8
static void cvmx_bootmem_phy_set_size(uint64_t addr, uint64_t size)
{
cvmx_write64_uint64((addr + SIZE_OFFSET) | (1ull << 63), size);
}
static void cvmx_bootmem_phy_set_next(uint64_t addr, uint64_t next)
{
cvmx_write64_uint64((addr + NEXT_OFFSET) | (1ull << 63), next);
}
static uint64_t cvmx_bootmem_phy_get_size(uint64_t addr)
{
return cvmx_read64_uint64((addr + SIZE_OFFSET) | (1ull << 63));
}
static uint64_t cvmx_bootmem_phy_get_next(uint64_t addr)
{
return cvmx_read64_uint64((addr + NEXT_OFFSET) | (1ull << 63));
}
void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment,
uint64_t min_addr, uint64_t max_addr)
{
int64_t address;
address =
cvmx_bootmem_phy_alloc(size, min_addr, max_addr, alignment, 0);
if (address > 0)
return cvmx_phys_to_ptr(address);
else
return NULL;
}
void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address,
uint64_t alignment)
{
return cvmx_bootmem_alloc_range(size, alignment, address,
address + size);
}
void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment)
{
return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
}
int cvmx_bootmem_free_named(char *name)
{
return cvmx_bootmem_phy_named_block_free(name, 0);
}
struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name)
{
return cvmx_bootmem_phy_named_block_find(name, 0);
}
void cvmx_bootmem_lock(void)
{
cvmx_spinlock_lock((cvmx_spinlock_t *) &(cvmx_bootmem_desc->lock));
}
void cvmx_bootmem_unlock(void)
{
cvmx_spinlock_unlock((cvmx_spinlock_t *) &(cvmx_bootmem_desc->lock));
}
int cvmx_bootmem_init(void *mem_desc_ptr)
{
/* Here we set the global pointer to the bootmem descriptor
* block. This pointer will be used directly, so we will set
* it up to be directly usable by the application. It is set
* up as follows for the various runtime/ABI combinations:
*
* Linux 64 bit: Set XKPHYS bit
* Linux 32 bit: use mmap to create mapping, use virtual address
* CVMX 64 bit: use physical address directly
* CVMX 32 bit: use physical address directly
*
* Note that the CVMX environment assumes the use of 1-1 TLB
* mappings so that the physical addresses can be used
* directly
*/
if (!cvmx_bootmem_desc) {
#if defined(CVMX_ABI_64)
/* Set XKPHYS bit */
cvmx_bootmem_desc = cvmx_phys_to_ptr(CAST64(mem_desc_ptr));
#else
cvmx_bootmem_desc = (struct cvmx_bootmem_desc *) mem_desc_ptr;
#endif
}
return 0;
}
/*
* The cvmx_bootmem_phy* functions below return 64 bit physical
* addresses, and expose more features that the cvmx_bootmem_functions
* above. These are required for full memory space access in 32 bit
* applications, as well as for using some advance features. Most
* applications should not need to use these.
*/
int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min,
uint64_t address_max, uint64_t alignment,
uint32_t flags)
{
uint64_t head_addr;
uint64_t ent_addr;
/* points to previous list entry, NULL current entry is head of list */
uint64_t prev_addr = 0;
uint64_t new_ent_addr = 0;
uint64_t desired_min_addr;
#ifdef DEBUG
cvmx_dprintf("cvmx_bootmem_phy_alloc: req_size: 0x%llx, "
"min_addr: 0x%llx, max_addr: 0x%llx, align: 0x%llx\n",
(unsigned long long)req_size,
(unsigned long long)address_min,
(unsigned long long)address_max,
(unsigned long long)alignment);
#endif
if (cvmx_bootmem_desc->major_version > 3) {
cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
"version: %d.%d at addr: %p\n",
(int)cvmx_bootmem_desc->major_version,
(int)cvmx_bootmem_desc->minor_version,
cvmx_bootmem_desc);
goto error_out;
}
/*
* Do a variety of checks to validate the arguments. The
* allocator code will later assume that these checks have
* been made. We validate that the requested constraints are
* not self-contradictory before we look through the list of
* available memory.
*/
/* 0 is not a valid req_size for this allocator */
if (!req_size)
goto error_out;
/* Round req_size up to mult of minimum alignment bytes */
req_size = (req_size + (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1)) &
~(CVMX_BOOTMEM_ALIGNMENT_SIZE - 1);
/*
* Convert !0 address_min and 0 address_max to special case of
* range that specifies an exact memory block to allocate. Do
* this before other checks and adjustments so that this
* tranformation will be validated.
*/
if (address_min && !address_max)
address_max = address_min + req_size;
else if (!address_min && !address_max)
address_max = ~0ull; /* If no limits given, use max limits */
/*
* Enforce minimum alignment (this also keeps the minimum free block
* req_size the same as the alignment req_size.
*/
if (alignment < CVMX_BOOTMEM_ALIGNMENT_SIZE)
alignment = CVMX_BOOTMEM_ALIGNMENT_SIZE;
/*
* Adjust address minimum based on requested alignment (round
* up to meet alignment). Do this here so we can reject
* impossible requests up front. (NOP for address_min == 0)
*/
if (alignment)
address_min = __ALIGN_MASK(address_min, (alignment - 1));
/*
* Reject inconsistent args. We have adjusted these, so this
* may fail due to our internal changes even if this check
* would pass for the values the user supplied.
*/
if (req_size > address_max - address_min)
goto error_out;
/* Walk through the list entries - first fit found is returned */
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
cvmx_bootmem_lock();
head_addr = cvmx_bootmem_desc->head_addr;
ent_addr = head_addr;
for (; ent_addr;
prev_addr = ent_addr,
ent_addr = cvmx_bootmem_phy_get_next(ent_addr)) {
uint64_t usable_base, usable_max;
uint64_t ent_size = cvmx_bootmem_phy_get_size(ent_addr);
if (cvmx_bootmem_phy_get_next(ent_addr)
&& ent_addr > cvmx_bootmem_phy_get_next(ent_addr)) {
cvmx_dprintf("Internal bootmem_alloc() error: ent: "
"0x%llx, next: 0x%llx\n",
(unsigned long long)ent_addr,
(unsigned long long)
cvmx_bootmem_phy_get_next(ent_addr));
goto error_out;
}
/*
* Determine if this is an entry that can satisify the
* request Check to make sure entry is large enough to
* satisfy request.
*/
usable_base =
__ALIGN_MASK(max(address_min, ent_addr), alignment - 1);
usable_max = min(address_max, ent_addr + ent_size);
/*
* We should be able to allocate block at address
* usable_base.
*/
desired_min_addr = usable_base;
/*
* Determine if request can be satisfied from the
* current entry.
*/
if (!((ent_addr + ent_size) > usable_base
&& ent_addr < address_max
&& req_size <= usable_max - usable_base))
continue;
/*
* We have found an entry that has room to satisfy the
* request, so allocate it from this entry. If end
* CVMX_BOOTMEM_FLAG_END_ALLOC set, then allocate from
* the end of this block rather than the beginning.
*/
if (flags & CVMX_BOOTMEM_FLAG_END_ALLOC) {
desired_min_addr = usable_max - req_size;
/*
* Align desired address down to required
* alignment.
*/
desired_min_addr &= ~(alignment - 1);
}
/* Match at start of entry */
if (desired_min_addr == ent_addr) {
if (req_size < ent_size) {
/*
* big enough to create a new block
* from top portion of block.
*/
new_ent_addr = ent_addr + req_size;
cvmx_bootmem_phy_set_next(new_ent_addr,
cvmx_bootmem_phy_get_next(ent_addr));
cvmx_bootmem_phy_set_size(new_ent_addr,
ent_size -
req_size);
/*
* Adjust next pointer as following
* code uses this.
*/
cvmx_bootmem_phy_set_next(ent_addr,
new_ent_addr);
}
/*
* adjust prev ptr or head to remove this
* entry from list.
*/
if (prev_addr)
cvmx_bootmem_phy_set_next(prev_addr,
cvmx_bootmem_phy_get_next(ent_addr));
else
/*
* head of list being returned, so
* update head ptr.
*/
cvmx_bootmem_desc->head_addr =
cvmx_bootmem_phy_get_next(ent_addr);
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
cvmx_bootmem_unlock();
return desired_min_addr;
}
/*
* block returned doesn't start at beginning of entry,
* so we know that we will be splitting a block off
* the front of this one. Create a new block from the
* beginning, add to list, and go to top of loop
* again.
*
* create new block from high portion of
* block, so that top block starts at desired
* addr.
*/
new_ent_addr = desired_min_addr;
cvmx_bootmem_phy_set_next(new_ent_addr,
cvmx_bootmem_phy_get_next
(ent_addr));
cvmx_bootmem_phy_set_size(new_ent_addr,
cvmx_bootmem_phy_get_size
(ent_addr) -
(desired_min_addr -
ent_addr));
cvmx_bootmem_phy_set_size(ent_addr,
desired_min_addr - ent_addr);
cvmx_bootmem_phy_set_next(ent_addr, new_ent_addr);
/* Loop again to handle actual alloc from new block */
}
error_out:
/* We didn't find anything, so return error */
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
cvmx_bootmem_unlock();
return -1;
}
int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags)
{
uint64_t cur_addr;
uint64_t prev_addr = 0; /* zero is invalid */
int retval = 0;
#ifdef DEBUG
cvmx_dprintf("__cvmx_bootmem_phy_free addr: 0x%llx, size: 0x%llx\n",
(unsigned long long)phy_addr, (unsigned long long)size);
#endif
if (cvmx_bootmem_desc->major_version > 3) {
cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
"version: %d.%d at addr: %p\n",
(int)cvmx_bootmem_desc->major_version,
(int)cvmx_bootmem_desc->minor_version,
cvmx_bootmem_desc);
return 0;
}
/* 0 is not a valid size for this allocator */
if (!size)
return 0;
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
cvmx_bootmem_lock();
cur_addr = cvmx_bootmem_desc->head_addr;
if (cur_addr == 0 || phy_addr < cur_addr) {
/* add at front of list - special case with changing head ptr */
if (cur_addr && phy_addr + size > cur_addr)
goto bootmem_free_done; /* error, overlapping section */
else if (phy_addr + size == cur_addr) {
/* Add to front of existing first block */
cvmx_bootmem_phy_set_next(phy_addr,
cvmx_bootmem_phy_get_next
(cur_addr));
cvmx_bootmem_phy_set_size(phy_addr,
cvmx_bootmem_phy_get_size
(cur_addr) + size);
cvmx_bootmem_desc->head_addr = phy_addr;
} else {
/* New block before first block. OK if cur_addr is 0 */
cvmx_bootmem_phy_set_next(phy_addr, cur_addr);
cvmx_bootmem_phy_set_size(phy_addr, size);
cvmx_bootmem_desc->head_addr = phy_addr;
}
retval = 1;
goto bootmem_free_done;
}
/* Find place in list to add block */
while (cur_addr && phy_addr > cur_addr) {
prev_addr = cur_addr;
cur_addr = cvmx_bootmem_phy_get_next(cur_addr);
}
if (!cur_addr) {
/*
* We have reached the end of the list, add on to end,
* checking to see if we need to combine with last
* block
*/
if (prev_addr + cvmx_bootmem_phy_get_size(prev_addr) ==
phy_addr) {
cvmx_bootmem_phy_set_size(prev_addr,
cvmx_bootmem_phy_get_size
(prev_addr) + size);
} else {
cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
cvmx_bootmem_phy_set_size(phy_addr, size);
cvmx_bootmem_phy_set_next(phy_addr, 0);
}
retval = 1;
goto bootmem_free_done;
} else {
/*
* insert between prev and cur nodes, checking for
* merge with either/both.
*/
if (prev_addr + cvmx_bootmem_phy_get_size(prev_addr) ==
phy_addr) {
/* Merge with previous */
cvmx_bootmem_phy_set_size(prev_addr,
cvmx_bootmem_phy_get_size
(prev_addr) + size);
if (phy_addr + size == cur_addr) {
/* Also merge with current */
cvmx_bootmem_phy_set_size(prev_addr,
cvmx_bootmem_phy_get_size(cur_addr) +
cvmx_bootmem_phy_get_size(prev_addr));
cvmx_bootmem_phy_set_next(prev_addr,
cvmx_bootmem_phy_get_next(cur_addr));
}
retval = 1;
goto bootmem_free_done;
} else if (phy_addr + size == cur_addr) {
/* Merge with current */
cvmx_bootmem_phy_set_size(phy_addr,
cvmx_bootmem_phy_get_size
(cur_addr) + size);
cvmx_bootmem_phy_set_next(phy_addr,
cvmx_bootmem_phy_get_next
(cur_addr));
cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
retval = 1;
goto bootmem_free_done;
}
/* It is a standalone block, add in between prev and cur */
cvmx_bootmem_phy_set_size(phy_addr, size);
cvmx_bootmem_phy_set_next(phy_addr, cur_addr);
cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
}
retval = 1;
bootmem_free_done:
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
cvmx_bootmem_unlock();
return retval;
}
struct cvmx_bootmem_named_block_desc *
cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags)
{
unsigned int i;
struct cvmx_bootmem_named_block_desc *named_block_array_ptr;
#ifdef DEBUG
cvmx_dprintf("cvmx_bootmem_phy_named_block_find: %s\n", name);
#endif
/*
* Lock the structure to make sure that it is not being
* changed while we are examining it.
*/
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
cvmx_bootmem_lock();
/* Use XKPHYS for 64 bit linux */
named_block_array_ptr = (struct cvmx_bootmem_named_block_desc *)
cvmx_phys_to_ptr(cvmx_bootmem_desc->named_block_array_addr);
#ifdef DEBUG
cvmx_dprintf
("cvmx_bootmem_phy_named_block_find: named_block_array_ptr: %p\n",
named_block_array_ptr);
#endif
if (cvmx_bootmem_desc->major_version == 3) {
for (i = 0;
i < cvmx_bootmem_desc->named_block_num_blocks; i++) {
if ((name && named_block_array_ptr[i].size
&& !strncmp(name, named_block_array_ptr[i].name,
cvmx_bootmem_desc->named_block_name_len
- 1))
|| (!name && !named_block_array_ptr[i].size)) {
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
cvmx_bootmem_unlock();
return &(named_block_array_ptr[i]);
}
}
} else {
cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
"version: %d.%d at addr: %p\n",
(int)cvmx_bootmem_desc->major_version,
(int)cvmx_bootmem_desc->minor_version,
cvmx_bootmem_desc);
}
if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
cvmx_bootmem_unlock();
return NULL;
}
int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags)
{
struct cvmx_bootmem_named_block_desc *named_block_ptr;
if (cvmx_bootmem_desc->major_version != 3) {
cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: "
"%d.%d at addr: %p\n",
(int)cvmx_bootmem_desc->major_version,
(int)cvmx_bootmem_desc->minor_version,
cvmx_bootmem_desc);
return 0;
}
#ifdef DEBUG
cvmx_dprintf("cvmx_bootmem_phy_named_block_free: %s\n", name);
#endif
/*
* Take lock here, as name lookup/block free/name free need to
* be atomic.
*/
cvmx_bootmem_lock();
named_block_ptr =
cvmx_bootmem_phy_named_block_find(name,
CVMX_BOOTMEM_FLAG_NO_LOCKING);
if (named_block_ptr) {
#ifdef DEBUG
cvmx_dprintf("cvmx_bootmem_phy_named_block_free: "
"%s, base: 0x%llx, size: 0x%llx\n",
name,
(unsigned long long)named_block_ptr->base_addr,
(unsigned long long)named_block_ptr->size);
#endif
__cvmx_bootmem_phy_free(named_block_ptr->base_addr,
named_block_ptr->size,
CVMX_BOOTMEM_FLAG_NO_LOCKING);
named_block_ptr->size = 0;
/* Set size to zero to indicate block not used. */
}
cvmx_bootmem_unlock();
return named_block_ptr != NULL; /* 0 on failure, 1 on success */
}

View file

@ -0,0 +1,734 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* Implementation of the Level 2 Cache (L2C) control, measurement, and
* debugging facilities.
*/
#include <asm/octeon/cvmx.h>
#include <asm/octeon/cvmx-l2c.h>
#include <asm/octeon/cvmx-spinlock.h>
/*
* This spinlock is used internally to ensure that only one core is
* performing certain L2 operations at a time.
*
* NOTE: This only protects calls from within a single application -
* if multiple applications or operating systems are running, then it
* is up to the user program to coordinate between them.
*/
static cvmx_spinlock_t cvmx_l2c_spinlock;
static inline int l2_size_half(void)
{
uint64_t val = cvmx_read_csr(CVMX_L2D_FUS3);
return !!(val & (1ull << 34));
}
int cvmx_l2c_get_core_way_partition(uint32_t core)
{
uint32_t field;
/* Validate the core number */
if (core >= cvmx_octeon_num_cores())
return -1;
/*
* Use the lower two bits of the coreNumber to determine the
* bit offset of the UMSK[] field in the L2C_SPAR register.
*/
field = (core & 0x3) * 8;
/*
* Return the UMSK[] field from the appropriate L2C_SPAR
* register based on the coreNumber.
*/
switch (core & 0xC) {
case 0x0:
return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >>
field;
case 0x4:
return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >>
field;
case 0x8:
return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >>
field;
case 0xC:
return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >>
field;
}
return 0;
}
int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask)
{
uint32_t field;
uint32_t valid_mask;
valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1;
mask &= valid_mask;
/* A UMSK setting which blocks all L2C Ways is an error. */
if (mask == valid_mask)
return -1;
/* Validate the core number */
if (core >= cvmx_octeon_num_cores())
return -1;
/* Check to make sure current mask & new mask don't block all ways */
if (((mask | cvmx_l2c_get_core_way_partition(core)) & valid_mask) ==
valid_mask)
return -1;
/* Use the lower two bits of core to determine the bit offset of the
* UMSK[] field in the L2C_SPAR register.
*/
field = (core & 0x3) * 8;
/* Assign the new mask setting to the UMSK[] field in the appropriate
* L2C_SPAR register based on the core_num.
*
*/
switch (core & 0xC) {
case 0x0:
cvmx_write_csr(CVMX_L2C_SPAR0,
(cvmx_read_csr(CVMX_L2C_SPAR0) &
~(0xFF << field)) | mask << field);
break;
case 0x4:
cvmx_write_csr(CVMX_L2C_SPAR1,
(cvmx_read_csr(CVMX_L2C_SPAR1) &
~(0xFF << field)) | mask << field);
break;
case 0x8:
cvmx_write_csr(CVMX_L2C_SPAR2,
(cvmx_read_csr(CVMX_L2C_SPAR2) &
~(0xFF << field)) | mask << field);
break;
case 0xC:
cvmx_write_csr(CVMX_L2C_SPAR3,
(cvmx_read_csr(CVMX_L2C_SPAR3) &
~(0xFF << field)) | mask << field);
break;
}
return 0;
}
int cvmx_l2c_set_hw_way_partition(uint32_t mask)
{
uint32_t valid_mask;
valid_mask = 0xff;
if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN38XX)) {
if (l2_size_half())
valid_mask = 0xf;
} else if (l2_size_half())
valid_mask = 0x3;
mask &= valid_mask;
/* A UMSK setting which blocks all L2C Ways is an error. */
if (mask == valid_mask)
return -1;
/* Check to make sure current mask & new mask don't block all ways */
if (((mask | cvmx_l2c_get_hw_way_partition()) & valid_mask) ==
valid_mask)
return -1;
cvmx_write_csr(CVMX_L2C_SPAR4,
(cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
return 0;
}
int cvmx_l2c_get_hw_way_partition(void)
{
return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
}
void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event,
uint32_t clear_on_read)
{
union cvmx_l2c_pfctl pfctl;
pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
switch (counter) {
case 0:
pfctl.s.cnt0sel = event;
pfctl.s.cnt0ena = 1;
if (!cvmx_octeon_is_pass1())
pfctl.s.cnt0rdclr = clear_on_read;
break;
case 1:
pfctl.s.cnt1sel = event;
pfctl.s.cnt1ena = 1;
if (!cvmx_octeon_is_pass1())
pfctl.s.cnt1rdclr = clear_on_read;
break;
case 2:
pfctl.s.cnt2sel = event;
pfctl.s.cnt2ena = 1;
if (!cvmx_octeon_is_pass1())
pfctl.s.cnt2rdclr = clear_on_read;
break;
case 3:
default:
pfctl.s.cnt3sel = event;
pfctl.s.cnt3ena = 1;
if (!cvmx_octeon_is_pass1())
pfctl.s.cnt3rdclr = clear_on_read;
break;
}
cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
}
uint64_t cvmx_l2c_read_perf(uint32_t counter)
{
switch (counter) {
case 0:
return cvmx_read_csr(CVMX_L2C_PFC0);
case 1:
return cvmx_read_csr(CVMX_L2C_PFC1);
case 2:
return cvmx_read_csr(CVMX_L2C_PFC2);
case 3:
default:
return cvmx_read_csr(CVMX_L2C_PFC3);
}
}
/**
* @INTERNAL
* Helper function use to fault in cache lines for L2 cache locking
*
* @addr: Address of base of memory region to read into L2 cache
* @len: Length (in bytes) of region to fault in
*/
static void fault_in(uint64_t addr, int len)
{
volatile char *ptr;
volatile char dummy;
/*
* Adjust addr and length so we get all cache lines even for
* small ranges spanning two cache lines
*/
len += addr & CVMX_CACHE_LINE_MASK;
addr &= ~CVMX_CACHE_LINE_MASK;
ptr = (volatile char *)cvmx_phys_to_ptr(addr);
/*
* Invalidate L1 cache to make sure all loads result in data
* being in L2.
*/
CVMX_DCACHE_INVALIDATE;
while (len > 0) {
dummy += *ptr;
len -= CVMX_CACHE_LINE_SIZE;
ptr += CVMX_CACHE_LINE_SIZE;
}
}
int cvmx_l2c_lock_line(uint64_t addr)
{
int retval = 0;
union cvmx_l2c_dbg l2cdbg;
union cvmx_l2c_lckbase lckbase;
union cvmx_l2c_lckoff lckoff;
union cvmx_l2t_err l2t_err;
l2cdbg.u64 = 0;
lckbase.u64 = 0;
lckoff.u64 = 0;
cvmx_spinlock_lock(&cvmx_l2c_spinlock);
/* Clear l2t error bits if set */
l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
l2t_err.s.lckerr = 1;
l2t_err.s.lckerr2 = 1;
cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
addr &= ~CVMX_CACHE_LINE_MASK;
/* Set this core as debug core */
l2cdbg.s.ppnum = cvmx_get_core_num();
CVMX_SYNC;
cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
cvmx_read_csr(CVMX_L2C_DBG);
lckoff.s.lck_offset = 0; /* Only lock 1 line at a time */
cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
cvmx_read_csr(CVMX_L2C_LCKOFF);
if (((union cvmx_l2c_cfg) (cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
int alias_shift =
CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
uint64_t addr_tmp =
addr ^ (addr & ((1 << alias_shift) - 1)) >>
CVMX_L2_SET_BITS;
lckbase.s.lck_base = addr_tmp >> 7;
} else {
lckbase.s.lck_base = addr >> 7;
}
lckbase.s.lck_ena = 1;
cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
cvmx_read_csr(CVMX_L2C_LCKBASE); /* Make sure it gets there */
fault_in(addr, CVMX_CACHE_LINE_SIZE);
lckbase.s.lck_ena = 0;
cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
cvmx_read_csr(CVMX_L2C_LCKBASE); /* Make sure it gets there */
/* Stop being debug core */
cvmx_write_csr(CVMX_L2C_DBG, 0);
cvmx_read_csr(CVMX_L2C_DBG);
l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
retval = 1; /* We were unable to lock the line */
cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
return retval;
}
int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
{
int retval = 0;
/* Round start/end to cache line boundaries */
len += start & CVMX_CACHE_LINE_MASK;
start &= ~CVMX_CACHE_LINE_MASK;
len = (len + CVMX_CACHE_LINE_MASK) & ~CVMX_CACHE_LINE_MASK;
while (len) {
retval += cvmx_l2c_lock_line(start);
start += CVMX_CACHE_LINE_SIZE;
len -= CVMX_CACHE_LINE_SIZE;
}
return retval;
}
void cvmx_l2c_flush(void)
{
uint64_t assoc, set;
uint64_t n_assoc, n_set;
union cvmx_l2c_dbg l2cdbg;
cvmx_spinlock_lock(&cvmx_l2c_spinlock);
l2cdbg.u64 = 0;
if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
l2cdbg.s.ppnum = cvmx_get_core_num();
l2cdbg.s.finv = 1;
n_set = CVMX_L2_SETS;
n_assoc = l2_size_half() ? (CVMX_L2_ASSOC / 2) : CVMX_L2_ASSOC;
for (set = 0; set < n_set; set++) {
for (assoc = 0; assoc < n_assoc; assoc++) {
l2cdbg.s.set = assoc;
/* Enter debug mode, and make sure all other
** writes complete before we enter debug
** mode */
CVMX_SYNCW;
cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
cvmx_read_csr(CVMX_L2C_DBG);
CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
(CVMX_MIPS_SPACE_XKPHYS,
set * CVMX_CACHE_LINE_SIZE), 0);
CVMX_SYNCW; /* Push STF out to L2 */
/* Exit debug mode */
CVMX_SYNC;
cvmx_write_csr(CVMX_L2C_DBG, 0);
cvmx_read_csr(CVMX_L2C_DBG);
}
}
cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
}
int cvmx_l2c_unlock_line(uint64_t address)
{
int assoc;
union cvmx_l2c_tag tag;
union cvmx_l2c_dbg l2cdbg;
uint32_t tag_addr;
uint32_t index = cvmx_l2c_address_to_index(address);
cvmx_spinlock_lock(&cvmx_l2c_spinlock);
/* Compute portion of address that is stored in tag */
tag_addr =
((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) &
((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
tag = cvmx_get_l2c_tag(assoc, index);
if (tag.s.V && (tag.s.addr == tag_addr)) {
l2cdbg.u64 = 0;
l2cdbg.s.ppnum = cvmx_get_core_num();
l2cdbg.s.set = assoc;
l2cdbg.s.finv = 1;
CVMX_SYNC;
/* Enter debug mode */
cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
cvmx_read_csr(CVMX_L2C_DBG);
CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
(CVMX_MIPS_SPACE_XKPHYS,
address), 0);
CVMX_SYNC;
/* Exit debug mode */
cvmx_write_csr(CVMX_L2C_DBG, 0);
cvmx_read_csr(CVMX_L2C_DBG);
cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
return tag.s.L;
}
}
cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
return 0;
}
int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len)
{
int num_unlocked = 0;
/* Round start/end to cache line boundaries */
len += start & CVMX_CACHE_LINE_MASK;
start &= ~CVMX_CACHE_LINE_MASK;
len = (len + CVMX_CACHE_LINE_MASK) & ~CVMX_CACHE_LINE_MASK;
while (len > 0) {
num_unlocked += cvmx_l2c_unlock_line(start);
start += CVMX_CACHE_LINE_SIZE;
len -= CVMX_CACHE_LINE_SIZE;
}
return num_unlocked;
}
/*
* Internal l2c tag types. These are converted to a generic structure
* that can be used on all chips.
*/
union __cvmx_l2c_tag {
uint64_t u64;
struct cvmx_l2c_tag_cn50xx {
uint64_t reserved:40;
uint64_t V:1; /* Line valid */
uint64_t D:1; /* Line dirty */
uint64_t L:1; /* Line locked */
uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:20; /* Phys mem addr (33..14) */
} cn50xx;
struct cvmx_l2c_tag_cn30xx {
uint64_t reserved:41;
uint64_t V:1; /* Line valid */
uint64_t D:1; /* Line dirty */
uint64_t L:1; /* Line locked */
uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:19; /* Phys mem addr (33..15) */
} cn30xx;
struct cvmx_l2c_tag_cn31xx {
uint64_t reserved:42;
uint64_t V:1; /* Line valid */
uint64_t D:1; /* Line dirty */
uint64_t L:1; /* Line locked */
uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:18; /* Phys mem addr (33..16) */
} cn31xx;
struct cvmx_l2c_tag_cn38xx {
uint64_t reserved:43;
uint64_t V:1; /* Line valid */
uint64_t D:1; /* Line dirty */
uint64_t L:1; /* Line locked */
uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:17; /* Phys mem addr (33..17) */
} cn38xx;
struct cvmx_l2c_tag_cn58xx {
uint64_t reserved:44;
uint64_t V:1; /* Line valid */
uint64_t D:1; /* Line dirty */
uint64_t L:1; /* Line locked */
uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:16; /* Phys mem addr (33..18) */
} cn58xx;
struct cvmx_l2c_tag_cn58xx cn56xx; /* 2048 sets */
struct cvmx_l2c_tag_cn31xx cn52xx; /* 512 sets */
};
/**
* @INTERNAL
* Function to read a L2C tag. This code make the current core
* the 'debug core' for the L2. This code must only be executed by
* 1 core at a time.
*
* @assoc: Association (way) of the tag to dump
* @index: Index of the cacheline
*
* Returns The Octeon model specific tag structure. This is
* translated by a wrapper function to a generic form that is
* easier for applications to use.
*/
static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
{
uint64_t debug_tag_addr = (((1ULL << 63) | (index << 7)) + 96);
uint64_t core = cvmx_get_core_num();
union __cvmx_l2c_tag tag_val;
uint64_t dbg_addr = CVMX_L2C_DBG;
unsigned long flags;
union cvmx_l2c_dbg debug_val;
debug_val.u64 = 0;
/*
* For low core count parts, the core number is always small enough
* to stay in the correct field and not set any reserved bits.
*/
debug_val.s.ppnum = core;
debug_val.s.l2t = 1;
debug_val.s.set = assoc;
/*
* Make sure core is quiet (no prefetches, etc.) before
* entering debug mode.
*/
CVMX_SYNC;
/* Flush L1 to make sure debug load misses L1 */
CVMX_DCACHE_INVALIDATE;
local_irq_save(flags);
/*
* The following must be done in assembly as when in debug
* mode all data loads from L2 return special debug data, not
* normal memory contents. Also, interrupts must be
* disabled, since if an interrupt occurs while in debug mode
* the ISR will get debug data from all its memory reads
* instead of the contents of memory
*/
asm volatile (".set push \n"
" .set mips64 \n"
" .set noreorder \n"
/* Enter debug mode, wait for store */
" sd %[dbg_val], 0(%[dbg_addr]) \n"
" ld $0, 0(%[dbg_addr]) \n"
/* Read L2C tag data */
" ld %[tag_val], 0(%[tag_addr]) \n"
/* Exit debug mode, wait for store */
" sd $0, 0(%[dbg_addr]) \n"
" ld $0, 0(%[dbg_addr]) \n"
/* Invalidate dcache to discard debug data */
" cache 9, 0($0) \n"
" .set pop" :
[tag_val] "=r"(tag_val.u64) : [dbg_addr] "r"(dbg_addr),
[dbg_val] "r"(debug_val.u64),
[tag_addr] "r"(debug_tag_addr) : "memory");
local_irq_restore(flags);
return tag_val;
}
union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index)
{
union __cvmx_l2c_tag tmp_tag;
union cvmx_l2c_tag tag;
tag.u64 = 0;
if ((int)association >= cvmx_l2c_get_num_assoc()) {
cvmx_dprintf
("ERROR: cvmx_get_l2c_tag association out of range\n");
return tag;
}
if ((int)index >= cvmx_l2c_get_num_sets()) {
cvmx_dprintf("ERROR: cvmx_get_l2c_tag "
"index out of range (arg: %d, max: %d\n",
index, cvmx_l2c_get_num_sets());
return tag;
}
/* __read_l2_tag is intended for internal use only */
tmp_tag = __read_l2_tag(association, index);
/*
* Convert all tag structure types to generic version, as it
* can represent all models.
*/
if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
tag.s.V = tmp_tag.cn58xx.V;
tag.s.D = tmp_tag.cn58xx.D;
tag.s.L = tmp_tag.cn58xx.L;
tag.s.U = tmp_tag.cn58xx.U;
tag.s.addr = tmp_tag.cn58xx.addr;
} else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
tag.s.V = tmp_tag.cn38xx.V;
tag.s.D = tmp_tag.cn38xx.D;
tag.s.L = tmp_tag.cn38xx.L;
tag.s.U = tmp_tag.cn38xx.U;
tag.s.addr = tmp_tag.cn38xx.addr;
} else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
|| OCTEON_IS_MODEL(OCTEON_CN52XX)) {
tag.s.V = tmp_tag.cn31xx.V;
tag.s.D = tmp_tag.cn31xx.D;
tag.s.L = tmp_tag.cn31xx.L;
tag.s.U = tmp_tag.cn31xx.U;
tag.s.addr = tmp_tag.cn31xx.addr;
} else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
tag.s.V = tmp_tag.cn30xx.V;
tag.s.D = tmp_tag.cn30xx.D;
tag.s.L = tmp_tag.cn30xx.L;
tag.s.U = tmp_tag.cn30xx.U;
tag.s.addr = tmp_tag.cn30xx.addr;
} else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
tag.s.V = tmp_tag.cn50xx.V;
tag.s.D = tmp_tag.cn50xx.D;
tag.s.L = tmp_tag.cn50xx.L;
tag.s.U = tmp_tag.cn50xx.U;
tag.s.addr = tmp_tag.cn50xx.addr;
} else {
cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
}
return tag;
}
uint32_t cvmx_l2c_address_to_index(uint64_t addr)
{
uint64_t idx = addr >> CVMX_L2C_IDX_ADDR_SHIFT;
union cvmx_l2c_cfg l2c_cfg;
l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
if (l2c_cfg.s.idxalias) {
idx ^=
((addr & CVMX_L2C_ALIAS_MASK) >>
CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
}
idx &= CVMX_L2C_IDX_MASK;
return idx;
}
int cvmx_l2c_get_cache_size_bytes(void)
{
return cvmx_l2c_get_num_sets() * cvmx_l2c_get_num_assoc() *
CVMX_CACHE_LINE_SIZE;
}
/**
* Return log base 2 of the number of sets in the L2 cache
* Returns
*/
int cvmx_l2c_get_set_bits(void)
{
int l2_set_bits;
if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
l2_set_bits = 11; /* 2048 sets */
else if (OCTEON_IS_MODEL(OCTEON_CN38XX))
l2_set_bits = 10; /* 1024 sets */
else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
|| OCTEON_IS_MODEL(OCTEON_CN52XX))
l2_set_bits = 9; /* 512 sets */
else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
l2_set_bits = 8; /* 256 sets */
else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
l2_set_bits = 7; /* 128 sets */
else {
cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
l2_set_bits = 11; /* 2048 sets */
}
return l2_set_bits;
}
/* Return the number of sets in the L2 Cache */
int cvmx_l2c_get_num_sets(void)
{
return 1 << cvmx_l2c_get_set_bits();
}
/* Return the number of associations in the L2 Cache */
int cvmx_l2c_get_num_assoc(void)
{
int l2_assoc;
if (OCTEON_IS_MODEL(OCTEON_CN56XX) ||
OCTEON_IS_MODEL(OCTEON_CN52XX) ||
OCTEON_IS_MODEL(OCTEON_CN58XX) ||
OCTEON_IS_MODEL(OCTEON_CN50XX) || OCTEON_IS_MODEL(OCTEON_CN38XX))
l2_assoc = 8;
else if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
OCTEON_IS_MODEL(OCTEON_CN30XX))
l2_assoc = 4;
else {
cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
l2_assoc = 8;
}
/* Check to see if part of the cache is disabled */
if (cvmx_fuse_read(265))
l2_assoc = l2_assoc >> 2;
else if (cvmx_fuse_read(264))
l2_assoc = l2_assoc >> 1;
return l2_assoc;
}
/**
* Flush a line from the L2 cache
* This should only be called from one core at a time, as this routine
* sets the core to the 'debug' core in order to flush the line.
*
* @assoc: Association (or way) to flush
* @index: Index to flush
*/
void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index)
{
union cvmx_l2c_dbg l2cdbg;
l2cdbg.u64 = 0;
l2cdbg.s.ppnum = cvmx_get_core_num();
l2cdbg.s.finv = 1;
l2cdbg.s.set = assoc;
/*
* Enter debug mode, and make sure all other writes complete
* before we enter debug mode.
*/
asm volatile ("sync" : : : "memory");
cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
cvmx_read_csr(CVMX_L2C_DBG);
CVMX_PREPARE_FOR_STORE(((1ULL << 63) + (index) * 128), 0);
/* Exit debug mode */
asm volatile ("sync" : : : "memory");
cvmx_write_csr(CVMX_L2C_DBG, 0);
cvmx_read_csr(CVMX_L2C_DBG);
}

View file

@ -0,0 +1,116 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* This module provides system/board/application information obtained
* by the bootloader.
*/
#include <asm/octeon/cvmx.h>
#include <asm/octeon/cvmx-spinlock.h>
#include <asm/octeon/cvmx-sysinfo.h>
/**
* This structure defines the private state maintained by sysinfo module.
*
*/
static struct {
struct cvmx_sysinfo sysinfo; /* system information */
cvmx_spinlock_t lock; /* mutex spinlock */
} state = {
.lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER
};
/*
* Global variables that define the min/max of the memory region set
* up for 32 bit userspace access.
*/
uint64_t linux_mem32_min;
uint64_t linux_mem32_max;
uint64_t linux_mem32_wired;
uint64_t linux_mem32_offset;
/**
* This function returns the application information as obtained
* by the bootloader. This provides the core mask of the cores
* running the same application image, as well as the physical
* memory regions available to the core.
*
* Returns Pointer to the boot information structure
*
*/
struct cvmx_sysinfo *cvmx_sysinfo_get(void)
{
return &(state.sysinfo);
}
/**
* This function is used in non-simple executive environments (such as
* Linux kernel, u-boot, etc.) to configure the minimal fields that
* are required to use simple executive files directly.
*
* Locking (if required) must be handled outside of this
* function
*
* @phy_mem_desc_ptr:
* Pointer to global physical memory descriptor
* (bootmem descriptor) @board_type: Octeon board
* type enumeration
*
* @board_rev_major:
* Board major revision
* @board_rev_minor:
* Board minor revision
* @cpu_clock_hz:
* CPU clock freqency in hertz
*
* Returns 0: Failure
* 1: success
*/
int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr,
uint16_t board_type,
uint8_t board_rev_major,
uint8_t board_rev_minor,
uint32_t cpu_clock_hz)
{
/* The sysinfo structure was already initialized */
if (state.sysinfo.board_type)
return 0;
memset(&(state.sysinfo), 0x0, sizeof(state.sysinfo));
state.sysinfo.phy_mem_desc_ptr = phy_mem_desc_ptr;
state.sysinfo.board_type = board_type;
state.sysinfo.board_rev_major = board_rev_major;
state.sysinfo.board_rev_minor = board_rev_minor;
state.sysinfo.cpu_clock_hz = cpu_clock_hz;
return 1;
}

View file

@ -0,0 +1,358 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* File defining functions for working with different Octeon
* models.
*/
#include <asm/octeon/octeon.h>
/**
* Given the chip processor ID from COP0, this function returns a
* string representing the chip model number. The string is of the
* form CNXXXXpX.X-FREQ-SUFFIX.
* - XXXX = The chip model number
* - X.X = Chip pass number
* - FREQ = Current frequency in Mhz
* - SUFFIX = NSP, EXP, SCP, SSP, or CP
*
* @chip_id: Chip ID
*
* Returns Model string
*/
const char *octeon_model_get_string(uint32_t chip_id)
{
static char buffer[32];
return octeon_model_get_string_buffer(chip_id, buffer);
}
/*
* Version of octeon_model_get_string() that takes buffer as argument,
* as running early in u-boot static/global variables don't work when
* running from flash.
*/
const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
{
const char *family;
const char *core_model;
char pass[4];
int clock_mhz;
const char *suffix;
union cvmx_l2d_fus3 fus3;
int num_cores;
union cvmx_mio_fus_dat2 fus_dat2;
union cvmx_mio_fus_dat3 fus_dat3;
char fuse_model[10];
uint32_t fuse_data = 0;
fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
num_cores = cvmx_octeon_num_cores();
/* Make sure the non existant devices look disabled */
switch ((chip_id >> 8) & 0xff) {
case 6: /* CN50XX */
case 2: /* CN30XX */
fus_dat3.s.nodfa_dte = 1;
fus_dat3.s.nozip = 1;
break;
case 4: /* CN57XX or CN56XX */
fus_dat3.s.nodfa_dte = 1;
break;
default:
break;
}
/* Make a guess at the suffix */
/* NSP = everything */
/* EXP = No crypto */
/* SCP = No DFA, No zip */
/* CP = No DFA, No crypto, No zip */
if (fus_dat3.s.nodfa_dte) {
if (fus_dat2.s.nocrypto)
suffix = "CP";
else
suffix = "SCP";
} else if (fus_dat2.s.nocrypto)
suffix = "EXP";
else
suffix = "NSP";
/*
* Assume pass number is encoded using <5:3><2:0>. Exceptions
* will be fixed later.
*/
sprintf(pass, "%u.%u", ((chip_id >> 3) & 7) + 1, chip_id & 7);
/*
* Use the number of cores to determine the last 2 digits of
* the model number. There are some exceptions that are fixed
* later.
*/
switch (num_cores) {
case 16:
core_model = "60";
break;
case 15:
core_model = "58";
break;
case 14:
core_model = "55";
break;
case 13:
core_model = "52";
break;
case 12:
core_model = "50";
break;
case 11:
core_model = "48";
break;
case 10:
core_model = "45";
break;
case 9:
core_model = "42";
break;
case 8:
core_model = "40";
break;
case 7:
core_model = "38";
break;
case 6:
core_model = "34";
break;
case 5:
core_model = "32";
break;
case 4:
core_model = "30";
break;
case 3:
core_model = "25";
break;
case 2:
core_model = "20";
break;
case 1:
core_model = "10";
break;
default:
core_model = "XX";
break;
}
/* Now figure out the family, the first two digits */
switch ((chip_id >> 8) & 0xff) {
case 0: /* CN38XX, CN37XX or CN36XX */
if (fus3.cn38xx.crip_512k) {
/*
* For some unknown reason, the 16 core one is
* called 37 instead of 36.
*/
if (num_cores >= 16)
family = "37";
else
family = "36";
} else
family = "38";
/*
* This series of chips didn't follow the standard
* pass numbering.
*/
switch (chip_id & 0xf) {
case 0:
strcpy(pass, "1.X");
break;
case 1:
strcpy(pass, "2.X");
break;
case 3:
strcpy(pass, "3.X");
break;
default:
strcpy(pass, "X.X");
break;
}
break;
case 1: /* CN31XX or CN3020 */
if ((chip_id & 0x10) || fus3.cn31xx.crip_128k)
family = "30";
else
family = "31";
/*
* This series of chips didn't follow the standard
* pass numbering.
*/
switch (chip_id & 0xf) {
case 0:
strcpy(pass, "1.0");
break;
case 2:
strcpy(pass, "1.1");
break;
default:
strcpy(pass, "X.X");
break;
}
break;
case 2: /* CN3010 or CN3005 */
family = "30";
/* A chip with half cache is an 05 */
if (fus3.cn30xx.crip_64k)
core_model = "05";
/*
* This series of chips didn't follow the standard
* pass numbering.
*/
switch (chip_id & 0xf) {
case 0:
strcpy(pass, "1.0");
break;
case 2:
strcpy(pass, "1.1");
break;
default:
strcpy(pass, "X.X");
break;
}
break;
case 3: /* CN58XX */
family = "58";
/* Special case. 4 core, no crypto */
if ((num_cores == 4) && fus_dat2.cn38xx.nocrypto)
core_model = "29";
/* Pass 1 uses different encodings for pass numbers */
if ((chip_id & 0xFF) < 0x8) {
switch (chip_id & 0x3) {
case 0:
strcpy(pass, "1.0");
break;
case 1:
strcpy(pass, "1.1");
break;
case 3:
strcpy(pass, "1.2");
break;
default:
strcpy(pass, "1.X");
break;
}
}
break;
case 4: /* CN57XX, CN56XX, CN55XX, CN54XX */
if (fus_dat2.cn56xx.raid_en) {
if (fus3.cn56xx.crip_1024k)
family = "55";
else
family = "57";
if (fus_dat2.cn56xx.nocrypto)
suffix = "SP";
else
suffix = "SSP";
} else {
if (fus_dat2.cn56xx.nocrypto)
suffix = "CP";
else {
suffix = "NSP";
if (fus_dat3.s.nozip)
suffix = "SCP";
}
if (fus3.cn56xx.crip_1024k)
family = "54";
else
family = "56";
}
break;
case 6: /* CN50XX */
family = "50";
break;
case 7: /* CN52XX */
if (fus3.cn52xx.crip_256k)
family = "51";
else
family = "52";
break;
default:
family = "XX";
core_model = "XX";
strcpy(pass, "X.X");
suffix = "XXX";
break;
}
clock_mhz = octeon_get_clock_rate() / 1000000;
if (family[0] != '3') {
/* Check for model in fuses, overrides normal decode */
/* This is _not_ valid for Octeon CN3XXX models */
fuse_data |= cvmx_fuse_read_byte(51);
fuse_data = fuse_data << 8;
fuse_data |= cvmx_fuse_read_byte(50);
fuse_data = fuse_data << 8;
fuse_data |= cvmx_fuse_read_byte(49);
fuse_data = fuse_data << 8;
fuse_data |= cvmx_fuse_read_byte(48);
if (fuse_data & 0x7ffff) {
int model = fuse_data & 0x3fff;
int suffix = (fuse_data >> 14) & 0x1f;
if (suffix && model) {
/*
* Have both number and suffix in
* fuses, so both
*/
sprintf(fuse_model, "%d%c",
model, 'A' + suffix - 1);
core_model = "";
family = fuse_model;
} else if (suffix && !model) {
/*
* Only have suffix, so add suffix to
* 'normal' model number.
*/
sprintf(fuse_model, "%s%c", core_model,
'A' + suffix - 1);
core_model = fuse_model;
} else {
/*
* Don't have suffix, so just use
* model from fuses.
*/
sprintf(fuse_model, "%d", model);
core_model = "";
family = fuse_model;
}
}
}
sprintf(buffer, "CN%s%sp%s-%d-%s",
family, core_model, pass, clock_mhz, suffix);
return buffer;
}

View file

@ -0,0 +1,84 @@
/*
* Octeon Bootbus flash setup
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2007, 2008 Cavium Networks
*/
#include <linux/kernel.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/map.h>
#include <linux/mtd/partitions.h>
#include <asm/octeon/octeon.h>
static struct map_info flash_map;
static struct mtd_info *mymtd;
#ifdef CONFIG_MTD_PARTITIONS
static int nr_parts;
static struct mtd_partition *parts;
static const char *part_probe_types[] = {
"cmdlinepart",
#ifdef CONFIG_MTD_REDBOOT_PARTS
"RedBoot",
#endif
NULL
};
#endif
/**
* Module/ driver initialization.
*
* Returns Zero on success
*/
static int __init flash_init(void)
{
/*
* Read the bootbus region 0 setup to determine the base
* address of the flash.
*/
union cvmx_mio_boot_reg_cfgx region_cfg;
region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0));
if (region_cfg.s.en) {
/*
* The bootloader always takes the flash and sets its
* address so the entire flash fits below
* 0x1fc00000. This way the flash aliases to
* 0x1fc00000 for booting. Software can access the
* full flash at the true address, while core boot can
* access 4MB.
*/
/* Use this name so old part lines work */
flash_map.name = "phys_mapped_flash";
flash_map.phys = region_cfg.s.base << 16;
flash_map.size = 0x1fc00000 - flash_map.phys;
flash_map.bankwidth = 1;
flash_map.virt = ioremap(flash_map.phys, flash_map.size);
pr_notice("Bootbus flash: Setting flash for %luMB flash at "
"0x%08lx\n", flash_map.size >> 20, flash_map.phys);
simple_map_init(&flash_map);
mymtd = do_map_probe("cfi_probe", &flash_map);
if (mymtd) {
mymtd->owner = THIS_MODULE;
#ifdef CONFIG_MTD_PARTITIONS
nr_parts = parse_mtd_partitions(mymtd,
part_probe_types,
&parts, 0);
if (nr_parts > 0)
add_mtd_partitions(mymtd, parts, nr_parts);
else
add_mtd_device(mymtd);
#else
add_mtd_device(mymtd);
#endif
} else {
pr_err("Failed to register MTD device for flash\n");
}
}
return 0;
}
late_initcall(flash_init);

View file

@ -0,0 +1,497 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004-2008 Cavium Networks
*/
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/hardirq.h>
#include <asm/octeon/octeon.h>
DEFINE_RWLOCK(octeon_irq_ciu0_rwlock);
DEFINE_RWLOCK(octeon_irq_ciu1_rwlock);
DEFINE_SPINLOCK(octeon_irq_msi_lock);
static void octeon_irq_core_ack(unsigned int irq)
{
unsigned int bit = irq - OCTEON_IRQ_SW0;
/*
* We don't need to disable IRQs to make these atomic since
* they are already disabled earlier in the low level
* interrupt code.
*/
clear_c0_status(0x100 << bit);
/* The two user interrupts must be cleared manually. */
if (bit < 2)
clear_c0_cause(0x100 << bit);
}
static void octeon_irq_core_eoi(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
unsigned int bit = irq - OCTEON_IRQ_SW0;
/*
* If an IRQ is being processed while we are disabling it the
* handler will attempt to unmask the interrupt after it has
* been disabled.
*/
if (desc->status & IRQ_DISABLED)
return;
/* There is a race here. We should fix it. */
/*
* We don't need to disable IRQs to make these atomic since
* they are already disabled earlier in the low level
* interrupt code.
*/
set_c0_status(0x100 << bit);
}
static void octeon_irq_core_enable(unsigned int irq)
{
unsigned long flags;
unsigned int bit = irq - OCTEON_IRQ_SW0;
/*
* We need to disable interrupts to make sure our updates are
* atomic.
*/
local_irq_save(flags);
set_c0_status(0x100 << bit);
local_irq_restore(flags);
}
static void octeon_irq_core_disable_local(unsigned int irq)
{
unsigned long flags;
unsigned int bit = irq - OCTEON_IRQ_SW0;
/*
* We need to disable interrupts to make sure our updates are
* atomic.
*/
local_irq_save(flags);
clear_c0_status(0x100 << bit);
local_irq_restore(flags);
}
static void octeon_irq_core_disable(unsigned int irq)
{
#ifdef CONFIG_SMP
on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local,
(void *) (long) irq, 1);
#else
octeon_irq_core_disable_local(irq);
#endif
}
static struct irq_chip octeon_irq_chip_core = {
.name = "Core",
.enable = octeon_irq_core_enable,
.disable = octeon_irq_core_disable,
.ack = octeon_irq_core_ack,
.eoi = octeon_irq_core_eoi,
};
static void octeon_irq_ciu0_ack(unsigned int irq)
{
/*
* In order to avoid any locking accessing the CIU, we
* acknowledge CIU interrupts by disabling all of them. This
* way we can use a per core register and avoid any out of
* core locking requirements. This has the side affect that
* CIU interrupts can't be processed recursively.
*
* We don't need to disable IRQs to make these atomic since
* they are already disabled earlier in the low level
* interrupt code.
*/
clear_c0_status(0x100 << 2);
}
static void octeon_irq_ciu0_eoi(unsigned int irq)
{
/*
* Enable all CIU interrupts again. We don't need to disable
* IRQs to make these atomic since they are already disabled
* earlier in the low level interrupt code.
*/
set_c0_status(0x100 << 2);
}
static void octeon_irq_ciu0_enable(unsigned int irq)
{
int coreid = cvmx_get_core_num();
unsigned long flags;
uint64_t en0;
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
/*
* A read lock is used here to make sure only one core is ever
* updating the CIU enable bits at a time. During an enable
* the cores don't interfere with each other. During a disable
* the write lock stops any enables that might cause a
* problem.
*/
read_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
en0 |= 1ull << bit;
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
read_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
}
static void octeon_irq_ciu0_disable(unsigned int irq)
{
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
unsigned long flags;
uint64_t en0;
#ifdef CONFIG_SMP
int cpu;
write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu);
en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
en0 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
}
/*
* We need to do a read after the last update to make sure all
* of them are done.
*/
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
#else
int coreid = cvmx_get_core_num();
local_irq_save(flags);
en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
en0 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
local_irq_restore(flags);
#endif
}
#ifdef CONFIG_SMP
static void octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
{
int cpu;
int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
write_lock(&octeon_irq_ciu0_rwlock);
for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu);
uint64_t en0 =
cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
if (cpumask_test_cpu(cpu, dest))
en0 |= 1ull << bit;
else
en0 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
}
/*
* We need to do a read after the last update to make sure all
* of them are done.
*/
cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
write_unlock(&octeon_irq_ciu0_rwlock);
}
#endif
static struct irq_chip octeon_irq_chip_ciu0 = {
.name = "CIU0",
.enable = octeon_irq_ciu0_enable,
.disable = octeon_irq_ciu0_disable,
.ack = octeon_irq_ciu0_ack,
.eoi = octeon_irq_ciu0_eoi,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu0_set_affinity,
#endif
};
static void octeon_irq_ciu1_ack(unsigned int irq)
{
/*
* In order to avoid any locking accessing the CIU, we
* acknowledge CIU interrupts by disabling all of them. This
* way we can use a per core register and avoid any out of
* core locking requirements. This has the side affect that
* CIU interrupts can't be processed recursively. We don't
* need to disable IRQs to make these atomic since they are
* already disabled earlier in the low level interrupt code.
*/
clear_c0_status(0x100 << 3);
}
static void octeon_irq_ciu1_eoi(unsigned int irq)
{
/*
* Enable all CIU interrupts again. We don't need to disable
* IRQs to make these atomic since they are already disabled
* earlier in the low level interrupt code.
*/
set_c0_status(0x100 << 3);
}
static void octeon_irq_ciu1_enable(unsigned int irq)
{
int coreid = cvmx_get_core_num();
unsigned long flags;
uint64_t en1;
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
/*
* A read lock is used here to make sure only one core is ever
* updating the CIU enable bits at a time. During an enable
* the cores don't interfere with each other. During a disable
* the write lock stops any enables that might cause a
* problem.
*/
read_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
en1 |= 1ull << bit;
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
read_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
}
static void octeon_irq_ciu1_disable(unsigned int irq)
{
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
unsigned long flags;
uint64_t en1;
#ifdef CONFIG_SMP
int cpu;
write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu);
en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
en1 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
}
/*
* We need to do a read after the last update to make sure all
* of them are done.
*/
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
#else
int coreid = cvmx_get_core_num();
local_irq_save(flags);
en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
en1 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
local_irq_restore(flags);
#endif
}
#ifdef CONFIG_SMP
static void octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
{
int cpu;
int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
write_lock(&octeon_irq_ciu1_rwlock);
for_each_online_cpu(cpu) {
int coreid = cpu_logical_map(cpu);
uint64_t en1 =
cvmx_read_csr(CVMX_CIU_INTX_EN1
(coreid * 2 + 1));
if (cpumask_test_cpu(cpu, dest))
en1 |= 1ull << bit;
else
en1 &= ~(1ull << bit);
cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
}
/*
* We need to do a read after the last update to make sure all
* of them are done.
*/
cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
write_unlock(&octeon_irq_ciu1_rwlock);
}
#endif
static struct irq_chip octeon_irq_chip_ciu1 = {
.name = "CIU1",
.enable = octeon_irq_ciu1_enable,
.disable = octeon_irq_ciu1_disable,
.ack = octeon_irq_ciu1_ack,
.eoi = octeon_irq_ciu1_eoi,
#ifdef CONFIG_SMP
.set_affinity = octeon_irq_ciu1_set_affinity,
#endif
};
#ifdef CONFIG_PCI_MSI
static void octeon_irq_msi_ack(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/* These chips have PCI */
cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
1ull << (irq - OCTEON_IRQ_MSI_BIT0));
} else {
/*
* These chips have PCIe. Thankfully the ACK doesn't
* need any locking.
*/
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
1ull << (irq - OCTEON_IRQ_MSI_BIT0));
}
}
static void octeon_irq_msi_eoi(unsigned int irq)
{
/* Nothing needed */
}
static void octeon_irq_msi_enable(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/*
* Octeon PCI doesn't have the ability to mask/unmask
* MSI interrupts individually. Instead of
* masking/unmasking them in groups of 16, we simple
* assume MSI devices are well behaved. MSI
* interrupts are always enable and the ACK is assumed
* to be enough.
*/
} else {
/* These chips have PCIe. Note that we only support
* the first 64 MSI interrupts. Unfortunately all the
* MSI enables are in the same register. We use
* MSI0's lock to control access to them all.
*/
uint64_t en;
unsigned long flags;
spin_lock_irqsave(&octeon_irq_msi_lock, flags);
en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
en |= 1ull << (irq - OCTEON_IRQ_MSI_BIT0);
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
}
}
static void octeon_irq_msi_disable(unsigned int irq)
{
if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
/* See comment in enable */
} else {
/*
* These chips have PCIe. Note that we only support
* the first 64 MSI interrupts. Unfortunately all the
* MSI enables are in the same register. We use
* MSI0's lock to control access to them all.
*/
uint64_t en;
unsigned long flags;
spin_lock_irqsave(&octeon_irq_msi_lock, flags);
en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
en &= ~(1ull << (irq - OCTEON_IRQ_MSI_BIT0));
cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
}
}
static struct irq_chip octeon_irq_chip_msi = {
.name = "MSI",
.enable = octeon_irq_msi_enable,
.disable = octeon_irq_msi_disable,
.ack = octeon_irq_msi_ack,
.eoi = octeon_irq_msi_eoi,
};
#endif
void __init arch_init_irq(void)
{
int irq;
#ifdef CONFIG_SMP
/* Set the default affinity to the boot cpu. */
cpumask_clear(irq_default_affinity);
cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
#endif
if (NR_IRQS < OCTEON_IRQ_LAST)
pr_err("octeon_irq_init: NR_IRQS is set too low\n");
/* 0 - 15 reserved for i8259 master and slave controller. */
/* 17 - 23 Mips internal */
for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_core,
handle_percpu_irq);
}
/* 24 - 87 CIU_INT_SUM0 */
for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu0,
handle_percpu_irq);
}
/* 88 - 151 CIU_INT_SUM1 */
for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu1,
handle_percpu_irq);
}
#ifdef CONFIG_PCI_MSI
/* 152 - 215 PCI/PCIe MSI interrupts */
for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_BIT63; irq++) {
set_irq_chip_and_handler(irq, &octeon_irq_chip_msi,
handle_percpu_irq);
}
#endif
set_c0_status(0x300 << 2);
}
asmlinkage void plat_irq_dispatch(void)
{
const unsigned long core_id = cvmx_get_core_num();
const uint64_t ciu_sum0_address = CVMX_CIU_INTX_SUM0(core_id * 2);
const uint64_t ciu_en0_address = CVMX_CIU_INTX_EN0(core_id * 2);
const uint64_t ciu_sum1_address = CVMX_CIU_INT_SUM1;
const uint64_t ciu_en1_address = CVMX_CIU_INTX_EN1(core_id * 2 + 1);
unsigned long cop0_cause;
unsigned long cop0_status;
uint64_t ciu_en;
uint64_t ciu_sum;
while (1) {
cop0_cause = read_c0_cause();
cop0_status = read_c0_status();
cop0_cause &= cop0_status;
cop0_cause &= ST0_IM;
if (unlikely(cop0_cause & STATUSF_IP2)) {
ciu_sum = cvmx_read_csr(ciu_sum0_address);
ciu_en = cvmx_read_csr(ciu_en0_address);
ciu_sum &= ciu_en;
if (likely(ciu_sum))
do_IRQ(fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1);
else
spurious_interrupt();
} else if (unlikely(cop0_cause & STATUSF_IP3)) {
ciu_sum = cvmx_read_csr(ciu_sum1_address);
ciu_en = cvmx_read_csr(ciu_en1_address);
ciu_sum &= ciu_en;
if (likely(ciu_sum))
do_IRQ(fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1);
else
spurious_interrupt();
} else if (likely(cop0_cause)) {
do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE);
} else {
break;
}
}
}

View file

@ -0,0 +1,521 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Unified implementation of memcpy, memmove and the __copy_user backend.
*
* Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
* Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
* Copyright (C) 2002 Broadcom, Inc.
* memcpy/copy_user author: Mark Vandevoorde
*
* Mnemonic names for arguments to memcpy/__copy_user
*/
#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/regdef.h>
#define dst a0
#define src a1
#define len a2
/*
* Spec
*
* memcpy copies len bytes from src to dst and sets v0 to dst.
* It assumes that
* - src and dst don't overlap
* - src is readable
* - dst is writable
* memcpy uses the standard calling convention
*
* __copy_user copies up to len bytes from src to dst and sets a2 (len) to
* the number of uncopied bytes due to an exception caused by a read or write.
* __copy_user assumes that src and dst don't overlap, and that the call is
* implementing one of the following:
* copy_to_user
* - src is readable (no exceptions when reading src)
* copy_from_user
* - dst is writable (no exceptions when writing dst)
* __copy_user uses a non-standard calling convention; see
* arch/mips/include/asm/uaccess.h
*
* When an exception happens on a load, the handler must
# ensure that all of the destination buffer is overwritten to prevent
* leaking information to user mode programs.
*/
/*
* Implementation
*/
/*
* The exception handler for loads requires that:
* 1- AT contain the address of the byte just past the end of the source
* of the copy,
* 2- src_entry <= src < AT, and
* 3- (dst - src) == (dst_entry - src_entry),
* The _entry suffix denotes values when __copy_user was called.
*
* (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
* (2) is met by incrementing src by the number of bytes copied
* (3) is met by not doing loads between a pair of increments of dst and src
*
* The exception handlers for stores adjust len (if necessary) and return.
* These handlers do not need to overwrite any data.
*
* For __rmemcpy and memmove an exception is always a kernel bug, therefore
* they're not protected.
*/
#define EXC(inst_reg,addr,handler) \
9: inst_reg, addr; \
.section __ex_table,"a"; \
PTR 9b, handler; \
.previous
/*
* Only on the 64-bit kernel we can made use of 64-bit registers.
*/
#ifdef CONFIG_64BIT
#define USE_DOUBLE
#endif
#ifdef USE_DOUBLE
#define LOAD ld
#define LOADL ldl
#define LOADR ldr
#define STOREL sdl
#define STORER sdr
#define STORE sd
#define ADD daddu
#define SUB dsubu
#define SRL dsrl
#define SRA dsra
#define SLL dsll
#define SLLV dsllv
#define SRLV dsrlv
#define NBYTES 8
#define LOG_NBYTES 3
/*
* As we are sharing code base with the mips32 tree (which use the o32 ABI
* register definitions). We need to redefine the register definitions from
* the n64 ABI register naming to the o32 ABI register naming.
*/
#undef t0
#undef t1
#undef t2
#undef t3
#define t0 $8
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#else
#define LOAD lw
#define LOADL lwl
#define LOADR lwr
#define STOREL swl
#define STORER swr
#define STORE sw
#define ADD addu
#define SUB subu
#define SRL srl
#define SLL sll
#define SRA sra
#define SLLV sllv
#define SRLV srlv
#define NBYTES 4
#define LOG_NBYTES 2
#endif /* USE_DOUBLE */
#ifdef CONFIG_CPU_LITTLE_ENDIAN
#define LDFIRST LOADR
#define LDREST LOADL
#define STFIRST STORER
#define STREST STOREL
#define SHIFT_DISCARD SLLV
#else
#define LDFIRST LOADL
#define LDREST LOADR
#define STFIRST STOREL
#define STREST STORER
#define SHIFT_DISCARD SRLV
#endif
#define FIRST(unit) ((unit)*NBYTES)
#define REST(unit) (FIRST(unit)+NBYTES-1)
#define UNIT(unit) FIRST(unit)
#define ADDRMASK (NBYTES-1)
.text
.set noreorder
.set noat
/*
* A combined memcpy/__copy_user
* __copy_user sets len to 0 for success; else to an upper bound of
* the number of uncopied bytes.
* memcpy sets v0 to dst.
*/
.align 5
LEAF(memcpy) /* a0=dst a1=src a2=len */
move v0, dst /* return value */
__memcpy:
FEXPORT(__copy_user)
/*
* Note: dst & src may be unaligned, len may be 0
* Temps
*/
#
# Octeon doesn't care if the destination is unaligned. The hardware
# can fix it faster than we can special case the assembly.
#
pref 0, 0(src)
sltu t0, len, NBYTES # Check if < 1 word
bnez t0, copy_bytes_checklen
and t0, src, ADDRMASK # Check if src unaligned
bnez t0, src_unaligned
sltu t0, len, 4*NBYTES # Check if < 4 words
bnez t0, less_than_4units
sltu t0, len, 8*NBYTES # Check if < 8 words
bnez t0, less_than_8units
sltu t0, len, 16*NBYTES # Check if < 16 words
bnez t0, cleanup_both_aligned
sltu t0, len, 128+1 # Check if len < 129
bnez t0, 1f # Skip prefetch if len is too short
sltu t0, len, 256+1 # Check if len < 257
bnez t0, 1f # Skip prefetch if len is too short
pref 0, 128(src) # We must not prefetch invalid addresses
#
# This is where we loop if there is more than 128 bytes left
2: pref 0, 256(src) # We must not prefetch invalid addresses
#
# This is where we loop if we can't prefetch anymore
1:
EXC( LOAD t0, UNIT(0)(src), l_exc)
EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
SUB len, len, 16*NBYTES
EXC( STORE t0, UNIT(0)(dst), s_exc_p16u)
EXC( STORE t1, UNIT(1)(dst), s_exc_p15u)
EXC( STORE t2, UNIT(2)(dst), s_exc_p14u)
EXC( STORE t3, UNIT(3)(dst), s_exc_p13u)
EXC( LOAD t0, UNIT(4)(src), l_exc_copy)
EXC( LOAD t1, UNIT(5)(src), l_exc_copy)
EXC( LOAD t2, UNIT(6)(src), l_exc_copy)
EXC( LOAD t3, UNIT(7)(src), l_exc_copy)
EXC( STORE t0, UNIT(4)(dst), s_exc_p12u)
EXC( STORE t1, UNIT(5)(dst), s_exc_p11u)
EXC( STORE t2, UNIT(6)(dst), s_exc_p10u)
ADD src, src, 16*NBYTES
EXC( STORE t3, UNIT(7)(dst), s_exc_p9u)
ADD dst, dst, 16*NBYTES
EXC( LOAD t0, UNIT(-8)(src), l_exc_copy)
EXC( LOAD t1, UNIT(-7)(src), l_exc_copy)
EXC( LOAD t2, UNIT(-6)(src), l_exc_copy)
EXC( LOAD t3, UNIT(-5)(src), l_exc_copy)
EXC( STORE t0, UNIT(-8)(dst), s_exc_p8u)
EXC( STORE t1, UNIT(-7)(dst), s_exc_p7u)
EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u)
EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u)
EXC( LOAD t0, UNIT(-4)(src), l_exc_copy)
EXC( LOAD t1, UNIT(-3)(src), l_exc_copy)
EXC( LOAD t2, UNIT(-2)(src), l_exc_copy)
EXC( LOAD t3, UNIT(-1)(src), l_exc_copy)
EXC( STORE t0, UNIT(-4)(dst), s_exc_p4u)
EXC( STORE t1, UNIT(-3)(dst), s_exc_p3u)
EXC( STORE t2, UNIT(-2)(dst), s_exc_p2u)
EXC( STORE t3, UNIT(-1)(dst), s_exc_p1u)
sltu t0, len, 256+1 # See if we can prefetch more
beqz t0, 2b
sltu t0, len, 128 # See if we can loop more time
beqz t0, 1b
nop
#
# Jump here if there are less than 16*NBYTES left.
#
cleanup_both_aligned:
beqz len, done
sltu t0, len, 8*NBYTES
bnez t0, less_than_8units
nop
EXC( LOAD t0, UNIT(0)(src), l_exc)
EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
SUB len, len, 8*NBYTES
EXC( STORE t0, UNIT(0)(dst), s_exc_p8u)
EXC( STORE t1, UNIT(1)(dst), s_exc_p7u)
EXC( STORE t2, UNIT(2)(dst), s_exc_p6u)
EXC( STORE t3, UNIT(3)(dst), s_exc_p5u)
EXC( LOAD t0, UNIT(4)(src), l_exc_copy)
EXC( LOAD t1, UNIT(5)(src), l_exc_copy)
EXC( LOAD t2, UNIT(6)(src), l_exc_copy)
EXC( LOAD t3, UNIT(7)(src), l_exc_copy)
EXC( STORE t0, UNIT(4)(dst), s_exc_p4u)
EXC( STORE t1, UNIT(5)(dst), s_exc_p3u)
EXC( STORE t2, UNIT(6)(dst), s_exc_p2u)
EXC( STORE t3, UNIT(7)(dst), s_exc_p1u)
ADD src, src, 8*NBYTES
beqz len, done
ADD dst, dst, 8*NBYTES
#
# Jump here if there are less than 8*NBYTES left.
#
less_than_8units:
sltu t0, len, 4*NBYTES
bnez t0, less_than_4units
nop
EXC( LOAD t0, UNIT(0)(src), l_exc)
EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
SUB len, len, 4*NBYTES
EXC( STORE t0, UNIT(0)(dst), s_exc_p4u)
EXC( STORE t1, UNIT(1)(dst), s_exc_p3u)
EXC( STORE t2, UNIT(2)(dst), s_exc_p2u)
EXC( STORE t3, UNIT(3)(dst), s_exc_p1u)
ADD src, src, 4*NBYTES
beqz len, done
ADD dst, dst, 4*NBYTES
#
# Jump here if there are less than 4*NBYTES left. This means
# we may need to copy up to 3 NBYTES words.
#
less_than_4units:
sltu t0, len, 1*NBYTES
bnez t0, copy_bytes_checklen
nop
#
# 1) Copy NBYTES, then check length again
#
EXC( LOAD t0, 0(src), l_exc)
SUB len, len, NBYTES
sltu t1, len, 8
EXC( STORE t0, 0(dst), s_exc_p1u)
ADD src, src, NBYTES
bnez t1, copy_bytes_checklen
ADD dst, dst, NBYTES
#
# 2) Copy NBYTES, then check length again
#
EXC( LOAD t0, 0(src), l_exc)
SUB len, len, NBYTES
sltu t1, len, 8
EXC( STORE t0, 0(dst), s_exc_p1u)
ADD src, src, NBYTES
bnez t1, copy_bytes_checklen
ADD dst, dst, NBYTES
#
# 3) Copy NBYTES, then check length again
#
EXC( LOAD t0, 0(src), l_exc)
SUB len, len, NBYTES
ADD src, src, NBYTES
ADD dst, dst, NBYTES
b copy_bytes_checklen
EXC( STORE t0, -8(dst), s_exc_p1u)
src_unaligned:
#define rem t8
SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
beqz t0, cleanup_src_unaligned
and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
1:
/*
* Avoid consecutive LD*'s to the same register since some mips
* implementations can't issue them in the same cycle.
* It's OK to load FIRST(N+1) before REST(N) because the two addresses
* are to the same unit (unless src is aligned, but it's not).
*/
EXC( LDFIRST t0, FIRST(0)(src), l_exc)
EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy)
SUB len, len, 4*NBYTES
EXC( LDREST t0, REST(0)(src), l_exc_copy)
EXC( LDREST t1, REST(1)(src), l_exc_copy)
EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy)
EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy)
EXC( LDREST t2, REST(2)(src), l_exc_copy)
EXC( LDREST t3, REST(3)(src), l_exc_copy)
ADD src, src, 4*NBYTES
EXC( STORE t0, UNIT(0)(dst), s_exc_p4u)
EXC( STORE t1, UNIT(1)(dst), s_exc_p3u)
EXC( STORE t2, UNIT(2)(dst), s_exc_p2u)
EXC( STORE t3, UNIT(3)(dst), s_exc_p1u)
bne len, rem, 1b
ADD dst, dst, 4*NBYTES
cleanup_src_unaligned:
beqz len, done
and rem, len, NBYTES-1 # rem = len % NBYTES
beq rem, len, copy_bytes
nop
1:
EXC( LDFIRST t0, FIRST(0)(src), l_exc)
EXC( LDREST t0, REST(0)(src), l_exc_copy)
SUB len, len, NBYTES
EXC( STORE t0, 0(dst), s_exc_p1u)
ADD src, src, NBYTES
bne len, rem, 1b
ADD dst, dst, NBYTES
copy_bytes_checklen:
beqz len, done
nop
copy_bytes:
/* 0 < len < NBYTES */
#define COPY_BYTE(N) \
EXC( lb t0, N(src), l_exc); \
SUB len, len, 1; \
beqz len, done; \
EXC( sb t0, N(dst), s_exc_p1)
COPY_BYTE(0)
COPY_BYTE(1)
#ifdef USE_DOUBLE
COPY_BYTE(2)
COPY_BYTE(3)
COPY_BYTE(4)
COPY_BYTE(5)
#endif
EXC( lb t0, NBYTES-2(src), l_exc)
SUB len, len, 1
jr ra
EXC( sb t0, NBYTES-2(dst), s_exc_p1)
done:
jr ra
nop
END(memcpy)
l_exc_copy:
/*
* Copy bytes from src until faulting load address (or until a
* lb faults)
*
* When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
* may be more than a byte beyond the last address.
* Hence, the lb below may get an exception.
*
* Assumes src < THREAD_BUADDR($28)
*/
LOAD t0, TI_TASK($28)
nop
LOAD t0, THREAD_BUADDR(t0)
1:
EXC( lb t1, 0(src), l_exc)
ADD src, src, 1
sb t1, 0(dst) # can't fault -- we're copy_from_user
bne src, t0, 1b
ADD dst, dst, 1
l_exc:
LOAD t0, TI_TASK($28)
nop
LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
nop
SUB len, AT, t0 # len number of uncopied bytes
/*
* Here's where we rely on src and dst being incremented in tandem,
* See (3) above.
* dst += (fault addr - src) to put dst at first byte to clear
*/
ADD dst, t0 # compute start address in a1
SUB dst, src
/*
* Clear len bytes starting at dst. Can't call __bzero because it
* might modify len. An inefficient loop for these rare times...
*/
beqz len, done
SUB src, len, 1
1: sb zero, 0(dst)
ADD dst, dst, 1
bnez src, 1b
SUB src, src, 1
jr ra
nop
#define SEXC(n) \
s_exc_p ## n ## u: \
jr ra; \
ADD len, len, n*NBYTES
SEXC(16)
SEXC(15)
SEXC(14)
SEXC(13)
SEXC(12)
SEXC(11)
SEXC(10)
SEXC(9)
SEXC(8)
SEXC(7)
SEXC(6)
SEXC(5)
SEXC(4)
SEXC(3)
SEXC(2)
SEXC(1)
s_exc_p1:
jr ra
ADD len, len, 1
s_exc:
jr ra
nop
.align 5
LEAF(memmove)
ADD t0, a0, a2
ADD t1, a1, a2
sltu t0, a1, t0 # dst + len <= src -> memcpy
sltu t1, a0, t1 # dst >= src + len -> memcpy
and t0, t1
beqz t0, __memcpy
move v0, a0 /* return value */
beqz a2, r_out
END(memmove)
/* fall through to __rmemcpy */
LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
sltu t0, a1, a0
beqz t0, r_end_bytes_up # src >= dst
nop
ADD a0, a2 # dst = dst + len
ADD a1, a2 # src = src + len
r_end_bytes:
lb t0, -1(a1)
SUB a2, a2, 0x1
sb t0, -1(a0)
SUB a1, a1, 0x1
bnez a2, r_end_bytes
SUB a0, a0, 0x1
r_out:
jr ra
move a2, zero
r_end_bytes_up:
lb t0, (a1)
SUB a2, a2, 0x1
sb t0, (a0)
ADD a1, a1, 0x1
bnez a2, r_end_bytes_up
ADD a0, a0, 0x1
jr ra
move a2, zero
END(__rmemcpy)

View file

@ -0,0 +1,136 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004-2007 Cavium Networks
*/
#include <linux/console.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
#include <linux/tty.h>
#include <asm/time.h>
#include <asm/octeon/octeon.h>
#ifdef CONFIG_GDB_CONSOLE
#define DEBUG_UART 0
#else
#define DEBUG_UART 1
#endif
unsigned int octeon_serial_in(struct uart_port *up, int offset)
{
int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
if (offset == UART_IIR && (rv & 0xf) == 7) {
/* Busy interrupt, read the USR (39) and try again. */
cvmx_read_csr((uint64_t)(up->membase + (39 << 3)));
rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
}
return rv;
}
void octeon_serial_out(struct uart_port *up, int offset, int value)
{
/*
* If bits 6 or 7 of the OCTEON UART's LCR are set, it quits
* working.
*/
if (offset == UART_LCR)
value &= 0x9f;
cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value);
}
/*
* Allocated in .bss, so it is all zeroed.
*/
#define OCTEON_MAX_UARTS 3
static struct plat_serial8250_port octeon_uart8250_data[OCTEON_MAX_UARTS + 1];
static struct platform_device octeon_uart8250_device = {
.name = "serial8250",
.id = PLAT8250_DEV_PLATFORM,
.dev = {
.platform_data = octeon_uart8250_data,
},
};
static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
{
p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
p->type = PORT_OCTEON;
p->iotype = UPIO_MEM;
p->regshift = 3; /* I/O addresses are every 8 bytes */
p->uartclk = mips_hpt_frequency;
p->serial_in = octeon_serial_in;
p->serial_out = octeon_serial_out;
}
static int __init octeon_serial_init(void)
{
int enable_uart0;
int enable_uart1;
int enable_uart2;
struct plat_serial8250_port *p;
#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
/*
* If we are configured to run as the second of two kernels,
* disable uart0 and enable uart1. Uart0 is owned by the first
* kernel
*/
enable_uart0 = 0;
enable_uart1 = 1;
#else
/*
* We are configured for the first kernel. We'll enable uart0
* if the bootloader told us to use 0, otherwise will enable
* uart 1.
*/
enable_uart0 = (octeon_get_boot_uart() == 0);
enable_uart1 = (octeon_get_boot_uart() == 1);
#ifdef CONFIG_KGDB
enable_uart1 = 1;
#endif
#endif
/* Right now CN52XX is the only chip with a third uart */
enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX);
p = octeon_uart8250_data;
if (enable_uart0) {
/* Add a ttyS device for hardware uart 0 */
octeon_uart_set_common(p);
p->membase = (void *) CVMX_MIO_UARTX_RBR(0);
p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1);
p->irq = OCTEON_IRQ_UART0;
p++;
}
if (enable_uart1) {
/* Add a ttyS device for hardware uart 1 */
octeon_uart_set_common(p);
p->membase = (void *) CVMX_MIO_UARTX_RBR(1);
p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1);
p->irq = OCTEON_IRQ_UART1;
p++;
}
if (enable_uart2) {
/* Add a ttyS device for hardware uart 2 */
octeon_uart_set_common(p);
p->membase = (void *) CVMX_MIO_UART2_RBR;
p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1);
p->irq = OCTEON_IRQ_UART2;
p++;
}
BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]);
return platform_device_register(&octeon_uart8250_device);
}
device_initcall(octeon_serial_init);

View file

@ -0,0 +1,929 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004-2007 Cavium Networks
* Copyright (C) 2008 Wind River Systems
*/
#include <linux/init.h>
#include <linux/console.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/serial.h>
#include <linux/types.h>
#include <linux/string.h> /* for memset */
#include <linux/serial.h>
#include <linux/tty.h>
#include <linux/time.h>
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
#include <linux/string.h>
#include <asm/processor.h>
#include <asm/reboot.h>
#include <asm/smp-ops.h>
#include <asm/system.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
#include <asm/bootinfo.h>
#include <asm/sections.h>
#include <asm/time.h>
#include <asm/octeon/octeon.h>
#ifdef CONFIG_CAVIUM_DECODE_RSL
extern void cvmx_interrupt_rsl_decode(void);
extern int __cvmx_interrupt_ecc_report_single_bit_errors;
extern void cvmx_interrupt_rsl_enable(void);
#endif
extern struct plat_smp_ops octeon_smp_ops;
#ifdef CONFIG_PCI
extern void pci_console_init(const char *arg);
#endif
#ifdef CONFIG_CAVIUM_RESERVE32
extern uint64_t octeon_reserve32_memory;
#endif
static unsigned long long MAX_MEMORY = 512ull << 20;
struct octeon_boot_descriptor *octeon_boot_desc_ptr;
struct cvmx_bootinfo *octeon_bootinfo;
EXPORT_SYMBOL(octeon_bootinfo);
#ifdef CONFIG_CAVIUM_RESERVE32
uint64_t octeon_reserve32_memory;
EXPORT_SYMBOL(octeon_reserve32_memory);
#endif
static int octeon_uart;
extern asmlinkage void handle_int(void);
extern asmlinkage void plat_irq_dispatch(void);
/**
* Return non zero if we are currently running in the Octeon simulator
*
* Returns
*/
int octeon_is_simulation(void)
{
return octeon_bootinfo->board_type == CVMX_BOARD_TYPE_SIM;
}
EXPORT_SYMBOL(octeon_is_simulation);
/**
* Return true if Octeon is in PCI Host mode. This means
* Linux can control the PCI bus.
*
* Returns Non zero if Octeon in host mode.
*/
int octeon_is_pci_host(void)
{
#ifdef CONFIG_PCI
return octeon_bootinfo->config_flags & CVMX_BOOTINFO_CFG_FLAG_PCI_HOST;
#else
return 0;
#endif
}
/**
* Get the clock rate of Octeon
*
* Returns Clock rate in HZ
*/
uint64_t octeon_get_clock_rate(void)
{
if (octeon_is_simulation())
octeon_bootinfo->eclock_hz = 6000000;
return octeon_bootinfo->eclock_hz;
}
EXPORT_SYMBOL(octeon_get_clock_rate);
/**
* Write to the LCD display connected to the bootbus. This display
* exists on most Cavium evaluation boards. If it doesn't exist, then
* this function doesn't do anything.
*
* @s: String to write
*/
void octeon_write_lcd(const char *s)
{
if (octeon_bootinfo->led_display_base_addr) {
void __iomem *lcd_address =
ioremap_nocache(octeon_bootinfo->led_display_base_addr,
8);
int i;
for (i = 0; i < 8; i++, s++) {
if (*s)
iowrite8(*s, lcd_address + i);
else
iowrite8(' ', lcd_address + i);
}
iounmap(lcd_address);
}
}
/**
* Return the console uart passed by the bootloader
*
* Returns uart (0 or 1)
*/
int octeon_get_boot_uart(void)
{
int uart;
#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
uart = 1;
#else
uart = (octeon_boot_desc_ptr->flags & OCTEON_BL_FLAG_CONSOLE_UART1) ?
1 : 0;
#endif
return uart;
}
/**
* Get the coremask Linux was booted on.
*
* Returns Core mask
*/
int octeon_get_boot_coremask(void)
{
return octeon_boot_desc_ptr->core_mask;
}
/**
* Check the hardware BIST results for a CPU
*/
void octeon_check_cpu_bist(void)
{
const int coreid = cvmx_get_core_num();
unsigned long long mask;
unsigned long long bist_val;
/* Check BIST results for COP0 registers */
mask = 0x1f00000000ull;
bist_val = read_octeon_c0_icacheerr();
if (bist_val & mask)
pr_err("Core%d BIST Failure: CacheErr(icache) = 0x%llx\n",
coreid, bist_val);
bist_val = read_octeon_c0_dcacheerr();
if (bist_val & 1)
pr_err("Core%d L1 Dcache parity error: "
"CacheErr(dcache) = 0x%llx\n",
coreid, bist_val);
mask = 0xfc00000000000000ull;
bist_val = read_c0_cvmmemctl();
if (bist_val & mask)
pr_err("Core%d BIST Failure: COP0_CVM_MEM_CTL = 0x%llx\n",
coreid, bist_val);
write_octeon_c0_dcacheerr(0);
}
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
/**
* Called on every core to setup the wired tlb entry needed
* if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
*
*/
static void octeon_hal_setup_per_cpu_reserved32(void *unused)
{
/*
* The config has selected to wire the reserve32 memory for all
* userspace applications. We need to put a wired TLB entry in for each
* 512MB of reserve32 memory. We only handle double 256MB pages here,
* so reserve32 must be multiple of 512MB.
*/
uint32_t size = CONFIG_CAVIUM_RESERVE32;
uint32_t entrylo0 =
0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
uint32_t entrylo1 = entrylo0 + (256 << 14);
uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
while (size >= 512) {
#if 0
pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
smp_processor_id(), entryhi);
#endif
add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
entrylo0 += 512 << 14;
entrylo1 += 512 << 14;
entryhi += 512 << 20;
size -= 512;
}
}
#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
/**
* Called to release the named block which was used to made sure
* that nobody used the memory for something else during
* init. Now we'll free it so userspace apps can use this
* memory region with bootmem_alloc.
*
* This function is called only once from prom_free_prom_memory().
*/
void octeon_hal_setup_reserved32(void)
{
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
#endif
}
/**
* Reboot Octeon
*
* @command: Command to pass to the bootloader. Currently ignored.
*/
static void octeon_restart(char *command)
{
/* Disable all watchdogs before soft reset. They don't get cleared */
#ifdef CONFIG_SMP
int cpu;
for_each_online_cpu(cpu)
cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
#else
cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
#endif
mb();
while (1)
cvmx_write_csr(CVMX_CIU_SOFT_RST, 1);
}
/**
* Permanently stop a core.
*
* @arg: Ignored.
*/
static void octeon_kill_core(void *arg)
{
mb();
if (octeon_is_simulation()) {
/* The simulator needs the watchdog to stop for dead cores */
cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
/* A break instruction causes the simulator stop a core */
asm volatile ("sync\nbreak");
}
}
/**
* Halt the system
*/
static void octeon_halt(void)
{
smp_call_function(octeon_kill_core, NULL, 0);
switch (octeon_bootinfo->board_type) {
case CVMX_BOARD_TYPE_NAO38:
/* Driving a 1 to GPIO 12 shuts off this board */
cvmx_write_csr(CVMX_GPIO_BIT_CFGX(12), 1);
cvmx_write_csr(CVMX_GPIO_TX_SET, 0x1000);
break;
default:
octeon_write_lcd("PowerOff");
break;
}
octeon_kill_core(NULL);
}
#if 0
/**
* Platform time init specifics.
* Returns
*/
void __init plat_time_init(void)
{
/* Nothing special here, but we are required to have one */
}
#endif
/**
* Handle all the error condition interrupts that might occur.
*
*/
#ifdef CONFIG_CAVIUM_DECODE_RSL
static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id)
{
cvmx_interrupt_rsl_decode();
return IRQ_HANDLED;
}
#endif
/**
* Return a string representing the system type
*
* Returns
*/
const char *octeon_board_type_string(void)
{
static char name[80];
sprintf(name, "%s (%s)",
cvmx_board_type_to_string(octeon_bootinfo->board_type),
octeon_model_get_string(read_c0_prid()));
return name;
}
const char *get_system_type(void)
__attribute__ ((alias("octeon_board_type_string")));
void octeon_user_io_init(void)
{
union octeon_cvmemctl cvmmemctl;
union cvmx_iob_fau_timeout fau_timeout;
union cvmx_pow_nw_tim nm_tim;
uint64_t cvmctl;
/* Get the current settings for CP0_CVMMEMCTL_REG */
cvmmemctl.u64 = read_c0_cvmmemctl();
/* R/W If set, marked write-buffer entries time out the same
* as as other entries; if clear, marked write-buffer entries
* use the maximum timeout. */
cvmmemctl.s.dismarkwblongto = 1;
/* R/W If set, a merged store does not clear the write-buffer
* entry timeout state. */
cvmmemctl.s.dismrgclrwbto = 0;
/* R/W Two bits that are the MSBs of the resultant CVMSEG LM
* word location for an IOBDMA. The other 8 bits come from the
* SCRADDR field of the IOBDMA. */
cvmmemctl.s.iobdmascrmsb = 0;
/* R/W If set, SYNCWS and SYNCS only order marked stores; if
* clear, SYNCWS and SYNCS only order unmarked
* stores. SYNCWSMARKED has no effect when DISSYNCWS is
* set. */
cvmmemctl.s.syncwsmarked = 0;
/* R/W If set, SYNCWS acts as SYNCW and SYNCS acts as SYNC. */
cvmmemctl.s.dissyncws = 0;
/* R/W If set, no stall happens on write buffer full. */
if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
cvmmemctl.s.diswbfst = 1;
else
cvmmemctl.s.diswbfst = 0;
/* R/W If set (and SX set), supervisor-level loads/stores can
* use XKPHYS addresses with <48>==0 */
cvmmemctl.s.xkmemenas = 0;
/* R/W If set (and UX set), user-level loads/stores can use
* XKPHYS addresses with VA<48>==0 */
cvmmemctl.s.xkmemenau = 0;
/* R/W If set (and SX set), supervisor-level loads/stores can
* use XKPHYS addresses with VA<48>==1 */
cvmmemctl.s.xkioenas = 0;
/* R/W If set (and UX set), user-level loads/stores can use
* XKPHYS addresses with VA<48>==1 */
cvmmemctl.s.xkioenau = 0;
/* R/W If set, all stores act as SYNCW (NOMERGE must be set
* when this is set) RW, reset to 0. */
cvmmemctl.s.allsyncw = 0;
/* R/W If set, no stores merge, and all stores reach the
* coherent bus in order. */
cvmmemctl.s.nomerge = 0;
/* R/W Selects the bit in the counter used for DID time-outs 0
* = 231, 1 = 230, 2 = 229, 3 = 214. Actual time-out is
* between 1x and 2x this interval. For example, with
* DIDTTO=3, expiration interval is between 16K and 32K. */
cvmmemctl.s.didtto = 0;
/* R/W If set, the (mem) CSR clock never turns off. */
cvmmemctl.s.csrckalwys = 0;
/* R/W If set, mclk never turns off. */
cvmmemctl.s.mclkalwys = 0;
/* R/W Selects the bit in the counter used for write buffer
* flush time-outs (WBFLT+11) is the bit position in an
* internal counter used to determine expiration. The write
* buffer expires between 1x and 2x this interval. For
* example, with WBFLT = 0, a write buffer expires between 2K
* and 4K cycles after the write buffer entry is allocated. */
cvmmemctl.s.wbfltime = 0;
/* R/W If set, do not put Istream in the L2 cache. */
cvmmemctl.s.istrnol2 = 0;
/* R/W The write buffer threshold. */
cvmmemctl.s.wbthresh = 10;
/* R/W If set, CVMSEG is available for loads/stores in
* kernel/debug mode. */
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
cvmmemctl.s.cvmsegenak = 1;
#else
cvmmemctl.s.cvmsegenak = 0;
#endif
/* R/W If set, CVMSEG is available for loads/stores in
* supervisor mode. */
cvmmemctl.s.cvmsegenas = 0;
/* R/W If set, CVMSEG is available for loads/stores in user
* mode. */
cvmmemctl.s.cvmsegenau = 0;
/* R/W Size of local memory in cache blocks, 54 (6912 bytes)
* is max legal value. */
cvmmemctl.s.lmemsz = CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE;
if (smp_processor_id() == 0)
pr_notice("CVMSEG size: %d cache lines (%d bytes)\n",
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
write_c0_cvmmemctl(cvmmemctl.u64);
/* Move the performance counter interrupts to IRQ 6 */
cvmctl = read_c0_cvmctl();
cvmctl &= ~(7 << 7);
cvmctl |= 6 << 7;
write_c0_cvmctl(cvmctl);
/* Set a default for the hardware timeouts */
fau_timeout.u64 = 0;
fau_timeout.s.tout_val = 0xfff;
/* Disable tagwait FAU timeout */
fau_timeout.s.tout_enb = 0;
cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64);
nm_tim.u64 = 0;
/* 4096 cycles */
nm_tim.s.nw_tim = 3;
cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64);
write_octeon_c0_icacheerr(0);
write_c0_derraddr1(0);
}
/**
* Early entry point for arch setup
*/
void __init prom_init(void)
{
struct cvmx_sysinfo *sysinfo;
const int coreid = cvmx_get_core_num();
int i;
int argc;
struct uart_port octeon_port;
#ifdef CONFIG_CAVIUM_RESERVE32
int64_t addr = -1;
#endif
/*
* The bootloader passes a pointer to the boot descriptor in
* $a3, this is available as fw_arg3.
*/
octeon_boot_desc_ptr = (struct octeon_boot_descriptor *)fw_arg3;
octeon_bootinfo =
cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
cvmx_bootmem_init(cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr));
/*
* Only enable the LED controller if we're running on a CN38XX, CN58XX,
* or CN56XX. The CN30XX and CN31XX don't have an LED controller.
*/
if (!octeon_is_simulation() &&
octeon_has_feature(OCTEON_FEATURE_LED_CONTROLLER)) {
cvmx_write_csr(CVMX_LED_EN, 0);
cvmx_write_csr(CVMX_LED_PRT, 0);
cvmx_write_csr(CVMX_LED_DBG, 0);
cvmx_write_csr(CVMX_LED_PRT_FMT, 0);
cvmx_write_csr(CVMX_LED_UDD_CNTX(0), 32);
cvmx_write_csr(CVMX_LED_UDD_CNTX(1), 32);
cvmx_write_csr(CVMX_LED_UDD_DATX(0), 0);
cvmx_write_csr(CVMX_LED_UDD_DATX(1), 0);
cvmx_write_csr(CVMX_LED_EN, 1);
}
#ifdef CONFIG_CAVIUM_RESERVE32
/*
* We need to temporarily allocate all memory in the reserve32
* region. This makes sure the kernel doesn't allocate this
* memory when it is getting memory from the
* bootloader. Later, after the memory allocations are
* complete, the reserve32 will be freed.
*/
#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
"This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
"is set\n");
else
addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
0, 0, 512 << 20,
"CAVIUM_RESERVE32", 0);
#else
/*
* Allocate memory for RESERVED32 aligned on 2MB boundary. This
* is in case we later use hugetlb entries with it.
*/
addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
0, 0, 2 << 20,
"CAVIUM_RESERVE32", 0);
#endif
if (addr < 0)
pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
else
octeon_reserve32_memory = addr;
#endif
#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2
if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) {
pr_info("Skipping L2 locking due to reduced L2 cache size\n");
} else {
uint32_t ebase = read_c0_ebase() & 0x3ffff000;
#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB
/* TLB refill */
cvmx_l2c_lock_mem_region(ebase, 0x100);
#endif
#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION
/* General exception */
cvmx_l2c_lock_mem_region(ebase + 0x180, 0x80);
#endif
#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT
/* Interrupt handler */
cvmx_l2c_lock_mem_region(ebase + 0x200, 0x80);
#endif
#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT
cvmx_l2c_lock_mem_region(__pa_symbol(handle_int), 0x100);
cvmx_l2c_lock_mem_region(__pa_symbol(plat_irq_dispatch), 0x80);
#endif
#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY
cvmx_l2c_lock_mem_region(__pa_symbol(memcpy), 0x480);
#endif
}
#endif
sysinfo = cvmx_sysinfo_get();
memset(sysinfo, 0, sizeof(*sysinfo));
sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
sysinfo->phy_mem_desc_ptr =
cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
sysinfo->core_mask = octeon_bootinfo->core_mask;
sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
sysinfo->board_type = octeon_bootinfo->board_type;
sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
sizeof(sysinfo->mac_addr_base));
sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
memcpy(sysinfo->board_serial_number,
octeon_bootinfo->board_serial_number,
sizeof(sysinfo->board_serial_number));
sysinfo->compact_flash_common_base_addr =
octeon_bootinfo->compact_flash_common_base_addr;
sysinfo->compact_flash_attribute_base_addr =
octeon_bootinfo->compact_flash_attribute_base_addr;
sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
octeon_check_cpu_bist();
octeon_uart = octeon_get_boot_uart();
/*
* Disable All CIU Interrupts. The ones we need will be
* enabled later. Read the SUM register so we know the write
* completed.
*/
cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0);
cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
#ifdef CONFIG_SMP
octeon_write_lcd("LinuxSMP");
#else
octeon_write_lcd("Linux");
#endif
#ifdef CONFIG_CAVIUM_GDB
/*
* When debugging the linux kernel, force the cores to enter
* the debug exception handler to break in.
*/
if (octeon_get_boot_debug_flag()) {
cvmx_write_csr(CVMX_CIU_DINT, 1 << cvmx_get_core_num());
cvmx_read_csr(CVMX_CIU_DINT);
}
#endif
/*
* BIST should always be enabled when doing a soft reset. L2
* Cache locking for instance is not cleared unless BIST is
* enabled. Unfortunately due to a chip errata G-200 for
* Cn38XX and CN31XX, BIST msut be disabled on these parts.
*/
if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) ||
OCTEON_IS_MODEL(OCTEON_CN31XX))
cvmx_write_csr(CVMX_CIU_SOFT_BIST, 0);
else
cvmx_write_csr(CVMX_CIU_SOFT_BIST, 1);
/* Default to 64MB in the simulator to speed things up */
if (octeon_is_simulation())
MAX_MEMORY = 64ull << 20;
arcs_cmdline[0] = 0;
argc = octeon_boot_desc_ptr->argc;
for (i = 0; i < argc; i++) {
const char *arg =
cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]);
if ((strncmp(arg, "MEM=", 4) == 0) ||
(strncmp(arg, "mem=", 4) == 0)) {
sscanf(arg + 4, "%llu", &MAX_MEMORY);
MAX_MEMORY <<= 20;
if (MAX_MEMORY == 0)
MAX_MEMORY = 32ull << 30;
} else if (strcmp(arg, "ecc_verbose") == 0) {
#ifdef CONFIG_CAVIUM_REPORT_SINGLE_BIT_ECC
__cvmx_interrupt_ecc_report_single_bit_errors = 1;
pr_notice("Reporting of single bit ECC errors is "
"turned on\n");
#endif
} else if (strlen(arcs_cmdline) + strlen(arg) + 1 <
sizeof(arcs_cmdline) - 1) {
strcat(arcs_cmdline, " ");
strcat(arcs_cmdline, arg);
}
}
if (strstr(arcs_cmdline, "console=") == NULL) {
#ifdef CONFIG_GDB_CONSOLE
strcat(arcs_cmdline, " console=gdb");
#else
#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
strcat(arcs_cmdline, " console=ttyS0,115200");
#else
if (octeon_uart == 1)
strcat(arcs_cmdline, " console=ttyS1,115200");
else
strcat(arcs_cmdline, " console=ttyS0,115200");
#endif
#endif
}
if (octeon_is_simulation()) {
/*
* The simulator uses a mtdram device pre filled with
* the filesystem. Also specify the calibration delay
* to avoid calculating it every time.
*/
strcat(arcs_cmdline, " rw root=1f00"
" lpj=60176 slram=root,0x40000000,+1073741824");
}
mips_hpt_frequency = octeon_get_clock_rate();
octeon_init_cvmcount();
_machine_restart = octeon_restart;
_machine_halt = octeon_halt;
memset(&octeon_port, 0, sizeof(octeon_port));
/*
* For early_serial_setup we don't set the port type or
* UPF_FIXED_TYPE.
*/
octeon_port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ;
octeon_port.iotype = UPIO_MEM;
/* I/O addresses are every 8 bytes */
octeon_port.regshift = 3;
/* Clock rate of the chip */
octeon_port.uartclk = mips_hpt_frequency;
octeon_port.fifosize = 64;
octeon_port.mapbase = 0x0001180000000800ull + (1024 * octeon_uart);
octeon_port.membase = cvmx_phys_to_ptr(octeon_port.mapbase);
octeon_port.serial_in = octeon_serial_in;
octeon_port.serial_out = octeon_serial_out;
#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
octeon_port.line = 0;
#else
octeon_port.line = octeon_uart;
#endif
octeon_port.irq = 42 + octeon_uart;
early_serial_setup(&octeon_port);
octeon_user_io_init();
register_smp_ops(&octeon_smp_ops);
}
void __init plat_mem_setup(void)
{
uint64_t mem_alloc_size;
uint64_t total;
int64_t memory;
total = 0;
/* First add the init memory we will be returning. */
memory = __pa_symbol(&__init_begin) & PAGE_MASK;
mem_alloc_size = (__pa_symbol(&__init_end) & PAGE_MASK) - memory;
if (mem_alloc_size > 0) {
add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
total += mem_alloc_size;
}
/*
* The Mips memory init uses the first memory location for
* some memory vectors. When SPARSEMEM is in use, it doesn't
* verify that the size is big enough for the final
* vectors. Making the smallest chuck 4MB seems to be enough
* to consistantly work.
*/
mem_alloc_size = 4 << 20;
if (mem_alloc_size > MAX_MEMORY)
mem_alloc_size = MAX_MEMORY;
/*
* When allocating memory, we want incrementing addresses from
* bootmem_alloc so the code in add_memory_region can merge
* regions next to each other.
*/
cvmx_bootmem_lock();
while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX)
&& (total < MAX_MEMORY)) {
#if defined(CONFIG_64BIT) || defined(CONFIG_64BIT_PHYS_ADDR)
memory = cvmx_bootmem_phy_alloc(mem_alloc_size,
__pa_symbol(&__init_end), -1,
0x100000,
CVMX_BOOTMEM_FLAG_NO_LOCKING);
#elif defined(CONFIG_HIGHMEM)
memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 1ull << 31,
0x100000,
CVMX_BOOTMEM_FLAG_NO_LOCKING);
#else
memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 512 << 20,
0x100000,
CVMX_BOOTMEM_FLAG_NO_LOCKING);
#endif
if (memory >= 0) {
/*
* This function automatically merges address
* regions next to each other if they are
* received in incrementing order.
*/
add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
total += mem_alloc_size;
} else {
break;
}
}
cvmx_bootmem_unlock();
#ifdef CONFIG_CAVIUM_RESERVE32
/*
* Now that we've allocated the kernel memory it is safe to
* free the reserved region. We free it here so that builtin
* drivers can use the memory.
*/
if (octeon_reserve32_memory)
cvmx_bootmem_free_named("CAVIUM_RESERVE32");
#endif /* CONFIG_CAVIUM_RESERVE32 */
if (total == 0)
panic("Unable to allocate memory from "
"cvmx_bootmem_phy_alloc\n");
}
int prom_putchar(char c)
{
uint64_t lsrval;
/* Spin until there is room */
do {
lsrval = cvmx_read_csr(CVMX_MIO_UARTX_LSR(octeon_uart));
} while ((lsrval & 0x20) == 0);
/* Write the byte */
cvmx_write_csr(CVMX_MIO_UARTX_THR(octeon_uart), c);
return 1;
}
void prom_free_prom_memory(void)
{
#ifdef CONFIG_CAVIUM_DECODE_RSL
cvmx_interrupt_rsl_enable();
/* Add an interrupt handler for general failures. */
if (request_irq(OCTEON_IRQ_RML, octeon_rlm_interrupt, IRQF_SHARED,
"RML/RSL", octeon_rlm_interrupt)) {
panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
}
#endif
/* This call is here so that it is performed after any TLB
initializations. It needs to be after these in case the
CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
octeon_hal_setup_reserved32();
}
static struct octeon_cf_data octeon_cf_data;
static int __init octeon_cf_device_init(void)
{
union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
unsigned long base_ptr, region_base, region_size;
struct platform_device *pd;
struct resource cf_resources[3];
unsigned int num_resources;
int i;
int ret = 0;
/* Setup octeon-cf platform device if present. */
base_ptr = 0;
if (octeon_bootinfo->major_version == 1
&& octeon_bootinfo->minor_version >= 1) {
if (octeon_bootinfo->compact_flash_common_base_addr)
base_ptr =
octeon_bootinfo->compact_flash_common_base_addr;
} else {
base_ptr = 0x1d000800;
}
if (!base_ptr)
return ret;
/* Find CS0 region. */
for (i = 0; i < 8; i++) {
mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i));
region_base = mio_boot_reg_cfg.s.base << 16;
region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
&& base_ptr < region_base + region_size)
break;
}
if (i >= 7) {
/* i and i + 1 are CS0 and CS1, both must be less than 8. */
goto out;
}
octeon_cf_data.base_region = i;
octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width;
octeon_cf_data.base_region_bias = base_ptr - region_base;
memset(cf_resources, 0, sizeof(cf_resources));
num_resources = 0;
cf_resources[num_resources].flags = IORESOURCE_MEM;
cf_resources[num_resources].start = region_base;
cf_resources[num_resources].end = region_base + region_size - 1;
num_resources++;
if (!(base_ptr & 0xfffful)) {
/*
* Boot loader signals availability of DMA (true_ide
* mode) by setting low order bits of base_ptr to
* zero.
*/
/* Asume that CS1 immediately follows. */
mio_boot_reg_cfg.u64 =
cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1));
region_base = mio_boot_reg_cfg.s.base << 16;
region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
if (!mio_boot_reg_cfg.s.en)
goto out;
cf_resources[num_resources].flags = IORESOURCE_MEM;
cf_resources[num_resources].start = region_base;
cf_resources[num_resources].end = region_base + region_size - 1;
num_resources++;
octeon_cf_data.dma_engine = 0;
cf_resources[num_resources].flags = IORESOURCE_IRQ;
cf_resources[num_resources].start = OCTEON_IRQ_BOOTDMA;
cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA;
num_resources++;
} else {
octeon_cf_data.dma_engine = -1;
}
pd = platform_device_alloc("pata_octeon_cf", -1);
if (!pd) {
ret = -ENOMEM;
goto out;
}
pd->dev.platform_data = &octeon_cf_data;
ret = platform_device_add_resources(pd, cf_resources, num_resources);
if (ret)
goto fail;
ret = platform_device_add(pd);
if (ret)
goto fail;
return ret;
fail:
platform_device_put(pd);
out:
return ret;
}
device_initcall(octeon_cf_device_init);

View file

@ -0,0 +1,211 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004-2008 Cavium Networks
*/
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/sched.h>
#include <linux/module.h>
#include <asm/mmu_context.h>
#include <asm/system.h>
#include <asm/time.h>
#include <asm/octeon/octeon.h>
volatile unsigned long octeon_processor_boot = 0xff;
volatile unsigned long octeon_processor_sp;
volatile unsigned long octeon_processor_gp;
static irqreturn_t mailbox_interrupt(int irq, void *dev_id)
{
const int coreid = cvmx_get_core_num();
uint64_t action;
/* Load the mailbox register to figure out what we're supposed to do */
action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid));
/* Clear the mailbox to clear the interrupt */
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action);
if (action & SMP_CALL_FUNCTION)
smp_call_function_interrupt();
/* Check if we've been told to flush the icache */
if (action & SMP_ICACHE_FLUSH)
asm volatile ("synci 0($0)\n");
return IRQ_HANDLED;
}
/**
* Cause the function described by call_data to be executed on the passed
* cpu. When the function has finished, increment the finished field of
* call_data.
*/
void octeon_send_ipi_single(int cpu, unsigned int action)
{
int coreid = cpu_logical_map(cpu);
/*
pr_info("SMP: Mailbox send cpu=%d, coreid=%d, action=%u\n", cpu,
coreid, action);
*/
cvmx_write_csr(CVMX_CIU_MBOX_SETX(coreid), action);
}
static inline void octeon_send_ipi_mask(cpumask_t mask, unsigned int action)
{
unsigned int i;
for_each_cpu_mask(i, mask)
octeon_send_ipi_single(i, action);
}
/**
* Detect available CPUs, populate phys_cpu_present_map
*/
static void octeon_smp_setup(void)
{
const int coreid = cvmx_get_core_num();
int cpus;
int id;
int core_mask = octeon_get_boot_coremask();
cpus_clear(cpu_possible_map);
__cpu_number_map[coreid] = 0;
__cpu_logical_map[0] = coreid;
cpu_set(0, cpu_possible_map);
cpus = 1;
for (id = 0; id < 16; id++) {
if ((id != coreid) && (core_mask & (1 << id))) {
cpu_set(cpus, cpu_possible_map);
__cpu_number_map[id] = cpus;
__cpu_logical_map[cpus] = id;
cpus++;
}
}
}
/**
* Firmware CPU startup hook
*
*/
static void octeon_boot_secondary(int cpu, struct task_struct *idle)
{
int count;
pr_info("SMP: Booting CPU%02d (CoreId %2d)...\n", cpu,
cpu_logical_map(cpu));
octeon_processor_sp = __KSTK_TOS(idle);
octeon_processor_gp = (unsigned long)(task_thread_info(idle));
octeon_processor_boot = cpu_logical_map(cpu);
mb();
count = 10000;
while (octeon_processor_sp && count) {
/* Waiting for processor to get the SP and GP */
udelay(1);
count--;
}
if (count == 0)
pr_err("Secondary boot timeout\n");
}
/**
* After we've done initial boot, this function is called to allow the
* board code to clean up state, if needed
*/
static void octeon_init_secondary(void)
{
const int coreid = cvmx_get_core_num();
union cvmx_ciu_intx_sum0 interrupt_enable;
octeon_check_cpu_bist();
octeon_init_cvmcount();
/*
pr_info("SMP: CPU%d (CoreId %lu) started\n", cpu, coreid);
*/
/* Enable Mailbox interrupts to this core. These are the only
interrupts allowed on line 3 */
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), 0xffffffff);
interrupt_enable.u64 = 0;
interrupt_enable.s.mbox = 0x3;
cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), interrupt_enable.u64);
cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
/* Enable core interrupt processing for 2,3 and 7 */
set_c0_status(0x8c01);
}
/**
* Callout to firmware before smp_init
*
*/
void octeon_prepare_cpus(unsigned int max_cpus)
{
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff);
if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_SHARED,
"mailbox0", mailbox_interrupt)) {
panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
}
if (request_irq(OCTEON_IRQ_MBOX1, mailbox_interrupt, IRQF_SHARED,
"mailbox1", mailbox_interrupt)) {
panic("Cannot request_irq(OCTEON_IRQ_MBOX1)\n");
}
}
/**
* Last chance for the board code to finish SMP initialization before
* the CPU is "online".
*/
static void octeon_smp_finish(void)
{
#ifdef CONFIG_CAVIUM_GDB
unsigned long tmp;
/* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
to be not masked by this core so we know the signal is received by
someone */
asm volatile ("dmfc0 %0, $22\n"
"ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
#endif
octeon_user_io_init();
/* to generate the first CPU timer interrupt */
write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
}
/**
* Hook for after all CPUs are online
*/
static void octeon_cpus_done(void)
{
#ifdef CONFIG_CAVIUM_GDB
unsigned long tmp;
/* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
to be not masked by this core so we know the signal is received by
someone */
asm volatile ("dmfc0 %0, $22\n"
"ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
#endif
}
struct plat_smp_ops octeon_smp_ops = {
.send_ipi_single = octeon_send_ipi_single,
.send_ipi_mask = octeon_send_ipi_mask,
.init_secondary = octeon_init_secondary,
.smp_finish = octeon_smp_finish,
.cpus_done = octeon_cpus_done,
.boot_secondary = octeon_boot_secondary,
.smp_setup = octeon_smp_setup,
.prepare_cpus = octeon_prepare_cpus,
};

View file

@ -0,0 +1,943 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.28-rc6
# Wed Dec 3 11:00:58 2008
#
CONFIG_MIPS=y
#
# Machine selection
#
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_BASLER_EXCITE is not set
# CONFIG_BCM47XX is not set
# CONFIG_MIPS_COBALT is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
# CONFIG_LASAT is not set
# CONFIG_LEMOTE_FULONG is not set
# CONFIG_MIPS_MALTA is not set
# CONFIG_MIPS_SIM is not set
# CONFIG_MACH_EMMA is not set
# CONFIG_MACH_VR41XX is not set
# CONFIG_NXP_STB220 is not set
# CONFIG_NXP_STB225 is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
# CONFIG_SGI_IP32 is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SWARM is not set
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SNI_RM is not set
# CONFIG_MACH_TX39XX is not set
# CONFIG_MACH_TX49XX is not set
# CONFIG_MIKROTIK_RB532 is not set
# CONFIG_WR_PPMC is not set
# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y
CONFIG_CAVIUM_OCTEON_SPECIFIC_OPTIONS=y
# CONFIG_CAVIUM_OCTEON_2ND_KERNEL is not set
CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED=y
CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2
CONFIG_CAVIUM_OCTEON_LOCK_L2=y
CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB=y
CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION=y
CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT=y
CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT=y
CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY=y
CONFIG_ARCH_SPARSEMEM_ENABLE=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_SUPPORTS_OPROFILE=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
CONFIG_CEVT_R4K=y
CONFIG_CSRC_R4K=y
CONFIG_DMA_COHERENT=y
# CONFIG_EARLY_PRINTK is not set
CONFIG_SYS_HAS_EARLY_PRINTK=y
# CONFIG_HOTPLUG_CPU is not set
# CONFIG_NO_IOPORT is not set
CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_CPU_OCTEON=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_MIPS_L1_CACHE_SHIFT=7
#
# CPU selection
#
# CONFIG_CPU_LOONGSON2 is not set
# CONFIG_CPU_MIPS32_R1 is not set
# CONFIG_CPU_MIPS32_R2 is not set
# CONFIG_CPU_MIPS64_R1 is not set
# CONFIG_CPU_MIPS64_R2 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_VR41XX is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_TX49XX is not set
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
# CONFIG_CPU_R5500 is not set
# CONFIG_CPU_R6000 is not set
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R8000 is not set
# CONFIG_CPU_R10000 is not set
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
CONFIG_CPU_CAVIUM_OCTEON=y
CONFIG_WEAK_ORDERING=y
CONFIG_WEAK_REORDERING_BEYOND_LLSC=y
CONFIG_CPU_MIPSR2=y
CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y
#
# Kernel type
#
# CONFIG_32BIT is not set
CONFIG_64BIT=y
CONFIG_PAGE_SIZE_4KB=y
# CONFIG_PAGE_SIZE_8KB is not set
# CONFIG_PAGE_SIZE_16KB is not set
# CONFIG_PAGE_SIZE_64KB is not set
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
CONFIG_64BIT_PHYS_ADDR=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_IRQ_PER_CPU=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_SYS_SUPPORTS_HIGHMEM=y
CONFIG_ARCH_FLATMEM_ENABLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_SELECT_MEMORY_MODEL=y
# CONFIG_FLATMEM_MANUAL is not set
# CONFIG_DISCONTIGMEM_MANUAL is not set
CONFIG_SPARSEMEM_MANUAL=y
CONFIG_SPARSEMEM=y
CONFIG_HAVE_MEMORY_PRESENT=y
CONFIG_SPARSEMEM_STATIC=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
CONFIG_RESOURCES_64BIT=y
CONFIG_PHYS_ADDR_T_64BIT=y
CONFIG_ZONE_DMA_FLAG=0
CONFIG_VIRT_TO_BUS=y
CONFIG_UNEVICTABLE_LRU=y
CONFIG_SMP=y
CONFIG_SYS_SUPPORTS_SMP=y
CONFIG_NR_CPUS_DEFAULT_16=y
CONFIG_NR_CPUS=16
# CONFIG_NO_HZ is not set
# CONFIG_HIGH_RES_TIMERS is not set
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
# CONFIG_HZ_48 is not set
# CONFIG_HZ_100 is not set
# CONFIG_HZ_128 is not set
CONFIG_HZ_250=y
# CONFIG_HZ_256 is not set
# CONFIG_HZ_1000 is not set
# CONFIG_HZ_1024 is not set
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_HZ=250
# CONFIG_PREEMPT_NONE is not set
# CONFIG_PREEMPT_VOLUNTARY is not set
CONFIG_PREEMPT=y
# CONFIG_PREEMPT_RCU is not set
# CONFIG_KEXEC is not set
CONFIG_SECCOMP=y
CONFIG_LOCKDEP_SUPPORT=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
# General setup
#
CONFIG_EXPERIMENTAL=y
CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
CONFIG_GROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_RT_GROUP_SCHED is not set
CONFIG_USER_SCHED=y
# CONFIG_CGROUP_SCHED is not set
CONFIG_SYSFS_DEPRECATED=y
CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_RELAY=y
# CONFIG_NAMESPACES is not set
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_ELF_CORE=y
# CONFIG_PCSPKR_PLATFORM is not set
CONFIG_COMPAT_BRK=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_ANON_INODES=y
CONFIG_EPOLL=y
CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
CONFIG_USE_GENERIC_SMP_HELPERS=y
# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
CONFIG_KMOD=y
CONFIG_STOP_MACHINE=y
CONFIG_BLOCK=y
# CONFIG_BLK_DEV_IO_TRACE is not set
# CONFIG_BLK_DEV_BSG is not set
# CONFIG_BLK_DEV_INTEGRITY is not set
CONFIG_BLOCK_COMPAT=y
#
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
CONFIG_IOSCHED_AS=y
CONFIG_IOSCHED_DEADLINE=y
CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_CLASSIC_RCU=y
# CONFIG_PROBE_INITRD_HEADER is not set
# CONFIG_FREEZER is not set
#
# Bus options (PCI, PCMCIA, EISA, ISA, TC)
#
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_MMU=y
# CONFIG_PCCARD is not set
#
# Executable file formats
#
CONFIG_BINFMT_ELF=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
CONFIG_MIPS32_COMPAT=y
CONFIG_COMPAT=y
CONFIG_SYSVIPC_COMPAT=y
CONFIG_MIPS32_O32=y
CONFIG_MIPS32_N32=y
CONFIG_BINFMT_ELF32=y
#
# Power management options
#
# CONFIG_PM is not set
CONFIG_NET=y
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
CONFIG_XFRM=y
# CONFIG_XFRM_USER is not set
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
# CONFIG_NET_KEY is not set
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_ASK_IP_FIB_HASH=y
# CONFIG_IP_FIB_TRIE is not set
CONFIG_IP_FIB_HASH=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_IP_ROUTE_VERBOSE=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
CONFIG_IP_PNP_RARP=y
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
CONFIG_IP_MROUTE=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
# CONFIG_ARPD is not set
CONFIG_SYN_COOKIES=y
# CONFIG_INET_AH is not set
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
CONFIG_INET_XFRM_MODE_TRANSPORT=y
CONFIG_INET_XFRM_MODE_TUNNEL=y
CONFIG_INET_XFRM_MODE_BEET=y
# CONFIG_INET_LRO is not set
CONFIG_INET_DIAG=y
CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_TCP_MD5SIG is not set
# CONFIG_IPV6 is not set
# CONFIG_NETLABEL is not set
# CONFIG_NETWORK_SECMARK is not set
# CONFIG_NETFILTER is not set
# CONFIG_IP_DCCP is not set
# CONFIG_IP_SCTP is not set
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
#
# Network testing
#
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
# CONFIG_PHONET is not set
CONFIG_FIB_RULES=y
# CONFIG_WIRELESS is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
#
# Device Drivers
#
#
# Generic Driver Options
#
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
# CONFIG_CONNECTOR is not set
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
# CONFIG_MTD_CMDLINE_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
#
# User Modules And Translation Layers
#
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
# CONFIG_FTL is not set
# CONFIG_NFTL is not set
# CONFIG_INFTL is not set
# CONFIG_RFD_FTL is not set
# CONFIG_SSFDC is not set
# CONFIG_MTD_OOPS is not set
#
# RAM/ROM/Flash chip drivers
#
CONFIG_MTD_CFI=y
# CONFIG_MTD_JEDECPROBE is not set
CONFIG_MTD_GEN_PROBE=y
# CONFIG_MTD_CFI_ADV_OPTIONS is not set
CONFIG_MTD_MAP_BANK_WIDTH_1=y
CONFIG_MTD_MAP_BANK_WIDTH_2=y
CONFIG_MTD_MAP_BANK_WIDTH_4=y
# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
CONFIG_MTD_CFI_I1=y
CONFIG_MTD_CFI_I2=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
# CONFIG_MTD_RAM is not set
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
#
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_PHYSMAP_START=0x8000000
CONFIG_MTD_PHYSMAP_LEN=0x0
CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_PLATRAM is not set
#
# Self-contained MTD device drivers
#
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
# CONFIG_MTD_BLOCK2MTD is not set
#
# Disk-On-Chip Device Drivers
#
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
# CONFIG_MTD_NAND is not set
# CONFIG_MTD_ONENAND is not set
#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_BLK_DEV_HD is not set
# CONFIG_MISC_DEVICES is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
#
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
# CONFIG_SCSI is not set
# CONFIG_SCSI_DMA is not set
# CONFIG_SCSI_NETLINK is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_VETH is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_B44 is not set
CONFIG_NETDEV_1000=y
# CONFIG_NETDEV_10000 is not set
#
# Wireless LAN
#
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
# CONFIG_IWLWIFI_LEDS is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
# CONFIG_NETCONSOLE is not set
# CONFIG_NETPOLL is not set
# CONFIG_NET_POLL_CONTROLLER is not set
# CONFIG_ISDN is not set
# CONFIG_PHONE is not set
#
# Input device support
#
# CONFIG_INPUT is not set
#
# Hardware I/O ports
#
# CONFIG_SERIO is not set
# CONFIG_GAMEPORT is not set
#
# Character devices
#
# CONFIG_VT is not set
CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_8250_NR_UARTS=2
CONFIG_SERIAL_8250_RUNTIME_UARTS=2
# CONFIG_SERIAL_8250_EXTENDED is not set
#
# Non-8250 serial port support
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
# CONFIG_HW_RANDOM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
# CONFIG_I2C is not set
# CONFIG_SPI is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
# CONFIG_THERMAL is not set
# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
#
# Watchdog Device Drivers
#
# CONFIG_SOFT_WATCHDOG is not set
CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_REGULATOR is not set
#
# Multimedia devices
#
#
# Multimedia core support
#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
# CONFIG_VIDEO_MEDIA is not set
#
# Multimedia drivers
#
# CONFIG_DAB is not set
#
# Graphics support
#
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
# CONFIG_FB is not set
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
#
# Display device support
#
# CONFIG_DISPLAY_SUPPORT is not set
# CONFIG_SOUND is not set
# CONFIG_USB_SUPPORT is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
# CONFIG_ACCESSIBILITY is not set
CONFIG_RTC_LIB=y
# CONFIG_RTC_CLASS is not set
# CONFIG_DMADEVICES is not set
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
CONFIG_STAGING_EXCLUDE_BUILD=y
#
# File systems
#
# CONFIG_EXT2_FS is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4_FS is not set
# CONFIG_REISERFS_FS is not set
# CONFIG_JFS_FS is not set
# CONFIG_FS_POSIX_ACL is not set
CONFIG_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_GFS2_FS is not set
# CONFIG_OCFS2_FS is not set
CONFIG_DNOTIFY=y
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
# CONFIG_FUSE_FS is not set
#
# CD-ROM/DVD Filesystems
#
# CONFIG_ISO9660_FS is not set
# CONFIG_UDF_FS is not set
#
# DOS/FAT/NT Filesystems
#
# CONFIG_MSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_NTFS_FS is not set
#
# Pseudo filesystems
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
#
# Miscellaneous filesystems
#
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_HFSPLUS_FS is not set
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS2_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
# CONFIG_NETWORK_FILESYSTEMS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
# CONFIG_DLM is not set
#
# Kernel hacking
#
CONFIG_TRACE_IRQFLAGS_SUPPORT=y
# CONFIG_PRINTK_TIME is not set
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=2048
CONFIG_MAGIC_SYSRQ=y
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_DEBUG_SHIRQ is not set
CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
CONFIG_SCHED_DEBUG=y
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
CONFIG_DEBUG_PREEMPT=y
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
CONFIG_DEBUG_SPINLOCK=y
# CONFIG_DEBUG_MUTEXES is not set
# CONFIG_DEBUG_LOCK_ALLOC is not set
# CONFIG_PROVE_LOCKING is not set
# CONFIG_LOCK_STAT is not set
CONFIG_DEBUG_SPINLOCK_SLEEP=y
# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_INFO=y
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_WRITECOUNT is not set
# CONFIG_DEBUG_MEMORY_INIT is not set
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
#
# Tracers
#
# CONFIG_IRQSOFF_TRACER is not set
# CONFIG_PREEMPT_TRACER is not set
# CONFIG_SCHED_TRACER is not set
# CONFIG_CONTEXT_SWITCH_TRACER is not set
# CONFIG_BOOT_TRACER is not set
# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
# CONFIG_KGDB is not set
CONFIG_CMDLINE=""
# CONFIG_DEBUG_STACK_USAGE is not set
# CONFIG_RUNTIME_DEBUG is not set
#
# Security options
#
# CONFIG_KEYS is not set
CONFIG_SECURITY=y
# CONFIG_SECURITYFS is not set
CONFIG_SECURITY_NETWORK=y
# CONFIG_SECURITY_NETWORK_XFRM is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
CONFIG_CRYPTO_AEAD=y
CONFIG_CRYPTO_BLKCIPHER=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_RNG=y
CONFIG_CRYPTO_MANAGER=y
# CONFIG_CRYPTO_GF128MUL is not set
# CONFIG_CRYPTO_NULL is not set
# CONFIG_CRYPTO_CRYPTD is not set
# CONFIG_CRYPTO_AUTHENC is not set
# CONFIG_CRYPTO_TEST is not set
#
# Authenticated Encryption with Associated Data
#
# CONFIG_CRYPTO_CCM is not set
# CONFIG_CRYPTO_GCM is not set
# CONFIG_CRYPTO_SEQIV is not set
#
# Block modes
#
CONFIG_CRYPTO_CBC=y
# CONFIG_CRYPTO_CTR is not set
# CONFIG_CRYPTO_CTS is not set
# CONFIG_CRYPTO_ECB is not set
# CONFIG_CRYPTO_LRW is not set
# CONFIG_CRYPTO_PCBC is not set
# CONFIG_CRYPTO_XTS is not set
#
# Hash modes
#
CONFIG_CRYPTO_HMAC=y
# CONFIG_CRYPTO_XCBC is not set
#
# Digest
#
# CONFIG_CRYPTO_CRC32C is not set
# CONFIG_CRYPTO_MD4 is not set
CONFIG_CRYPTO_MD5=y
# CONFIG_CRYPTO_MICHAEL_MIC is not set
# CONFIG_CRYPTO_RMD128 is not set
# CONFIG_CRYPTO_RMD160 is not set
# CONFIG_CRYPTO_RMD256 is not set
# CONFIG_CRYPTO_RMD320 is not set
# CONFIG_CRYPTO_SHA1 is not set
# CONFIG_CRYPTO_SHA256 is not set
# CONFIG_CRYPTO_SHA512 is not set
# CONFIG_CRYPTO_TGR192 is not set
# CONFIG_CRYPTO_WP512 is not set
#
# Ciphers
#
# CONFIG_CRYPTO_AES is not set
# CONFIG_CRYPTO_ANUBIS is not set
# CONFIG_CRYPTO_ARC4 is not set
# CONFIG_CRYPTO_BLOWFISH is not set
# CONFIG_CRYPTO_CAMELLIA is not set
# CONFIG_CRYPTO_CAST5 is not set
# CONFIG_CRYPTO_CAST6 is not set
CONFIG_CRYPTO_DES=y
# CONFIG_CRYPTO_FCRYPT is not set
# CONFIG_CRYPTO_KHAZAD is not set
# CONFIG_CRYPTO_SALSA20 is not set
# CONFIG_CRYPTO_SEED is not set
# CONFIG_CRYPTO_SERPENT is not set
# CONFIG_CRYPTO_TEA is not set
# CONFIG_CRYPTO_TWOFISH is not set
#
# Compression
#
# CONFIG_CRYPTO_DEFLATE is not set
# CONFIG_CRYPTO_LZO is not set
#
# Random Number Generation
#
# CONFIG_CRYPTO_ANSI_CPRNG is not set
CONFIG_CRYPTO_HW=y
#
# Library routines
#
CONFIG_BITREVERSE=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
# CONFIG_LIBCRC32C is not set
CONFIG_PLIST=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y

View file

@ -38,6 +38,9 @@
#ifndef cpu_has_tx39_cache
#define cpu_has_tx39_cache (cpu_data[0].options & MIPS_CPU_TX39_CACHE)
#endif
#ifndef cpu_has_octeon_cache
#define cpu_has_octeon_cache 0
#endif
#ifndef cpu_has_fpu
#define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU)
#define raw_cpu_has_fpu (raw_current_cpu_data.options & MIPS_CPU_FPU)

View file

@ -33,6 +33,7 @@
#define PRID_COMP_TOSHIBA 0x070000
#define PRID_COMP_LSI 0x080000
#define PRID_COMP_LEXRA 0x0b0000
#define PRID_COMP_CAVIUM 0x0d0000
/*
@ -113,6 +114,18 @@
#define PRID_IMP_BCM4710 0x4000
#define PRID_IMP_BCM3302 0x9000
/*
* These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
*/
#define PRID_IMP_CAVIUM_CN38XX 0x0000
#define PRID_IMP_CAVIUM_CN31XX 0x0100
#define PRID_IMP_CAVIUM_CN30XX 0x0200
#define PRID_IMP_CAVIUM_CN58XX 0x0300
#define PRID_IMP_CAVIUM_CN56XX 0x0400
#define PRID_IMP_CAVIUM_CN50XX 0x0600
#define PRID_IMP_CAVIUM_CN52XX 0x0700
/*
* Definitions for 7:0 on legacy processors
*/
@ -203,6 +216,7 @@ enum cpu_type_enum {
* MIPS64 class processors
*/
CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
CPU_CAVIUM_OCTEON,
CPU_LAST
};

View file

@ -42,7 +42,7 @@ ASMMACRO(_ehb,
/*
* TLB hazards
*/
#if defined(CONFIG_CPU_MIPSR2)
#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_CPU_CAVIUM_OCTEON)
/*
* MIPSR2 defines ehb for hazard avoidance
@ -138,7 +138,7 @@ do { \
__instruction_hazard(); \
} while (0)
#elif defined(CONFIG_CPU_R10000)
#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_CAVIUM_OCTEON)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.

View file

@ -295,6 +295,12 @@ static inline void iounmap(const volatile void __iomem *addr)
#undef __IS_KSEG1
}
#ifdef CONFIG_CPU_CAVIUM_OCTEON
#define war_octeon_io_reorder_wmb() wmb()
#else
#define war_octeon_io_reorder_wmb() do { } while (0)
#endif
#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
\
static inline void pfx##write##bwlq(type val, \
@ -303,6 +309,8 @@ static inline void pfx##write##bwlq(type val, \
volatile type *__mem; \
type __val; \
\
war_octeon_io_reorder_wmb(); \
\
__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
\
__val = pfx##ioswab##bwlq(__mem, val); \
@ -370,6 +378,8 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \
volatile type *__addr; \
type __val; \
\
war_octeon_io_reorder_wmb(); \
\
__addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
\
__val = pfx##ioswab##bwlq(__addr, val); \
@ -504,8 +514,12 @@ BUILDSTRING(q, u64)
#endif
#ifdef CONFIG_CPU_CAVIUM_OCTEON
#define mmiowb() wmb()
#else
/* Depends on MIPS II instruction set */
#define mmiowb() asm volatile ("sync" ::: "memory")
#endif
static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
{

View file

@ -91,14 +91,57 @@ static inline u32 au_readl(unsigned long reg)
return *(volatile u32 *)reg;
}
/* Early Au1000 have a write-only SYS_CPUPLL register. */
static inline int au1xxx_cpu_has_pll_wo(void)
{
switch (read_c0_prid()) {
case 0x00030100: /* Au1000 DA */
case 0x00030201: /* Au1000 HA */
case 0x00030202: /* Au1000 HB */
return 1;
}
return 0;
}
/* does CPU need CONFIG[OD] set to fix tons of errata? */
static inline int au1xxx_cpu_needs_config_od(void)
{
/*
* c0_config.od (bit 19) was write only (and read as 0) on the
* early revisions of Alchemy SOCs. It disables the bus trans-
* action overlapping and needs to be set to fix various errata.
*/
switch (read_c0_prid()) {
case 0x00030100: /* Au1000 DA */
case 0x00030201: /* Au1000 HA */
case 0x00030202: /* Au1000 HB */
case 0x01030200: /* Au1500 AB */
/*
* Au1100/Au1200 errata actually keep silence about this bit,
* so we set it just in case for those revisions that require
* it to be set according to the (now gone) cpu_table.
*/
case 0x02030200: /* Au1100 AB */
case 0x02030201: /* Au1100 BA */
case 0x02030202: /* Au1100 BC */
case 0x04030201: /* Au1200 AC */
return 1;
}
return 0;
}
/* arch/mips/au1000/common/clocks.c */
extern void set_au1x00_speed(unsigned int new_freq);
extern unsigned int get_au1x00_speed(void);
extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
extern unsigned long get_au1x00_uart_baud_base(void);
extern void set_au1x00_lcd_clock(void);
extern unsigned int get_au1x00_lcd_clock(void);
extern unsigned long au1xxx_calc_clock(void);
/* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */
void au1xxx_save_and_sleep(void);
void au_sleep(void);
void save_au1xxx_intctl(void);
void restore_au1xxx_intctl(void);
/*
* Every board describes its IRQ mapping with this table.
@ -109,10 +152,11 @@ struct au1xxx_irqmap {
int im_request;
};
/*
* init_IRQ looks for a table with this name.
*/
extern struct au1xxx_irqmap au1xxx_irq_map[];
/* core calls this function to let boards initialize other IRQ sources */
void board_init_irq(void);
/* boards call this to register additional (GPIO) interrupts */
void au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count);
#endif /* !defined (_LANGUAGE_ASSEMBLY) */
@ -505,15 +549,6 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
#define IC1_TESTBIT 0xB1800080
/* Interrupt Configuration Modes */
#define INTC_INT_DISABLED 0x0
#define INTC_INT_RISE_EDGE 0x1
#define INTC_INT_FALL_EDGE 0x2
#define INTC_INT_RISE_AND_FALL_EDGE 0x3
#define INTC_INT_HIGH_LEVEL 0x5
#define INTC_INT_LOW_LEVEL 0x6
#define INTC_INT_HIGH_AND_LOW_LEVEL 0x7
/* Interrupt Numbers */
/* Au1000 */
#ifdef CONFIG_SOC_AU1000
@ -1525,6 +1560,10 @@ enum soc_au1200_ints {
#define SYS_SLPPWR 0xB1900078
#define SYS_SLEEP 0xB190007C
#define SYS_WAKEMSK_D2 (1 << 9)
#define SYS_WAKEMSK_M2 (1 << 8)
#define SYS_WAKEMSK_GPIO(x) (1 << (x))
/* Clock Controller */
#define SYS_FREQCTRL0 0xB1900020
# define SYS_FC_FRDIV2_BIT 22
@ -1749,24 +1788,4 @@ static AU1X00_SYS * const sys = (AU1X00_SYS *)SYS_BASE;
#endif
/*
* Processor information based on PRID.
* Copied from PowerPC.
*/
#ifndef _LANGUAGE_ASSEMBLY
struct cpu_spec {
/* CPU is matched via (PRID & prid_mask) == prid_value */
unsigned int prid_mask;
unsigned int prid_value;
char *cpu_name;
unsigned char cpu_od; /* Set Config[OD] */
unsigned char cpu_bclk; /* Enable BCLK switching */
unsigned char cpu_pll_wo; /* sys_cpupll reg. write-only */
};
extern struct cpu_spec cpu_specs[];
extern struct cpu_spec *cur_cpu_spec[];
#endif
#endif

View file

@ -357,6 +357,11 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr);
u32 au1xxx_ddma_add_device(dbdev_tab_t *dev);
extern void au1xxx_ddma_del_device(u32 devid);
void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
#ifdef CONFIG_PM
void au1xxx_dbdma_suspend(void);
void au1xxx_dbdma_resume(void);
#endif
/*
* Some compatibilty macros -- needed to make changes to API

View file

@ -0,0 +1,78 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004 Cavium Networks
*/
#ifndef __ASM_MACH_CAVIUM_OCTEON_CPU_FEATURE_OVERRIDES_H
#define __ASM_MACH_CAVIUM_OCTEON_CPU_FEATURE_OVERRIDES_H
#include <linux/types.h>
#include <asm/mipsregs.h>
/*
* Cavium Octeons are MIPS64v2 processors
*/
#define cpu_dcache_line_size() 128
#define cpu_icache_line_size() 128
#define cpu_has_4kex 1
#define cpu_has_3k_cache 0
#define cpu_has_4k_cache 0
#define cpu_has_tx39_cache 0
#define cpu_has_fpu 0
#define cpu_has_counter 1
#define cpu_has_watch 1
#define cpu_has_divec 1
#define cpu_has_vce 0
#define cpu_has_cache_cdex_p 0
#define cpu_has_cache_cdex_s 0
#define cpu_has_prefetch 1
/*
* We should disable LL/SC on non SMP systems as it is faster to
* disable interrupts for atomic access than a LL/SC. Unfortunatly we
* cannot as this breaks asm/futex.h
*/
#define cpu_has_llsc 1
#define cpu_has_vtag_icache 1
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 0
#define cpu_has_64bits 1
#define cpu_has_octeon_cache 1
#define cpu_has_saa octeon_has_saa()
#define cpu_has_mips32r1 0
#define cpu_has_mips32r2 0
#define cpu_has_mips64r1 0
#define cpu_has_mips64r2 1
#define cpu_has_dsp 0
#define cpu_has_mipsmt 0
#define cpu_has_userlocal 0
#define cpu_has_vint 0
#define cpu_has_veic 0
#define ARCH_HAS_READ_CURRENT_TIMER 1
#define ARCH_HAS_IRQ_PER_CPU 1
#define ARCH_HAS_SPINLOCK_PREFETCH 1
#define spin_lock_prefetch(x) prefetch(x)
#define PREFETCH_STRIDE 128
static inline int read_current_timer(unsigned long *result)
{
asm volatile ("rdhwr %0,$31\n"
#ifndef CONFIG_64BIT
"\tsll %0, 0"
#endif
: "=r" (*result));
return 0;
}
static inline int octeon_has_saa(void)
{
int id;
asm volatile ("mfc0 %0, $15,0" : "=r" (id));
return id >= 0x000d0300;
}
#endif

View file

@ -0,0 +1,64 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
*
*
* Similar to mach-generic/dma-coherence.h except
* plat_device_is_coherent hard coded to return 1.
*
*/
#ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
#define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
struct device;
dma_addr_t octeon_map_dma_mem(struct device *, void *, size_t);
void octeon_unmap_dma_mem(struct device *, dma_addr_t);
static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
size_t size)
{
return octeon_map_dma_mem(dev, addr, size);
}
static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
struct page *page)
{
return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
}
static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
{
return dma_addr;
}
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
octeon_unmap_dma_mem(dev, dma_addr);
}
static inline int plat_dma_supported(struct device *dev, u64 mask)
{
return 1;
}
static inline void plat_extra_sync_for_device(struct device *dev)
{
mb();
}
static inline int plat_device_is_coherent(struct device *dev)
{
return 1;
}
static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr)
{
return dma_addr == -1;
}
#endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */

View file

@ -0,0 +1,244 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2004-2008 Cavium Networks
*/
#ifndef __OCTEON_IRQ_H__
#define __OCTEON_IRQ_H__
#define NR_IRQS OCTEON_IRQ_LAST
#define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0
/* 0 - 7 represent the i8259 master */
#define OCTEON_IRQ_I8259M0 0
#define OCTEON_IRQ_I8259M1 1
#define OCTEON_IRQ_I8259M2 2
#define OCTEON_IRQ_I8259M3 3
#define OCTEON_IRQ_I8259M4 4
#define OCTEON_IRQ_I8259M5 5
#define OCTEON_IRQ_I8259M6 6
#define OCTEON_IRQ_I8259M7 7
/* 8 - 15 represent the i8259 slave */
#define OCTEON_IRQ_I8259S0 8
#define OCTEON_IRQ_I8259S1 9
#define OCTEON_IRQ_I8259S2 10
#define OCTEON_IRQ_I8259S3 11
#define OCTEON_IRQ_I8259S4 12
#define OCTEON_IRQ_I8259S5 13
#define OCTEON_IRQ_I8259S6 14
#define OCTEON_IRQ_I8259S7 15
/* 16 - 23 represent the 8 MIPS standard interrupt sources */
#define OCTEON_IRQ_SW0 16
#define OCTEON_IRQ_SW1 17
#define OCTEON_IRQ_CIU0 18
#define OCTEON_IRQ_CIU1 19
#define OCTEON_IRQ_CIU4 20
#define OCTEON_IRQ_5 21
#define OCTEON_IRQ_PERF 22
#define OCTEON_IRQ_TIMER 23
/* 24 - 87 represent the sources in CIU_INTX_EN0 */
#define OCTEON_IRQ_WORKQ0 24
#define OCTEON_IRQ_WORKQ1 25
#define OCTEON_IRQ_WORKQ2 26
#define OCTEON_IRQ_WORKQ3 27
#define OCTEON_IRQ_WORKQ4 28
#define OCTEON_IRQ_WORKQ5 29
#define OCTEON_IRQ_WORKQ6 30
#define OCTEON_IRQ_WORKQ7 31
#define OCTEON_IRQ_WORKQ8 32
#define OCTEON_IRQ_WORKQ9 33
#define OCTEON_IRQ_WORKQ10 34
#define OCTEON_IRQ_WORKQ11 35
#define OCTEON_IRQ_WORKQ12 36
#define OCTEON_IRQ_WORKQ13 37
#define OCTEON_IRQ_WORKQ14 38
#define OCTEON_IRQ_WORKQ15 39
#define OCTEON_IRQ_GPIO0 40
#define OCTEON_IRQ_GPIO1 41
#define OCTEON_IRQ_GPIO2 42
#define OCTEON_IRQ_GPIO3 43
#define OCTEON_IRQ_GPIO4 44
#define OCTEON_IRQ_GPIO5 45
#define OCTEON_IRQ_GPIO6 46
#define OCTEON_IRQ_GPIO7 47
#define OCTEON_IRQ_GPIO8 48
#define OCTEON_IRQ_GPIO9 49
#define OCTEON_IRQ_GPIO10 50
#define OCTEON_IRQ_GPIO11 51
#define OCTEON_IRQ_GPIO12 52
#define OCTEON_IRQ_GPIO13 53
#define OCTEON_IRQ_GPIO14 54
#define OCTEON_IRQ_GPIO15 55
#define OCTEON_IRQ_MBOX0 56
#define OCTEON_IRQ_MBOX1 57
#define OCTEON_IRQ_UART0 58
#define OCTEON_IRQ_UART1 59
#define OCTEON_IRQ_PCI_INT0 60
#define OCTEON_IRQ_PCI_INT1 61
#define OCTEON_IRQ_PCI_INT2 62
#define OCTEON_IRQ_PCI_INT3 63
#define OCTEON_IRQ_PCI_MSI0 64
#define OCTEON_IRQ_PCI_MSI1 65
#define OCTEON_IRQ_PCI_MSI2 66
#define OCTEON_IRQ_PCI_MSI3 67
#define OCTEON_IRQ_RESERVED68 68 /* Summary of CIU_INT_SUM1 */
#define OCTEON_IRQ_TWSI 69
#define OCTEON_IRQ_RML 70
#define OCTEON_IRQ_TRACE 71
#define OCTEON_IRQ_GMX_DRP0 72
#define OCTEON_IRQ_GMX_DRP1 73
#define OCTEON_IRQ_IPD_DRP 74
#define OCTEON_IRQ_KEY_ZERO 75
#define OCTEON_IRQ_TIMER0 76
#define OCTEON_IRQ_TIMER1 77
#define OCTEON_IRQ_TIMER2 78
#define OCTEON_IRQ_TIMER3 79
#define OCTEON_IRQ_USB0 80
#define OCTEON_IRQ_PCM 81
#define OCTEON_IRQ_MPI 82
#define OCTEON_IRQ_TWSI2 83
#define OCTEON_IRQ_POWIQ 84
#define OCTEON_IRQ_IPDPPTHR 85
#define OCTEON_IRQ_MII0 86
#define OCTEON_IRQ_BOOTDMA 87
/* 88 - 151 represent the sources in CIU_INTX_EN1 */
#define OCTEON_IRQ_WDOG0 88
#define OCTEON_IRQ_WDOG1 89
#define OCTEON_IRQ_WDOG2 90
#define OCTEON_IRQ_WDOG3 91
#define OCTEON_IRQ_WDOG4 92
#define OCTEON_IRQ_WDOG5 93
#define OCTEON_IRQ_WDOG6 94
#define OCTEON_IRQ_WDOG7 95
#define OCTEON_IRQ_WDOG8 96
#define OCTEON_IRQ_WDOG9 97
#define OCTEON_IRQ_WDOG10 98
#define OCTEON_IRQ_WDOG11 99
#define OCTEON_IRQ_WDOG12 100
#define OCTEON_IRQ_WDOG13 101
#define OCTEON_IRQ_WDOG14 102
#define OCTEON_IRQ_WDOG15 103
#define OCTEON_IRQ_UART2 104
#define OCTEON_IRQ_USB1 105
#define OCTEON_IRQ_MII1 106
#define OCTEON_IRQ_RESERVED107 107
#define OCTEON_IRQ_RESERVED108 108
#define OCTEON_IRQ_RESERVED109 109
#define OCTEON_IRQ_RESERVED110 110
#define OCTEON_IRQ_RESERVED111 111
#define OCTEON_IRQ_RESERVED112 112
#define OCTEON_IRQ_RESERVED113 113
#define OCTEON_IRQ_RESERVED114 114
#define OCTEON_IRQ_RESERVED115 115
#define OCTEON_IRQ_RESERVED116 116
#define OCTEON_IRQ_RESERVED117 117
#define OCTEON_IRQ_RESERVED118 118
#define OCTEON_IRQ_RESERVED119 119
#define OCTEON_IRQ_RESERVED120 120
#define OCTEON_IRQ_RESERVED121 121
#define OCTEON_IRQ_RESERVED122 122
#define OCTEON_IRQ_RESERVED123 123
#define OCTEON_IRQ_RESERVED124 124
#define OCTEON_IRQ_RESERVED125 125
#define OCTEON_IRQ_RESERVED126 126
#define OCTEON_IRQ_RESERVED127 127
#define OCTEON_IRQ_RESERVED128 128
#define OCTEON_IRQ_RESERVED129 129
#define OCTEON_IRQ_RESERVED130 130
#define OCTEON_IRQ_RESERVED131 131
#define OCTEON_IRQ_RESERVED132 132
#define OCTEON_IRQ_RESERVED133 133
#define OCTEON_IRQ_RESERVED134 134
#define OCTEON_IRQ_RESERVED135 135
#define OCTEON_IRQ_RESERVED136 136
#define OCTEON_IRQ_RESERVED137 137
#define OCTEON_IRQ_RESERVED138 138
#define OCTEON_IRQ_RESERVED139 139
#define OCTEON_IRQ_RESERVED140 140
#define OCTEON_IRQ_RESERVED141 141
#define OCTEON_IRQ_RESERVED142 142
#define OCTEON_IRQ_RESERVED143 143
#define OCTEON_IRQ_RESERVED144 144
#define OCTEON_IRQ_RESERVED145 145
#define OCTEON_IRQ_RESERVED146 146
#define OCTEON_IRQ_RESERVED147 147
#define OCTEON_IRQ_RESERVED148 148
#define OCTEON_IRQ_RESERVED149 149
#define OCTEON_IRQ_RESERVED150 150
#define OCTEON_IRQ_RESERVED151 151
#ifdef CONFIG_PCI_MSI
/* 152 - 215 represent the MSI interrupts 0-63 */
#define OCTEON_IRQ_MSI_BIT0 152
#define OCTEON_IRQ_MSI_BIT1 153
#define OCTEON_IRQ_MSI_BIT2 154
#define OCTEON_IRQ_MSI_BIT3 155
#define OCTEON_IRQ_MSI_BIT4 156
#define OCTEON_IRQ_MSI_BIT5 157
#define OCTEON_IRQ_MSI_BIT6 158
#define OCTEON_IRQ_MSI_BIT7 159
#define OCTEON_IRQ_MSI_BIT8 160
#define OCTEON_IRQ_MSI_BIT9 161
#define OCTEON_IRQ_MSI_BIT10 162
#define OCTEON_IRQ_MSI_BIT11 163
#define OCTEON_IRQ_MSI_BIT12 164
#define OCTEON_IRQ_MSI_BIT13 165
#define OCTEON_IRQ_MSI_BIT14 166
#define OCTEON_IRQ_MSI_BIT15 167
#define OCTEON_IRQ_MSI_BIT16 168
#define OCTEON_IRQ_MSI_BIT17 169
#define OCTEON_IRQ_MSI_BIT18 170
#define OCTEON_IRQ_MSI_BIT19 171
#define OCTEON_IRQ_MSI_BIT20 172
#define OCTEON_IRQ_MSI_BIT21 173
#define OCTEON_IRQ_MSI_BIT22 174
#define OCTEON_IRQ_MSI_BIT23 175
#define OCTEON_IRQ_MSI_BIT24 176
#define OCTEON_IRQ_MSI_BIT25 177
#define OCTEON_IRQ_MSI_BIT26 178
#define OCTEON_IRQ_MSI_BIT27 179
#define OCTEON_IRQ_MSI_BIT28 180
#define OCTEON_IRQ_MSI_BIT29 181
#define OCTEON_IRQ_MSI_BIT30 182
#define OCTEON_IRQ_MSI_BIT31 183
#define OCTEON_IRQ_MSI_BIT32 184
#define OCTEON_IRQ_MSI_BIT33 185
#define OCTEON_IRQ_MSI_BIT34 186
#define OCTEON_IRQ_MSI_BIT35 187
#define OCTEON_IRQ_MSI_BIT36 188
#define OCTEON_IRQ_MSI_BIT37 189
#define OCTEON_IRQ_MSI_BIT38 190
#define OCTEON_IRQ_MSI_BIT39 191
#define OCTEON_IRQ_MSI_BIT40 192
#define OCTEON_IRQ_MSI_BIT41 193
#define OCTEON_IRQ_MSI_BIT42 194
#define OCTEON_IRQ_MSI_BIT43 195
#define OCTEON_IRQ_MSI_BIT44 196
#define OCTEON_IRQ_MSI_BIT45 197
#define OCTEON_IRQ_MSI_BIT46 198
#define OCTEON_IRQ_MSI_BIT47 199
#define OCTEON_IRQ_MSI_BIT48 200
#define OCTEON_IRQ_MSI_BIT49 201
#define OCTEON_IRQ_MSI_BIT50 202
#define OCTEON_IRQ_MSI_BIT51 203
#define OCTEON_IRQ_MSI_BIT52 204
#define OCTEON_IRQ_MSI_BIT53 205
#define OCTEON_IRQ_MSI_BIT54 206
#define OCTEON_IRQ_MSI_BIT55 207
#define OCTEON_IRQ_MSI_BIT56 208
#define OCTEON_IRQ_MSI_BIT57 209
#define OCTEON_IRQ_MSI_BIT58 210
#define OCTEON_IRQ_MSI_BIT59 211
#define OCTEON_IRQ_MSI_BIT60 212
#define OCTEON_IRQ_MSI_BIT61 213
#define OCTEON_IRQ_MSI_BIT62 214
#define OCTEON_IRQ_MSI_BIT63 215
#define OCTEON_IRQ_LAST 216
#else
#define OCTEON_IRQ_LAST 152
#endif
#endif

View file

@ -0,0 +1,131 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2005-2008 Cavium Networks, Inc
*/
#ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
#define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
#define CP0_CYCLE_COUNTER $9, 6
#define CP0_CVMCTL_REG $9, 7
#define CP0_CVMMEMCTL_REG $11,7
#define CP0_PRID_REG $15, 0
#define CP0_PRID_OCTEON_PASS1 0x000d0000
#define CP0_PRID_OCTEON_CN30XX 0x000d0200
.macro kernel_entry_setup
# Registers set by bootloader:
# (only 32 bits set by bootloader, all addresses are physical
# addresses, and need to have the appropriate memory region set
# by the kernel
# a0 = argc
# a1 = argv (kseg0 compat addr)
# a2 = 1 if init core, zero otherwise
# a3 = address of boot descriptor block
.set push
.set arch=octeon
# Read the cavium mem control register
dmfc0 v0, CP0_CVMMEMCTL_REG
# Clear the lower 6 bits, the CVMSEG size
dins v0, $0, 0, 6
ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register
dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register
#ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
# Disable unaligned load/store support but leave HW fixup enabled
or v0, v0, 0x5001
xor v0, v0, 0x1001
#else
# Disable unaligned load/store and HW fixup support
or v0, v0, 0x5001
xor v0, v0, 0x5001
#endif
# Read the processor ID register
mfc0 v1, CP0_PRID_REG
# Disable instruction prefetching (Octeon Pass1 errata)
or v0, v0, 0x2000
# Skip reenable of prefetching for Octeon Pass1
beq v1, CP0_PRID_OCTEON_PASS1, skip
nop
# Reenable instruction prefetching, not on Pass1
xor v0, v0, 0x2000
# Strip off pass number off of processor id
srl v1, 8
sll v1, 8
# CN30XX needs some extra stuff turned off for better performance
bne v1, CP0_PRID_OCTEON_CN30XX, skip
nop
# CN30XX Use random Icache replacement
or v0, v0, 0x400
# CN30XX Disable instruction prefetching
or v0, v0, 0x2000
skip:
# Write the cavium control register
dmtc0 v0, CP0_CVMCTL_REG
sync
# Flush dcache after config change
cache 9, 0($0)
# Get my core id
rdhwr v0, $0
# Jump the master to kernel_entry
bne a2, zero, octeon_main_processor
nop
#ifdef CONFIG_SMP
#
# All cores other than the master need to wait here for SMP bootstrap
# to begin
#
# This is the variable where the next core to boot os stored
PTR_LA t0, octeon_processor_boot
octeon_spin_wait_boot:
# Get the core id of the next to be booted
LONG_L t1, (t0)
# Keep looping if it isn't me
bne t1, v0, octeon_spin_wait_boot
nop
# Get my GP from the global variable
PTR_LA t0, octeon_processor_gp
LONG_L gp, (t0)
# Get my SP from the global variable
PTR_LA t0, octeon_processor_sp
LONG_L sp, (t0)
# Set the SP global variable to zero so the master knows we've started
LONG_S zero, (t0)
#ifdef __OCTEON__
syncw
syncw
#else
sync
#endif
# Jump to the normal Linux SMP entry point
j smp_bootstrap
nop
#else /* CONFIG_SMP */
#
# Someone tried to boot SMP with a non SMP kernel. All extra cores
# will halt here.
#
octeon_wait_forever:
wait
b octeon_wait_forever
nop
#endif /* CONFIG_SMP */
octeon_main_processor:
.set pop
.endm
/*
* Do SMP slave processor setup necessary before we can savely execute C code.
*/
.macro smp_slave_setup
.endm
#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */

View file

@ -0,0 +1,26 @@
/*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
* Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
* Copyright (C) 2008 Cavium Networks <support@caviumnetworks.com>
*/
#ifndef __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H
#define __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H
#define R4600_V1_INDEX_ICACHEOP_WAR 0
#define R4600_V1_HIT_CACHEOP_WAR 0
#define R4600_V2_HIT_CACHEOP_WAR 0
#define R5432_CP0_INTERRUPT_WAR 0
#define BCM1250_M3_WAR 0
#define SIBYTE_1956_WAR 0
#define MIPS4K_ICACHE_REFILL_WAR 0
#define MIPS_CACHE_SYNC_WAR 0
#define TX49XX_ICACHE_INDEX_INV_WAR 0
#define RM9000_CDEX_SMP_WAR 0
#define ICACHE_REFILLS_WORKAROUND_WAR 0
#define R10000_LLSC_WAR 0
#define MIPS34K_MISSED_ITLB_WAR 0
#endif /* __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H */

View file

@ -28,10 +28,34 @@ static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return dma_addr;
}
static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
}
static inline int plat_dma_supported(struct device *dev, u64 mask)
{
/*
* we fall back to GFP_DMA when the mask isn't all 1s,
* so we can't guarantee allocations that must be
* within a tighter range than GFP_DMA..
*/
if (mask < DMA_BIT_MASK(24))
return 0;
return 1;
}
static inline void plat_extra_sync_for_device(struct device *dev)
{
return;
}
static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr)
{
return 0;
}
static inline int plat_device_is_coherent(struct device *dev)
{
#ifdef CONFIG_DMA_COHERENT

View file

@ -38,10 +38,34 @@ static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return dma_addr & ~(0xffUL << 56);
}
static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
}
static inline int plat_dma_supported(struct device *dev, u64 mask)
{
/*
* we fall back to GFP_DMA when the mask isn't all 1s,
* so we can't guarantee allocations that must be
* within a tighter range than GFP_DMA..
*/
if (mask < DMA_BIT_MASK(24))
return 0;
return 1;
}
static inline void plat_extra_sync_for_device(struct device *dev)
{
return;
}
static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr)
{
return 0;
}
static inline int plat_device_is_coherent(struct device *dev)
{
return 1; /* IP27 non-cohernet mode is unsupported */

View file

@ -60,10 +60,34 @@ static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return addr;
}
static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
}
static inline int plat_dma_supported(struct device *dev, u64 mask)
{
/*
* we fall back to GFP_DMA when the mask isn't all 1s,
* so we can't guarantee allocations that must be
* within a tighter range than GFP_DMA..
*/
if (mask < DMA_BIT_MASK(24))
return 0;
return 1;
}
static inline void plat_extra_sync_for_device(struct device *dev)
{
return;
}
static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr)
{
return 0;
}
static inline int plat_device_is_coherent(struct device *dev)
{
return 0; /* IP32 is non-cohernet */

View file

@ -27,11 +27,35 @@ static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return vdma_log2phys(dma_addr);
}
static void plat_unmap_dma_mem(dma_addr_t dma_addr)
static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
vdma_free(dma_addr);
}
static inline int plat_dma_supported(struct device *dev, u64 mask)
{
/*
* we fall back to GFP_DMA when the mask isn't all 1s,
* so we can't guarantee allocations that must be
* within a tighter range than GFP_DMA..
*/
if (mask < DMA_BIT_MASK(24))
return 0;
return 1;
}
static inline void plat_extra_sync_for_device(struct device *dev)
{
return;
}
static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr)
{
return 0;
}
static inline int plat_device_is_coherent(struct device *dev)
{
return 0;

View file

@ -30,10 +30,34 @@ static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return dma_addr & 0x7fffffff;
}
static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
}
static inline int plat_dma_supported(struct device *dev, u64 mask)
{
/*
* we fall back to GFP_DMA when the mask isn't all 1s,
* so we can't guarantee allocations that must be
* within a tighter range than GFP_DMA..
*/
if (mask < DMA_BIT_MASK(24))
return 0;
return 1;
}
static inline void plat_extra_sync_for_device(struct device *dev)
{
return;
}
static inline int plat_dma_mapping_error(struct device *dev,
dma_addr_t dma_addr)
{
return 0;
}
static inline int plat_device_is_coherent(struct device *dev)
{
return 0;

View file

@ -1000,6 +1000,26 @@ do { \
#define read_c0_ebase() __read_32bit_c0_register($15, 1)
#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val)
/* Cavium OCTEON (cnMIPS) */
#define read_c0_cvmcount() __read_ulong_c0_register($9, 6)
#define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val)
#define read_c0_cvmctl() __read_64bit_c0_register($9, 7)
#define write_c0_cvmctl(val) __write_64bit_c0_register($9, 7, val)
#define read_c0_cvmmemctl() __read_64bit_c0_register($11, 7)
#define write_c0_cvmmemctl(val) __write_64bit_c0_register($11, 7, val)
/*
* The cacheerr registers are not standardized. On OCTEON, they are
* 64 bits wide.
*/
#define read_octeon_c0_icacheerr() __read_64bit_c0_register($27, 0)
#define write_octeon_c0_icacheerr(val) __write_64bit_c0_register($27, 0, val)
#define read_octeon_c0_dcacheerr() __read_64bit_c0_register($27, 1)
#define write_octeon_c0_dcacheerr(val) __write_64bit_c0_register($27, 1, val)
/*
* Macros to access the floating point coprocessor control registers
*/
@ -1008,6 +1028,8 @@ do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\treorder\n\t" \
/* gas fails to assemble cfc1 for some archs (octeon).*/ \
".set\tmips1\n\t" \
"cfc1\t%0,"STR(source)"\n\t" \
".set\tpop" \
: "=r" (__res)); \

View file

@ -116,6 +116,8 @@ search_module_dbetables(unsigned long addr)
#define MODULE_PROC_FAMILY "SB1 "
#elif defined CONFIG_CPU_LOONGSON2
#define MODULE_PROC_FAMILY "LOONGSON2 "
#elif defined CONFIG_CPU_CAVIUM_OCTEON
#define MODULE_PROC_FAMILY "OCTEON "
#else
#error MODULE_PROC_FAMILY undefined for your processor configuration
#endif

View file

@ -0,0 +1,128 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
*
* This is file defines ASM primitives for the executive.
*/
#ifndef __CVMX_ASM_H__
#define __CVMX_ASM_H__
#include "octeon-model.h"
/* other useful stuff */
#define CVMX_SYNC asm volatile ("sync" : : : "memory")
/* String version of SYNCW macro for using in inline asm constructs */
#define CVMX_SYNCW_STR "syncw\nsyncw\n"
#ifdef __OCTEON__
/* Deprecated, will be removed in future release */
#define CVMX_SYNCIO asm volatile ("nop")
#define CVMX_SYNCIOBDMA asm volatile ("synciobdma" : : : "memory")
/* Deprecated, will be removed in future release */
#define CVMX_SYNCIOALL asm volatile ("nop")
/*
* We actually use two syncw instructions in a row when we need a write
* memory barrier. This is because the CN3XXX series of Octeons have
* errata Core-401. This can cause a single syncw to not enforce
* ordering under very rare conditions. Even if it is rare, better safe
* than sorry.
*/
#define CVMX_SYNCW asm volatile ("syncw\n\tsyncw" : : : "memory")
/*
* Define new sync instructions to be normal SYNC instructions for
* operating systems that use threads.
*/
#define CVMX_SYNCWS CVMX_SYNCW
#define CVMX_SYNCS CVMX_SYNC
#define CVMX_SYNCWS_STR CVMX_SYNCW_STR
#else
/*
* Not using a Cavium compiler, always use the slower sync so the
* assembler stays happy.
*/
/* Deprecated, will be removed in future release */
#define CVMX_SYNCIO asm volatile ("nop")
#define CVMX_SYNCIOBDMA asm volatile ("sync" : : : "memory")
/* Deprecated, will be removed in future release */
#define CVMX_SYNCIOALL asm volatile ("nop")
#define CVMX_SYNCW asm volatile ("sync" : : : "memory")
#define CVMX_SYNCWS CVMX_SYNCW
#define CVMX_SYNCS CVMX_SYNC
#define CVMX_SYNCWS_STR CVMX_SYNCW_STR
#endif
/*
* CVMX_PREPARE_FOR_STORE makes each byte of the block unpredictable
* (actually old value or zero) until that byte is stored to (by this or
* another processor. Note that the value of each byte is not only
* unpredictable, but may also change again - up until the point when one
* of the cores stores to the byte.
*/
#define CVMX_PREPARE_FOR_STORE(address, offset) \
asm volatile ("pref 30, " CVMX_TMP_STR(offset) "(%[rbase])" : : \
[rbase] "d" (address))
/*
* This is a command headed to the L2 controller to tell it to clear
* its dirty bit for a block. Basically, SW is telling HW that the
* current version of the block will not be used.
*/
#define CVMX_DONT_WRITE_BACK(address, offset) \
asm volatile ("pref 29, " CVMX_TMP_STR(offset) "(%[rbase])" : : \
[rbase] "d" (address))
/* flush stores, invalidate entire icache */
#define CVMX_ICACHE_INVALIDATE \
{ CVMX_SYNC; asm volatile ("synci 0($0)" : : ); }
/* flush stores, invalidate entire icache */
#define CVMX_ICACHE_INVALIDATE2 \
{ CVMX_SYNC; asm volatile ("cache 0, 0($0)" : : ); }
/* complete prefetches, invalidate entire dcache */
#define CVMX_DCACHE_INVALIDATE \
{ CVMX_SYNC; asm volatile ("cache 9, 0($0)" : : ); }
#define CVMX_POP(result, input) \
asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
#define CVMX_DPOP(result, input) \
asm ("dpop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
/* some new cop0-like stuff */
#define CVMX_RDHWR(result, regstr) \
asm volatile ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result))
#define CVMX_RDHWRNV(result, regstr) \
asm ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result))
#endif /* __CVMX_ASM_H__ */

View file

@ -0,0 +1,262 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* Header file containing the ABI with the bootloader.
*/
#ifndef __CVMX_BOOTINFO_H__
#define __CVMX_BOOTINFO_H__
/*
* Current major and minor versions of the CVMX bootinfo block that is
* passed from the bootloader to the application. This is versioned
* so that applications can properly handle multiple bootloader
* versions.
*/
#define CVMX_BOOTINFO_MAJ_VER 1
#define CVMX_BOOTINFO_MIN_VER 2
#if (CVMX_BOOTINFO_MAJ_VER == 1)
#define CVMX_BOOTINFO_OCTEON_SERIAL_LEN 20
/*
* This structure is populated by the bootloader. For binary
* compatibility the only changes that should be made are
* adding members to the end of the structure, and the minor
* version should be incremented at that time.
* If an incompatible change is made, the major version
* must be incremented, and the minor version should be reset
* to 0.
*/
struct cvmx_bootinfo {
uint32_t major_version;
uint32_t minor_version;
uint64_t stack_top;
uint64_t heap_base;
uint64_t heap_end;
uint64_t desc_vaddr;
uint32_t exception_base_addr;
uint32_t stack_size;
uint32_t flags;
uint32_t core_mask;
/* DRAM size in megabytes */
uint32_t dram_size;
/* physical address of free memory descriptor block*/
uint32_t phy_mem_desc_addr;
/* used to pass flags from app to debugger */
uint32_t debugger_flags_base_addr;
/* CPU clock speed, in hz */
uint32_t eclock_hz;
/* DRAM clock speed, in hz */
uint32_t dclock_hz;
uint32_t reserved0;
uint16_t board_type;
uint8_t board_rev_major;
uint8_t board_rev_minor;
uint16_t reserved1;
uint8_t reserved2;
uint8_t reserved3;
char board_serial_number[CVMX_BOOTINFO_OCTEON_SERIAL_LEN];
uint8_t mac_addr_base[6];
uint8_t mac_addr_count;
#if (CVMX_BOOTINFO_MIN_VER >= 1)
/*
* Several boards support compact flash on the Octeon boot
* bus. The CF memory spaces may be mapped to different
* addresses on different boards. These are the physical
* addresses, so care must be taken to use the correct
* XKPHYS/KSEG0 addressing depending on the application's
* ABI. These values will be 0 if CF is not present.
*/
uint64_t compact_flash_common_base_addr;
uint64_t compact_flash_attribute_base_addr;
/*
* Base address of the LED display (as on EBT3000 board)
* This will be 0 if LED display not present.
*/
uint64_t led_display_base_addr;
#endif
#if (CVMX_BOOTINFO_MIN_VER >= 2)
/* DFA reference clock in hz (if applicable)*/
uint32_t dfa_ref_clock_hz;
/*
* flags indicating various configuration options. These
* flags supercede the 'flags' variable and should be used
* instead if available.
*/
uint32_t config_flags;
#endif
};
#define CVMX_BOOTINFO_CFG_FLAG_PCI_HOST (1ull << 0)
#define CVMX_BOOTINFO_CFG_FLAG_PCI_TARGET (1ull << 1)
#define CVMX_BOOTINFO_CFG_FLAG_DEBUG (1ull << 2)
#define CVMX_BOOTINFO_CFG_FLAG_NO_MAGIC (1ull << 3)
/* This flag is set if the TLB mappings are not contained in the
* 0x10000000 - 0x20000000 boot bus region. */
#define CVMX_BOOTINFO_CFG_FLAG_OVERSIZE_TLB_MAPPING (1ull << 4)
#define CVMX_BOOTINFO_CFG_FLAG_BREAK (1ull << 5)
#endif /* (CVMX_BOOTINFO_MAJ_VER == 1) */
/* Type defines for board and chip types */
enum cvmx_board_types_enum {
CVMX_BOARD_TYPE_NULL = 0,
CVMX_BOARD_TYPE_SIM = 1,
CVMX_BOARD_TYPE_EBT3000 = 2,
CVMX_BOARD_TYPE_KODAMA = 3,
CVMX_BOARD_TYPE_NIAGARA = 4,
CVMX_BOARD_TYPE_NAC38 = 5, /* formerly NAO38 */
CVMX_BOARD_TYPE_THUNDER = 6,
CVMX_BOARD_TYPE_TRANTOR = 7,
CVMX_BOARD_TYPE_EBH3000 = 8,
CVMX_BOARD_TYPE_EBH3100 = 9,
CVMX_BOARD_TYPE_HIKARI = 10,
CVMX_BOARD_TYPE_CN3010_EVB_HS5 = 11,
CVMX_BOARD_TYPE_CN3005_EVB_HS5 = 12,
CVMX_BOARD_TYPE_KBP = 13,
/* Deprecated, CVMX_BOARD_TYPE_CN3010_EVB_HS5 supports the CN3020 */
CVMX_BOARD_TYPE_CN3020_EVB_HS5 = 14,
CVMX_BOARD_TYPE_EBT5800 = 15,
CVMX_BOARD_TYPE_NICPRO2 = 16,
CVMX_BOARD_TYPE_EBH5600 = 17,
CVMX_BOARD_TYPE_EBH5601 = 18,
CVMX_BOARD_TYPE_EBH5200 = 19,
CVMX_BOARD_TYPE_BBGW_REF = 20,
CVMX_BOARD_TYPE_NIC_XLE_4G = 21,
CVMX_BOARD_TYPE_EBT5600 = 22,
CVMX_BOARD_TYPE_EBH5201 = 23,
CVMX_BOARD_TYPE_MAX,
/*
* The range from CVMX_BOARD_TYPE_MAX to
* CVMX_BOARD_TYPE_CUST_DEFINED_MIN is reserved for future
* SDK use.
*/
/*
* Set aside a range for customer boards. These numbers are managed
* by Cavium.
*/
CVMX_BOARD_TYPE_CUST_DEFINED_MIN = 10000,
CVMX_BOARD_TYPE_CUST_WSX16 = 10001,
CVMX_BOARD_TYPE_CUST_NS0216 = 10002,
CVMX_BOARD_TYPE_CUST_NB5 = 10003,
CVMX_BOARD_TYPE_CUST_WMR500 = 10004,
CVMX_BOARD_TYPE_CUST_DEFINED_MAX = 20000,
/*
* Set aside a range for customer private use. The SDK won't
* use any numbers in this range.
*/
CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
/* The remaining range is reserved for future use. */
};
enum cvmx_chip_types_enum {
CVMX_CHIP_TYPE_NULL = 0,
CVMX_CHIP_SIM_TYPE_DEPRECATED = 1,
CVMX_CHIP_TYPE_OCTEON_SAMPLE = 2,
CVMX_CHIP_TYPE_MAX,
};
/* Compatability alias for NAC38 name change, planned to be removed
* from SDK 1.7 */
#define CVMX_BOARD_TYPE_NAO38 CVMX_BOARD_TYPE_NAC38
/* Functions to return string based on type */
#define ENUM_BRD_TYPE_CASE(x) \
case x: return(#x + 16); /* Skip CVMX_BOARD_TYPE_ */
static inline const char *cvmx_board_type_to_string(enum
cvmx_board_types_enum type)
{
switch (type) {
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NULL)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_SIM)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT3000)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KODAMA)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIAGARA)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NAC38)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_THUNDER)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_TRANTOR)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH3000)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH3100)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_HIKARI)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3010_EVB_HS5)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3005_EVB_HS5)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KBP)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3020_EVB_HS5)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5800)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NICPRO2)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5600)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5601)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5200)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_BBGW_REF)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC_XLE_4G)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5600)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5201)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_MAX)
/* Customer boards listed here */
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DEFINED_MIN)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_WSX16)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NS0216)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NB5)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_WMR500)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DEFINED_MAX)
/* Customer private range */
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
}
return "Unsupported Board";
}
#define ENUM_CHIP_TYPE_CASE(x) \
case x: return(#x + 15); /* Skip CVMX_CHIP_TYPE */
static inline const char *cvmx_chip_type_to_string(enum
cvmx_chip_types_enum type)
{
switch (type) {
ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_NULL)
ENUM_CHIP_TYPE_CASE(CVMX_CHIP_SIM_TYPE_DEPRECATED)
ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_OCTEON_SAMPLE)
ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_MAX)
}
return "Unsupported Chip";
}
#endif /* __CVMX_BOOTINFO_H__ */

View file

@ -0,0 +1,288 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* Simple allocate only memory allocator. Used to allocate memory at
* application start time.
*/
#ifndef __CVMX_BOOTMEM_H__
#define __CVMX_BOOTMEM_H__
/* Must be multiple of 8, changing breaks ABI */
#define CVMX_BOOTMEM_NAME_LEN 128
/* Can change without breaking ABI */
#define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64
/* minimum alignment of bootmem alloced blocks */
#define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull)
/* Flags for cvmx_bootmem_phy_mem* functions */
/* Allocate from end of block instead of beginning */
#define CVMX_BOOTMEM_FLAG_END_ALLOC (1 << 0)
/* Don't do any locking. */
#define CVMX_BOOTMEM_FLAG_NO_LOCKING (1 << 1)
/* First bytes of each free physical block of memory contain this structure,
* which is used to maintain the free memory list. Since the bootloader is
* only 32 bits, there is a union providing 64 and 32 bit versions. The
* application init code converts addresses to 64 bit addresses before the
* application starts.
*/
struct cvmx_bootmem_block_header {
/*
* Note: these are referenced from assembly routines in the
* bootloader, so this structure should not be changed
* without changing those routines as well.
*/
uint64_t next_block_addr;
uint64_t size;
};
/*
* Structure for named memory blocks. Number of descriptors available
* can be changed without affecting compatiblity, but name length
* changes require a bump in the bootmem descriptor version Note: This
* structure must be naturally 64 bit aligned, as a single memory
* image will be used by both 32 and 64 bit programs.
*/
struct cvmx_bootmem_named_block_desc {
/* Base address of named block */
uint64_t base_addr;
/*
* Size actually allocated for named block (may differ from
* requested).
*/
uint64_t size;
/* name of named block */
char name[CVMX_BOOTMEM_NAME_LEN];
};
/* Current descriptor versions */
/* CVMX bootmem descriptor major version */
#define CVMX_BOOTMEM_DESC_MAJ_VER 3
/* CVMX bootmem descriptor minor version */
#define CVMX_BOOTMEM_DESC_MIN_VER 0
/* First three members of cvmx_bootmem_desc_t are left in original
* positions for backwards compatibility.
*/
struct cvmx_bootmem_desc {
/* spinlock to control access to list */
uint32_t lock;
/* flags for indicating various conditions */
uint32_t flags;
uint64_t head_addr;
/* Incremented when incompatible changes made */
uint32_t major_version;
/*
* Incremented changed when compatible changes made, reset to
* zero when major incremented.
*/
uint32_t minor_version;
uint64_t app_data_addr;
uint64_t app_data_size;
/* number of elements in named blocks array */
uint32_t named_block_num_blocks;
/* length of name array in bootmem blocks */
uint32_t named_block_name_len;
/* address of named memory block descriptors */
uint64_t named_block_array_addr;
};
/**
* Initialize the boot alloc memory structures. This is
* normally called inside of cvmx_user_app_init()
*
* @mem_desc_ptr: Address of the free memory list
*/
extern int cvmx_bootmem_init(void *mem_desc_ptr);
/**
* Allocate a block of memory from the free list that was passed
* to the application by the bootloader.
* This is an allocate-only algorithm, so freeing memory is not possible.
*
* @size: Size in bytes of block to allocate
* @alignment: Alignment required - must be power of 2
*
* Returns pointer to block of memory, NULL on error
*/
extern void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment);
/**
* Allocate a block of memory from the free list that was
* passed to the application by the bootloader at a specific
* address. This is an allocate-only algorithm, so
* freeing memory is not possible. Allocation will fail if
* memory cannot be allocated at the specified address.
*
* @size: Size in bytes of block to allocate
* @address: Physical address to allocate memory at. If this memory is not
* available, the allocation fails.
* @alignment: Alignment required - must be power of 2
* Returns pointer to block of memory, NULL on error
*/
extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address,
uint64_t alignment);
/**
* Allocate a block of memory from the free list that was
* passed to the application by the bootloader within a specified
* address range. This is an allocate-only algorithm, so
* freeing memory is not possible. Allocation will fail if
* memory cannot be allocated in the requested range.
*
* @size: Size in bytes of block to allocate
* @min_addr: defines the minimum address of the range
* @max_addr: defines the maximum address of the range
* @alignment: Alignment required - must be power of 2
* Returns pointer to block of memory, NULL on error
*/
extern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment,
uint64_t min_addr, uint64_t max_addr);
/**
* Frees a previously allocated named bootmem block.
*
* @name: name of block to free
*
* Returns 0 on failure,
* !0 on success
*/
extern int cvmx_bootmem_free_named(char *name);
/**
* Finds a named bootmem block by name.
*
* @name: name of block to free
*
* Returns pointer to named block descriptor on success
* 0 on failure
*/
struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name);
/**
* Allocates a block of physical memory from the free list, at
* (optional) requested address and alignment.
*
* @req_size: size of region to allocate. All requests are rounded up
* to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size
*
* @address_min: Minimum address that block can occupy.
*
* @address_max: Specifies the maximum address_min (inclusive) that
* the allocation can use.
*
* @alignment: Requested alignment of the block. If this alignment
* cannot be met, the allocation fails. This must be a
* power of 2. (Note: Alignment of
* CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
* internally enforced. Requested alignments of less than
* CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
* CVMX_BOOTMEM_ALIGNMENT_SIZE.)
*
* @flags: Flags to control options for the allocation.
*
* Returns physical address of block allocated, or -1 on failure
*/
int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min,
uint64_t address_max, uint64_t alignment,
uint32_t flags);
/**
* Finds a named memory block by name.
* Also used for finding an unused entry in the named block table.
*
* @name: Name of memory block to find. If NULL pointer given, then
* finds unused descriptor, if available.
*
* @flags: Flags to control options for the allocation.
*
* Returns Pointer to memory block descriptor, NULL if not found.
* If NULL returned when name parameter is NULL, then no memory
* block descriptors are available.
*/
struct cvmx_bootmem_named_block_desc *
cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags);
/**
* Frees a named block.
*
* @name: name of block to free
* @flags: flags for passing options
*
* Returns 0 on failure
* 1 on success
*/
int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags);
/**
* Frees a block to the bootmem allocator list. This must
* be used with care, as the size provided must match the size
* of the block that was allocated, or the list will become
* corrupted.
*
* IMPORTANT: This is only intended to be used as part of named block
* frees and initial population of the free memory list.
* *
*
* @phy_addr: physical address of block
* @size: size of block in bytes.
* @flags: flags for passing options
*
* Returns 1 on success,
* 0 on failure
*/
int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags);
/**
* Locks the bootmem allocator. This is useful in certain situations
* where multiple allocations must be made without being interrupted.
* This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
*
*/
void cvmx_bootmem_lock(void);
/**
* Unlocks the bootmem allocator. This is useful in certain situations
* where multiple allocations must be made without being interrupted.
* This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
*
*/
void cvmx_bootmem_unlock(void);
#endif /* __CVMX_BOOTMEM_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,219 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_GPIO_DEFS_H__
#define __CVMX_GPIO_DEFS_H__
#define CVMX_GPIO_BIT_CFGX(offset) \
CVMX_ADD_IO_SEG(0x0001070000000800ull + (((offset) & 15) * 8))
#define CVMX_GPIO_BOOT_ENA \
CVMX_ADD_IO_SEG(0x00010700000008A8ull)
#define CVMX_GPIO_CLK_GENX(offset) \
CVMX_ADD_IO_SEG(0x00010700000008C0ull + (((offset) & 3) * 8))
#define CVMX_GPIO_DBG_ENA \
CVMX_ADD_IO_SEG(0x00010700000008A0ull)
#define CVMX_GPIO_INT_CLR \
CVMX_ADD_IO_SEG(0x0001070000000898ull)
#define CVMX_GPIO_RX_DAT \
CVMX_ADD_IO_SEG(0x0001070000000880ull)
#define CVMX_GPIO_TX_CLR \
CVMX_ADD_IO_SEG(0x0001070000000890ull)
#define CVMX_GPIO_TX_SET \
CVMX_ADD_IO_SEG(0x0001070000000888ull)
#define CVMX_GPIO_XBIT_CFGX(offset) \
CVMX_ADD_IO_SEG(0x0001070000000900ull + (((offset) & 31) * 8) - 8 * 16)
union cvmx_gpio_bit_cfgx {
uint64_t u64;
struct cvmx_gpio_bit_cfgx_s {
uint64_t reserved_15_63:49;
uint64_t clk_gen:1;
uint64_t clk_sel:2;
uint64_t fil_sel:4;
uint64_t fil_cnt:4;
uint64_t int_type:1;
uint64_t int_en:1;
uint64_t rx_xor:1;
uint64_t tx_oe:1;
} s;
struct cvmx_gpio_bit_cfgx_cn30xx {
uint64_t reserved_12_63:52;
uint64_t fil_sel:4;
uint64_t fil_cnt:4;
uint64_t int_type:1;
uint64_t int_en:1;
uint64_t rx_xor:1;
uint64_t tx_oe:1;
} cn30xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn31xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn38xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2;
struct cvmx_gpio_bit_cfgx_cn30xx cn50xx;
struct cvmx_gpio_bit_cfgx_s cn52xx;
struct cvmx_gpio_bit_cfgx_s cn52xxp1;
struct cvmx_gpio_bit_cfgx_s cn56xx;
struct cvmx_gpio_bit_cfgx_s cn56xxp1;
struct cvmx_gpio_bit_cfgx_cn30xx cn58xx;
struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1;
};
union cvmx_gpio_boot_ena {
uint64_t u64;
struct cvmx_gpio_boot_ena_s {
uint64_t reserved_12_63:52;
uint64_t boot_ena:4;
uint64_t reserved_0_7:8;
} s;
struct cvmx_gpio_boot_ena_s cn30xx;
struct cvmx_gpio_boot_ena_s cn31xx;
struct cvmx_gpio_boot_ena_s cn50xx;
};
union cvmx_gpio_clk_genx {
uint64_t u64;
struct cvmx_gpio_clk_genx_s {
uint64_t reserved_32_63:32;
uint64_t n:32;
} s;
struct cvmx_gpio_clk_genx_s cn52xx;
struct cvmx_gpio_clk_genx_s cn52xxp1;
struct cvmx_gpio_clk_genx_s cn56xx;
struct cvmx_gpio_clk_genx_s cn56xxp1;
};
union cvmx_gpio_dbg_ena {
uint64_t u64;
struct cvmx_gpio_dbg_ena_s {
uint64_t reserved_21_63:43;
uint64_t dbg_ena:21;
} s;
struct cvmx_gpio_dbg_ena_s cn30xx;
struct cvmx_gpio_dbg_ena_s cn31xx;
struct cvmx_gpio_dbg_ena_s cn50xx;
};
union cvmx_gpio_int_clr {
uint64_t u64;
struct cvmx_gpio_int_clr_s {
uint64_t reserved_16_63:48;
uint64_t type:16;
} s;
struct cvmx_gpio_int_clr_s cn30xx;
struct cvmx_gpio_int_clr_s cn31xx;
struct cvmx_gpio_int_clr_s cn38xx;
struct cvmx_gpio_int_clr_s cn38xxp2;
struct cvmx_gpio_int_clr_s cn50xx;
struct cvmx_gpio_int_clr_s cn52xx;
struct cvmx_gpio_int_clr_s cn52xxp1;
struct cvmx_gpio_int_clr_s cn56xx;
struct cvmx_gpio_int_clr_s cn56xxp1;
struct cvmx_gpio_int_clr_s cn58xx;
struct cvmx_gpio_int_clr_s cn58xxp1;
};
union cvmx_gpio_rx_dat {
uint64_t u64;
struct cvmx_gpio_rx_dat_s {
uint64_t reserved_24_63:40;
uint64_t dat:24;
} s;
struct cvmx_gpio_rx_dat_s cn30xx;
struct cvmx_gpio_rx_dat_s cn31xx;
struct cvmx_gpio_rx_dat_cn38xx {
uint64_t reserved_16_63:48;
uint64_t dat:16;
} cn38xx;
struct cvmx_gpio_rx_dat_cn38xx cn38xxp2;
struct cvmx_gpio_rx_dat_s cn50xx;
struct cvmx_gpio_rx_dat_cn38xx cn52xx;
struct cvmx_gpio_rx_dat_cn38xx cn52xxp1;
struct cvmx_gpio_rx_dat_cn38xx cn56xx;
struct cvmx_gpio_rx_dat_cn38xx cn56xxp1;
struct cvmx_gpio_rx_dat_cn38xx cn58xx;
struct cvmx_gpio_rx_dat_cn38xx cn58xxp1;
};
union cvmx_gpio_tx_clr {
uint64_t u64;
struct cvmx_gpio_tx_clr_s {
uint64_t reserved_24_63:40;
uint64_t clr:24;
} s;
struct cvmx_gpio_tx_clr_s cn30xx;
struct cvmx_gpio_tx_clr_s cn31xx;
struct cvmx_gpio_tx_clr_cn38xx {
uint64_t reserved_16_63:48;
uint64_t clr:16;
} cn38xx;
struct cvmx_gpio_tx_clr_cn38xx cn38xxp2;
struct cvmx_gpio_tx_clr_s cn50xx;
struct cvmx_gpio_tx_clr_cn38xx cn52xx;
struct cvmx_gpio_tx_clr_cn38xx cn52xxp1;
struct cvmx_gpio_tx_clr_cn38xx cn56xx;
struct cvmx_gpio_tx_clr_cn38xx cn56xxp1;
struct cvmx_gpio_tx_clr_cn38xx cn58xx;
struct cvmx_gpio_tx_clr_cn38xx cn58xxp1;
};
union cvmx_gpio_tx_set {
uint64_t u64;
struct cvmx_gpio_tx_set_s {
uint64_t reserved_24_63:40;
uint64_t set:24;
} s;
struct cvmx_gpio_tx_set_s cn30xx;
struct cvmx_gpio_tx_set_s cn31xx;
struct cvmx_gpio_tx_set_cn38xx {
uint64_t reserved_16_63:48;
uint64_t set:16;
} cn38xx;
struct cvmx_gpio_tx_set_cn38xx cn38xxp2;
struct cvmx_gpio_tx_set_s cn50xx;
struct cvmx_gpio_tx_set_cn38xx cn52xx;
struct cvmx_gpio_tx_set_cn38xx cn52xxp1;
struct cvmx_gpio_tx_set_cn38xx cn56xx;
struct cvmx_gpio_tx_set_cn38xx cn56xxp1;
struct cvmx_gpio_tx_set_cn38xx cn58xx;
struct cvmx_gpio_tx_set_cn38xx cn58xxp1;
};
union cvmx_gpio_xbit_cfgx {
uint64_t u64;
struct cvmx_gpio_xbit_cfgx_s {
uint64_t reserved_12_63:52;
uint64_t fil_sel:4;
uint64_t fil_cnt:4;
uint64_t reserved_2_3:2;
uint64_t rx_xor:1;
uint64_t tx_oe:1;
} s;
struct cvmx_gpio_xbit_cfgx_s cn30xx;
struct cvmx_gpio_xbit_cfgx_s cn31xx;
struct cvmx_gpio_xbit_cfgx_s cn50xx;
};
#endif

View file

@ -0,0 +1,530 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_IOB_DEFS_H__
#define __CVMX_IOB_DEFS_H__
#define CVMX_IOB_BIST_STATUS \
CVMX_ADD_IO_SEG(0x00011800F00007F8ull)
#define CVMX_IOB_CTL_STATUS \
CVMX_ADD_IO_SEG(0x00011800F0000050ull)
#define CVMX_IOB_DWB_PRI_CNT \
CVMX_ADD_IO_SEG(0x00011800F0000028ull)
#define CVMX_IOB_FAU_TIMEOUT \
CVMX_ADD_IO_SEG(0x00011800F0000000ull)
#define CVMX_IOB_I2C_PRI_CNT \
CVMX_ADD_IO_SEG(0x00011800F0000010ull)
#define CVMX_IOB_INB_CONTROL_MATCH \
CVMX_ADD_IO_SEG(0x00011800F0000078ull)
#define CVMX_IOB_INB_CONTROL_MATCH_ENB \
CVMX_ADD_IO_SEG(0x00011800F0000088ull)
#define CVMX_IOB_INB_DATA_MATCH \
CVMX_ADD_IO_SEG(0x00011800F0000070ull)
#define CVMX_IOB_INB_DATA_MATCH_ENB \
CVMX_ADD_IO_SEG(0x00011800F0000080ull)
#define CVMX_IOB_INT_ENB \
CVMX_ADD_IO_SEG(0x00011800F0000060ull)
#define CVMX_IOB_INT_SUM \
CVMX_ADD_IO_SEG(0x00011800F0000058ull)
#define CVMX_IOB_N2C_L2C_PRI_CNT \
CVMX_ADD_IO_SEG(0x00011800F0000020ull)
#define CVMX_IOB_N2C_RSP_PRI_CNT \
CVMX_ADD_IO_SEG(0x00011800F0000008ull)
#define CVMX_IOB_OUTB_COM_PRI_CNT \
CVMX_ADD_IO_SEG(0x00011800F0000040ull)
#define CVMX_IOB_OUTB_CONTROL_MATCH \
CVMX_ADD_IO_SEG(0x00011800F0000098ull)
#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB \
CVMX_ADD_IO_SEG(0x00011800F00000A8ull)
#define CVMX_IOB_OUTB_DATA_MATCH \
CVMX_ADD_IO_SEG(0x00011800F0000090ull)
#define CVMX_IOB_OUTB_DATA_MATCH_ENB \
CVMX_ADD_IO_SEG(0x00011800F00000A0ull)
#define CVMX_IOB_OUTB_FPA_PRI_CNT \
CVMX_ADD_IO_SEG(0x00011800F0000048ull)
#define CVMX_IOB_OUTB_REQ_PRI_CNT \
CVMX_ADD_IO_SEG(0x00011800F0000038ull)
#define CVMX_IOB_P2C_REQ_PRI_CNT \
CVMX_ADD_IO_SEG(0x00011800F0000018ull)
#define CVMX_IOB_PKT_ERR \
CVMX_ADD_IO_SEG(0x00011800F0000068ull)
union cvmx_iob_bist_status {
uint64_t u64;
struct cvmx_iob_bist_status_s {
uint64_t reserved_18_63:46;
uint64_t icnrcb:1;
uint64_t icr0:1;
uint64_t icr1:1;
uint64_t icnr1:1;
uint64_t icnr0:1;
uint64_t ibdr0:1;
uint64_t ibdr1:1;
uint64_t ibr0:1;
uint64_t ibr1:1;
uint64_t icnrt:1;
uint64_t ibrq0:1;
uint64_t ibrq1:1;
uint64_t icrn0:1;
uint64_t icrn1:1;
uint64_t icrp0:1;
uint64_t icrp1:1;
uint64_t ibd:1;
uint64_t icd:1;
} s;
struct cvmx_iob_bist_status_s cn30xx;
struct cvmx_iob_bist_status_s cn31xx;
struct cvmx_iob_bist_status_s cn38xx;
struct cvmx_iob_bist_status_s cn38xxp2;
struct cvmx_iob_bist_status_s cn50xx;
struct cvmx_iob_bist_status_s cn52xx;
struct cvmx_iob_bist_status_s cn52xxp1;
struct cvmx_iob_bist_status_s cn56xx;
struct cvmx_iob_bist_status_s cn56xxp1;
struct cvmx_iob_bist_status_s cn58xx;
struct cvmx_iob_bist_status_s cn58xxp1;
};
union cvmx_iob_ctl_status {
uint64_t u64;
struct cvmx_iob_ctl_status_s {
uint64_t reserved_5_63:59;
uint64_t outb_mat:1;
uint64_t inb_mat:1;
uint64_t pko_enb:1;
uint64_t dwb_enb:1;
uint64_t fau_end:1;
} s;
struct cvmx_iob_ctl_status_s cn30xx;
struct cvmx_iob_ctl_status_s cn31xx;
struct cvmx_iob_ctl_status_s cn38xx;
struct cvmx_iob_ctl_status_s cn38xxp2;
struct cvmx_iob_ctl_status_s cn50xx;
struct cvmx_iob_ctl_status_s cn52xx;
struct cvmx_iob_ctl_status_s cn52xxp1;
struct cvmx_iob_ctl_status_s cn56xx;
struct cvmx_iob_ctl_status_s cn56xxp1;
struct cvmx_iob_ctl_status_s cn58xx;
struct cvmx_iob_ctl_status_s cn58xxp1;
};
union cvmx_iob_dwb_pri_cnt {
uint64_t u64;
struct cvmx_iob_dwb_pri_cnt_s {
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
} s;
struct cvmx_iob_dwb_pri_cnt_s cn38xx;
struct cvmx_iob_dwb_pri_cnt_s cn38xxp2;
struct cvmx_iob_dwb_pri_cnt_s cn52xx;
struct cvmx_iob_dwb_pri_cnt_s cn52xxp1;
struct cvmx_iob_dwb_pri_cnt_s cn56xx;
struct cvmx_iob_dwb_pri_cnt_s cn56xxp1;
struct cvmx_iob_dwb_pri_cnt_s cn58xx;
struct cvmx_iob_dwb_pri_cnt_s cn58xxp1;
};
union cvmx_iob_fau_timeout {
uint64_t u64;
struct cvmx_iob_fau_timeout_s {
uint64_t reserved_13_63:51;
uint64_t tout_enb:1;
uint64_t tout_val:12;
} s;
struct cvmx_iob_fau_timeout_s cn30xx;
struct cvmx_iob_fau_timeout_s cn31xx;
struct cvmx_iob_fau_timeout_s cn38xx;
struct cvmx_iob_fau_timeout_s cn38xxp2;
struct cvmx_iob_fau_timeout_s cn50xx;
struct cvmx_iob_fau_timeout_s cn52xx;
struct cvmx_iob_fau_timeout_s cn52xxp1;
struct cvmx_iob_fau_timeout_s cn56xx;
struct cvmx_iob_fau_timeout_s cn56xxp1;
struct cvmx_iob_fau_timeout_s cn58xx;
struct cvmx_iob_fau_timeout_s cn58xxp1;
};
union cvmx_iob_i2c_pri_cnt {
uint64_t u64;
struct cvmx_iob_i2c_pri_cnt_s {
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
} s;
struct cvmx_iob_i2c_pri_cnt_s cn38xx;
struct cvmx_iob_i2c_pri_cnt_s cn38xxp2;
struct cvmx_iob_i2c_pri_cnt_s cn52xx;
struct cvmx_iob_i2c_pri_cnt_s cn52xxp1;
struct cvmx_iob_i2c_pri_cnt_s cn56xx;
struct cvmx_iob_i2c_pri_cnt_s cn56xxp1;
struct cvmx_iob_i2c_pri_cnt_s cn58xx;
struct cvmx_iob_i2c_pri_cnt_s cn58xxp1;
};
union cvmx_iob_inb_control_match {
uint64_t u64;
struct cvmx_iob_inb_control_match_s {
uint64_t reserved_29_63:35;
uint64_t mask:8;
uint64_t opc:4;
uint64_t dst:9;
uint64_t src:8;
} s;
struct cvmx_iob_inb_control_match_s cn30xx;
struct cvmx_iob_inb_control_match_s cn31xx;
struct cvmx_iob_inb_control_match_s cn38xx;
struct cvmx_iob_inb_control_match_s cn38xxp2;
struct cvmx_iob_inb_control_match_s cn50xx;
struct cvmx_iob_inb_control_match_s cn52xx;
struct cvmx_iob_inb_control_match_s cn52xxp1;
struct cvmx_iob_inb_control_match_s cn56xx;
struct cvmx_iob_inb_control_match_s cn56xxp1;
struct cvmx_iob_inb_control_match_s cn58xx;
struct cvmx_iob_inb_control_match_s cn58xxp1;
};
union cvmx_iob_inb_control_match_enb {
uint64_t u64;
struct cvmx_iob_inb_control_match_enb_s {
uint64_t reserved_29_63:35;
uint64_t mask:8;
uint64_t opc:4;
uint64_t dst:9;
uint64_t src:8;
} s;
struct cvmx_iob_inb_control_match_enb_s cn30xx;
struct cvmx_iob_inb_control_match_enb_s cn31xx;
struct cvmx_iob_inb_control_match_enb_s cn38xx;
struct cvmx_iob_inb_control_match_enb_s cn38xxp2;
struct cvmx_iob_inb_control_match_enb_s cn50xx;
struct cvmx_iob_inb_control_match_enb_s cn52xx;
struct cvmx_iob_inb_control_match_enb_s cn52xxp1;
struct cvmx_iob_inb_control_match_enb_s cn56xx;
struct cvmx_iob_inb_control_match_enb_s cn56xxp1;
struct cvmx_iob_inb_control_match_enb_s cn58xx;
struct cvmx_iob_inb_control_match_enb_s cn58xxp1;
};
union cvmx_iob_inb_data_match {
uint64_t u64;
struct cvmx_iob_inb_data_match_s {
uint64_t data:64;
} s;
struct cvmx_iob_inb_data_match_s cn30xx;
struct cvmx_iob_inb_data_match_s cn31xx;
struct cvmx_iob_inb_data_match_s cn38xx;
struct cvmx_iob_inb_data_match_s cn38xxp2;
struct cvmx_iob_inb_data_match_s cn50xx;
struct cvmx_iob_inb_data_match_s cn52xx;
struct cvmx_iob_inb_data_match_s cn52xxp1;
struct cvmx_iob_inb_data_match_s cn56xx;
struct cvmx_iob_inb_data_match_s cn56xxp1;
struct cvmx_iob_inb_data_match_s cn58xx;
struct cvmx_iob_inb_data_match_s cn58xxp1;
};
union cvmx_iob_inb_data_match_enb {
uint64_t u64;
struct cvmx_iob_inb_data_match_enb_s {
uint64_t data:64;
} s;
struct cvmx_iob_inb_data_match_enb_s cn30xx;
struct cvmx_iob_inb_data_match_enb_s cn31xx;
struct cvmx_iob_inb_data_match_enb_s cn38xx;
struct cvmx_iob_inb_data_match_enb_s cn38xxp2;
struct cvmx_iob_inb_data_match_enb_s cn50xx;
struct cvmx_iob_inb_data_match_enb_s cn52xx;
struct cvmx_iob_inb_data_match_enb_s cn52xxp1;
struct cvmx_iob_inb_data_match_enb_s cn56xx;
struct cvmx_iob_inb_data_match_enb_s cn56xxp1;
struct cvmx_iob_inb_data_match_enb_s cn58xx;
struct cvmx_iob_inb_data_match_enb_s cn58xxp1;
};
union cvmx_iob_int_enb {
uint64_t u64;
struct cvmx_iob_int_enb_s {
uint64_t reserved_6_63:58;
uint64_t p_dat:1;
uint64_t np_dat:1;
uint64_t p_eop:1;
uint64_t p_sop:1;
uint64_t np_eop:1;
uint64_t np_sop:1;
} s;
struct cvmx_iob_int_enb_cn30xx {
uint64_t reserved_4_63:60;
uint64_t p_eop:1;
uint64_t p_sop:1;
uint64_t np_eop:1;
uint64_t np_sop:1;
} cn30xx;
struct cvmx_iob_int_enb_cn30xx cn31xx;
struct cvmx_iob_int_enb_cn30xx cn38xx;
struct cvmx_iob_int_enb_cn30xx cn38xxp2;
struct cvmx_iob_int_enb_s cn50xx;
struct cvmx_iob_int_enb_s cn52xx;
struct cvmx_iob_int_enb_s cn52xxp1;
struct cvmx_iob_int_enb_s cn56xx;
struct cvmx_iob_int_enb_s cn56xxp1;
struct cvmx_iob_int_enb_s cn58xx;
struct cvmx_iob_int_enb_s cn58xxp1;
};
union cvmx_iob_int_sum {
uint64_t u64;
struct cvmx_iob_int_sum_s {
uint64_t reserved_6_63:58;
uint64_t p_dat:1;
uint64_t np_dat:1;
uint64_t p_eop:1;
uint64_t p_sop:1;
uint64_t np_eop:1;
uint64_t np_sop:1;
} s;
struct cvmx_iob_int_sum_cn30xx {
uint64_t reserved_4_63:60;
uint64_t p_eop:1;
uint64_t p_sop:1;
uint64_t np_eop:1;
uint64_t np_sop:1;
} cn30xx;
struct cvmx_iob_int_sum_cn30xx cn31xx;
struct cvmx_iob_int_sum_cn30xx cn38xx;
struct cvmx_iob_int_sum_cn30xx cn38xxp2;
struct cvmx_iob_int_sum_s cn50xx;
struct cvmx_iob_int_sum_s cn52xx;
struct cvmx_iob_int_sum_s cn52xxp1;
struct cvmx_iob_int_sum_s cn56xx;
struct cvmx_iob_int_sum_s cn56xxp1;
struct cvmx_iob_int_sum_s cn58xx;
struct cvmx_iob_int_sum_s cn58xxp1;
};
union cvmx_iob_n2c_l2c_pri_cnt {
uint64_t u64;
struct cvmx_iob_n2c_l2c_pri_cnt_s {
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
} s;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xxp2;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn52xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn52xxp1;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xxp1;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xx;
struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xxp1;
};
union cvmx_iob_n2c_rsp_pri_cnt {
uint64_t u64;
struct cvmx_iob_n2c_rsp_pri_cnt_s {
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
} s;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xxp2;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn52xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn52xxp1;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xxp1;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xx;
struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xxp1;
};
union cvmx_iob_outb_com_pri_cnt {
uint64_t u64;
struct cvmx_iob_outb_com_pri_cnt_s {
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
} s;
struct cvmx_iob_outb_com_pri_cnt_s cn38xx;
struct cvmx_iob_outb_com_pri_cnt_s cn38xxp2;
struct cvmx_iob_outb_com_pri_cnt_s cn52xx;
struct cvmx_iob_outb_com_pri_cnt_s cn52xxp1;
struct cvmx_iob_outb_com_pri_cnt_s cn56xx;
struct cvmx_iob_outb_com_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_com_pri_cnt_s cn58xx;
struct cvmx_iob_outb_com_pri_cnt_s cn58xxp1;
};
union cvmx_iob_outb_control_match {
uint64_t u64;
struct cvmx_iob_outb_control_match_s {
uint64_t reserved_26_63:38;
uint64_t mask:8;
uint64_t eot:1;
uint64_t dst:8;
uint64_t src:9;
} s;
struct cvmx_iob_outb_control_match_s cn30xx;
struct cvmx_iob_outb_control_match_s cn31xx;
struct cvmx_iob_outb_control_match_s cn38xx;
struct cvmx_iob_outb_control_match_s cn38xxp2;
struct cvmx_iob_outb_control_match_s cn50xx;
struct cvmx_iob_outb_control_match_s cn52xx;
struct cvmx_iob_outb_control_match_s cn52xxp1;
struct cvmx_iob_outb_control_match_s cn56xx;
struct cvmx_iob_outb_control_match_s cn56xxp1;
struct cvmx_iob_outb_control_match_s cn58xx;
struct cvmx_iob_outb_control_match_s cn58xxp1;
};
union cvmx_iob_outb_control_match_enb {
uint64_t u64;
struct cvmx_iob_outb_control_match_enb_s {
uint64_t reserved_26_63:38;
uint64_t mask:8;
uint64_t eot:1;
uint64_t dst:8;
uint64_t src:9;
} s;
struct cvmx_iob_outb_control_match_enb_s cn30xx;
struct cvmx_iob_outb_control_match_enb_s cn31xx;
struct cvmx_iob_outb_control_match_enb_s cn38xx;
struct cvmx_iob_outb_control_match_enb_s cn38xxp2;
struct cvmx_iob_outb_control_match_enb_s cn50xx;
struct cvmx_iob_outb_control_match_enb_s cn52xx;
struct cvmx_iob_outb_control_match_enb_s cn52xxp1;
struct cvmx_iob_outb_control_match_enb_s cn56xx;
struct cvmx_iob_outb_control_match_enb_s cn56xxp1;
struct cvmx_iob_outb_control_match_enb_s cn58xx;
struct cvmx_iob_outb_control_match_enb_s cn58xxp1;
};
union cvmx_iob_outb_data_match {
uint64_t u64;
struct cvmx_iob_outb_data_match_s {
uint64_t data:64;
} s;
struct cvmx_iob_outb_data_match_s cn30xx;
struct cvmx_iob_outb_data_match_s cn31xx;
struct cvmx_iob_outb_data_match_s cn38xx;
struct cvmx_iob_outb_data_match_s cn38xxp2;
struct cvmx_iob_outb_data_match_s cn50xx;
struct cvmx_iob_outb_data_match_s cn52xx;
struct cvmx_iob_outb_data_match_s cn52xxp1;
struct cvmx_iob_outb_data_match_s cn56xx;
struct cvmx_iob_outb_data_match_s cn56xxp1;
struct cvmx_iob_outb_data_match_s cn58xx;
struct cvmx_iob_outb_data_match_s cn58xxp1;
};
union cvmx_iob_outb_data_match_enb {
uint64_t u64;
struct cvmx_iob_outb_data_match_enb_s {
uint64_t data:64;
} s;
struct cvmx_iob_outb_data_match_enb_s cn30xx;
struct cvmx_iob_outb_data_match_enb_s cn31xx;
struct cvmx_iob_outb_data_match_enb_s cn38xx;
struct cvmx_iob_outb_data_match_enb_s cn38xxp2;
struct cvmx_iob_outb_data_match_enb_s cn50xx;
struct cvmx_iob_outb_data_match_enb_s cn52xx;
struct cvmx_iob_outb_data_match_enb_s cn52xxp1;
struct cvmx_iob_outb_data_match_enb_s cn56xx;
struct cvmx_iob_outb_data_match_enb_s cn56xxp1;
struct cvmx_iob_outb_data_match_enb_s cn58xx;
struct cvmx_iob_outb_data_match_enb_s cn58xxp1;
};
union cvmx_iob_outb_fpa_pri_cnt {
uint64_t u64;
struct cvmx_iob_outb_fpa_pri_cnt_s {
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
} s;
struct cvmx_iob_outb_fpa_pri_cnt_s cn38xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn38xxp2;
struct cvmx_iob_outb_fpa_pri_cnt_s cn52xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn52xxp1;
struct cvmx_iob_outb_fpa_pri_cnt_s cn56xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_fpa_pri_cnt_s cn58xx;
struct cvmx_iob_outb_fpa_pri_cnt_s cn58xxp1;
};
union cvmx_iob_outb_req_pri_cnt {
uint64_t u64;
struct cvmx_iob_outb_req_pri_cnt_s {
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
} s;
struct cvmx_iob_outb_req_pri_cnt_s cn38xx;
struct cvmx_iob_outb_req_pri_cnt_s cn38xxp2;
struct cvmx_iob_outb_req_pri_cnt_s cn52xx;
struct cvmx_iob_outb_req_pri_cnt_s cn52xxp1;
struct cvmx_iob_outb_req_pri_cnt_s cn56xx;
struct cvmx_iob_outb_req_pri_cnt_s cn56xxp1;
struct cvmx_iob_outb_req_pri_cnt_s cn58xx;
struct cvmx_iob_outb_req_pri_cnt_s cn58xxp1;
};
union cvmx_iob_p2c_req_pri_cnt {
uint64_t u64;
struct cvmx_iob_p2c_req_pri_cnt_s {
uint64_t reserved_16_63:48;
uint64_t cnt_enb:1;
uint64_t cnt_val:15;
} s;
struct cvmx_iob_p2c_req_pri_cnt_s cn38xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn38xxp2;
struct cvmx_iob_p2c_req_pri_cnt_s cn52xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn52xxp1;
struct cvmx_iob_p2c_req_pri_cnt_s cn56xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn56xxp1;
struct cvmx_iob_p2c_req_pri_cnt_s cn58xx;
struct cvmx_iob_p2c_req_pri_cnt_s cn58xxp1;
};
union cvmx_iob_pkt_err {
uint64_t u64;
struct cvmx_iob_pkt_err_s {
uint64_t reserved_6_63:58;
uint64_t port:6;
} s;
struct cvmx_iob_pkt_err_s cn30xx;
struct cvmx_iob_pkt_err_s cn31xx;
struct cvmx_iob_pkt_err_s cn38xx;
struct cvmx_iob_pkt_err_s cn38xxp2;
struct cvmx_iob_pkt_err_s cn50xx;
struct cvmx_iob_pkt_err_s cn52xx;
struct cvmx_iob_pkt_err_s cn52xxp1;
struct cvmx_iob_pkt_err_s cn56xx;
struct cvmx_iob_pkt_err_s cn56xxp1;
struct cvmx_iob_pkt_err_s cn58xx;
struct cvmx_iob_pkt_err_s cn58xxp1;
};
#endif

View file

@ -0,0 +1,877 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_IPD_DEFS_H__
#define __CVMX_IPD_DEFS_H__
#define CVMX_IPD_1ST_MBUFF_SKIP \
CVMX_ADD_IO_SEG(0x00014F0000000000ull)
#define CVMX_IPD_1st_NEXT_PTR_BACK \
CVMX_ADD_IO_SEG(0x00014F0000000150ull)
#define CVMX_IPD_2nd_NEXT_PTR_BACK \
CVMX_ADD_IO_SEG(0x00014F0000000158ull)
#define CVMX_IPD_BIST_STATUS \
CVMX_ADD_IO_SEG(0x00014F00000007F8ull)
#define CVMX_IPD_BP_PRT_RED_END \
CVMX_ADD_IO_SEG(0x00014F0000000328ull)
#define CVMX_IPD_CLK_COUNT \
CVMX_ADD_IO_SEG(0x00014F0000000338ull)
#define CVMX_IPD_CTL_STATUS \
CVMX_ADD_IO_SEG(0x00014F0000000018ull)
#define CVMX_IPD_INT_ENB \
CVMX_ADD_IO_SEG(0x00014F0000000160ull)
#define CVMX_IPD_INT_SUM \
CVMX_ADD_IO_SEG(0x00014F0000000168ull)
#define CVMX_IPD_NOT_1ST_MBUFF_SKIP \
CVMX_ADD_IO_SEG(0x00014F0000000008ull)
#define CVMX_IPD_PACKET_MBUFF_SIZE \
CVMX_ADD_IO_SEG(0x00014F0000000010ull)
#define CVMX_IPD_PKT_PTR_VALID \
CVMX_ADD_IO_SEG(0x00014F0000000358ull)
#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) \
CVMX_ADD_IO_SEG(0x00014F0000000028ull + (((offset) & 63) * 8))
#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) \
CVMX_ADD_IO_SEG(0x00014F0000000368ull + (((offset) & 63) * 8) - 8 * 36)
#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) \
CVMX_ADD_IO_SEG(0x00014F0000000388ull + (((offset) & 63) * 8) - 8 * 36)
#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) \
CVMX_ADD_IO_SEG(0x00014F00000001B8ull + (((offset) & 63) * 8))
#define CVMX_IPD_PORT_QOS_INTX(offset) \
CVMX_ADD_IO_SEG(0x00014F0000000808ull + (((offset) & 7) * 8))
#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) \
CVMX_ADD_IO_SEG(0x00014F0000000848ull + (((offset) & 7) * 8))
#define CVMX_IPD_PORT_QOS_X_CNT(offset) \
CVMX_ADD_IO_SEG(0x00014F0000000888ull + (((offset) & 511) * 8))
#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL \
CVMX_ADD_IO_SEG(0x00014F0000000348ull)
#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL \
CVMX_ADD_IO_SEG(0x00014F0000000350ull)
#define CVMX_IPD_PTR_COUNT \
CVMX_ADD_IO_SEG(0x00014F0000000320ull)
#define CVMX_IPD_PWP_PTR_FIFO_CTL \
CVMX_ADD_IO_SEG(0x00014F0000000340ull)
#define CVMX_IPD_QOS0_RED_MARKS \
CVMX_ADD_IO_SEG(0x00014F0000000178ull)
#define CVMX_IPD_QOS1_RED_MARKS \
CVMX_ADD_IO_SEG(0x00014F0000000180ull)
#define CVMX_IPD_QOS2_RED_MARKS \
CVMX_ADD_IO_SEG(0x00014F0000000188ull)
#define CVMX_IPD_QOS3_RED_MARKS \
CVMX_ADD_IO_SEG(0x00014F0000000190ull)
#define CVMX_IPD_QOS4_RED_MARKS \
CVMX_ADD_IO_SEG(0x00014F0000000198ull)
#define CVMX_IPD_QOS5_RED_MARKS \
CVMX_ADD_IO_SEG(0x00014F00000001A0ull)
#define CVMX_IPD_QOS6_RED_MARKS \
CVMX_ADD_IO_SEG(0x00014F00000001A8ull)
#define CVMX_IPD_QOS7_RED_MARKS \
CVMX_ADD_IO_SEG(0x00014F00000001B0ull)
#define CVMX_IPD_QOSX_RED_MARKS(offset) \
CVMX_ADD_IO_SEG(0x00014F0000000178ull + (((offset) & 7) * 8))
#define CVMX_IPD_QUE0_FREE_PAGE_CNT \
CVMX_ADD_IO_SEG(0x00014F0000000330ull)
#define CVMX_IPD_RED_PORT_ENABLE \
CVMX_ADD_IO_SEG(0x00014F00000002D8ull)
#define CVMX_IPD_RED_PORT_ENABLE2 \
CVMX_ADD_IO_SEG(0x00014F00000003A8ull)
#define CVMX_IPD_RED_QUE0_PARAM \
CVMX_ADD_IO_SEG(0x00014F00000002E0ull)
#define CVMX_IPD_RED_QUE1_PARAM \
CVMX_ADD_IO_SEG(0x00014F00000002E8ull)
#define CVMX_IPD_RED_QUE2_PARAM \
CVMX_ADD_IO_SEG(0x00014F00000002F0ull)
#define CVMX_IPD_RED_QUE3_PARAM \
CVMX_ADD_IO_SEG(0x00014F00000002F8ull)
#define CVMX_IPD_RED_QUE4_PARAM \
CVMX_ADD_IO_SEG(0x00014F0000000300ull)
#define CVMX_IPD_RED_QUE5_PARAM \
CVMX_ADD_IO_SEG(0x00014F0000000308ull)
#define CVMX_IPD_RED_QUE6_PARAM \
CVMX_ADD_IO_SEG(0x00014F0000000310ull)
#define CVMX_IPD_RED_QUE7_PARAM \
CVMX_ADD_IO_SEG(0x00014F0000000318ull)
#define CVMX_IPD_RED_QUEX_PARAM(offset) \
CVMX_ADD_IO_SEG(0x00014F00000002E0ull + (((offset) & 7) * 8))
#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT \
CVMX_ADD_IO_SEG(0x00014F0000000148ull)
#define CVMX_IPD_SUB_PORT_FCS \
CVMX_ADD_IO_SEG(0x00014F0000000170ull)
#define CVMX_IPD_SUB_PORT_QOS_CNT \
CVMX_ADD_IO_SEG(0x00014F0000000800ull)
#define CVMX_IPD_WQE_FPA_QUEUE \
CVMX_ADD_IO_SEG(0x00014F0000000020ull)
#define CVMX_IPD_WQE_PTR_VALID \
CVMX_ADD_IO_SEG(0x00014F0000000360ull)
union cvmx_ipd_1st_mbuff_skip {
uint64_t u64;
struct cvmx_ipd_1st_mbuff_skip_s {
uint64_t reserved_6_63:58;
uint64_t skip_sz:6;
} s;
struct cvmx_ipd_1st_mbuff_skip_s cn30xx;
struct cvmx_ipd_1st_mbuff_skip_s cn31xx;
struct cvmx_ipd_1st_mbuff_skip_s cn38xx;
struct cvmx_ipd_1st_mbuff_skip_s cn38xxp2;
struct cvmx_ipd_1st_mbuff_skip_s cn50xx;
struct cvmx_ipd_1st_mbuff_skip_s cn52xx;
struct cvmx_ipd_1st_mbuff_skip_s cn52xxp1;
struct cvmx_ipd_1st_mbuff_skip_s cn56xx;
struct cvmx_ipd_1st_mbuff_skip_s cn56xxp1;
struct cvmx_ipd_1st_mbuff_skip_s cn58xx;
struct cvmx_ipd_1st_mbuff_skip_s cn58xxp1;
};
union cvmx_ipd_1st_next_ptr_back {
uint64_t u64;
struct cvmx_ipd_1st_next_ptr_back_s {
uint64_t reserved_4_63:60;
uint64_t back:4;
} s;
struct cvmx_ipd_1st_next_ptr_back_s cn30xx;
struct cvmx_ipd_1st_next_ptr_back_s cn31xx;
struct cvmx_ipd_1st_next_ptr_back_s cn38xx;
struct cvmx_ipd_1st_next_ptr_back_s cn38xxp2;
struct cvmx_ipd_1st_next_ptr_back_s cn50xx;
struct cvmx_ipd_1st_next_ptr_back_s cn52xx;
struct cvmx_ipd_1st_next_ptr_back_s cn52xxp1;
struct cvmx_ipd_1st_next_ptr_back_s cn56xx;
struct cvmx_ipd_1st_next_ptr_back_s cn56xxp1;
struct cvmx_ipd_1st_next_ptr_back_s cn58xx;
struct cvmx_ipd_1st_next_ptr_back_s cn58xxp1;
};
union cvmx_ipd_2nd_next_ptr_back {
uint64_t u64;
struct cvmx_ipd_2nd_next_ptr_back_s {
uint64_t reserved_4_63:60;
uint64_t back:4;
} s;
struct cvmx_ipd_2nd_next_ptr_back_s cn30xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn31xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn38xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn38xxp2;
struct cvmx_ipd_2nd_next_ptr_back_s cn50xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn52xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn52xxp1;
struct cvmx_ipd_2nd_next_ptr_back_s cn56xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn56xxp1;
struct cvmx_ipd_2nd_next_ptr_back_s cn58xx;
struct cvmx_ipd_2nd_next_ptr_back_s cn58xxp1;
};
union cvmx_ipd_bist_status {
uint64_t u64;
struct cvmx_ipd_bist_status_s {
uint64_t reserved_18_63:46;
uint64_t csr_mem:1;
uint64_t csr_ncmd:1;
uint64_t pwq_wqed:1;
uint64_t pwq_wp1:1;
uint64_t pwq_pow:1;
uint64_t ipq_pbe1:1;
uint64_t ipq_pbe0:1;
uint64_t pbm3:1;
uint64_t pbm2:1;
uint64_t pbm1:1;
uint64_t pbm0:1;
uint64_t pbm_word:1;
uint64_t pwq1:1;
uint64_t pwq0:1;
uint64_t prc_off:1;
uint64_t ipd_old:1;
uint64_t ipd_new:1;
uint64_t pwp:1;
} s;
struct cvmx_ipd_bist_status_cn30xx {
uint64_t reserved_16_63:48;
uint64_t pwq_wqed:1;
uint64_t pwq_wp1:1;
uint64_t pwq_pow:1;
uint64_t ipq_pbe1:1;
uint64_t ipq_pbe0:1;
uint64_t pbm3:1;
uint64_t pbm2:1;
uint64_t pbm1:1;
uint64_t pbm0:1;
uint64_t pbm_word:1;
uint64_t pwq1:1;
uint64_t pwq0:1;
uint64_t prc_off:1;
uint64_t ipd_old:1;
uint64_t ipd_new:1;
uint64_t pwp:1;
} cn30xx;
struct cvmx_ipd_bist_status_cn30xx cn31xx;
struct cvmx_ipd_bist_status_cn30xx cn38xx;
struct cvmx_ipd_bist_status_cn30xx cn38xxp2;
struct cvmx_ipd_bist_status_cn30xx cn50xx;
struct cvmx_ipd_bist_status_s cn52xx;
struct cvmx_ipd_bist_status_s cn52xxp1;
struct cvmx_ipd_bist_status_s cn56xx;
struct cvmx_ipd_bist_status_s cn56xxp1;
struct cvmx_ipd_bist_status_cn30xx cn58xx;
struct cvmx_ipd_bist_status_cn30xx cn58xxp1;
};
union cvmx_ipd_bp_prt_red_end {
uint64_t u64;
struct cvmx_ipd_bp_prt_red_end_s {
uint64_t reserved_40_63:24;
uint64_t prt_enb:40;
} s;
struct cvmx_ipd_bp_prt_red_end_cn30xx {
uint64_t reserved_36_63:28;
uint64_t prt_enb:36;
} cn30xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn31xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xxp2;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn50xx;
struct cvmx_ipd_bp_prt_red_end_s cn52xx;
struct cvmx_ipd_bp_prt_red_end_s cn52xxp1;
struct cvmx_ipd_bp_prt_red_end_s cn56xx;
struct cvmx_ipd_bp_prt_red_end_s cn56xxp1;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xx;
struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xxp1;
};
union cvmx_ipd_clk_count {
uint64_t u64;
struct cvmx_ipd_clk_count_s {
uint64_t clk_cnt:64;
} s;
struct cvmx_ipd_clk_count_s cn30xx;
struct cvmx_ipd_clk_count_s cn31xx;
struct cvmx_ipd_clk_count_s cn38xx;
struct cvmx_ipd_clk_count_s cn38xxp2;
struct cvmx_ipd_clk_count_s cn50xx;
struct cvmx_ipd_clk_count_s cn52xx;
struct cvmx_ipd_clk_count_s cn52xxp1;
struct cvmx_ipd_clk_count_s cn56xx;
struct cvmx_ipd_clk_count_s cn56xxp1;
struct cvmx_ipd_clk_count_s cn58xx;
struct cvmx_ipd_clk_count_s cn58xxp1;
};
union cvmx_ipd_ctl_status {
uint64_t u64;
struct cvmx_ipd_ctl_status_s {
uint64_t reserved_15_63:49;
uint64_t no_wptr:1;
uint64_t pq_apkt:1;
uint64_t pq_nabuf:1;
uint64_t ipd_full:1;
uint64_t pkt_off:1;
uint64_t len_m8:1;
uint64_t reset:1;
uint64_t addpkt:1;
uint64_t naddbuf:1;
uint64_t pkt_lend:1;
uint64_t wqe_lend:1;
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
} s;
struct cvmx_ipd_ctl_status_cn30xx {
uint64_t reserved_10_63:54;
uint64_t len_m8:1;
uint64_t reset:1;
uint64_t addpkt:1;
uint64_t naddbuf:1;
uint64_t pkt_lend:1;
uint64_t wqe_lend:1;
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
} cn30xx;
struct cvmx_ipd_ctl_status_cn30xx cn31xx;
struct cvmx_ipd_ctl_status_cn30xx cn38xx;
struct cvmx_ipd_ctl_status_cn38xxp2 {
uint64_t reserved_9_63:55;
uint64_t reset:1;
uint64_t addpkt:1;
uint64_t naddbuf:1;
uint64_t pkt_lend:1;
uint64_t wqe_lend:1;
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
} cn38xxp2;
struct cvmx_ipd_ctl_status_s cn50xx;
struct cvmx_ipd_ctl_status_s cn52xx;
struct cvmx_ipd_ctl_status_s cn52xxp1;
struct cvmx_ipd_ctl_status_s cn56xx;
struct cvmx_ipd_ctl_status_s cn56xxp1;
struct cvmx_ipd_ctl_status_cn58xx {
uint64_t reserved_12_63:52;
uint64_t ipd_full:1;
uint64_t pkt_off:1;
uint64_t len_m8:1;
uint64_t reset:1;
uint64_t addpkt:1;
uint64_t naddbuf:1;
uint64_t pkt_lend:1;
uint64_t wqe_lend:1;
uint64_t pbp_en:1;
uint64_t opc_mode:2;
uint64_t ipd_en:1;
} cn58xx;
struct cvmx_ipd_ctl_status_cn58xx cn58xxp1;
};
union cvmx_ipd_int_enb {
uint64_t u64;
struct cvmx_ipd_int_enb_s {
uint64_t reserved_12_63:52;
uint64_t pq_sub:1;
uint64_t pq_add:1;
uint64_t bc_ovr:1;
uint64_t d_coll:1;
uint64_t c_coll:1;
uint64_t cc_ovr:1;
uint64_t dc_ovr:1;
uint64_t bp_sub:1;
uint64_t prc_par3:1;
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
} s;
struct cvmx_ipd_int_enb_cn30xx {
uint64_t reserved_5_63:59;
uint64_t bp_sub:1;
uint64_t prc_par3:1;
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
} cn30xx;
struct cvmx_ipd_int_enb_cn30xx cn31xx;
struct cvmx_ipd_int_enb_cn38xx {
uint64_t reserved_10_63:54;
uint64_t bc_ovr:1;
uint64_t d_coll:1;
uint64_t c_coll:1;
uint64_t cc_ovr:1;
uint64_t dc_ovr:1;
uint64_t bp_sub:1;
uint64_t prc_par3:1;
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
} cn38xx;
struct cvmx_ipd_int_enb_cn30xx cn38xxp2;
struct cvmx_ipd_int_enb_cn38xx cn50xx;
struct cvmx_ipd_int_enb_s cn52xx;
struct cvmx_ipd_int_enb_s cn52xxp1;
struct cvmx_ipd_int_enb_s cn56xx;
struct cvmx_ipd_int_enb_s cn56xxp1;
struct cvmx_ipd_int_enb_cn38xx cn58xx;
struct cvmx_ipd_int_enb_cn38xx cn58xxp1;
};
union cvmx_ipd_int_sum {
uint64_t u64;
struct cvmx_ipd_int_sum_s {
uint64_t reserved_12_63:52;
uint64_t pq_sub:1;
uint64_t pq_add:1;
uint64_t bc_ovr:1;
uint64_t d_coll:1;
uint64_t c_coll:1;
uint64_t cc_ovr:1;
uint64_t dc_ovr:1;
uint64_t bp_sub:1;
uint64_t prc_par3:1;
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
} s;
struct cvmx_ipd_int_sum_cn30xx {
uint64_t reserved_5_63:59;
uint64_t bp_sub:1;
uint64_t prc_par3:1;
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
} cn30xx;
struct cvmx_ipd_int_sum_cn30xx cn31xx;
struct cvmx_ipd_int_sum_cn38xx {
uint64_t reserved_10_63:54;
uint64_t bc_ovr:1;
uint64_t d_coll:1;
uint64_t c_coll:1;
uint64_t cc_ovr:1;
uint64_t dc_ovr:1;
uint64_t bp_sub:1;
uint64_t prc_par3:1;
uint64_t prc_par2:1;
uint64_t prc_par1:1;
uint64_t prc_par0:1;
} cn38xx;
struct cvmx_ipd_int_sum_cn30xx cn38xxp2;
struct cvmx_ipd_int_sum_cn38xx cn50xx;
struct cvmx_ipd_int_sum_s cn52xx;
struct cvmx_ipd_int_sum_s cn52xxp1;
struct cvmx_ipd_int_sum_s cn56xx;
struct cvmx_ipd_int_sum_s cn56xxp1;
struct cvmx_ipd_int_sum_cn38xx cn58xx;
struct cvmx_ipd_int_sum_cn38xx cn58xxp1;
};
union cvmx_ipd_not_1st_mbuff_skip {
uint64_t u64;
struct cvmx_ipd_not_1st_mbuff_skip_s {
uint64_t reserved_6_63:58;
uint64_t skip_sz:6;
} s;
struct cvmx_ipd_not_1st_mbuff_skip_s cn30xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn31xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn38xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn38xxp2;
struct cvmx_ipd_not_1st_mbuff_skip_s cn50xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn52xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn52xxp1;
struct cvmx_ipd_not_1st_mbuff_skip_s cn56xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn56xxp1;
struct cvmx_ipd_not_1st_mbuff_skip_s cn58xx;
struct cvmx_ipd_not_1st_mbuff_skip_s cn58xxp1;
};
union cvmx_ipd_packet_mbuff_size {
uint64_t u64;
struct cvmx_ipd_packet_mbuff_size_s {
uint64_t reserved_12_63:52;
uint64_t mb_size:12;
} s;
struct cvmx_ipd_packet_mbuff_size_s cn30xx;
struct cvmx_ipd_packet_mbuff_size_s cn31xx;
struct cvmx_ipd_packet_mbuff_size_s cn38xx;
struct cvmx_ipd_packet_mbuff_size_s cn38xxp2;
struct cvmx_ipd_packet_mbuff_size_s cn50xx;
struct cvmx_ipd_packet_mbuff_size_s cn52xx;
struct cvmx_ipd_packet_mbuff_size_s cn52xxp1;
struct cvmx_ipd_packet_mbuff_size_s cn56xx;
struct cvmx_ipd_packet_mbuff_size_s cn56xxp1;
struct cvmx_ipd_packet_mbuff_size_s cn58xx;
struct cvmx_ipd_packet_mbuff_size_s cn58xxp1;
};
union cvmx_ipd_pkt_ptr_valid {
uint64_t u64;
struct cvmx_ipd_pkt_ptr_valid_s {
uint64_t reserved_29_63:35;
uint64_t ptr:29;
} s;
struct cvmx_ipd_pkt_ptr_valid_s cn30xx;
struct cvmx_ipd_pkt_ptr_valid_s cn31xx;
struct cvmx_ipd_pkt_ptr_valid_s cn38xx;
struct cvmx_ipd_pkt_ptr_valid_s cn50xx;
struct cvmx_ipd_pkt_ptr_valid_s cn52xx;
struct cvmx_ipd_pkt_ptr_valid_s cn52xxp1;
struct cvmx_ipd_pkt_ptr_valid_s cn56xx;
struct cvmx_ipd_pkt_ptr_valid_s cn56xxp1;
struct cvmx_ipd_pkt_ptr_valid_s cn58xx;
struct cvmx_ipd_pkt_ptr_valid_s cn58xxp1;
};
union cvmx_ipd_portx_bp_page_cnt {
uint64_t u64;
struct cvmx_ipd_portx_bp_page_cnt_s {
uint64_t reserved_18_63:46;
uint64_t bp_enb:1;
uint64_t page_cnt:17;
} s;
struct cvmx_ipd_portx_bp_page_cnt_s cn30xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn31xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn38xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn38xxp2;
struct cvmx_ipd_portx_bp_page_cnt_s cn50xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn52xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn52xxp1;
struct cvmx_ipd_portx_bp_page_cnt_s cn56xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn56xxp1;
struct cvmx_ipd_portx_bp_page_cnt_s cn58xx;
struct cvmx_ipd_portx_bp_page_cnt_s cn58xxp1;
};
union cvmx_ipd_portx_bp_page_cnt2 {
uint64_t u64;
struct cvmx_ipd_portx_bp_page_cnt2_s {
uint64_t reserved_18_63:46;
uint64_t bp_enb:1;
uint64_t page_cnt:17;
} s;
struct cvmx_ipd_portx_bp_page_cnt2_s cn52xx;
struct cvmx_ipd_portx_bp_page_cnt2_s cn52xxp1;
struct cvmx_ipd_portx_bp_page_cnt2_s cn56xx;
struct cvmx_ipd_portx_bp_page_cnt2_s cn56xxp1;
};
union cvmx_ipd_port_bp_counters2_pairx {
uint64_t u64;
struct cvmx_ipd_port_bp_counters2_pairx_s {
uint64_t reserved_25_63:39;
uint64_t cnt_val:25;
} s;
struct cvmx_ipd_port_bp_counters2_pairx_s cn52xx;
struct cvmx_ipd_port_bp_counters2_pairx_s cn52xxp1;
struct cvmx_ipd_port_bp_counters2_pairx_s cn56xx;
struct cvmx_ipd_port_bp_counters2_pairx_s cn56xxp1;
};
union cvmx_ipd_port_bp_counters_pairx {
uint64_t u64;
struct cvmx_ipd_port_bp_counters_pairx_s {
uint64_t reserved_25_63:39;
uint64_t cnt_val:25;
} s;
struct cvmx_ipd_port_bp_counters_pairx_s cn30xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn31xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn38xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn38xxp2;
struct cvmx_ipd_port_bp_counters_pairx_s cn50xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn52xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn52xxp1;
struct cvmx_ipd_port_bp_counters_pairx_s cn56xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn56xxp1;
struct cvmx_ipd_port_bp_counters_pairx_s cn58xx;
struct cvmx_ipd_port_bp_counters_pairx_s cn58xxp1;
};
union cvmx_ipd_port_qos_x_cnt {
uint64_t u64;
struct cvmx_ipd_port_qos_x_cnt_s {
uint64_t wmark:32;
uint64_t cnt:32;
} s;
struct cvmx_ipd_port_qos_x_cnt_s cn52xx;
struct cvmx_ipd_port_qos_x_cnt_s cn52xxp1;
struct cvmx_ipd_port_qos_x_cnt_s cn56xx;
struct cvmx_ipd_port_qos_x_cnt_s cn56xxp1;
};
union cvmx_ipd_port_qos_intx {
uint64_t u64;
struct cvmx_ipd_port_qos_intx_s {
uint64_t intr:64;
} s;
struct cvmx_ipd_port_qos_intx_s cn52xx;
struct cvmx_ipd_port_qos_intx_s cn52xxp1;
struct cvmx_ipd_port_qos_intx_s cn56xx;
struct cvmx_ipd_port_qos_intx_s cn56xxp1;
};
union cvmx_ipd_port_qos_int_enbx {
uint64_t u64;
struct cvmx_ipd_port_qos_int_enbx_s {
uint64_t enb:64;
} s;
struct cvmx_ipd_port_qos_int_enbx_s cn52xx;
struct cvmx_ipd_port_qos_int_enbx_s cn52xxp1;
struct cvmx_ipd_port_qos_int_enbx_s cn56xx;
struct cvmx_ipd_port_qos_int_enbx_s cn56xxp1;
};
union cvmx_ipd_prc_hold_ptr_fifo_ctl {
uint64_t u64;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s {
uint64_t reserved_39_63:25;
uint64_t max_pkt:3;
uint64_t praddr:3;
uint64_t ptr:29;
uint64_t cena:1;
uint64_t raddr:3;
} s;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn30xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn31xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn38xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn50xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn52xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn52xxp1;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xxp1;
};
union cvmx_ipd_prc_port_ptr_fifo_ctl {
uint64_t u64;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s {
uint64_t reserved_44_63:20;
uint64_t max_pkt:7;
uint64_t ptr:29;
uint64_t cena:1;
uint64_t raddr:7;
} s;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn30xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn31xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn38xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn50xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn52xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn52xxp1;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xxp1;
};
union cvmx_ipd_ptr_count {
uint64_t u64;
struct cvmx_ipd_ptr_count_s {
uint64_t reserved_19_63:45;
uint64_t pktv_cnt:1;
uint64_t wqev_cnt:1;
uint64_t pfif_cnt:3;
uint64_t pkt_pcnt:7;
uint64_t wqe_pcnt:7;
} s;
struct cvmx_ipd_ptr_count_s cn30xx;
struct cvmx_ipd_ptr_count_s cn31xx;
struct cvmx_ipd_ptr_count_s cn38xx;
struct cvmx_ipd_ptr_count_s cn38xxp2;
struct cvmx_ipd_ptr_count_s cn50xx;
struct cvmx_ipd_ptr_count_s cn52xx;
struct cvmx_ipd_ptr_count_s cn52xxp1;
struct cvmx_ipd_ptr_count_s cn56xx;
struct cvmx_ipd_ptr_count_s cn56xxp1;
struct cvmx_ipd_ptr_count_s cn58xx;
struct cvmx_ipd_ptr_count_s cn58xxp1;
};
union cvmx_ipd_pwp_ptr_fifo_ctl {
uint64_t u64;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s {
uint64_t reserved_61_63:3;
uint64_t max_cnts:7;
uint64_t wraddr:8;
uint64_t praddr:8;
uint64_t ptr:29;
uint64_t cena:1;
uint64_t raddr:8;
} s;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn30xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn31xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn38xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn50xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn52xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn52xxp1;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xxp1;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xx;
struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xxp1;
};
union cvmx_ipd_qosx_red_marks {
uint64_t u64;
struct cvmx_ipd_qosx_red_marks_s {
uint64_t drop:32;
uint64_t pass:32;
} s;
struct cvmx_ipd_qosx_red_marks_s cn30xx;
struct cvmx_ipd_qosx_red_marks_s cn31xx;
struct cvmx_ipd_qosx_red_marks_s cn38xx;
struct cvmx_ipd_qosx_red_marks_s cn38xxp2;
struct cvmx_ipd_qosx_red_marks_s cn50xx;
struct cvmx_ipd_qosx_red_marks_s cn52xx;
struct cvmx_ipd_qosx_red_marks_s cn52xxp1;
struct cvmx_ipd_qosx_red_marks_s cn56xx;
struct cvmx_ipd_qosx_red_marks_s cn56xxp1;
struct cvmx_ipd_qosx_red_marks_s cn58xx;
struct cvmx_ipd_qosx_red_marks_s cn58xxp1;
};
union cvmx_ipd_que0_free_page_cnt {
uint64_t u64;
struct cvmx_ipd_que0_free_page_cnt_s {
uint64_t reserved_32_63:32;
uint64_t q0_pcnt:32;
} s;
struct cvmx_ipd_que0_free_page_cnt_s cn30xx;
struct cvmx_ipd_que0_free_page_cnt_s cn31xx;
struct cvmx_ipd_que0_free_page_cnt_s cn38xx;
struct cvmx_ipd_que0_free_page_cnt_s cn38xxp2;
struct cvmx_ipd_que0_free_page_cnt_s cn50xx;
struct cvmx_ipd_que0_free_page_cnt_s cn52xx;
struct cvmx_ipd_que0_free_page_cnt_s cn52xxp1;
struct cvmx_ipd_que0_free_page_cnt_s cn56xx;
struct cvmx_ipd_que0_free_page_cnt_s cn56xxp1;
struct cvmx_ipd_que0_free_page_cnt_s cn58xx;
struct cvmx_ipd_que0_free_page_cnt_s cn58xxp1;
};
union cvmx_ipd_red_port_enable {
uint64_t u64;
struct cvmx_ipd_red_port_enable_s {
uint64_t prb_dly:14;
uint64_t avg_dly:14;
uint64_t prt_enb:36;
} s;
struct cvmx_ipd_red_port_enable_s cn30xx;
struct cvmx_ipd_red_port_enable_s cn31xx;
struct cvmx_ipd_red_port_enable_s cn38xx;
struct cvmx_ipd_red_port_enable_s cn38xxp2;
struct cvmx_ipd_red_port_enable_s cn50xx;
struct cvmx_ipd_red_port_enable_s cn52xx;
struct cvmx_ipd_red_port_enable_s cn52xxp1;
struct cvmx_ipd_red_port_enable_s cn56xx;
struct cvmx_ipd_red_port_enable_s cn56xxp1;
struct cvmx_ipd_red_port_enable_s cn58xx;
struct cvmx_ipd_red_port_enable_s cn58xxp1;
};
union cvmx_ipd_red_port_enable2 {
uint64_t u64;
struct cvmx_ipd_red_port_enable2_s {
uint64_t reserved_4_63:60;
uint64_t prt_enb:4;
} s;
struct cvmx_ipd_red_port_enable2_s cn52xx;
struct cvmx_ipd_red_port_enable2_s cn52xxp1;
struct cvmx_ipd_red_port_enable2_s cn56xx;
struct cvmx_ipd_red_port_enable2_s cn56xxp1;
};
union cvmx_ipd_red_quex_param {
uint64_t u64;
struct cvmx_ipd_red_quex_param_s {
uint64_t reserved_49_63:15;
uint64_t use_pcnt:1;
uint64_t new_con:8;
uint64_t avg_con:8;
uint64_t prb_con:32;
} s;
struct cvmx_ipd_red_quex_param_s cn30xx;
struct cvmx_ipd_red_quex_param_s cn31xx;
struct cvmx_ipd_red_quex_param_s cn38xx;
struct cvmx_ipd_red_quex_param_s cn38xxp2;
struct cvmx_ipd_red_quex_param_s cn50xx;
struct cvmx_ipd_red_quex_param_s cn52xx;
struct cvmx_ipd_red_quex_param_s cn52xxp1;
struct cvmx_ipd_red_quex_param_s cn56xx;
struct cvmx_ipd_red_quex_param_s cn56xxp1;
struct cvmx_ipd_red_quex_param_s cn58xx;
struct cvmx_ipd_red_quex_param_s cn58xxp1;
};
union cvmx_ipd_sub_port_bp_page_cnt {
uint64_t u64;
struct cvmx_ipd_sub_port_bp_page_cnt_s {
uint64_t reserved_31_63:33;
uint64_t port:6;
uint64_t page_cnt:25;
} s;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn30xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn31xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn38xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn38xxp2;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn50xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn52xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn52xxp1;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xxp1;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xx;
struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xxp1;
};
union cvmx_ipd_sub_port_fcs {
uint64_t u64;
struct cvmx_ipd_sub_port_fcs_s {
uint64_t reserved_40_63:24;
uint64_t port_bit2:4;
uint64_t reserved_32_35:4;
uint64_t port_bit:32;
} s;
struct cvmx_ipd_sub_port_fcs_cn30xx {
uint64_t reserved_3_63:61;
uint64_t port_bit:3;
} cn30xx;
struct cvmx_ipd_sub_port_fcs_cn30xx cn31xx;
struct cvmx_ipd_sub_port_fcs_cn38xx {
uint64_t reserved_32_63:32;
uint64_t port_bit:32;
} cn38xx;
struct cvmx_ipd_sub_port_fcs_cn38xx cn38xxp2;
struct cvmx_ipd_sub_port_fcs_cn30xx cn50xx;
struct cvmx_ipd_sub_port_fcs_s cn52xx;
struct cvmx_ipd_sub_port_fcs_s cn52xxp1;
struct cvmx_ipd_sub_port_fcs_s cn56xx;
struct cvmx_ipd_sub_port_fcs_s cn56xxp1;
struct cvmx_ipd_sub_port_fcs_cn38xx cn58xx;
struct cvmx_ipd_sub_port_fcs_cn38xx cn58xxp1;
};
union cvmx_ipd_sub_port_qos_cnt {
uint64_t u64;
struct cvmx_ipd_sub_port_qos_cnt_s {
uint64_t reserved_41_63:23;
uint64_t port_qos:9;
uint64_t cnt:32;
} s;
struct cvmx_ipd_sub_port_qos_cnt_s cn52xx;
struct cvmx_ipd_sub_port_qos_cnt_s cn52xxp1;
struct cvmx_ipd_sub_port_qos_cnt_s cn56xx;
struct cvmx_ipd_sub_port_qos_cnt_s cn56xxp1;
};
union cvmx_ipd_wqe_fpa_queue {
uint64_t u64;
struct cvmx_ipd_wqe_fpa_queue_s {
uint64_t reserved_3_63:61;
uint64_t wqe_pool:3;
} s;
struct cvmx_ipd_wqe_fpa_queue_s cn30xx;
struct cvmx_ipd_wqe_fpa_queue_s cn31xx;
struct cvmx_ipd_wqe_fpa_queue_s cn38xx;
struct cvmx_ipd_wqe_fpa_queue_s cn38xxp2;
struct cvmx_ipd_wqe_fpa_queue_s cn50xx;
struct cvmx_ipd_wqe_fpa_queue_s cn52xx;
struct cvmx_ipd_wqe_fpa_queue_s cn52xxp1;
struct cvmx_ipd_wqe_fpa_queue_s cn56xx;
struct cvmx_ipd_wqe_fpa_queue_s cn56xxp1;
struct cvmx_ipd_wqe_fpa_queue_s cn58xx;
struct cvmx_ipd_wqe_fpa_queue_s cn58xxp1;
};
union cvmx_ipd_wqe_ptr_valid {
uint64_t u64;
struct cvmx_ipd_wqe_ptr_valid_s {
uint64_t reserved_29_63:35;
uint64_t ptr:29;
} s;
struct cvmx_ipd_wqe_ptr_valid_s cn30xx;
struct cvmx_ipd_wqe_ptr_valid_s cn31xx;
struct cvmx_ipd_wqe_ptr_valid_s cn38xx;
struct cvmx_ipd_wqe_ptr_valid_s cn50xx;
struct cvmx_ipd_wqe_ptr_valid_s cn52xx;
struct cvmx_ipd_wqe_ptr_valid_s cn52xxp1;
struct cvmx_ipd_wqe_ptr_valid_s cn56xx;
struct cvmx_ipd_wqe_ptr_valid_s cn56xxp1;
struct cvmx_ipd_wqe_ptr_valid_s cn58xx;
struct cvmx_ipd_wqe_ptr_valid_s cn58xxp1;
};
#endif

View file

@ -0,0 +1,963 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_L2C_DEFS_H__
#define __CVMX_L2C_DEFS_H__
#define CVMX_L2C_BST0 \
CVMX_ADD_IO_SEG(0x00011800800007F8ull)
#define CVMX_L2C_BST1 \
CVMX_ADD_IO_SEG(0x00011800800007F0ull)
#define CVMX_L2C_BST2 \
CVMX_ADD_IO_SEG(0x00011800800007E8ull)
#define CVMX_L2C_CFG \
CVMX_ADD_IO_SEG(0x0001180080000000ull)
#define CVMX_L2C_DBG \
CVMX_ADD_IO_SEG(0x0001180080000030ull)
#define CVMX_L2C_DUT \
CVMX_ADD_IO_SEG(0x0001180080000050ull)
#define CVMX_L2C_GRPWRR0 \
CVMX_ADD_IO_SEG(0x00011800800000C8ull)
#define CVMX_L2C_GRPWRR1 \
CVMX_ADD_IO_SEG(0x00011800800000D0ull)
#define CVMX_L2C_INT_EN \
CVMX_ADD_IO_SEG(0x0001180080000100ull)
#define CVMX_L2C_INT_STAT \
CVMX_ADD_IO_SEG(0x00011800800000F8ull)
#define CVMX_L2C_LCKBASE \
CVMX_ADD_IO_SEG(0x0001180080000058ull)
#define CVMX_L2C_LCKOFF \
CVMX_ADD_IO_SEG(0x0001180080000060ull)
#define CVMX_L2C_LFB0 \
CVMX_ADD_IO_SEG(0x0001180080000038ull)
#define CVMX_L2C_LFB1 \
CVMX_ADD_IO_SEG(0x0001180080000040ull)
#define CVMX_L2C_LFB2 \
CVMX_ADD_IO_SEG(0x0001180080000048ull)
#define CVMX_L2C_LFB3 \
CVMX_ADD_IO_SEG(0x00011800800000B8ull)
#define CVMX_L2C_OOB \
CVMX_ADD_IO_SEG(0x00011800800000D8ull)
#define CVMX_L2C_OOB1 \
CVMX_ADD_IO_SEG(0x00011800800000E0ull)
#define CVMX_L2C_OOB2 \
CVMX_ADD_IO_SEG(0x00011800800000E8ull)
#define CVMX_L2C_OOB3 \
CVMX_ADD_IO_SEG(0x00011800800000F0ull)
#define CVMX_L2C_PFC0 \
CVMX_ADD_IO_SEG(0x0001180080000098ull)
#define CVMX_L2C_PFC1 \
CVMX_ADD_IO_SEG(0x00011800800000A0ull)
#define CVMX_L2C_PFC2 \
CVMX_ADD_IO_SEG(0x00011800800000A8ull)
#define CVMX_L2C_PFC3 \
CVMX_ADD_IO_SEG(0x00011800800000B0ull)
#define CVMX_L2C_PFCTL \
CVMX_ADD_IO_SEG(0x0001180080000090ull)
#define CVMX_L2C_PFCX(offset) \
CVMX_ADD_IO_SEG(0x0001180080000098ull + (((offset) & 3) * 8))
#define CVMX_L2C_PPGRP \
CVMX_ADD_IO_SEG(0x00011800800000C0ull)
#define CVMX_L2C_SPAR0 \
CVMX_ADD_IO_SEG(0x0001180080000068ull)
#define CVMX_L2C_SPAR1 \
CVMX_ADD_IO_SEG(0x0001180080000070ull)
#define CVMX_L2C_SPAR2 \
CVMX_ADD_IO_SEG(0x0001180080000078ull)
#define CVMX_L2C_SPAR3 \
CVMX_ADD_IO_SEG(0x0001180080000080ull)
#define CVMX_L2C_SPAR4 \
CVMX_ADD_IO_SEG(0x0001180080000088ull)
union cvmx_l2c_bst0 {
uint64_t u64;
struct cvmx_l2c_bst0_s {
uint64_t reserved_24_63:40;
uint64_t dtbnk:1;
uint64_t wlb_msk:4;
uint64_t dtcnt:13;
uint64_t dt:1;
uint64_t stin_msk:1;
uint64_t wlb_dat:4;
} s;
struct cvmx_l2c_bst0_cn30xx {
uint64_t reserved_23_63:41;
uint64_t wlb_msk:4;
uint64_t reserved_15_18:4;
uint64_t dtcnt:9;
uint64_t dt:1;
uint64_t reserved_4_4:1;
uint64_t wlb_dat:4;
} cn30xx;
struct cvmx_l2c_bst0_cn31xx {
uint64_t reserved_23_63:41;
uint64_t wlb_msk:4;
uint64_t reserved_16_18:3;
uint64_t dtcnt:10;
uint64_t dt:1;
uint64_t stin_msk:1;
uint64_t wlb_dat:4;
} cn31xx;
struct cvmx_l2c_bst0_cn38xx {
uint64_t reserved_19_63:45;
uint64_t dtcnt:13;
uint64_t dt:1;
uint64_t stin_msk:1;
uint64_t wlb_dat:4;
} cn38xx;
struct cvmx_l2c_bst0_cn38xx cn38xxp2;
struct cvmx_l2c_bst0_cn50xx {
uint64_t reserved_24_63:40;
uint64_t dtbnk:1;
uint64_t wlb_msk:4;
uint64_t reserved_16_18:3;
uint64_t dtcnt:10;
uint64_t dt:1;
uint64_t stin_msk:1;
uint64_t wlb_dat:4;
} cn50xx;
struct cvmx_l2c_bst0_cn50xx cn52xx;
struct cvmx_l2c_bst0_cn50xx cn52xxp1;
struct cvmx_l2c_bst0_s cn56xx;
struct cvmx_l2c_bst0_s cn56xxp1;
struct cvmx_l2c_bst0_s cn58xx;
struct cvmx_l2c_bst0_s cn58xxp1;
};
union cvmx_l2c_bst1 {
uint64_t u64;
struct cvmx_l2c_bst1_s {
uint64_t reserved_9_63:55;
uint64_t l2t:9;
} s;
struct cvmx_l2c_bst1_cn30xx {
uint64_t reserved_16_63:48;
uint64_t vwdf:4;
uint64_t lrf:2;
uint64_t vab_vwcf:1;
uint64_t reserved_5_8:4;
uint64_t l2t:5;
} cn30xx;
struct cvmx_l2c_bst1_cn30xx cn31xx;
struct cvmx_l2c_bst1_cn38xx {
uint64_t reserved_16_63:48;
uint64_t vwdf:4;
uint64_t lrf:2;
uint64_t vab_vwcf:1;
uint64_t l2t:9;
} cn38xx;
struct cvmx_l2c_bst1_cn38xx cn38xxp2;
struct cvmx_l2c_bst1_cn38xx cn50xx;
struct cvmx_l2c_bst1_cn52xx {
uint64_t reserved_19_63:45;
uint64_t plc2:1;
uint64_t plc1:1;
uint64_t plc0:1;
uint64_t vwdf:4;
uint64_t reserved_11_11:1;
uint64_t ilc:1;
uint64_t vab_vwcf:1;
uint64_t l2t:9;
} cn52xx;
struct cvmx_l2c_bst1_cn52xx cn52xxp1;
struct cvmx_l2c_bst1_cn56xx {
uint64_t reserved_24_63:40;
uint64_t plc2:1;
uint64_t plc1:1;
uint64_t plc0:1;
uint64_t ilc:1;
uint64_t vwdf1:4;
uint64_t vwdf0:4;
uint64_t vab_vwcf1:1;
uint64_t reserved_10_10:1;
uint64_t vab_vwcf0:1;
uint64_t l2t:9;
} cn56xx;
struct cvmx_l2c_bst1_cn56xx cn56xxp1;
struct cvmx_l2c_bst1_cn38xx cn58xx;
struct cvmx_l2c_bst1_cn38xx cn58xxp1;
};
union cvmx_l2c_bst2 {
uint64_t u64;
struct cvmx_l2c_bst2_s {
uint64_t reserved_16_63:48;
uint64_t mrb:4;
uint64_t reserved_4_11:8;
uint64_t ipcbst:1;
uint64_t picbst:1;
uint64_t xrdmsk:1;
uint64_t xrddat:1;
} s;
struct cvmx_l2c_bst2_cn30xx {
uint64_t reserved_16_63:48;
uint64_t mrb:4;
uint64_t rmdf:4;
uint64_t reserved_4_7:4;
uint64_t ipcbst:1;
uint64_t reserved_2_2:1;
uint64_t xrdmsk:1;
uint64_t xrddat:1;
} cn30xx;
struct cvmx_l2c_bst2_cn30xx cn31xx;
struct cvmx_l2c_bst2_cn38xx {
uint64_t reserved_16_63:48;
uint64_t mrb:4;
uint64_t rmdf:4;
uint64_t rhdf:4;
uint64_t ipcbst:1;
uint64_t picbst:1;
uint64_t xrdmsk:1;
uint64_t xrddat:1;
} cn38xx;
struct cvmx_l2c_bst2_cn38xx cn38xxp2;
struct cvmx_l2c_bst2_cn30xx cn50xx;
struct cvmx_l2c_bst2_cn30xx cn52xx;
struct cvmx_l2c_bst2_cn30xx cn52xxp1;
struct cvmx_l2c_bst2_cn56xx {
uint64_t reserved_16_63:48;
uint64_t mrb:4;
uint64_t rmdb:4;
uint64_t rhdb:4;
uint64_t ipcbst:1;
uint64_t picbst:1;
uint64_t xrdmsk:1;
uint64_t xrddat:1;
} cn56xx;
struct cvmx_l2c_bst2_cn56xx cn56xxp1;
struct cvmx_l2c_bst2_cn56xx cn58xx;
struct cvmx_l2c_bst2_cn56xx cn58xxp1;
};
union cvmx_l2c_cfg {
uint64_t u64;
struct cvmx_l2c_cfg_s {
uint64_t reserved_20_63:44;
uint64_t bstrun:1;
uint64_t lbist:1;
uint64_t xor_bank:1;
uint64_t dpres1:1;
uint64_t dpres0:1;
uint64_t dfill_dis:1;
uint64_t fpexp:4;
uint64_t fpempty:1;
uint64_t fpen:1;
uint64_t idxalias:1;
uint64_t mwf_crd:4;
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
} s;
struct cvmx_l2c_cfg_cn30xx {
uint64_t reserved_14_63:50;
uint64_t fpexp:4;
uint64_t fpempty:1;
uint64_t fpen:1;
uint64_t idxalias:1;
uint64_t mwf_crd:4;
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
} cn30xx;
struct cvmx_l2c_cfg_cn30xx cn31xx;
struct cvmx_l2c_cfg_cn30xx cn38xx;
struct cvmx_l2c_cfg_cn30xx cn38xxp2;
struct cvmx_l2c_cfg_cn50xx {
uint64_t reserved_20_63:44;
uint64_t bstrun:1;
uint64_t lbist:1;
uint64_t reserved_14_17:4;
uint64_t fpexp:4;
uint64_t fpempty:1;
uint64_t fpen:1;
uint64_t idxalias:1;
uint64_t mwf_crd:4;
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
} cn50xx;
struct cvmx_l2c_cfg_cn50xx cn52xx;
struct cvmx_l2c_cfg_cn50xx cn52xxp1;
struct cvmx_l2c_cfg_s cn56xx;
struct cvmx_l2c_cfg_s cn56xxp1;
struct cvmx_l2c_cfg_cn58xx {
uint64_t reserved_20_63:44;
uint64_t bstrun:1;
uint64_t lbist:1;
uint64_t reserved_15_17:3;
uint64_t dfill_dis:1;
uint64_t fpexp:4;
uint64_t fpempty:1;
uint64_t fpen:1;
uint64_t idxalias:1;
uint64_t mwf_crd:4;
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
} cn58xx;
struct cvmx_l2c_cfg_cn58xxp1 {
uint64_t reserved_15_63:49;
uint64_t dfill_dis:1;
uint64_t fpexp:4;
uint64_t fpempty:1;
uint64_t fpen:1;
uint64_t idxalias:1;
uint64_t mwf_crd:4;
uint64_t rsp_arb_mode:1;
uint64_t rfb_arb_mode:1;
uint64_t lrf_arb_mode:1;
} cn58xxp1;
};
union cvmx_l2c_dbg {
uint64_t u64;
struct cvmx_l2c_dbg_s {
uint64_t reserved_15_63:49;
uint64_t lfb_enum:4;
uint64_t lfb_dmp:1;
uint64_t ppnum:4;
uint64_t set:3;
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
} s;
struct cvmx_l2c_dbg_cn30xx {
uint64_t reserved_13_63:51;
uint64_t lfb_enum:2;
uint64_t lfb_dmp:1;
uint64_t reserved_5_9:5;
uint64_t set:2;
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
} cn30xx;
struct cvmx_l2c_dbg_cn31xx {
uint64_t reserved_14_63:50;
uint64_t lfb_enum:3;
uint64_t lfb_dmp:1;
uint64_t reserved_7_9:3;
uint64_t ppnum:1;
uint64_t reserved_5_5:1;
uint64_t set:2;
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
} cn31xx;
struct cvmx_l2c_dbg_s cn38xx;
struct cvmx_l2c_dbg_s cn38xxp2;
struct cvmx_l2c_dbg_cn50xx {
uint64_t reserved_14_63:50;
uint64_t lfb_enum:3;
uint64_t lfb_dmp:1;
uint64_t reserved_7_9:3;
uint64_t ppnum:1;
uint64_t set:3;
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
} cn50xx;
struct cvmx_l2c_dbg_cn52xx {
uint64_t reserved_14_63:50;
uint64_t lfb_enum:3;
uint64_t lfb_dmp:1;
uint64_t reserved_8_9:2;
uint64_t ppnum:2;
uint64_t set:3;
uint64_t finv:1;
uint64_t l2d:1;
uint64_t l2t:1;
} cn52xx;
struct cvmx_l2c_dbg_cn52xx cn52xxp1;
struct cvmx_l2c_dbg_s cn56xx;
struct cvmx_l2c_dbg_s cn56xxp1;
struct cvmx_l2c_dbg_s cn58xx;
struct cvmx_l2c_dbg_s cn58xxp1;
};
union cvmx_l2c_dut {
uint64_t u64;
struct cvmx_l2c_dut_s {
uint64_t reserved_32_63:32;
uint64_t dtena:1;
uint64_t reserved_30_30:1;
uint64_t dt_vld:1;
uint64_t dt_tag:29;
} s;
struct cvmx_l2c_dut_s cn30xx;
struct cvmx_l2c_dut_s cn31xx;
struct cvmx_l2c_dut_s cn38xx;
struct cvmx_l2c_dut_s cn38xxp2;
struct cvmx_l2c_dut_s cn50xx;
struct cvmx_l2c_dut_s cn52xx;
struct cvmx_l2c_dut_s cn52xxp1;
struct cvmx_l2c_dut_s cn56xx;
struct cvmx_l2c_dut_s cn56xxp1;
struct cvmx_l2c_dut_s cn58xx;
struct cvmx_l2c_dut_s cn58xxp1;
};
union cvmx_l2c_grpwrr0 {
uint64_t u64;
struct cvmx_l2c_grpwrr0_s {
uint64_t plc1rmsk:32;
uint64_t plc0rmsk:32;
} s;
struct cvmx_l2c_grpwrr0_s cn52xx;
struct cvmx_l2c_grpwrr0_s cn52xxp1;
struct cvmx_l2c_grpwrr0_s cn56xx;
struct cvmx_l2c_grpwrr0_s cn56xxp1;
};
union cvmx_l2c_grpwrr1 {
uint64_t u64;
struct cvmx_l2c_grpwrr1_s {
uint64_t ilcrmsk:32;
uint64_t plc2rmsk:32;
} s;
struct cvmx_l2c_grpwrr1_s cn52xx;
struct cvmx_l2c_grpwrr1_s cn52xxp1;
struct cvmx_l2c_grpwrr1_s cn56xx;
struct cvmx_l2c_grpwrr1_s cn56xxp1;
};
union cvmx_l2c_int_en {
uint64_t u64;
struct cvmx_l2c_int_en_s {
uint64_t reserved_9_63:55;
uint64_t lck2ena:1;
uint64_t lckena:1;
uint64_t l2ddeden:1;
uint64_t l2dsecen:1;
uint64_t l2tdeden:1;
uint64_t l2tsecen:1;
uint64_t oob3en:1;
uint64_t oob2en:1;
uint64_t oob1en:1;
} s;
struct cvmx_l2c_int_en_s cn52xx;
struct cvmx_l2c_int_en_s cn52xxp1;
struct cvmx_l2c_int_en_s cn56xx;
struct cvmx_l2c_int_en_s cn56xxp1;
};
union cvmx_l2c_int_stat {
uint64_t u64;
struct cvmx_l2c_int_stat_s {
uint64_t reserved_9_63:55;
uint64_t lck2:1;
uint64_t lck:1;
uint64_t l2dded:1;
uint64_t l2dsec:1;
uint64_t l2tded:1;
uint64_t l2tsec:1;
uint64_t oob3:1;
uint64_t oob2:1;
uint64_t oob1:1;
} s;
struct cvmx_l2c_int_stat_s cn52xx;
struct cvmx_l2c_int_stat_s cn52xxp1;
struct cvmx_l2c_int_stat_s cn56xx;
struct cvmx_l2c_int_stat_s cn56xxp1;
};
union cvmx_l2c_lckbase {
uint64_t u64;
struct cvmx_l2c_lckbase_s {
uint64_t reserved_31_63:33;
uint64_t lck_base:27;
uint64_t reserved_1_3:3;
uint64_t lck_ena:1;
} s;
struct cvmx_l2c_lckbase_s cn30xx;
struct cvmx_l2c_lckbase_s cn31xx;
struct cvmx_l2c_lckbase_s cn38xx;
struct cvmx_l2c_lckbase_s cn38xxp2;
struct cvmx_l2c_lckbase_s cn50xx;
struct cvmx_l2c_lckbase_s cn52xx;
struct cvmx_l2c_lckbase_s cn52xxp1;
struct cvmx_l2c_lckbase_s cn56xx;
struct cvmx_l2c_lckbase_s cn56xxp1;
struct cvmx_l2c_lckbase_s cn58xx;
struct cvmx_l2c_lckbase_s cn58xxp1;
};
union cvmx_l2c_lckoff {
uint64_t u64;
struct cvmx_l2c_lckoff_s {
uint64_t reserved_10_63:54;
uint64_t lck_offset:10;
} s;
struct cvmx_l2c_lckoff_s cn30xx;
struct cvmx_l2c_lckoff_s cn31xx;
struct cvmx_l2c_lckoff_s cn38xx;
struct cvmx_l2c_lckoff_s cn38xxp2;
struct cvmx_l2c_lckoff_s cn50xx;
struct cvmx_l2c_lckoff_s cn52xx;
struct cvmx_l2c_lckoff_s cn52xxp1;
struct cvmx_l2c_lckoff_s cn56xx;
struct cvmx_l2c_lckoff_s cn56xxp1;
struct cvmx_l2c_lckoff_s cn58xx;
struct cvmx_l2c_lckoff_s cn58xxp1;
};
union cvmx_l2c_lfb0 {
uint64_t u64;
struct cvmx_l2c_lfb0_s {
uint64_t reserved_32_63:32;
uint64_t stcpnd:1;
uint64_t stpnd:1;
uint64_t stinv:1;
uint64_t stcfl:1;
uint64_t vam:1;
uint64_t inxt:4;
uint64_t itl:1;
uint64_t ihd:1;
uint64_t set:3;
uint64_t vabnum:4;
uint64_t sid:9;
uint64_t cmd:4;
uint64_t vld:1;
} s;
struct cvmx_l2c_lfb0_cn30xx {
uint64_t reserved_32_63:32;
uint64_t stcpnd:1;
uint64_t stpnd:1;
uint64_t stinv:1;
uint64_t stcfl:1;
uint64_t vam:1;
uint64_t reserved_25_26:2;
uint64_t inxt:2;
uint64_t itl:1;
uint64_t ihd:1;
uint64_t reserved_20_20:1;
uint64_t set:2;
uint64_t reserved_16_17:2;
uint64_t vabnum:2;
uint64_t sid:9;
uint64_t cmd:4;
uint64_t vld:1;
} cn30xx;
struct cvmx_l2c_lfb0_cn31xx {
uint64_t reserved_32_63:32;
uint64_t stcpnd:1;
uint64_t stpnd:1;
uint64_t stinv:1;
uint64_t stcfl:1;
uint64_t vam:1;
uint64_t reserved_26_26:1;
uint64_t inxt:3;
uint64_t itl:1;
uint64_t ihd:1;
uint64_t reserved_20_20:1;
uint64_t set:2;
uint64_t reserved_17_17:1;
uint64_t vabnum:3;
uint64_t sid:9;
uint64_t cmd:4;
uint64_t vld:1;
} cn31xx;
struct cvmx_l2c_lfb0_s cn38xx;
struct cvmx_l2c_lfb0_s cn38xxp2;
struct cvmx_l2c_lfb0_cn50xx {
uint64_t reserved_32_63:32;
uint64_t stcpnd:1;
uint64_t stpnd:1;
uint64_t stinv:1;
uint64_t stcfl:1;
uint64_t vam:1;
uint64_t reserved_26_26:1;
uint64_t inxt:3;
uint64_t itl:1;
uint64_t ihd:1;
uint64_t set:3;
uint64_t reserved_17_17:1;
uint64_t vabnum:3;
uint64_t sid:9;
uint64_t cmd:4;
uint64_t vld:1;
} cn50xx;
struct cvmx_l2c_lfb0_cn50xx cn52xx;
struct cvmx_l2c_lfb0_cn50xx cn52xxp1;
struct cvmx_l2c_lfb0_s cn56xx;
struct cvmx_l2c_lfb0_s cn56xxp1;
struct cvmx_l2c_lfb0_s cn58xx;
struct cvmx_l2c_lfb0_s cn58xxp1;
};
union cvmx_l2c_lfb1 {
uint64_t u64;
struct cvmx_l2c_lfb1_s {
uint64_t reserved_19_63:45;
uint64_t dsgoing:1;
uint64_t bid:2;
uint64_t wtrsp:1;
uint64_t wtdw:1;
uint64_t wtdq:1;
uint64_t wtwhp:1;
uint64_t wtwhf:1;
uint64_t wtwrm:1;
uint64_t wtstm:1;
uint64_t wtrda:1;
uint64_t wtstdt:1;
uint64_t wtstrsp:1;
uint64_t wtstrsc:1;
uint64_t wtvtm:1;
uint64_t wtmfl:1;
uint64_t prbrty:1;
uint64_t wtprb:1;
uint64_t vld:1;
} s;
struct cvmx_l2c_lfb1_s cn30xx;
struct cvmx_l2c_lfb1_s cn31xx;
struct cvmx_l2c_lfb1_s cn38xx;
struct cvmx_l2c_lfb1_s cn38xxp2;
struct cvmx_l2c_lfb1_s cn50xx;
struct cvmx_l2c_lfb1_s cn52xx;
struct cvmx_l2c_lfb1_s cn52xxp1;
struct cvmx_l2c_lfb1_s cn56xx;
struct cvmx_l2c_lfb1_s cn56xxp1;
struct cvmx_l2c_lfb1_s cn58xx;
struct cvmx_l2c_lfb1_s cn58xxp1;
};
union cvmx_l2c_lfb2 {
uint64_t u64;
struct cvmx_l2c_lfb2_s {
uint64_t reserved_0_63:64;
} s;
struct cvmx_l2c_lfb2_cn30xx {
uint64_t reserved_27_63:37;
uint64_t lfb_tag:19;
uint64_t lfb_idx:8;
} cn30xx;
struct cvmx_l2c_lfb2_cn31xx {
uint64_t reserved_27_63:37;
uint64_t lfb_tag:17;
uint64_t lfb_idx:10;
} cn31xx;
struct cvmx_l2c_lfb2_cn31xx cn38xx;
struct cvmx_l2c_lfb2_cn31xx cn38xxp2;
struct cvmx_l2c_lfb2_cn50xx {
uint64_t reserved_27_63:37;
uint64_t lfb_tag:20;
uint64_t lfb_idx:7;
} cn50xx;
struct cvmx_l2c_lfb2_cn52xx {
uint64_t reserved_27_63:37;
uint64_t lfb_tag:18;
uint64_t lfb_idx:9;
} cn52xx;
struct cvmx_l2c_lfb2_cn52xx cn52xxp1;
struct cvmx_l2c_lfb2_cn56xx {
uint64_t reserved_27_63:37;
uint64_t lfb_tag:16;
uint64_t lfb_idx:11;
} cn56xx;
struct cvmx_l2c_lfb2_cn56xx cn56xxp1;
struct cvmx_l2c_lfb2_cn56xx cn58xx;
struct cvmx_l2c_lfb2_cn56xx cn58xxp1;
};
union cvmx_l2c_lfb3 {
uint64_t u64;
struct cvmx_l2c_lfb3_s {
uint64_t reserved_5_63:59;
uint64_t stpartdis:1;
uint64_t lfb_hwm:4;
} s;
struct cvmx_l2c_lfb3_cn30xx {
uint64_t reserved_5_63:59;
uint64_t stpartdis:1;
uint64_t reserved_2_3:2;
uint64_t lfb_hwm:2;
} cn30xx;
struct cvmx_l2c_lfb3_cn31xx {
uint64_t reserved_5_63:59;
uint64_t stpartdis:1;
uint64_t reserved_3_3:1;
uint64_t lfb_hwm:3;
} cn31xx;
struct cvmx_l2c_lfb3_s cn38xx;
struct cvmx_l2c_lfb3_s cn38xxp2;
struct cvmx_l2c_lfb3_cn31xx cn50xx;
struct cvmx_l2c_lfb3_cn31xx cn52xx;
struct cvmx_l2c_lfb3_cn31xx cn52xxp1;
struct cvmx_l2c_lfb3_s cn56xx;
struct cvmx_l2c_lfb3_s cn56xxp1;
struct cvmx_l2c_lfb3_s cn58xx;
struct cvmx_l2c_lfb3_s cn58xxp1;
};
union cvmx_l2c_oob {
uint64_t u64;
struct cvmx_l2c_oob_s {
uint64_t reserved_2_63:62;
uint64_t dwbena:1;
uint64_t stena:1;
} s;
struct cvmx_l2c_oob_s cn52xx;
struct cvmx_l2c_oob_s cn52xxp1;
struct cvmx_l2c_oob_s cn56xx;
struct cvmx_l2c_oob_s cn56xxp1;
};
union cvmx_l2c_oob1 {
uint64_t u64;
struct cvmx_l2c_oob1_s {
uint64_t fadr:27;
uint64_t fsrc:1;
uint64_t reserved_34_35:2;
uint64_t sadr:14;
uint64_t reserved_14_19:6;
uint64_t size:14;
} s;
struct cvmx_l2c_oob1_s cn52xx;
struct cvmx_l2c_oob1_s cn52xxp1;
struct cvmx_l2c_oob1_s cn56xx;
struct cvmx_l2c_oob1_s cn56xxp1;
};
union cvmx_l2c_oob2 {
uint64_t u64;
struct cvmx_l2c_oob2_s {
uint64_t fadr:27;
uint64_t fsrc:1;
uint64_t reserved_34_35:2;
uint64_t sadr:14;
uint64_t reserved_14_19:6;
uint64_t size:14;
} s;
struct cvmx_l2c_oob2_s cn52xx;
struct cvmx_l2c_oob2_s cn52xxp1;
struct cvmx_l2c_oob2_s cn56xx;
struct cvmx_l2c_oob2_s cn56xxp1;
};
union cvmx_l2c_oob3 {
uint64_t u64;
struct cvmx_l2c_oob3_s {
uint64_t fadr:27;
uint64_t fsrc:1;
uint64_t reserved_34_35:2;
uint64_t sadr:14;
uint64_t reserved_14_19:6;
uint64_t size:14;
} s;
struct cvmx_l2c_oob3_s cn52xx;
struct cvmx_l2c_oob3_s cn52xxp1;
struct cvmx_l2c_oob3_s cn56xx;
struct cvmx_l2c_oob3_s cn56xxp1;
};
union cvmx_l2c_pfcx {
uint64_t u64;
struct cvmx_l2c_pfcx_s {
uint64_t reserved_36_63:28;
uint64_t pfcnt0:36;
} s;
struct cvmx_l2c_pfcx_s cn30xx;
struct cvmx_l2c_pfcx_s cn31xx;
struct cvmx_l2c_pfcx_s cn38xx;
struct cvmx_l2c_pfcx_s cn38xxp2;
struct cvmx_l2c_pfcx_s cn50xx;
struct cvmx_l2c_pfcx_s cn52xx;
struct cvmx_l2c_pfcx_s cn52xxp1;
struct cvmx_l2c_pfcx_s cn56xx;
struct cvmx_l2c_pfcx_s cn56xxp1;
struct cvmx_l2c_pfcx_s cn58xx;
struct cvmx_l2c_pfcx_s cn58xxp1;
};
union cvmx_l2c_pfctl {
uint64_t u64;
struct cvmx_l2c_pfctl_s {
uint64_t reserved_36_63:28;
uint64_t cnt3rdclr:1;
uint64_t cnt2rdclr:1;
uint64_t cnt1rdclr:1;
uint64_t cnt0rdclr:1;
uint64_t cnt3ena:1;
uint64_t cnt3clr:1;
uint64_t cnt3sel:6;
uint64_t cnt2ena:1;
uint64_t cnt2clr:1;
uint64_t cnt2sel:6;
uint64_t cnt1ena:1;
uint64_t cnt1clr:1;
uint64_t cnt1sel:6;
uint64_t cnt0ena:1;
uint64_t cnt0clr:1;
uint64_t cnt0sel:6;
} s;
struct cvmx_l2c_pfctl_s cn30xx;
struct cvmx_l2c_pfctl_s cn31xx;
struct cvmx_l2c_pfctl_s cn38xx;
struct cvmx_l2c_pfctl_s cn38xxp2;
struct cvmx_l2c_pfctl_s cn50xx;
struct cvmx_l2c_pfctl_s cn52xx;
struct cvmx_l2c_pfctl_s cn52xxp1;
struct cvmx_l2c_pfctl_s cn56xx;
struct cvmx_l2c_pfctl_s cn56xxp1;
struct cvmx_l2c_pfctl_s cn58xx;
struct cvmx_l2c_pfctl_s cn58xxp1;
};
union cvmx_l2c_ppgrp {
uint64_t u64;
struct cvmx_l2c_ppgrp_s {
uint64_t reserved_24_63:40;
uint64_t pp11grp:2;
uint64_t pp10grp:2;
uint64_t pp9grp:2;
uint64_t pp8grp:2;
uint64_t pp7grp:2;
uint64_t pp6grp:2;
uint64_t pp5grp:2;
uint64_t pp4grp:2;
uint64_t pp3grp:2;
uint64_t pp2grp:2;
uint64_t pp1grp:2;
uint64_t pp0grp:2;
} s;
struct cvmx_l2c_ppgrp_cn52xx {
uint64_t reserved_8_63:56;
uint64_t pp3grp:2;
uint64_t pp2grp:2;
uint64_t pp1grp:2;
uint64_t pp0grp:2;
} cn52xx;
struct cvmx_l2c_ppgrp_cn52xx cn52xxp1;
struct cvmx_l2c_ppgrp_s cn56xx;
struct cvmx_l2c_ppgrp_s cn56xxp1;
};
union cvmx_l2c_spar0 {
uint64_t u64;
struct cvmx_l2c_spar0_s {
uint64_t reserved_32_63:32;
uint64_t umsk3:8;
uint64_t umsk2:8;
uint64_t umsk1:8;
uint64_t umsk0:8;
} s;
struct cvmx_l2c_spar0_cn30xx {
uint64_t reserved_4_63:60;
uint64_t umsk0:4;
} cn30xx;
struct cvmx_l2c_spar0_cn31xx {
uint64_t reserved_12_63:52;
uint64_t umsk1:4;
uint64_t reserved_4_7:4;
uint64_t umsk0:4;
} cn31xx;
struct cvmx_l2c_spar0_s cn38xx;
struct cvmx_l2c_spar0_s cn38xxp2;
struct cvmx_l2c_spar0_cn50xx {
uint64_t reserved_16_63:48;
uint64_t umsk1:8;
uint64_t umsk0:8;
} cn50xx;
struct cvmx_l2c_spar0_s cn52xx;
struct cvmx_l2c_spar0_s cn52xxp1;
struct cvmx_l2c_spar0_s cn56xx;
struct cvmx_l2c_spar0_s cn56xxp1;
struct cvmx_l2c_spar0_s cn58xx;
struct cvmx_l2c_spar0_s cn58xxp1;
};
union cvmx_l2c_spar1 {
uint64_t u64;
struct cvmx_l2c_spar1_s {
uint64_t reserved_32_63:32;
uint64_t umsk7:8;
uint64_t umsk6:8;
uint64_t umsk5:8;
uint64_t umsk4:8;
} s;
struct cvmx_l2c_spar1_s cn38xx;
struct cvmx_l2c_spar1_s cn38xxp2;
struct cvmx_l2c_spar1_s cn56xx;
struct cvmx_l2c_spar1_s cn56xxp1;
struct cvmx_l2c_spar1_s cn58xx;
struct cvmx_l2c_spar1_s cn58xxp1;
};
union cvmx_l2c_spar2 {
uint64_t u64;
struct cvmx_l2c_spar2_s {
uint64_t reserved_32_63:32;
uint64_t umsk11:8;
uint64_t umsk10:8;
uint64_t umsk9:8;
uint64_t umsk8:8;
} s;
struct cvmx_l2c_spar2_s cn38xx;
struct cvmx_l2c_spar2_s cn38xxp2;
struct cvmx_l2c_spar2_s cn56xx;
struct cvmx_l2c_spar2_s cn56xxp1;
struct cvmx_l2c_spar2_s cn58xx;
struct cvmx_l2c_spar2_s cn58xxp1;
};
union cvmx_l2c_spar3 {
uint64_t u64;
struct cvmx_l2c_spar3_s {
uint64_t reserved_32_63:32;
uint64_t umsk15:8;
uint64_t umsk14:8;
uint64_t umsk13:8;
uint64_t umsk12:8;
} s;
struct cvmx_l2c_spar3_s cn38xx;
struct cvmx_l2c_spar3_s cn38xxp2;
struct cvmx_l2c_spar3_s cn58xx;
struct cvmx_l2c_spar3_s cn58xxp1;
};
union cvmx_l2c_spar4 {
uint64_t u64;
struct cvmx_l2c_spar4_s {
uint64_t reserved_8_63:56;
uint64_t umskiob:8;
} s;
struct cvmx_l2c_spar4_cn30xx {
uint64_t reserved_4_63:60;
uint64_t umskiob:4;
} cn30xx;
struct cvmx_l2c_spar4_cn30xx cn31xx;
struct cvmx_l2c_spar4_s cn38xx;
struct cvmx_l2c_spar4_s cn38xxp2;
struct cvmx_l2c_spar4_s cn50xx;
struct cvmx_l2c_spar4_s cn52xx;
struct cvmx_l2c_spar4_s cn52xxp1;
struct cvmx_l2c_spar4_s cn56xx;
struct cvmx_l2c_spar4_s cn56xxp1;
struct cvmx_l2c_spar4_s cn58xx;
struct cvmx_l2c_spar4_s cn58xxp1;
};
#endif

View file

@ -0,0 +1,325 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
*
* Interface to the Level 2 Cache (L2C) control, measurement, and debugging
* facilities.
*/
#ifndef __CVMX_L2C_H__
#define __CVMX_L2C_H__
/* Deprecated macro, use function */
#define CVMX_L2_ASSOC cvmx_l2c_get_num_assoc()
/* Deprecated macro, use function */
#define CVMX_L2_SET_BITS cvmx_l2c_get_set_bits()
/* Deprecated macro, use function */
#define CVMX_L2_SETS cvmx_l2c_get_num_sets()
#define CVMX_L2C_IDX_ADDR_SHIFT 7 /* based on 128 byte cache line size */
#define CVMX_L2C_IDX_MASK (cvmx_l2c_get_num_sets() - 1)
/* Defines for index aliasing computations */
#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT \
(CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits())
#define CVMX_L2C_ALIAS_MASK \
(CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT)
union cvmx_l2c_tag {
uint64_t u64;
struct {
uint64_t reserved:28;
uint64_t V:1; /* Line valid */
uint64_t D:1; /* Line dirty */
uint64_t L:1; /* Line locked */
uint64_t U:1; /* Use, LRU eviction */
uint64_t addr:32; /* Phys mem (not all bits valid) */
} s;
};
/* L2C Performance Counter events. */
enum cvmx_l2c_event {
CVMX_L2C_EVENT_CYCLES = 0,
CVMX_L2C_EVENT_INSTRUCTION_MISS = 1,
CVMX_L2C_EVENT_INSTRUCTION_HIT = 2,
CVMX_L2C_EVENT_DATA_MISS = 3,
CVMX_L2C_EVENT_DATA_HIT = 4,
CVMX_L2C_EVENT_MISS = 5,
CVMX_L2C_EVENT_HIT = 6,
CVMX_L2C_EVENT_VICTIM_HIT = 7,
CVMX_L2C_EVENT_INDEX_CONFLICT = 8,
CVMX_L2C_EVENT_TAG_PROBE = 9,
CVMX_L2C_EVENT_TAG_UPDATE = 10,
CVMX_L2C_EVENT_TAG_COMPLETE = 11,
CVMX_L2C_EVENT_TAG_DIRTY = 12,
CVMX_L2C_EVENT_DATA_STORE_NOP = 13,
CVMX_L2C_EVENT_DATA_STORE_READ = 14,
CVMX_L2C_EVENT_DATA_STORE_WRITE = 15,
CVMX_L2C_EVENT_FILL_DATA_VALID = 16,
CVMX_L2C_EVENT_WRITE_REQUEST = 17,
CVMX_L2C_EVENT_READ_REQUEST = 18,
CVMX_L2C_EVENT_WRITE_DATA_VALID = 19,
CVMX_L2C_EVENT_XMC_NOP = 20,
CVMX_L2C_EVENT_XMC_LDT = 21,
CVMX_L2C_EVENT_XMC_LDI = 22,
CVMX_L2C_EVENT_XMC_LDD = 23,
CVMX_L2C_EVENT_XMC_STF = 24,
CVMX_L2C_EVENT_XMC_STT = 25,
CVMX_L2C_EVENT_XMC_STP = 26,
CVMX_L2C_EVENT_XMC_STC = 27,
CVMX_L2C_EVENT_XMC_DWB = 28,
CVMX_L2C_EVENT_XMC_PL2 = 29,
CVMX_L2C_EVENT_XMC_PSL1 = 30,
CVMX_L2C_EVENT_XMC_IOBLD = 31,
CVMX_L2C_EVENT_XMC_IOBST = 32,
CVMX_L2C_EVENT_XMC_IOBDMA = 33,
CVMX_L2C_EVENT_XMC_IOBRSP = 34,
CVMX_L2C_EVENT_XMC_BUS_VALID = 35,
CVMX_L2C_EVENT_XMC_MEM_DATA = 36,
CVMX_L2C_EVENT_XMC_REFL_DATA = 37,
CVMX_L2C_EVENT_XMC_IOBRSP_DATA = 38,
CVMX_L2C_EVENT_RSC_NOP = 39,
CVMX_L2C_EVENT_RSC_STDN = 40,
CVMX_L2C_EVENT_RSC_FILL = 41,
CVMX_L2C_EVENT_RSC_REFL = 42,
CVMX_L2C_EVENT_RSC_STIN = 43,
CVMX_L2C_EVENT_RSC_SCIN = 44,
CVMX_L2C_EVENT_RSC_SCFL = 45,
CVMX_L2C_EVENT_RSC_SCDN = 46,
CVMX_L2C_EVENT_RSC_DATA_VALID = 47,
CVMX_L2C_EVENT_RSC_VALID_FILL = 48,
CVMX_L2C_EVENT_RSC_VALID_STRSP = 49,
CVMX_L2C_EVENT_RSC_VALID_REFL = 50,
CVMX_L2C_EVENT_LRF_REQ = 51,
CVMX_L2C_EVENT_DT_RD_ALLOC = 52,
CVMX_L2C_EVENT_DT_WR_INVAL = 53
};
/**
* Configure one of the four L2 Cache performance counters to capture event
* occurences.
*
* @counter: The counter to configure. Range 0..3.
* @event: The type of L2 Cache event occurrence to count.
* @clear_on_read: When asserted, any read of the performance counter
* clears the counter.
*
* The routine does not clear the counter.
*/
void cvmx_l2c_config_perf(uint32_t counter,
enum cvmx_l2c_event event, uint32_t clear_on_read);
/**
* Read the given L2 Cache performance counter. The counter must be configured
* before reading, but this routine does not enforce this requirement.
*
* @counter: The counter to configure. Range 0..3.
*
* Returns The current counter value.
*/
uint64_t cvmx_l2c_read_perf(uint32_t counter);
/**
* Return the L2 Cache way partitioning for a given core.
*
* @core: The core processor of interest.
*
* Returns The mask specifying the partitioning. 0 bits in mask indicates
* the cache 'ways' that a core can evict from.
* -1 on error
*/
int cvmx_l2c_get_core_way_partition(uint32_t core);
/**
* Partitions the L2 cache for a core
*
* @core: The core that the partitioning applies to.
*
* @mask: The partitioning of the ways expressed as a binary mask. A 0
* bit allows the core to evict cache lines from a way, while a
* 1 bit blocks the core from evicting any lines from that
* way. There must be at least one allowed way (0 bit) in the
* mask.
*
* If any ways are blocked for all cores and the HW blocks, then those
* ways will never have any cache lines evicted from them. All cores
* and the hardware blocks are free to read from all ways regardless
* of the partitioning.
*/
int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask);
/**
* Return the L2 Cache way partitioning for the hw blocks.
*
* Returns The mask specifying the reserved way. 0 bits in mask indicates
* the cache 'ways' that a core can evict from.
* -1 on error
*/
int cvmx_l2c_get_hw_way_partition(void);
/**
* Partitions the L2 cache for the hardware blocks.
*
* @mask: The partitioning of the ways expressed as a binary mask. A 0
* bit allows the core to evict cache lines from a way, while a
* 1 bit blocks the core from evicting any lines from that
* way. There must be at least one allowed way (0 bit) in the
* mask.
*
* If any ways are blocked for all cores and the HW blocks, then those
* ways will never have any cache lines evicted from them. All cores
* and the hardware blocks are free to read from all ways regardless
* of the partitioning.
*/
int cvmx_l2c_set_hw_way_partition(uint32_t mask);
/**
* Locks a line in the L2 cache at the specified physical address
*
* @addr: physical address of line to lock
*
* Returns 0 on success,
* 1 if line not locked.
*/
int cvmx_l2c_lock_line(uint64_t addr);
/**
* Locks a specified memory region in the L2 cache.
*
* Note that if not all lines can be locked, that means that all
* but one of the ways (associations) available to the locking
* core are locked. Having only 1 association available for
* normal caching may have a significant adverse affect on performance.
* Care should be taken to ensure that enough of the L2 cache is left
* unlocked to allow for normal caching of DRAM.
*
* @start: Physical address of the start of the region to lock
* @len: Length (in bytes) of region to lock
*
* Returns Number of requested lines that where not locked.
* 0 on success (all locked)
*/
int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len);
/**
* Unlock and flush a cache line from the L2 cache.
* IMPORTANT: Must only be run by one core at a time due to use
* of L2C debug features.
* Note that this function will flush a matching but unlocked cache line.
* (If address is not in L2, no lines are flushed.)
*
* @address: Physical address to unlock
*
* Returns 0: line not unlocked
* 1: line unlocked
*/
int cvmx_l2c_unlock_line(uint64_t address);
/**
* Unlocks a region of memory that is locked in the L2 cache
*
* @start: start physical address
* @len: length (in bytes) to unlock
*
* Returns Number of locked lines that the call unlocked
*/
int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len);
/**
* Read the L2 controller tag for a given location in L2
*
* @association:
* Which association to read line from
* @index: Which way to read from.
*
* Returns l2c tag structure for line requested.
*/
union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index);
/* Wrapper around deprecated old function name */
static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association,
uint32_t index)
{
return cvmx_l2c_get_tag(association, index);
}
/**
* Returns the cache index for a given physical address
*
* @addr: physical address
*
* Returns L2 cache index
*/
uint32_t cvmx_l2c_address_to_index(uint64_t addr);
/**
* Flushes (and unlocks) the entire L2 cache.
* IMPORTANT: Must only be run by one core at a time due to use
* of L2C debug features.
*/
void cvmx_l2c_flush(void);
/**
*
* Returns Returns the size of the L2 cache in bytes,
* -1 on error (unrecognized model)
*/
int cvmx_l2c_get_cache_size_bytes(void);
/**
* Return the number of sets in the L2 Cache
*
* Returns
*/
int cvmx_l2c_get_num_sets(void);
/**
* Return log base 2 of the number of sets in the L2 cache
* Returns
*/
int cvmx_l2c_get_set_bits(void);
/**
* Return the number of associations in the L2 Cache
*
* Returns
*/
int cvmx_l2c_get_num_assoc(void);
/**
* Flush a line from the L2 cache
* This should only be called from one core at a time, as this routine
* sets the core to the 'debug' core in order to flush the line.
*
* @assoc: Association (or way) to flush
* @index: Index to flush
*/
void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index);
#endif /* __CVMX_L2C_H__ */

View file

@ -0,0 +1,369 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_L2D_DEFS_H__
#define __CVMX_L2D_DEFS_H__
#define CVMX_L2D_BST0 \
CVMX_ADD_IO_SEG(0x0001180080000780ull)
#define CVMX_L2D_BST1 \
CVMX_ADD_IO_SEG(0x0001180080000788ull)
#define CVMX_L2D_BST2 \
CVMX_ADD_IO_SEG(0x0001180080000790ull)
#define CVMX_L2D_BST3 \
CVMX_ADD_IO_SEG(0x0001180080000798ull)
#define CVMX_L2D_ERR \
CVMX_ADD_IO_SEG(0x0001180080000010ull)
#define CVMX_L2D_FADR \
CVMX_ADD_IO_SEG(0x0001180080000018ull)
#define CVMX_L2D_FSYN0 \
CVMX_ADD_IO_SEG(0x0001180080000020ull)
#define CVMX_L2D_FSYN1 \
CVMX_ADD_IO_SEG(0x0001180080000028ull)
#define CVMX_L2D_FUS0 \
CVMX_ADD_IO_SEG(0x00011800800007A0ull)
#define CVMX_L2D_FUS1 \
CVMX_ADD_IO_SEG(0x00011800800007A8ull)
#define CVMX_L2D_FUS2 \
CVMX_ADD_IO_SEG(0x00011800800007B0ull)
#define CVMX_L2D_FUS3 \
CVMX_ADD_IO_SEG(0x00011800800007B8ull)
union cvmx_l2d_bst0 {
uint64_t u64;
struct cvmx_l2d_bst0_s {
uint64_t reserved_35_63:29;
uint64_t ftl:1;
uint64_t q0stat:34;
} s;
struct cvmx_l2d_bst0_s cn30xx;
struct cvmx_l2d_bst0_s cn31xx;
struct cvmx_l2d_bst0_s cn38xx;
struct cvmx_l2d_bst0_s cn38xxp2;
struct cvmx_l2d_bst0_s cn50xx;
struct cvmx_l2d_bst0_s cn52xx;
struct cvmx_l2d_bst0_s cn52xxp1;
struct cvmx_l2d_bst0_s cn56xx;
struct cvmx_l2d_bst0_s cn56xxp1;
struct cvmx_l2d_bst0_s cn58xx;
struct cvmx_l2d_bst0_s cn58xxp1;
};
union cvmx_l2d_bst1 {
uint64_t u64;
struct cvmx_l2d_bst1_s {
uint64_t reserved_34_63:30;
uint64_t q1stat:34;
} s;
struct cvmx_l2d_bst1_s cn30xx;
struct cvmx_l2d_bst1_s cn31xx;
struct cvmx_l2d_bst1_s cn38xx;
struct cvmx_l2d_bst1_s cn38xxp2;
struct cvmx_l2d_bst1_s cn50xx;
struct cvmx_l2d_bst1_s cn52xx;
struct cvmx_l2d_bst1_s cn52xxp1;
struct cvmx_l2d_bst1_s cn56xx;
struct cvmx_l2d_bst1_s cn56xxp1;
struct cvmx_l2d_bst1_s cn58xx;
struct cvmx_l2d_bst1_s cn58xxp1;
};
union cvmx_l2d_bst2 {
uint64_t u64;
struct cvmx_l2d_bst2_s {
uint64_t reserved_34_63:30;
uint64_t q2stat:34;
} s;
struct cvmx_l2d_bst2_s cn30xx;
struct cvmx_l2d_bst2_s cn31xx;
struct cvmx_l2d_bst2_s cn38xx;
struct cvmx_l2d_bst2_s cn38xxp2;
struct cvmx_l2d_bst2_s cn50xx;
struct cvmx_l2d_bst2_s cn52xx;
struct cvmx_l2d_bst2_s cn52xxp1;
struct cvmx_l2d_bst2_s cn56xx;
struct cvmx_l2d_bst2_s cn56xxp1;
struct cvmx_l2d_bst2_s cn58xx;
struct cvmx_l2d_bst2_s cn58xxp1;
};
union cvmx_l2d_bst3 {
uint64_t u64;
struct cvmx_l2d_bst3_s {
uint64_t reserved_34_63:30;
uint64_t q3stat:34;
} s;
struct cvmx_l2d_bst3_s cn30xx;
struct cvmx_l2d_bst3_s cn31xx;
struct cvmx_l2d_bst3_s cn38xx;
struct cvmx_l2d_bst3_s cn38xxp2;
struct cvmx_l2d_bst3_s cn50xx;
struct cvmx_l2d_bst3_s cn52xx;
struct cvmx_l2d_bst3_s cn52xxp1;
struct cvmx_l2d_bst3_s cn56xx;
struct cvmx_l2d_bst3_s cn56xxp1;
struct cvmx_l2d_bst3_s cn58xx;
struct cvmx_l2d_bst3_s cn58xxp1;
};
union cvmx_l2d_err {
uint64_t u64;
struct cvmx_l2d_err_s {
uint64_t reserved_6_63:58;
uint64_t bmhclsel:1;
uint64_t ded_err:1;
uint64_t sec_err:1;
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
} s;
struct cvmx_l2d_err_s cn30xx;
struct cvmx_l2d_err_s cn31xx;
struct cvmx_l2d_err_s cn38xx;
struct cvmx_l2d_err_s cn38xxp2;
struct cvmx_l2d_err_s cn50xx;
struct cvmx_l2d_err_s cn52xx;
struct cvmx_l2d_err_s cn52xxp1;
struct cvmx_l2d_err_s cn56xx;
struct cvmx_l2d_err_s cn56xxp1;
struct cvmx_l2d_err_s cn58xx;
struct cvmx_l2d_err_s cn58xxp1;
};
union cvmx_l2d_fadr {
uint64_t u64;
struct cvmx_l2d_fadr_s {
uint64_t reserved_19_63:45;
uint64_t fadru:1;
uint64_t fowmsk:4;
uint64_t fset:3;
uint64_t fadr:11;
} s;
struct cvmx_l2d_fadr_cn30xx {
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t reserved_13_13:1;
uint64_t fset:2;
uint64_t reserved_9_10:2;
uint64_t fadr:9;
} cn30xx;
struct cvmx_l2d_fadr_cn31xx {
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t reserved_13_13:1;
uint64_t fset:2;
uint64_t reserved_10_10:1;
uint64_t fadr:10;
} cn31xx;
struct cvmx_l2d_fadr_cn38xx {
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t fset:3;
uint64_t fadr:11;
} cn38xx;
struct cvmx_l2d_fadr_cn38xx cn38xxp2;
struct cvmx_l2d_fadr_cn50xx {
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t fset:3;
uint64_t reserved_8_10:3;
uint64_t fadr:8;
} cn50xx;
struct cvmx_l2d_fadr_cn52xx {
uint64_t reserved_18_63:46;
uint64_t fowmsk:4;
uint64_t fset:3;
uint64_t reserved_10_10:1;
uint64_t fadr:10;
} cn52xx;
struct cvmx_l2d_fadr_cn52xx cn52xxp1;
struct cvmx_l2d_fadr_s cn56xx;
struct cvmx_l2d_fadr_s cn56xxp1;
struct cvmx_l2d_fadr_s cn58xx;
struct cvmx_l2d_fadr_s cn58xxp1;
};
union cvmx_l2d_fsyn0 {
uint64_t u64;
struct cvmx_l2d_fsyn0_s {
uint64_t reserved_20_63:44;
uint64_t fsyn_ow1:10;
uint64_t fsyn_ow0:10;
} s;
struct cvmx_l2d_fsyn0_s cn30xx;
struct cvmx_l2d_fsyn0_s cn31xx;
struct cvmx_l2d_fsyn0_s cn38xx;
struct cvmx_l2d_fsyn0_s cn38xxp2;
struct cvmx_l2d_fsyn0_s cn50xx;
struct cvmx_l2d_fsyn0_s cn52xx;
struct cvmx_l2d_fsyn0_s cn52xxp1;
struct cvmx_l2d_fsyn0_s cn56xx;
struct cvmx_l2d_fsyn0_s cn56xxp1;
struct cvmx_l2d_fsyn0_s cn58xx;
struct cvmx_l2d_fsyn0_s cn58xxp1;
};
union cvmx_l2d_fsyn1 {
uint64_t u64;
struct cvmx_l2d_fsyn1_s {
uint64_t reserved_20_63:44;
uint64_t fsyn_ow3:10;
uint64_t fsyn_ow2:10;
} s;
struct cvmx_l2d_fsyn1_s cn30xx;
struct cvmx_l2d_fsyn1_s cn31xx;
struct cvmx_l2d_fsyn1_s cn38xx;
struct cvmx_l2d_fsyn1_s cn38xxp2;
struct cvmx_l2d_fsyn1_s cn50xx;
struct cvmx_l2d_fsyn1_s cn52xx;
struct cvmx_l2d_fsyn1_s cn52xxp1;
struct cvmx_l2d_fsyn1_s cn56xx;
struct cvmx_l2d_fsyn1_s cn56xxp1;
struct cvmx_l2d_fsyn1_s cn58xx;
struct cvmx_l2d_fsyn1_s cn58xxp1;
};
union cvmx_l2d_fus0 {
uint64_t u64;
struct cvmx_l2d_fus0_s {
uint64_t reserved_34_63:30;
uint64_t q0fus:34;
} s;
struct cvmx_l2d_fus0_s cn30xx;
struct cvmx_l2d_fus0_s cn31xx;
struct cvmx_l2d_fus0_s cn38xx;
struct cvmx_l2d_fus0_s cn38xxp2;
struct cvmx_l2d_fus0_s cn50xx;
struct cvmx_l2d_fus0_s cn52xx;
struct cvmx_l2d_fus0_s cn52xxp1;
struct cvmx_l2d_fus0_s cn56xx;
struct cvmx_l2d_fus0_s cn56xxp1;
struct cvmx_l2d_fus0_s cn58xx;
struct cvmx_l2d_fus0_s cn58xxp1;
};
union cvmx_l2d_fus1 {
uint64_t u64;
struct cvmx_l2d_fus1_s {
uint64_t reserved_34_63:30;
uint64_t q1fus:34;
} s;
struct cvmx_l2d_fus1_s cn30xx;
struct cvmx_l2d_fus1_s cn31xx;
struct cvmx_l2d_fus1_s cn38xx;
struct cvmx_l2d_fus1_s cn38xxp2;
struct cvmx_l2d_fus1_s cn50xx;
struct cvmx_l2d_fus1_s cn52xx;
struct cvmx_l2d_fus1_s cn52xxp1;
struct cvmx_l2d_fus1_s cn56xx;
struct cvmx_l2d_fus1_s cn56xxp1;
struct cvmx_l2d_fus1_s cn58xx;
struct cvmx_l2d_fus1_s cn58xxp1;
};
union cvmx_l2d_fus2 {
uint64_t u64;
struct cvmx_l2d_fus2_s {
uint64_t reserved_34_63:30;
uint64_t q2fus:34;
} s;
struct cvmx_l2d_fus2_s cn30xx;
struct cvmx_l2d_fus2_s cn31xx;
struct cvmx_l2d_fus2_s cn38xx;
struct cvmx_l2d_fus2_s cn38xxp2;
struct cvmx_l2d_fus2_s cn50xx;
struct cvmx_l2d_fus2_s cn52xx;
struct cvmx_l2d_fus2_s cn52xxp1;
struct cvmx_l2d_fus2_s cn56xx;
struct cvmx_l2d_fus2_s cn56xxp1;
struct cvmx_l2d_fus2_s cn58xx;
struct cvmx_l2d_fus2_s cn58xxp1;
};
union cvmx_l2d_fus3 {
uint64_t u64;
struct cvmx_l2d_fus3_s {
uint64_t reserved_40_63:24;
uint64_t ema_ctl:3;
uint64_t reserved_34_36:3;
uint64_t q3fus:34;
} s;
struct cvmx_l2d_fus3_cn30xx {
uint64_t reserved_35_63:29;
uint64_t crip_64k:1;
uint64_t q3fus:34;
} cn30xx;
struct cvmx_l2d_fus3_cn31xx {
uint64_t reserved_35_63:29;
uint64_t crip_128k:1;
uint64_t q3fus:34;
} cn31xx;
struct cvmx_l2d_fus3_cn38xx {
uint64_t reserved_36_63:28;
uint64_t crip_256k:1;
uint64_t crip_512k:1;
uint64_t q3fus:34;
} cn38xx;
struct cvmx_l2d_fus3_cn38xx cn38xxp2;
struct cvmx_l2d_fus3_cn50xx {
uint64_t reserved_40_63:24;
uint64_t ema_ctl:3;
uint64_t reserved_36_36:1;
uint64_t crip_32k:1;
uint64_t crip_64k:1;
uint64_t q3fus:34;
} cn50xx;
struct cvmx_l2d_fus3_cn52xx {
uint64_t reserved_40_63:24;
uint64_t ema_ctl:3;
uint64_t reserved_36_36:1;
uint64_t crip_128k:1;
uint64_t crip_256k:1;
uint64_t q3fus:34;
} cn52xx;
struct cvmx_l2d_fus3_cn52xx cn52xxp1;
struct cvmx_l2d_fus3_cn56xx {
uint64_t reserved_40_63:24;
uint64_t ema_ctl:3;
uint64_t reserved_36_36:1;
uint64_t crip_512k:1;
uint64_t crip_1024k:1;
uint64_t q3fus:34;
} cn56xx;
struct cvmx_l2d_fus3_cn56xx cn56xxp1;
struct cvmx_l2d_fus3_cn58xx {
uint64_t reserved_39_63:25;
uint64_t ema_ctl:2;
uint64_t reserved_36_36:1;
uint64_t crip_512k:1;
uint64_t crip_1024k:1;
uint64_t q3fus:34;
} cn58xx;
struct cvmx_l2d_fus3_cn58xx cn58xxp1;
};
#endif

View file

@ -0,0 +1,141 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_L2T_DEFS_H__
#define __CVMX_L2T_DEFS_H__
#define CVMX_L2T_ERR \
CVMX_ADD_IO_SEG(0x0001180080000008ull)
union cvmx_l2t_err {
uint64_t u64;
struct cvmx_l2t_err_s {
uint64_t reserved_29_63:35;
uint64_t fadru:1;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
uint64_t lck_intena:1;
uint64_t lckerr:1;
uint64_t fset:3;
uint64_t fadr:10;
uint64_t fsyn:6;
uint64_t ded_err:1;
uint64_t sec_err:1;
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
} s;
struct cvmx_l2t_err_cn30xx {
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
uint64_t lck_intena:1;
uint64_t lckerr:1;
uint64_t reserved_23_23:1;
uint64_t fset:2;
uint64_t reserved_19_20:2;
uint64_t fadr:8;
uint64_t fsyn:6;
uint64_t ded_err:1;
uint64_t sec_err:1;
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
} cn30xx;
struct cvmx_l2t_err_cn31xx {
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
uint64_t lck_intena:1;
uint64_t lckerr:1;
uint64_t reserved_23_23:1;
uint64_t fset:2;
uint64_t reserved_20_20:1;
uint64_t fadr:9;
uint64_t fsyn:6;
uint64_t ded_err:1;
uint64_t sec_err:1;
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
} cn31xx;
struct cvmx_l2t_err_cn38xx {
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
uint64_t lck_intena:1;
uint64_t lckerr:1;
uint64_t fset:3;
uint64_t fadr:10;
uint64_t fsyn:6;
uint64_t ded_err:1;
uint64_t sec_err:1;
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
} cn38xx;
struct cvmx_l2t_err_cn38xx cn38xxp2;
struct cvmx_l2t_err_cn50xx {
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
uint64_t lck_intena:1;
uint64_t lckerr:1;
uint64_t fset:3;
uint64_t reserved_18_20:3;
uint64_t fadr:7;
uint64_t fsyn:6;
uint64_t ded_err:1;
uint64_t sec_err:1;
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
} cn50xx;
struct cvmx_l2t_err_cn52xx {
uint64_t reserved_28_63:36;
uint64_t lck_intena2:1;
uint64_t lckerr2:1;
uint64_t lck_intena:1;
uint64_t lckerr:1;
uint64_t fset:3;
uint64_t reserved_20_20:1;
uint64_t fadr:9;
uint64_t fsyn:6;
uint64_t ded_err:1;
uint64_t sec_err:1;
uint64_t ded_intena:1;
uint64_t sec_intena:1;
uint64_t ecc_ena:1;
} cn52xx;
struct cvmx_l2t_err_cn52xx cn52xxp1;
struct cvmx_l2t_err_s cn56xx;
struct cvmx_l2t_err_s cn56xxp1;
struct cvmx_l2t_err_s cn58xx;
struct cvmx_l2t_err_s cn58xxp1;
};
#endif

View file

@ -0,0 +1,240 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_LED_DEFS_H__
#define __CVMX_LED_DEFS_H__
#define CVMX_LED_BLINK \
CVMX_ADD_IO_SEG(0x0001180000001A48ull)
#define CVMX_LED_CLK_PHASE \
CVMX_ADD_IO_SEG(0x0001180000001A08ull)
#define CVMX_LED_CYLON \
CVMX_ADD_IO_SEG(0x0001180000001AF8ull)
#define CVMX_LED_DBG \
CVMX_ADD_IO_SEG(0x0001180000001A18ull)
#define CVMX_LED_EN \
CVMX_ADD_IO_SEG(0x0001180000001A00ull)
#define CVMX_LED_POLARITY \
CVMX_ADD_IO_SEG(0x0001180000001A50ull)
#define CVMX_LED_PRT \
CVMX_ADD_IO_SEG(0x0001180000001A10ull)
#define CVMX_LED_PRT_FMT \
CVMX_ADD_IO_SEG(0x0001180000001A30ull)
#define CVMX_LED_PRT_STATUSX(offset) \
CVMX_ADD_IO_SEG(0x0001180000001A80ull + (((offset) & 7) * 8))
#define CVMX_LED_UDD_CNTX(offset) \
CVMX_ADD_IO_SEG(0x0001180000001A20ull + (((offset) & 1) * 8))
#define CVMX_LED_UDD_DATX(offset) \
CVMX_ADD_IO_SEG(0x0001180000001A38ull + (((offset) & 1) * 8))
#define CVMX_LED_UDD_DAT_CLRX(offset) \
CVMX_ADD_IO_SEG(0x0001180000001AC8ull + (((offset) & 1) * 16))
#define CVMX_LED_UDD_DAT_SETX(offset) \
CVMX_ADD_IO_SEG(0x0001180000001AC0ull + (((offset) & 1) * 16))
union cvmx_led_blink {
uint64_t u64;
struct cvmx_led_blink_s {
uint64_t reserved_8_63:56;
uint64_t rate:8;
} s;
struct cvmx_led_blink_s cn38xx;
struct cvmx_led_blink_s cn38xxp2;
struct cvmx_led_blink_s cn56xx;
struct cvmx_led_blink_s cn56xxp1;
struct cvmx_led_blink_s cn58xx;
struct cvmx_led_blink_s cn58xxp1;
};
union cvmx_led_clk_phase {
uint64_t u64;
struct cvmx_led_clk_phase_s {
uint64_t reserved_7_63:57;
uint64_t phase:7;
} s;
struct cvmx_led_clk_phase_s cn38xx;
struct cvmx_led_clk_phase_s cn38xxp2;
struct cvmx_led_clk_phase_s cn56xx;
struct cvmx_led_clk_phase_s cn56xxp1;
struct cvmx_led_clk_phase_s cn58xx;
struct cvmx_led_clk_phase_s cn58xxp1;
};
union cvmx_led_cylon {
uint64_t u64;
struct cvmx_led_cylon_s {
uint64_t reserved_16_63:48;
uint64_t rate:16;
} s;
struct cvmx_led_cylon_s cn38xx;
struct cvmx_led_cylon_s cn38xxp2;
struct cvmx_led_cylon_s cn56xx;
struct cvmx_led_cylon_s cn56xxp1;
struct cvmx_led_cylon_s cn58xx;
struct cvmx_led_cylon_s cn58xxp1;
};
union cvmx_led_dbg {
uint64_t u64;
struct cvmx_led_dbg_s {
uint64_t reserved_1_63:63;
uint64_t dbg_en:1;
} s;
struct cvmx_led_dbg_s cn38xx;
struct cvmx_led_dbg_s cn38xxp2;
struct cvmx_led_dbg_s cn56xx;
struct cvmx_led_dbg_s cn56xxp1;
struct cvmx_led_dbg_s cn58xx;
struct cvmx_led_dbg_s cn58xxp1;
};
union cvmx_led_en {
uint64_t u64;
struct cvmx_led_en_s {
uint64_t reserved_1_63:63;
uint64_t en:1;
} s;
struct cvmx_led_en_s cn38xx;
struct cvmx_led_en_s cn38xxp2;
struct cvmx_led_en_s cn56xx;
struct cvmx_led_en_s cn56xxp1;
struct cvmx_led_en_s cn58xx;
struct cvmx_led_en_s cn58xxp1;
};
union cvmx_led_polarity {
uint64_t u64;
struct cvmx_led_polarity_s {
uint64_t reserved_1_63:63;
uint64_t polarity:1;
} s;
struct cvmx_led_polarity_s cn38xx;
struct cvmx_led_polarity_s cn38xxp2;
struct cvmx_led_polarity_s cn56xx;
struct cvmx_led_polarity_s cn56xxp1;
struct cvmx_led_polarity_s cn58xx;
struct cvmx_led_polarity_s cn58xxp1;
};
union cvmx_led_prt {
uint64_t u64;
struct cvmx_led_prt_s {
uint64_t reserved_8_63:56;
uint64_t prt_en:8;
} s;
struct cvmx_led_prt_s cn38xx;
struct cvmx_led_prt_s cn38xxp2;
struct cvmx_led_prt_s cn56xx;
struct cvmx_led_prt_s cn56xxp1;
struct cvmx_led_prt_s cn58xx;
struct cvmx_led_prt_s cn58xxp1;
};
union cvmx_led_prt_fmt {
uint64_t u64;
struct cvmx_led_prt_fmt_s {
uint64_t reserved_4_63:60;
uint64_t format:4;
} s;
struct cvmx_led_prt_fmt_s cn38xx;
struct cvmx_led_prt_fmt_s cn38xxp2;
struct cvmx_led_prt_fmt_s cn56xx;
struct cvmx_led_prt_fmt_s cn56xxp1;
struct cvmx_led_prt_fmt_s cn58xx;
struct cvmx_led_prt_fmt_s cn58xxp1;
};
union cvmx_led_prt_statusx {
uint64_t u64;
struct cvmx_led_prt_statusx_s {
uint64_t reserved_6_63:58;
uint64_t status:6;
} s;
struct cvmx_led_prt_statusx_s cn38xx;
struct cvmx_led_prt_statusx_s cn38xxp2;
struct cvmx_led_prt_statusx_s cn56xx;
struct cvmx_led_prt_statusx_s cn56xxp1;
struct cvmx_led_prt_statusx_s cn58xx;
struct cvmx_led_prt_statusx_s cn58xxp1;
};
union cvmx_led_udd_cntx {
uint64_t u64;
struct cvmx_led_udd_cntx_s {
uint64_t reserved_6_63:58;
uint64_t cnt:6;
} s;
struct cvmx_led_udd_cntx_s cn38xx;
struct cvmx_led_udd_cntx_s cn38xxp2;
struct cvmx_led_udd_cntx_s cn56xx;
struct cvmx_led_udd_cntx_s cn56xxp1;
struct cvmx_led_udd_cntx_s cn58xx;
struct cvmx_led_udd_cntx_s cn58xxp1;
};
union cvmx_led_udd_datx {
uint64_t u64;
struct cvmx_led_udd_datx_s {
uint64_t reserved_32_63:32;
uint64_t dat:32;
} s;
struct cvmx_led_udd_datx_s cn38xx;
struct cvmx_led_udd_datx_s cn38xxp2;
struct cvmx_led_udd_datx_s cn56xx;
struct cvmx_led_udd_datx_s cn56xxp1;
struct cvmx_led_udd_datx_s cn58xx;
struct cvmx_led_udd_datx_s cn58xxp1;
};
union cvmx_led_udd_dat_clrx {
uint64_t u64;
struct cvmx_led_udd_dat_clrx_s {
uint64_t reserved_32_63:32;
uint64_t clr:32;
} s;
struct cvmx_led_udd_dat_clrx_s cn38xx;
struct cvmx_led_udd_dat_clrx_s cn38xxp2;
struct cvmx_led_udd_dat_clrx_s cn56xx;
struct cvmx_led_udd_dat_clrx_s cn56xxp1;
struct cvmx_led_udd_dat_clrx_s cn58xx;
struct cvmx_led_udd_dat_clrx_s cn58xxp1;
};
union cvmx_led_udd_dat_setx {
uint64_t u64;
struct cvmx_led_udd_dat_setx_s {
uint64_t reserved_32_63:32;
uint64_t set:32;
} s;
struct cvmx_led_udd_dat_setx_s cn38xx;
struct cvmx_led_udd_dat_setx_s cn38xxp2;
struct cvmx_led_udd_dat_setx_s cn56xx;
struct cvmx_led_udd_dat_setx_s cn56xxp1;
struct cvmx_led_udd_dat_setx_s cn58xx;
struct cvmx_led_udd_dat_setx_s cn58xxp1;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,61 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* Packet buffer defines.
*/
#ifndef __CVMX_PACKET_H__
#define __CVMX_PACKET_H__
/**
* This structure defines a buffer pointer on Octeon
*/
union cvmx_buf_ptr {
void *ptr;
uint64_t u64;
struct {
/* if set, invert the "free" pick of the overall
* packet. HW always sets this bit to 0 on inbound
* packet */
uint64_t i:1;
/* Indicates the amount to back up to get to the
* buffer start in cache lines. In most cases this is
* less than one complete cache line, so the value is
* zero */
uint64_t back:4;
/* The pool that the buffer came from / goes to */
uint64_t pool:3;
/* The size of the segment pointed to by addr (in bytes) */
uint64_t size:16;
/* Pointer to the first byte of the data, NOT buffer */
uint64_t addr:40;
} s;
};
#endif /* __CVMX_PACKET_H__ */

View file

@ -0,0 +1,698 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_POW_DEFS_H__
#define __CVMX_POW_DEFS_H__
#define CVMX_POW_BIST_STAT \
CVMX_ADD_IO_SEG(0x00016700000003F8ull)
#define CVMX_POW_DS_PC \
CVMX_ADD_IO_SEG(0x0001670000000398ull)
#define CVMX_POW_ECC_ERR \
CVMX_ADD_IO_SEG(0x0001670000000218ull)
#define CVMX_POW_INT_CTL \
CVMX_ADD_IO_SEG(0x0001670000000220ull)
#define CVMX_POW_IQ_CNTX(offset) \
CVMX_ADD_IO_SEG(0x0001670000000340ull + (((offset) & 7) * 8))
#define CVMX_POW_IQ_COM_CNT \
CVMX_ADD_IO_SEG(0x0001670000000388ull)
#define CVMX_POW_IQ_INT \
CVMX_ADD_IO_SEG(0x0001670000000238ull)
#define CVMX_POW_IQ_INT_EN \
CVMX_ADD_IO_SEG(0x0001670000000240ull)
#define CVMX_POW_IQ_THRX(offset) \
CVMX_ADD_IO_SEG(0x00016700000003A0ull + (((offset) & 7) * 8))
#define CVMX_POW_NOS_CNT \
CVMX_ADD_IO_SEG(0x0001670000000228ull)
#define CVMX_POW_NW_TIM \
CVMX_ADD_IO_SEG(0x0001670000000210ull)
#define CVMX_POW_PF_RST_MSK \
CVMX_ADD_IO_SEG(0x0001670000000230ull)
#define CVMX_POW_PP_GRP_MSKX(offset) \
CVMX_ADD_IO_SEG(0x0001670000000000ull + (((offset) & 15) * 8))
#define CVMX_POW_QOS_RNDX(offset) \
CVMX_ADD_IO_SEG(0x00016700000001C0ull + (((offset) & 7) * 8))
#define CVMX_POW_QOS_THRX(offset) \
CVMX_ADD_IO_SEG(0x0001670000000180ull + (((offset) & 7) * 8))
#define CVMX_POW_TS_PC \
CVMX_ADD_IO_SEG(0x0001670000000390ull)
#define CVMX_POW_WA_COM_PC \
CVMX_ADD_IO_SEG(0x0001670000000380ull)
#define CVMX_POW_WA_PCX(offset) \
CVMX_ADD_IO_SEG(0x0001670000000300ull + (((offset) & 7) * 8))
#define CVMX_POW_WQ_INT \
CVMX_ADD_IO_SEG(0x0001670000000200ull)
#define CVMX_POW_WQ_INT_CNTX(offset) \
CVMX_ADD_IO_SEG(0x0001670000000100ull + (((offset) & 15) * 8))
#define CVMX_POW_WQ_INT_PC \
CVMX_ADD_IO_SEG(0x0001670000000208ull)
#define CVMX_POW_WQ_INT_THRX(offset) \
CVMX_ADD_IO_SEG(0x0001670000000080ull + (((offset) & 15) * 8))
#define CVMX_POW_WS_PCX(offset) \
CVMX_ADD_IO_SEG(0x0001670000000280ull + (((offset) & 15) * 8))
union cvmx_pow_bist_stat {
uint64_t u64;
struct cvmx_pow_bist_stat_s {
uint64_t reserved_32_63:32;
uint64_t pp:16;
uint64_t reserved_0_15:16;
} s;
struct cvmx_pow_bist_stat_cn30xx {
uint64_t reserved_17_63:47;
uint64_t pp:1;
uint64_t reserved_9_15:7;
uint64_t cam:1;
uint64_t nbt1:1;
uint64_t nbt0:1;
uint64_t index:1;
uint64_t fidx:1;
uint64_t nbr1:1;
uint64_t nbr0:1;
uint64_t pend:1;
uint64_t adr:1;
} cn30xx;
struct cvmx_pow_bist_stat_cn31xx {
uint64_t reserved_18_63:46;
uint64_t pp:2;
uint64_t reserved_9_15:7;
uint64_t cam:1;
uint64_t nbt1:1;
uint64_t nbt0:1;
uint64_t index:1;
uint64_t fidx:1;
uint64_t nbr1:1;
uint64_t nbr0:1;
uint64_t pend:1;
uint64_t adr:1;
} cn31xx;
struct cvmx_pow_bist_stat_cn38xx {
uint64_t reserved_32_63:32;
uint64_t pp:16;
uint64_t reserved_10_15:6;
uint64_t cam:1;
uint64_t nbt:1;
uint64_t index:1;
uint64_t fidx:1;
uint64_t nbr1:1;
uint64_t nbr0:1;
uint64_t pend1:1;
uint64_t pend0:1;
uint64_t adr1:1;
uint64_t adr0:1;
} cn38xx;
struct cvmx_pow_bist_stat_cn38xx cn38xxp2;
struct cvmx_pow_bist_stat_cn31xx cn50xx;
struct cvmx_pow_bist_stat_cn52xx {
uint64_t reserved_20_63:44;
uint64_t pp:4;
uint64_t reserved_9_15:7;
uint64_t cam:1;
uint64_t nbt1:1;
uint64_t nbt0:1;
uint64_t index:1;
uint64_t fidx:1;
uint64_t nbr1:1;
uint64_t nbr0:1;
uint64_t pend:1;
uint64_t adr:1;
} cn52xx;
struct cvmx_pow_bist_stat_cn52xx cn52xxp1;
struct cvmx_pow_bist_stat_cn56xx {
uint64_t reserved_28_63:36;
uint64_t pp:12;
uint64_t reserved_10_15:6;
uint64_t cam:1;
uint64_t nbt:1;
uint64_t index:1;
uint64_t fidx:1;
uint64_t nbr1:1;
uint64_t nbr0:1;
uint64_t pend1:1;
uint64_t pend0:1;
uint64_t adr1:1;
uint64_t adr0:1;
} cn56xx;
struct cvmx_pow_bist_stat_cn56xx cn56xxp1;
struct cvmx_pow_bist_stat_cn38xx cn58xx;
struct cvmx_pow_bist_stat_cn38xx cn58xxp1;
};
union cvmx_pow_ds_pc {
uint64_t u64;
struct cvmx_pow_ds_pc_s {
uint64_t reserved_32_63:32;
uint64_t ds_pc:32;
} s;
struct cvmx_pow_ds_pc_s cn30xx;
struct cvmx_pow_ds_pc_s cn31xx;
struct cvmx_pow_ds_pc_s cn38xx;
struct cvmx_pow_ds_pc_s cn38xxp2;
struct cvmx_pow_ds_pc_s cn50xx;
struct cvmx_pow_ds_pc_s cn52xx;
struct cvmx_pow_ds_pc_s cn52xxp1;
struct cvmx_pow_ds_pc_s cn56xx;
struct cvmx_pow_ds_pc_s cn56xxp1;
struct cvmx_pow_ds_pc_s cn58xx;
struct cvmx_pow_ds_pc_s cn58xxp1;
};
union cvmx_pow_ecc_err {
uint64_t u64;
struct cvmx_pow_ecc_err_s {
uint64_t reserved_45_63:19;
uint64_t iop_ie:13;
uint64_t reserved_29_31:3;
uint64_t iop:13;
uint64_t reserved_14_15:2;
uint64_t rpe_ie:1;
uint64_t rpe:1;
uint64_t reserved_9_11:3;
uint64_t syn:5;
uint64_t dbe_ie:1;
uint64_t sbe_ie:1;
uint64_t dbe:1;
uint64_t sbe:1;
} s;
struct cvmx_pow_ecc_err_s cn30xx;
struct cvmx_pow_ecc_err_cn31xx {
uint64_t reserved_14_63:50;
uint64_t rpe_ie:1;
uint64_t rpe:1;
uint64_t reserved_9_11:3;
uint64_t syn:5;
uint64_t dbe_ie:1;
uint64_t sbe_ie:1;
uint64_t dbe:1;
uint64_t sbe:1;
} cn31xx;
struct cvmx_pow_ecc_err_s cn38xx;
struct cvmx_pow_ecc_err_cn31xx cn38xxp2;
struct cvmx_pow_ecc_err_s cn50xx;
struct cvmx_pow_ecc_err_s cn52xx;
struct cvmx_pow_ecc_err_s cn52xxp1;
struct cvmx_pow_ecc_err_s cn56xx;
struct cvmx_pow_ecc_err_s cn56xxp1;
struct cvmx_pow_ecc_err_s cn58xx;
struct cvmx_pow_ecc_err_s cn58xxp1;
};
union cvmx_pow_int_ctl {
uint64_t u64;
struct cvmx_pow_int_ctl_s {
uint64_t reserved_6_63:58;
uint64_t pfr_dis:1;
uint64_t nbr_thr:5;
} s;
struct cvmx_pow_int_ctl_s cn30xx;
struct cvmx_pow_int_ctl_s cn31xx;
struct cvmx_pow_int_ctl_s cn38xx;
struct cvmx_pow_int_ctl_s cn38xxp2;
struct cvmx_pow_int_ctl_s cn50xx;
struct cvmx_pow_int_ctl_s cn52xx;
struct cvmx_pow_int_ctl_s cn52xxp1;
struct cvmx_pow_int_ctl_s cn56xx;
struct cvmx_pow_int_ctl_s cn56xxp1;
struct cvmx_pow_int_ctl_s cn58xx;
struct cvmx_pow_int_ctl_s cn58xxp1;
};
union cvmx_pow_iq_cntx {
uint64_t u64;
struct cvmx_pow_iq_cntx_s {
uint64_t reserved_32_63:32;
uint64_t iq_cnt:32;
} s;
struct cvmx_pow_iq_cntx_s cn30xx;
struct cvmx_pow_iq_cntx_s cn31xx;
struct cvmx_pow_iq_cntx_s cn38xx;
struct cvmx_pow_iq_cntx_s cn38xxp2;
struct cvmx_pow_iq_cntx_s cn50xx;
struct cvmx_pow_iq_cntx_s cn52xx;
struct cvmx_pow_iq_cntx_s cn52xxp1;
struct cvmx_pow_iq_cntx_s cn56xx;
struct cvmx_pow_iq_cntx_s cn56xxp1;
struct cvmx_pow_iq_cntx_s cn58xx;
struct cvmx_pow_iq_cntx_s cn58xxp1;
};
union cvmx_pow_iq_com_cnt {
uint64_t u64;
struct cvmx_pow_iq_com_cnt_s {
uint64_t reserved_32_63:32;
uint64_t iq_cnt:32;
} s;
struct cvmx_pow_iq_com_cnt_s cn30xx;
struct cvmx_pow_iq_com_cnt_s cn31xx;
struct cvmx_pow_iq_com_cnt_s cn38xx;
struct cvmx_pow_iq_com_cnt_s cn38xxp2;
struct cvmx_pow_iq_com_cnt_s cn50xx;
struct cvmx_pow_iq_com_cnt_s cn52xx;
struct cvmx_pow_iq_com_cnt_s cn52xxp1;
struct cvmx_pow_iq_com_cnt_s cn56xx;
struct cvmx_pow_iq_com_cnt_s cn56xxp1;
struct cvmx_pow_iq_com_cnt_s cn58xx;
struct cvmx_pow_iq_com_cnt_s cn58xxp1;
};
union cvmx_pow_iq_int {
uint64_t u64;
struct cvmx_pow_iq_int_s {
uint64_t reserved_8_63:56;
uint64_t iq_int:8;
} s;
struct cvmx_pow_iq_int_s cn52xx;
struct cvmx_pow_iq_int_s cn52xxp1;
struct cvmx_pow_iq_int_s cn56xx;
struct cvmx_pow_iq_int_s cn56xxp1;
};
union cvmx_pow_iq_int_en {
uint64_t u64;
struct cvmx_pow_iq_int_en_s {
uint64_t reserved_8_63:56;
uint64_t int_en:8;
} s;
struct cvmx_pow_iq_int_en_s cn52xx;
struct cvmx_pow_iq_int_en_s cn52xxp1;
struct cvmx_pow_iq_int_en_s cn56xx;
struct cvmx_pow_iq_int_en_s cn56xxp1;
};
union cvmx_pow_iq_thrx {
uint64_t u64;
struct cvmx_pow_iq_thrx_s {
uint64_t reserved_32_63:32;
uint64_t iq_thr:32;
} s;
struct cvmx_pow_iq_thrx_s cn52xx;
struct cvmx_pow_iq_thrx_s cn52xxp1;
struct cvmx_pow_iq_thrx_s cn56xx;
struct cvmx_pow_iq_thrx_s cn56xxp1;
};
union cvmx_pow_nos_cnt {
uint64_t u64;
struct cvmx_pow_nos_cnt_s {
uint64_t reserved_12_63:52;
uint64_t nos_cnt:12;
} s;
struct cvmx_pow_nos_cnt_cn30xx {
uint64_t reserved_7_63:57;
uint64_t nos_cnt:7;
} cn30xx;
struct cvmx_pow_nos_cnt_cn31xx {
uint64_t reserved_9_63:55;
uint64_t nos_cnt:9;
} cn31xx;
struct cvmx_pow_nos_cnt_s cn38xx;
struct cvmx_pow_nos_cnt_s cn38xxp2;
struct cvmx_pow_nos_cnt_cn31xx cn50xx;
struct cvmx_pow_nos_cnt_cn52xx {
uint64_t reserved_10_63:54;
uint64_t nos_cnt:10;
} cn52xx;
struct cvmx_pow_nos_cnt_cn52xx cn52xxp1;
struct cvmx_pow_nos_cnt_s cn56xx;
struct cvmx_pow_nos_cnt_s cn56xxp1;
struct cvmx_pow_nos_cnt_s cn58xx;
struct cvmx_pow_nos_cnt_s cn58xxp1;
};
union cvmx_pow_nw_tim {
uint64_t u64;
struct cvmx_pow_nw_tim_s {
uint64_t reserved_10_63:54;
uint64_t nw_tim:10;
} s;
struct cvmx_pow_nw_tim_s cn30xx;
struct cvmx_pow_nw_tim_s cn31xx;
struct cvmx_pow_nw_tim_s cn38xx;
struct cvmx_pow_nw_tim_s cn38xxp2;
struct cvmx_pow_nw_tim_s cn50xx;
struct cvmx_pow_nw_tim_s cn52xx;
struct cvmx_pow_nw_tim_s cn52xxp1;
struct cvmx_pow_nw_tim_s cn56xx;
struct cvmx_pow_nw_tim_s cn56xxp1;
struct cvmx_pow_nw_tim_s cn58xx;
struct cvmx_pow_nw_tim_s cn58xxp1;
};
union cvmx_pow_pf_rst_msk {
uint64_t u64;
struct cvmx_pow_pf_rst_msk_s {
uint64_t reserved_8_63:56;
uint64_t rst_msk:8;
} s;
struct cvmx_pow_pf_rst_msk_s cn50xx;
struct cvmx_pow_pf_rst_msk_s cn52xx;
struct cvmx_pow_pf_rst_msk_s cn52xxp1;
struct cvmx_pow_pf_rst_msk_s cn56xx;
struct cvmx_pow_pf_rst_msk_s cn56xxp1;
struct cvmx_pow_pf_rst_msk_s cn58xx;
struct cvmx_pow_pf_rst_msk_s cn58xxp1;
};
union cvmx_pow_pp_grp_mskx {
uint64_t u64;
struct cvmx_pow_pp_grp_mskx_s {
uint64_t reserved_48_63:16;
uint64_t qos7_pri:4;
uint64_t qos6_pri:4;
uint64_t qos5_pri:4;
uint64_t qos4_pri:4;
uint64_t qos3_pri:4;
uint64_t qos2_pri:4;
uint64_t qos1_pri:4;
uint64_t qos0_pri:4;
uint64_t grp_msk:16;
} s;
struct cvmx_pow_pp_grp_mskx_cn30xx {
uint64_t reserved_16_63:48;
uint64_t grp_msk:16;
} cn30xx;
struct cvmx_pow_pp_grp_mskx_cn30xx cn31xx;
struct cvmx_pow_pp_grp_mskx_cn30xx cn38xx;
struct cvmx_pow_pp_grp_mskx_cn30xx cn38xxp2;
struct cvmx_pow_pp_grp_mskx_s cn50xx;
struct cvmx_pow_pp_grp_mskx_s cn52xx;
struct cvmx_pow_pp_grp_mskx_s cn52xxp1;
struct cvmx_pow_pp_grp_mskx_s cn56xx;
struct cvmx_pow_pp_grp_mskx_s cn56xxp1;
struct cvmx_pow_pp_grp_mskx_s cn58xx;
struct cvmx_pow_pp_grp_mskx_s cn58xxp1;
};
union cvmx_pow_qos_rndx {
uint64_t u64;
struct cvmx_pow_qos_rndx_s {
uint64_t reserved_32_63:32;
uint64_t rnd_p3:8;
uint64_t rnd_p2:8;
uint64_t rnd_p1:8;
uint64_t rnd:8;
} s;
struct cvmx_pow_qos_rndx_s cn30xx;
struct cvmx_pow_qos_rndx_s cn31xx;
struct cvmx_pow_qos_rndx_s cn38xx;
struct cvmx_pow_qos_rndx_s cn38xxp2;
struct cvmx_pow_qos_rndx_s cn50xx;
struct cvmx_pow_qos_rndx_s cn52xx;
struct cvmx_pow_qos_rndx_s cn52xxp1;
struct cvmx_pow_qos_rndx_s cn56xx;
struct cvmx_pow_qos_rndx_s cn56xxp1;
struct cvmx_pow_qos_rndx_s cn58xx;
struct cvmx_pow_qos_rndx_s cn58xxp1;
};
union cvmx_pow_qos_thrx {
uint64_t u64;
struct cvmx_pow_qos_thrx_s {
uint64_t reserved_60_63:4;
uint64_t des_cnt:12;
uint64_t buf_cnt:12;
uint64_t free_cnt:12;
uint64_t reserved_23_23:1;
uint64_t max_thr:11;
uint64_t reserved_11_11:1;
uint64_t min_thr:11;
} s;
struct cvmx_pow_qos_thrx_cn30xx {
uint64_t reserved_55_63:9;
uint64_t des_cnt:7;
uint64_t reserved_43_47:5;
uint64_t buf_cnt:7;
uint64_t reserved_31_35:5;
uint64_t free_cnt:7;
uint64_t reserved_18_23:6;
uint64_t max_thr:6;
uint64_t reserved_6_11:6;
uint64_t min_thr:6;
} cn30xx;
struct cvmx_pow_qos_thrx_cn31xx {
uint64_t reserved_57_63:7;
uint64_t des_cnt:9;
uint64_t reserved_45_47:3;
uint64_t buf_cnt:9;
uint64_t reserved_33_35:3;
uint64_t free_cnt:9;
uint64_t reserved_20_23:4;
uint64_t max_thr:8;
uint64_t reserved_8_11:4;
uint64_t min_thr:8;
} cn31xx;
struct cvmx_pow_qos_thrx_s cn38xx;
struct cvmx_pow_qos_thrx_s cn38xxp2;
struct cvmx_pow_qos_thrx_cn31xx cn50xx;
struct cvmx_pow_qos_thrx_cn52xx {
uint64_t reserved_58_63:6;
uint64_t des_cnt:10;
uint64_t reserved_46_47:2;
uint64_t buf_cnt:10;
uint64_t reserved_34_35:2;
uint64_t free_cnt:10;
uint64_t reserved_21_23:3;
uint64_t max_thr:9;
uint64_t reserved_9_11:3;
uint64_t min_thr:9;
} cn52xx;
struct cvmx_pow_qos_thrx_cn52xx cn52xxp1;
struct cvmx_pow_qos_thrx_s cn56xx;
struct cvmx_pow_qos_thrx_s cn56xxp1;
struct cvmx_pow_qos_thrx_s cn58xx;
struct cvmx_pow_qos_thrx_s cn58xxp1;
};
union cvmx_pow_ts_pc {
uint64_t u64;
struct cvmx_pow_ts_pc_s {
uint64_t reserved_32_63:32;
uint64_t ts_pc:32;
} s;
struct cvmx_pow_ts_pc_s cn30xx;
struct cvmx_pow_ts_pc_s cn31xx;
struct cvmx_pow_ts_pc_s cn38xx;
struct cvmx_pow_ts_pc_s cn38xxp2;
struct cvmx_pow_ts_pc_s cn50xx;
struct cvmx_pow_ts_pc_s cn52xx;
struct cvmx_pow_ts_pc_s cn52xxp1;
struct cvmx_pow_ts_pc_s cn56xx;
struct cvmx_pow_ts_pc_s cn56xxp1;
struct cvmx_pow_ts_pc_s cn58xx;
struct cvmx_pow_ts_pc_s cn58xxp1;
};
union cvmx_pow_wa_com_pc {
uint64_t u64;
struct cvmx_pow_wa_com_pc_s {
uint64_t reserved_32_63:32;
uint64_t wa_pc:32;
} s;
struct cvmx_pow_wa_com_pc_s cn30xx;
struct cvmx_pow_wa_com_pc_s cn31xx;
struct cvmx_pow_wa_com_pc_s cn38xx;
struct cvmx_pow_wa_com_pc_s cn38xxp2;
struct cvmx_pow_wa_com_pc_s cn50xx;
struct cvmx_pow_wa_com_pc_s cn52xx;
struct cvmx_pow_wa_com_pc_s cn52xxp1;
struct cvmx_pow_wa_com_pc_s cn56xx;
struct cvmx_pow_wa_com_pc_s cn56xxp1;
struct cvmx_pow_wa_com_pc_s cn58xx;
struct cvmx_pow_wa_com_pc_s cn58xxp1;
};
union cvmx_pow_wa_pcx {
uint64_t u64;
struct cvmx_pow_wa_pcx_s {
uint64_t reserved_32_63:32;
uint64_t wa_pc:32;
} s;
struct cvmx_pow_wa_pcx_s cn30xx;
struct cvmx_pow_wa_pcx_s cn31xx;
struct cvmx_pow_wa_pcx_s cn38xx;
struct cvmx_pow_wa_pcx_s cn38xxp2;
struct cvmx_pow_wa_pcx_s cn50xx;
struct cvmx_pow_wa_pcx_s cn52xx;
struct cvmx_pow_wa_pcx_s cn52xxp1;
struct cvmx_pow_wa_pcx_s cn56xx;
struct cvmx_pow_wa_pcx_s cn56xxp1;
struct cvmx_pow_wa_pcx_s cn58xx;
struct cvmx_pow_wa_pcx_s cn58xxp1;
};
union cvmx_pow_wq_int {
uint64_t u64;
struct cvmx_pow_wq_int_s {
uint64_t reserved_32_63:32;
uint64_t iq_dis:16;
uint64_t wq_int:16;
} s;
struct cvmx_pow_wq_int_s cn30xx;
struct cvmx_pow_wq_int_s cn31xx;
struct cvmx_pow_wq_int_s cn38xx;
struct cvmx_pow_wq_int_s cn38xxp2;
struct cvmx_pow_wq_int_s cn50xx;
struct cvmx_pow_wq_int_s cn52xx;
struct cvmx_pow_wq_int_s cn52xxp1;
struct cvmx_pow_wq_int_s cn56xx;
struct cvmx_pow_wq_int_s cn56xxp1;
struct cvmx_pow_wq_int_s cn58xx;
struct cvmx_pow_wq_int_s cn58xxp1;
};
union cvmx_pow_wq_int_cntx {
uint64_t u64;
struct cvmx_pow_wq_int_cntx_s {
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t ds_cnt:12;
uint64_t iq_cnt:12;
} s;
struct cvmx_pow_wq_int_cntx_cn30xx {
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t reserved_19_23:5;
uint64_t ds_cnt:7;
uint64_t reserved_7_11:5;
uint64_t iq_cnt:7;
} cn30xx;
struct cvmx_pow_wq_int_cntx_cn31xx {
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t reserved_21_23:3;
uint64_t ds_cnt:9;
uint64_t reserved_9_11:3;
uint64_t iq_cnt:9;
} cn31xx;
struct cvmx_pow_wq_int_cntx_s cn38xx;
struct cvmx_pow_wq_int_cntx_s cn38xxp2;
struct cvmx_pow_wq_int_cntx_cn31xx cn50xx;
struct cvmx_pow_wq_int_cntx_cn52xx {
uint64_t reserved_28_63:36;
uint64_t tc_cnt:4;
uint64_t reserved_22_23:2;
uint64_t ds_cnt:10;
uint64_t reserved_10_11:2;
uint64_t iq_cnt:10;
} cn52xx;
struct cvmx_pow_wq_int_cntx_cn52xx cn52xxp1;
struct cvmx_pow_wq_int_cntx_s cn56xx;
struct cvmx_pow_wq_int_cntx_s cn56xxp1;
struct cvmx_pow_wq_int_cntx_s cn58xx;
struct cvmx_pow_wq_int_cntx_s cn58xxp1;
};
union cvmx_pow_wq_int_pc {
uint64_t u64;
struct cvmx_pow_wq_int_pc_s {
uint64_t reserved_60_63:4;
uint64_t pc:28;
uint64_t reserved_28_31:4;
uint64_t pc_thr:20;
uint64_t reserved_0_7:8;
} s;
struct cvmx_pow_wq_int_pc_s cn30xx;
struct cvmx_pow_wq_int_pc_s cn31xx;
struct cvmx_pow_wq_int_pc_s cn38xx;
struct cvmx_pow_wq_int_pc_s cn38xxp2;
struct cvmx_pow_wq_int_pc_s cn50xx;
struct cvmx_pow_wq_int_pc_s cn52xx;
struct cvmx_pow_wq_int_pc_s cn52xxp1;
struct cvmx_pow_wq_int_pc_s cn56xx;
struct cvmx_pow_wq_int_pc_s cn56xxp1;
struct cvmx_pow_wq_int_pc_s cn58xx;
struct cvmx_pow_wq_int_pc_s cn58xxp1;
};
union cvmx_pow_wq_int_thrx {
uint64_t u64;
struct cvmx_pow_wq_int_thrx_s {
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
uint64_t reserved_23_23:1;
uint64_t ds_thr:11;
uint64_t reserved_11_11:1;
uint64_t iq_thr:11;
} s;
struct cvmx_pow_wq_int_thrx_cn30xx {
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
uint64_t reserved_18_23:6;
uint64_t ds_thr:6;
uint64_t reserved_6_11:6;
uint64_t iq_thr:6;
} cn30xx;
struct cvmx_pow_wq_int_thrx_cn31xx {
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
uint64_t reserved_20_23:4;
uint64_t ds_thr:8;
uint64_t reserved_8_11:4;
uint64_t iq_thr:8;
} cn31xx;
struct cvmx_pow_wq_int_thrx_s cn38xx;
struct cvmx_pow_wq_int_thrx_s cn38xxp2;
struct cvmx_pow_wq_int_thrx_cn31xx cn50xx;
struct cvmx_pow_wq_int_thrx_cn52xx {
uint64_t reserved_29_63:35;
uint64_t tc_en:1;
uint64_t tc_thr:4;
uint64_t reserved_21_23:3;
uint64_t ds_thr:9;
uint64_t reserved_9_11:3;
uint64_t iq_thr:9;
} cn52xx;
struct cvmx_pow_wq_int_thrx_cn52xx cn52xxp1;
struct cvmx_pow_wq_int_thrx_s cn56xx;
struct cvmx_pow_wq_int_thrx_s cn56xxp1;
struct cvmx_pow_wq_int_thrx_s cn58xx;
struct cvmx_pow_wq_int_thrx_s cn58xxp1;
};
union cvmx_pow_ws_pcx {
uint64_t u64;
struct cvmx_pow_ws_pcx_s {
uint64_t reserved_32_63:32;
uint64_t ws_pc:32;
} s;
struct cvmx_pow_ws_pcx_s cn30xx;
struct cvmx_pow_ws_pcx_s cn31xx;
struct cvmx_pow_ws_pcx_s cn38xx;
struct cvmx_pow_ws_pcx_s cn38xxp2;
struct cvmx_pow_ws_pcx_s cn50xx;
struct cvmx_pow_ws_pcx_s cn52xx;
struct cvmx_pow_ws_pcx_s cn52xxp1;
struct cvmx_pow_ws_pcx_s cn56xx;
struct cvmx_pow_ws_pcx_s cn56xxp1;
struct cvmx_pow_ws_pcx_s cn58xx;
struct cvmx_pow_ws_pcx_s cn58xxp1;
};
#endif

View file

@ -0,0 +1,232 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/**
* Implementation of spinlocks for Octeon CVMX. Although similar in
* function to Linux kernel spinlocks, they are not compatible.
* Octeon CVMX spinlocks are only used to synchronize with the boot
* monitor and other non-Linux programs running in the system.
*/
#ifndef __CVMX_SPINLOCK_H__
#define __CVMX_SPINLOCK_H__
#include "cvmx-asm.h"
/* Spinlocks for Octeon */
/* define these to enable recursive spinlock debugging */
/*#define CVMX_SPINLOCK_DEBUG */
/**
* Spinlocks for Octeon CVMX
*/
typedef struct {
volatile uint32_t value;
} cvmx_spinlock_t;
/* note - macros not expanded in inline ASM, so values hardcoded */
#define CVMX_SPINLOCK_UNLOCKED_VAL 0
#define CVMX_SPINLOCK_LOCKED_VAL 1
#define CVMX_SPINLOCK_UNLOCKED_INITIALIZER {CVMX_SPINLOCK_UNLOCKED_VAL}
/**
* Initialize a spinlock
*
* @lock: Lock to initialize
*/
static inline void cvmx_spinlock_init(cvmx_spinlock_t *lock)
{
lock->value = CVMX_SPINLOCK_UNLOCKED_VAL;
}
/**
* Return non-zero if the spinlock is currently locked
*
* @lock: Lock to check
* Returns Non-zero if locked
*/
static inline int cvmx_spinlock_locked(cvmx_spinlock_t *lock)
{
return lock->value != CVMX_SPINLOCK_UNLOCKED_VAL;
}
/**
* Releases lock
*
* @lock: pointer to lock structure
*/
static inline void cvmx_spinlock_unlock(cvmx_spinlock_t *lock)
{
CVMX_SYNCWS;
lock->value = 0;
CVMX_SYNCWS;
}
/**
* Attempts to take the lock, but does not spin if lock is not available.
* May take some time to acquire the lock even if it is available
* due to the ll/sc not succeeding.
*
* @lock: pointer to lock structure
*
* Returns 0: lock successfully taken
* 1: lock not taken, held by someone else
* These return values match the Linux semantics.
*/
static inline unsigned int cvmx_spinlock_trylock(cvmx_spinlock_t *lock)
{
unsigned int tmp;
__asm__ __volatile__(".set noreorder \n"
"1: ll %[tmp], %[val] \n"
/* if lock held, fail immediately */
" bnez %[tmp], 2f \n"
" li %[tmp], 1 \n"
" sc %[tmp], %[val] \n"
" beqz %[tmp], 1b \n"
" li %[tmp], 0 \n"
"2: \n"
".set reorder \n" :
[val] "+m"(lock->value), [tmp] "=&r"(tmp)
: : "memory");
return tmp != 0; /* normalize to 0 or 1 */
}
/**
* Gets lock, spins until lock is taken
*
* @lock: pointer to lock structure
*/
static inline void cvmx_spinlock_lock(cvmx_spinlock_t *lock)
{
unsigned int tmp;
__asm__ __volatile__(".set noreorder \n"
"1: ll %[tmp], %[val] \n"
" bnez %[tmp], 1b \n"
" li %[tmp], 1 \n"
" sc %[tmp], %[val] \n"
" beqz %[tmp], 1b \n"
" nop \n"
".set reorder \n" :
[val] "+m"(lock->value), [tmp] "=&r"(tmp)
: : "memory");
}
/** ********************************************************************
* Bit spinlocks
* These spinlocks use a single bit (bit 31) of a 32 bit word for locking.
* The rest of the bits in the word are left undisturbed. This enables more
* compact data structures as only 1 bit is consumed for the lock.
*
*/
/**
* Gets lock, spins until lock is taken
* Preserves the low 31 bits of the 32 bit
* word used for the lock.
*
*
* @word: word to lock bit 31 of
*/
static inline void cvmx_spinlock_bit_lock(uint32_t *word)
{
unsigned int tmp;
unsigned int sav;
__asm__ __volatile__(".set noreorder \n"
".set noat \n"
"1: ll %[tmp], %[val] \n"
" bbit1 %[tmp], 31, 1b \n"
" li $at, 1 \n"
" ins %[tmp], $at, 31, 1 \n"
" sc %[tmp], %[val] \n"
" beqz %[tmp], 1b \n"
" nop \n"
".set at \n"
".set reorder \n" :
[val] "+m"(*word), [tmp] "=&r"(tmp), [sav] "=&r"(sav)
: : "memory");
}
/**
* Attempts to get lock, returns immediately with success/failure
* Preserves the low 31 bits of the 32 bit
* word used for the lock.
*
*
* @word: word to lock bit 31 of
* Returns 0: lock successfully taken
* 1: lock not taken, held by someone else
* These return values match the Linux semantics.
*/
static inline unsigned int cvmx_spinlock_bit_trylock(uint32_t *word)
{
unsigned int tmp;
__asm__ __volatile__(".set noreorder\n\t"
".set noat\n"
"1: ll %[tmp], %[val] \n"
/* if lock held, fail immediately */
" bbit1 %[tmp], 31, 2f \n"
" li $at, 1 \n"
" ins %[tmp], $at, 31, 1 \n"
" sc %[tmp], %[val] \n"
" beqz %[tmp], 1b \n"
" li %[tmp], 0 \n"
"2: \n"
".set at \n"
".set reorder \n" :
[val] "+m"(*word), [tmp] "=&r"(tmp)
: : "memory");
return tmp != 0; /* normalize to 0 or 1 */
}
/**
* Releases bit lock
*
* Unconditionally clears bit 31 of the lock word. Note that this is
* done non-atomically, as this implementation assumes that the rest
* of the bits in the word are protected by the lock.
*
* @word: word to unlock bit 31 in
*/
static inline void cvmx_spinlock_bit_unlock(uint32_t *word)
{
CVMX_SYNCWS;
*word &= ~(1UL << 31);
CVMX_SYNCWS;
}
#endif /* __CVMX_SPINLOCK_H__ */

View file

@ -0,0 +1,152 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* This module provides system/board information obtained by the bootloader.
*/
#ifndef __CVMX_SYSINFO_H__
#define __CVMX_SYSINFO_H__
#define OCTEON_SERIAL_LEN 20
/**
* Structure describing application specific information.
* __cvmx_app_init() populates this from the cvmx boot descriptor.
* This structure is private to simple executive applications, so
* no versioning is required.
*
* This structure must be provided with some fields set in order to
* use simple executive functions in other applications (Linux kernel,
* u-boot, etc.) The cvmx_sysinfo_minimal_initialize() function is
* provided to set the required values in these cases.
*/
struct cvmx_sysinfo {
/* System wide variables */
/* installed DRAM in system, in bytes */
uint64_t system_dram_size;
/* ptr to memory descriptor block */
void *phy_mem_desc_ptr;
/* Application image specific variables */
/* stack top address (virtual) */
uint64_t stack_top;
/* heap base address (virtual) */
uint64_t heap_base;
/* stack size in bytes */
uint32_t stack_size;
/* heap size in bytes */
uint32_t heap_size;
/* coremask defining cores running application */
uint32_t core_mask;
/* Deprecated, use cvmx_coremask_first_core() to select init core */
uint32_t init_core;
/* exception base address, as set by bootloader */
uint64_t exception_base_addr;
/* cpu clock speed in hz */
uint32_t cpu_clock_hz;
/* dram data rate in hz (data rate = 2 * clock rate */
uint32_t dram_data_rate_hz;
uint16_t board_type;
uint8_t board_rev_major;
uint8_t board_rev_minor;
uint8_t mac_addr_base[6];
uint8_t mac_addr_count;
char board_serial_number[OCTEON_SERIAL_LEN];
/*
* Several boards support compact flash on the Octeon boot
* bus. The CF memory spaces may be mapped to different
* addresses on different boards. These values will be 0 if
* CF is not present. Note that these addresses are physical
* addresses, and it is up to the application to use the
* proper addressing mode (XKPHYS, KSEG0, etc.)
*/
uint64_t compact_flash_common_base_addr;
uint64_t compact_flash_attribute_base_addr;
/*
* Base address of the LED display (as on EBT3000 board) This
* will be 0 if LED display not present. Note that this
* address is a physical address, and it is up to the
* application to use the proper addressing mode (XKPHYS,
* KSEG0, etc.)
*/
uint64_t led_display_base_addr;
/* DFA reference clock in hz (if applicable)*/
uint32_t dfa_ref_clock_hz;
/* configuration flags from bootloader */
uint32_t bootloader_config_flags;
/* Uart number used for console */
uint8_t console_uart_num;
};
/**
* This function returns the system/board information as obtained
* by the bootloader.
*
*
* Returns Pointer to the boot information structure
*
*/
extern struct cvmx_sysinfo *cvmx_sysinfo_get(void);
/**
* This function is used in non-simple executive environments (such as
* Linux kernel, u-boot, etc.) to configure the minimal fields that
* are required to use simple executive files directly.
*
* Locking (if required) must be handled outside of this
* function
*
* @phy_mem_desc_ptr: Pointer to global physical memory descriptor
* (bootmem descriptor) @board_type: Octeon board
* type enumeration
*
* @board_rev_major:
* Board major revision
* @board_rev_minor:
* Board minor revision
* @cpu_clock_hz:
* CPU clock freqency in hertz
*
* Returns 0: Failure
* 1: success
*/
extern int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr,
uint16_t board_type,
uint8_t board_rev_major,
uint8_t board_rev_minor,
uint32_t cpu_clock_hz);
#endif /* __CVMX_SYSINFO_H__ */

View file

@ -0,0 +1,505 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
#ifndef __CVMX_H__
#define __CVMX_H__
#include <linux/kernel.h>
#include <linux/string.h>
#include "cvmx-asm.h"
#include "cvmx-packet.h"
#include "cvmx-sysinfo.h"
#include "cvmx-ciu-defs.h"
#include "cvmx-gpio-defs.h"
#include "cvmx-iob-defs.h"
#include "cvmx-ipd-defs.h"
#include "cvmx-l2c-defs.h"
#include "cvmx-l2d-defs.h"
#include "cvmx-l2t-defs.h"
#include "cvmx-led-defs.h"
#include "cvmx-mio-defs.h"
#include "cvmx-pow-defs.h"
#include "cvmx-bootinfo.h"
#include "cvmx-bootmem.h"
#include "cvmx-l2c.h"
#ifndef CVMX_ENABLE_DEBUG_PRINTS
#define CVMX_ENABLE_DEBUG_PRINTS 1
#endif
#if CVMX_ENABLE_DEBUG_PRINTS
#define cvmx_dprintf printk
#else
#define cvmx_dprintf(...) {}
#endif
#define CVMX_MAX_CORES (16)
#define CVMX_CACHE_LINE_SIZE (128) /* In bytes */
#define CVMX_CACHE_LINE_MASK (CVMX_CACHE_LINE_SIZE - 1) /* In bytes */
#define CVMX_CACHE_LINE_ALIGNED __attribute__ ((aligned(CVMX_CACHE_LINE_SIZE)))
#define CAST64(v) ((long long)(long)(v))
#define CASTPTR(type, v) ((type *)(long)(v))
/*
* Returns processor ID, different Linux and simple exec versions
* provided in the cvmx-app-init*.c files.
*/
static inline uint32_t cvmx_get_proc_id(void) __attribute__ ((pure));
static inline uint32_t cvmx_get_proc_id(void)
{
uint32_t id;
asm("mfc0 %0, $15,0" : "=r"(id));
return id;
}
/* turn the variable name into a string */
#define CVMX_TMP_STR(x) CVMX_TMP_STR2(x)
#define CVMX_TMP_STR2(x) #x
/**
* Builds a bit mask given the required size in bits.
*
* @bits: Number of bits in the mask
* Returns The mask
*/ static inline uint64_t cvmx_build_mask(uint64_t bits)
{
return ~((~0x0ull) << bits);
}
/**
* Builds a memory address for I/O based on the Major and Sub DID.
*
* @major_did: 5 bit major did
* @sub_did: 3 bit sub did
* Returns I/O base address
*/
static inline uint64_t cvmx_build_io_address(uint64_t major_did,
uint64_t sub_did)
{
return (0x1ull << 48) | (major_did << 43) | (sub_did << 40);
}
/**
* Perform mask and shift to place the supplied value into
* the supplied bit rage.
*
* Example: cvmx_build_bits(39,24,value)
* <pre>
* 6 5 4 3 3 2 1
* 3 5 7 9 1 3 5 7 0
* +-------+-------+-------+-------+-------+-------+-------+------+
* 000000000000000000000000___________value000000000000000000000000
* </pre>
*
* @high_bit: Highest bit value can occupy (inclusive) 0-63
* @low_bit: Lowest bit value can occupy inclusive 0-high_bit
* @value: Value to use
* Returns Value masked and shifted
*/
static inline uint64_t cvmx_build_bits(uint64_t high_bit,
uint64_t low_bit, uint64_t value)
{
return (value & cvmx_build_mask(high_bit - low_bit + 1)) << low_bit;
}
enum cvmx_mips_space {
CVMX_MIPS_SPACE_XKSEG = 3LL,
CVMX_MIPS_SPACE_XKPHYS = 2LL,
CVMX_MIPS_SPACE_XSSEG = 1LL,
CVMX_MIPS_SPACE_XUSEG = 0LL
};
/* These macros for use when using 32 bit pointers. */
#define CVMX_MIPS32_SPACE_KSEG0 1l
#define CVMX_ADD_SEG32(segment, add) \
(((int32_t)segment << 31) | (int32_t)(add))
#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
/* These macros simplify the process of creating common IO addresses */
#define CVMX_ADD_SEG(segment, add) \
((((uint64_t)segment) << 62) | (add))
#ifndef CVMX_ADD_IO_SEG
#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
#endif
/**
* Convert a memory pointer (void*) into a hardware compatable
* memory address (uint64_t). Octeon hardware widgets don't
* understand logical addresses.
*
* @ptr: C style memory pointer
* Returns Hardware physical address
*/
static inline uint64_t cvmx_ptr_to_phys(void *ptr)
{
if (sizeof(void *) == 8) {
/*
* We're running in 64 bit mode. Normally this means
* that we can use 40 bits of address space (the
* hardware limit). Unfortunately there is one case
* were we need to limit this to 30 bits, sign
* extended 32 bit. Although these are 64 bits wide,
* only 30 bits can be used.
*/
if ((CAST64(ptr) >> 62) == 3)
return CAST64(ptr) & cvmx_build_mask(30);
else
return CAST64(ptr) & cvmx_build_mask(40);
} else {
return (long)(ptr) & 0x1fffffff;
}
}
/**
* Convert a hardware physical address (uint64_t) into a
* memory pointer (void *).
*
* @physical_address:
* Hardware physical address to memory
* Returns Pointer to memory
*/
static inline void *cvmx_phys_to_ptr(uint64_t physical_address)
{
if (sizeof(void *) == 8) {
/* Just set the top bit, avoiding any TLB uglyness */
return CASTPTR(void,
CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
physical_address));
} else {
return CASTPTR(void,
CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0,
physical_address));
}
}
/* The following #if controls the definition of the macro
CVMX_BUILD_WRITE64. This macro is used to build a store operation to
a full 64bit address. With a 64bit ABI, this can be done with a simple
pointer access. 32bit ABIs require more complicated assembly */
/* We have a full 64bit ABI. Writing to a 64bit address can be done with
a simple volatile pointer */
#define CVMX_BUILD_WRITE64(TYPE, ST) \
static inline void cvmx_write64_##TYPE(uint64_t addr, TYPE##_t val) \
{ \
*CASTPTR(volatile TYPE##_t, addr) = val; \
}
/* The following #if controls the definition of the macro
CVMX_BUILD_READ64. This macro is used to build a load operation from
a full 64bit address. With a 64bit ABI, this can be done with a simple
pointer access. 32bit ABIs require more complicated assembly */
/* We have a full 64bit ABI. Writing to a 64bit address can be done with
a simple volatile pointer */
#define CVMX_BUILD_READ64(TYPE, LT) \
static inline TYPE##_t cvmx_read64_##TYPE(uint64_t addr) \
{ \
return *CASTPTR(volatile TYPE##_t, addr); \
}
/* The following defines 8 functions for writing to a 64bit address. Each
takes two arguments, the address and the value to write.
cvmx_write64_int64 cvmx_write64_uint64
cvmx_write64_int32 cvmx_write64_uint32
cvmx_write64_int16 cvmx_write64_uint16
cvmx_write64_int8 cvmx_write64_uint8 */
CVMX_BUILD_WRITE64(int64, "sd");
CVMX_BUILD_WRITE64(int32, "sw");
CVMX_BUILD_WRITE64(int16, "sh");
CVMX_BUILD_WRITE64(int8, "sb");
CVMX_BUILD_WRITE64(uint64, "sd");
CVMX_BUILD_WRITE64(uint32, "sw");
CVMX_BUILD_WRITE64(uint16, "sh");
CVMX_BUILD_WRITE64(uint8, "sb");
#define cvmx_write64 cvmx_write64_uint64
/* The following defines 8 functions for reading from a 64bit address. Each
takes the address as the only argument
cvmx_read64_int64 cvmx_read64_uint64
cvmx_read64_int32 cvmx_read64_uint32
cvmx_read64_int16 cvmx_read64_uint16
cvmx_read64_int8 cvmx_read64_uint8 */
CVMX_BUILD_READ64(int64, "ld");
CVMX_BUILD_READ64(int32, "lw");
CVMX_BUILD_READ64(int16, "lh");
CVMX_BUILD_READ64(int8, "lb");
CVMX_BUILD_READ64(uint64, "ld");
CVMX_BUILD_READ64(uint32, "lw");
CVMX_BUILD_READ64(uint16, "lhu");
CVMX_BUILD_READ64(uint8, "lbu");
#define cvmx_read64 cvmx_read64_uint64
static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val)
{
cvmx_write64(csr_addr, val);
/*
* Perform an immediate read after every write to an RSL
* register to force the write to complete. It doesn't matter
* what RSL read we do, so we choose CVMX_MIO_BOOT_BIST_STAT
* because it is fast and harmless.
*/
if ((csr_addr >> 40) == (0x800118))
cvmx_read64(CVMX_MIO_BOOT_BIST_STAT);
}
static inline void cvmx_write_io(uint64_t io_addr, uint64_t val)
{
cvmx_write64(io_addr, val);
}
static inline uint64_t cvmx_read_csr(uint64_t csr_addr)
{
uint64_t val = cvmx_read64(csr_addr);
return val;
}
static inline void cvmx_send_single(uint64_t data)
{
const uint64_t CVMX_IOBDMA_SENDSINGLE = 0xffffffffffffa200ull;
cvmx_write64(CVMX_IOBDMA_SENDSINGLE, data);
}
static inline void cvmx_read_csr_async(uint64_t scraddr, uint64_t csr_addr)
{
union {
uint64_t u64;
struct {
uint64_t scraddr:8;
uint64_t len:8;
uint64_t addr:48;
} s;
} addr;
addr.u64 = csr_addr;
addr.s.scraddr = scraddr >> 3;
addr.s.len = 1;
cvmx_send_single(addr.u64);
}
/* Return true if Octeon is CN38XX pass 1 */
static inline int cvmx_octeon_is_pass1(void)
{
#if OCTEON_IS_COMMON_BINARY()
return 0; /* Pass 1 isn't supported for common binaries */
#else
/* Now that we know we're built for a specific model, only check CN38XX */
#if OCTEON_IS_MODEL(OCTEON_CN38XX)
return cvmx_get_proc_id() == OCTEON_CN38XX_PASS1;
#else
return 0; /* Built for non CN38XX chip, we're not CN38XX pass1 */
#endif
#endif
}
static inline unsigned int cvmx_get_core_num(void)
{
unsigned int core_num;
CVMX_RDHWRNV(core_num, 0);
return core_num;
}
/**
* Returns the number of bits set in the provided value.
* Simple wrapper for POP instruction.
*
* @val: 32 bit value to count set bits in
*
* Returns Number of bits set
*/
static inline uint32_t cvmx_pop(uint32_t val)
{
uint32_t pop;
CVMX_POP(pop, val);
return pop;
}
/**
* Returns the number of bits set in the provided value.
* Simple wrapper for DPOP instruction.
*
* @val: 64 bit value to count set bits in
*
* Returns Number of bits set
*/
static inline int cvmx_dpop(uint64_t val)
{
int pop;
CVMX_DPOP(pop, val);
return pop;
}
/**
* Provide current cycle counter as a return value
*
* Returns current cycle counter
*/
static inline uint64_t cvmx_get_cycle(void)
{
uint64_t cycle;
CVMX_RDHWR(cycle, 31);
return cycle;
}
/**
* Reads a chip global cycle counter. This counts CPU cycles since
* chip reset. The counter is 64 bit.
* This register does not exist on CN38XX pass 1 silicion
*
* Returns Global chip cycle count since chip reset.
*/
static inline uint64_t cvmx_get_cycle_global(void)
{
if (cvmx_octeon_is_pass1())
return 0;
else
return cvmx_read64(CVMX_IPD_CLK_COUNT);
}
/**
* This macro spins on a field waiting for it to reach a value. It
* is common in code to need to wait for a specific field in a CSR
* to match a specific value. Conceptually this macro expands to:
*
* 1) read csr at "address" with a csr typedef of "type"
* 2) Check if ("type".s."field" "op" "value")
* 3) If #2 isn't true loop to #1 unless too much time has passed.
*/
#define CVMX_WAIT_FOR_FIELD64(address, type, field, op, value, timeout_usec)\
( \
{ \
int result; \
do { \
uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
cvmx_sysinfo_get()->cpu_clock_hz / 1000000; \
type c; \
while (1) { \
c.u64 = cvmx_read_csr(address); \
if ((c.s.field) op(value)) { \
result = 0; \
break; \
} else if (cvmx_get_cycle() > done) { \
result = -1; \
break; \
} else \
cvmx_wait(100); \
} \
} while (0); \
result; \
})
/***************************************************************************/
static inline void cvmx_reset_octeon(void)
{
union cvmx_ciu_soft_rst ciu_soft_rst;
ciu_soft_rst.u64 = 0;
ciu_soft_rst.s.soft_rst = 1;
cvmx_write_csr(CVMX_CIU_SOFT_RST, ciu_soft_rst.u64);
}
/* Return the number of cores available in the chip */
static inline uint32_t cvmx_octeon_num_cores(void)
{
uint32_t ciu_fuse = (uint32_t) cvmx_read_csr(CVMX_CIU_FUSE) & 0xffff;
return cvmx_pop(ciu_fuse);
}
/**
* Read a byte of fuse data
* @byte_addr: address to read
*
* Returns fuse value: 0 or 1
*/
static uint8_t cvmx_fuse_read_byte(int byte_addr)
{
union cvmx_mio_fus_rcmd read_cmd;
read_cmd.u64 = 0;
read_cmd.s.addr = byte_addr;
read_cmd.s.pend = 1;
cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
&& read_cmd.s.pend)
;
return read_cmd.s.dat;
}
/**
* Read a single fuse bit
*
* @fuse: Fuse number (0-1024)
*
* Returns fuse value: 0 or 1
*/
static inline int cvmx_fuse_read(int fuse)
{
return (cvmx_fuse_read_byte(fuse >> 3) >> (fuse & 0x7)) & 1;
}
static inline int cvmx_octeon_model_CN36XX(void)
{
return OCTEON_IS_MODEL(OCTEON_CN38XX)
&& !cvmx_octeon_is_pass1()
&& cvmx_fuse_read(264);
}
static inline int cvmx_octeon_zip_present(void)
{
return octeon_has_feature(OCTEON_FEATURE_ZIP);
}
static inline int cvmx_octeon_dfa_present(void)
{
if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
&& !OCTEON_IS_MODEL(OCTEON_CN31XX)
&& !OCTEON_IS_MODEL(OCTEON_CN58XX))
return 0;
else if (OCTEON_IS_MODEL(OCTEON_CN3020))
return 0;
else if (cvmx_octeon_is_pass1())
return 1;
else
return !cvmx_fuse_read(120);
}
static inline int cvmx_octeon_crypto_present(void)
{
return octeon_has_feature(OCTEON_FEATURE_CRYPTO);
}
#endif /* __CVMX_H__ */

View file

@ -0,0 +1,119 @@
/***********************license start***************
* Author: Cavium Networks
*
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
* Copyright (c) 2003-2008 Cavium Networks
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, Version 2, as
* published by the Free Software Foundation.
*
* This file is distributed in the hope that it will be useful, but
* AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
* NONINFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this file; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
* or visit http://www.gnu.org/licenses/.
*
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
/*
* File defining checks for different Octeon features.
*/
#ifndef __OCTEON_FEATURE_H__
#define __OCTEON_FEATURE_H__
enum octeon_feature {
/*
* Octeon models in the CN5XXX family and higher support
* atomic add instructions to memory (saa/saad).
*/
OCTEON_FEATURE_SAAD,
/* Does this Octeon support the ZIP offload engine? */
OCTEON_FEATURE_ZIP,
/* Does this Octeon support crypto acceleration using COP2? */
OCTEON_FEATURE_CRYPTO,
/* Does this Octeon support PCI express? */
OCTEON_FEATURE_PCIE,
/* Some Octeon models support internal memory for storing
* cryptographic keys */
OCTEON_FEATURE_KEY_MEMORY,
/* Octeon has a LED controller for banks of external LEDs */
OCTEON_FEATURE_LED_CONTROLLER,
/* Octeon has a trace buffer */
OCTEON_FEATURE_TRA,
/* Octeon has a management port */
OCTEON_FEATURE_MGMT_PORT,
/* Octeon has a raid unit */
OCTEON_FEATURE_RAID,
/* Octeon has a builtin USB */
OCTEON_FEATURE_USB,
};
static inline int cvmx_fuse_read(int fuse);
/**
* Determine if the current Octeon supports a specific feature. These
* checks have been optimized to be fairly quick, but they should still
* be kept out of fast path code.
*
* @feature: Feature to check for. This should always be a constant so the
* compiler can remove the switch statement through optimization.
*
* Returns Non zero if the feature exists. Zero if the feature does not
* exist.
*/
static inline int octeon_has_feature(enum octeon_feature feature)
{
switch (feature) {
case OCTEON_FEATURE_SAAD:
return !OCTEON_IS_MODEL(OCTEON_CN3XXX);
case OCTEON_FEATURE_ZIP:
if (OCTEON_IS_MODEL(OCTEON_CN30XX)
|| OCTEON_IS_MODEL(OCTEON_CN50XX)
|| OCTEON_IS_MODEL(OCTEON_CN52XX))
return 0;
else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
return 1;
else
return !cvmx_fuse_read(121);
case OCTEON_FEATURE_CRYPTO:
return !cvmx_fuse_read(90);
case OCTEON_FEATURE_PCIE:
return OCTEON_IS_MODEL(OCTEON_CN56XX)
|| OCTEON_IS_MODEL(OCTEON_CN52XX);
case OCTEON_FEATURE_KEY_MEMORY:
case OCTEON_FEATURE_LED_CONTROLLER:
return OCTEON_IS_MODEL(OCTEON_CN38XX)
|| OCTEON_IS_MODEL(OCTEON_CN58XX)
|| OCTEON_IS_MODEL(OCTEON_CN56XX);
case OCTEON_FEATURE_TRA:
return !(OCTEON_IS_MODEL(OCTEON_CN30XX)
|| OCTEON_IS_MODEL(OCTEON_CN50XX));
case OCTEON_FEATURE_MGMT_PORT:
return OCTEON_IS_MODEL(OCTEON_CN56XX)
|| OCTEON_IS_MODEL(OCTEON_CN52XX);
case OCTEON_FEATURE_RAID:
return OCTEON_IS_MODEL(OCTEON_CN56XX)
|| OCTEON_IS_MODEL(OCTEON_CN52XX);
case OCTEON_FEATURE_USB:
return !(OCTEON_IS_MODEL(OCTEON_CN38XX)
|| OCTEON_IS_MODEL(OCTEON_CN58XX));
}
return 0;
}
#endif /* __OCTEON_FEATURE_H__ */

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