Adds the C and header source files for the Cisco PowerTV platform.
History
v2 Check clocksource function to correspond to changed prototype.
v1 First release
Signed-off-by: David VomLehn <>
---
arch/mips/include/asm/mach-powertv/asic.h | 124 +
arch/mips/include/asm/mach-powertv/asic_regs.h | 136 +
arch/mips/include/asm/mach-powertv/dma-coherence.h | 123 +
arch/mips/include/asm/mach-powertv/interrupts.h | 234 ++
arch/mips/include/asm/mach-powertv/war.h | 27 +
arch/mips/powertv/Kconfig | 17 +
arch/mips/powertv/Makefile | 37 +
arch/mips/powertv/asic/Kconfig | 24 +
arch/mips/powertv/asic/Makefile | 24 +
arch/mips/powertv/asic/asic_devices.c | 2902 +++++++++++++++++++
arch/mips/powertv/asic/asic_int.c | 146 +
arch/mips/powertv/asic/irq_asic.c | 115 +
arch/mips/powertv/cevt-powertv.c | 247 ++
arch/mips/powertv/cmdline.c | 51 +
arch/mips/powertv/csrc-powertv.c | 84 +
arch/mips/powertv/init.c | 127 +
arch/mips/powertv/init.h | 10 +
arch/mips/powertv/memory.c | 183 ++
arch/mips/powertv/pci/Makefile | 26 +
arch/mips/powertv/pci/fixup-powertv.c | 14 +
arch/mips/powertv/pci/pci.c | 35 +
arch/mips/powertv/pci/pciemod.c | 2921 ++++++++++++++++++++
arch/mips/powertv/pci/pcieregs.h | 333 +++
arch/mips/powertv/pci/powertv-pci.h | 12 +
arch/mips/powertv/powertv-clock.h | 10 +
arch/mips/powertv/powertv_setup.c | 351 +++
arch/mips/powertv/reset.c | 69 +
arch/mips/powertv/reset.h | 8 +
arch/mips/powertv/time.c | 47 +
29 files changed, 8437 insertions(+), 0 deletions(-)
diff --git a/arch/mips/include/asm/mach-powertv/asic.h
b/arch/mips/include/asm/mach-powertv/asic.h
new file mode 100644
index 0000000..4240e4e
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/asic.h
@@ -0,0 +1,124 @@
+#ifndef _ASM_ASIC_H
+#define _ASM_ASIC_H
+
+#include <asm/mach-powertv/asic_regs.h>
+
+#define DVR_CAPABLE (1<<0)
+#define PCIE_CAPABLE (1<<1)
+#define FFS_CAPABLE (1<<2)
+#define DISPLAY_CAPABLE (1<<3)
+
+/* Platform Family types
+ * For compitability, the new value must be added in the end */
+enum tFamilyType {
+ FAMILY_8500,
+ FAMILY_8500RNG,
+ FAMILY_4500,
+ FAMILY_1500,
+ FAMILY_8600,
+ FAMILY_4600,
+ FAMILY_4600VZA,
+ FAMILY_8600VZB,
+ FAMILY_1500VZE,
+ FAMILY_1500VZF,
+ FAMILIES
+};
+
+extern void powertv_platform_init(void);
+extern void platform_alloc_bootmem(void);
+extern enum tAsicType platform_get_asic(void);
+extern enum tFamilyType platform_get_family(void);
+extern int platform_supports_dvr(void);
+extern int platform_supports_ffs(void);
+extern int platform_supports_pcie(void);
+extern int platform_supports_display(void);
+extern void configure_platform(void);
+extern void platform_configure_usb_ehci(void);
+extern void platform_unconfigure_usb_ehci(void);
+extern void platform_configure_usb_ohci(void);
+extern void platform_unconfigure_usb_ohci(void);
+
+/*
+ * The bus addresses are different than the physical addresses that
+ * the processor sees by an offset. This offset varies by ASIC
+ * version. Define a variable to hold the offset and some macros to
+ * make the conversion simpler. */
+extern unsigned long gPhysToBusOffset;
+
+#ifdef CONFIG_HIGHMEM
+/*
+ * TODO: We will use the hard code for conversion between physical and
+ * bus until the bootloader releases their device tree to us.
+ */
+#define phys_to_bus(x) (((x) < 0x20000000) ? ((x) + gPhysToBusOffset) : (x))
+#define bus_to_phys(x) (((x) < 0x60000000) ? ((x) - gPhysToBusOffset) : (x))
+#else
+#define phys_to_bus(x) ((x) + gPhysToBusOffset)
+#define bus_to_phys(x) ((x) - gPhysToBusOffset)
+#endif
+
+/*
+ * Determine whether the address we are given is for an ASIC device
+ * Params: addr Address to check
+ * Returns: Zero if the address is not for ASIC devices, non-zero
+ * if it is.
+ */
+static inline int asic_is_device_addr(phys_t addr)
+{
+ return !((phys_t)addr & (phys_t) ~0x1fffffffULL);
+}
+
+/*
+ * Determine whether the address we are given is external RAM mappable
+ * into KSEG1.
+ * Params: addr Address to check
+ * Returns: Zero if the address is not for external RAM and
+ */
+static inline int asic_is_lowmem_ram_addr(phys_t addr)
+{
+ /*
+ * The RAM always starts at the following address in the processor's
+ * physical address space
+ */
+ static const phys_t phys_ram_base = 0x10000000;
+ phys_t bus_ram_base;
+
+ bus_ram_base = gPhysToBusOffset + phys_ram_base;
+
+ return addr >= bus_ram_base &&
+ addr < (bus_ram_base + 256 * 1024 * 1024);
+}
+
+/* Platform Resources */
+#define ASIC_RESOURCE_GET_EXISTS 1
+extern struct resource *asic_resource_get(const char *name);
+extern void platform_release_memory(void *baddr, int size);
+
+/* Reboot Cause */
+extern void set_reboot_cause(char code, unsigned int data, unsigned int data2);
+extern void set_locked_reboot_cause(char code, unsigned int data,
+ unsigned int data2);
+
+enum eSys_RebootType {
+ kSys_UnknownReboot = 0x00, /* Unknown reboot cause */
+ kSys_DavicChange = 0x01, /* Reboot due to change in DAVIC
+ * mode */
+ kSys_UserReboot = 0x02, /* Reboot initiated by user */
+ kSys_SystemReboot = 0x03, /* Reboot initiated by OS */
+ kSys_TrapReboot = 0x04, /* Reboot due to a CPU trap */
+ kSys_SilentReboot = 0x05, /* Silent reboot */
+ kSys_BootLdrReboot = 0x06, /* Bootloader reboot */
+ kSys_PowerUpReboot = 0x07, /* Power on bootup. Older
+ * drivers may report as
+ * userReboot. */
+ kSys_CodeChange = 0x08, /* Reboot to take code change.
+ * Older drivers may report as
+ * userReboot. */
+ kSys_HardwareReset = 0x09, /* HW Watchdog or front-panel
+ * reset button reset. Older
+ * drivers may report as
+ * userReboot. */
+ kSys_WatchdogInterrupt = 0x0A /* Pre-watchdog interrupt */
+};
+
+#endif /* _ASM_ASIC_H */
diff --git a/arch/mips/include/asm/mach-powertv/asic_regs.h
b/arch/mips/include/asm/mach-powertv/asic_regs.h
new file mode 100644
index 0000000..8bdbec2
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/asic_regs.h
@@ -0,0 +1,136 @@
+
+#ifndef __ASIC_H_
+#define __ASIC_H_
+#include <linux/io.h>
+
+/* ASIC types */
+enum tAsicType {
+ ASIC_UNKNOWN,
+ ASIC_ZEUS,
+ ASIC_CALLIOPE,
+ ASIC_CRONUS,
+ ASIC_CRONUSLITE,
+ ASICS
+};
+
+/* hardcoded values read from Chip Version registers */
+#define CRONUS_10 0x0B4C1C20
+#define CRONUS_11 0x0B4C1C21
+#define CRONUSLITE_10 0x0B4C1C40
+
+#define NAND_FLASH_BASE 0x03000000
+#define ZEUS_IO_BASE 0x09000000
+#define CALLIOPE_IO_BASE 0x08000000
+#define CRONUS_IO_BASE 0x09000000
+#define ASIC_IO_SIZE 0x01000000
+
+/* ASIC register enumeration */
+struct tRegisterMap { /* ==ZEUS== ==CALLIOPE== */
+ int EIC_SLOW0_STRT_ADD;
+ int EIC_CFG_BITS;
+ int EIC_READY_STATUS; /* 0x00004c 0x80004c */
+
+ int CHIPVER3; /* 0x280800 0xA00800 */
+ int CHIPVER2; /* 0x280804 0xA00804 */
+ int CHIPVER1; /* 0x280808 0xA00808 */
+ int CHIPVER0; /* 0x28080c 0xA0080c */
+
+ int UART1_INTSTAT; /* 0x281800 0xA01800 */
+ int UART1_INTEN; /* 0x281804 0xA01804 */
+ int UART1_CONFIG1; /* 0x281808 0xA01808 */
+ int UART1_CONFIG2; /* 0x28180C 0xA0180C */
+ int UART1_DIVISORHI; /* 0x281810 0xA01810 */
+ int UART1_DIVISORLO; /* 0x281814 0xA01814 */
+ int UART1_DATA; /* 0x281818 0xA01818 */
+ int UART1_STATUS; /* 0x28181C 0xA0181C */
+
+ int Int_Stat_3; /* 0x282800 0xA02800 */
+ int Int_Stat_2; /* 0x282804 0xA02804 */
+ int Int_Stat_1; /* 0x282808 0xA02808 */
+ int Int_Stat_0; /* 0x28280c 0xA0280c */
+ int Int_Config; /* 0x282810 0xA02810 */
+ int Int_Int_Scan; /* 0x282818 0xA02818 */
+ int Ien_Int_3; /* 0x282830 0xA02830 */
+ int Ien_Int_2; /* 0x282834 0xA02834 */
+ int Ien_Int_1; /* 0x282838 0xA02838 */
+ int Ien_Int_0; /* 0x28283c 0xA0283c */
+ int Int_Level_3_3; /* 0x282880 0xA02880 */
+ int Int_Level_3_2; /* 0x282884 0xA02884 */
+ int Int_Level_3_1; /* 0x282888 0xA02888 */
+ int Int_Level_3_0; /* 0x28288c 0xA0288c */
+ int Int_Level_2_3; /* 0x282890 0xA02890 */
+ int Int_Level_2_2; /* 0x282894 0xA02894 */
+ int Int_Level_2_1; /* 0x282898 0xA02898 */
+ int Int_Level_2_0; /* 0x28289c 0xA0289c */
+ int Int_Level_1_3; /* 0x2828a0 0xA028a0 */
+ int Int_Level_1_2; /* 0x2828a4 0xA028a4 */
+ int Int_Level_1_1; /* 0x2828a8 0xA028a8 */
+ int Int_Level_1_0; /* 0x2828ac 0xA028ac */
+ int Int_Level_0_3; /* 0x2828b0 0xA028b0 */
+ int Int_Level_0_2; /* 0x2828b4 0xA028b4 */
+ int Int_Level_0_1; /* 0x2828b8 0xA028b8 */
+ int Int_Level_0_0; /* 0x2828bc 0xA028bc */
+ int Int_Docsis_En; /* 0x2828F4 0xA028F4 */
+
+ int MIPS_PLL_SETUP; /* 0x1a0000 0x980000 */
+ int USB_FS; /* 0x1a0018 0x980030 */
+ int Test_Bus; /* 0x1a0238 0x9800CC */
+ int USB2_OHCI_IntMask; /* 0x1e000c 0x9A000c */
+ int USB2_Strap; /* 0x1e0014 0x9A0014 */
+ int EHCI_HCAPBASE; /* 0x1FFE00 0x9BFE00 */
+ int OHCI_HcRevision; /* 0x1FFC00 0x9BFC00 */
+ int BCM1_BS_LMI_STEER; /* 0x2C0008 0x9E0004 */
+ int USB2_Control; /* 0x2c01a0 0x9E0054 */
+ int USB2_STBUS_OBC; /* 0x1FFF00 0x9BFF00 */
+ int USB2_STBUS_MESS_SIZE; /* 0x1FFF04 0x9BFF04 */
+ int USB2_STBUS_CHUNK_SIZE; /* 0x1FFF08 0x9BFF08 */
+
+ int PCIe_Regs; /* 0x200000 0x000000 */
+ int Free_Running_Ctr_Hi; /* 0x282C10 0xA02C10 */
+ int Free_Running_Ctr_Lo; /* 0x282C14 0xA02C14 */
+ int GPIO_DOUT; /* 0x282c20 0xA02c20 */
+ int GPIO_DIN; /* 0x282c24 0xA02c24 */
+ int GPIO_DIR; /* 0x282c2c 0xA02c2c */
+ int Watchdog; /* 0x282c30 0xA02c30 */
+ int Front_Panel; /* 0x283800 0x000000 */
+
+ int REGISTER_MAPS;
+};
+
+extern enum tAsicType gAsic;
+extern const struct tRegisterMap *gRegisterMap;
+extern unsigned long gAsicPhyBase; /* Physical address of ASIC */
+extern unsigned long pAsicBase; /* Virtual address of ASIC */
+
+/*
+ * Macros to interface to registers through their ioremapped address
+ * asic_reg_offset Returns the offset of a given register from the start
+ * of the ASIC address space
+ * asic_reg_phys_addr Returns the physical address of the given register
+ * asic_reg_addr Returns the iomapped virtual address of the given
+ * register.
+ */
+#define asic_reg_offset(x) (gRegisterMap->x)
+#define asic_reg_phys_addr(x) (gAsicPhyBase + asic_reg_offset(x))
+#define asic_reg_addr(x) ((unsigned int *) (pAsicBase + asic_reg_offset(x)))
+
+/*
+ * The asic_reg macro is gone. It should be replaced by either asic_read or
+ * asic_write, as appropriate.
+ */
+
+#define asic_read(x) _asic_read(asic_reg_addr(x))
+#define asic_write(v, x) _asic_write(v, asic_reg_addr(x))
+
+static inline unsigned int _asic_read(unsigned int *addr)
+{
+ return readl(addr);
+}
+
+static inline void _asic_write(unsigned int value, unsigned int *addr)
+{
+ writel(value, addr);
+}
+
+extern void asic_irq_init(void);
+#endif
diff --git a/arch/mips/include/asm/mach-powertv/dma-coherence.h
b/arch/mips/include/asm/mach-powertv/dma-coherence.h
new file mode 100644
index 0000000..b39f945
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/dma-coherence.h
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ *
+ * Version from mach-generic modified to support PowerTV port
+ *
+ * Copyright (C) 2006 Ralf Baechle <>
+ *
+ */
+#ifndef __ASM_MACH_GENERIC_DMA_COHERENCE_H
+#define __ASM_MACH_GENERIC_DMA_COHERENCE_H
+
+#include <linux/sched.h>
+#include <linux/version.h>
+#include <asm/mach-powertv/asic.h>
+
+struct device;
+
+
+static inline bool is_kseg2(void *addr)
+{
+ return (unsigned long)addr >= KSEG2;
+}
+
+static inline unsigned long virt_to_phys_from_pte(void *addr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *ptep, pte;
+
+ unsigned long virt_addr = (unsigned long)addr;
+ unsigned long phys_addr = 0UL;
+
+ /* get the page global directory. */
+ pgd = pgd_offset_k(virt_addr);
+
+ if (!pgd_none(*pgd)) {
+ /* get the page upper directory */
+ pud = pud_offset(pgd, virt_addr);
+ if (!pud_none(*pud)) {
+ /* get the page middle directory */
+ pmd = pmd_offset(pud, virt_addr);
+ if (!pmd_none(*pmd)) {
+ /* get a pointer to the page table entry */
+ ptep = pte_offset(pmd, virt_addr);
+ pte = *ptep;
+ /* check for a valid page */
+ if (pte_present(pte)) {
+ /* get the physical address the page is
+ * refering to */
+ phys_addr = (unsigned long)
+ page_to_phys(pte_page(pte));
+ /* add the offset within the page */
+ phys_addr |= (virt_addr & ~PAGE_MASK);
+ }
+ }
+ }
+ }
+
+ return phys_addr;
+}
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+ size_t size)
+{
+ if (is_kseg2(addr))
+ return phys_to_bus(virt_to_phys_from_pte(addr));
+ else
+ return phys_to_bus(virt_to_phys(addr));
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ return phys_to_bus(page_to_phys(page));
+}
+
+static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+{
+ return bus_to_phys(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
+ return 1;
+#endif
+#ifdef CONFIG_DMA_NONCOHERENT
+ return 0;
+#endif
+}
+
+#endif /* __ASM_MACH_GENERIC_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-powertv/interrupts.h
b/arch/mips/include/asm/mach-powertv/interrupts.h
new file mode 100644
index 0000000..c37df64
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/interrupts.h
@@ -0,0 +1,234 @@
+#ifndef _INTERRUPTS_H_
+#define _INTERRUPTS_H_
+
+
+/*************************************************************
+ * \brief Defines for all of the interrupt lines
+ *************************************************************/
+
+#define kIBase 0
+
+/*------------- Register: Int_Stat_3 */
+/* 126 unused (bit 31) */
+#define kIrq_ASC2Video (kIBase+126) /* ASC 2 Video Interrupt */
+#define kIrq_ASC1Video (kIBase+125) /* ASC 1 Video Interrupt */
+#define kIrq_COMMS_BlockWd (kIBase+124) /* ASC 1 Video Interrupt */
+#define kIrq_FDMA_Mailbox (kIBase+123) /* FDMA Mailbox Output */
+#define kIrq_FDMA_GP (kIBase+122) /* FDMA GP Output */
+#define kIrq_MipsPIC (kIBase+121) /* MIPS Performance Counter
+ * Interrupt */
+#define kIrq_MipsTimer (kIBase+120) /* MIPS Timer Interrupt */
+#define kIrq_Memory_Protect (kIBase+119) /* Memory Protection Interrupt
+ * -- Ored by glue logic inside
+ * SPARC ILC (see
+ * INT_MEM_PROT_STAT, below,
+ * for individual interrupts)
+ */
+/* 118 unused (bit 22) */
+#define kIrq_SBAG (kIBase+117) /* SBAG Interrupt -- Ored by
+ * glue logic inside SPARC ILC
+ * (see INT_SBAG_STAT, below,
+ * for individual interrupts) */
+#define kIrq_QamB_FEC (kIBase+116) /* QAM B FEC Interrupt */
+#define kIrq_QamA_FEC (kIBase+115) /* QAM A FEC Interrupt */
+/* 114 unused (bit 18) */
+#define kIrq_Mailbox (kIBase+113) /* Mailbox Debug Interrupt --
+ * Ored by glue logic inside
+ * SPARC ILC (see
+ * INT_MAILBOX_STAT, below, for
+ * individual interrupts) */
+#define kIrq_FuseStat1 (kIBase+112) /* Fuse Status 1 */
+#define kIrq_FuseStat2 (kIBase+111) /* Fuse Status 2 */
+#define kIrq_FuseStat3 (kIBase+110) /* Blitter Interrupt / Fuse
+ * Status 3 */
+#define kIrq_Blitter (kIBase+110) /* Blitter Interrupt / Fuse
+ * Status 3 */
+#define kIrq_AVC1_PP0 (kIBase+109) /* AVC Decoder #1 PP0
+ * Interrupt */
+#define kIrq_AVC1_PP1 (kIBase+108) /* AVC Decoder #1 PP1
+ * Interrupt */
+#define kIrq_AVC1_MBE (kIBase+107) /* AVC Decoder #1 MBE
+ * Interrupt */
+#define kIrq_AVC2_PP0 (kIBase+106) /* AVC Decoder #2 PP0
+ * Interrupt */
+#define kIrq_AVC2_PP1 (kIBase+105) /* AVC Decoder #2 PP1
+ * Interrupt */
+#define kIrq_AVC2_MBE (kIBase+104) /* AVC Decoder #2 MBE
+ * Interrupt */
+#define kIrq_ZbugSpi (kIBase+103) /* Zbug SPI Slave Interrupt */
+#define kIrq_QAM_MOD2 (kIBase+102) /* QAM Modulator 2 DMA
+ * Interrupt */
+#define kIrq_IrRx (kIBase+101) /* IR RX 2 Interrupt */
+#define kIrq_AudDsp2 (kIBase+100) /* Audio DSP #2 Interrupt */
+#define kIrq_AudDsp1 (kIBase+99) /* Audio DSP #1 Interrupt */
+#define kIrq_Docsis (kIBase+98) /* DOCSIS Debug Interrupt */
+#define kIrq_SdDVP1 (kIBase+97) /* SD DVP #1 Interrupt */
+#define kIrq_SdDVP2 (kIBase+96) /* SD DVP #2 Interrupt */
+/*------------- Register: Int_Stat_2 */
+#define kIrq_HdDVP (kIBase+95) /* HD DVP Interrupt */
+#define kIrq_PreWatchdog (kIBase+94) /* Watchdog Pre-Interrupt */
+#define kIrq_Timer2 (kIBase+93) /* Programmable Timer
+ * Interrupt 2 */
+#define kIrq_1394 (kIBase+92) /* 1394 Firewire Interrupt */
+#define kIrq_USBOHCI (kIBase+91) /* USB 2.0 OHCI Interrupt */
+#define kIrq_USBEHCI (kIBase+90) /* USB 2.0 EHCI Interrupt */
+#define kIrq_PCIExp (kIBase+89) /* PCI Express 0 Interrupt */
+#define kIrq_PCIExp0 (kIBase+89) /* PCI Express 0 Interrupt */
+#define kIrq_AFE1 (kIBase+88) /* AFE 1 Interrupt */
+#define kIrq_SATA (kIBase+87) /* SATA 1 Interrupt */
+#define kIrq_SATA1 (kIBase+87) /* SATA 1 Interrupt */
+#define kIrq_DTCP (kIBase+86) /* DTCP Interrupt */
+#define kIrq_PCIExp1 (kIBase+85) /* PCI Express 1 Interrupt */
+/* 84 unused (bit 20) */
+/* 83 unused (bit 19) */
+/* 82 unused (bit 18) */
+#define kIrq_SATA2 (kIBase+81) /* SATA2 Interrupt */
+#define kIrq_Uart2 (kIBase+80) /* UART2 Interrupt */
+#define kIrq_LegacyUSB (kIBase+79) /* Legacy USB Host ISR (1.1
+ * Host module) */
+#define kIrq_POD (kIBase+78) /* POD Interrupt */
+#define kIrq_SlaveUSB (kIBase+77) /* Slave USB */
+#define kIrq_Denc1 (kIBase+76) /* DENC #1 VTG Interrupt */
+#define kIrq_VbiVTG (kIBase+75) /* VBI VTG Interrupt */
+#define kIrq_AFE2 (kIBase+74) /* AFE 2 Interrupt */
+#define kIrq_Denc2 (kIBase+73) /* DENC #2 VTG Interrupt */
+#define kIrq_ASC2 (kIBase+72) /* ASC #2 Interrupt */
+#define kIrq_ASC1 (kIBase+71) /* ASC #1 Interrupt */
+#define kIrq_ModDMA (kIBase+70) /* Modulator DMA Interrupt */
+#define kIrq_ByteEng1 (kIBase+69) /* Byte Engine Interrupt [1] */
+#define kIrq_ByteEng0 (kIBase+68) /* Byte Engine Interrupt [0] */
+/* 67 unused (bit 03) */
+/* 66 unused (bit 02) */
+/* 65 unused (bit 01) */
+/* 64 unused (bit 00) */
+/*------------- Register: Int_Stat_1 */
+/* 63 unused (bit 31) */
+/* 62 unused (bit 30) */
+/* 61 unused (bit 29) */
+/* 60 unused (bit 28) */
+/* 59 unused (bit 27) */
+/* 58 unused (bit 26) */
+/* 57 unused (bit 25) */
+/* 56 unused (bit 24) */
+#define kIrq_BufDMA_Mem2Mem (kIBase+55) /* BufDMA Memory to Memory
+ * Interrupt */
+#define kIrq_BufDMA_USBTransmit (kIBase+54) /* BufDMA USB Transmit
+ * Interrupt */
+#define kIrq_BufDMA_QPSKPODTransmit (kIBase+53) /* BufDMA QPSK/POD
Tramsit
+ * Interrupt */
+#define kIrq_BufDMA_TransmitError (kIBase+52) /* BufDMA Transmit Error
+ * Interrupt */
+#define kIrq_BufDMA_USBRecv (kIBase+51) /* BufDMA USB Receive
+ * Interrupt */
+#define kIrq_BufDMA_QPSKPODRecv (kIBase+50) /* BufDMA QPSK/POD
Receive
+ * Interrupt */
+#define kIrq_BufDMA_RecvError (kIBase+49) /* BufDMA Receive Error
+ * Interrupt */
+#define kIrq_QAMDMA_TransmitPlay (kIBase+48) /* QAMDMA Transmit/Play
+ * Interrupt */
+#define kIrq_QAMDMA_TransmitError (kIBase+47) /* QAMDMA Transmit Error
+ * Interrupt */
+#define kIrq_QAMDMA_Recv2High (kIBase+46) /* QAMDMA Receive 2 High
+ * (Chans 63-32) */
+#define kIrq_QAMDMA_Recv2Low (kIBase+45) /* QAMDMA Receive 2 Low
+ * (Chans 31-0) */
+#define kIrq_QAMDMA_Recv1High (kIBase+44) /* QAMDMA Receive 1 High
+ * (Chans 63-32) */
+#define kIrq_QAMDMA_Recv1Low (kIBase+43) /* QAMDMA Receive 1 Low
+ * (Chans 31-0) */
+#define kIrq_QAMDMA_RecvError (kIBase+42) /* QAMDMA Receive Error
+ * Interrupt */
+#define kIrq_MPEGSplice (kIBase+41) /* MPEG Splice
Interrupt */
+#define kIrq_DeinterlaceRdy (kIBase+40) /* Deinterlacer Frame Ready
+ * Interrupt */
+#define kIrq_ExtIn0 (kIBase+39) /* External Interrupt irq_in0 */
+#define kIrq_Gpio3 (kIBase+38) /* GP I/O IRQ 3 - From GP I/O
+ * Module */
+#define kIrq_Gpio2 (kIBase+37) /* GP I/O IRQ 2 - From GP I/O
+ * Module (ABE_intN) */
+#define kIrq_PCRCmplt1 (kIBase+36) /* PCR Capture Complete or
+ * Discontinuity 1 */
+#define kIrq_PCRCmplt2 (kIBase+35) /* PCR Capture Complete or
+ * Discontinuity 2 */
+#define kIrq_ParsePEIErr (kIBase+34) /* PID Parser Error Detect
+ * (PEI) */
+#define kIrq_ParseContErr (kIBase+33) /* PID Parser continuity error
+ * detect */
+#define kIrq_DS1Framer (kIBase+32) /* DS1 Framer Interrupt */
+/*------------- Register: Int_Stat_0 */
+#define kIrq_Gpio1 (kIBase+31) /* GP I/O IRQ 1 - From GP I/O
+ * Module */
+#define kIrq_Gpio0 (kIBase+30) /* GP I/O IRQ 0 - From GP I/O
+ * Module */
+#define kIrq_QpskOutAloha (kIBase+29) /* QPSK Output Slotted Aloha
+ * (chan 3) Transmission
+ * Completed OK */
+#define kIrq_QpskOutTdma (kIBase+28) /* QPSK Output TDMA (chan 2)
+ * Transmission Completed OK */
+#define kIrq_QpskOutReserve (kIBase+27) /* QPSK Output Reservation
+ * (chan 1) Transmission
+ * Completed OK */
+#define kIrq_QpskOutAlohaErr (kIBase+26) /* QPSK Output Slotted Aloha
+ * (chan 3)Transmission
+ * completed with Errors. */
+#define kIrq_QpskOutTdmaErr (kIBase+25) /* QPSK Output TDMA (chan 2)
+ * Transmission completed with
+ * Errors. */
+#define kIrq_QpskOutRsrvErr (kIBase+24) /* QPSK Output Reservation
+ * (chan 1) Transmission
+ * completed with Errors */
+#define kIrq_AlohaFail (kIBase+23) /* Unsuccessful Resend of Aloha
+ * for N times. Aloha retry
+ * timeout for channel 3. */
+#define kIrq_Timer1 (kIBase+22) /* Programmable Timer
+ * Interrupt */
+#define kIrq_Keyboard (kIBase+21) /* Keyboard Module Interrupt */
+#define kIrq_I2c (kIBase+20) /* I2C Module Interrupt */
+#define kIrq_Spi (kIBase+19) /* SPI Module Interrupt */
+#define kIrq_IRBlaster (kIBase+18) /* IR Blaster Interrupt */
+#define kIrq_SpliceDetect (kIBase+17) /* PID Key Change Interrupt or
+ * Splice Detect Interrupt */
+#define kIrq_SeMicro (kIBase+16) /* Secure Micro I/F Module
+ * Interrupt */
+#define kIrq_Uart1 (kIBase+15) /* UART Interrupt */
+#define kIrq_IRrecv (kIBase+14) /* IR Receiver Interrupt */
+#define kIrq_HostInt1 (kIBase+13) /* Host-to-Host Interrupt 1 */
+#define kIrq_HostInt0 (kIBase+12) /* Host-to-Host Interrupt 0 */
+#define kIrq_QpskHECErr (kIBase+11) /* QPSK HEC Error
Interrupt */
+#define kIrq_QpskCRCErr (kIBase+10) /* QPSK AAL-5 CRC Error
+ * Interrupt */
+/* 9 unused (bit 09) */
+/* 8 unused (bit 08) */
+#define kIrq_PSICRCErr (kIBase+7) /* QAM PSI CRC Error
+ * Interrupt */
+#define kIrq_PSILengthErr (kIBase+6) /* QAM PSI Length Error
+ * Interrupt */
+#define kIrq_ESFForward (kIBase+5) /* ESF Interrupt Mark
From
+ * Forward Path Reference -
+ * every 3ms when forward Mbits
+ * and forward slot control
+ * bytes are updated. */
+#define kIrq_ESFReverse (kIBase+4) /* ESF Interrupt Mark
from
+ * Reverse Path Reference -
+ * delayed from forward mark by
+ * the ranging delay plus a
+ * fixed amount. When reverse
+ * Mbits and reverse slot
+ * control bytes are updated.
+ * Occurs every 3ms for 3.0M and
+ * 1.554 M upstream rates and
+ * every 6 ms for 256K upstream
+ * rate. */
+#define kIrq_AlohaTimeout (kIBase+3) /* Slotted-Aloha timeout on
+ * Channel 1. */
+#define kIrq_Reservation (kIBase+2) /* Partial (or Incremental)
+ * Reservation Message Completed
+ * or Slotted aloha verify for
+ * channel 1. */
+#define kIrq_Aloha3 (kIBase+1) /* Slotted-Aloha Message Verify
+ * Interrupt or Reservation
+ * increment completed for
+ * channel 3. */
+#define kIrq_MpegD (kIBase+0) /* MPEG Decoder Interrupt */
+#endif /* _INTERRUPTS_H_ */
+
diff --git a/arch/mips/include/asm/mach-powertv/war.h
b/arch/mips/include/asm/mach-powertv/war.h
new file mode 100644
index 0000000..2f4a155
--- /dev/null
+++ b/arch/mips/include/asm/mach-powertv/war.h
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * This version for the PowerTV platform copied from the Malta version.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <>
+ */
+#ifndef __ASM_MIPS_MACH_MIPS_WAR_H
+#define __ASM_MIPS_MACH_MIPS_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 1
+#define MIPS_CACHE_SYNC_WAR 1
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 1
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_MIPS_WAR_H */
diff --git a/arch/mips/powertv/Kconfig b/arch/mips/powertv/Kconfig
new file mode 100644
index 0000000..ada1732
--- /dev/null
+++ b/arch/mips/powertv/Kconfig
@@ -0,0 +1,17 @@
+source "arch/mips/powertv/asic/Kconfig"
+
+config BOOTLOADER_DRIVER
+ bool "PowerTV Bootloader Driver Support"
+ default n
+ depends on POWERTV
+ help
+ Use this option if you want to load bootloader driver.
+
+config BOOTLOADER_FAMILY
+ string "POWERTV Bootloader Family string"
+ default "85"
+ depends on POWERTV && !BOOTLOADER_DRIVER
+ help
+ This value should be specified when the bootloader driver is disabled
+ and must be exactly two characters long.
+
diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile
new file mode 100644
index 0000000..87886e0
--- /dev/null
+++ b/arch/mips/powertv/Makefile
@@ -0,0 +1,37 @@
+#
+# Carsten Langgaard,
+# Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+#
+# Carsten Langgaard,
+# Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+#
+# This program is free software; you can distribute it and/or modify it
+# under the terms of the GNU General Public License (Version 2) as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 59 Temple Place - Suite 330, Boston MA , USA.
+#
+# Makefile for the MIPS Malta specific kernel interface routines
+# under Linux.
+#
+
+obj-y :=
+
+obj-$(CONFIG_POWERTV) += cmdline.o \
+ init.o \
+ memory.o \
+ reset.o \
+ time.o \
+ powertv_setup.o \
+ asic/ \
+ pci/
+
+obj-$(CONFIG_CEVT_POWERTV) += cevt-powertv.o
+obj-$(CONFIG_CSRC_POWERTV) += csrc-powertv.o
diff --git a/arch/mips/powertv/asic/Kconfig b/arch/mips/powertv/asic/Kconfig
new file mode 100644
index 0000000..48b85ea
--- /dev/null
+++ b/arch/mips/powertv/asic/Kconfig
@@ -0,0 +1,24 @@
+config MIN_RUNTIME_RESOURCES
+ bool "Support for minimum runtime resources"
+ depends on POWERTV
+ help
+ Enables support for minimizing the number of (SA asic) runtime
+ resources that are preallocated by the kernel.
+
+config MIN_RUNTIME_DOCSIS
+ bool "Support for minimum DOCSIS resource"
+ depends on MIN_RUNTIME_RESOURCES
+ help
+ Enables support for the preallocated DOCSIS resource.
+
+config MIN_RUNTIME_PMEM
+ bool "Support for minimum PMEM resource"
+ depends on MIN_RUNTIME_RESOURCES
+ help
+ Enables support for the preallocated Memory resource.
+
+config MIN_RUNTIME_TFTP
+ bool "Support for minimum TFTP resource"
+ depends on MIN_RUNTIME_RESOURCES
+ help
+ Enables support for the preallocated TFTP resource.
diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile
new file mode 100644
index 0000000..52d4336
--- /dev/null
+++ b/arch/mips/powertv/asic/Makefile
@@ -0,0 +1,24 @@
+# *****************************************************************************
+# Make file for PowerTV Asic related files
+#
+# Copyright (C) 2009 Scientific-Atlanta, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA USA
+#
+# *****************************************************************************
+
+obj-y :=
+
+obj-$(CONFIG_POWERTV) += irq_asic.o asic_devices.o asic_int.o
diff --git a/arch/mips/powertv/asic/asic_devices.c
b/arch/mips/powertv/asic/asic_devices.c
new file mode 100644
index 0000000..2e67979
--- /dev/null
+++ b/arch/mips/powertv/asic/asic_devices.c
@@ -0,0 +1,2902 @@
+/****************************************************************************
+ * ASIC Device List Intialization
+ *
+ * Copyright (C) Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA USA
+ *****************************************************************************
+ *
+ * File Name: asic_devices.c
+ *
+ * See Also:
+ *
+ * Project: SA explorer settops
+ *
+ * Compiler:
+ *
+ * Author: Ken Eppinett
+ * David Schleef <>
+ *
+ * Description: Defines the platform resources for the SA settop.
+ *
+ * NOTE: The bootloader allocates persistent memory at an address which is
+ * 16 MiB below the end of the highest address in KSEG0. All fixed
+ * address memory reservations must avoid this region.
+ *
+ *****************************************************************************
+ * History:
+ * Rev Level Date Name ECN# Description
+ *----------------------------------------------------------------------------
+ * 1.0 Eppinett initial version
+ ****************************************************************************/
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/resource.h>
+#include <linux/serial_reg.h>
+#include <linux/io.h>
+#include <linux/bootmem.h>
+#include <linux/mm.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <asm/page.h>
+#include <linux/swap.h>
+#include <linux/highmem.h>
+
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/asic_regs.h>
+#include <asm/mach-powertv/interrupts.h>
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+#include <asm/mach-powertv/kbldr.h>
+#endif
+
+/******************************************************************************
+ * Forward Prototypes
+ *****************************************************************************/
+static void pmem_setup_resource(void);
+
+/******************************************************************************
+ * Global Variables
+ *****************************************************************************/
+enum tAsicType gAsic;
+
+unsigned int gPlatformFeatures;
+unsigned int gPlatformFamily;
+const struct tRegisterMap *gRegisterMap;
+EXPORT_SYMBOL(gRegisterMap); /* Exported for testing */
+unsigned long gAsicPhyBase;
+unsigned long pAsicBase;
+EXPORT_SYMBOL(pAsicBase); /* Exported for testing */
+struct resource *gpResources;
+static bool usb_configured;
+
+/*
+ * Don't recommend to use it directly, it is usually used by kernel internally.
+ * Portable code should be using interfaces such as ioremp, dma_map_single,
etc.
+ */
+unsigned long gPhysToBusOffset;
+EXPORT_SYMBOL(gPhysToBusOffset);
+
+static const struct tRegisterMap zeus_register_map = {
+ .EIC_SLOW0_STRT_ADD = 0x000000,
+ .EIC_CFG_BITS = 0x000038,
+ .EIC_READY_STATUS = 0x00004c,
+
+ .CHIPVER3 = 0x280800,
+ .CHIPVER2 = 0x280804,
+ .CHIPVER1 = 0x280808,
+ .CHIPVER0 = 0x28080c,
+
+ /* The registers of IRBlaster */
+ .UART1_INTSTAT = 0x281800,
+ .UART1_INTEN = 0x281804,
+ .UART1_CONFIG1 = 0x281808,
+ .UART1_CONFIG2 = 0x28180C,
+ .UART1_DIVISORHI = 0x281810,
+ .UART1_DIVISORLO = 0x281814,
+ .UART1_DATA = 0x281818,
+ .UART1_STATUS = 0x28181C,
+
+ .Int_Stat_3 = 0x282800,
+ .Int_Stat_2 = 0x282804,
+ .Int_Stat_1 = 0x282808,
+ .Int_Stat_0 = 0x28280c,
+ .Int_Config = 0x282810,
+ .Int_Int_Scan = 0x282818,
+ .Ien_Int_3 = 0x282830,
+ .Ien_Int_2 = 0x282834,
+ .Ien_Int_1 = 0x282838,
+ .Ien_Int_0 = 0x28283c,
+ .Int_Level_3_3 = 0x282880,
+ .Int_Level_3_2 = 0x282884,
+ .Int_Level_3_1 = 0x282888,
+ .Int_Level_3_0 = 0x28288c,
+ .Int_Level_2_3 = 0x282890,
+ .Int_Level_2_2 = 0x282894,
+ .Int_Level_2_1 = 0x282898,
+ .Int_Level_2_0 = 0x28289c,
+ .Int_Level_1_3 = 0x2828a0,
+ .Int_Level_1_2 = 0x2828a4,
+ .Int_Level_1_1 = 0x2828a8,
+ .Int_Level_1_0 = 0x2828ac,
+ .Int_Level_0_3 = 0x2828b0,
+ .Int_Level_0_2 = 0x2828b4,
+ .Int_Level_0_1 = 0x2828b8,
+ .Int_Level_0_0 = 0x2828bc,
+ .Int_Docsis_En = 0x2828F4,
+
+ .MIPS_PLL_SETUP = 0x1a0000,
+ .USB_FS = 0x1a0018,
+ .Test_Bus = 0x1a0238,
+ .USB2_OHCI_IntMask = 0x1e000c,
+ .USB2_Strap = 0x1e0014,
+ .EHCI_HCAPBASE = 0x1FFE00,
+ .OHCI_HcRevision = 0x1FFC00,
+ .BCM1_BS_LMI_STEER = 0x2C0008,
+ .USB2_Control = 0x2c01a0,
+ .USB2_STBUS_OBC = 0x1FFF00,
+ .USB2_STBUS_MESS_SIZE = 0x1FFF04,
+ .USB2_STBUS_CHUNK_SIZE = 0x1FFF08,
+
+ .PCIe_Regs = 0x200000,
+ .Free_Running_Ctr_Hi = 0x282C10,
+ .Free_Running_Ctr_Lo = 0x282C14,
+ .GPIO_DOUT = 0x282c20,
+ .GPIO_DIN = 0x282c24,
+ .GPIO_DIR = 0x282c2C,
+ .Watchdog = 0x282c30,
+ .Front_Panel = 0x283800,
+};
+
+static const struct tRegisterMap calliope_register_map = {
+ .EIC_SLOW0_STRT_ADD = 0x800000,
+ .EIC_CFG_BITS = 0x800038,
+ .EIC_READY_STATUS = 0x80004c,
+
+ .CHIPVER3 = 0xA00800,
+ .CHIPVER2 = 0xA00804,
+ .CHIPVER1 = 0xA00808,
+ .CHIPVER0 = 0xA0080c,
+
+ /* The registers of IRBlaster */
+ .UART1_INTSTAT = 0xA01800,
+ .UART1_INTEN = 0xA01804,
+ .UART1_CONFIG1 = 0xA01808,
+ .UART1_CONFIG2 = 0xA0180C,
+ .UART1_DIVISORHI = 0xA01810,
+ .UART1_DIVISORLO = 0xA01814,
+ .UART1_DATA = 0xA01818,
+ .UART1_STATUS = 0xA0181C,
+
+ .Int_Stat_3 = 0xA02800,
+ .Int_Stat_2 = 0xA02804,
+ .Int_Stat_1 = 0xA02808,
+ .Int_Stat_0 = 0xA0280c,
+ .Int_Config = 0xA02810,
+ .Int_Int_Scan = 0xA02818,
+ .Ien_Int_3 = 0xA02830,
+ .Ien_Int_2 = 0xA02834,
+ .Ien_Int_1 = 0xA02838,
+ .Ien_Int_0 = 0xA0283c,
+ .Int_Level_3_3 = 0xA02880,
+ .Int_Level_3_2 = 0xA02884,
+ .Int_Level_3_1 = 0xA02888,
+ .Int_Level_3_0 = 0xA0288c,
+ .Int_Level_2_3 = 0xA02890,
+ .Int_Level_2_2 = 0xA02894,
+ .Int_Level_2_1 = 0xA02898,
+ .Int_Level_2_0 = 0xA0289c,
+ .Int_Level_1_3 = 0xA028a0,
+ .Int_Level_1_2 = 0xA028a4,
+ .Int_Level_1_1 = 0xA028a8,
+ .Int_Level_1_0 = 0xA028ac,
+ .Int_Level_0_3 = 0xA028b0,
+ .Int_Level_0_2 = 0xA028b4,
+ .Int_Level_0_1 = 0xA028b8,
+ .Int_Level_0_0 = 0xA028bc,
+ .Int_Docsis_En = 0xA028F4,
+
+ .MIPS_PLL_SETUP = 0x980000,
+ .USB_FS = 0x980030, /* -default - */
+ .Test_Bus = 0x9800CC,
+ .USB2_OHCI_IntMask = 0x9A000c,
+ .USB2_Strap = 0x9A0014,
+ .EHCI_HCAPBASE = 0x9BFE00,
+ .OHCI_HcRevision = 0x9BFC00,
+ .BCM1_BS_LMI_STEER = 0x9E0004,
+ .USB2_Control = 0x9E0054,
+ .USB2_STBUS_OBC = 0x9BFF00,
+ .USB2_STBUS_MESS_SIZE = 0x9BFF04,
+ .USB2_STBUS_CHUNK_SIZE = 0x9BFF08,
+
+ .PCIe_Regs = 0x000000, /* -doesn't exist- */
+ .Free_Running_Ctr_Hi = 0xA02C10,
+ .Free_Running_Ctr_Lo = 0xA02C14,
+ .GPIO_DOUT = 0xA02c20,
+ .GPIO_DIN = 0xA02c24,
+ .GPIO_DIR = 0xA02c2C,
+ .Watchdog = 0xA02c30,
+ .Front_Panel = 0x000000, /* -not used- */
+};
+
+static const struct tRegisterMap cronus_register_map = {
+ .EIC_SLOW0_STRT_ADD = 0x000000,
+ .EIC_CFG_BITS = 0x000038,
+ .EIC_READY_STATUS = 0x00004C,
+
+ .CHIPVER3 = 0x2A0800,
+ .CHIPVER2 = 0x2A0804,
+ .CHIPVER1 = 0x2A0808,
+ .CHIPVER0 = 0x2A080C,
+
+ /* The registers of IRBlaster */
+ .UART1_INTSTAT = 0x2A1800,
+ .UART1_INTEN = 0x2A1804,
+ .UART1_CONFIG1 = 0x2A1808,
+ .UART1_CONFIG2 = 0x2A180C,
+ .UART1_DIVISORHI = 0x2A1810,
+ .UART1_DIVISORLO = 0x2A1814,
+ .UART1_DATA = 0x2A1818,
+ .UART1_STATUS = 0x2A181C,
+
+ .Int_Stat_3 = 0x2A2800,
+ .Int_Stat_2 = 0x2A2804,
+ .Int_Stat_1 = 0x2A2808,
+ .Int_Stat_0 = 0x2A280C,
+ .Int_Config = 0x2A2810,
+ .Int_Int_Scan = 0x2A2818,
+ .Ien_Int_3 = 0x2A2830,
+ .Ien_Int_2 = 0x2A2834,
+ .Ien_Int_1 = 0x2A2838,
+ .Ien_Int_0 = 0x2A283C,
+ .Int_Level_3_3 = 0x2A2880,
+ .Int_Level_3_2 = 0x2A2884,
+ .Int_Level_3_1 = 0x2A2888,
+ .Int_Level_3_0 = 0x2A288C,
+ .Int_Level_2_3 = 0x2A2890,
+ .Int_Level_2_2 = 0x2A2894,
+ .Int_Level_2_1 = 0x2A2898,
+ .Int_Level_2_0 = 0x2A289C,
+ .Int_Level_1_3 = 0x2A28A0,
+ .Int_Level_1_2 = 0x2A28A4,
+ .Int_Level_1_1 = 0x2A28A8,
+ .Int_Level_1_0 = 0x2A28AC,
+ .Int_Level_0_3 = 0x2A28B0,
+ .Int_Level_0_2 = 0x2A28B4,
+ .Int_Level_0_1 = 0x2A28B8,
+ .Int_Level_0_0 = 0x2A28BC,
+ .Int_Docsis_En = 0x2A28F4,
+
+ .MIPS_PLL_SETUP = 0x1C0000,
+ .USB_FS = 0x1C0018,
+ .Test_Bus = 0x1C00CC,
+ .USB2_OHCI_IntMask = 0x20000C,
+ .USB2_Strap = 0x200014,
+ .EHCI_HCAPBASE = 0x21FE00,
+ .OHCI_HcRevision = 0x1E0000,
+ .BCM1_BS_LMI_STEER = 0x2E0008,
+ .USB2_Control = 0x2E004C,
+ .USB2_STBUS_OBC = 0x21FF00,
+ .USB2_STBUS_MESS_SIZE = 0x21FF04,
+ .USB2_STBUS_CHUNK_SIZE = 0x21FF08,
+
+ .PCIe_Regs = 0x220000,
+ .Free_Running_Ctr_Hi = 0x2A2C10,
+ .Free_Running_Ctr_Lo = 0x2A2C14,
+ .GPIO_DOUT = 0x2A2C20,
+ .GPIO_DIN = 0x2A2C24,
+ .GPIO_DIR = 0x2A2C2C,
+ .Watchdog = 0x2A2C30,
+ .Front_Panel = 0x2A3800,
+};
+
+/******************************************************************************
+ * DVR_CAPABLE RESOURCES
+ *****************************************************************************/
+struct resource dvr_zeus_resources[] =
+{
+ /**********************************************************************
+ *
+ * VIDEO1 / LX1
+ *
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x20000000,
+ .end = 0x201FFFFF, /* 2MiB */
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
+ .start = 0x20200000,
+ .end = 0x20201FFF,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x20202000,
+ .end = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * VIDEO2 / LX2
+ *
+ *********************************************************************/
+ {
+ .name = "ST231bImage", /* Delta-Mu 2 image and ram */
+ .start = 0x30000000,
+ .end = 0x301FFFFF, /* 2MiB */
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "ST231bMonitor", /* 8KiB block ST231b monitor */
+ .start = 0x30200000,
+ .end = 0x30201FFF,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "MediaMemory2",
+ .start = 0x30202000,
+ .end = 0x31FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * Sysaudio Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * DSP_Image_Buff - DSP code and data images (1MB)
+ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+ * ADSC_Main_Buff - ADSC Main buffer (16KB)
+ *
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * STAVEM driver/STAPI
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ *
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x00000000,
+ .end = 0x00c00000 - 1, /* 12 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * DOCSIS Subsystem
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "Docsis",
+ .start = 0x40100000,
+ .end = 0x407fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * GHW HAL Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * GraphicsHeap - PowerTV Graphics Heap
+ *
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x46900000,
+ .end = 0x47700000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * multi com buffer area
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x47900000,
+ .end = 0x47920000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * DMA Ring buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x00280000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Display bins buffer for unit0
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit0
+ *
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Display bins buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit1
+ *
+ *********************************************************************/
+ {
+ .name = "DisplayBins1",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * ITFS
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "ITFS",
+ .start = 0x00000000,
+ /* 815,104 bytes each for 2 ITFS partitions. */
+ .end = 0x0018DFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * AVFS
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x00000000,
+ /* (945K * 8) = (128K * 3) 5 playbacks / 3 server */
+ .end = 0x007c2000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "AvfsFileSys",
+ .start = 0x00000000,
+ .end = 0x00001000 - 1, /* 4K */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * PMEM
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Persistent memory for diagnostics.
+ *
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Smartcard
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Read and write buffers for Internal/External cards
+ *
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x00000000,
+ .end = 0x2800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Add other resources here
+ */
+ /*
+ * End of Resource marker
+ *
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+/******************************************************************************
+ * NON_DVR_CAPABLE ZEUS RESOURCES
+ *****************************************************************************/
+struct resource non_dvr_zeus_resources[] =
+{
+ /**********************************************************************
+ * VIDEO1 / LX1
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x20000000,
+ .end = 0x201FFFFF, /* 2MiB */
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
+ .start = 0x20200000,
+ .end = 0x20201FFF,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x20202000,
+ .end = 0x21FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ * Sysaudio Driver
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * STAVEM driver/STAPI
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x00000000,
+ .end = 0x00600000 - 1, /* 6 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * DOCSIS Subsystem
+ *********************************************************************/
+ {
+ .name = "Docsis",
+ .start = 0x40100000,
+ .end = 0x407fffff,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * GHW HAL Driver
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x46900000,
+ .end = 0x47700000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * multi com buffer area
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x47900000,
+ .end = 0x47920000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * DMA Ring buffer
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x00280000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Display bins buffer for unit0
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * AVFS: player HAL memory
+ *
+ *
+ *********************************************************************/
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x00000000,
+ .end = 0x002c4c00 - 1, /* 945K * 3 for playback */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * PMEM
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Smartcard
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x00000000,
+ .end = 0x2800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * NAND Flash
+ *********************************************************************/
+ {
+ .name = "NandFlash",
+ .start = NAND_FLASH_BASE,
+ .end = NAND_FLASH_BASE + 0x400 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ * Add other resources here
+ *
+ * End of Resource marker
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+/******************************************************************************
+ * NON_DVR_CAPABLE CALLIOPE RESOURCES
+ *****************************************************************************/
+struct resource non_dvr_calliope_resources[] =
+{
+ /**********************************************************************
+ * VIDEO / LX1
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x24000000,
+ .end = 0x24200000 - 1, /*2MiB */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ST231aMonitor", /*8KiB block ST231a monitor */
+ .start = 0x24200000,
+ .end = 0x24202000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x24202000,
+ .end = 0x26700000 - 1, /*~36.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Sysaudio Driver
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * STAVEM driver/STAPI
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x00000000,
+ .end = 0x00600000 - 1, /* 6 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * DOCSIS Subsystem
+ *********************************************************************/
+ {
+ .name = "Docsis",
+ .start = 0x22000000,
+ .end = 0x22700000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * GHW HAL Driver
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x22700000,
+ .end = 0x23500000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * multi com buffer area
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x23700000,
+ .end = 0x23720000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * DMA Ring buffer (don't need recording buffers)
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x000AA000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Display bins buffer for unit0
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * AVFS: player HAL memory
+ *
+ *
+ *********************************************************************/
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x00000000,
+ .end = 0x002c4c00 - 1, /* 945K * 3 for playback */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * PMEM
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Smartcard
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x00000000,
+ .end = 0x2800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * NAND Flash
+ *********************************************************************/
+ {
+ .name = "NandFlash",
+ .start = NAND_FLASH_BASE,
+ .end = NAND_FLASH_BASE + 0x400 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ * Synopsys GMAC Memory Region
+ *********************************************************************/
+ {
+ .name = "GMAC",
+ .start = 0x00000000,
+ .end = 0x00010000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Add other resources here
+ *
+ */
+ /*
+ * End of Resource marker
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+struct resource non_dvr_vz_calliope_resources[] =
+{
+ /**********************************************************************
+ * VIDEO / LX1
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x24000000,
+ .end = 0x24200000 - 1, /*2 Meg */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ST231aMonitor", /* 8k block ST231a monitor */
+ .start = 0x24200000,
+ .end = 0x24202000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x22202000,
+ .end = 0x22C20B85 - 1, /* 10.12 Meg */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Sysaudio Driver
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * STAVEM driver/STAPI
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x20300000,
+ .end = 0x20620000-1, /*3.125 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * GHW HAL Driver
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x20100000,
+ .end = 0x20300000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * multi com buffer area
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x23900000,
+ .end = 0x23920000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * DMA Ring buffer
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x000AA000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Display bins buffer for unit0
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * PMEM
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Smartcard
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x00000000,
+ .end = 0x2800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * NAND Flash
+ *********************************************************************/
+ {
+ .name = "NandFlash",
+ .start = NAND_FLASH_BASE,
+ .end = NAND_FLASH_BASE+0x400 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ * Synopsys GMAC Memory Region
+ *********************************************************************/
+ {
+ .name = "GMAC",
+ .start = 0x00000000,
+ .end = 0x00010000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Add other resources here
+ */
+ /*
+ * End of Resource marker
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+
+/*
+ * NOTES:
+ *
+ * There are two things to be done on CRONUS platforms when we try to reserve
+ * the space of HIGHMEM for a specific device.
+ *
+ * 1. "IORESOURCE_MEM" flag can't be used anymore, it should be changed to
+ * "IORESOURCE_IO".
+ *
+ * 2. For the kernel with HIGHMEM support, we have to do some work in the
+ * memory configuration (in memory.c) since we don't make any actual
+ * reservation which has "IORESOURCE_IO" flag through bootmem allocator.
+ *
+ * TODO: Find a solution to make it working easily.
+ */
+
+static struct resource non_dvr_vze_calliope_resources[] __initdata =
+{
+ /**********************************************************************
+ * VIDEO / LX1
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x22000000,
+ .end = 0x22200000 - 1, /*2 Meg */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ST231aMonitor", /* 8k block ST231a monitor */
+ .start = 0x22200000,
+ .end = 0x22202000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x22202000,
+ .end = 0x22C20B85 - 1, /* 10.12 Meg */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Sysaudio Driver
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * STAVEM driver/STAPI
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x20396000,
+ .end = 0x206B6000 - 1, /* 3.125 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * GHW HAL Driver
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x20100000,
+ .end = 0x20396000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * multi com buffer area
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x206B6000,
+ .end = 0x206D6000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * DMA Ring buffer
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x000AA000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Display bins buffer for unit0
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * PMEM
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Smartcard
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x00000000,
+ .end = 0x2800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * NAND Flash
+ *********************************************************************/
+ {
+ .name = "NandFlash",
+ .start = NAND_FLASH_BASE,
+ .end = NAND_FLASH_BASE+0x400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Synopsys GMAC Memory Region
+ *********************************************************************/
+ {
+ .name = "GMAC",
+ .start = 0x00000000,
+ .end = 0x00010000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Add other resources here
+ */
+ /*
+ * End of Resource marker
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+static struct resource non_dvr_vzf_calliope_resources[] __initdata =
+{
+ /**********************************************************************
+ * VIDEO / LX1
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /*Delta-Mu 1 image and ram */
+ .start = 0x24000000,
+ .end = 0x24200000 - 1, /*2MiB */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ST231aMonitor", /*8KiB block ST231a monitor */
+ .start = 0x24200000,
+ .end = 0x24202000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x24202000,
+ /* ~.5MiB - (2MiB + 8KiB)) */
+ .end = 0x25580000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Sysaudio Driver
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * STAVEM driver/STAPI
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x00000000,
+ .end = 0x00480000 - 1, /* 4.5 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * GHW HAL Driver
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x22700000,
+ .end = 0x23500000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * multi com buffer area
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x23700000,
+ .end = 0x23720000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * DMA Ring buffer (don't need recording buffers)
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x000AA000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Display bins buffer for unit0
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Display bins buffer for unit1
+ *********************************************************************/
+ {
+ .name = "DisplayBins1",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * AVFS: player HAL memory
+ *
+ *
+ *********************************************************************/
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x00000000,
+ .end = 0x002c4c00 - 1, /* 945K * 3 for playback */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * PMEM
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Smartcard
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x00000000,
+ .end = 0x2800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * NAND Flash
+ *********************************************************************/
+ {
+ .name = "NandFlash",
+ .start = NAND_FLASH_BASE,
+ .end = NAND_FLASH_BASE + 0x400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Synopsys GMAC Memory Region
+ *********************************************************************/
+ {
+ .name = "GMAC",
+ .start = 0x00000000,
+ .end = 0x00010000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ * Add other resources here
+ */
+ /*********************************************************************
+ * End of Resource marker
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+/******************************************************************************
+ * DVR_CAPABLE CRONUS RESOURCES
+ *****************************************************************************/
+struct resource dvr_cronus_resources[] =
+{
+ /**********************************************************************
+ *
+ * VIDEO1 / LX1
+ *
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x24000000,
+ .end = 0x241FFFFF, /* 2MiB */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
+ .start = 0x24200000,
+ .end = 0x24201FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x24202000,
+ .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * VIDEO2 / LX2
+ *
+ *********************************************************************/
+ {
+ .name = "ST231bImage", /* Delta-Mu 2 image and ram */
+ .start = 0x60000000,
+ .end = 0x601FFFFF, /* 2MiB */
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "ST231bMonitor", /* 8KiB block ST231b monitor */
+ .start = 0x60200000,
+ .end = 0x60201FFF,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "MediaMemory2",
+ .start = 0x60202000,
+ .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * Sysaudio Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * DSP_Image_Buff - DSP code and data images (1MB)
+ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+ * ADSC_Main_Buff - ADSC Main buffer (16KB)
+ *
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * STAVEM driver/STAPI
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ *
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x63580000,
+ .end = 0x64180000 - 1, /* 12 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * DOCSIS Subsystem
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "Docsis",
+ .start = 0x62000000,
+ .end = 0x62700000 - 1, /* 7 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * GHW HAL Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * GraphicsHeap - PowerTV Graphics Heap
+ *
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x62700000,
+ .end = 0x63500000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * multi com buffer area
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x26000000,
+ .end = 0x26020000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * DMA Ring buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x00280000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Display bins buffer for unit0
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit0
+ *
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Display bins buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit1
+ *
+ *********************************************************************/
+ {
+ .name = "DisplayBins1",
+ .start = 0x64AD4000,
+ .end = 0x64AD5000 - 1, /* 4 KB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * ITFS
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "ITFS",
+ .start = 0x64180000,
+ /* 815,104 bytes each for 2 ITFS partitions. */
+ .end = 0x6430DFFF,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * AVFS
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x6430E000,
+ /* (945K * 8) = (128K *3) 5 playbacks / 3 server */
+ .end = 0x64AD0000 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "AvfsFileSys",
+ .start = 0x64AD0000,
+ .end = 0x64AD1000 - 1, /* 4K */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * PMEM
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Persistent memory for diagnostics.
+ *
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Smartcard
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Read and write buffers for Internal/External cards
+ *
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x64AD1000,
+ .end = 0x64AD3800 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * KAVNET
+ * NP Reset Vector - must be of the form xxCxxxxx
+ * NP Image - must be video bank 1
+ * NP IPC - must be video bank 2
+ *********************************************************************/
+ {
+ .name = "NP_Reset_Vector",
+ .start = 0x27c00000,
+ .end = 0x27c01000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_Image",
+ .start = 0x27020000,
+ .end = 0x27060000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_IPC",
+ .start = 0x63500000,
+ .end = 0x63580000 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ * Add other resources here
+ */
+ /*
+ * End of Resource marker
+ *
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+/******************************************************************************
+ * NON_DVR_CAPABLE CRONUSLITE RESOURCES
+ *****************************************************************************/
+struct resource non_dvr_cronuslite_resources[] =
+{
+ /**********************************************************************
+ *
+ * VIDEO2 / LX2
+ *
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /* Delta-Mu 2 image and ram */
+ .start = 0x60000000,
+ .end = 0x601FFFFF, /* 2MiB */
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "ST231aMonitor", /* 8KiB block ST231b monitor */
+ .start = 0x60200000,
+ .end = 0x60201FFF,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x60202000,
+ .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * Sysaudio Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * DSP_Image_Buff - DSP code and data images (1MB)
+ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+ * ADSC_Main_Buff - ADSC Main buffer (16KB)
+ *
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * STAVEM driver/STAPI
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ *
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x63580000,
+ .end = 0x63B80000 - 1, /* 6 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * DOCSIS Subsystem
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "Docsis",
+ .start = 0x62000000,
+ .end = 0x62700000 - 1, /* 7 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * GHW HAL Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * GraphicsHeap - PowerTV Graphics Heap
+ *
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x62700000,
+ .end = 0x63500000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * multi com buffer area
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x26000000,
+ .end = 0x26020000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * DMA Ring buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x000AA000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Display bins buffer for unit0
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit0
+ *
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Display bins buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit1
+ *
+ *********************************************************************/
+ {
+ .name = "DisplayBins1",
+ .start = 0x63B83000,
+ .end = 0x63B84000 - 1, /* 4 KB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * AVFS: player HAL memory
+ *
+ *
+ *********************************************************************/
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x63B84000,
+ .end = 0x63E48C00 - 1, /* 945K * 3 for playback */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * PMEM
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Persistent memory for diagnostics.
+ *
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Smartcard
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Read and write buffers for Internal/External cards
+ *
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x63B80000,
+ .end = 0x63B82800 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * KAVNET
+ * NP Reset Vector - must be of the form xxCxxxxx
+ * NP Image - must be video bank 1
+ * NP IPC - must be video bank 2
+ *********************************************************************/
+ {
+ .name = "NP_Reset_Vector",
+ .start = 0x27c00000,
+ .end = 0x27c01000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_Image",
+ .start = 0x27020000,
+ .end = 0x27060000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_IPC",
+ .start = 0x63500000,
+ .end = 0x63580000 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ * NAND Flash
+ *********************************************************************/
+ {
+ .name = "NandFlash",
+ .start = NAND_FLASH_BASE,
+ .end = NAND_FLASH_BASE + 0x400 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ * Add other resources here
+ */
+ /*
+ * End of Resource marker
+ *
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+/******************************************************************************
+ * NON_DVR_CAPABLE CRONUS RESOURCES
+ *****************************************************************************/
+struct resource non_dvr_cronus_resources[] =
+{
+ /**********************************************************************
+ *
+ * VIDEO1 / LX1
+ *
+ *********************************************************************/
+ {
+ .name = "ST231aImage", /* Delta-Mu 1 image and ram */
+ .start = 0x24000000,
+ .end = 0x241FFFFF, /* 2MiB */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ST231aMonitor", /* 8KiB block ST231a monitor */
+ .start = 0x24200000,
+ .end = 0x24201FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "MediaMemory1",
+ .start = 0x24202000,
+ .end = 0x25FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * VIDEO2 / LX2
+ *
+ *********************************************************************/
+ {
+ .name = "ST231bImage", /* Delta-Mu 2 image and ram */
+ .start = 0x60000000,
+ .end = 0x601FFFFF, /* 2MiB */
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "ST231bMonitor", /* 8KiB block ST231b monitor */
+ .start = 0x60200000,
+ .end = 0x60201FFF,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "MediaMemory2",
+ .start = 0x60202000,
+ .end = 0x61FFFFFF, /*~29.9MiB (32MiB - (2MiB + 8KiB)) */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * Sysaudio Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * DSP_Image_Buff - DSP code and data images (1MB)
+ * ADSC_CPU_PCM_Buff - ADSC CPU PCM buffer (40KB)
+ * ADSC_AUX_Buff - ADSC AUX buffer (16KB)
+ * ADSC_Main_Buff - ADSC Main buffer (16KB)
+ *
+ *********************************************************************/
+ {
+ .name = "DSP_Image_Buff",
+ .start = 0x00000000,
+ .end = 0x000FFFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_CPU_PCM_Buff",
+ .start = 0x00000000,
+ .end = 0x00009FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_AUX_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ADSC_Main_Buff",
+ .start = 0x00000000,
+ .end = 0x00003FFF,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * STAVEM driver/STAPI
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * This memory area is used for allocating buffers for Video decoding
+ * purposes. Allocation/De-allocation within this buffer is managed
+ * by the STAVMEM driver of the STAPI. They could be Decimated
+ * Picture Buffers, Intermediate Buffers, as deemed necessary for
+ * video decoding purposes, for any video decoders on Zeus.
+ *
+ *********************************************************************/
+ {
+ .name = "AVMEMPartition0",
+ .start = 0x63580000,
+ .end = 0x64180000 - 1, /* 12 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * DOCSIS Subsystem
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "Docsis",
+ .start = 0x62000000,
+ .end = 0x62700000 - 1, /* 7 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * GHW HAL Driver
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * GraphicsHeap - PowerTV Graphics Heap
+ *
+ *********************************************************************/
+ {
+ .name = "GraphicsHeap",
+ .start = 0x62700000,
+ .end = 0x63500000 - 1, /* 14 MB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * multi com buffer area
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "MulticomSHM",
+ .start = 0x26000000,
+ .end = 0x26020000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * DMA Ring buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Docsis -
+ *
+ *********************************************************************/
+ {
+ .name = "BMM_Buffer",
+ .start = 0x00000000,
+ .end = 0x000AA000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Display bins buffer for unit0
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit0
+ *
+ *********************************************************************/
+ {
+ .name = "DisplayBins0",
+ .start = 0x00000000,
+ .end = 0x00000FFF, /* 4 KB total */
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Display bins buffer
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Display Bins for unit1
+ *
+ *********************************************************************/
+ {
+ .name = "DisplayBins1",
+ .start = 0x64AD4000,
+ .end = 0x64AD5000 - 1, /* 4 KB total */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * AVFS: player HAL memory
+ *
+ *
+ *********************************************************************/
+ {
+ .name = "AvfsDmaMem",
+ .start = 0x6430E000,
+ .end = 0x645D2C00 - 1, /* 945K * 3 for playback */
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * PMEM
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Persistent memory for diagnostics.
+ *
+ *********************************************************************/
+ {
+ .name = "DiagPersistentMemory",
+ .start = 0x00000000,
+ .end = 0x10000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ /**********************************************************************
+ *
+ * Smartcard
+ *
+ * This driver requires:
+ *
+ * Arbitrary Based Buffers:
+ * Read and write buffers for Internal/External cards
+ *
+ *********************************************************************/
+ {
+ .name = "SmartCardInfo",
+ .start = 0x64AD1000,
+ .end = 0x64AD3800 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ *
+ * KAVNET
+ * NP Reset Vector - must be of the form xxCxxxxx
+ * NP Image - must be video bank 1
+ * NP IPC - must be video bank 2
+ *********************************************************************/
+ {
+ .name = "NP_Reset_Vector",
+ .start = 0x27c00000,
+ .end = 0x27c01000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_Image",
+ .start = 0x27020000,
+ .end = 0x27060000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "NP_IPC",
+ .start = 0x63500000,
+ .end = 0x63580000 - 1,
+ .flags = IORESOURCE_IO,
+ },
+ /**********************************************************************
+ * Add other resources here
+ */
+ /*
+ * End of Resource marker
+ *
+ *********************************************************************/
+ {
+ .flags = 0,
+ },
+};
+
+/*
+ *
+ * IO Resource Definition
+ *
+ */
+
+struct resource asic_resource = {
+ .name = "ASIC Resource",
+ .start = 0,
+ .end = ASIC_IO_SIZE,
+ .flags = IORESOURCE_MEM,
+};
+
+/*
+ *
+ * USB Host Resource Definition
+ *
+ */
+
+static struct resource ehci_resources[] = {
+ {
+ .parent = &asic_resource,
+ .start = 0,
+ .end = 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = kIrq_USBEHCI,
+ .end = kIrq_USBEHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ehci_dmamask = 0xffffffffULL;
+
+static struct platform_device ehci_device = {
+ .name = "powertv-ehci",
+ .id = 0,
+ .num_resources = 2,
+ .resource = ehci_resources,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct resource ohci_resources[] = {
+ {
+ .parent = &asic_resource,
+ .start = 0,
+ .end = 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = kIrq_USBOHCI,
+ .end = kIrq_USBOHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ohci_dmamask = 0xffffffffULL;
+
+static struct platform_device ohci_device = {
+ .name = "powertv-ohci",
+ .id = 0,
+ .num_resources = 2,
+ .resource = ohci_resources,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+static struct platform_device *platform_devices[] = {
+ &ehci_device,
+ &ohci_device,
+};
+
+/*
+ *
+ * Platform Configuration and Device Initialization
+ *
+ */
+static void __init fs_update(int pe, int md, int sdiv, int disable_div_by_3)
+{
+ int en_prg, byp, pwr, nsb, val;
+ int sout;
+
+ sout = 1;
+ en_prg = 1;
+ byp = 0;
+ nsb = 1;
+ pwr = 1;
+
+ val = ((sdiv << 29) | (md << 24) | (pe<<8) | (sout<<3) | (byp<<2) |
+ (nsb<<1) | (disable_div_by_3<<5));
+
+ asic_write(val, USB_FS);
+ asic_write(val | (en_prg<<4), USB_FS);
+ asic_write(val | (en_prg<<4) | pwr, USB_FS);
+}
+
+/*
+ * \brief platform_get_family() determine major platform family type.
+ *
+ * \param none
+ *
+ * \return family type; -1 if none
+ *
+ */
+enum tFamilyType platform_get_family(void)
+{
+#define BOOTLDRFAMILY(byte1, byte0) (((byte1) << 8) | (byte0))
+
+ unsigned short bootldrFamily;
+ static enum tFamilyType family = -1;
+ static int firstTime = 1;
+
+ if (firstTime) {
+ firstTime = 0;
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+ bootldrFamily = (unsigned short) kbldr_GetSWFamily();
+#else
+#if defined(CONFIG_BOOTLOADER_FAMILY)
+ bootldrFamily = (unsigned short) BOOTLDRFAMILY(
+ CONFIG_BOOTLOADER_FAMILY[0],
+ CONFIG_BOOTLOADER_FAMILY[1]);
+#else
+#error "Unknown Bootloader Family"
+#endif
+#endif
+
+ pr_info("Bootloader Family = 0x%04X\n", bootldrFamily);
+
+ switch (bootldrFamily) {
+ case BOOTLDRFAMILY('R', '1'):
+ family = FAMILY_1500;
+ break;
+ case BOOTLDRFAMILY('4', '4'):
+ family = FAMILY_4500;
+ break;
+ case BOOTLDRFAMILY('4', '6'):
+ family = FAMILY_4600;
+ break;
+ case BOOTLDRFAMILY('A', '1'):
+ family = FAMILY_4600VZA;
+ break;
+ case BOOTLDRFAMILY('8', '5'):
+ family = FAMILY_8500;
+ break;
+ case BOOTLDRFAMILY('R', '2'):
+ family = FAMILY_8500RNG;
+ break;
+ case BOOTLDRFAMILY('8', '6'):
+ family = FAMILY_8600;
+ break;
+ case BOOTLDRFAMILY('B', '1'):
+ family = FAMILY_8600VZB;
+ break;
+ case BOOTLDRFAMILY('E', '1'):
+ family = FAMILY_1500VZE;
+ break;
+ case BOOTLDRFAMILY('F', '1'):
+ family = FAMILY_1500VZF;
+ break;
+ default:
+ family = -1;
+ }
+ }
+
+ return family;
+
+#undef BOOTLDRFAMILY
+}
+EXPORT_SYMBOL(platform_get_family);
+
+/*
+ * \brief platform_get_asic() determine the ASIC type.
+ *
+ * \param none
+ *
+ * \return ASIC type; ASIC_UNKNOWN if none
+ *
+ */
+enum tAsicType platform_get_asic(void)
+{
+ return gAsic;
+}
+EXPORT_SYMBOL(platform_get_asic);
+
+/*
+ * \brief platform_configure_usb() usb configuration based on platform type.
+ *
+ * \param int divide_by_3 divide clock setting by 3
+ *
+ * \return none
+ *
+ */
+static void platform_configure_usb(void)
+{
+ int divide_by_3;
+
+ if (usb_configured)
+ return;
+
+ switch (gAsic) {
+ case ASIC_ZEUS:
+ case ASIC_CRONUS:
+ case ASIC_CRONUSLITE:
+ divide_by_3 = 0;
+ break;
+
+ case ASIC_CALLIOPE:
+ divide_by_3 = 1;
+ break;
+
+ default:
+ pr_err("Unknown ASIC type: %d\n", gAsic);
+ divide_by_3 = 0;
+ break;
+ }
+
+ /* Set up PLL for USB */
+ fs_update(0x0000, 0x11, 0x02, divide_by_3);
+ /* turn on USB power */
+ asic_write(0, USB2_Strap);
+ /* Enable all OHCI interrupts */
+ asic_write(0x00000803, USB2_Control);
+ /* USB2_STBUS_OBC store32/load32 */
+ asic_write(3, USB2_STBUS_OBC);
+ /* USB2_STBUS_MESS_SIZE 2 packets */
+ asic_write(1, USB2_STBUS_MESS_SIZE);
+ /* USB2_STBUS_CHUNK_SIZE 2 packets */
+ asic_write(1, USB2_STBUS_CHUNK_SIZE);
+
+ usb_configured = true;
+}
+
+/*
+ * Set up the USB EHCI interface
+ */
+void platform_configure_usb_ehci()
+{ platform_configure_usb();
+}
+
+/*
+ * Set up the USB OHCI interface
+ */
+void platform_configure_usb_ohci()
+{ platform_configure_usb();
+}
+
+/*
+ * Shut the USB EHCI interface down--currently a NOP
+ */
+void platform_unconfigure_usb_ehci()
+{
+}
+
+/*
+ * Shut the USB OHCI interface down--currently a NOP
+ */
+void platform_unconfigure_usb_ohci()
+{
+}
+
+/*
+ * \brief configure_platform() configuration based on platform type.
+ *
+ * \param none
+ *
+ * \return none
+ *
+ */
+void __init configure_platform(void)
+{
+ gPlatformFamily = platform_get_family();
+
+ switch (gPlatformFamily) {
+ case FAMILY_1500:
+ case FAMILY_1500VZE:
+ case FAMILY_1500VZF:
+ gPlatformFeatures = FFS_CAPABLE;
+ gAsic = ASIC_CALLIOPE;
+ gAsicPhyBase = CALLIOPE_IO_BASE;
+ gRegisterMap = &calliope_register_map;
+ pAsicBase = (unsigned long)ioremap_nocache(gAsicPhyBase,
+ ASIC_IO_SIZE);
+
+ if (gPlatformFamily == FAMILY_1500VZE) {
+ gpResources = non_dvr_vze_calliope_resources;
+ pr_info("Platform: 1500/Vz Class E - "
+ "CALLIOPE, NON_DVR_CAPABLE\n");
+ } else if (gPlatformFamily == FAMILY_1500VZF) {
+ gpResources = non_dvr_vzf_calliope_resources;
+ pr_info("Platform: 1500/Vz Class F - "
+ "CALLIOPE, NON_DVR_CAPABLE\n");
+ } else {
+ gpResources = non_dvr_calliope_resources;
+ pr_info("Platform: 1500/RNG100 - CALLIOPE, "
+ "NON_DVR_CAPABLE\n");
+ }
+ break;
+
+ case FAMILY_4500:
+ gPlatformFeatures = FFS_CAPABLE | PCIE_CAPABLE |
+ DISPLAY_CAPABLE;
+ gAsic = ASIC_ZEUS;
+ gAsicPhyBase = ZEUS_IO_BASE;
+ gRegisterMap = &zeus_register_map;
+ pAsicBase = (unsigned long)ioremap_nocache(gAsicPhyBase,
+ ASIC_IO_SIZE);
+ gpResources = non_dvr_zeus_resources;
+
+ pr_info("Platform: 4500 - ZEUS, NON_DVR_CAPABLE\n");
+ break;
+
+ case FAMILY_4600:
+ {
+ unsigned int chipversion = 0;
+
+ /* The settop has PCIE but it isn't used, so don't advertise
+ * it*/
+ gPlatformFeatures = FFS_CAPABLE | DISPLAY_CAPABLE;
+ gAsicPhyBase = CRONUS_IO_BASE; /* same as Cronus */
+ gRegisterMap = &cronus_register_map; /* same as Cronus */
+ pAsicBase = (unsigned long)ioremap_nocache(gAsicPhyBase,
+ ASIC_IO_SIZE);
+ gpResources = non_dvr_cronuslite_resources;
+
+ /* ASIC version will determine if this is a real CronusLite or
+ * Castrati(Cronus) */
+ chipversion = asic_read(CHIPVER3) << 24;
+ chipversion |= asic_read(CHIPVER2) << 16;
+ chipversion |= asic_read(CHIPVER1) << 8;
+ chipversion |= asic_read(CHIPVER0);
+
+ if ((chipversion == CRONUS_10) || (chipversion == CRONUS_11))
+ gAsic = ASIC_CRONUS;
+ else
+ gAsic = ASIC_CRONUSLITE;
+
+ pr_info("Platform: 4600 - %s, NON_DVR_CAPABLE, "
+ "chipversion=0x%08X\n",
+ (gAsic == ASIC_CRONUS) ? "CRONUS" : "CRONUS LITE",
+ chipversion);
+ break;
+ }
+ case FAMILY_4600VZA:
+ gPlatformFeatures = FFS_CAPABLE | DISPLAY_CAPABLE;
+ gAsic = ASIC_CRONUS;
+ gAsicPhyBase = CRONUS_IO_BASE;
+ gRegisterMap = &cronus_register_map;
+ pAsicBase = (unsigned long)ioremap_nocache(gAsicPhyBase,
+ ASIC_IO_SIZE);
+ gpResources = non_dvr_cronus_resources;
+
+ pr_info("Platform: Vz Class A - CRONUS, NON_DVR_CAPABLE\n");
+ break;
+
+ case FAMILY_8500:
+ case FAMILY_8500RNG:
+ gPlatformFeatures = DVR_CAPABLE | PCIE_CAPABLE |
+ DISPLAY_CAPABLE;
+ gAsic = ASIC_ZEUS;
+ gAsicPhyBase = ZEUS_IO_BASE;
+ gRegisterMap = &zeus_register_map;
+ pAsicBase = (unsigned long)ioremap_nocache(gAsicPhyBase,
+ ASIC_IO_SIZE);
+ gpResources = dvr_zeus_resources;
+ break;
+
+ case FAMILY_8600:
+ case FAMILY_8600VZB:
+ gPlatformFeatures = DVR_CAPABLE | PCIE_CAPABLE |
+ DISPLAY_CAPABLE;
+ gAsic = ASIC_CRONUS;
+ gAsicPhyBase = CRONUS_IO_BASE;
+ gRegisterMap = &cronus_register_map;
+ pAsicBase = (unsigned long)ioremap_nocache(gAsicPhyBase,
+ ASIC_IO_SIZE);
+ gpResources = dvr_cronus_resources;
+
+ pr_info("Platform: 8600/Vz Class B - CRONUS, "
+ "DVR_CAPABLE\n");
+ break;
+
+ default:
+ gPlatformFeatures = 0;
+ gAsic = ASIC_UNKNOWN;
+ gAsicPhyBase = 0;
+ gRegisterMap = NULL;
+ gpResources = NULL;
+
+ pr_crit("Platform: UNKNOWN PLATFORM\n");
+ break;
+ }
+
+ platform_configure_usb();
+
+ switch (gAsic) {
+ case ASIC_ZEUS:
+ gPhysToBusOffset = 0x30000000;
+ break;
+ case ASIC_CALLIOPE:
+ gPhysToBusOffset = 0x10000000;
+ break;
+ case ASIC_CRONUSLITE:
+ /* Fall through */
+ case ASIC_CRONUS:
+ /*
+ * TODO: We suppose 0x10000000 aliases into 0x20000000-
+ * 0x2XXXXXXX. If 0x10000000 aliases into 0x60000000-
+ * 0x6XXXXXXX, the offset should be 0x50000000, not 0x10000000.
+ */
+ gPhysToBusOffset = 0x10000000;
+ break;
+ default:
+ gPhysToBusOffset = 0x00000000;
+ break;
+ }
+}
+
+/*
+ * \brief platform_devices_init() sets up USB device resourse.
+ *
+ * \param none
+ *
+ * \return none
+ *
+ */
+static int __init platform_devices_init(void)
+{
+ pr_crit("%s: ----- Initializing USB resources -----\n", __func__);
+
+ asic_resource.start = gAsicPhyBase;
+ asic_resource.end += asic_resource.start;
+
+ ehci_resources[0].start = asic_reg_phys_addr(EHCI_HCAPBASE);
+ ehci_resources[0].end += ehci_resources[0].start;
+
+ ohci_resources[0].start = asic_reg_phys_addr(OHCI_HcRevision);
+ ohci_resources[0].end += ohci_resources[0].start;
+
+ set_io_port_base(0);
+
+ platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+
+ return 0;
+}
+
+arch_initcall(platform_devices_init);
+
+/*
+ *
+ * BOOTMEM ALLOCATION
+ *
+ */
+/*
+ * Allocates/reserves the Platform memory resources early in the boot process.
+ * This ignores any resources that are designated IORESOURCE_IO
+ */
+void __init platform_alloc_bootmem(void)
+{
+ int i;
+ int total = 0;
+
+ /* Get persistent memory data from command line before allocating
+ * resources. This need to happen before normal command line parsing
+ * has been done */
+ pmem_setup_resource();
+
+ /* Loop through looking for resources that want a particular address */
+ for (i = 0; gpResources[i].flags != 0; i++) {
+ int size = gpResources[i].end - gpResources[i].start + 1;
+ if ((gpResources[i].start != 0) &&
+ ((gpResources[i].flags & IORESOURCE_MEM) != 0)) {
+ reserve_bootmem(bus_to_phys(gpResources[i].start),
+ size, 0);
+ total += gpResources[i].end - gpResources[i].start + 1;
+ pr_info("reserve resource %s at %08x (%u bytes)\n",
+ gpResources[i].name, gpResources[i].start,
+ gpResources[i].end - gpResources[i].start + 1);
+ }
+ }
+
+ /* Loop through assigning addresses for those that are left */
+ for (i = 0; gpResources[i].flags != 0; i++) {
+ int size = gpResources[i].end - gpResources[i].start + 1;
+ if ((gpResources[i].start == 0) &&
+ ((gpResources[i].flags & IORESOURCE_MEM) != 0)) {
+ void *mem = alloc_bootmem_pages(size);
+
+ if (mem == NULL)
+ pr_err("Unable to allocate bootmem pages "
+ "for %s\n", gpResources[i].name);
+
+ else {
+ gpResources[i].start =
+ phys_to_bus(virt_to_phys(mem));
+ gpResources[i].end =
+ gpResources[i].start + size - 1;
+ total += size;
+ pr_info("allocate resource %s at %08x "
+ "(%u bytes)\n",
+ gpResources[i].name,
+ gpResources[i].start, size);
+ }
+ }
+ }
+
+ pr_info("Total Platform driver memory allocation: 0x%08x\n", total);
+
+ /* indicate resources that are platform I/O related */
+ for (i = 0; gpResources[i].flags != 0; i++) {
+ if ((gpResources[i].start != 0) &&
+ ((gpResources[i].flags & IORESOURCE_IO) != 0)) {
+ pr_info("reserved platform resource %s at %08x\n",
+ gpResources[i].name, gpResources[i].start);
+ }
+ }
+}
+
+/*
+ *
+ * PERSISTENT MEMORY (PMEM) CONFIGURATION
+ *
+ */
+static unsigned long pmemaddr __initdata;
+
+static int __init early_param_pmemaddr(char *p)
+{
+ pmemaddr = (unsigned long)simple_strtoul(p, NULL, 0);
+ return 0;
+}
+early_param("pmemaddr", early_param_pmemaddr);
+
+static long pmemlen __initdata;
+
+static int __init early_param_pmemlen(char *p)
+{
+/* TODO: we can use this code when and if the bootloader ever changes this */
+#if 0
+ pmemlen = (unsigned long)simple_strtoul(p, NULL, 0);
+#else
+ pmemlen = 0x20000;
+#endif
+ return 0;
+}
+early_param("pmemlen", early_param_pmemlen);
+
+/*
+ * Set up persistent memory. If we were given values, we patch the array of
+ * resources. Otherwise, persistent memory may be allocated anywhere at all.
+ */
+static void __init pmem_setup_resource(void)
+{
+ struct resource *resource;
+ resource = asic_resource_get("DiagPersistentMemory");
+
+ if (resource && pmemaddr && pmemlen) {
+ /* The address provided by bootloader is in kseg0. Convert to
+ * a bus address. */
+ resource->start = phys_to_bus(pmemaddr - 0x80000000);
+ resource->end = resource->start + pmemlen - 1;
+
+ pr_info("persistent memory: start=0x%x end=0x%x\n",
+ resource->start, resource->end);
+ }
+}
+
+/*
+ *
+ * RESOURCE ACCESS FUNCTIONS
+ *
+ */
+
+/*
+ * \brief asic_resource_get() retreives parameters used for allocating
+ * a platform resource.
+ *
+ * \param name - string to match resource
+ *
+ * \return resource ptr
+ *
+ * CANNOT BE NAMED platform_resource_get is this function name is already
+ * declared
+ */
+struct resource *asic_resource_get(const char *name)
+{
+ int i;
+
+ for (i = 0; gpResources[i].flags != 0; i++) {
+ if (strcmp(gpResources[i].name, name) == 0)
+ return &gpResources[i];
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(asic_resource_get);
+
+/*
+ * \brief platform_release_memory() .
+ *
+ * \param ptr - pointer to resource
+ * \param size - size of resource
+ *
+ * \return resource ptr
+ *
+ */
+void platform_release_memory(void *ptr, int size)
+{
+ unsigned long addr;
+ unsigned long end;
+
+ addr = ((unsigned long)ptr + (PAGE_SIZE - 1)) & PAGE_MASK;
+ end = ((unsigned long)ptr + size) & PAGE_MASK;
+
+ for (; addr < end; addr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(__va(addr)));
+ init_page_count(virt_to_page(__va(addr)));
+ free_page((unsigned long)__va(addr));
+ }
+}
+EXPORT_SYMBOL(platform_release_memory);
+
+/*
+ *
+ * FEATURE AVAILABILITY FUNCTIONS
+ *
+ */
+int platform_supports_dvr(void)
+{
+ return (gPlatformFeatures & DVR_CAPABLE) != 0;
+}
+
+int platform_supports_ffs(void)
+{
+ return (gPlatformFeatures & FFS_CAPABLE) != 0;
+}
+
+int platform_supports_pcie(void)
+{
+ return (gPlatformFeatures & PCIE_CAPABLE) != 0;
+}
+
+int platform_supports_display(void)
+{
+ return (gPlatformFeatures & DISPLAY_CAPABLE) != 0;
+}
diff --git a/arch/mips/powertv/asic/asic_int.c
b/arch/mips/powertv/asic/asic_int.c
new file mode 100644
index 0000000..94b6ca9
--- /dev/null
+++ b/arch/mips/powertv/asic/asic_int.c
@@ -0,0 +1,146 @@
+/*
+ * Carsten Langgaard,
+ * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
+ * Copyright (C) 2001 Ralf Baechle
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA , USA.
+ *
+ * Routines for generic manipulation of the interrupts found on the MIPS
+ * Malta board.
+ * The interrupt controller is located in the South Bridge a PIIX4 device
+ * with two internal 82C95 interrupt controllers.
+ */
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/kernel.h>
+#include <linux/random.h>
+
+#include <asm/irq_cpu.h>
+#include <linux/io.h>
+#include <asm/irq_regs.h>
+#include <asm/mips-boards/generic.h>
+
+#include <asm/mach-powertv/asic_regs.h>
+
+static DEFINE_SPINLOCK(mips_irq_lock);
+
+static inline int get_int(void)
+{
+ unsigned long flags;
+ int irq;
+
+ spin_lock_irqsave(&mips_irq_lock, flags);
+
+ irq = (asic_read(Int_Int_Scan) >> 4) - 1;
+
+ if (irq == 0 || irq >= NR_IRQS)
+ irq = -1;
+
+ spin_unlock_irqrestore(&mips_irq_lock, flags);
+
+ return irq;
+}
+
+static void asic_irqdispatch(void)
+{
+ int irq;
+
+ irq = get_int();
+ if (irq < 0)
+ return; /* interrupt has already been cleared */
+
+ do_IRQ(irq);
+}
+
+static inline int clz(unsigned long x)
+{
+ __asm__(
+ " .set push \n"
+ " .set mips32 \n"
+ " clz %0, %1 \n"
+ " .set pop \n"
+ : "=r" (x)
+ : "r" (x));
+
+ return x;
+}
+
+/*
+ * Version of ffs that only looks at bits 12..15.
+ */
+static inline unsigned int irq_ffs(unsigned int pending)
+{
+#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
+ return -clz(pending) + 31 - CAUSEB_IP;
+#else
+ unsigned int a0 = 7;
+ unsigned int t0;
+
+ t0 = pending & 0xf000;
+ t0 = t0 < 1;
+ t0 = t0 << 2;
+ a0 = a0 - t0;
+ pending = pending << t0;
+
+ t0 = pending & 0xc000;
+ t0 = t0 < 1;
+ t0 = t0 << 1;
+ a0 = a0 - t0;
+ pending = pending << t0;
+
+ t0 = pending & 0x8000;
+ t0 = t0 < 1;
+ a0 = a0 - t0;
+
+ return a0;
+#endif
+}
+
+/*
+ * TODO: check how it works under EIC mode.
+ */
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
+ int irq;
+
+ irq = irq_ffs(pending);
+
+ if (irq == CAUSEF_IP3)
+ asic_irqdispatch();
+ else if (irq >= 0)
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ int i;
+
+ asic_irq_init();
+
+ /*
+ * Initialize interrupt exception vectors.
+ */
+ if (cpu_has_veic || cpu_has_vint) {
+ int nvec = cpu_has_veic ? 64 : 8;
+ for (i = 0; i < nvec; i++)
+ set_vi_handler(i, asic_irqdispatch);
+ }
+}
diff --git a/arch/mips/powertv/asic/irq_asic.c
b/arch/mips/powertv/asic/irq_asic.c
new file mode 100644
index 0000000..693abab
--- /dev/null
+++ b/arch/mips/powertv/asic/irq_asic.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2005 Scientific Atlanta
+ *
+ * Modified from arch/mips/kernel/irq-rm7000.c:
+ * Copyright (C) 2003 Ralf Baechle
+ *
+ * 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 <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/system.h>
+
+#include <asm/mach-powertv/asic_regs.h>
+
+static inline void unmask_asic_irq(unsigned int irq)
+{
+ unsigned long enable_bit;
+
+ enable_bit = (1 << (irq & 0x1f));
+
+ switch (irq >> 5) {
+ case 0:
+ asic_write(asic_read(Ien_Int_0) | enable_bit, Ien_Int_0);
+ break;
+ case 1:
+ asic_write(asic_read(Ien_Int_1) | enable_bit, Ien_Int_1);
+ break;
+ case 2:
+ asic_write(asic_read(Ien_Int_2) | enable_bit, Ien_Int_2);
+ break;
+ case 3:
+ asic_write(asic_read(Ien_Int_3) | enable_bit, Ien_Int_3);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static inline void mask_asic_irq(unsigned int irq)
+{
+ unsigned long disable_mask;
+
+ disable_mask = ~(1 << (irq & 0x1f));
+
+ switch (irq >> 5) {
+ case 0:
+ asic_write(asic_read(Ien_Int_0) & disable_mask, Ien_Int_0);
+ break;
+ case 1:
+ asic_write(asic_read(Ien_Int_1) & disable_mask, Ien_Int_1);
+ break;
+ case 2:
+ asic_write(asic_read(Ien_Int_2) & disable_mask, Ien_Int_2);
+ break;
+ case 3:
+ asic_write(asic_read(Ien_Int_3) & disable_mask, Ien_Int_3);
+ break;
+ default:
+ BUG();
+ }
+}
+
+static struct irq_chip asic_irq_chip = {
+ .name = "ASIC Level",
+ .ack = mask_asic_irq,
+ .mask = mask_asic_irq,
+ .mask_ack = mask_asic_irq,
+ .unmask = unmask_asic_irq,
+ .eoi = unmask_asic_irq,
+};
+
+void __init asic_irq_init(void)
+{
+ int i;
+
+ /* set priority to 0 */
+ write_c0_status(read_c0_status() & ~(0x0000fc00));
+
+ asic_write(0, Ien_Int_0);
+ asic_write(0, Ien_Int_1);
+ asic_write(0, Ien_Int_2);
+ asic_write(0, Ien_Int_3);
+
+ asic_write(0x0fffffff, Int_Level_3_3);
+ asic_write(0xffffffff, Int_Level_3_2);
+ asic_write(0xffffffff, Int_Level_3_1);
+ asic_write(0xffffffff, Int_Level_3_0);
+ asic_write(0xffffffff, Int_Level_2_3);
+ asic_write(0xffffffff, Int_Level_2_2);
+ asic_write(0xffffffff, Int_Level_2_1);
+ asic_write(0xffffffff, Int_Level_2_0);
+ asic_write(0xffffffff, Int_Level_1_3);
+ asic_write(0xffffffff, Int_Level_1_2);
+ asic_write(0xffffffff, Int_Level_1_1);
+ asic_write(0xffffffff, Int_Level_1_0);
+ asic_write(0xffffffff, Int_Level_0_3);
+ asic_write(0xffffffff, Int_Level_0_2);
+ asic_write(0xffffffff, Int_Level_0_1);
+ asic_write(0xffffffff, Int_Level_0_0);
+
+ asic_write(0xf, Int_Int_Scan);
+
+ /*
+ * Initialize interrupt handlers.
+ */
+ for (i = 0; i < NR_IRQS; i++)
+ set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
+}
diff --git a/arch/mips/powertv/cevt-powertv.c b/arch/mips/powertv/cevt-powertv.c
new file mode 100644
index 0000000..cecbf40
--- /dev/null
+++ b/arch/mips/powertv/cevt-powertv.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2008 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA , USA.
+ */
+/*
+ * The file comes from kernel/cevt-r4k.c
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/version.h>
+
+#include <asm/smtc_ipi.h>
+#include <asm/time.h> /* Not included in linux/time.h */
+
+#include <asm/mach-powertv/interrupts.h>
+#include "powertv-clock.h"
+
+static int mips_next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ unsigned int cnt;
+ int res;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ {
+ unsigned long flags, vpflags;
+ local_irq_save(flags);
+ vpflags = dvpe();
+#endif
+ cnt = read_c0_count();
+ cnt += delta;
+ write_c0_compare(cnt);
+ res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0;
+#ifdef CONFIG_MIPS_MT_SMTC
+ evpe(vpflags);
+ local_irq_restore(flags);
+ }
+#endif
+ return res;
+}
+
+static void mips_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Nothing to do ... */
+}
+
+static DEFINE_PER_CPU(struct clock_event_device, mips_clockevent_device);
+static int cp0_timer_irq_installed;
+
+/*
+ * Timer ack for an R4k-compatible timer of a known frequency.
+ */
+static void c0_timer_ack(void)
+{
+ write_c0_compare(read_c0_compare());
+}
+
+#ifndef CONFIG_SEPARATE_PCI_TI
+/*
+ * Possibly handle a performance counter interrupt.
+ * Return true if the timer interrupt should not be checked
+ */
+static inline int handle_perf_irq(int r2)
+{
+ /*
+ * The performance counter overflow interrupt may be shared with the
+ * timer interrupt (cp0_perfcount_irq < 0). If it is and a
+ * performance counter has overflowed (perf_irq() == IRQ_HANDLED)
+ * and we can't reliably determine if a counter interrupt has also
+ * happened (!r2) then don't check for a timer interrupt.
+ */
+ return (cp0_perfcount_irq < 0) &&
+ perf_irq() == IRQ_HANDLED &&
+ !r2;
+}
+#endif
+
+static irqreturn_t c0_compare_interrupt(int irq, void *dev_id)
+{
+ const int r2 = cpu_has_mips_r2;
+ struct clock_event_device *cd;
+ int cpu = smp_processor_id();
+
+#ifndef CONFIG_SEPARATE_PCI_TI
+ /*
+ * Suckage alert:
+ * Before R2 of the architecture there was no way to see if a
+ * performance counter interrupt was pending, so we have to run
+ * the performance counter interrupt handler anyway.
+ */
+ if (handle_perf_irq(r2))
+ return IRQ_HANDLED;
+#endif
+
+ /*
+ * The same applies to performance counter interrupts. But with the
+ * above we now know that the reason we got here must be a timer
+ * interrupt. Being the paranoiacs we are we check anyway.
+ */
+ if (!r2 || (read_c0_cause() & (1 << 30))) {
+ c0_timer_ack();
+#ifdef CONFIG_MIPS_MT_SMTC
+ if (cpu_data[cpu].vpe_id)
+ return IRQ_HANDLED;
+ cpu = 0;
+#endif
+ cd = &per_cpu(mips_clockevent_device, cpu);
+ cd->event_handler(cd);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction c0_compare_irqaction = {
+ .handler = c0_compare_interrupt,
+#ifdef CONFIG_MIPS_MT_SMTC
+ .flags = IRQF_DISABLED,
+#else
+ .flags = IRQF_DISABLED | IRQF_PERCPU,
+#endif
+ .name = "timer",
+};
+
+#ifdef CONFIG_MIPS_MT_SMTC
+DEFINE_PER_CPU(struct clock_event_device, smtc_dummy_clockevent_device);
+
+static void smtc_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+}
+
+static void mips_broadcast(cpumask_t mask)
+{
+ unsigned int cpu;
+
+ for_each_cpu_mask(cpu, mask)
+ smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0);
+}
+
+static void setup_smtc_dummy_clockevent_device(void)
+{
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
+
+ cd = &per_cpu(smtc_dummy_clockevent_device, cpu);
+
+ cd->name = "SMTC";
+ cd->features = CLOCK_EVT_FEAT_DUMMY;
+
+ /* Calculate the min / max delta */
+ cd->mult = 0;
+ cd->shift = 0;
+ cd->max_delta_ns = 0;
+ cd->min_delta_ns = 0;
+
+ cd->rating = 200;
+ cd->irq = 17;
+ cd->cpumask = cpumask_of_cpu(cpu);
+
+ cd->set_mode = smtc_set_mode;
+
+ cd->broadcast = mips_broadcast;
+
+ clockevents_register_device(cd);
+}
+#endif
+
+static void mips_event_handler(struct clock_event_device *dev)
+{
+}
+
+int __cpuinit powertv_clockevent_init(void)
+{
+ uint64_t mips_freq = mips_hpt_frequency;
+ unsigned int cpu = smp_processor_id();
+ struct clock_event_device *cd;
+ unsigned int irq;
+
+ if (!cpu_has_counter || !mips_hpt_frequency)
+ return -ENXIO;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+ setup_smtc_dummy_clockevent_device();
+
+ /*
+ * On SMTC we only register VPE0's compare interrupt as clockevent
+ * device.
+ */
+ if (cpu)
+ return 0;
+#endif
+
+ irq = kIrq_MipsTimer;
+
+ cd = &per_cpu(mips_clockevent_device, cpu);
+
+ cd->name = "MIPS";
+ cd->features = CLOCK_EVT_FEAT_ONESHOT;
+
+ /* Calculate the min / max delta */
+ cd->mult = div_sc((unsigned long) mips_freq, NSEC_PER_SEC, 32);
+ cd->shift = 32;
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
+
+ cd->rating = 300;
+ cd->irq = irq;
+#ifdef CONFIG_MIPS_MT_SMTC
+ cd->cpumask = CPU_MASK_ALL;
+#else
+ cd->cpumask = get_cpu_mask(cpu);
+#endif
+ cd->set_next_event = mips_next_event;
+ cd->set_mode = mips_set_mode;
+ cd->event_handler = mips_event_handler;
+
+ clockevents_register_device(cd);
+
+ if (cp0_timer_irq_installed)
+ return 0;
+
+ cp0_timer_irq_installed = 1;
+
+#ifdef CONFIG_MIPS_MT_SMTC
+#define CPUCTR_IMASKBIT (0x100 << cp0_compare_irq)
+ setup_irq_smtc(irq, &c0_compare_irqaction, CPUCTR_IMASKBIT);
+#else
+ setup_irq(irq, &c0_compare_irqaction);
+#endif
+
+ return 0;
+}
diff --git a/arch/mips/powertv/cmdline.c b/arch/mips/powertv/cmdline.c
new file mode 100644
index 0000000..ee570a1
--- /dev/null
+++ b/arch/mips/powertv/cmdline.c
@@ -0,0 +1,51 @@
+/*
+ * Carsten Langgaard,
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA , USA.
+ *
+ * Kernel command line creation using the prom monitor (YAMON) argc/argv.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+
+#include "init.h"
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension.
+ */
+#define prom_argv(index) ((char *)(long)_prom_argv[(index)])
+
+char * __init prom_getcmdline(void)
+{
+ return &(arcs_cmdline[0]);
+}
+
+void __init prom_init_cmdline(void)
+{
+ int len;
+
+ if (prom_argc != 1)
+ return;
+
+ len = strlen(arcs_cmdline);
+
+ arcs_cmdline[len] = ' ';
+
+ strlcpy(arcs_cmdline + len + 1, (char *)_prom_argv,
+ COMMAND_LINE_SIZE - len - 1);
+}
diff --git a/arch/mips/powertv/csrc-powertv.c b/arch/mips/powertv/csrc-powertv.c
new file mode 100644
index 0000000..c032660
--- /dev/null
+++ b/arch/mips/powertv/csrc-powertv.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2008 Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA , USA.
+ */
+/*
+ * The file comes from kernel/csrc-r4k.c
+ */
+#include <linux/clocksource.h>
+#include <linux/init.h>
+
+#include <asm/time.h> /* Not included in linux/time.h */
+
+#include <asm/mach-powertv/asic_regs.h>
+#include "powertv-clock.h"
+
+/* MIPS PLL Register Definitions */
+#define PLL_GET_M(x) (((x) >> 8) & 0x000000FF)
+#define PLL_GET_N(x) (((x) >> 16) & 0x000000FF)
+#define PLL_GET_P(x) (((x) >> 24) & 0x00000007)
+
+/*
+ * returns: Clock frequency in kHz
+ */
+unsigned int __init mips_get_pll_freq(void)
+{
+ unsigned int pll_reg, m, n, p;
+ unsigned int fin = 54000; /* Base frequency in kHz */
+ unsigned int fout;
+
+ /* Read PLL register setting */
+ pll_reg = asic_read(MIPS_PLL_SETUP);
+ m = PLL_GET_M(pll_reg);
+ n = PLL_GET_N(pll_reg);
+ p = PLL_GET_P(pll_reg);
+ pr_info("MIPS PLL Register:0x%x M=%d N=%d P=%d\n", pll_reg, m, n, p);
+
+ /* Calculate clock frequency = (2 * N * 54MHz) / (M * (2**P)) */
+ fout = ((2 * n * fin) / (m * (0x01 << p)));
+
+ pr_info("MIPS Clock Freq=%d kHz\n", fout);
+
+ return fout;
+}
+
+static cycle_t c0_hpt_read(struct clocksource *cs)
+{
+ return read_c0_count();
+}
+
+static struct clocksource clocksource_mips = {
+ .name = "powertv-counter",
+ .read = c0_hpt_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init powertv_clocksource_init(void)
+{
+ unsigned int pll_freq = mips_get_pll_freq();
+
+ pr_info("CPU frequency %d.%02d MHz\n", pll_freq / 1000,
+ (pll_freq % 1000) * 100 / 1000);
+
+ mips_hpt_frequency = pll_freq / 2 * 1000;
+
+ clocksource_mips.rating = 200 + mips_hpt_frequency / ;
+
+ clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+
+ clocksource_register(&clocksource_mips);
+}
diff --git a/arch/mips/powertv/init.c b/arch/mips/powertv/init.c
new file mode 100644
index 0000000..6d7b229
--- /dev/null
+++ b/arch/mips/powertv/init.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <>
+ * Maciej W. Rozycki <>
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA , USA.
+ *
+ * PROM library initialisation code.
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+
+#include <asm/bootinfo.h>
+#include <linux/io.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+#include <asm/traps.h>
+
+#include <asm/mips-boards/prom.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mach-powertv/asic.h>
+
+#include "init.h"
+
+int prom_argc;
+int *_prom_argv, *_prom_envp;
+unsigned long _prom_memsize;
+
+/*
+ * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer.
+ * This macro take care of sign extension, if running in 64-bit mode.
+ */
+#define prom_envp(index) ((char *)(long)_prom_envp[(index)])
+
+char *prom_getenv(char *envname)
+{
+ char *result = NULL;
+
+ if (_prom_envp != NULL) {
+ /*
+ * Return a pointer to the given environment variable.
+ * In 64-bit mode: we're using 64-bit pointers, but all pointers
+ * in the PROM structures are only 32-bit, so we need some
+ * workarounds, if we are running in 64-bit mode.
+ */
+ int i, index = 0;
+
+ i = strlen(envname);
+
+ while (prom_envp(index)) {
+ if (strncmp(envname, prom_envp(index), i) == 0) {
+ result = prom_envp(index + 1);
+ break;
+ }
+ index += 2;
+ }
+ }
+
+ return result;
+}
+
+/* TODO: Verify on linux-mips mailing list that the following two */
+/* functions are correct */
+/* TODO: Copy NMI and EJTAG exception vectors to memory from the */
+/* BootROM exception vectors. Flush their cache entries. test it. */
+
+static void __init mips_nmi_setup(void)
+{
+ void *base;
+#if defined(CONFIG_CPU_MIPS32_R1)
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa80) :
+ (void *)(CAC_BASE + 0x380);
+#elif defined(CONFIG_CPU_MIPS32_R2)
+ base = (void *)0xbfc00000;
+#else
+#error NMI exception handler address not defined
+#endif
+}
+
+static void __init mips_ejtag_setup(void)
+{
+ void *base;
+
+#if defined(CONFIG_CPU_MIPS32_R1)
+ base = cpu_has_veic ?
+ (void *)(CAC_BASE + 0xa00) :
+ (void *)(CAC_BASE + 0x300);
+#elif defined(CONFIG_CPU_MIPS32_R2)
+ base = (void *)0xbfc00480;
+#else
+#error EJTAG exception handler address not defined
+#endif
+}
+
+void __init prom_init(void)
+{
+ prom_argc = fw_arg0;
+ _prom_argv = (int *) fw_arg1;
+ _prom_envp = (int *) fw_arg2;
+ _prom_memsize = (unsigned long) fw_arg3;
+
+ board_nmi_handler_setup = mips_nmi_setup;
+ board_ejtag_handler_setup = mips_ejtag_setup;
+
+ pr_info("\nLINUX started...\n");
+ prom_init_cmdline();
+ configure_platform();
+ prom_meminit();
+
+#ifndef CONFIG_BOOTLOADER_DRIVER
+ pr_info("\nBootloader driver isn't loaded...\n");
+#endif
+}
diff --git a/arch/mips/powertv/init.h b/arch/mips/powertv/init.h
new file mode 100644
index 0000000..763472e
--- /dev/null
+++ b/arch/mips/powertv/init.h
@@ -0,0 +1,10 @@
+/*
+ * Definitions from powertv init.c file
+ */
+
+#ifndef _POWERTV_INIT_H
+#define _POWERTV_INIT_H
+extern int prom_argc;
+extern int *_prom_argv;
+extern unsigned long _prom_memsize;
+#endif
diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c
new file mode 100644
index 0000000..a57972f
--- /dev/null
+++ b/arch/mips/powertv/memory.c
@@ -0,0 +1,183 @@
+/*
+ * Carsten Langgaard,
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA , USA.
+ *
+ * PROM library functions for acquiring/using memory descriptors given to
+ * us from the YAMON.
+ */
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/pfn.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/page.h>
+#include <asm/sections.h>
+
+#include <asm/mips-boards/prom.h>
+
+#include "init.h"
+
+/* Memory constants */
+#define KIBIBYTE(n) ((n) * 1024) /* Number of kibibytes
*/
+#define MEBIBYTE(n) ((n) * KIBIBYTE(1024)) /* Number of
mebibytes */
+#define DEFAULT_MEMSIZE MEBIBYTE(256) /* If no memsize
provided */
+#define LOW_MEM_MAX MEBIBYTE(252) /* Max usable low mem */
+#define RES_BOOTLDR_MEMSIZE MEBIBYTE(1) /* Memory reserved for
bldr */
+#define BOOT_MEM_SIZE KIBIBYTE(256) /* Memory reserved for
bldr */
+#define PHYS_MEM_START 0x10000000 /* Start of physical
memory */
+
+unsigned long ptv_memsize;
+
+void __init prom_meminit(void)
+{
+ char *memsize_str;
+ unsigned long memsize = 0;
+ unsigned int physend;
+ char cmdline[CL_SIZE], *ptr;
+ int low_mem;
+ int high_mem;
+
+ /* Check the command line first for a memsize directive */
+ strcpy(cmdline, arcs_cmdline);
+ ptr = strstr(cmdline, "memsize=");
+ if (ptr && (ptr != cmdline) && (*(ptr - 1) != ' '))
+ ptr = strstr(ptr, " memsize=");
+
+ if (ptr) {
+ memsize = memparse(ptr + 8, &ptr);
+ } else {
+ /* otherwise look in the environment */
+ memsize_str = prom_getenv("memsize");
+
+ if (memsize_str != NULL) {
+ pr_info("prom memsize = %s\n", memsize_str);
+ memsize = simple_strtol(memsize_str, NULL, 0);
+ }
+
+ if (memsize == 0) {
+ if (_prom_memsize != 0) {
+ memsize = _prom_memsize;
+ pr_info("_prom_memsize = 0x%lx\n", memsize);
+ /* add in memory that the bootloader doesn't
+ * report */
+ memsize += BOOT_MEM_SIZE;
+ } else {
+ memsize = DEFAULT_MEMSIZE;
+ pr_info("Memsize not passed by bootloader, "
+ "defaulting to 0x%lx\n", memsize);
+ }
+ }
+ }
+
+ /* Store memsize for diagnostic purposes */
+ ptv_memsize = memsize;
+
+ physend = PFN_ALIGN(&_end) - 0x80000000;
+ if (memsize > LOW_MEM_MAX) {
+ low_mem = LOW_MEM_MAX;
+ high_mem = memsize - low_mem;
+ } else {
+ low_mem = memsize;
+ high_mem = 0;
+ }
+
+/*
+ * TODO: We will use the hard code for memory configuration until
+ * the bootloader releases their device tree to us.
+ */
+ /*
+ * Add the memory reserved for use by the bootloader to the
+ * memory map.
+ */
+ add_memory_region(PHYS_MEM_START, RES_BOOTLDR_MEMSIZE,
+ BOOT_MEM_RESERVED);
+#ifdef CONFIG_HIGHMEM_256_128
+ /*
+ * Add memory in low for general use by the kernel and its friends
+ * (like drivers, applications, etc).
+ */
+ add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
+ LOW_MEM_MAX - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
+ /*
+ * Add the memory reserved for reset vector.
+ */
+ add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
+ /*
+ * Add the memory reserved.
+ */
+ add_memory_region(0x20000000, MEBIBYTE(1024 + 75), BOOT_MEM_RESERVED);
+ /*
+ * Add memory in high for general use by the kernel and its friends
+ * (like drivers, applications, etc).
+ *
+ * 75MB is reserved for devices which are using the memory in high.
+ */
+ add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(),
+ BOOT_MEM_RAM);
+#elif defined CONFIG_HIGHMEM_128_128
+ /*
+ * Add memory in low for general use by the kernel and its friends
+ * (like drivers, applications, etc).
+ */
+ add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
+ MEBIBYTE(128) - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
+ /*
+ * Add the memory reserved.
+ */
+ add_memory_region(PHYS_MEM_START + MEBIBYTE(128),
+ MEBIBYTE(128 + 1024 + 75), BOOT_MEM_RESERVED);
+ /*
+ * Add memory in high for general use by the kernel and its friends
+ * (like drivers, applications, etc).
+ *
+ * 75MB is reserved for devices which are using the memory in high.
+ */
+ add_memory_region(0x60000000 + MEBIBYTE(75), MEBIBYTE(),
+ BOOT_MEM_RAM);
+#else
+ /* Add low memory regions for either:
+ * - no-highmemory configuration case -OR-
+ * - highmemory "HIGHMEM_LOWBANK_ONLY" case
+ */
+ /*
+ * Add memory for general use by the kernel and its friends
+ * (like drivers, applications, etc).
+ */
+ add_memory_region(PHYS_MEM_START + RES_BOOTLDR_MEMSIZE,
+ low_mem - RES_BOOTLDR_MEMSIZE, BOOT_MEM_RAM);
+ /*
+ * Add the memory reserved for reset vector.
+ */
+ add_memory_region(0x1fc00000, MEBIBYTE(4), BOOT_MEM_RESERVED);
+#endif
+}
+
+void __init prom_free_prom_memory(void)
+{
+ unsigned long addr;
+ int i;
+
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
+ continue;
+
+ addr = boot_mem_map.map[i].addr;
+ free_init_pages("prom memory",
+ addr, addr + boot_mem_map.map[i].size);
+ }
+}
diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile
new file mode 100644
index 0000000..7bf9f8c
--- /dev/null
+++ b/arch/mips/powertv/pci/Makefile
@@ -0,0 +1,26 @@
+# *****************************************************************************
+# Make file for PowerTV PCI driver
+#
+# Copyright (C) 2009 Scientific-Atlanta, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA USA
+#
+# *****************************************************************************
+
+obj-y :=
+
+obj-$(CONFIG_PCI) += pci.o fixup-powertv.o pciemod.o
+
+
diff --git a/arch/mips/powertv/pci/fixup-powertv.c
b/arch/mips/powertv/pci/fixup-powertv.c
new file mode 100644
index 0000000..a75a9ab
--- /dev/null
+++ b/arch/mips/powertv/pci/fixup-powertv.c
@@ -0,0 +1,14 @@
+#include <linux/init.h>
+#include <linux/pci.h>
+#include "powertv-pci.h"
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return asic_pcie_map_irq(dev, slot, pin);
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
diff --git a/arch/mips/powertv/pci/pci.c b/arch/mips/powertv/pci/pci.c
new file mode 100644
index 0000000..3358b5f
--- /dev/null
+++ b/arch/mips/powertv/pci/pci.c
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 1999, 2000, 2004, 2005 MIPS Technologies, Inc.
+ * All rights reserved.
+ * Authors: Carsten Langgaard <>
+ * Maciej W. Rozycki <>
+ *
+ * Copyright (C) 2004 by Ralf Baechle ()
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA , USA.
+ *
+ * MIPS boards specific PCI support.
+ */
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/mips-boards/generic.h>
+#include "powertv-pci.h"
+
+void __init mips_pcibios_init(void)
+{
+ asic_pcie_init();
+}
diff --git a/arch/mips/powertv/pci/pciemod.c b/arch/mips/powertv/pci/pciemod.c
new file mode 100644
index 0000000..f152fc5
--- /dev/null
+++ b/arch/mips/powertv/pci/pciemod.c
@@ -0,0 +1,2921 @@
+/*
-----------------------------------------------------------------------------
+ * PCIE Module
+ *
+ * Copyright (C) Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA USA
+ *
+ *
-----------------------------------------------------------------------------
+ *
+ * File Name: pciemod.c
+ *
+ * Project: NGP
+ *
+ * Compiler: gnu C (gcc)
+ *
+ * Author(s): Tom Haman
+ *
+ * Description: Routines implementing kernel PCIE Module.
+ *
+ * Documents: PCIE Software Design Document
+ *
+ * NOTES:
+ *
+ *
-----------------------------------------------------------------------------
+ * History:
+ * Rev Level Date Name ECN# Description
+ *
-----------------------------------------------------------------------------
+ * /27/06 Tom Haman --- Initial version for NGP (Zeus)
+ *
-----------------------------------------------------------------------------
+ */
+
+
+/*platform and compile/usage definitions */
+#define DEBUG 1
+#define LOADABLE 0
+
+#ifndef SA8KG5
+#define SA8KG5 1
+#endif
+
+#ifndef qDebug
+#define qDebug DEBUG
+#endif
+
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/cdev.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/pci.h>
+
+/* SA includes */
+#include <asm/mach-powertv/asic.h>
+#include <asm/mach-powertv/asic_regs.h>
+#include <asm/mach-powertv/interrupts.h>
+
+#include "pcieregs.h"
+
+
+
+/******************************************************************************
+ ******************************************************************************
+ * these items would normally be in SA driver include files but since we are
+ * in the low level Kernel, they are defined here
+ ******************************************************************************
+ ******************************************************************************
+ * FROM "SAKernel.h"
+ */
+enum {
+ SA_OFF,
+ SA_FATAL,
+ SA_SEVERE,
+ SA_INFO,
+ SA_NOISE
+} eSa_LogLevels;
+
+#define SA_LOG_TO_PRINT 1
+
+#if ((defined(DEBUG) && DEBUG) || (defined(qDebug) && qDebug))
+#define SAPRINT(level, destflags, fmt...) do { \
+ if ((level <= LogLevel) && ((destflags) & SA_LOG_TO_PRINT)) \
+ printk(fmt); \
+ } while (0)
+#else
+#define SAPRINT(level, destflags, fmt...) do {} while (0)
+#endif
+
+MODULE_AUTHOR("Tom Haman");
+MODULE_DESCRIPTION("PCIE Module");
+MODULE_LICENSE("GPL");
+
+/* File ID info (DO NOT EDIT) */
+const char PCIE_ident[] = "SA-Drv-Ident %name: %, %version: %, "
+ "%instance: %, %date_created: %, %created_by: %";
+
+/*******************************************************************************
+
*******************************************************************************
+ * LOADABLE Elements
+
*******************************************************************************
+
******************************************************************************/
+#if LOADABLE
+/*Module Parameters */
+module_param(LogLevel, int, S_IRUGO);
+MODULE_PARM_DESC(LogLevel, "Module debug log level");
+#endif /*LOADABLE */
+
+/*******************************************************************************
+
*******************************************************************************
+ * KERNEL Elements
+
*******************************************************************************
+
******************************************************************************/
+/*---------- Defines ------------ */
+#define pcieModule_Name "pcie"
+
+/*---------- Variables ------------ */
+static struct proc_dir_entry *PCIE_pProc; /* proc directory entry */
+static int LogLevel = SA_INFO;
+static struct tPCIERegs *PCIE_RegsPtr;
+static int PCIE_irqrequest_pcie;
+static u32 PCIE_initialized;
+static u32 *timerptr;
+static spinlock_t PCIE_lock;
+
+/*---------- Non Private Module Prototypes ------------ */
+static int __init pcie_Init(void);
+static void __exit pcie_Finalize(void);
+static int asic_pcie_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val);
+static int asic_pcie_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val);
+
+/*---------- Private Module Prototypes ------------ */
+static irqreturn_t asic_pcie_process_interrupt(int irq, void *dev_id);
+static u32 pcie_rc_cfg_read32(u32 type, u32 busnum, u32 devnum, u32 func_num,
+ u32 reg_num, u32 *dataptr);
+static u32 pcie_rc_cfg_write32(u32 type, u32 busnum, u32 devnum, u32 func_num,
+ u32 reg_num, u32 *dataptr);
+static void pcie_DumpRegs(void);
+static int pcie_dumpcapability(int busnumber, int dev, int fn, int ptr);
+static int pcie_dumpextendedcapability(int busnumber, int dev, int fn, int
ptr);
+static void pcie_delay(u32 ms);
+static int pcie_reset_ethernet(void) ;
+static void pcie_uSecDelay(u32 us);
+
+/*proc */
+static int pcie_WriteProc(struct file *pfile, const char __user *pbuff,
+ unsigned long bytecnt, void *data);
+static int pcie_ReadProc(char *page, char **start, off_t off, int pageSize,
+ int *eof, void *data);
+
+/*interrupt */
+static u32 intdata[4];
+static int intcountslow[32], intcountshigh[32];
+
+/*---------- Structures ----------- */
+static struct pci_ops asic_pci_ops = {
+ .read = asic_pcie_read_config,
+ .write = asic_pcie_write_config
+};
+
+static struct resource asic_mem_resource = {
+ .name = "ZEUS PCI MEM",
+ .flags = IORESOURCE_MEM,
+ .start = 0x08000000UL,
+ .end = 0x083FFFFFUL,
+
+};
+
+static struct resource asic_io_resource = {
+ .name = "ASIC PCI I/O",
+ .start = 0x08400000UL,
+ .end = 0x087FFFFFUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller asic_controller = {
+ .pci_ops = &asic_pci_ops,
+ .io_resource = &asic_io_resource,
+ .mem_resource = &asic_mem_resource,
+ .io_offset = 0x00000000UL,
+ .mem_offset = 0x00000000UL
+};
+
+
+/* VFD-SPI registers */
+struct tFPanel_regs {
+ u32 rSVFDControl; /* control register */
+ u32 rSVFDStart; /* start register */
+ u32 rSVFDFifo; /* Fifo register */
+ u32 rSVFDKeyData; /* key data register */
+ u32 rSVFDManReadData; /* manual read data register */
+ u32 rSVFDReadCmd; /* read command register */
+ u32 rSVFDStatus; /* status register */
+ u32 rSVFDIntStat; /* interrupt status register */
+ u32 rSVFDIntEnable; /* interrupt enable register */
+};
+
+/*---------- Constants ------------ */
+
+/*---------- Externals ------------ */
+
+/*---------- Temporary Fixes ------------ */
+static inline u8 fix_readb(u8 *addr)
+{
+ u32 temp = (u32)addr ^ 3;
+ u8 *ptr;
+ ptr = (u8 *)temp;
+ return readb(ptr);
+}
+static inline u16 fix_readw(u16 *addr)
+{
+ u32 temp = (u32)addr ^ 2;
+ u16 *ptr;
+ ptr = (u16 *)temp;
+ return readw(ptr);
+}
+static inline u32 fix_readl(u32 *addr)
+{
+ return readl(addr);
+}
+
+static inline void fix_writeb(u8 val, u8 *addr)
+{
+ u32 temp = (u32)addr ^ 3;
+ u8 *ptr;
+ ptr = (u8 *)temp;
+ writeb(val, ptr);
+}
+static inline void fix_writew(u16 val, u16 *addr)
+{
+ u32 temp = (u32)addr ^ 2;
+ u16 *ptr;
+ ptr = (u16 *)temp;
+ writew(val, ptr);
+}
+static inline void fix_writel(u32 val, u32 *addr)
+{
+ writel(val, addr);
+}
+
+/* Convenience functions for performing logical operations on device
+ * registers */
+static void writel_or(u32 v, u32 *addr)
+{
+ writel(readl(addr) | v, addr);
+}
+
+static void writel_and(u32 v, u32 *addr)
+{
+ writel(readl(addr) & v, addr);
+}
+
+
+#ifdef PCIE_PLL_FIX
+
+ static struct tTBRegs *TB_RegsPtr;
+ static unsigned int scr_data_in[kSCR_DEPTH];
+
+
+/*******************************************************************************
+ * asic_pcie_reset
+ *
+ * If the box is a Zeus 1.0 box and the PHY layer's PLL has not acheived lock,
+ * then load the PLL with the correct value and then reset it. There is no way
+ * to reset the PHY layer by a conventional register command. Therefore, this
+ * backdoor method using the testbus to control the jtag port has been used.
+ * PCIe PHY layer to be reset after new PLL value has been loaded.
+ *
+ *
+
******************************************************************************/
+void asic_shift_clk(void)
+{
+ /* clock low */
+ writel_and(0xFFFFFFFD, &TB_RegsPtr->TEST_BUS_GPIO);
+ pcie_uSecDelay(20);
+ /* clock high */
+ writel_or(0x2, &TB_RegsPtr->TEST_BUS_GPIO);
+ pcie_uSecDelay(20);
+}
+
+
+void asic_shift_in(void)
+{
+ int i;
+
+ writel_or(0x30, &TB_RegsPtr->TEST_BUS_GPIO); /* Set SCR_OPCODE to a 3 */
+ for (i = kSCR_DEPTH-1; i >= 0; i--) {
+ if (scr_data_in[i])
+ /* Set SCR_IN high */
+ writel_or(0x4, &TB_RegsPtr->TEST_BUS_GPIO);
+ else
+ /* Set SCR_IN lo */
+ writel_and(0xFFFFFFFB, &TB_RegsPtr->TEST_BUS_GPIO);
+ asic_shift_clk();
+ }
+ /* Set SCR_OPCODE to 2'b10 */
+ writel_and(0xFFFFFFEF, &TB_RegsPtr->TEST_BUS_GPIO);
+ asic_shift_clk();
+ /* Set SCR_OPCODE to zero */
+ writel_and(0xFFFFFFCF, &TB_RegsPtr->TEST_BUS_GPIO);
+}
+
+void asic_phy_reset(void)
+{
+ int i;
+
+ /* Enable OEs */
+ writel_or(0x17 | 0x107F00, &TB_RegsPtr->TEST_BUS_GPIO_CTL);
+ /* Set lower bits to zero */
+ writel_and(0xFFFFF80, &TB_RegsPtr->TEST_BUS_GPIO);
+ /* Set mode bit */
+ writel_or(0x8, &TB_RegsPtr->TEST_BUS_GPIO);
+
+ for (i = kSCR_DEPTH-1; i >= 0; i--)
+ scr_data_in[i] = 0;
+
+ scr_data_in[kSCR_DEPTH-93] = 1;
+ scr_data_in[kSCR_DEPTH-94] = 1;
+
+ asic_shift_in();
+
+ /* Clear mode bit */
+ writel_and(0xFFFFFFF7, &TB_RegsPtr->TEST_BUS_GPIO);
+
+}
+
+void asic_write_jtag(unsigned int tms, unsigned int tdi)
+{
+ /* drive bit 13 low (clk) */
+ writel_and(0xFFFFDFFF, &TB_RegsPtr->TEST_BUS_GPIO);
+
+ if (tms) /* set tms */
+ writel_or(0x2, &TB_RegsPtr->TEST_BUS_GPIO);
+ else /* clear tms */
+ writel_and(0xFFFFFFFD, &TB_RegsPtr->TEST_BUS_GPIO);
+
+ if (tdi) /* set tdi */
+ writel_or(0x4, &TB_RegsPtr->TEST_BUS_GPIO);
+ else /* clear tdi */
+ writel_and(0xFFFFFFFB, &TB_RegsPtr->TEST_BUS_GPIO);
+
+ pcie_uSecDelay(20);
+ /* drive bit 13 high (clk) */
+ writel_or(0x00002000, &TB_RegsPtr->TEST_BUS_GPIO);
+ pcie_uSecDelay(20);
+}
+
+
+void asic_setup_jtag(unsigned int value)
+
+{
+ int i;
+
+ writel(0x17 | 0x300600, &TB_RegsPtr->TEST_BUS_GPIO_CTL);
+
+ /*Select Controller 0 */
+ /* drive bit 12, 13, 1, 2 low */
+ writel_and(0xFFFFCFF9, &TB_RegsPtr->TEST_BUS_GPIO);
+ pcie_uSecDelay(20);
+ writel_or(0x00000004, &TB_RegsPtr->TEST_BUS_GPIO); /* tdI = 1 */
+ pcie_uSecDelay(20);
+ writel_or(0x00002000, &TB_RegsPtr->TEST_BUS_GPIO); /* CLK = 1 */
+ pcie_uSecDelay(20);
+ writel_and(0xFFFFDFFF, &TB_RegsPtr->TEST_BUS_GPIO); /* CLK = 0 */
+ pcie_uSecDelay(20);
+ writel_or(0x00001000, &TB_RegsPtr->TEST_BUS_GPIO); /* trstn = 1 */
+ writel_and(0xFFFFFFFB, &TB_RegsPtr->TEST_BUS_GPIO); /* tdi = 0 */
+ pcie_uSecDelay(20);
+ writel_or(0x00002000, &TB_RegsPtr->TEST_BUS_GPIO); /* CLK = 1 */
+ pcie_uSecDelay(20);
+ writel_and(0xFFFFDFFF, &TB_RegsPtr->TEST_BUS_GPIO); /* CLK = 0 */
+
+ asic_write_jtag(1, 0);
+ asic_write_jtag(1, 0);
+ asic_write_jtag(1, 0);
+ asic_write_jtag(0, 0);
+ asic_write_jtag(1, 0);
+ asic_write_jtag(1, 0);
+ asic_write_jtag(0, 0);
+ asic_write_jtag(0, 0);
+ asic_write_jtag(0, 0);
+ asic_write_jtag(0, 0);
+ asic_write_jtag(0, 0);
+ asic_write_jtag(0, 1);
+ asic_write_jtag(1, 0);
+ asic_write_jtag(1, 0);
+ asic_write_jtag(0, 0);
+ asic_write_jtag(1, 0);
+ asic_write_jtag(0, 0);
+ asic_write_jtag(0, 0);
+
+ for (i = 0; i < 28 ; i++)
+ asic_write_jtag(0, 0);
+
+ asic_write_jtag(0, value);
+ for (i = 0; i < 75 ; i++)
+ asic_write_jtag(0, 0);
+
+ asic_write_jtag(1, 0);
+ asic_write_jtag(1, 0);
+ asic_write_jtag(0, 0);
+}
+
+void asic_pcie_reset(void)
+{
+ asic_setup_jtag(1);
+ asic_phy_reset();
+ asic_setup_jtag(0);
+}
+
+#endif
+
+
+/*******************************************************************************
+
*******************************************************************************
+ * PCIE General Interface
+
*******************************************************************************
+
*******************************************************************************
+
*******************************************************************************
+ * asic_pcie_init
+ *
+ * This API is called at power up and therefore must be exposed to other
+ * modules.
+ *
+ * Parameters - None
+ *
+ * Return Value - 0 or error
+ *
+ * Description:
+ * asic_pcie_init initializes the ASIC' PCI Express registers, obtains an IRQ
+ * from the Linux Kernel and registers the controller with the PCI System
+ * Software.
+
******************************************************************************/
+int asic_pcie_init(void)
+{
+ unsigned int timeout_count;
+ int i;
+
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT,
+ "%s:%s:asic_pcie_init called.\n", pcieModule_Name,
+ __func__);
+
+ if (!platform_supports_pcie())
+ return -1;
+
+ /*init spinlock */
+ spin_lock_init(&PCIE_lock);
+
+ /*map ASIC LS timer register */
+ timerptr = (u32 *) (asic_reg_addr(Free_Running_Ctr_Lo));
+ if (timerptr == 0) {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s: failed to get timer register mapping\n",
+ pcieModule_Name, __func__);
+ return -1;
+ }
+
+ /*map the registers */
+ PCIE_RegsPtr = (struct tPCIERegs *)(asic_reg_addr(PCIe_Regs));
+
+ if (PCIE_RegsPtr == 0) {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s: failed to get register mapping\n",
+ pcieModule_Name, __func__);
+ return -1;
+ }
+
+ /*--------------- Hw initialization begins here ------------------- */
+ /*reset ethernet chip */
+ if (pcie_reset_ethernet() == -1) {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s: failed to reset ethernet chip\n",
+ pcieModule_Name, __func__);
+ return -1;
+ }
+
+#ifdef PCIE_PLL_FIX
+ /* if PCIE_PLL_FIX is defined, then apply workaround to allow
+ * PCIe PHY layer to be reset after new PLL value has been loaded.
+ * subsequent versions of Zeus will have proper PLL default value
+ * set so that this will not be necessary. */
+
+ TB_RegsPtr = (struct tTBRegs *)(asic_reg_addr(Test_Bus));
+
+ if (TB_RegsPtr == 0) {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s: failed to get TESTBUS register mapping\n",
+ pcieModule_Name, __func__);
+ return -1;
+ }
+
+ {
+ int asicVersion;
+
+ /* read CHIPVER0 Zeus register */
+ asicVersion = (int)asic_read(CHIPVER0);
+
+ /* if Zeus 1.0 */
+ if (asicVersion == 0x11) {
+ /* if PLL is not locked, then apply workaround */
+ if ((readl(&PCIE_RegsPtr->PCIX_PHY_READ_BACK) &
+ kPCIX_PHY_READ_BACK_Ready) == 0) {
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT,
+ "%s:%s:Applying PCIe PHY PLL "
+ "workaround\n", pcieModule_Name,
+ __func__);
+
+ /* load correct PHY PLL value */
+ writel(0x19232300,
+ &PCIE_RegsPtr->PCIX_PHY_CONT_DATA1);
+
+ /* reset PHY layer */
+ pcie_delay(10);
+ asic_pcie_reset();
+ }
+ }
+ }
+#endif
+
+
+ /* Check PLL Lock */
+ timeout_count = 0;
+ while ((readl(&PCIE_RegsPtr->PCIX_PHY_READ_BACK) &
+ kPCIX_PHY_READ_BACK_PllLock) == 0) {
+ timeout_count += 1;
+ if (timeout_count == 1000)
+ break;
+ pcie_delay(1);
+ }
+
+ if (readl(&PCIE_RegsPtr->PCIX_PHY_READ_BACK) &
+ kPCIX_PHY_READ_BACK_PllLock)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "%s:%s: PLL lock.\n",
+ pcieModule_Name, __func__);
+ else {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s: PLL NOT LOCKED.\n", pcieModule_Name,
+ __func__);
+ PCIE_RegsPtr = 0;
+ return -1;
+ }
+
+ /* Check PHY Ready */
+ timeout_count = 0;
+ while ((readl(&PCIE_RegsPtr->PCIX_PHY_READ_BACK)
+ & kPCIX_PHY_READ_BACK_Ready)
+ == 0) {
+ timeout_count += 1;
+ if (timeout_count == 1000)
+ break;
+ pcie_delay(1);
+ }
+
+
+ if (readl(&PCIE_RegsPtr->PCIX_PHY_READ_BACK) &
+ kPCIX_PHY_READ_BACK_Ready)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT,
+ "%s:%s: PHY ready.\n", pcieModule_Name, __func__);
+ else {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT, "%s:%s: PHY not ready.\n",
+ pcieModule_Name, __func__);
+ PCIE_RegsPtr = 0;
+ return -1;
+ }
+
+ /* set port link control. Set link to be x1. (Zeus undocumented
+ * register) */
+ writel_and(0x0000FFFF, &PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[452]);
+ writel_or(0x00010000, &PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[452]);
+
+ /*All is well with the PHY, Set the control register */
+ writel(kPCIX_CTL1_PCIE_FUNC0 | kPCIX_CTL1_PCIE_ROOT_COMPLEX |
+ kPCIX_CTL1_PCIE_SEL_CLOCK, &PCIE_RegsPtr->PCIX_CTL1);
+
+ writel_or(kPCIX_CTL1_PCIE_LTSSM, &PCIE_RegsPtr->PCIX_CTL1);
+ pcie_delay(100);
+
+ /* verify data link layer up */
+ timeout_count = 0;
+ while ((readl(&PCIE_RegsPtr->PCIX_RDLH_LINK) &
+ kPCIX_RDLH_LINK_RdlhUp) == 0) {
+ timeout_count += 1;
+ if (timeout_count == 1000)
+ break;
+ pcie_delay(1);
+ }
+
+
+ if (readl(&PCIE_RegsPtr->PCIX_RDLH_LINK) & kPCIX_RDLH_LINK_RdlhUp)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT,
+ "%s:%s: Data Link Layer up.\n", pcieModule_Name,
+ __func__);
+ else {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s: Data Link Layer not available.\n",
+ pcieModule_Name, __func__);
+ PCIE_RegsPtr = 0;
+ return -1;
+ }
+
+ /* Going to map target space, map 8M, Zeus spec says we have 16 meg but
+ * can only get to 8M because of register limitations
+ * (limit to 8MB because HW only carries 23 bits)
+ * Memory Space from 0x08000000 - 0x083FFFFF */
+ writel(0x00000000, &PCIE_RegsPtr->PCIX_T3TARG_BASE0);
+ /* 4 MB at PCIe add 0x08000000, Zeus add = 0x08000000 */
+ writel(0x08000000 | 0x16, &PCIE_RegsPtr->PCIX_T3TARG_WIN0);
+
+ /* I/O Space from 0x08400000 - 0x087FFFFF (ORed bit 23 is I/O enable */
+ writel(0x00400000 | 0x00800000, &PCIE_RegsPtr->PCIX_T3TARG_BASE1);
+ /* 4 MB at PCIe add 0x08400000, Zeus add = 0x08400000 */
+ writel(0x08400000 | 0x16, &PCIE_RegsPtr->PCIX_T3TARG_WIN1);
+
+ /* T3 init config */
+ writel(0x00000000, &PCIE_RegsPtr->PCIX_ACC_BAR0[4]); /* Reset BAR 0 */
+ writel(0x00000000, &PCIE_RegsPtr->PCIX_ACC_BAR0[5]); /* Reset BAR 1 */
+
+ /* BAR0 - Zeus space at 0x00000000 in PCIe space */
+ writel(0x40000000, &PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[4]);
+ /* BAR1 - Unused */
+ writel(0x0, &PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[5]);
+ /* Mem Limit/Mem Base (0x00000000 - 0x00000000) */
+ writel(0x00000000, &PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[8]);
+ /* Bus Master/Memory Enable */
+ writel_or(0x6, &PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[1]);
+
+ /* map all of memory for PCIE */
+ /*0x00000000 - 0x7FFFFFFFF) */
+ writel(0x00000000 | 31, &PCIE_RegsPtr->PCIX_FUNC0_USERBAR0);
+
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s: PCIE Bus num %d, device num = %d\n.\n",
+ pcieModule_Name, __func__, PCIE_RegsPtr->PCIX_CFG_PBUS_NUM,
+ PCIE_RegsPtr->PCIX_CFG_PBUS_DEVNUM);
+
+
+ writel(0, &PCIE_RegsPtr->PCIX_CLIENT0_TLPTC);
+ writel(1, &PCIE_RegsPtr->PCIX_CLIENT0_TLPATTR);
+ writel(0, &PCIE_RegsPtr->PCIX_CLIENT0_TLPFUN);
+
+ /*clear the interrupt counters */
+ for (i = 0; i < 32; i++) {
+ intcountslow[i] = 0;
+ intcountshigh[i] = 0;
+ }
+
+ /*unmask the interrupts that we care about (overall interrupt enable
+ * will be set when IRQ requested) */
+ writel(~(kPCIX_IntLow_cfg_sys_err_rc0 |
+ kPCIX_IntLow_radm_cpl_timeout |
+ kPCIX_IntLow_cfg_aer_rc_err_int0 |
+ kPCIX_IntLow_radm_inta_asserted |
+ kPCIX_IntLow_radm_intb_asserted |
+ kPCIX_IntLow_radm_intc_asserted |
+ kPCIX_IntLow_radm_intd_asserted |
+ kPCIX_IntLow_radm_correctable_err |
+ kPCIX_IntLow_radm_nonfatal_err |
+ kPCIX_IntLow_radm_pm_pme |
+ kPCIX_IntLow_radm_cpl_dllp_abort |
+ kPCIX_IntLow_radm_cpl_tlp_abort |
+ kPCIX_IntLow_radm_cpl_ecrc_err |
+ kPCIX_IntLow_radm_fatal_err),
+ &PCIE_RegsPtr->PCIX_MASKRISE_LOW);
+
+ writel(~(kPCIX_IntHigh_radm_inta_deasserted |
+ kPCIX_IntHigh_radm_intb_deasserted |
+ kPCIX_IntHigh_radm_intc_deasserted |
+ kPCIX_IntHigh_radm_pm_to_ack |
+ kPCIX_IntHigh_radm_cpl_error_int |
+ kPCIX_IntHigh_radm_intd_deasserted),
+ &PCIE_RegsPtr->PCIX_MASKRISE_HIGH);
+
+ /*register controller */
+#if !LOADABLE
+ register_pci_controller(&asic_controller);
+#endif /*!LOADABLE */
+
+ PCIE_initialized = 1;
+ return 0;
+}
+EXPORT_SYMBOL(asic_pcie_init);
+
+
+
+
+/*******************************************************************************
+ * asic_pcie_read_config
+ *
+ * This API is called to read PCI Express Configuration Space registers. It is
+ * exposed to the PCI System Software.
+ *
+ * Parameters:
+ * *bus - pointer to pci_bus structure
+ * devfn - device function number
+ * where - configuration space register number
+ * size - byte, word, or doubleword
+ * *val - pointer to memory where read data is to be stored
+ *
+ * Return Value:
+ * returns: PCIBIOS_SUCCESSFUL if successful otherwise
+ * PCIBIOS_BAD_REGISTER_NUMBER or -1
+ *
+ * Description:
+ * asic_pcie_read_config is called to read PCI Express Space Configuration
+ * registers. Configuration reads may be for byte, word or double word
accesses.
+ *
+ *
+
******************************************************************************/
+int asic_pcie_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 *val)
+{
+ u32 data = 0;
+ u32 rtn = 0;
+ unsigned long flags = 0;
+ int offset = where & 3;
+ u32 type;
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s:asic_pcie_read_config called (%x, %x, %x, %x).\n",
+ pcieModule_Name, __func__, bus->number, devfn, where, size);
+
+ if (PCIE_initialized == 0)
+ return -1;
+
+ /*error checks */
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ spin_lock_irqsave(&PCIE_lock, flags);
+
+ if (bus->number == 255) {
+ /*root complex, only one device and function in root complex */
+ if (devfn == 0)
+ /*read the 32 bits directly */
+ data = readl(&PCIE_RegsPtr->
+ PCIX_CFG_SPACE_FUNC0[where >> 2]);
+ else
+ data = 0xFFFFFFFF;
+ } else {
+ /* For now only one bus, and one device on that bus and one
+ * function on that device (0, 0, 0). If we can ever get the
+ * ethernet chip to not respond to everything we can lose this
+ * check */
+ if ((bus->number == 0) && (devfn == 0)) {
+ /*not root complex, type 0 or 1 msg */
+ if (bus->number == 0)
+ type = kPCIE_RC_CFG_SETUP1_TYPE0;
+ else
+ type = kPCIE_RC_CFG_SETUP1_TYPE1;
+
+ /*read 32 bits of data */
+ rtn = pcie_rc_cfg_read32(type, bus->number,
+ PCI_SLOT(devfn), PCI_FUNC(devfn), where & ~0x3,
+ &data);
+ } else
+ data = 0xFFFFFFFF;
+ }
+
+ /*check for error */
+ if (rtn == -1) {
+ spin_unlock_irqrestore(&PCIE_lock, flags);
+ return PCIBIOS_SET_FAILED;
+ }
+
+ /*right justify the data */
+ switch (size) {
+ case 1:
+ if (offset == 3)
+ *val = (data >> 24) & 0xFF;
+ if (offset == 2)
+ *val = (data >> 16) & 0xFF;
+ if (offset == 1)
+ *val = (data >> 8) & 0xFF;
+ if (offset == 0)
+ *val = data & 0xFF;
+ break;
+
+ case 2:
+ if (offset == 2)
+ *val = (data >> 16) & 0xFFFF;
+ if (offset == 0)
+ *val = data & 0xFFFF;
+ break;
+
+ case 4:
+ *val = data;
+ break;
+ }
+
+
+ spin_unlock_irqrestore(&PCIE_lock, flags);
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s: READ PCI data %8x from bus %8x device %8x function "
+ "%8x register %8x size %d\n", pcieModule_Name, __func__,
+ *val, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where,
+ size);
+
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+
+
+/*******************************************************************************
+ * asic_pcie_write_config
+ *
+ * Parameters:
+ * *bus - pointer to pci_bus structure
+ * devfn - device function number
+ * where - configuration space register number
+ * size - byte, word, or doubleword
+ * val - data to be written
+ *
+ * Return Value:
+ * returns: PCIBIOS_SUCCESSFUL if successful otherwise
+ * PCIBIOS_BAD_REGISTER_NUMBER or -1
+ *
+ * Description:
+ * asic_pcie_write_config is called to write PCI Express Configuration Space
+ * registers. Configuration writes may be for byte, word or double word
+ * accesses.
+
******************************************************************************/
+int asic_pcie_write_config(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, u32 val)
+{
+ u32 data = 0;
+ u32 rtn = 0;
+ unsigned long flags = 0;
+ int offset = where & 3;
+ u32 type;
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s:asic_pcie_write_config called (%x, %x, %x, %x, %x).\n",
+ pcieModule_Name, __func__, bus->number, devfn, where, size,
+ val);
+
+ if (PCIE_initialized == 0)
+ return -1;
+
+ /*error checks */
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ spin_lock_irqsave(&PCIE_lock, flags);
+
+ if (bus->number == 255) {
+ /* root complex, only one device and function in root complex */
+ if (devfn != 0) {
+ spin_unlock_irqrestore(&PCIE_lock, flags);
+ return PCIBIOS_SET_FAILED;
+ }
+
+ /*read the register first */
+ data = readl(&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[where >> 2]);
+
+ /*clear old value or in the new one */
+ switch (size) {
+ case 1:
+ val = val & 0xFF;
+ if (offset == 3)
+ data = (data & 0x00FFFFFF) | (val << 24);
+ if (offset == 2)
+ data = (data & 0xFF00FFFF) | (val << 16);
+ if (offset == 1)
+ data = (data & 0xFFFF00FF) | (val << 8);
+ if (offset == 0)
+ data = (data & 0xFFFFFF00) | val ;
+ break;
+
+ case 2:
+ val = val & 0xFFFF;
+ if (offset == 2)
+ data = (data & 0x0000FFFF) | (val << 16);
+ if (offset == 0)
+ data = (data & 0xFFFF0000) | val ;
+ break;
+
+ case 4:
+ data = val;
+ break;
+ }
+
+ /*write the new 32 bits */
+ writel(data, &PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[where >> 2]);
+ } else {
+ /*not root complex, type 0 or 1 msg */
+ if (bus->number == 0)
+ type = kPCIE_RC_CFG_SETUP1_TYPE0;
+ else
+ type = kPCIE_RC_CFG_SETUP1_TYPE1;
+
+
+ /*read the register first */
+ rtn = pcie_rc_cfg_read32(type, bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where & ~0x3, &data);
+
+ /*check for error */
+ if (rtn == -1) {
+ spin_unlock_irqrestore(&PCIE_lock, flags);
+ return PCIBIOS_SET_FAILED;
+ }
+
+ /*clear old value or in the new one */
+ switch (size) {
+ case 1:
+ val = val & 0xFF;
+ if (offset == 3)
+ data = (data & 0x00FFFFFF) | (val << 24);
+ if (offset == 2)
+ data = (data & 0xFF00FFFF) | (val << 16);
+ if (offset == 1)
+ data = (data & 0xFFFF00FF) | (val << 8);
+ if (offset == 0)
+ data = (data & 0xFFFFFF00) | val ;
+ break;
+
+ case 2:
+ val = val & 0xFFFF;
+ if (offset == 2)
+ data = (data & 0x0000FFFF) | (val << 16);
+ if (offset == 0)
+ data = (data & 0xFFFF0000) | val ;
+ break;
+
+ case 4:
+ data = val;
+ break;
+ }
+
+ /*write the new 32 bits */
+ pcie_rc_cfg_write32(type, bus->number, PCI_SLOT(devfn),
+ PCI_FUNC(devfn), where & ~0x3, &data);
+ }
+
+ spin_unlock_irqrestore(&PCIE_lock, flags);
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s: WROTE PCI data %8x to bus %8x device %8x function "
+ "%8x register %8x size %d\n", pcieModule_Name, __func__,
+ val, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where,
+ size);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+
+
+/*******************************************************************************
+ * asic_pcie_process_interrupt
+ *
+ * Parameters:
+ * Irq - interrupt number
+ * tbd - pointer to controller specific data (specifics tbd)
+ * pointer to register contents prior to interrupt
+ *
+ * Return Value:
+ * returns: IRQ_HANDLED or IRQ_NONE
+ *
+ * Description:
+ * asic_pcie_process_interrupt is called to process PCI Express interrupts.
+ *
+
******************************************************************************/
+static irqreturn_t asic_pcie_process_interrupt(int irq, void *dev_id)
+{
+ int i;
+ u32 bit;
+
+ if (PCIE_initialized == 0)
+ return IRQ_NONE;
+
+ /*disable all pcie interrupts */
+ writel_and(~kPCIX_CTL1_PCI_ENAB_INTS, &PCIE_RegsPtr->PCIX_CTL1);
+
+ /*save the system data */
+ intdata[0] = (u32)irq;
+ intdata[1] = (u32)dev_id;
+
+ /*save interrupts pending */
+ intdata[2] = readl(&PCIE_RegsPtr->PCIX_RISING_EVENT_LOW);
+ intdata[3] = readl(&PCIE_RegsPtr->PCIX_RISING_EVENT_HIGH);
+
+ /*clear the pending interrupts (pulse high then low) */
+ writel(intdata[2], &PCIE_RegsPtr->PCIX_CLRRISE_LOW);
+ writel(0, &PCIE_RegsPtr->PCIX_CLRRISE_LOW);
+ writel(intdata[3], &PCIE_RegsPtr->PCIX_CLRRISE_HIGH);
+ writel(0, &PCIE_RegsPtr->PCIX_CLRRISE_HIGH);
+
+ /*adjust interrupt counters */
+ bit = 0x01;
+ for (i = 0; i < 32; i++) {
+ if (intdata[2] & bit)
+ intcountslow[i]++;
+ if (intdata[3] & bit)
+ intcountshigh[i]++;
+ bit = bit << 1;
+ }
+
+ /*enable all pcie interrupts */
+ writel_or(kPCIX_CTL1_PCI_ENAB_INTS, &PCIE_RegsPtr->PCIX_CTL1);
+
+
+ return IRQ_HANDLED;
+}
+
+
+
+/*******************************************************************************
+ * asic_pcie_map_irq
+ *
+ * Parameters:
+ * *dev - pointer to a pci_dev structure (not used)
+ * slot - slot number (not used)
+ * pin - pin number (not used)
+ *
+ * Return Value:
+ * Returns: IRQ number (always the PCI Express IRQ number)
+ *
+ * Description:
+ * asic_pcie_map_irq will return the IRQ number of the PCI Express interrupt.
+ *
+
******************************************************************************/
+int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s:asic_pcie_map_irq called(%x, %x, %x).\n",
+ pcieModule_Name, __func__, (u32)dev, slot, pin);
+
+ return kIrq_PCIExp;
+}
+EXPORT_SYMBOL(asic_pcie_map_irq);
+
+
+
+/*******************************************************************************
+ * pcie_rc_cfg_read32
+ *
+ * Read 32 bit value from non RC config space
+ *
+ * Parameters:
+ * type - type 0 or 1 header
+ * busnum - bus number
+ * devnum - device number
+ * func_num - function number
+ * reg_num - register number
+ * *dataptr - pointer to where data value should be stored
+ *
+ * Return Value: 0 success -1 error
+ *
+
******************************************************************************/
+u32 pcie_rc_cfg_read32(u32 type, u32 busnum, u32 devnum, u32 func_num,
+ u32 reg_num, u32 *dataptr)
+{
+
+ unsigned int temp;
+ unsigned int stat;
+ u32 rtn = 0;
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s:pcie_rc_cfg_read32 called (%x, %x, %x, %x, %x, %x).\n",
+ pcieModule_Name, __func__, type, busnum, devnum, func_num,
+ reg_num, *dataptr);
+
+ /*enter RC mode */
+ writel_and(~kPCIX_CTL1_PCIE_TLP_ENABLE, &PCIE_RegsPtr->PCIX_CTL1);
+ writel(1, &PCIE_RegsPtr->PCIE_RC_CFG_MODE);
+
+ /*setup for read */
+ temp = (reg_num) | (func_num<<16) | (devnum<<19) | (busnum<<24);
+ writel(temp, &PCIE_RegsPtr->PCIE_RC_CFG_SETUP2);
+ writel(kPCIE_RC_CFG_SETUP1_CFG_ENAB_ALL_BYTES | (type<<2) |
+ kPCIE_RC_CFG_SETUP1_CFG_READ,
+ &PCIE_RegsPtr->PCIE_RC_CFG_SETUP1);
+
+ /*read and wait for completion */
+ stat = readl(&PCIE_RegsPtr->PCIE_RC_CFG_STAT);
+ while ((stat & 6) == 0)
+ stat = readl(&PCIE_RegsPtr->PCIE_RC_CFG_STAT);
+
+ /*successful? */
+ if (stat & 4) {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s:pcie_rc_cfg_read32 timeout.\n",
+ pcieModule_Name, __func__);
+ rtn = -1;
+ }
+
+ *dataptr = readl(&PCIE_RegsPtr->PCIE_RC_CFG_CPL_DATA);
+
+ /* leave RC config mode */
+ writel(0, &PCIE_RegsPtr->PCIE_RC_CFG_MODE);
+ writel_or(kPCIX_CTL1_PCIE_TLP_ENABLE, &PCIE_RegsPtr->PCIX_CTL1);
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s:pcie_rc_cfg_read32 read %x.\n", pcieModule_Name,
+ __func__, *dataptr);
+ return rtn;
+}
+
+
+
+
+/*******************************************************************************
+ * pcie_rc_cfg_write32
+ *
+ * Write 32 bit value from non RC config space
+ *
+ * Parameters:
+ * type - type 0 or 1 header
+ * busnum - bus number
+ * devnum - device number
+ * func_num - function number
+ * reg_num - register number (word based!)
+ * *dataptr - pointer to where data value should be stored
+
+ * Return Value: 0 success -1 error
+ *
+
******************************************************************************/
+u32 pcie_rc_cfg_write32(u32 type, u32 busnum, u32 devnum, u32 func_num,
+ u32 reg_num, u32 *dataptr)
+{
+
+ unsigned int temp;
+ u32 rtn = 0;
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s:%s:pcie_rc_cfg_write32 called (%x, %x, %x, %x, %x, %x).\n",
+ pcieModule_Name, __func__, type, busnum, devnum, func_num,
+ reg_num, *dataptr);
+
+ /*enter RC mode */
+ writel_and(~kPCIX_CTL1_PCIE_TLP_ENABLE, &PCIE_RegsPtr->PCIX_CTL1);
+ writel(1, &PCIE_RegsPtr->PCIE_RC_CFG_MODE);
+
+ /*setup for write */
+ temp = (reg_num) | (func_num<<16) | (devnum<<19) | (busnum<<24);
+ writel(temp, &PCIE_RegsPtr->PCIE_RC_CFG_SETUP2);
+ writel(*dataptr, &PCIE_RegsPtr->PCIE_RC_CFG_WRITE_DATA);
+
+ /*write the data */
+ writel(kPCIE_RC_CFG_SETUP1_CFG_ENAB_ALL_BYTES | (type<<2) |
+ kPCIE_RC_CFG_SETUP1_CFG_WRITE,
+ &PCIE_RegsPtr->PCIE_RC_CFG_SETUP1);
+
+ /* leave RC config mode */
+ writel(0, &PCIE_RegsPtr->PCIE_RC_CFG_MODE);
+ writel_or(kPCIX_CTL1_PCIE_TLP_ENABLE, &PCIE_RegsPtr->PCIX_CTL1);
+
+ return rtn;
+}
+
+
+
+
+/*******************************************************************************
+ * pcie_uSecDelay
+ *
+ * delay number of us passed
+ *
+ * Parameters:
+ * us - number of microseconds
+ *
+ * Return Value: none
+ *
+
******************************************************************************/
+static void pcie_uSecDelay(u32 us)
+{
+ u32 start, stop, adder;
+
+ /*check for no delay */
+ if (us == 0)
+ return;
+
+ /*read timer and calculate end time */
+ start = *timerptr;
+ stop = start + (us * 3); /* rounded down from 3.375 */
+ adder = 0;
+
+ /*check for wrap */
+ if (stop < start) {
+ stop += 0x7FFFFFFF;
+ adder = 0x7FFFFFFF;
+ }
+
+loop:
+ if (stop > (*timerptr + adder))
+ goto loop;
+}
+
+
+
+
+/*******************************************************************************
+ * pcie_delay
+ *
+ * delay number of ms passed
+ *
+ * Parameters:
+ * ms - number of milliseconds
+ *
+ * Return Value: none
+ *
+
******************************************************************************/
+static void pcie_delay(u32 ms)
+{
+ u32 start, stop, adder;
+
+ /*check for no delay */
+ if (ms == 0)
+ return;
+
+ /*read timer and calculate end time */
+ start = *timerptr;
+ stop = start + (ms * 3375);
+ adder = 0;
+
+ /*check for wrap */
+ if (stop < start) {
+ stop += 0x7FFFFFFF;
+ adder = 0x7FFFFFFF;
+ }
+
+loop:
+ if (stop > (*timerptr + adder))
+ goto loop;
+}
+
+
+
+
+/*******************************************************************************
+ * pcie_reset_ethernet
+ *
+ * reset ethernet chip
+ *
+ * Parameters: none
+ *
+ * Return Value: -1 error, otherwise 0
+ *
+
******************************************************************************/
+static int pcie_reset_ethernet(void)
+{
+ /* virtual pointer to register region */
+ struct tFPanel_regs *pFPanelRegs;
+
+ /*Map VFD registers for ethernet reset line */
+ pFPanelRegs = (struct tFPanel_regs *)(asic_reg_addr(Front_Panel));
+ if (pFPanelRegs == 0) {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s: failed to remap reset register\n",
+ pcieModule_Name, __func__);
+ return -1;
+ }
+
+ writel(0x45, &pFPanelRegs->rSVFDFifo);
+ writel(0x107, &pFPanelRegs->rSVFDFifo);
+ writel(0x1, &pFPanelRegs->rSVFDStart);
+
+ pcie_delay(140);
+
+ writel(0x45, &pFPanelRegs->rSVFDFifo);
+ writel(0x10F, &pFPanelRegs->rSVFDFifo);
+ writel(0x1, &pFPanelRegs->rSVFDStart);
+
+ return 0;
+}
+
+
+
+
+/*******************************************************************************
+
*******************************************************************************
+ * DEBUG/INFORMATION Elements
+
*******************************************************************************
+
*******************************************************************************
+
*******************************************************************************
+ * pcie_Init
+ *
+ * API Type - Kernel public
+ *
+ * Parameters - None
+ *
+ * Return Value - 0 or error
+ *
+ * Description:
+ * This is expected to be called from the Linux kernel during module
+ * installation. It has no functionality except to init the global semaphore
+ *
+
******************************************************************************/
+static int __init pcie_Init(void)
+{
+#if LOADABLE
+ int status = 0;
+
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "%s:%s:pcie_Init called.\n",
+ pcieModule_Name, __func__);
+
+ if (!platform_supports_pcie())
+ return -1;
+
+ /*init asic PCIE */
+ status = asic_pcie_init();
+ if (status != 0) {
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s:pcie_Init failed.\n", pcieModule_Name,
+ __func__);
+ return -EADDRINUSE;
+ }
+#else
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "%s:%s:pcie_Init called.\n",
+ pcieModule_Name, __func__);
+
+ if (!platform_supports_pcie())
+ return -1;
+
+#endif /*LOADABLE */
+
+
+ if (PCIE_initialized == 0)
+ return -1;
+
+
+ /*request the IRQ and enable interrupts if successful */
+ PCIE_irqrequest_pcie =
+ request_irq(kIrq_PCIExp, asic_pcie_process_interrupt,
+ IRQF_SHARED, "PCIE Interrupt", (void *)PCIE_RegsPtr);
+
+ if (PCIE_irqrequest_pcie != 0)
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT,
+ "%s:%s: failed to get IRQ (%x)\n", pcieModule_Name,
+ __func__, PCIE_irqrequest_pcie);
+ else {
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "%s:%s: Got IRQ (%x)\n",
+ pcieModule_Name, __func__, PCIE_irqrequest_pcie);
+
+ /*enable interrupts */
+ writel_or(kPCIX_CTL1_PCI_ENAB_INTS, &PCIE_RegsPtr->PCIX_CTL1);
+ }
+
+
+
+
+ /*Proc stuff */
+ PCIE_pProc = create_proc_entry(pcieModule_Name, S_IRUGO | S_IWUGO,
+ NULL);
+
+ if (PCIE_pProc != NULL) {
+ PCIE_pProc->read_proc = pcie_ReadProc;
+ PCIE_pProc->write_proc = pcie_WriteProc;
+ } else
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT, "%s:%s: proc not created\n",
+ pcieModule_Name, __func__);
+
+ return 0;
+}
+module_init(pcie_Init);
+
+
+/*******************************************************************************
+ * pcie_Finalize
+ *
+ * API Type - Kernel public.
+ *
+ * Parameters - None
+ *
+ * Return Value - None
+ *
+ * Description:
+ * This is expected to be called from the Linux kernel when the module is
+ * unloaded. It has no functionality.
+ *
+
******************************************************************************/
+static void __exit pcie_Finalize(void)
+{
+
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "%s:%s:pcie_Finalize called.\n",
+ pcieModule_Name, __func__);
+
+ /*free IRQ */
+ if (PCIE_irqrequest_pcie == 0)
+ free_irq(kIrq_PCIExp, 0);
+
+ /*remove proc entry */
+ if (PCIE_pProc != NULL)
+ remove_proc_entry(pcieModule_Name, NULL);
+}
+module_exit(pcie_Finalize);
+
+
+
+
+/*******************************************************************************
+ * pcie_WriteProc
+ *
+ * pfile - pointer to the return buffer
+ * pbuff - not used
+ * bytecnt - not used
+ * pdata - length of the return buffer
+ *
+ * bytes filled in the return buffer
+ *
+
******************************************************************************/
+static int pcie_WriteProc(struct file *pfile, const char __user *pbuff,
+ unsigned long bytecnt, void *data)
+{
+ u8 buffer[65];
+ int cnt;
+ u32 addr;
+ u32 *ioaddr;
+ int i, stat, index;
+ struct pci_bus pseudobus;
+ int busnumber, dev, fn, where, size, val;
+ int rtn;
+ int saveloglevel;
+ int rval, wval;
+ u8 byte;
+ u8 *byteptr;
+ u16 word;
+ u16 *wordptr;
+ u32 dword;
+ u32 *dwordptr;
+ u32 savemem;
+ u32 led;
+ struct tFPanel_regs *pFPanelRegs;
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT, "%s: pcie WriteProc \n",
+ pcieModule_Name);
+
+ /* get the buffer count, but limit it to 64 chars */
+ cnt = (bytecnt < 64) ? bytecnt : 64;
+
+ memset(buffer, 0, 65);
+
+ /* get the users buffer */
+ stat = copy_from_user(buffer, pbuff, cnt);
+ if (stat < 0)
+ return stat;
+
+ pr_info("STRING= %s \n", buffer);
+
+ /* if its the log level command then change the level */
+ if (!strncmp(buffer, "LogLevel=", 8)) {
+ sscanf(buffer, "LogLevel=%d", &LogLevel);
+
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT,
+ "%s: Noise log \n", pcieModule_Name);
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "%s: Info log \n",
+ pcieModule_Name);
+ SAPRINT(SA_SEVERE, SA_LOG_TO_PRINT, "%s: Severe log \n",
+ pcieModule_Name);
+ SAPRINT(SA_FATAL, SA_LOG_TO_PRINT, "%s: Fatal log \n",
+ pcieModule_Name);
+
+ return cnt;
+ }
+
+ /*set VFD ledn (ethernet reset is led4 (bit 3) */
+ if (!strncmp(buffer, "Z=", 2)) {
+ sscanf(buffer, "Z=%x", &led);
+ pFPanelRegs = (struct tFPanel_regs *)
+ (asic_reg_addr(Front_Panel));
+ writel(0x45, &pFPanelRegs->rSVFDFifo);
+ writel(0x100 | led, &pFPanelRegs->rSVFDFifo);
+ writel(0x1, &pFPanelRegs->rSVFDStart);
+ pr_info("set Led to %x\n", led);
+ return cnt;
+ }
+
+ /*reset ethernet */
+ if (!strncmp(buffer, "z=", 2)) {
+ pcie_reset_ethernet();
+ return cnt;
+ }
+
+ /*read register */
+ if (!strncmp(buffer, "R=", 2)) {
+ ioaddr = (u32 *)PCIE_RegsPtr;
+ sscanf(buffer, "R=%x", &index);
+ pr_info("Data at PCIe[%x]= %x\n", index, ioaddr[index]);
+ return cnt;
+ }
+
+ /*write register */
+ if (!strncmp(buffer, "W=", 2)) {
+ ioaddr = (u32 *)PCIE_RegsPtr;
+ sscanf(buffer, "W=%x %x", &index, &val);
+ pr_info("Writing data at PCIe[%x] to %x\n", index, val);
+ ioaddr[index] = val;
+ return cnt;
+ }
+
+ /*dump specific range of registers */
+ if (!strncmp(buffer, "D=", 2)) {
+ ioaddr = (u32 *)PCIE_RegsPtr;
+ saveloglevel = LogLevel;
+ LogLevel = SA_OFF;
+ sscanf(buffer, "D=%x %x", &index, &val);
+ for (i = 0; i < val; i++) {
+ pr_info("Data at PCIe[%x] %x\n", index,
+ ioaddr[index]);
+ index++;
+ }
+ LogLevel = saveloglevel;
+ return cnt;
+ }
+
+ /*dump all registers */
+ if (!strncmp(buffer, "d=", 2)) {
+ pcie_DumpRegs();
+ return cnt;
+ }
+
+ /*interrupt counters */
+ if (!strncmp(buffer, "N=", 2)) {
+ for (i = 0; i < 32; i++) {
+ if (intcountslow[i] != 0)
+ pr_info("Interrupt count low %d is %x\n", i,
+ intcountslow[i]);
+ }
+ for (i = 0; i < 32; i++) {
+ if (intcountshigh[i] != 0)
+ pr_info("Interrupt count high %d is %x\n", i,
+ intcountshigh[i]);
+ }
+ return cnt;
+ }
+
+ /*read config word */
+ if (!strncmp(buffer, "I=", 2)) {
+ sscanf(buffer, "I=%d %d %d %x %d", &busnumber, &dev, &fn,
+ &where, &size);
+ pseudobus.number = busnumber;
+ rtn = asic_pcie_read_config(&pseudobus, PCI_DEVFN(dev, fn),
+ where, size, &val);
+ if (rtn == PCIBIOS_SUCCESSFUL)
+ pr_info("Data at bus %d device %d function %d register "
+ "%x (size %d) was %x\n", busnumber, dev, fn,
+ where, size, (u32)val);
+ else
+ pr_err("asic_pcie_read_config failed (%d).\n", rtn);
+ return cnt;
+ }
+
+ /*write config word */
+ if (!strncmp(buffer, "O=", 2)) {
+ sscanf(buffer, "O=%d %d %d %x %d %x", &busnumber, &dev, &fn,
+ &where, &size, &val);
+ pseudobus.number = busnumber;
+ rtn = asic_pcie_write_config(&pseudobus, PCI_DEVFN(dev, fn),
+ where, size, val);
+ if (rtn == PCIBIOS_SUCCESSFUL)
+ pr_info("Data written to bus %d device %d function %d "
+ "register %x (size %d) was %x\n", busnumber,
+ dev, fn, where, size, (u32)val);
+ else
+ pr_err("asic_pcie_write_config failed (%d).\n", rtn);
+ return cnt;
+ }
+
+ /*enumerate bus */
+ if (!strncmp(buffer, "E=", 2)) {
+ saveloglevel = LogLevel;
+ LogLevel = SA_OFF;
+ sscanf(buffer, "E=%d", &busnumber);
+ pseudobus.number = busnumber;
+ for (dev = 0; dev < 32; dev++) {
+ rtn = asic_pcie_read_config(&pseudobus,
+ PCI_DEVFN(dev, 0), 0, 4, &val);
+ if (rtn == PCIBIOS_SUCCESSFUL)
+ pr_info("Data at bus %d device %d function 0 "
+ "register 0 (size 4) was %x\n",
+ busnumber, dev, (u32)val);
+ else
+ pr_err("asic_pcie_read_config failed (%d).\n",
+ rtn);
+ }
+ LogLevel = saveloglevel;
+ return cnt;
+ }
+
+ /*dump Config area */
+ if (!strncmp(buffer, "C=", 2)) {
+ saveloglevel = LogLevel;
+ LogLevel = SA_OFF;
+ sscanf(buffer, "C=%d %d %d", &busnumber, &dev, &fn);
+ pseudobus.number = busnumber;
+ where = 0;
+ pr_info("\n");
+ for (where = 0; where < 4096; where = where+4) {
+ if ((where & 0x1F) == 0x00)
+ pr_info("\n%08x ", where);
+ rtn = asic_pcie_read_config(&pseudobus,
+ PCI_DEVFN(dev, fn), where, 4, &val);
+ if (rtn == PCIBIOS_SUCCESSFUL)
+ pr_info(" %08x", (u32)val);
+ else
+ pr_info(" xxxxxxxx");
+ }
+ pr_info("\n");
+ LogLevel = saveloglevel;
+ return cnt;
+ }
+
+ /*dump Config area */
+ if (!strncmp(buffer, "S=", 2)) {
+ int ptr;
+
+ saveloglevel = LogLevel;
+ LogLevel = SA_OFF;
+ sscanf(buffer, "S=%d %d %d", &busnumber, &dev, &fn);
+ pseudobus.number = busnumber;
+ pr_info("Header:\n");
+ for (where = 0; where < 64; where = where+4) {
+ if ((where & 0x1F) == 0x00)
+ pr_info("\n%08x ", where);
+ rtn = asic_pcie_read_config(&pseudobus,
+ PCI_DEVFN(dev, fn), where, 4, &val);
+ if (rtn == PCIBIOS_SUCCESSFUL)
+ pr_info(" %08x", (u32)val);
+ else
+ pr_info(" xxxxxxxx");
+ }
+
+ /*follow the capabilities */
+ rtn = asic_pcie_read_config(&pseudobus, PCI_DEVFN(dev, fn),
+ 0x34, 1, &ptr);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ LogLevel = saveloglevel;
+ return cnt;
+ }
+
+ if (ptr != 0) {
+ while ((ptr != 0x100) && ((ptr & 0x03) == 0))
+ ptr = pcie_dumpcapability(busnumber, dev, fn,
+ ptr);
+
+ /*follow the extended capabilities */
+ ptr = 0x100;
+ while ((ptr != 0x1000) && ((ptr & 0x03) == 0))
+ ptr = pcie_dumpextendedcapability(busnumber,
+ dev, fn, ptr);
+ }
+
+ pr_info("\n");
+ LogLevel = saveloglevel;
+ return cnt;
+ }
+
+ /*Root Complex R/W test */
+ if (!strncmp(buffer, "T=", 2)) {
+ pr_info("Root Complex R/W test\n");
+ pseudobus.number = 255;
+
+ /*save old value */
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x20, 4, &val);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Setup failed\n");
+ return cnt;
+ }
+
+ /* bytewise test */
+ wval = 0x10;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x20, 1, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x20, 1, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_info("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ wval = 0x32;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x21, 1, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x21, 1, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ wval = 0x40;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x22, 1, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x22, 1,
+ &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ wval = 0x65;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x23, 1, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x23, 1, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+
+ /* 16 bit test */
+ wval = 0x9870;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x20, 2, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x20, 2,
+ &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ wval = 0xCBA0;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x22, 2, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x22, 2, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ /* 32 bit test */
+ wval = 0x77605540;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x20, 4, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x20, 4, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+
+ /*restore original value */
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x20, 4,
+ val);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Restore failed\n");
+ return cnt;
+ }
+
+
+ pr_info("Test passed\n");
+
+ return cnt;
+ }
+
+ /*Endpoint R/W test */
+ if (!strncmp(buffer, "t=", 2)) {
+ pr_info("Endpoint R/W test\n");
+
+ pseudobus.number = 0;
+
+ /*save old value */
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x14, 4, &val);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Setup failed\n");
+ return cnt;
+ }
+
+
+ /* bytewise test */
+ wval = 0x10;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x14, 1, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x14, 1, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ wval = 0x32;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x15, 1, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x15, 1, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ wval = 0x40;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x16, 1, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x16, 1, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ wval = 0x65;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x17, 1, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x17, 1, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+
+
+ /* 16 bit test */
+ wval = 0x9870;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x14, 2, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x14, 2, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+ wval = 0xCBA0;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x16, 2, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x16, 2, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+
+
+ /* 32 bit test */
+ wval = 0x77605540;
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x14, 4, wval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Write failed\n");
+ return cnt;
+ }
+ rtn = asic_pcie_read_config(&pseudobus, 0, 0x14, 4, &rval);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Read failed\n");
+ return cnt;
+ }
+ if (wval != rval) {
+ pr_err("Test failed (%x, %x)\n", wval, rval);
+ return cnt;
+ }
+
+
+ /*restore original value */
+ rtn = asic_pcie_write_config(&pseudobus, 0, 0x20, 4, val);
+ if (rtn != PCIBIOS_SUCCESSFUL) {
+ pr_err("Restore failed\n");
+ return cnt;
+ }
+
+
+ pr_info("Test passed\n");
+
+ return cnt;
+ }
+
+
+ /*Byte Order Memory Mapped Register test */
+ if (!strncmp(buffer, "M=", 2)) {
+ pr_info("Byte Order Memory Mapped Register test\n");
+
+ byteptr = (u8 *)ioremap_nocache(0x8000000, 1024);
+ wordptr = (u16 *)byteptr;
+ dwordptr = (u32 *)byteptr;
+
+ if (byteptr == 0) {
+ pr_err("Test failed. Unable to remap memory\n");
+ return cnt;
+ }
+
+ /*TEST1 */
+ /*read memory mapped register as byte, word, and dword */
+ byte = fix_readb(byteptr+0x11B);
+ word = fix_readw(wordptr+0x08D);
+ dword = fix_readl(dwordptr+0x046);
+
+ if ((byte != 0xB7) || ((word & 0xFF00) != 0xB700) ||
+ ((dword & 0xFF000000) != 0xB7000000)) {
+ iounmap(byteptr);
+ pr_err("Test failed. byte= %x word= %x dword= %x\n",
+ byte, word, dword);
+ return cnt;
+ }
+
+
+ /*TEST2 */
+ /*seve original contents */
+ savemem = fix_readl(dwordptr + 0x3);
+
+
+ /*write as a long */
+ fix_writel(0x11223344, dwordptr + 0x03);
+
+ /*read as bytes */
+ byte = fix_readb(byteptr + 0x0C);
+ if (byte != 0x44) {
+ pr_err("Test Failed. Byte 0x11 (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0D);
+ if (byte != 0x33) {
+ pr_err("Test Failed. Byte 0x22 (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0E);
+ if (byte != 0x22) {
+ pr_err("Test Failed. Byte 0x33 (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0F);
+ if (byte != 0x11) {
+ pr_err("Test Failed. Byte 0x44 (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+ /*read as words */
+ word = fix_readw(wordptr + 0x06);
+ if (word != 0x3344) {
+ pr_err("Test Failed. Word 0x1122 (%x)\n", word);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ word = fix_readw(wordptr + 0x07);
+ if (word != 0x1122) {
+ pr_err("Test Failed. Word 0x3344 (%x)\n", word);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+ /*read as a long */
+ dword = fix_readl(dwordptr + 0x03);
+ if (dword != 0x11223344) {
+ pr_err("Test Failed. Dword 0x11223344 (%x)\n", dword);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+
+ /*write as two words */
+ fix_writew(0x8899, wordptr + 0x06);
+ fix_writew(0x6677, wordptr + 0x07);
+
+ /*read as bytes */
+ byte = fix_readb(byteptr + 0x0C);
+ if (byte != 0x99) {
+ pr_err("Test Failed. Byte 0x88 (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0D);
+ if (byte != 0x88) {
+ pr_err("Test Failed. Byte 0x99 (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0E);
+ if (byte != 0x77) {
+ pr_err("Test Failed. Byte 0x66 (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0F);
+ if (byte != 0x66) {
+ pr_err("Test Failed. Byte 0x77 (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+ /*read as words */
+ word = fix_readw(wordptr + 0x06);
+ if (word != 0x8899) {
+ pr_err("Test Failed. Word 0x8899 (%x)\n", word);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ word = fix_readw(wordptr + 0x07);
+ if (word != 0x6677) {
+ pr_err("Test Failed. Word 0x6677 (%x)\n", word);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+ /*read as a long */
+ dword = fix_readl(dwordptr + 0x03);
+ if (dword != 0x66778899) {
+ pr_err("Test Failed. Dword 0x88996677 (%x)\n", dword);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+
+ /*write as four bytes */
+ fix_writeb(0xFF, byteptr + 0x0C);
+ fix_writeb(0xEE, byteptr + 0x0D);
+ fix_writeb(0xDD, byteptr + 0x0E);
+ fix_writeb(0xCC, byteptr + 0x0F);
+
+ /*read as bytes */
+ byte = fix_readb(byteptr + 0x0C);
+ if (byte != 0xFF) {
+ pr_err("Test Failed. Byte 0xFF (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0D);
+ if (byte != 0xEE) {
+ pr_err("Test Failed. Byte 0xEE (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0E);
+ if (byte != 0xDD) {
+ pr_err("Test Failed. Byte 0xDD (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ byte = fix_readb(byteptr + 0x0F);
+ if (byte != 0xCC) {
+ pr_err("Test Failed. Byte 0xCC (%x)\n", byte);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+ /*read as words */
+ word = fix_readw(wordptr + 0x06);
+ if (word != 0xEEFF) {
+ pr_err("Test Failed. Word 0xFFEE (%x)\n", word);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+ word = fix_readw(wordptr + 0x07);
+ if (word != 0xCCDD) {
+ pr_err("Test Failed. Word 0xDDCC (%x)\n", word);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+ /*read as a long */
+ dword = fix_readl(dwordptr + 0x03);
+ if (dword != 0xCCDDEEFF) {
+ pr_err("Test Failed. Dword 0xCCDDEEFF (%x)\n", dword);
+ iounmap(byteptr);
+ fix_writel(savemem, dwordptr + 0x03);
+ return cnt;
+ }
+
+
+ /*restore test location */
+ fix_writel(savemem, dwordptr + 0x03);
+
+
+ iounmap(byteptr);
+
+ pr_info("Test passed\n");
+
+ return cnt;
+ }
+
+ /*Memory Mapped Register dump */
+ if (!strncmp(buffer, "H=", 2)) {
+ dwordptr = (u32 *)ioremap_nocache(0x8000000, 16384);
+ if (dwordptr == 0) {
+ pr_err("Failed. Unable to remap memory\n");
+ return cnt;
+ }
+
+ sscanf(buffer, "H=%x %x", &addr, &val);
+ addr = (addr + (u32)dwordptr) & 0xFFFFFFE0;
+ val |= 0xF;
+ pr_info("dump %x words of memory from %x\n", val, addr);
+
+ for (i = 0; i < val; i++) {
+ if ((addr & 0x1F) == 0x00)
+ pr_info("\n%08x ", addr);
+ dword = fix_readl((u32 *)addr);
+ pr_info(" %08x", (u32)dword);
+ addr += 4;
+ }
+ pr_info("\n");
+
+ iounmap(dwordptr);
+ return cnt;
+ }
+
+
+ return cnt;
+}
+
+
+
+
+/*******************************************************************************
+ * pcie_ReadProc is called to dump HW registers
+ *
+ * page - not used
+ * start - not used
+ * off - not used
+ * count - not used
+ * eof - not used
+ * data - not used
+ *
+ * return - 0 or error if not enabled
+ *
+ *
+
******************************************************************************/
+static int pcie_ReadProc(char *page, char **start, off_t off, int pageSize,
+ int *eof, void *data)
+{
+ SAPRINT(SA_NOISE, SA_LOG_TO_PRINT, "%s: pcie ReadProc \n",
+ pcieModule_Name);
+
+ return 0;
+}
+
+
+
+
+/*******************************************************************************
+ * pcie_dumpcapability is called to dump a PCI capability structure
+ *
+ * bus - bus number
+ * dev - device number
+ * fun - function number
+ * ptr - pointer to beginning of device structure
+ *
+ * return - 0 or pointer to next capability structure
+ *
+ *
+
******************************************************************************/
+int pcie_dumpcapability(int busnumber, int dev, int fn, int ptr)
+{
+ struct pci_bus pseudobus;
+ int id, nextptr;
+ int rtn, val, where;
+ int dumpptr;
+
+ pseudobus.number = busnumber;
+
+ /*read id */
+ rtn = asic_pcie_read_config(&pseudobus, PCI_DEVFN(dev, fn), ptr, 1,
+ &id);
+ if (rtn != PCIBIOS_SUCCESSFUL)
+ return 0;
+
+ /*read nextptr */
+ rtn = asic_pcie_read_config(&pseudobus, PCI_DEVFN(dev, fn), ptr+1, 1,
+ &nextptr);
+ if (rtn != PCIBIOS_SUCCESSFUL)
+ return 0;
+ if (nextptr == 0)
+ nextptr = 0x100;
+
+ pr_info("\nID= %x", id);
+
+ dumpptr = ptr & 0xFFFFFFF0;
+ if (ptr != dumpptr) {
+ pr_info("\n%08x ", dumpptr);
+ for (where = dumpptr; where < ptr; where = where+4)
+ pr_info(" xxxxxxxx");
+ }
+
+ for (where = ptr; where < nextptr; where = where+4) {
+ if ((where & 0xF) == 0x00)
+ pr_info("\n%08x ", where);
+ rtn = asic_pcie_read_config(&pseudobus, PCI_DEVFN(dev, fn),
+ where, 4, &val);
+ if (rtn == PCIBIOS_SUCCESSFUL)
+ pr_info(" %08x", (u32)val);
+ else
+ pr_info(" xxxxxxxx");
+ }
+ return nextptr;
+}
+
+
+
+
+/*******************************************************************************
+ * pcie_dumpextendedcapability is called to dump an extended PCI capability
structure
+ *
+ * bus - bus number
+ * dev - device number
+ * fun - function number
+ * ptr - pointer to beginning of device structure
+ *
+ * return - 0 or pointer to next capability structure
+ *
+ *
+
******************************************************************************/
+int pcie_dumpextendedcapability(int busnumber, int dev, int fn, int ptr)
+{
+ struct pci_bus pseudobus;
+ int id, nextptr;
+ int rtn, val, where;
+
+ pseudobus.number = busnumber;
+
+ /*read id */
+ rtn = asic_pcie_read_config(&pseudobus, PCI_DEVFN(dev, fn), ptr, 2,
+ &id);
+ if (rtn != PCIBIOS_SUCCESSFUL)
+ return 0;
+
+ /*read nextptr */
+ rtn = asic_pcie_read_config(&pseudobus, PCI_DEVFN(dev, fn), ptr+2, 2,
+ &nextptr);
+ if (rtn != PCIBIOS_SUCCESSFUL)
+ return 0;
+ nextptr = nextptr >> 4;
+ if (nextptr == 0)
+ nextptr = 0x1000;
+
+ pr_info("\nExID= %x", id);
+
+ for (where = ptr; where < nextptr; where = where+4) {
+ if ((where & 0xF) == 0x00)
+ pr_info("\n%08x ", where);
+ rtn = asic_pcie_read_config(&pseudobus, PCI_DEVFN(dev, fn),
+ where, 4, &val);
+ if (rtn == PCIBIOS_SUCCESSFUL)
+ pr_info(" %08x", (u32)val);
+ else
+ pr_info(" xxxxxxxx");
+ }
+ return nextptr;
+}
+
+
+
+
+/*******************************************************************************
+ * pcie_DumpRegs
+ *
+ * API Type - pcie private
+ *
+ * Parameters - none
+ *
+ * Return Value - none
+ *
+ * Description:
+ * Dups all registers
+ *
+
******************************************************************************/
+void pcie_DumpRegs()
+{
+int i;
+
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "%s: pcie_DumpRegs \n",
+ pcieModule_Name);
+
+ for (i = 0; i < 1024; i++)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[i],
+ readl(&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC0[i]));
+ for (i = 0; i < 1024; i++)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC1[i],
+ readl(&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC1[i]));
+ for (i = 0; i < 1024; i++)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC2[i],
+ readl(&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC2[i]));
+ for (i = 0; i < 1024; i++)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC3[i],
+ readl(&PCIE_RegsPtr->PCIX_CFG_SPACE_FUNC3[i]));
+ for (i = 0; i < 1024; i++)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_ACC_BAR0[i],
+ readl(&PCIE_RegsPtr->PCIX_ACC_BAR0[i]));
+ for (i = 0; i < 1024; i++)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_ACC_BAR1[i],
+ readl(&PCIE_RegsPtr->PCIX_ACC_BAR1[i]));
+ for (i = 0; i < 1024; i++)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_ACC_BAR2[i],
+ readl(&PCIE_RegsPtr->PCIX_ACC_BAR2[i]));
+ for (i = 0; i < 1024; i++)
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_ACC_BAR3[i],
+ readl(&PCIE_RegsPtr->PCIX_ACC_BAR3[i]));
+
+
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CTL1,
+ readl(&PCIE_RegsPtr->PCIX_CTL1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_TRGT0_EN,
+ readl(&PCIE_RegsPtr->PCIX_TRGT0_EN));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT0_ADDR_ALIGN_EN,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT0_ADDR_ALIGN_EN));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT0_TLPREQID,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT0_TLPREQID));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT0_TLP_ADEOT,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT0_TLP_ADEOT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT0_TLPTC,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT0_TLPTC));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT0_TLPEP,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT0_TLPEP));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT0_TLPATTR,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT0_TLPATTR));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT0_TLPFUN,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT0_TLPFUN));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT1_ADDR_ALIGN_EN,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT1_ADDR_ALIGN_EN));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_APP_UNLOCK,
+ readl(&PCIE_RegsPtr->PCIX_APP_UNLOCK));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT1_TLP_BADEOT,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT1_TLP_BADEOT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_APPREQ,
+ readl(&PCIE_RegsPtr->PCIX_APPREQ));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLIENT1_TLPEP,
+ readl(&PCIE_RegsPtr->PCIX_CLIENT1_TLPEP));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MEMRD_LOCKEN,
+ readl(&PCIE_RegsPtr->PCIX_MEMRD_LOCKEN));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_SYSCMD,
+ readl(&PCIE_RegsPtr->PCIX_SYSCMD));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_PHYCFG,
+ readl(&PCIE_RegsPtr->PCIX_PHYCFG));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_OUTBAND_PWRUP,
+ readl(&PCIE_RegsPtr->PCIX_OUTBAND_PWRUP));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_SYSINT,
+ readl(&PCIE_RegsPtr->PCIX_SYSINT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_SYSATTEN,
+ readl(&PCIE_RegsPtr->PCIX_SYSATTEN));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLEAR_RST,
+ readl(&PCIE_RegsPtr->PCIX_CLEAR_RST));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_SOFT_RST,
+ readl(&PCIE_RegsPtr->PCIX_SOFT_RST));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MASKRISE_LOW,
+ readl(&PCIE_RegsPtr->PCIX_MASKRISE_LOW));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MASKRISE_HIGH,
+ readl(&PCIE_RegsPtr->PCIX_MASKRISE_HIGH));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLRRISE_LOW,
+ readl(&PCIE_RegsPtr->PCIX_CLRRISE_LOW));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLRRISE_HIGH,
+ readl(&PCIE_RegsPtr->PCIX_CLRRISE_HIGH));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSKFALL,
+ readl(&PCIE_RegsPtr->PCIX_MSKFALL));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLRFALL,
+ readl(&PCIE_RegsPtr->PCIX_CLRFALL));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSKLEV,
+ readl(&PCIE_RegsPtr->PCIX_MSKLEV));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLRLEV,
+ readl(&PCIE_RegsPtr->PCIX_CLRLEV));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_ABORT,
+ readl(&PCIE_RegsPtr->PCIX_ABORT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_APPINIT,
+ readl(&PCIE_RegsPtr->PCIX_APPINIT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC0_USERBAR0,
+ readl(&PCIE_RegsPtr->PCIX_FUNC0_USERBAR0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC0_USERBAR2,
+ readl(&PCIE_RegsPtr->PCIX_FUNC0_USERBAR2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC0_USERBAR4,
+ readl(&PCIE_RegsPtr->PCIX_FUNC0_USERBAR4));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC0_USEREXP,
+ readl(&PCIE_RegsPtr->PCIX_FUNC0_USEREXP));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC1_USERBAR0,
+ readl(&PCIE_RegsPtr->PCIX_FUNC1_USERBAR0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC1_USERBAR2,
+ readl(&PCIE_RegsPtr->PCIX_FUNC1_USERBAR2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC1_USERBAR4,
+ readl(&PCIE_RegsPtr->PCIX_FUNC1_USERBAR4));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC1_USEREXP,
+ readl(&PCIE_RegsPtr->PCIX_FUNC1_USEREXP));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC2_USERBAR0,
+ readl(&PCIE_RegsPtr->PCIX_FUNC2_USERBAR0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC2_USERBAR2,
+ readl(&PCIE_RegsPtr->PCIX_FUNC2_USERBAR2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC2_USERBAR4,
+ readl(&PCIE_RegsPtr->PCIX_FUNC2_USERBAR4));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC2_USEREXP,
+ readl(&PCIE_RegsPtr->PCIX_FUNC2_USEREXP));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC3_USERBAR0,
+ readl(&PCIE_RegsPtr->PCIX_FUNC3_USERBAR0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC3_USERBAR2,
+ readl(&PCIE_RegsPtr->PCIX_FUNC3_USERBAR2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC3_USERBAR4,
+ readl(&PCIE_RegsPtr->PCIX_FUNC3_USERBAR4));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FUNC3_USEREXP,
+ readl(&PCIE_RegsPtr->PCIX_FUNC3_USEREXP));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_T3TARG_BASE0,
+ readl(&PCIE_RegsPtr->PCIX_T3TARG_BASE0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_T3TARG_BASE1,
+ readl(&PCIE_RegsPtr->PCIX_T3TARG_BASE1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_T3TARG_BASE2,
+ readl(&PCIE_RegsPtr->PCIX_T3TARG_BASE2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_T3TARG_BASE3,
+ readl(&PCIE_RegsPtr->PCIX_T3TARG_BASE3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_T3TARG_WIN0,
+ readl(&PCIE_RegsPtr->PCIX_T3TARG_WIN0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_T3TARG_WIN1,
+ readl(&PCIE_RegsPtr->PCIX_T3TARG_WIN1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_T3TARG_WIN2,
+ readl(&PCIE_RegsPtr->PCIX_T3TARG_WIN2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_T3TARG_WIN3,
+ readl(&PCIE_RegsPtr->PCIX_T3TARG_WIN3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIE_RC_CFG_MODE,
+ readl(&PCIE_RegsPtr->PCIE_RC_CFG_MODE));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIE_RC_CFG_SETUP1,
+ readl(&PCIE_RegsPtr->PCIE_RC_CFG_SETUP1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIE_RC_CFG_SETUP2,
+ readl(&PCIE_RegsPtr->PCIE_RC_CFG_SETUP2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIE_RC_CFG_WRITE_DATA,
+ readl(&PCIE_RegsPtr->PCIE_RC_CFG_WRITE_DATA));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIE_RC_CFG_STAT,
+ readl(&PCIE_RegsPtr->PCIE_RC_CFG_STAT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIE_RC_CFG_CPL_DATA,
+ readl(&PCIE_RegsPtr->PCIE_RC_CFG_CPL_DATA));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIE_RC_CFG_CPLID,
+ readl(&PCIE_RegsPtr->PCIE_RC_CFG_CPLID));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RISING_EVENT_LOW,
+ readl(&PCIE_RegsPtr->PCIX_RISING_EVENT_LOW));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RISING_EVENT_HIGH,
+ readl(&PCIE_RegsPtr->PCIX_RISING_EVENT_HIGH));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FALLING_EVENT,
+ readl(&PCIE_RegsPtr->PCIX_FALLING_EVENT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_LEVEL_EVENT,
+ readl(&PCIE_RegsPtr->PCIX_LEVEL_EVENT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_PHY_CONT_DATA1,
+ readl(&PCIE_RegsPtr->PCIX_PHY_CONT_DATA1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_PHY_CONT_DATA2,
+ readl(&PCIE_RegsPtr->PCIX_PHY_CONT_DATA2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_PHY_READ_BACK,
+ readl(&PCIE_RegsPtr->PCIX_PHY_READ_BACK));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_APPS_PM,
+ readl(&PCIE_RegsPtr->PCIX_APPS_PM));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_INT_EN,
+ readl(&PCIE_RegsPtr->PCIX_INT_EN));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MASKRISE_LOW2,
+ readl(&PCIE_RegsPtr->PCIX_MASKRISE_LOW2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MASKRISE_HIGH2,
+ readl(&PCIE_RegsPtr->PCIX_MASKRISE_HIGH2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLRRISE_LOW2,
+ readl(&PCIE_RegsPtr->PCIX_CLRRISE_LOW2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLRRISE_HIGH2,
+ readl(&PCIE_RegsPtr->PCIX_CLRRISE_HIGH2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSKFALL2,
+ readl(&PCIE_RegsPtr->PCIX_MSKFALL2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLRFALL2,
+ readl(&PCIE_RegsPtr->PCIX_CLRFALL2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSKLEV2,
+ readl(&PCIE_RegsPtr->PCIX_MSKLEV2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CLRLEV2,
+ readl(&PCIE_RegsPtr->PCIX_CLRLEV2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RISING_EVENT_LOW2,
+ readl(&PCIE_RegsPtr->PCIX_RISING_EVENT_LOW2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RISING_EVENT_HIGH2,
+ readl(&PCIE_RegsPtr->PCIX_RISING_EVENT_HIGH2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_FALLING_EVENT2,
+ readl(&PCIE_RegsPtr->PCIX_FALLING_EVENT2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_LEVEL_EVENT2,
+ readl(&PCIE_RegsPtr->PCIX_LEVEL_EVENT2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_PBUS_NUM,
+ readl(&PCIE_RegsPtr->PCIX_CFG_PBUS_NUM));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_PBUS_DEVNUM,
+ readl(&PCIE_RegsPtr->PCIX_CFG_PBUS_DEVNUM));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_PMSTAT,
+ readl(&PCIE_RegsPtr->PCIX_PMSTAT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM,
+ readl(&PCIE_RegsPtr->PCIX_RADM));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSI_EN1,
+ readl(&PCIE_RegsPtr->PCIX_MSI_EN1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIADDR1_LOW,
+ readl(&PCIE_RegsPtr->PCIX_MSIADDR1_LOW));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIADDR1_HIGH,
+ readl(&PCIE_RegsPtr->PCIX_MSIADDR1_HIGH));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIDATA1,
+ readl(&PCIE_RegsPtr->PCIX_MSIDATA1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSI_EN2,
+ readl(&PCIE_RegsPtr->PCIX_MSI_EN2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIADDR2_LOW,
+ readl(&PCIE_RegsPtr->PCIX_MSIADDR2_LOW));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIADDR2_HIGH,
+ readl(&PCIE_RegsPtr->PCIX_MSIADDR2_HIGH));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIDATA2,
+ readl(&PCIE_RegsPtr->PCIX_MSIDATA2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_TESTBUS,
+ readl(&PCIE_RegsPtr->PCIX_TESTBUS));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIX_ADDR_LOW,
+ readl(&PCIE_RegsPtr->PCIX_MSIX_ADDR_LOW));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIX_ADDR_HIGH,
+ readl(&PCIE_RegsPtr->PCIX_MSIX_ADDR_HIGH));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIXDATA,
+ readl(&PCIE_RegsPtr->PCIX_MSIXDATA));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_MSIX_EN,
+ readl(&PCIE_RegsPtr->PCIX_MSIX_EN));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_AER_INT_MSGNUM,
+ readl(&PCIE_RegsPtr->PCIX_AER_INT_MSGNUM));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CAP_INT_MSTNUM,
+ readl(&PCIE_RegsPtr->PCIX_CAP_INT_MSTNUM));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_EMLCONT,
+ readl(&PCIE_RegsPtr->PCIX_EMLCONT));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_PHY_CONT0,
+ readl(&PCIE_RegsPtr->PCIX_CFG_PHY_CONT0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_START_0,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_START_0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_START_1,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_START_1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_START_2,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_START_2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_START_3,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_START_3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_START_4,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_START_4));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_START_5,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_START_5));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_START_6,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_START_6));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_START_7,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_START_7));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_0,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_2,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_3,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_4,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_4));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_5,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_5));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_6,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_6));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_7,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR0_LIMIT_7));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_START_0,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_START_0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_START_1,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_START_1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_START_2,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_START_2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_START_3,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_START_3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_START_4,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_START_4));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_START_5,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_START_5));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_START_6,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_START_6));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_START_7,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_START_7));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_0,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_1,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_2,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_3,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_4,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_4));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_5,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_5));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_6,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_6));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_7,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BAR1_LIMIT_7));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_START_0,
+ readl(&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_START_0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_START_1,
+ readl(&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_START_1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_START_2,
+ readl(&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_START_2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_START_3,
+ readl(&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_START_3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_LIMIT_0,
+ readl(&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_LIMIT_0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_LIMIT_1,
+ readl(&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_LIMIT_1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_LIMIT_2,
+ readl(&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_LIMIT_2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_LIMIT_3,
+ readl(&PCIE_RegsPtr->PCIX_CFG_EXP_ROM_LIMIT_3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_XLMH_STATE,
+ readl(&PCIE_RegsPtr->PCIX_XLMH_STATE));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RDLH_LINK,
+ readl(&PCIE_RegsPtr->PCIX_RDLH_LINK));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_BUS_MSTR,
+ readl(&PCIE_RegsPtr->PCIX_CFG_BUS_MSTR));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_MEM,
+ readl(&PCIE_RegsPtr->PCIX_CFG_MEM));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_MSI,
+ readl(&PCIE_RegsPtr->PCIX_CFG_MSI));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_MAX,
+ readl(&PCIE_RegsPtr->PCIX_CFG_MAX));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_PM_CURST,
+ readl(&PCIE_RegsPtr->PCIX_PM_CURST));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM_MSGCTL,
+ readl(&PCIE_RegsPtr->PCIX_RADM_MSGCTL));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM_MSGPAY,
+ readl(&PCIE_RegsPtr->PCIX_RADM_MSGPAY));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM_PWR,
+ readl(&PCIE_RegsPtr->PCIX_RADM_PWR));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM_CORR,
+ readl(&PCIE_RegsPtr->PCIX_RADM_CORR));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RTLH_UPD,
+ readl(&PCIE_RegsPtr->PCIX_RTLH_UPD));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RTLD_DATA,
+ readl(&PCIE_RegsPtr->PCIX_RTLD_DATA));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CXPL_DEBUGLO,
+ readl(&PCIE_RegsPtr->PCIX_CXPL_DEBUGLO));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CXPL_DEBUGHI,
+ readl(&PCIE_RegsPtr->PCIX_CXPL_DEBUGHI));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM_CPL_0,
+ readl(&PCIE_RegsPtr->PCIX_RADM_CPL_0));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM_CPL_1,
+ readl(&PCIE_RegsPtr->PCIX_RADM_CPL_1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM_CPL_2,
+ readl(&PCIE_RegsPtr->PCIX_RADM_CPL_2));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_RADM_CPL_3,
+ readl(&PCIE_RegsPtr->PCIX_RADM_CPL_3));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_CFG_RCB,
+ readl(&PCIE_RegsPtr->PCIX_CFG_RCB));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_VEN_MSG_STAT1,
+ readl(&PCIE_RegsPtr->PCIX_VEN_MSG_STAT1));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_VEN_MSG_DATALO,
+ readl(&PCIE_RegsPtr->PCIX_VEN_MSG_DATALO));
+ SAPRINT(SA_INFO, SA_LOG_TO_PRINT, "register at %8x = %8x\n",
+ (u32)&PCIE_RegsPtr->PCIX_VEN_MSG_DATAHI,
+ readl(&PCIE_RegsPtr->PCIX_VEN_MSG_DATAHI));
+}
+
diff --git a/arch/mips/powertv/pci/pcieregs.h b/arch/mips/powertv/pci/pcieregs.h
new file mode 100644
index
--- /dev/null
+++ b/arch/mips/powertv/pci/pcieregs.h
@@ -0,0 +1,333 @@
+/* ----------------------------------------------------------------------------
+ * PCIE Module
+ *
+ * Copyright (C) Scientific-Atlanta, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA USA
+ *
+ * ----------------------------------------------------------------------------
+ *
+ * File Name: pcieregs.h
+ *
+ * Project: NGP
+ *
+ * Compiler: gnu C (gcc)
+ *
+ * Author(s): Tom Haman
+ *
+ * Description: This header file defines the registers for the PCIE
+ * section of the Zeus Asic.
+ *
+ * Documents: PCIE Software Design Document
+ *
+ * NOTES:
+ *
+ * ----------------------------------------------------------------------------
+ * History:
+ * Rev Level Date Name ECN# Description
+ * ----------------------------------------------------------------------------
+ * /15/06 Tom Haman --- Initial version for NGP (Zeus)
+ * ----------------------------------------------------------------------------
+ */
+
+#ifndef _PCIE_REGS_H_
+#define _PCIE_REGS_H_
+
+#define PCIE_PLL_FIX
+#ifdef PCIE_PLL_FIX
+/* if PCIE_PLL_FIX is defined, then apply workaround to allow
+ * PCIe PHY layer to be reset after new PLL value has been loaded.
+ * subsequent versions of Zeus will have proper PLL default value
+ * set so that this will not be necessary. */
+
+/* TESTBUS Registers */
+#define kSCR_DEPTH 640
+
+struct tTBRegs {
+ u32 TEST_BUS_GPIO_CTL; /* 091A0238 */
+ u32 TEST_BUS_GPIO; /* 091A023C */
+};
+#endif
+
+/* PCIE Registers, Offsets and Bit Definitions */
+struct tPCIERegs {
+ u32 PCIX_CFG_SPACE_FUNC0[1024]; /* thru 09200FFF */
+ u32 PCIX_CFG_SPACE_FUNC1[1024]; /* thru 09201FFF */
+ u32 PCIX_CFG_SPACE_FUNC2[1024]; /* thru 09202FFF */
+ u32 PCIX_CFG_SPACE_FUNC3[1024]; /* thru 09203FFF */
+
+ u32 filler1[4096]; /* thru 09207FFF */
+
+ u32 PCIX_ACC_BAR0[1024]; /* thru 09208FFF */
+ u32 PCIX_ACC_BAR1[1024]; /* thru 09209FFF */
+ u32 PCIX_ACC_BAR2[1024]; /*0920A000 thru 0920AFFF */
+ u32 PCIX_ACC_BAR3[1024]; /*0920B000 thru 0920BFFF */
+
+ u32 filler2[4096]; /*0920C000 thru 0920FFFF */
+
+ u32 PCIX_CTL1; /* */
+ u32 PCIX_TRGT0_EN; /* */
+ u32 PCIX_CLIENT0_ADDR_ALIGN_EN; /* */
+ u32 PCIX_CLIENT0_TLPREQID; /*0921000C */
+ u32 PCIX_CLIENT0_TLP_ADEOT; /* */
+ u32 PCIX_CLIENT0_TLPTC; /* */
+ u32 PCIX_CLIENT0_TLPEP; /* */
+ u32 PCIX_CLIENT0_TLPATTR; /*0921001C */
+ u32 PCIX_CLIENT0_TLPFUN; /* */
+ u32 PCIX_CLIENT1_ADDR_ALIGN_EN; /* */
+ u32 PCIX_APP_UNLOCK; /* */
+ u32 PCIX_CLIENT1_TLP_BADEOT; /*0921002C */
+ u32 PCIX_APPREQ; /* */
+ u32 PCIX_CLIENT1_TLPEP; /* */
+ u32 PCIX_MEMRD_LOCKEN; /* */
+ u32 PCIX_SYSCMD; /*0921003C */
+ u32 PCIX_PHYCFG; /* */
+ u32 PCIX_OUTBAND_PWRUP; /* */
+ u32 PCIX_SYSINT; /* */
+ u32 PCIX_SYSATTEN; /*0921004C */
+ u32 PCIX_CLEAR_RST; /* */
+ u32 PCIX_SOFT_RST; /* */
+ u32 PCIX_MASKRISE_LOW; /* */
+ u32 PCIX_MASKRISE_HIGH; /*0921005C */
+ u32 PCIX_CLRRISE_LOW; /* */
+ u32 PCIX_CLRRISE_HIGH; /* */
+ u32 PCIX_MSKFALL; /* */
+ u32 PCIX_CLRFALL; /*0921006C */
+ u32 PCIX_MSKLEV; /* */
+ u32 PCIX_CLRLEV; /* */
+ u32 PCIX_ABORT; /* */
+ u32 PCIX_APPINIT; /*0921007C */
+ u32 PCIX_FUNC0_USERBAR0; /* */
+ u32 PCIX_FUNC0_USERBAR2; /* */
+ u32 PCIX_FUNC0_USERBAR4; /* */
+ u32 PCIX_FUNC0_USEREXP; /*0921008C */
+ u32 PCIX_FUNC1_USERBAR0; /* */
+ u32 PCIX_FUNC1_USERBAR2; /* */
+ u32 PCIX_FUNC1_USERBAR4; /* */
+ u32 PCIX_FUNC1_USEREXP; /*0921009C */
+ u32 PCIX_FUNC2_USERBAR0; /*092100A0 */
+ u32 PCIX_FUNC2_USERBAR2; /*092100A4 */
+ u32 PCIX_FUNC2_USERBAR4; /*092100A8 */
+ u32 PCIX_FUNC2_USEREXP; /*092100AC */
+ u32 PCIX_FUNC3_USERBAR0; /*092100B0 */
+ u32 PCIX_FUNC3_USERBAR2; /*092100B4 */
+ u32 PCIX_FUNC3_USERBAR4; /*092100B8 */
+ u32 PCIX_FUNC3_USEREXP; /*092100BC */
+ u32 PCIX_T3TARG_BASE0; /*092100C0 */
+ u32 PCIX_T3TARG_BASE1; /*092100C4 */
+ u32 PCIX_T3TARG_BASE2; /*092100C8 */
+ u32 PCIX_T3TARG_BASE3; /*092100CC */
+ u32 PCIX_T3TARG_WIN0; /*092100D0 */
+ u32 PCIX_T3TARG_WIN1; /*092100D4 */
+ u32 PCIX_T3TARG_WIN2; /*092100D8 */
+ u32 PCIX_T3TARG_WIN3; /*092100DC */
+ u32 filler3[8]; /*092100E0 thru 092100FF */
+ u32 PCIE_RC_CFG_MODE; /* */
+ u32 PCIE_RC_CFG_SETUP1; /* */
+ u32 PCIE_RC_CFG_SETUP2; /* */
+ u32 PCIE_RC_CFG_WRITE_DATA; /*0921010C */
+ u32 PCIE_RC_CFG_STAT; /* */
+ u32 PCIE_RC_CFG_CPL_DATA; /* */
+ u32 PCIE_RC_CFG_CPLID; /* */
+ u32 filler4; /*0921011C */
+ u32 PCIX_RISING_EVENT_LOW; /* */
+ u32 PCIX_RISING_EVENT_HIGH; /* */
+ u32 PCIX_FALLING_EVENT; /* */
+ u32 PCIX_LEVEL_EVENT; /*0921012C */
+ u32 PCIX_PHY_CONT_DATA1; /* */
+ u32 PCIX_PHY_CONT_DATA2; /* */
+ u32 PCIX_PHY_READ_BACK; /* */
+ u32 PCIX_APPS_PM; /*0921013C */
+ u32 PCIX_INT_EN; /* */
+ u32 PCIX_MASKRISE_LOW2; /* */
+ u32 PCIX_MASKRISE_HIGH2; /* */
+ u32 PCIX_CLRRISE_LOW2; /*0921014C */
+ u32 PCIX_CLRRISE_HIGH2; /* */
+ u32 PCIX_MSKFALL2; /* */
+ u32 PCIX_CLRFALL2; /* */
+ u32 PCIX_MSKLEV2; /*0921015C */
+ u32 PCIX_CLRLEV2; /* */
+ u32 PCIX_RISING_EVENT_LOW2; /* */
+ u32 PCIX_RISING_EVENT_HIGH2; /* */
+ u32 PCIX_FALLING_EVENT2; /*0921016C */
+ u32 PCIX_LEVEL_EVENT2; /* */
+ u32 PCIX_CFG_PBUS_NUM; /* */
+ u32 PCIX_CFG_PBUS_DEVNUM; /* */
+ u32 PCIX_PMSTAT; /*0921017C */
+ u32 PCIX_RADM; /* */
+ u32 PCIX_MSI_EN1; /* */
+ u32 PCIX_MSIADDR1_LOW; /* */
+ u32 PCIX_MSIADDR1_HIGH; /*0921018C */
+ u32 PCIX_MSIDATA1; /* */
+ u32 PCIX_MSI_EN2; /* */
+ u32 PCIX_MSIADDR2_LOW; /* */
+ u32 PCIX_MSIADDR2_HIGH; /*0921019C */
+ u32 PCIX_MSIDATA2; /*092101A0 */
+ u32 PCIX_TESTBUS; /*092101A4 */
+ u32 PCIX_MSIX_ADDR_LOW; /*092101A8 */
+ u32 PCIX_MSIX_ADDR_HIGH; /*092101AC */
+ u32 PCIX_MSIXDATA; /*092101B0 */
+ u32 PCIX_MSIX_EN; /*092101B4 */
+ u32 PCIX_AER_INT_MSGNUM; /*092101B8 */
+ u32 PCIX_CAP_INT_MSTNUM; /*092101BC */
+ u32 PCIX_EMLCONT; /*092101C0 */
+ u32 filler5[143]; /*092101C4 thru 092103FF */
+ u32 PCIX_CFG_PHY_CONT0; /* */
+ u32 filler6[3]; /* thru 0921040F */
+ u32 PCIX_CFG_BAR0_START_0; /* */
+ u32 PCIX_CFG_BAR0_START_1; /* */
+ u32 PCIX_CFG_BAR0_START_2; /* */
+ u32 PCIX_CFG_BAR0_START_3; /*0921041C */
+ u32 PCIX_CFG_BAR0_START_4; /* */
+ u32 PCIX_CFG_BAR0_START_5; /* */
+ u32 PCIX_CFG_BAR0_START_6; /* */
+ u32 PCIX_CFG_BAR0_START_7; /*0921042C */
+ u32 PCIX_CFG_BAR0_LIMIT_0; /* */
+ u32 filler7; /* */
+ u32 PCIX_CFG_BAR0_LIMIT_2; /* */
+ u32 PCIX_CFG_BAR0_LIMIT_3; /*0921043C */
+ u32 PCIX_CFG_BAR0_LIMIT_4; /* */
+ u32 PCIX_CFG_BAR0_LIMIT_5; /* */
+ u32 PCIX_CFG_BAR0_LIMIT_6; /* */
+ u32 PCIX_CFG_BAR0_LIMIT_7; /*0921044C */
+ u32 PCIX_CFG_BAR1_START_0; /* */
+ u32 PCIX_CFG_BAR1_START_1; /* */
+ u32 PCIX_CFG_BAR1_START_2; /* */
+ u32 PCIX_CFG_BAR1_START_3; /*0921045C */
+ u32 PCIX_CFG_BAR1_START_4; /* */
+ u32 PCIX_CFG_BAR1_START_5; /* */
+ u32 PCIX_CFG_BAR1_START_6; /* */
+ u32 PCIX_CFG_BAR1_START_7; /*0921046C */
+ u32 PCIX_CFG_BAR1_LIMIT_0; /* */
+ u32 PCIX_CFG_BAR1_LIMIT_1; /* */
+ u32 PCIX_CFG_BAR1_LIMIT_2; /* */
+ u32 PCIX_CFG_BAR1_LIMIT_3; /*0921047C */
+ u32 PCIX_CFG_BAR1_LIMIT_4; /* */
+ u32 PCIX_CFG_BAR1_LIMIT_5; /* */
+ u32 PCIX_CFG_BAR1_LIMIT_6; /* */
+ u32 PCIX_CFG_BAR1_LIMIT_7; /*0921048C */
+ u32 PCIX_CFG_EXP_ROM_START_0; /* */
+ u32 PCIX_CFG_EXP_ROM_START_1; /* */
+ u32 PCIX_CFG_EXP_ROM_START_2; /* */
+ u32 PCIX_CFG_EXP_ROM_START_3; /*0921049C */
+ u32 PCIX_CFG_EXP_ROM_LIMIT_0; /*092104A0 */
+ u32 PCIX_CFG_EXP_ROM_LIMIT_1; /*092104A4 */
+ u32 PCIX_CFG_EXP_ROM_LIMIT_2; /*092104A8 */
+ u32 PCIX_CFG_EXP_ROM_LIMIT_3; /*092104AC */
+ u32 PCIX_XLMH_STATE; /*092104B0 */
+ u32 PCIX_RDLH_LINK; /*092104B4 */
+ u32 PCIX_CFG_BUS_MSTR; /*092104B8 */
+ u32 PCIX_CFG_MEM; /*092104BC */
+ u32 PCIX_CFG_MSI; /*092104C0 */
+ u32 PCIX_CFG_MAX; /*092104C4 */
+ u32 filler8; /*092104C8 */
+ u32 PCIX_PM_CURST; /*092104CC */
+ u32 PCIX_RADM_MSGCTL; /*092104D0 */
+ u32 PCIX_RADM_MSGPAY; /*092104D4 */
+ u32 PCIX_RADM_PWR; /*092104D8 */
+ u32 filler9[2]; /*092104DC thru 092104E0 */
+ u32 PCIX_RADM_CORR; /*092104E4 */
+ u32 PCIX_RTLH_UPD; /*092104E8 */
+ u32 PCIX_RTLD_DATA; /*092104EC */
+ u32 PCIX_CXPL_DEBUGLO; /*092104F0 */
+ u32 PCIX_CXPL_DEBUGHI; /*092104F4 */
+ u32 PCIX_RADM_CPL_0; /*092104F8 */
+ u32 PCIX_RADM_CPL_1; /*092104FC */
+ u32 PCIX_RADM_CPL_2; /* */
+ u32 PCIX_RADM_CPL_3; /* */
+ u32 PCIX_CFG_RCB; /* */
+ u32 filler10[7872]; /*0921050C thru */
+ u32 PCIX_VEN_MSG_STAT1; /*0921800C */
+ u32 PCIX_VEN_MSG_DATALO; /* */
+ u32 PCIX_VEN_MSG_DATAHI; /* */
+};
+
+/*PCIX_PHY_READ_BACK bits */
+#define kPCIX_PHY_READ_BACK_PllLock 0x01
+#define kPCIX_PHY_READ_BACK_Ready 0x02
+
+/*PCIX_CTL1 bits */
+#define kPCIX_CTL1_PCIE_TLP_ENABLE 0x0002
+#define kPCIX_CTL1_PCIE_FUNC0 0x0040
+#define kPCIX_CTL1_PCIE_ROOT_COMPLEX 0x0010
+#define kPCIX_CTL1_PCIE_SEL_CLOCK 0x1000
+#define kPCIX_CTL1_PCIE_LTSSM 0x0400
+#define kPCIX_CTL1_PCI_ENAB_INTS 0x0800
+
+/*PCIX_RDLH_LINK bits */
+#define kPCIX_RDLH_LINK_RdlhUp 0x01
+
+/*PCIE_RC_CFG_SETUP1 */
+#define kPCIE_RC_CFG_SETUP1_CFG_ENAB_ALL_BYTES 0x78
+#define kPCIE_RC_CFG_SETUP1_CFG_READ 0x01
+#define kPCIE_RC_CFG_SETUP1_CFG_WRITE 0x03
+#define kPCIE_RC_CFG_SETUP1_TYPE0 0x00
+#define kPCIE_RC_CFG_SETUP1_TYPE1 0x01
+
+/*Interrupt bits */
+#define kPCIX_IntLow_cfg_sys_err_rc3 0x80000000
+#define kPCIX_IntLow_cfg_sys_err_rc2 0x40000000
+#define kPCIX_IntLow_cfg_sys_err_rc1 0x20000000
+#define kPCIX_IntLow_cfg_sys_err_rc0 0x10000000
+#define kPCIX_IntLow_radm_cpl_hv 0x08000000
+#define kPCIX_IntLow_radm_cpl_dllp_abort 0x04000000
+#define kPCIX_IntLow_radm_cpl_tlp_abort 0x02000000
+#define kPCIX_IntLow_radm_cpl_ecrc_err 0x01000000
+#define kPCIX_IntLow_radm_cpl_eot 0x00800000
+#define kPCIX_IntLow_radm_cpl_last 0x00400000
+#define kPCIX_IntLow_radm_cpl_timeout 0x00200000
+#define kPCIX_IntLow_radm_trgt1_hv 0x00100000
+#define kPCIX_IntLow_radm_trgt1_eot 0x00080000
+#define kPCIX_IntLow_training_rst_n 0x00040000
+#define kPCIX_IntLow_rtlh_rfc_upd 0x00020000
+#define kPCIX_IntLow_pm_xtlh_block_tlp 0x00010000
+#define kPCIX_IntLow_cfg_aer_rc_err_int3 0x00008000
+#define kPCIX_IntLow_cfg_aer_rc_err_int2 0x00004000
+#define kPCIX_IntLow_cfg_aer_rc_err_int1 0x00002000
+#define kPCIX_IntLow_cfg_aer_rc_err_int0 0x00001000
+#define kPCIX_IntLow_rdlh_link_up 0x00000800
+#define kPCIX_IntLow_radm_vendor_msg 0x00000400
+#define kPCIX_IntLow_radm_msg_unlock 0x00000200
+#define kPCIX_IntLow_radm_inta_asserted 0x00000100
+#define kPCIX_IntLow_radm_intb_asserted 0x00000080
+#define kPCIX_IntLow_radm_intc_asserted 0x00000040
+#define kPCIX_IntLow_radm_intd_asserted 0x00000020
+#define kPCIX_IntLow_radm_correctable_err 0x00000010
+#define kPCIX_IntLow_radm_nonfatal_err 0x00000008
+#define kPCIX_IntLow_radm_fatal_err 0x00000004
+#define kPCIX_IntLow_radm_att_button_pressed 0x00000002
+#define kPCIX_IntLow_radm_pm_pme 0x00000001
+
+#define kPCIX_IntHigh_radm_pm_to_ack 0x00020000
+#define kPCIX_IntHigh_xmlh_link_up 0x00010000
+#define kPCIX_IntHigh_wake_n 0x00008000
+#define kPCIX_IntHigh_cfg_bus_master_en3 0x00004000
+#define kPCIX_IntHigh_cfg_bus_master_en2 0x00002000
+#define kPCIX_IntHigh_cfg_bus_master_en1 0x00001000
+#define kPCIX_IntHigh_cfg_bus_master_en0 0x00000800
+#define kPCIX_IntHigh_radm_inta_deasserted 0x00000400
+#define kPCIX_IntHigh_radm_intb_deasserted 0x00000200
+#define kPCIX_IntHigh_radm_intc_deasserted 0x00000100
+#define kPCIX_IntHigh_radm_intd_deasserted 0x00000080
+#define kPCIX_IntHigh_radm_att_ind_on 0x00000040
+#define kPCIX_IntHigh_radm_att_ind_blink 0x00000020
+#define kPCIX_IntHigh_radm_att_ind_off 0x00000010
+#define kPCIX_IntHigh_radm_pwr_ind_on 0x00000008
+#define kPCIX_IntHigh_radm_pwr_ind_blink 0x00000004
+#define kPCIX_IntHigh_radm_pwr_ind_off 0x00000002
+#define kPCIX_IntHigh_radm_cpl_error_int 0x00000001
+
+#endif /* _PCIE_REGS_H_ */
+
diff --git a/arch/mips/powertv/pci/powertv-pci.h
b/arch/mips/powertv/pci/powertv-pci.h
new file mode 100644
index 0000000..98c087e
--- /dev/null
+++ b/arch/mips/powertv/pci/powertv-pci.h
@@ -0,0 +1,12 @@
+/*
+ * Local definitions for the powertv PCI code
+ */
+
+#ifndef _POWERTV_PCI_H_
+#define _POWERTV_PCI_H_
+extern int asic_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin);
+extern int asic_pcie_init(void);
+extern int asic_pcie_init(void);
+
+extern int LogLevel;
+#endif
diff --git a/arch/mips/powertv/powertv-clock.h
b/arch/mips/powertv/powertv-clock.h
new file mode 100644
index 0000000..6f8c17b
--- /dev/null
+++ b/arch/mips/powertv/powertv-clock.h
@@ -0,0 +1,10 @@
+/*
+ * Definitions for clocks
+ */
+
+#ifndef _POWERTV_CLOCK_H
+#define _POWERTV_CLOCK_H
+extern int powertv_clockevent_init(void);
+extern void powertv_clocksource_init(void);
+extern unsigned int mips_get_pll_freq(void);
+#endif
diff --git a/arch/mips/powertv/powertv_setup.c
b/arch/mips/powertv/powertv_setup.c
new file mode 100644
index 0000000..f19f36f
--- /dev/null
+++ b/arch/mips/powertv/powertv_setup.c
@@ -0,0 +1,351 @@
+/*
+ * Carsten Langgaard,
+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA , USA.
+ */
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/screen_info.h>
+#include <linux/notifier.h>
+#include <linux/etherdevice.h>
+#include <linux/if_ether.h>
+#include <linux/ctype.h>
+
+#include <linux/cpu.h>
+#include <asm/bootinfo.h>
+#include <asm/irq.h>
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+#include <asm/dma.h>
+#include <linux/time.h>
+#include <asm/traps.h>
+#include <asm/asm-offsets.h>
+#include "reset.h"
+
+#define VAL(n) STR(n)
+
+/*
+ * Macros for loading addresses and storing registers:
+ * PTR_LA Load the address into a register
+ * LONG_S Store the full width of the given register.
+ * LONG_L Load the full width of the given register
+ * PTR_ADDIU Add a constant value to a register used as a pointer
+ * REG_SIZE Number of 8-bit bytes in a full width register
+ */
+#ifdef CONFIG_64BIT
+#warning TODO: 64-bit code needs to be verified
+#define PTR_LA "dla "
+#define LONG_S "sd "
+#define LONG_L "ld "
+#define PTR_ADDIU "daddiu "
+#define REG_SIZE "8" /* In bytes */
+#endif
+
+#ifdef CONFIG_32BIT
+#define PTR_LA "la "
+#define LONG_S "sw "
+#define LONG_L "lw "
+#define PTR_ADDIU "addiu "
+#define REG_SIZE "4" /* In bytes */
+#endif
+
+static struct pt_regs die_regs;
+static bool have_die_regs;
+
+static void register_panic_notifier(void);
+static int panic_handler(struct notifier_block *notifier_block,
+ unsigned long event, void *cause_string);
+
+const char *get_system_type(void)
+{
+ return "PowerTV";
+}
+
+void __init plat_mem_setup(void)
+{
+ panic_on_oops = 1;
+ register_panic_notifier();
+
+ mips_pcibios_init();
+ mips_reboot_setup();
+}
+
+/*
+ * Install a panic notifier for platform-specific diagnostics
+ */
+static void register_panic_notifier()
+{
+ static struct notifier_block panic_notifier = {
+ .notifier_call = panic_handler,
+ .next = NULL,
+ .priority = INT_MAX
+ };
+ atomic_notifier_chain_register(&panic_notifier_list, &panic_notifier);
+}
+
+static int panic_handler (struct notifier_block *notifier_block,
+ unsigned long event, void *cause_string)
+{
+ struct pt_regs my_regs;
+
+ /* Save all of the registers */
+ {
+ unsigned long at, v0, v1; /* Must be on the stack */
+
+ /* Start by saving $at and v0 on the stack. We use $at
+ * ourselves, but it looks like the compiler may use v0 or v1
+ * to load the address of the pt_regs structure. We'll come
+ * back later to store the registers in the pt_regs
+ * structure. */
+ __asm__ __volatile__ (
+ ".set noat\n"
+ LONG_S "$at, %[at]\n"
+ LONG_S "$2, %[v0]\n"
+ LONG_S "$3, %[v1]\n"
+ :
+ [at] "=m" (at),
+ [v0] "=m" (v0),
+ [v1] "=m" (v1)
+ :
+ : "at"
+ );
+
+ __asm__ __volatile__ (
+ ".set noat\n"
+ "move $at, %[pt_regs]\n"
+
+ /* Argument registers */
+ LONG_S "$4, " VAL(PT_R4) "($at)\n"
+ LONG_S "$5, " VAL(PT_R5) "($at)\n"
+ LONG_S "$6, " VAL(PT_R6) "($at)\n"
+ LONG_S "$7, " VAL(PT_R7) "($at)\n"
+
+ /* Temporary regs */
+ LONG_S "$8, " VAL(PT_R8) "($at)\n"
+ LONG_S "$9, " VAL(PT_R9) "($at)\n"
+ LONG_S "$10, " VAL(PT_R10) "($at)\n"
+ LONG_S "$11, " VAL(PT_R11) "($at)\n"
+ LONG_S "$12, " VAL(PT_R12) "($at)\n"
+ LONG_S "$13, " VAL(PT_R13) "($at)\n"
+ LONG_S "$14, " VAL(PT_R14) "($at)\n"
+ LONG_S "$15, " VAL(PT_R15) "($at)\n"
+
+ /* "Saved" registers */
+ LONG_S "$16, " VAL(PT_R16) "($at)\n"
+ LONG_S "$17, " VAL(PT_R17) "($at)\n"
+ LONG_S "$18, " VAL(PT_R18) "($at)\n"
+ LONG_S "$19, " VAL(PT_R19) "($at)\n"
+ LONG_S "$20, " VAL(PT_R20) "($at)\n"
+ LONG_S "$21, " VAL(PT_R21) "($at)\n"
+ LONG_S "$22, " VAL(PT_R22) "($at)\n"
+ LONG_S "$23, " VAL(PT_R23) "($at)\n"
+
+ /* Add'l temp regs */
+ LONG_S "$24, " VAL(PT_R24) "($at)\n"
+ LONG_S "$25, " VAL(PT_R25) "($at)\n"
+
+ /* Kernel temp regs */
+ LONG_S "$26, " VAL(PT_R26) "($at)\n"
+ LONG_S "$27, " VAL(PT_R27) "($at)\n"
+
+ /* Global pointer, stack pointer, frame pointer and
+ * return address */
+ LONG_S "$gp, " VAL(PT_R28) "($at)\n"
+ LONG_S "$sp, " VAL(PT_R29) "($at)\n"
+ LONG_S "$fp, " VAL(PT_R30) "($at)\n"
+ LONG_S "$ra, " VAL(PT_R31) "($at)\n"
+
+ /* Now we can get the $at and v0 registers back and
+ * store them */
+ LONG_L "$8, %[at]\n"
+ LONG_S "$8, " VAL(PT_R1) "($at)\n"
+ LONG_L "$8, %[v0]\n"
+ LONG_S "$8, " VAL(PT_R2) "($at)\n"
+ LONG_L "$8, %[v1]\n"
+ LONG_S "$8, " VAL(PT_R3) "($at)\n"
+ :
+ :
+ [at] "m" (at),
+ [v0] "m" (v0),
+ [v1] "m" (v1),
+ [pt_regs] "r" (&my_regs)
+ : "at", "t0"
+ );
+
+ /* Set the current EPC value to be the current location in this
+ * function */
+ __asm__ __volatile__ (
+ ".set noat\n"
+ "1:\n"
+ PTR_LA "$at, 1b\n"
+ LONG_S "$at, %[cp0_epc]\n"
+ :
+ [cp0_epc] "=m" (my_regs.cp0_epc)
+ :
+ : "at"
+ );
+
+ my_regs.cp0_cause = read_c0_cause();
+ my_regs.cp0_status = read_c0_status();
+ }
+
+#ifdef CONFIG_DIAGNOSTICS
+ failure_report((char *) cause_string,
+ have_die_regs ? &die_regs : &my_regs);
+ have_die_regs = false;
+#else
+ pr_crit("I'm feeling a bit sleepy. hmmmmm... perhaps a nap would... "
+ "zzzz... \n");
+#endif
+
+ return NOTIFY_DONE;
+}
+
+/**
+ * Platform-specific handling of oops
+ * @str: Pointer to the oops string
+ * @regs: Pointer to the oops registers
+ * All we do here is to save the registers for subsequent printing through
+ * the panic notifier.
+ */
+void platform_die(const char *str, const struct pt_regs *regs)
+{
+ /* If we already have saved registers, don't overwrite them as they
+ * they apply to the initial fault */
+
+ if (!have_die_regs) {
+ have_die_regs = true;
+ die_regs = *regs;
+ }
+}
+
+/* Information about the RF MAC address, if one was supplied on the
+ * command line. */
+static bool have_rfmac;
+static u8 rfmac[ETH_ALEN];
+
+static int rfmac_param(char *p)
+{
+ u8 *q;
+ bool is_high_nibble;
+ int c;
+
+ /* Skip a leading "0x", if present */
+ if (*p == '0' && *(p+1) == 'x')
+ p += 2;
+
+ q = rfmac;
+ is_high_nibble = true;
+
+ for (c = (unsigned char) *p++;
+ isxdigit(c) && q - rfmac < ETH_ALEN;
+ c = (unsigned char) *p++) {
+ int nibble;
+
+ nibble = (isdigit(c) ? (c - '0') :
+ (isupper(c) ? c - 'A' + 10 : c - 'a' + 10));
+
+ if (is_high_nibble)
+ *q = nibble << 4;
+ else
+ *q++ |= nibble;
+
+ is_high_nibble = !is_high_nibble;
+ }
+
+ /* If we parsed all the way to the end of the parameter value and
+ * parsed all ETH_ALEN bytes, we have a usable RF MAC address */
+ have_rfmac = (c == '\0' && q - rfmac == ETH_ALEN);
+
+ return 0;
+}
+
+early_param("rfmac", rfmac_param);
+
+/*
+ * Generate an Ethernet MAC address that has a good chance of being unique.
+ * @addr: Pointer to six-byte array containing the Ethernet address
+ * Generates an Ethernet MAC address that is highly likely to be unique for
+ * this particular system on a network with other systems of the same type.
+ *
+ * The problem we are solving is that, when random_ether_addr() is used to
+ * generate MAC addresses at startup, there isn't much entropy for the random
+ * number generator to use and the addresses it produces are fairly likely to
+ * be the same as those of other identical systems on the same local network.
+ * This is true even for relatively small numbers of systems (for the reason
+ * why, see the Wikipedia entry for "Birthday problem" at:
+ *
+ *
+ * The good news is that we already have a MAC address known to be unique, the
+ * RF MAC address. The bad news is that this address is already in use on the
+ * RF interface. Worse, the obvious trick, taking the RF MAC address and
+ * turning on the locally managed bit, has already been used for other devices.
+ * Still, this does give us something to work with.
+ *
+ * The approach we take is:
+ * 1. If we can't get the RF MAC Address, just call random_ether_addr.
+ * 2. Use the 24-bit NIC-specific bits of the RF MAC address as the last 24
+ * bits of the new address. This is very likely to be unique, except for
+ * the current box.
+ * 3. To avoid using addresses already on the current box, we set the top
+ * six bits of the address with a value different from any currently
+ * registered Scientific Atlanta organizationally unique identifyer
+ * (OUI). This avoids duplication with any addresses on the system that
+ * were generated from valid Scientific Atlanta-registered address by
+ * simply flipping the locally managed bit.
+ * 4. We aren't generating a multicast address, so we leave the multicast
+ * bit off. Since we aren't using a registered address, we have to set
+ * the locally managed bit.
+ * 5. We then randomly generate the remaining 16-bits. This does two
+ * things:
+ * a. It allows us to call this function for more than one device
+ * in this system
+ * b. It ensures that things will probably still work even if
+ * some device on the device network has a locally managed
+ * address that matches the top six bits from step 2.
+ */
+void platform_random_ether_addr(u8 addr[ETH_ALEN])
+{
+#define NUM_RANDOM_BYTES 2
+#define NON_SCIATL_OUI_BITS 0xc0u
+#define MAC_ADDR_LOCALLY_MANAGED (1 << 1)
+
+ if (!have_rfmac) {
+ pr_warning("rfmac not available on command line; "
+ "generating random MAC address\n");
+ random_ether_addr(addr);
+ }
+
+ else {
+ int i;
+
+ /* Set the first byte to something that won't match a Scientific
+ * Atlanta OUI, is locally managed, and isn't a multicast
+ * address */
+ addr[0] = NON_SCIATL_OUI_BITS | MAC_ADDR_LOCALLY_MANAGED;
+
+ /* Get some bytes of random address information */
+ get_random_bytes(&addr[1], NUM_RANDOM_BYTES);
+
+ /* Copy over the NIC-specific bits of the RF MAC address */
+ for (i = 1 + NUM_RANDOM_BYTES; i < ETH_ALEN; i++)
+ addr[i] = rfmac[i];
+ }
+#undef NON_RANDOM_BYTES
+#undef NON_SCIATL_OUI_BITS
+#undef MAC_ADDR_LOCALLY_MANAGED
+}
diff --git a/arch/mips/powertv/reset.c b/arch/mips/powertv/reset.c
new file mode 100644
index
--- /dev/null
+++ b/arch/mips/powertv/reset.c
@@ -0,0 +1,69 @@
+/*
+ * Carsten Langgaard,
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * ########################################################################
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA , USA.
+ *
+ * ########################################################################
+ *
+ */
+#include <linux/pm.h>
+
+#include <linux/io.h>
+#include <asm/reboot.h> /* Not included by
linux/reboot.h */
+
+#ifdef CONFIG_BOOTLOADER_DRIVER
+#include <asm/mach-powertv/kbldr.h>
+#endif
+
+#include <asm/mach-powertv/asic_regs.h>
+#include "reset.h"
+
+static void mips_machine_restart(char *command);
+static void mips_machine_halt(void);
+
+static void mips_machine_restart(char *command)
+{
+#ifdef CONFIG_BOOTLOADER_DRIVER
+ /*
+ * Call the bootloader's reset function to ensure
+ * that persistent data is flushed before hard reset
+ */
+ kbldr_SetCauseAndReset();
+#else
+ writel(0x1, asic_reg_addr(Watchdog));
+#endif
+}
+
+static void mips_machine_halt(void)
+{
+#ifdef CONFIG_BOOTLOADER_DRIVER
+ /*
+ * Call the bootloader's reset function to ensure
+ * that persistent data is flushed before hard reset
+ */
+ kbldr_SetCauseAndReset();
+#else
+ writel(0x1, asic_reg_addr(Watchdog));
+#endif
+}
+
+void mips_reboot_setup(void)
+{
+ _machine_restart = mips_machine_restart;
+ _machine_halt = mips_machine_halt;
+ pm_power_off = mips_machine_halt;
+}
diff --git a/arch/mips/powertv/reset.h b/arch/mips/powertv/reset.h
new file mode 100644
index 0000000..79211ce
--- /dev/null
+++ b/arch/mips/powertv/reset.h
@@ -0,0 +1,8 @@
+/*
+ * Definitions from powertv reset.c file
+ */
+
+#ifndef _POWERTV_RESET_H
+#define _POWERTV_RESET_H
+extern void mips_reboot_setup(void);
+#endif
diff --git a/arch/mips/powertv/time.c b/arch/mips/powertv/time.c
new file mode 100644
index 0000000..b5806e5
--- /dev/null
+++ b/arch/mips/powertv/time.c
@@ -0,0 +1,47 @@
+/*
+ * Carsten Langgaard,
+ * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
+ *
+ * This program is free software; you can distribute it and/or modify it
+ * under the terms of the GNU General Public License (Version 2) as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston MA , USA.
+ *
+ * Setting up the clock on the MIPS boards.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/time.h>
+#include <linux/timex.h>
+
+#include <asm/mipsregs.h>
+#include <asm/mipsmtregs.h>
+#include <linux/hardirq.h>
+#include <asm/irq.h>
+#include <asm/div64.h>
+#include <linux/cpu.h>
+#include <linux/time.h>
+
+#include <asm/mips-boards/generic.h>
+#include <asm/mips-boards/prom.h>
+
+#include "powertv-clock.h"
+
+void __init plat_time_init(void)
+{
+ powertv_clocksource_init();
+ powertv_clockevent_init();
+}
|