+++ /dev/null
-CONFIG_ADM6996_PHY=y
-CONFIG_CPU_MIPS32_R1=y
-# CONFIG_CPU_MIPS32_R2 is not set
-CONFIG_CPU_MIPSR1=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_FIRMWARE_MEMMAP=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GPIO_GENERIC=y
-CONFIG_GPIO_GENERIC_PLATFORM=y
-CONFIG_HW_RANDOM=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-CONFIG_NLS=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SOC_AMAZON_SE=y
-# CONFIG_SOC_XWAY is not set
-CONFIG_SWCONFIG=y
-CONFIG_TARGET_ISA_REV=1
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
+++ /dev/null
-CONFIG_ARCH_32BIT_OFF_T=y
-CONFIG_ARCH_HIBERNATION_POSSIBLE=y
-CONFIG_ARCH_KEEP_MEMBLOCK=y
-CONFIG_ARCH_MMAP_RND_BITS_MAX=15
-CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MAX=15
-CONFIG_ARCH_SUSPEND_POSSIBLE=y
-CONFIG_CEVT_R4K=y
-CONFIG_CLONE_BACKWARDS=y
-CONFIG_COMPAT_32BIT_TIME=y
-CONFIG_CPU_BIG_ENDIAN=y
-CONFIG_CPU_GENERIC_DUMP_TLB=y
-CONFIG_CPU_HAS_DIEI=y
-CONFIG_CPU_HAS_PREFETCH=y
-CONFIG_CPU_HAS_RIXI=y
-CONFIG_CPU_HAS_SYNC=y
-CONFIG_CPU_MIPS32=y
-# CONFIG_CPU_MIPS32_R1 is not set
-CONFIG_CPU_MIPS32_R2=y
-CONFIG_CPU_MIPSR2=y
-CONFIG_CPU_MITIGATIONS=y
-CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
-CONFIG_CPU_R4K_CACHE_TLB=y
-CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
-CONFIG_CPU_SUPPORTS_HIGHMEM=y
-CONFIG_CPU_SUPPORTS_MSA=y
-CONFIG_CRYPTO_LIB_BLAKE2S_GENERIC=y
-CONFIG_CRYPTO_LIB_POLY1305_RSIZE=2
-CONFIG_CRYPTO_RNG2=y
-CONFIG_CSRC_R4K=y
-CONFIG_DMA_NONCOHERENT=y
-CONFIG_DTC=y
-# CONFIG_DT_EASY50712 is not set
-CONFIG_EARLY_PRINTK=y
-CONFIG_FIXED_PHY=y
-CONFIG_FUNCTION_ALIGNMENT=0
-CONFIG_FWNODE_MDIO=y
-CONFIG_FW_LOADER_PAGED_BUF=y
-CONFIG_GENERIC_ATOMIC64=y
-CONFIG_GENERIC_CLOCKEVENTS=y
-CONFIG_GENERIC_CMOS_UPDATE=y
-CONFIG_GENERIC_CPU_AUTOPROBE=y
-CONFIG_GENERIC_FIND_FIRST_BIT=y
-CONFIG_GENERIC_GETTIMEOFDAY=y
-CONFIG_GENERIC_IOMAP=y
-CONFIG_GENERIC_IRQ_CHIP=y
-CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
-CONFIG_GENERIC_IRQ_SHOW=y
-CONFIG_GENERIC_LIB_ASHLDI3=y
-CONFIG_GENERIC_LIB_ASHRDI3=y
-CONFIG_GENERIC_LIB_CMPDI2=y
-CONFIG_GENERIC_LIB_LSHRDI3=y
-CONFIG_GENERIC_LIB_UCMPDI2=y
-CONFIG_GENERIC_PCI_IOMAP=y
-CONFIG_GENERIC_PHY=y
-CONFIG_GENERIC_SCHED_CLOCK=y
-CONFIG_GENERIC_SMP_IDLE_THREAD=y
-CONFIG_GENERIC_TIME_VSYSCALL=y
-CONFIG_GPIO_CDEV=y
-CONFIG_GPIO_MM_LANTIQ=y
-CONFIG_GPIO_STP_XWAY=y
-CONFIG_HANDLE_DOMAIN_IRQ=y
-CONFIG_HARDWARE_WATCHPOINTS=y
-CONFIG_HAS_DMA=y
-CONFIG_HAS_IOMEM=y
-CONFIG_HAS_IOPORT_MAP=y
-CONFIG_HZ_PERIODIC=y
-CONFIG_INITRAMFS_SOURCE=""
-CONFIG_IRQCHIP=y
-CONFIG_IRQ_DOMAIN=y
-CONFIG_IRQ_FORCED_THREADING=y
-CONFIG_IRQ_MIPS_CPU=y
-CONFIG_IRQ_WORK=y
-CONFIG_LANTIQ=y
-CONFIG_LANTIQ_DT_NONE=y
-# CONFIG_LANTIQ_ETOP is not set
-CONFIG_LANTIQ_WDT=y
-# CONFIG_LANTIQ_XRX200 is not set
-CONFIG_LEDS_GPIO=y
-CONFIG_LIBFDT=y
-CONFIG_LOCK_DEBUGGING_SUPPORT=y
-CONFIG_MDIO_BUS=y
-CONFIG_MDIO_DEVICE=y
-CONFIG_MDIO_DEVRES=y
-CONFIG_MEMFD_CREATE=y
-CONFIG_MFD_CORE=y
-CONFIG_MFD_SYSCON=y
-CONFIG_MIGRATION=y
-CONFIG_MIPS=y
-CONFIG_MIPS_ASID_BITS=8
-CONFIG_MIPS_ASID_SHIFT=0
-CONFIG_MIPS_CLOCK_VSYSCALL=y
-# CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER is not set
-CONFIG_MIPS_CMDLINE_FROM_DTB=y
-CONFIG_MIPS_EBPF_JIT=y
-CONFIG_MIPS_L1_CACHE_SHIFT=5
-CONFIG_MIPS_LD_CAN_LINK_VDSO=y
-# CONFIG_MIPS_MT_SMP is not set
-# CONFIG_MIPS_NO_APPENDED_DTB is not set
-CONFIG_MIPS_RAW_APPENDED_DTB=y
-CONFIG_MIPS_SPRAM=y
-CONFIG_MODULES_USE_ELF_REL=y
-CONFIG_MTD_CFI_ADV_OPTIONS=y
-CONFIG_MTD_CFI_GEOMETRY=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_LANTIQ=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_MTD_SPLIT_BRNIMAGE_FW=y
-CONFIG_MTD_SPLIT_EVA_FW=y
-CONFIG_MTD_SPLIT_FIRMWARE=y
-CONFIG_MTD_SPLIT_TPLINK_FW=y
-CONFIG_MTD_SPLIT_UIMAGE_FW=y
-CONFIG_NEED_DMA_MAP_STATE=y
-CONFIG_NEED_PER_CPU_KM=y
-CONFIG_NET_SELFTESTS=y
-CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
-CONFIG_NVMEM=y
-CONFIG_NVMEM_LAYOUTS=y
-CONFIG_OF=y
-CONFIG_OF_ADDRESS=y
-CONFIG_OF_EARLY_FLATTREE=y
-CONFIG_OF_FLATTREE=y
-CONFIG_OF_GPIO=y
-CONFIG_OF_IRQ=y
-CONFIG_OF_KOBJ=y
-CONFIG_OF_MDIO=y
-CONFIG_PCI_DRIVERS_LEGACY=y
-CONFIG_PERF_USE_VMALLOC=y
-CONFIG_PGTABLE_LEVELS=2
-CONFIG_PHYLIB=y
-CONFIG_PHY_LANTIQ_RCU_USB2=y
-# CONFIG_PHY_LANTIQ_VRX200_PCIE is not set
-CONFIG_PINCTRL=y
-CONFIG_PINCTRL_LANTIQ=y
-# CONFIG_PINCTRL_SINGLE is not set
-CONFIG_PINCTRL_XWAY=y
-CONFIG_POWER_RESET=y
-CONFIG_POWER_RESET_SYSCON=y
-CONFIG_PTP_1588_CLOCK_OPTIONAL=y
-CONFIG_REGMAP=y
-CONFIG_REGMAP_MMIO=y
-CONFIG_RESET_CONTROLLER=y
-CONFIG_RESET_LANTIQ=y
-# CONFIG_SERIAL_8250 is not set
-CONFIG_SERIAL_LANTIQ=y
-CONFIG_SERIAL_LANTIQ_CONSOLE=y
-# CONFIG_SOC_AMAZON_SE is not set
-# CONFIG_SOC_FALCON is not set
-CONFIG_SOC_TYPE_XWAY=y
-CONFIG_SOC_XWAY=y
-CONFIG_SPI=y
-CONFIG_SPI_LANTIQ_SSC=y
-CONFIG_SPI_MASTER=y
-CONFIG_SPI_MEM=y
-CONFIG_SRCU=y
-CONFIG_SWAP_IO_SPACE=y
-CONFIG_SWPHY=y
-CONFIG_SYSCTL_EXCEPTION_TRACE=y
-CONFIG_SYS_HAS_CPU_MIPS32_R1=y
-CONFIG_SYS_HAS_CPU_MIPS32_R2=y
-CONFIG_SYS_HAS_EARLY_PRINTK=y
-CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
-CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
-CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
-CONFIG_SYS_SUPPORTS_MIPS16=y
-CONFIG_SYS_SUPPORTS_MULTITHREADING=y
-CONFIG_SYS_SUPPORTS_VPE_LOADER=y
-CONFIG_TARGET_ISA_REV=2
-CONFIG_TICK_CPU_ACCOUNTING=y
-CONFIG_TINY_SRCU=y
-CONFIG_USE_OF=y
-CONFIG_WATCHDOG_CORE=y
+++ /dev/null
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_SPLIT_FIRMWARE_NAME="linux"
-CONFIG_PINCTRL_FALCON=y
-CONFIG_SOC_FALCON=y
-# CONFIG_SOC_XWAY is not set
-CONFIG_SPI_FALCON=y
+++ /dev/null
-From 6f933347d0b4ed02d9534f5fa07f7b99f13eeaa1 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:12:28 +0200
-Subject: [PATCH 01/36] MIPS: lantiq: add pcie driver
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/lantiq/Kconfig | 10 +
- arch/mips/lantiq/xway/sysctrl.c | 2 +
- arch/mips/pci/Makefile | 2 +
- arch/mips/pci/fixup-lantiq-pcie.c | 82 +++
- arch/mips/pci/fixup-lantiq.c | 5 +-
- arch/mips/pci/ifxmips_pci_common.h | 57 ++
- arch/mips/pci/ifxmips_pcie.c | 1099 ++++++++++++++++++++++++++++++
- arch/mips/pci/ifxmips_pcie.h | 135 ++++
- arch/mips/pci/ifxmips_pcie_ar10.h | 290 ++++++++
- arch/mips/pci/ifxmips_pcie_msi.c | 392 +++++++++++
- arch/mips/pci/ifxmips_pcie_phy.c | 478 +++++++++++++
- arch/mips/pci/ifxmips_pcie_pm.c | 176 +++++
- arch/mips/pci/ifxmips_pcie_pm.h | 36 +
- arch/mips/pci/ifxmips_pcie_reg.h | 1001 +++++++++++++++++++++++++++
- arch/mips/pci/ifxmips_pcie_vr9.h | 271 ++++++++
- arch/mips/pci/pci.c | 25 +
- arch/mips/pci/pcie-lantiq.h | 1305 ++++++++++++++++++++++++++++++++++++
- drivers/pci/pcie/aer/Kconfig | 2 +-
- include/linux/pci.h | 2 +
- include/linux/pci_ids.h | 6 +
- 20 files changed, 5374 insertions(+), 2 deletions(-)
- create mode 100644 arch/mips/pci/fixup-lantiq-pcie.c
- create mode 100644 arch/mips/pci/ifxmips_pci_common.h
- create mode 100644 arch/mips/pci/ifxmips_pcie.c
- create mode 100644 arch/mips/pci/ifxmips_pcie.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_ar10.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_msi.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_phy.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_pm.c
- create mode 100644 arch/mips/pci/ifxmips_pcie_pm.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_reg.h
- create mode 100644 arch/mips/pci/ifxmips_pcie_vr9.h
- create mode 100644 arch/mips/pci/pcie-lantiq.h
-
---- a/arch/mips/lantiq/Kconfig
-+++ b/arch/mips/lantiq/Kconfig
-@@ -20,6 +20,7 @@ config SOC_XWAY
- bool "XWAY"
- select SOC_TYPE_XWAY
- select HAVE_PCI
-+ select ARCH_SUPPORTS_MSI
- select MFD_SYSCON
- select MFD_CORE
-
-@@ -52,4 +53,13 @@ config PCI_LANTIQ
- bool "PCI Support"
- depends on SOC_XWAY && PCI
-
-+config PCIE_LANTIQ
-+ bool "PCIE Support"
-+ depends on SOC_XWAY && PCI
-+
-+config PCIE_LANTIQ_MSI
-+ bool
-+ depends on PCIE_LANTIQ && PCI_MSI
-+ default y
-+
- endif
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -43,6 +43,8 @@ obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o
- obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
- obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
- obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
-+obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie_phy.o ifxmips_pcie.o fixup-lantiq-pcie.o
-+obj-$(CONFIG_PCIE_LANTIQ_MSI) += pcie-lantiq-msi.o
- obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
- obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
- obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
---- /dev/null
-+++ b/arch/mips/pci/fixup-lantiq-pcie.c
-@@ -0,0 +1,74 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_fixup_pcie.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_fixup_pcie.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe Fixup functions source file
-+*/
-+#include <linux/pci.h>
-+#include <linux/pci_regs.h>
-+#include <linux/pci_ids.h>
-+
-+#include <lantiq_soc.h>
-+
-+#include "pcie-lantiq.h"
-+
-+static void
-+ifx_pcie_fixup_resource(struct pci_dev *dev)
-+{
-+ u32 reg;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: enter\n", __func__, pci_name(dev));
-+
-+ printk("%s: fixup host controller %s (%04x:%04x)\n",
-+ __func__, pci_name(dev), dev->vendor, dev->device);
-+
-+ /* Setup COMMAND register */
-+ reg = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER /* |
-+ PCI_COMMAND_INTX_DISABLE */| PCI_COMMAND_SERR;
-+ pci_write_config_word(dev, PCI_COMMAND, reg);
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: exit\n", __func__, pci_name(dev));
-+}
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INFINEON, PCI_DEVICE_ID_INFINEON_PCIE, ifx_pcie_fixup_resource);
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LANTIQ, PCI_VENDOR_ID_LANTIQ, ifx_pcie_fixup_resource);
-+
-+static void
-+ifx_pcie_rc_class_early_fixup(struct pci_dev *dev)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: enter\n", __func__, pci_name(dev));
-+
-+ if (dev->devfn == PCI_DEVFN(0, 0) &&
-+ (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
-+
-+ dev->class = (PCI_CLASS_BRIDGE_PCI << 8) | (dev->class & 0xff);
-+
-+ printk(KERN_INFO "%s: fixed pcie host bridge to pci-pci bridge\n", __func__);
-+ }
-+ IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: exit\n", __func__, pci_name(dev));
-+ mdelay(10);
-+}
-+
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INFINEON, PCI_DEVICE_ID_INFINEON_PCIE,
-+ ifx_pcie_rc_class_early_fixup);
-+
-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LANTIQ, PCI_DEVICE_ID_LANTIQ_PCIE,
-+ ifx_pcie_rc_class_early_fixup);
---- a/arch/mips/pci/fixup-lantiq.c
-+++ b/arch/mips/pci/fixup-lantiq.c
-@@ -6,12 +6,19 @@
-
- #include <linux/of_irq.h>
- #include <linux/of_pci.h>
-+#include <linux/pci.h>
-+#include "ifxmips_pci_common.h"
-
- int (*ltq_pci_plat_arch_init)(struct pci_dev *dev) = NULL;
- int (*ltq_pci_plat_dev_init)(struct pci_dev *dev) = NULL;
-
- int pcibios_plat_dev_init(struct pci_dev *dev)
- {
-+#ifdef CONFIG_PCIE_LANTIQ
-+ if (pci_find_capability(dev, PCI_CAP_ID_EXP))
-+ ifx_pcie_bios_plat_dev_init(dev);
-+#endif
-+
- if (ltq_pci_plat_arch_init)
- return ltq_pci_plat_arch_init(dev);
-
-@@ -23,5 +30,10 @@ int pcibios_plat_dev_init(struct pci_dev
-
- int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
- {
-+#ifdef CONFIG_PCIE_LANTIQ
-+ if (pci_find_capability((struct pci_dev *)dev, PCI_CAP_ID_EXP))
-+ return ifx_pcie_bios_map_irq(dev, slot, pin);
-+#endif
-+
- return of_irq_parse_and_map_pci(dev, slot, pin);
- }
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pci_common.h
-@@ -0,0 +1,53 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pci_common.h
-+** PROJECT : IFX UEIP
-+** MODULES : PCI subsystem
-+**
-+** DATE : 30 June 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 30 June,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+
-+#ifndef IFXMIPS_PCI_COMMON_H
-+#define IFXMIPS_PCI_COMMON_H
-+#include <linux/version.h>
-+/*!
-+ \defgroup IFX_PCI_COM IFX PCI/PCIe common parts for OS integration
-+ \brief PCI/PCIe common parts
-+*/
-+
-+/*!
-+ \defgroup IFX_PCI_COM_OS OS APIs
-+ \ingroup IFX_PCI_COM
-+ \brief PCI/PCIe bus driver OS interface functions
-+*/
-+/*!
-+ \file ifxmips_pci_common.h
-+ \ingroup IFX_PCI_COM
-+ \brief PCI/PCIe bus driver common OS header file
-+*/
-+#define IFX_PCI_CONST const
-+#ifdef CONFIG_IFX_PCI
-+extern int ifx_pci_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin);
-+extern int ifx_pci_bios_plat_dev_init(struct pci_dev *dev);
-+#endif /* COFNIG_IFX_PCI */
-+
-+#ifdef CONFIG_PCIE_LANTIQ
-+extern int ifx_pcie_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin);
-+extern int ifx_pcie_bios_plat_dev_init(struct pci_dev *dev);
-+#endif
-+
-+#endif /* IFXMIPS_PCI_COMMON_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie.c
-@@ -0,0 +1,1091 @@
-+/*
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ *
-+ * Copyright (C) 2009 Lei Chuanhua <chuanhua.lei@infineon.com>
-+ * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/mm.h>
-+#include <asm/paccess.h>
-+#include <linux/pci.h>
-+#include <linux/pci_regs.h>
-+#include <linux/module.h>
-+
-+#include "ifxmips_pcie.h"
-+#include "ifxmips_pcie_reg.h"
-+
-+/* Enable 32bit io due to its mem mapped io nature */
-+#define IFX_PCIE_ERROR_INT
-+#define IFX_PCIE_IO_32BIT
-+
-+#define IFX_PCIE_IR (INT_NUM_IM4_IRL0 + 25)
-+#define IFX_PCIE_INTA (INT_NUM_IM4_IRL0 + 8)
-+#define IFX_PCIE_INTB (INT_NUM_IM4_IRL0 + 9)
-+#define IFX_PCIE_INTC (INT_NUM_IM4_IRL0 + 10)
-+#define IFX_PCIE_INTD (INT_NUM_IM4_IRL0 + 11)
-+#define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
-+#define SM(_v, _f) (((_v) << _f##_S) & (_f))
-+#define IFX_REG_SET_BIT(_f, _r) \
-+ IFX_REG_W32((IFX_REG_R32((_r)) &~ (_f)) | (_f), (_r))
-+
-+#define IFX_PCIE_LTSSM_ENABLE_TIMEOUT 10
-+
-+static DEFINE_SPINLOCK(ifx_pcie_lock);
-+
-+u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
-+
-+static ifx_pcie_irq_t pcie_irqs[IFX_PCIE_CORE_NR] = {
-+ {
-+ .ir_irq = {
-+ .irq = IFX_PCIE_IR,
-+ .name = "ifx_pcie_rc0",
-+ },
-+
-+ .legacy_irq = {
-+ {
-+ .irq_bit = PCIE_IRN_INTA,
-+ .irq = IFX_PCIE_INTA,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTB,
-+ .irq = IFX_PCIE_INTB,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTC,
-+ .irq = IFX_PCIE_INTC,
-+ },
-+ {
-+ .irq_bit = PCIE_IRN_INTD,
-+ .irq = IFX_PCIE_INTD,
-+ },
-+ },
-+ },
-+
-+};
-+
-+void ifx_pcie_debug(const char *fmt, ...)
-+{
-+ static char buf[256] = {0}; /* XXX */
-+ va_list ap;
-+
-+ va_start(ap, fmt);
-+ vsnprintf(buf, sizeof(buf), fmt, ap);
-+ va_end(ap);
-+
-+ printk("%s", buf);
-+}
-+
-+
-+static inline int pcie_ltssm_enable(int pcie_port)
-+{
-+ int i;
-+
-+ /* Enable LTSSM */
-+ IFX_REG_W32(PCIE_RC_CCR_LTSSM_ENABLE, PCIE_RC_CCR(pcie_port));
-+
-+ /* Wait for the link to come up */
-+ for (i = 0; i < IFX_PCIE_LTSSM_ENABLE_TIMEOUT; i++) {
-+ if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_RETRAIN_PENDING))
-+ return 0;
-+ udelay(10);
-+ }
-+
-+ printk("%s link timeout!!!!!\n", __func__);
-+ return -1;
-+}
-+
-+static inline void pcie_status_register_clear(int pcie_port)
-+{
-+ IFX_REG_W32(0, PCIE_RC_DR(pcie_port));
-+ IFX_REG_W32(0, PCIE_PCICMDSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_DCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_LCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_SLCTLSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_RSTS(pcie_port));
-+ IFX_REG_W32(0, PCIE_UES_R(pcie_port));
-+ IFX_REG_W32(0, PCIE_UEMR(pcie_port));
-+ IFX_REG_W32(0, PCIE_UESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_CESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_CEMR(pcie_port));
-+ IFX_REG_W32(0, PCIE_RESR(pcie_port));
-+ IFX_REG_W32(0, PCIE_PVCCRSR(pcie_port));
-+ IFX_REG_W32(0, PCIE_VC0_RSR0(pcie_port));
-+ IFX_REG_W32(0, PCIE_TPFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_TNPFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_TCFCS(pcie_port));
-+ IFX_REG_W32(0, PCIE_QSR(pcie_port));
-+ IFX_REG_W32(0, PCIE_IOBLSECS(pcie_port));
-+}
-+
-+static inline int ifx_pcie_link_up(int pcie_port)
-+{
-+ return (IFX_REG_R32(PCIE_PHY_SR(pcie_port)) & PCIE_PHY_SR_PHY_LINK_UP) ? 1 : 0;
-+}
-+
-+
-+static inline void pcie_mem_io_setup(int pcie_port)
-+{
-+ u32 reg;
-+ /*
-+ * BAR[0:1] readonly register
-+ * RC contains only minimal BARs for packets mapped to this device
-+ * Mem/IO filters defines a range of memory occupied by memory mapped IO devices that
-+ * reside on the downstream side fo the bridge.
-+ */
-+ reg = SM((PCIE_MEM_PHY_PORT_TO_END(pcie_port) >> 20), PCIE_MBML_MEM_LIMIT_ADDR)
-+ | SM((PCIE_MEM_PHY_PORT_TO_BASE(pcie_port) >> 20), PCIE_MBML_MEM_BASE_ADDR);
-+
-+ IFX_REG_W32(reg, PCIE_MBML(pcie_port));
-+
-+
-+#ifdef IFX_PCIE_PREFETCH_MEM_64BIT
-+ reg = SM((PCIE_MEM_PHY_PORT_TO_END(pcie_port) >> 20), PCIE_PMBL_END_ADDR)
-+ | SM((PCIE_MEM_PHY_PORT_TO_BASE(pcie_port) >> 20), PCIE_PMBL_UPPER_12BIT)
-+ | PCIE_PMBL_64BIT_ADDR;
-+ IFX_REG_W32(reg, PCIE_PMBL(pcie_port));
-+
-+ /* Must configure upper 32bit */
-+ IFX_REG_W32(0, PCIE_PMBU32(pcie_port));
-+ IFX_REG_W32(0, PCIE_PMLU32(pcie_port));
-+#else
-+ /* PCIe_PBML, same as MBML */
-+ IFX_REG_W32(IFX_REG_R32(PCIE_MBML(pcie_port)), PCIE_PMBL(pcie_port));
-+#endif
-+
-+ /* IO Address Range */
-+ reg = SM((PCIE_IO_PHY_PORT_TO_END(pcie_port) >> 12), PCIE_IOBLSECS_IO_LIMIT_ADDR)
-+ | SM((PCIE_IO_PHY_PORT_TO_BASE(pcie_port) >> 12), PCIE_IOBLSECS_IO_BASE_ADDR);
-+#ifdef IFX_PCIE_IO_32BIT
-+ reg |= PCIE_IOBLSECS_32BIT_IO_ADDR;
-+#endif /* IFX_PCIE_IO_32BIT */
-+ IFX_REG_W32(reg, PCIE_IOBLSECS(pcie_port));
-+
-+#ifdef IFX_PCIE_IO_32BIT
-+ reg = SM((PCIE_IO_PHY_PORT_TO_END(pcie_port) >> 16), PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT)
-+ | SM((PCIE_IO_PHY_PORT_TO_BASE(pcie_port) >> 16), PCIE_IO_BANDL_UPPER_16BIT_IO_BASE);
-+ IFX_REG_W32(reg, PCIE_IO_BANDL(pcie_port));
-+
-+#endif /* IFX_PCIE_IO_32BIT */
-+}
-+
-+static inline void
-+pcie_device_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Device capability register, set up Maximum payload size */
-+ reg = IFX_REG_R32(PCIE_DCAP(pcie_port));
-+ reg |= PCIE_DCAP_ROLE_BASE_ERR_REPORT;
-+ reg |= SM(PCIE_MAX_PAYLOAD_128, PCIE_DCAP_MAX_PAYLOAD_SIZE);
-+
-+ /* Only available for EP */
-+ reg &= ~(PCIE_DCAP_EP_L0S_LATENCY | PCIE_DCAP_EP_L1_LATENCY);
-+ IFX_REG_W32(reg, PCIE_DCAP(pcie_port));
-+
-+ /* Device control and status register */
-+ /* Set Maximum Read Request size for the device as a Requestor */
-+ reg = IFX_REG_R32(PCIE_DCTLSTS(pcie_port));
-+
-+ /*
-+ * Request size can be larger than the MPS used, but the completions returned
-+ * for the read will be bounded by the MPS size.
-+ * In our system, Max request size depends on AHB burst size. It is 64 bytes.
-+ * but we set it as 128 as minimum one.
-+ */
-+ reg |= SM(PCIE_MAX_PAYLOAD_128, PCIE_DCTLSTS_MAX_READ_SIZE)
-+ | SM(PCIE_MAX_PAYLOAD_128, PCIE_DCTLSTS_MAX_PAYLOAD_SIZE);
-+
-+ /* Enable relaxed ordering, no snoop, and all kinds of errors */
-+ reg |= PCIE_DCTLSTS_RELAXED_ORDERING_EN | PCIE_DCTLSTS_ERR_EN | PCIE_DCTLSTS_NO_SNOOP_EN;
-+
-+ IFX_REG_W32(reg, PCIE_DCTLSTS(pcie_port));
-+}
-+
-+static inline void
-+pcie_link_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /*
-+ * XXX, Link capability register, bit 18 for EP CLKREQ# dynamic clock management for L1, L2/3 CPM
-+ * L0s is reported during link training via TS1 order set by N_FTS
-+ */
-+ reg = IFX_REG_R32(PCIE_LCAP(pcie_port));
-+ reg &= ~PCIE_LCAP_L0S_EIXT_LATENCY;
-+ reg |= SM(3, PCIE_LCAP_L0S_EIXT_LATENCY);
-+ IFX_REG_W32(reg, PCIE_LCAP(pcie_port));
-+
-+ /* Link control and status register */
-+ reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
-+
-+ /* Link Enable, ASPM enabled */
-+ reg &= ~PCIE_LCTLSTS_LINK_DISABLE;
-+
-+#ifdef CONFIG_PCIEASPM
-+ /*
-+ * We use the same physical reference clock that the platform provides on the connector
-+ * It paved the way for ASPM to calculate the new exit Latency
-+ */
-+ reg |= PCIE_LCTLSTS_SLOT_CLK_CFG;
-+ reg |= PCIE_LCTLSTS_COM_CLK_CFG;
-+ /*
-+ * We should disable ASPM by default except that we have dedicated power management support
-+ * Enable ASPM will cause the system hangup/instability, performance degration
-+ */
-+ reg |= PCIE_LCTLSTS_ASPM_ENABLE;
-+#else
-+ reg &= ~PCIE_LCTLSTS_ASPM_ENABLE;
-+#endif /* CONFIG_PCIEASPM */
-+
-+ /*
-+ * The maximum size of any completion with data packet is bounded by the MPS setting
-+ * in device control register
-+ */
-+
-+ /* RCB may cause multiple split transactions, two options available, we use 64 byte RCB */
-+ reg &= ~ PCIE_LCTLSTS_RCB128;
-+
-+ IFX_REG_W32(reg, PCIE_LCTLSTS(pcie_port));
-+}
-+
-+static inline void pcie_error_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /*
-+ * Forward ERR_COR, ERR_NONFATAL, ERR_FATAL to the backbone
-+ * Poisoned write TLPs and completions indicating poisoned TLPs will set the PCIe_PCICMDSTS.MDPE
-+ */
-+ reg = IFX_REG_R32(PCIE_INTRBCTRL(pcie_port));
-+ reg |= PCIE_INTRBCTRL_SERR_ENABLE | PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE;
-+
-+ IFX_REG_W32(reg, PCIE_INTRBCTRL(pcie_port));
-+
-+ /* Uncorrectable Error Mask Register, Unmask <enable> all bits in PCIE_UESR */
-+ reg = IFX_REG_R32(PCIE_UEMR(pcie_port));
-+ reg &= ~PCIE_ALL_UNCORRECTABLE_ERR;
-+ IFX_REG_W32(reg, PCIE_UEMR(pcie_port));
-+
-+ /* Uncorrectable Error Severity Register, ALL errors are FATAL */
-+ IFX_REG_W32(PCIE_ALL_UNCORRECTABLE_ERR, PCIE_UESR(pcie_port));
-+
-+ /* Correctable Error Mask Register, unmask <enable> all bits */
-+ reg = IFX_REG_R32(PCIE_CEMR(pcie_port));
-+ reg &= ~PCIE_CORRECTABLE_ERR;
-+ IFX_REG_W32(reg, PCIE_CEMR(pcie_port));
-+
-+ /* Advanced Error Capabilities and Control Registr */
-+ reg = IFX_REG_R32(PCIE_AECCR(pcie_port));
-+ reg |= PCIE_AECCR_ECRC_CHECK_EN | PCIE_AECCR_ECRC_GEN_EN;
-+ IFX_REG_W32(reg, PCIE_AECCR(pcie_port));
-+
-+ /* Root Error Command Register, Report all types of errors */
-+ reg = IFX_REG_R32(PCIE_RECR(pcie_port));
-+ reg |= PCIE_RECR_ERR_REPORT_EN;
-+ IFX_REG_W32(reg, PCIE_RECR(pcie_port));
-+
-+ /* Clear the Root status register */
-+ reg = IFX_REG_R32(PCIE_RESR(pcie_port));
-+ IFX_REG_W32(reg, PCIE_RESR(pcie_port));
-+}
-+
-+static inline void pcie_port_logic_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* FTS number, default 12, increase to 63, may increase time from/to L0s to L0 */
-+ reg = IFX_REG_R32(PCIE_AFR(pcie_port));
-+ reg &= ~(PCIE_AFR_FTS_NUM | PCIE_AFR_COM_FTS_NUM);
-+ reg |= SM(PCIE_AFR_FTS_NUM_DEFAULT, PCIE_AFR_FTS_NUM)
-+ | SM(PCIE_AFR_FTS_NUM_DEFAULT, PCIE_AFR_COM_FTS_NUM);
-+ /* L0s and L1 entry latency */
-+ reg &= ~(PCIE_AFR_L0S_ENTRY_LATENCY | PCIE_AFR_L1_ENTRY_LATENCY);
-+ reg |= SM(PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT, PCIE_AFR_L0S_ENTRY_LATENCY)
-+ | SM(PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT, PCIE_AFR_L1_ENTRY_LATENCY);
-+ IFX_REG_W32(reg, PCIE_AFR(pcie_port));
-+
-+
-+ /* Port Link Control Register */
-+ reg = IFX_REG_R32(PCIE_PLCR(pcie_port));
-+ reg |= PCIE_PLCR_DLL_LINK_EN; /* Enable the DLL link */
-+ IFX_REG_W32(reg, PCIE_PLCR(pcie_port));
-+
-+ /* Lane Skew Register */
-+ reg = IFX_REG_R32(PCIE_LSR(pcie_port));
-+ /* Enable ACK/NACK and FC */
-+ reg &= ~(PCIE_LSR_ACKNAK_DISABLE | PCIE_LSR_FC_DISABLE);
-+ IFX_REG_W32(reg, PCIE_LSR(pcie_port));
-+
-+ /* Symbol Timer Register and Filter Mask Register 1 */
-+ reg = IFX_REG_R32(PCIE_STRFMR(pcie_port));
-+
-+ /* Default SKP interval is very accurate already, 5us */
-+ /* Enable IO/CFG transaction */
-+ reg |= PCIE_STRFMR_RX_CFG_TRANS_ENABLE | PCIE_STRFMR_RX_IO_TRANS_ENABLE;
-+ /* Disable FC WDT */
-+ reg &= ~PCIE_STRFMR_FC_WDT_DISABLE;
-+ IFX_REG_W32(reg, PCIE_STRFMR(pcie_port));
-+
-+ /* Filter Masker Register 2 */
-+ reg = IFX_REG_R32(PCIE_FMR2(pcie_port));
-+ reg |= PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 | PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1;
-+ IFX_REG_W32(reg, PCIE_FMR2(pcie_port));
-+
-+ /* VC0 Completion Receive Queue Control Register */
-+ reg = IFX_REG_R32(PCIE_VC0_CRQCR(pcie_port));
-+ reg &= ~PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE;
-+ reg |= SM(PCIE_VC0_TLP_QUEUE_MODE_BYPASS, PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE);
-+ IFX_REG_W32(reg, PCIE_VC0_CRQCR(pcie_port));
-+}
-+
-+static inline void pcie_rc_cfg_reg_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Disable LTSSM */
-+ IFX_REG_W32(0, PCIE_RC_CCR(pcie_port)); /* Disable LTSSM */
-+
-+ pcie_mem_io_setup(pcie_port);
-+
-+ /* XXX, MSI stuff should only apply to EP */
-+ /* MSI Capability: Only enable 32-bit addresses */
-+ reg = IFX_REG_R32(PCIE_MCAPR(pcie_port));
-+ reg &= ~PCIE_MCAPR_ADDR64_CAP;
-+
-+ reg |= PCIE_MCAPR_MSI_ENABLE;
-+
-+ /* Disable multiple message */
-+ reg &= ~(PCIE_MCAPR_MULTI_MSG_CAP | PCIE_MCAPR_MULTI_MSG_ENABLE);
-+ IFX_REG_W32(reg, PCIE_MCAPR(pcie_port));
-+
-+
-+ /* Enable PME, Soft reset enabled */
-+ reg = IFX_REG_R32(PCIE_PM_CSR(pcie_port));
-+ reg |= PCIE_PM_CSR_PME_ENABLE | PCIE_PM_CSR_SW_RST;
-+ IFX_REG_W32(reg, PCIE_PM_CSR(pcie_port));
-+
-+ /* setup the bus */
-+ reg = SM(0, PCIE_BNR_PRIMARY_BUS_NUM) | SM(1, PCIE_PNR_SECONDARY_BUS_NUM) | SM(0xFF, PCIE_PNR_SUB_BUS_NUM);
-+ IFX_REG_W32(reg, PCIE_BNR(pcie_port));
-+
-+
-+ pcie_device_setup(pcie_port);
-+ pcie_link_setup(pcie_port);
-+ pcie_error_setup(pcie_port);
-+
-+ /* Root control and capabilities register */
-+ reg = IFX_REG_R32(PCIE_RCTLCAP(pcie_port));
-+ reg |= PCIE_RCTLCAP_SERR_ENABLE | PCIE_RCTLCAP_PME_INT_EN;
-+ IFX_REG_W32(reg, PCIE_RCTLCAP(pcie_port));
-+
-+ /* Port VC Capability Register 2 */
-+ reg = IFX_REG_R32(PCIE_PVC2(pcie_port));
-+ reg &= ~PCIE_PVC2_VC_ARB_WRR;
-+ reg |= PCIE_PVC2_VC_ARB_16P_FIXED_WRR;
-+ IFX_REG_W32(reg, PCIE_PVC2(pcie_port));
-+
-+ /* VC0 Resource Capability Register */
-+ reg = IFX_REG_R32(PCIE_VC0_RC(pcie_port));
-+ reg &= ~PCIE_VC0_RC_REJECT_SNOOP;
-+ IFX_REG_W32(reg, PCIE_VC0_RC(pcie_port));
-+
-+ pcie_port_logic_setup(pcie_port);
-+}
-+
-+static int ifx_pcie_wait_phy_link_up(int pcie_port)
-+{
-+#define IFX_PCIE_PHY_LINK_UP_TIMEOUT 1000 /* XXX, tunable */
-+ int i;
-+
-+ /* Wait for PHY link is up */
-+ for (i = 0; i < IFX_PCIE_PHY_LINK_UP_TIMEOUT; i++) {
-+ if (ifx_pcie_link_up(pcie_port)) {
-+ break;
-+ }
-+ udelay(100);
-+ }
-+ if (i >= IFX_PCIE_PHY_LINK_UP_TIMEOUT) {
-+ printk(KERN_ERR "%s timeout\n", __func__);
-+ return -1;
-+ }
-+
-+ /* Check data link up or not */
-+ if (!(IFX_REG_R32(PCIE_RC_DR(pcie_port)) & PCIE_RC_DR_DLL_UP)) {
-+ printk(KERN_ERR "%s DLL link is still down\n", __func__);
-+ return -1;
-+ }
-+
-+ /* Check Data link active or not */
-+ if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_DLL_ACTIVE)) {
-+ printk(KERN_ERR "%s DLL is not active\n", __func__);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static inline int pcie_app_loigc_setup(int pcie_port)
-+{
-+ /* supress ahb bus errrors */
-+ IFX_REG_W32(PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS, PCIE_AHB_CTRL(pcie_port));
-+
-+ /* Pull PCIe EP out of reset */
-+ pcie_device_rst_deassert(pcie_port);
-+
-+ /* Start LTSSM training between RC and EP */
-+ pcie_ltssm_enable(pcie_port);
-+
-+ /* Check PHY status after enabling LTSSM */
-+ if (ifx_pcie_wait_phy_link_up(pcie_port) != 0)
-+ return -1;
-+
-+ return 0;
-+}
-+
-+/*
-+ * The numbers below are directly from the PCIe spec table 3-4/5.
-+ */
-+static inline void pcie_replay_time_update(int pcie_port)
-+{
-+ u32 reg;
-+ int nlw;
-+ int rtl;
-+
-+ reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
-+
-+ nlw = MS(reg, PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH);
-+ switch (nlw) {
-+ case PCIE_MAX_LENGTH_WIDTH_X1:
-+ rtl = 1677;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X2:
-+ rtl = 867;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X4:
-+ rtl = 462;
-+ break;
-+ case PCIE_MAX_LENGTH_WIDTH_X8:
-+ rtl = 258;
-+ break;
-+ default:
-+ rtl = 1677;
-+ break;
-+ }
-+ reg = IFX_REG_R32(PCIE_ALTRT(pcie_port));
-+ reg &= ~PCIE_ALTRT_REPLAY_TIME_LIMIT;
-+ reg |= SM(rtl, PCIE_ALTRT_REPLAY_TIME_LIMIT);
-+ IFX_REG_W32(reg, PCIE_ALTRT(pcie_port));
-+}
-+
-+/*
-+ * Table 359 Enhanced Configuration Address Mapping1)
-+ * 1) This table is defined in Table 7-1, page 341, PCI Express Base Specification v1.1
-+ * Memory Address PCI Express Configuration Space
-+ * A[(20+n-1):20] Bus Number 1 < n < 8
-+ * A[19:15] Device Number
-+ * A[14:12] Function Number
-+ * A[11:8] Extended Register Number
-+ * A[7:2] Register Number
-+ * A[1:0] Along with size of the access, used to generate Byte Enables
-+ * For VR9, only the address bits [22:0] are mapped to the configuration space:
-+ * . Address bits [22:20] select the target bus (1-of-8)1)
-+ * . Address bits [19:15] select the target device (1-of-32) on the bus
-+ * . Address bits [14:12] select the target function (1-of-8) within the device.
-+ * . Address bits [11:2] selects the target dword (1-of-1024) within the selected function.s configuration space
-+ * . Address bits [1:0] define the start byte location within the selected dword.
-+ */
-+static inline u32 pcie_bus_addr(u8 bus_num, u16 devfn, int where)
-+{
-+ u32 addr;
-+ u8 bus;
-+
-+ if (!bus_num) {
-+ /* type 0 */
-+ addr = ((PCI_SLOT(devfn) & 0x1F) << 15) | ((PCI_FUNC(devfn) & 0x7) << 12) | ((where & 0xFFF)& ~3);
-+ } else {
-+ bus = bus_num;
-+ /* type 1, only support 8 buses */
-+ addr = ((bus & 0x7) << 20) | ((PCI_SLOT(devfn) & 0x1F) << 15) |
-+ ((PCI_FUNC(devfn) & 0x7) << 12) | ((where & 0xFFF) & ~3);
-+ }
-+ return addr;
-+}
-+
-+static int pcie_valid_config(int pcie_port, int bus, int dev)
-+{
-+ /* RC itself */
-+ if ((bus == 0) && (dev == 0)) {
-+ return 1;
-+ }
-+
-+ /* No physical link */
-+ if (!ifx_pcie_link_up(pcie_port)) {
-+ return 0;
-+ }
-+
-+ /* Bus zero only has RC itself
-+ * XXX, check if EP will be integrated
-+ */
-+ if ((bus == 0) && (dev != 0)) {
-+ return 0;
-+ }
-+
-+ /* Maximum 8 buses supported for VRX */
-+ if (bus > 9) {
-+ return 0;
-+ }
-+
-+ /*
-+ * PCIe is PtP link, one bus only supports only one device
-+ * except bus zero and PCIe switch which is virtual bus device
-+ * The following two conditions really depends on the system design
-+ * and attached the device.
-+ * XXX, how about more new switch
-+ */
-+ if ((bus == 1) && (dev != 0)) {
-+ return 0;
-+ }
-+
-+ if ((bus >= 3) && (dev != 0)) {
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+static inline u32 ifx_pcie_cfg_rd(int pcie_port, u32 reg)
-+{
-+ return IFX_REG_R32((volatile u32 *)(PCIE_CFG_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline void ifx_pcie_cfg_wr(int pcie_port, unsigned int reg, u32 val)
-+{
-+ IFX_REG_W32( val, (volatile u32 *)(PCIE_CFG_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline u32 ifx_pcie_rc_cfg_rd(int pcie_port, u32 reg)
-+{
-+ return IFX_REG_R32((volatile u32 *)(PCIE_RC_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+static inline void ifx_pcie_rc_cfg_wr(int pcie_port, unsigned int reg, u32 val)
-+{
-+ IFX_REG_W32(val, (volatile u32 *)(PCIE_RC_PORT_TO_BASE(pcie_port) + reg));
-+}
-+
-+u32 ifx_pcie_bus_enum_read_hack(int where, u32 value)
-+{
-+ u32 tvalue = value;
-+
-+ if (where == PCI_PRIMARY_BUS) {
-+ u8 primary, secondary, subordinate;
-+
-+ primary = tvalue & 0xFF;
-+ secondary = (tvalue >> 8) & 0xFF;
-+ subordinate = (tvalue >> 16) & 0xFF;
-+ primary += pcibios_1st_host_bus_nr();
-+ secondary += pcibios_1st_host_bus_nr();
-+ subordinate += pcibios_1st_host_bus_nr();
-+ tvalue = (tvalue & 0xFF000000) | (u32)primary | (u32)(secondary << 8) | (u32)(subordinate << 16);
-+ }
-+ return tvalue;
-+}
-+
-+u32 ifx_pcie_bus_enum_write_hack(int where, u32 value)
-+{
-+ u32 tvalue = value;
-+
-+ if (where == PCI_PRIMARY_BUS) {
-+ u8 primary, secondary, subordinate;
-+
-+ primary = tvalue & 0xFF;
-+ secondary = (tvalue >> 8) & 0xFF;
-+ subordinate = (tvalue >> 16) & 0xFF;
-+ if (primary > 0 && primary != 0xFF) {
-+ primary -= pcibios_1st_host_bus_nr();
-+ }
-+
-+ if (secondary > 0 && secondary != 0xFF) {
-+ secondary -= pcibios_1st_host_bus_nr();
-+ }
-+ if (subordinate > 0 && subordinate != 0xFF) {
-+ subordinate -= pcibios_1st_host_bus_nr();
-+ }
-+ tvalue = (tvalue & 0xFF000000) | (u32)primary | (u32)(secondary << 8) | (u32)(subordinate << 16);
-+ }
-+ else if (where == PCI_SUBORDINATE_BUS) {
-+ u8 subordinate = tvalue & 0xFF;
-+
-+ subordinate = subordinate > 0 ? subordinate - pcibios_1st_host_bus_nr() : 0;
-+ tvalue = subordinate;
-+ }
-+ return tvalue;
-+}
-+
-+static int ifx_pcie_read_config(struct pci_bus *bus, u32 devfn,
-+ int where, int size, u32 *value)
-+{
-+ u32 data = 0;
-+ int bus_number = bus->number;
-+ static const u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
-+ int ret = PCIBIOS_SUCCESSFUL;
-+ struct ifx_pci_controller *ctrl = bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ if (unlikely(size != 1 && size != 2 && size != 4)){
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+
-+ /* Make sure the address is aligned to natural boundary */
-+ if (unlikely(((size - 1) & where))) {
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+
-+ /*
-+ * If we are second controller, we have to cheat OS so that it assume
-+ * its bus number starts from 0 in host controller
-+ */
-+ bus_number = ifx_pcie_bus_nr_deduct(bus_number, pcie_port);
-+
-+ /*
-+ * We need to force the bus number to be zero on the root
-+ * bus. Linux numbers the 2nd root bus to start after all
-+ * busses on root 0.
-+ */
-+ if (bus->parent == NULL) {
-+ bus_number = 0;
-+ }
-+
-+ /*
-+ * PCIe only has a single device connected to it. It is
-+ * always device ID 0. Don't bother doing reads for other
-+ * device IDs on the first segment.
-+ */
-+ if ((bus_number == 0) && (PCI_SLOT(devfn) != 0)) {
-+ ret = PCIBIOS_FUNC_NOT_SUPPORTED;
-+ goto out;
-+ }
-+
-+ if (pcie_valid_config(pcie_port, bus_number, PCI_SLOT(devfn)) == 0) {
-+ *value = 0xffffffff;
-+ ret = PCIBIOS_DEVICE_NOT_FOUND;
-+ goto out;
-+ }
-+
-+ PCIE_IRQ_LOCK(ifx_pcie_lock);
-+ if (bus_number == 0) { /* RC itself */
-+ u32 t;
-+
-+ t = (where & ~3);
-+ data = ifx_pcie_rc_cfg_rd(pcie_port, t);
-+ } else {
-+ u32 addr = pcie_bus_addr(bus_number, devfn, where);
-+
-+ data = ifx_pcie_cfg_rd(pcie_port, addr);
-+ #ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = le32_to_cpu(data);
-+ #endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ }
-+ /* To get a correct PCI topology, we have to restore the bus number to OS */
-+ data = ifx_pcie_bus_enum_hack(bus, devfn, where, data, pcie_port, 1);
-+
-+ PCIE_IRQ_UNLOCK(ifx_pcie_lock);
-+
-+ *value = (data >> (8 * (where & 3))) & mask[size & 7];
-+out:
-+ return ret;
-+}
-+
-+static u32 ifx_pcie_size_to_value(int where, int size, u32 data, u32 value)
-+{
-+ u32 shift;
-+ u32 tdata = data;
-+
-+ switch (size) {
-+ case 1:
-+ shift = (where & 0x3) << 3;
-+ tdata &= ~(0xffU << shift);
-+ tdata |= ((value & 0xffU) << shift);
-+ break;
-+ case 2:
-+ shift = (where & 3) << 3;
-+ tdata &= ~(0xffffU << shift);
-+ tdata |= ((value & 0xffffU) << shift);
-+ break;
-+ case 4:
-+ tdata = value;
-+ break;
-+ }
-+ return tdata;
-+}
-+
-+static int ifx_pcie_write_config(struct pci_bus *bus, u32 devfn,
-+ int where, int size, u32 value)
-+{
-+ int bus_number = bus->number;
-+ int ret = PCIBIOS_SUCCESSFUL;
-+ struct ifx_pci_controller *ctrl = bus->sysdata;
-+ int pcie_port = ctrl->port;
-+ u32 tvalue = value;
-+ u32 data;
-+
-+ /* Make sure the address is aligned to natural boundary */
-+ if (unlikely(((size - 1) & where))) {
-+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
-+ goto out;
-+ }
-+ /*
-+ * If we are second controller, we have to cheat OS so that it assume
-+ * its bus number starts from 0 in host controller
-+ */
-+ bus_number = ifx_pcie_bus_nr_deduct(bus_number, pcie_port);
-+
-+ /*
-+ * We need to force the bus number to be zero on the root
-+ * bus. Linux numbers the 2nd root bus to start after all
-+ * busses on root 0.
-+ */
-+ if (bus->parent == NULL) {
-+ bus_number = 0;
-+ }
-+
-+ if (pcie_valid_config(pcie_port, bus_number, PCI_SLOT(devfn)) == 0) {
-+ ret = PCIBIOS_DEVICE_NOT_FOUND;
-+ goto out;
-+ }
-+
-+ /* XXX, some PCIe device may need some delay */
-+ PCIE_IRQ_LOCK(ifx_pcie_lock);
-+
-+ /*
-+ * To configure the correct bus topology using native way, we have to cheat Os so that
-+ * it can configure the PCIe hardware correctly.
-+ */
-+ tvalue = ifx_pcie_bus_enum_hack(bus, devfn, where, value, pcie_port, 0);
-+
-+ if (bus_number == 0) { /* RC itself */
-+ u32 t;
-+
-+ t = (where & ~3);
-+ data = ifx_pcie_rc_cfg_rd(pcie_port, t);
-+
-+ data = ifx_pcie_size_to_value(where, size, data, tvalue);
-+
-+ ifx_pcie_rc_cfg_wr(pcie_port, t, data);
-+ } else {
-+ u32 addr = pcie_bus_addr(bus_number, devfn, where);
-+
-+ data = ifx_pcie_cfg_rd(pcie_port, addr);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = le32_to_cpu(data);
-+#endif
-+
-+ data = ifx_pcie_size_to_value(where, size, data, tvalue);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ data = cpu_to_le32(data);
-+#endif
-+ ifx_pcie_cfg_wr(pcie_port, addr, data);
-+ }
-+ PCIE_IRQ_UNLOCK(ifx_pcie_lock);
-+out:
-+ return ret;
-+}
-+
-+static struct resource ifx_pcie_io_resource = {
-+ .name = "PCIe0 I/O space",
-+ .start = PCIE_IO_PHY_BASE,
-+ .end = PCIE_IO_PHY_END,
-+ .flags = IORESOURCE_IO,
-+};
-+
-+static struct resource ifx_pcie_mem_resource = {
-+ .name = "PCIe0 Memory space",
-+ .start = PCIE_MEM_PHY_BASE,
-+ .end = PCIE_MEM_PHY_END,
-+ .flags = IORESOURCE_MEM,
-+};
-+
-+static struct pci_ops ifx_pcie_ops = {
-+ .read = ifx_pcie_read_config,
-+ .write = ifx_pcie_write_config,
-+};
-+
-+static struct ifx_pci_controller ifx_pcie_controller[IFX_PCIE_CORE_NR] = {
-+ {
-+ .pcic = {
-+ .pci_ops = &ifx_pcie_ops,
-+ .mem_resource = &ifx_pcie_mem_resource,
-+ .io_resource = &ifx_pcie_io_resource,
-+ },
-+ .port = IFX_PCIE_PORT0,
-+ },
-+};
-+
-+#ifdef IFX_PCIE_ERROR_INT
-+
-+static irqreturn_t pcie_rc_core_isr(int irq, void *dev_id)
-+{
-+ struct ifx_pci_controller *ctrl = (struct ifx_pci_controller *)dev_id;
-+ int pcie_port = ctrl->port;
-+ u32 reg;
-+
-+ pr_debug("PCIe RC error intr %d\n", irq);
-+ reg = IFX_REG_R32(PCIE_IRNCR(pcie_port));
-+ reg &= PCIE_RC_CORE_COMBINED_INT;
-+ IFX_REG_W32(reg, PCIE_IRNCR(pcie_port));
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static int
-+pcie_rc_core_int_init(int pcie_port)
-+{
-+ int ret;
-+
-+ /* Enable core interrupt */
-+ IFX_REG_SET_BIT(PCIE_RC_CORE_COMBINED_INT, PCIE_IRNEN(pcie_port));
-+
-+ /* Clear it first */
-+ IFX_REG_SET_BIT(PCIE_RC_CORE_COMBINED_INT, PCIE_IRNCR(pcie_port));
-+ ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, 0,
-+ pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
-+ if (ret)
-+ printk(KERN_ERR "%s request irq %d failed\n", __func__, IFX_PCIE_IR);
-+
-+ return ret;
-+}
-+#endif
-+
-+int ifx_pcie_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin)
-+{
-+ u32 irq_bit = 0;
-+ int irq = 0;
-+ struct ifx_pci_controller *ctrl = dev->bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ printk("%s port %d dev %s slot %d pin %d \n", __func__, pcie_port, pci_name(dev), slot, pin);
-+
-+ if ((pin == PCIE_LEGACY_DISABLE) || (pin > PCIE_LEGACY_INT_MAX)) {
-+ printk(KERN_WARNING "WARNING: dev %s: invalid interrupt pin %d\n", pci_name(dev), pin);
-+ return -1;
-+ }
-+
-+ /* Pin index so minus one */
-+ irq_bit = pcie_irqs[pcie_port].legacy_irq[pin - 1].irq_bit;
-+ irq = pcie_irqs[pcie_port].legacy_irq[pin - 1].irq;
-+ IFX_REG_SET_BIT(irq_bit, PCIE_IRNEN(pcie_port));
-+ IFX_REG_SET_BIT(irq_bit, PCIE_IRNCR(pcie_port));
-+ printk("%s dev %s irq %d assigned\n", __func__, pci_name(dev), irq);
-+ return irq;
-+}
-+
-+int ifx_pcie_bios_plat_dev_init(struct pci_dev *dev)
-+{
-+ u16 config;
-+#ifdef IFX_PCIE_ERROR_INT
-+ u32 dconfig;
-+ int pos;
-+#endif
-+
-+ /* Enable reporting System errors and parity errors on all devices */
-+ /* Enable parity checking and error reporting */
-+ pci_read_config_word(dev, PCI_COMMAND, &config);
-+ config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR /*| PCI_COMMAND_INVALIDATE |
-+ PCI_COMMAND_FAST_BACK*/;
-+ pci_write_config_word(dev, PCI_COMMAND, config);
-+
-+ if (dev->subordinate) {
-+ /* Set latency timers on sub bridges */
-+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40); /* XXX, */
-+ /* More bridge error detection */
-+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
-+ config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
-+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
-+ }
-+#ifdef IFX_PCIE_ERROR_INT
-+ /* Enable the PCIe normal error reporting */
-+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-+ if (pos) {
-+
-+ /* Disable system error generation in response to error messages */
-+ pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &config);
-+ config &= ~(PCI_EXP_RTCTL_SECEE | PCI_EXP_RTCTL_SENFEE | PCI_EXP_RTCTL_SEFEE);
-+ pci_write_config_word(dev, pos + PCI_EXP_RTCTL, config);
-+
-+ /* Clear PCIE Capability's Device Status */
-+ pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &config);
-+ pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, config);
-+
-+ /* Update Device Control */
-+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
-+ /* Correctable Error Reporting */
-+ config |= PCI_EXP_DEVCTL_CERE;
-+ /* Non-Fatal Error Reporting */
-+ config |= PCI_EXP_DEVCTL_NFERE;
-+ /* Fatal Error Reporting */
-+ config |= PCI_EXP_DEVCTL_FERE;
-+ /* Unsupported Request */
-+ config |= PCI_EXP_DEVCTL_URRE;
-+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
-+ }
-+
-+ /* Find the Advanced Error Reporting capability */
-+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
-+ if (pos) {
-+ /* Clear Uncorrectable Error Status */
-+ pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, dconfig);
-+ /* Enable reporting of all uncorrectable errors */
-+ /* Uncorrectable Error Mask - turned on bits disable errors */
-+ pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
-+ /*
-+ * Leave severity at HW default. This only controls if
-+ * errors are reported as uncorrectable or
-+ * correctable, not if the error is reported.
-+ */
-+ /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
-+ /* Clear Correctable Error Status */
-+ pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
-+ /* Enable reporting of all correctable errors */
-+ /* Correctable Error Mask - turned on bits disable errors */
-+ pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
-+ /* Advanced Error Capabilities */
-+ pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
-+ /* ECRC Generation Enable */
-+ if (dconfig & PCI_ERR_CAP_ECRC_GENC) {
-+ dconfig |= PCI_ERR_CAP_ECRC_GENE;
-+ }
-+ /* ECRC Check Enable */
-+ if (dconfig & PCI_ERR_CAP_ECRC_CHKC) {
-+ dconfig |= PCI_ERR_CAP_ECRC_CHKE;
-+ }
-+ pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
-+
-+ /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
-+ /* Enable Root Port's interrupt in response to error messages */
-+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
-+ PCI_ERR_ROOT_CMD_COR_EN |
-+ PCI_ERR_ROOT_CMD_NONFATAL_EN |
-+ PCI_ERR_ROOT_CMD_FATAL_EN);
-+ /* Clear the Root status register */
-+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
-+ pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
-+ }
-+#endif /* IFX_PCIE_ERROR_INT */
-+ /* WAR, only 128 MRRS is supported, force all EPs to support this value */
-+ pcie_set_readrq(dev, 128);
-+ return 0;
-+}
-+
-+static int
-+pcie_rc_initialize(int pcie_port)
-+{
-+ int i;
-+#define IFX_PCIE_PHY_LOOP_CNT 5
-+
-+ pcie_rcu_endian_setup(pcie_port);
-+
-+ pcie_ep_gpio_rst_init(pcie_port);
-+
-+ /*
-+ * XXX, PCIe elastic buffer bug will cause not to be detected. One more
-+ * reset PCIe PHY will solve this issue
-+ */
-+ for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
-+ /* Disable PCIe PHY Analog part for sanity check */
-+ pcie_phy_pmu_disable(pcie_port);
-+
-+ pcie_phy_rst_assert(pcie_port);
-+ pcie_phy_rst_deassert(pcie_port);
-+
-+ /* Make sure PHY PLL is stable */
-+ udelay(20);
-+
-+ /* PCIe Core reset enabled, low active, sw programmed */
-+ pcie_core_rst_assert(pcie_port);
-+
-+ /* Put PCIe EP in reset status */
-+ pcie_device_rst_assert(pcie_port);
-+
-+ /* PCI PHY & Core reset disabled, high active, sw programmed */
-+ pcie_core_rst_deassert(pcie_port);
-+
-+ /* Already in a quiet state, program PLL, enable PHY, check ready bit */
-+ pcie_phy_clock_mode_setup(pcie_port);
-+
-+ /* Enable PCIe PHY and Clock */
-+ pcie_core_pmu_setup(pcie_port);
-+
-+ /* Clear status registers */
-+ pcie_status_register_clear(pcie_port);
-+
-+#ifdef CONFIG_PCI_MSI
-+ pcie_msi_init(pcie_port);
-+#endif /* CONFIG_PCI_MSI */
-+ pcie_rc_cfg_reg_setup(pcie_port);
-+
-+ /* Once link is up, break out */
-+ if (pcie_app_loigc_setup(pcie_port) == 0)
-+ break;
-+ }
-+ if (i >= IFX_PCIE_PHY_LOOP_CNT) {
-+ printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
-+ return -EIO;
-+ }
-+ /* NB, don't increase ACK/NACK timer timeout value, which will cause a lot of COR errors */
-+ pcie_replay_time_update(pcie_port);
-+ return 0;
-+}
-+
-+static int __init ifx_pcie_bios_init(void)
-+{
-+ void __iomem *io_map_base;
-+ int pcie_port;
-+ int startup_port;
-+
-+ /* Enable AHB Master/ Slave */
-+ pcie_ahb_pmu_setup();
-+
-+ startup_port = IFX_PCIE_PORT0;
-+
-+ for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
-+ if (pcie_rc_initialize(pcie_port) == 0) {
-+ IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
-+ __func__, PCIE_CFG_PORT_TO_BASE(pcie_port));
-+ /* Otherwise, warning will pop up */
-+ io_map_base = ioremap(PCIE_IO_PHY_PORT_TO_BASE(pcie_port), PCIE_IO_SIZE);
-+ if (io_map_base == NULL) {
-+ IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
-+ return -ENOMEM;
-+ }
-+ ifx_pcie_controller[pcie_port].pcic.io_map_base = (unsigned long)io_map_base;
-+
-+ register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
-+ /* XXX, clear error status */
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: mem_resource 0x%p, io_resource 0x%p\n",
-+ __func__, &ifx_pcie_controller[pcie_port].pcic.mem_resource,
-+ &ifx_pcie_controller[pcie_port].pcic.io_resource);
-+
-+ #ifdef IFX_PCIE_ERROR_INT
-+ pcie_rc_core_int_init(pcie_port);
-+ #endif /* IFX_PCIE_ERROR_INT */
-+ }
-+ }
-+
-+ return 0;
-+}
-+arch_initcall(ifx_pcie_bios_init);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
-+MODULE_DESCRIPTION("Infineon builtin PCIe RC driver");
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie.h
-@@ -0,0 +1,131 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_H
-+#define IFXMIPS_PCIE_H
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+#include "ifxmips_pci_common.h"
-+#include "ifxmips_pcie_reg.h"
-+
-+/*!
-+ \defgroup IFX_PCIE PCI Express bus driver module
-+ \brief PCI Express IP module support VRX200
-+*/
-+
-+/*!
-+ \defgroup IFX_PCIE_OS OS APIs
-+ \ingroup IFX_PCIE
-+ \brief PCIe bus driver OS interface functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module common header file
-+*/
-+#define PCIE_IRQ_LOCK(lock) do { \
-+ unsigned long flags; \
-+ spin_lock_irqsave(&(lock), flags);
-+#define PCIE_IRQ_UNLOCK(lock) \
-+ spin_unlock_irqrestore(&(lock), flags); \
-+} while (0)
-+
-+#define PCIE_MSG_MSI 0x00000001
-+#define PCIE_MSG_ISR 0x00000002
-+#define PCIE_MSG_FIXUP 0x00000004
-+#define PCIE_MSG_READ_CFG 0x00000008
-+#define PCIE_MSG_WRITE_CFG 0x00000010
-+#define PCIE_MSG_CFG (PCIE_MSG_READ_CFG | PCIE_MSG_WRITE_CFG)
-+#define PCIE_MSG_REG 0x00000020
-+#define PCIE_MSG_INIT 0x00000040
-+#define PCIE_MSG_ERR 0x00000080
-+#define PCIE_MSG_PHY 0x00000100
-+#define PCIE_MSG_ANY 0x000001ff
-+
-+#define IFX_PCIE_PORT0 0
-+#define IFX_PCIE_PORT1 1
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+#define IFX_PCIE_CORE_NR 2
-+#else
-+#define IFX_PCIE_CORE_NR 1
-+#endif
-+
-+#define IFX_PCIE_ERROR_INT
-+
-+//#define IFX_PCIE_DBG
-+
-+#if defined(IFX_PCIE_DBG)
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) do { \
-+ ifx_pcie_debug((_fmt), ##args); \
-+} while (0)
-+
-+#define INLINE
-+#else
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) \
-+ do {} while(0)
-+#define INLINE inline
-+#endif
-+
-+struct ifx_pci_controller {
-+ struct pci_controller pcic;
-+
-+ /* RC specific, per host bus information */
-+ u32 port; /* Port index, 0 -- 1st core, 1 -- 2nd core */
-+};
-+
-+typedef struct ifx_pcie_ir_irq {
-+ const unsigned int irq;
-+ const char name[16];
-+}ifx_pcie_ir_irq_t;
-+
-+typedef struct ifx_pcie_legacy_irq{
-+ const u32 irq_bit;
-+ const int irq;
-+}ifx_pcie_legacy_irq_t;
-+
-+typedef struct ifx_pcie_irq {
-+ ifx_pcie_ir_irq_t ir_irq;
-+ ifx_pcie_legacy_irq_t legacy_irq[PCIE_LEGACY_INT_MAX];
-+}ifx_pcie_irq_t;
-+
-+extern u32 g_pcie_debug_flag;
-+extern void ifx_pcie_debug(const char *fmt, ...);
-+extern void pcie_phy_clock_mode_setup(int pcie_port);
-+extern void pcie_msi_pic_init(int pcie_port);
-+extern u32 ifx_pcie_bus_enum_read_hack(int where, u32 value);
-+extern u32 ifx_pcie_bus_enum_write_hack(int where, u32 value);
-+
-+#define CONFIG_VR9
-+
-+#ifdef CONFIG_VR9
-+#include "ifxmips_pcie_vr9.h"
-+#elif defined (CONFIG_AR10)
-+#include "ifxmips_pcie_ar10.h"
-+#else
-+#error "PCIE: platform not defined"
-+#endif /* CONFIG_VR9 */
-+
-+#endif /* IFXMIPS_PCIE_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_ar10.h
-@@ -0,0 +1,305 @@
-+/****************************************************************************
-+ Copyright (c) 2010
-+ Lantiq Deutschland GmbH
-+ Am Campeon 3; 85579 Neubiberg, Germany
-+
-+ For licensing information, see the file 'LICENSE' in the root folder of
-+ this software module.
-+
-+ *****************************************************************************/
-+/*!
-+ \file ifxmips_pcie_ar10.h
-+ \ingroup IFX_PCIE
-+ \brief PCIe RC driver ar10 specific file
-+*/
-+
-+#ifndef IFXMIPS_PCIE_AR10_H
-+#define IFXMIPS_PCIE_AR10_H
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+
-+/* Project header file */
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_pmu.h>
-+#include <asm/ifx/ifx_gpio.h>
-+#include <asm/ifx/ifx_ebu_led.h>
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+ ifx_ebu_led_enable();
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 1);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 1);
-+ }
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ /* XXX, moved to CGU to control AHBM */
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Inbound, big endian */
-+ reg |= IFX_RCU_BE_AHB4S;
-+ if (pcie_port == 0) {
-+ reg |= IFX_RCU_BE_PCIE0M;
-+
-+ #ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ /* Outbound, software swap needed */
-+ reg |= IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE0S;
-+ #else
-+ /* Outbound little endian */
-+ reg &= ~IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE0S;
-+ #endif
-+ }
-+ else {
-+ reg |= IFX_RCU_BE_PCIE1M;
-+ #ifdef CONFIG_IFX_PCIE1_HW_SWAP
-+ /* Outbound, software swap needed */
-+ reg |= IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE1S;
-+ #else
-+ /* Outbound little endian */
-+ reg &= ~IFX_RCU_BE_AHB3M;
-+ reg &= ~IFX_RCU_BE_PCIE1S;
-+ #endif
-+ }
-+
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ if (pcie_port == 0) { /* XXX, should use macro*/
-+ PCIE0_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PCIE1_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ if (pcie_port == 0) { /* XXX, should use macro*/
-+ PCIE0_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+ }
-+ else {
-+ PCIE1_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+ }
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ if (pcie_port == 0) {
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_BE_PCIE0_PDI;
-+ }
-+ else {
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_BE_PCIE1_PDI;
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ /* Enable PDI to access PCIe PHY register */
-+ PDI0_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PDI1_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset Core, bit 22 */
-+ if (pcie_port == 0) {
-+ reg |= 0x00400000;
-+ }
-+ else {
-+ reg |= 0x08000000; /* Bit 27 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg &= ~0x00400000; /* bit 22 */
-+ }
-+ else {
-+ reg &= ~0x08000000; /* Bit 27 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg |= 0x00001000; /* Bit 12 */
-+ }
-+ else {
-+ reg |= 0x00002000; /* Bit 13 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ if (pcie_port == 0) {
-+ reg &= ~0x00001000; /* Bit 12 */
-+ }
-+ else {
-+ reg &= ~0x00002000; /* Bit 13 */
-+ }
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 0);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 0);
-+ }
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ if (pcie_port == 0) {
-+ ifx_ebu_led_set_data(11, 1);
-+ }
-+ else {
-+ ifx_ebu_led_set_data(12, 1);
-+ }
-+ ifx_ebu_led_disable();
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ if (pcie_port == 0) {
-+ PCIE0_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ PCIE1_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ pcie_msi_pic_init(pcie_port);
-+ if (pcie_port == 0) {
-+ MSI0_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+ else {
-+ MSI1_PMU_SETUP(IFX_PMU_ENABLE);
-+ }
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+ }
-+#endif /* CONFIG_IFX_PCI */
-+ return tbus_number;
-+}
-+
-+static struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ }
-+ #endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_AR10_H */
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_msi.c
-@@ -0,0 +1,391 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_msi.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCI MSI sub module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe MSI Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Date $Author $Comment
-+** 02 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \defgroup IFX_PCIE_MSI MSI OS APIs
-+ \ingroup IFX_PCIE
-+ \brief PCIe bus driver OS interface functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie_msi.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe MSI OS interface file
-+*/
-+
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/init.h>
-+#include <linux/sched.h>
-+#include <linux/slab.h>
-+#include <linux/interrupt.h>
-+#include <linux/kernel_stat.h>
-+#include <linux/pci.h>
-+#include <linux/msi.h>
-+#include <linux/module.h>
-+#include <asm/bootinfo.h>
-+#include <asm/irq.h>
-+#include <asm/traps.h>
-+
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_regs.h>
-+#include <asm/ifx/common_routines.h>
-+#include <asm/ifx/irq.h>
-+
-+#include "ifxmips_pcie_reg.h"
-+#include "ifxmips_pcie.h"
-+
-+#define IFX_MSI_IRQ_NUM 16
-+
-+enum {
-+ IFX_PCIE_MSI_IDX0 = 0,
-+ IFX_PCIE_MSI_IDX1,
-+ IFX_PCIE_MSI_IDX2,
-+ IFX_PCIE_MSI_IDX3,
-+};
-+
-+typedef struct ifx_msi_irq_idx {
-+ const int irq;
-+ const int idx;
-+}ifx_msi_irq_idx_t;
-+
-+struct ifx_msi_pic {
-+ volatile u32 pic_table[IFX_MSI_IRQ_NUM];
-+ volatile u32 pic_endian; /* 0x40 */
-+};
-+typedef struct ifx_msi_pic *ifx_msi_pic_t;
-+
-+typedef struct ifx_msi_irq {
-+ const volatile ifx_msi_pic_t msi_pic_p;
-+ const u32 msi_phy_base;
-+ const ifx_msi_irq_idx_t msi_irq_idx[IFX_MSI_IRQ_NUM];
-+ /*
-+ * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
-+ * in use.
-+ */
-+ u16 msi_free_irq_bitmask;
-+
-+ /*
-+ * Each bit in msi_multiple_irq_bitmask tells that the device using
-+ * this bit in msi_free_irq_bitmask is also using the next bit. This
-+ * is used so we can disable all of the MSI interrupts when a device
-+ * uses multiple.
-+ */
-+ u16 msi_multiple_irq_bitmask;
-+}ifx_msi_irq_t;
-+
-+static ifx_msi_irq_t msi_irqs[IFX_PCIE_CORE_NR] = {
-+ {
-+ .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI_PIC_REG_BASE,
-+ .msi_phy_base = PCIE_MSI_PHY_BASE,
-+ .msi_irq_idx = {
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ },
-+ .msi_free_irq_bitmask = 0,
-+ .msi_multiple_irq_bitmask= 0,
-+ },
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ {
-+ .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI1_PIC_REG_BASE,
-+ .msi_phy_base = PCIE1_MSI_PHY_BASE,
-+ .msi_irq_idx = {
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
-+ {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
-+ },
-+ .msi_free_irq_bitmask = 0,
-+ .msi_multiple_irq_bitmask= 0,
-+
-+ },
-+#endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+};
-+
-+/*
-+ * This lock controls updates to msi_free_irq_bitmask,
-+ * msi_multiple_irq_bitmask and pic register settting
-+ */
-+static DEFINE_SPINLOCK(ifx_pcie_msi_lock);
-+
-+void pcie_msi_pic_init(int pcie_port)
-+{
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_pic_p->pic_endian = IFX_MSI_PIC_BIG_ENDIAN;
-+ spin_unlock(&ifx_pcie_msi_lock);
-+}
-+
-+/**
-+ * \fn int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-+ * \brief Called when a driver request MSI interrupts instead of the
-+ * legacy INT A-D. This routine will allocate multiple interrupts
-+ * for MSI devices that support them. A device can override this by
-+ * programming the MSI control bits [6:4] before calling
-+ * pci_enable_msi().
-+ *
-+ * \param[in] pdev Device requesting MSI interrupts
-+ * \param[in] desc MSI descriptor
-+ *
-+ * \return -EINVAL Invalid pcie root port or invalid msi bit
-+ * \return 0 OK
-+ * \ingroup IFX_PCIE_MSI
-+ */
-+int
-+arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
-+{
-+ int irq, pos;
-+ u16 control;
-+ int irq_idx;
-+ int irq_step;
-+ int configured_private_bits;
-+ int request_private_bits;
-+ struct msi_msg msg;
-+ u16 search_mask;
-+ struct ifx_pci_controller *ctrl = pdev->bus->sysdata;
-+ int pcie_port = ctrl->port;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s %s enter\n", __func__, pci_name(pdev));
-+
-+ /* XXX, skip RC MSI itself */
-+ if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s RC itself doesn't use MSI interrupt\n", __func__);
-+ return -EINVAL;
-+ }
-+
-+ /*
-+ * Read the MSI config to figure out how many IRQs this device
-+ * wants. Most devices only want 1, which will give
-+ * configured_private_bits and request_private_bits equal 0.
-+ */
-+ pci_read_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &control);
-+
-+ /*
-+ * If the number of private bits has been configured then use
-+ * that value instead of the requested number. This gives the
-+ * driver the chance to override the number of interrupts
-+ * before calling pci_enable_msi().
-+ */
-+ configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
-+ if (configured_private_bits == 0) {
-+ /* Nothing is configured, so use the hardware requested size */
-+ request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
-+ }
-+ else {
-+ /*
-+ * Use the number of configured bits, assuming the
-+ * driver wanted to override the hardware request
-+ * value.
-+ */
-+ request_private_bits = configured_private_bits;
-+ }
-+
-+ /*
-+ * The PCI 2.3 spec mandates that there are at most 32
-+ * interrupts. If this device asks for more, only give it one.
-+ */
-+ if (request_private_bits > 5) {
-+ request_private_bits = 0;
-+ }
-+again:
-+ /*
-+ * The IRQs have to be aligned on a power of two based on the
-+ * number being requested.
-+ */
-+ irq_step = (1 << request_private_bits);
-+
-+ /* Mask with one bit for each IRQ */
-+ search_mask = (1 << irq_step) - 1;
-+
-+ /*
-+ * We're going to search msi_free_irq_bitmask_lock for zero
-+ * bits. This represents an MSI interrupt number that isn't in
-+ * use.
-+ */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos += irq_step) {
-+ if ((msi_irqs[pcie_port].msi_free_irq_bitmask & (search_mask << pos)) == 0) {
-+ msi_irqs[pcie_port].msi_free_irq_bitmask |= search_mask << pos;
-+ msi_irqs[pcie_port].msi_multiple_irq_bitmask |= (search_mask >> 1) << pos;
-+ break;
-+ }
-+ }
-+ spin_unlock(&ifx_pcie_msi_lock);
-+
-+ /* Make sure the search for available interrupts didn't fail */
-+ if (pos >= IFX_MSI_IRQ_NUM) {
-+ if (request_private_bits) {
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s: Unable to find %d free "
-+ "interrupts, trying just one", __func__, 1 << request_private_bits);
-+ request_private_bits = 0;
-+ goto again;
-+ }
-+ else {
-+ printk(KERN_ERR "%s: Unable to find a free MSI interrupt\n", __func__);
-+ return -EINVAL;
-+ }
-+ }
-+ irq = msi_irqs[pcie_port].msi_irq_idx[pos].irq;
-+ irq_idx = msi_irqs[pcie_port].msi_irq_idx[pos].idx;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "pos %d, irq %d irq_idx %d\n", pos, irq, irq_idx);
-+
-+ /*
-+ * Initialize MSI. This has to match the memory-write endianess from the device
-+ * Address bits [23:12]
-+ */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] = SM(irq_idx, IFX_MSI_PIC_INT_LINE) |
-+ SM((msi_irqs[pcie_port].msi_phy_base >> 12), IFX_MSI_PIC_MSG_ADDR) |
-+ SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
-+
-+ /* Enable this entry */
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~IFX_MSI_PCI_INT_DISABLE;
-+ spin_unlock(&ifx_pcie_msi_lock);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "pic_table[%d]: 0x%08x\n",
-+ pos, msi_irqs[pcie_port].msi_pic_p->pic_table[pos]);
-+
-+ /* Update the number of IRQs the device has available to it */
-+ control &= ~PCI_MSI_FLAGS_QSIZE;
-+ control |= (request_private_bits << 4);
-+ pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, control);
-+
-+ set_irq_msi(irq, desc);
-+ msg.address_hi = 0x0;
-+ msg.address_lo = msi_irqs[pcie_port].msi_phy_base;
-+ msg.data = SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "msi_data: pos %d 0x%08x\n", pos, msg.data);
-+
-+ write_msi_msg(irq, &msg);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
-+ return 0;
-+}
-+
-+static int
-+pcie_msi_irq_to_port(unsigned int irq, int *port)
-+{
-+ int ret = 0;
-+
-+ if (irq == IFX_PCIE_MSI_IR0 || irq == IFX_PCIE_MSI_IR1 ||
-+ irq == IFX_PCIE_MSI_IR2 || irq == IFX_PCIE_MSI_IR3) {
-+ *port = IFX_PCIE_PORT0;
-+ }
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+ else if (irq == IFX_PCIE1_MSI_IR0 || irq == IFX_PCIE1_MSI_IR1 ||
-+ irq == IFX_PCIE1_MSI_IR2 || irq == IFX_PCIE1_MSI_IR3) {
-+ *port = IFX_PCIE_PORT1;
-+ }
-+#endif /* CONFIG_IFX_PCIE_2ND_CORE */
-+ else {
-+ printk(KERN_ERR "%s: Attempted to teardown illegal "
-+ "MSI interrupt (%d)\n", __func__, irq);
-+ ret = -EINVAL;
-+ }
-+ return ret;
-+}
-+
-+/**
-+ * \fn void arch_teardown_msi_irq(unsigned int irq)
-+ * \brief Called when a device no longer needs its MSI interrupts. All
-+ * MSI interrupts for the device are freed.
-+ *
-+ * \param irq The devices first irq number. There may be multple in sequence.
-+ * \return none
-+ * \ingroup IFX_PCIE_MSI
-+ */
-+void
-+arch_teardown_msi_irq(unsigned int irq)
-+{
-+ int pos;
-+ int number_irqs;
-+ u16 bitmask;
-+ int pcie_port;
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s enter\n", __func__);
-+
-+ BUG_ON(irq > INT_NUM_IM4_IRL31);
-+
-+ if (pcie_msi_irq_to_port(irq, &pcie_port) != 0) {
-+ return;
-+ }
-+
-+ /* Shift the mask to the correct bit location, not always correct
-+ * Probally, the first match will be chosen.
-+ */
-+ for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos++) {
-+ if ((msi_irqs[pcie_port].msi_irq_idx[pos].irq == irq)
-+ && (msi_irqs[pcie_port].msi_free_irq_bitmask & ( 1 << pos))) {
-+ break;
-+ }
-+ }
-+ if (pos >= IFX_MSI_IRQ_NUM) {
-+ printk(KERN_ERR "%s: Unable to find a matched MSI interrupt\n", __func__);
-+ return;
-+ }
-+ spin_lock(&ifx_pcie_msi_lock);
-+ /* Disable this entry */
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] |= IFX_MSI_PCI_INT_DISABLE;
-+ msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~(IFX_MSI_PIC_INT_LINE | IFX_MSI_PIC_MSG_ADDR | IFX_MSI_PIC_MSG_DATA);
-+ spin_unlock(&ifx_pcie_msi_lock);
-+ /*
-+ * Count the number of IRQs we need to free by looking at the
-+ * msi_multiple_irq_bitmask. Each bit set means that the next
-+ * IRQ is also owned by this device.
-+ */
-+ number_irqs = 0;
-+ while (((pos + number_irqs) < IFX_MSI_IRQ_NUM) &&
-+ (msi_irqs[pcie_port].msi_multiple_irq_bitmask & (1 << (pos + number_irqs)))) {
-+ number_irqs++;
-+ }
-+ number_irqs++;
-+
-+ /* Mask with one bit for each IRQ */
-+ bitmask = (1 << number_irqs) - 1;
-+
-+ bitmask <<= pos;
-+ if ((msi_irqs[pcie_port].msi_free_irq_bitmask & bitmask) != bitmask) {
-+ printk(KERN_ERR "%s: Attempted to teardown MSI "
-+ "interrupt (%d) not in use\n", __func__, irq);
-+ return;
-+ }
-+ /* Checks are done, update the in use bitmask */
-+ spin_lock(&ifx_pcie_msi_lock);
-+ msi_irqs[pcie_port].msi_free_irq_bitmask &= ~bitmask;
-+ msi_irqs[pcie_port].msi_multiple_irq_bitmask &= ~(bitmask >> 1);
-+ spin_unlock(&ifx_pcie_msi_lock);
-+ IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
-+}
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
-+MODULE_DESCRIPTION("Infineon PCIe IP builtin MSI PIC driver");
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_phy.c
-@@ -0,0 +1,478 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_phy.c
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe PHY sub module
-+**
-+** DATE : 14 May 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 14 May,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_pcie_phy.c
-+ \ingroup IFX_PCIE
-+ \brief PCIe PHY PLL register programming source file
-+*/
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/paccess.h>
-+#include <linux/delay.h>
-+
-+#include "ifxmips_pcie_reg.h"
-+#include "ifxmips_pcie.h"
-+
-+/* PCIe PDI only supports 16 bit operation */
-+
-+#define IFX_PCIE_PHY_REG_WRITE16(__addr, __data) \
-+ ((*(volatile u16 *) (__addr)) = (__data))
-+
-+#define IFX_PCIE_PHY_REG_READ16(__addr) \
-+ (*(volatile u16 *) (__addr))
-+
-+#define IFX_PCIE_PHY_REG16(__addr) \
-+ (*(volatile u16 *) (__addr))
-+
-+#define IFX_PCIE_PHY_REG(__reg, __value, __mask) do { \
-+ u16 read_data; \
-+ u16 write_data; \
-+ read_data = IFX_PCIE_PHY_REG_READ16((__reg)); \
-+ write_data = (read_data & ((u16)~(__mask))) | (((u16)(__value)) & ((u16)(__mask)));\
-+ IFX_PCIE_PHY_REG_WRITE16((__reg), write_data); \
-+} while (0)
-+
-+#define IFX_PCIE_PLL_TIMEOUT 1000 /* Tunnable */
-+
-+//#define IFX_PCI_PHY_REG_DUMP
-+
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+static void
-+pcie_phy_reg_dump(int pcie_port)
-+{
-+ printk("PLL REGFILE\n");
-+ printk("PCIE_PHY_PLL_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL4 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL4(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL5 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL5(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL6 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL6(pcie_port)));
-+ printk("PCIE_PHY_PLL_CTRL7 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL7(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_PLL_A_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_PLL_STATUS 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)));
-+
-+ printk("TX1 REGFILE\n");
-+ printk("PCIE_PHY_TX1_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX1_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX1_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL3(pcie_port)));
-+ printk("PCIE_PHY_TX1_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX1_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD1(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD2(pcie_port)));
-+ printk("PCIE_PHY_TX1_MOD3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD3(pcie_port)));
-+
-+ printk("TX2 REGFILE\n");
-+ printk("PCIE_PHY_TX2_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX2_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX2_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_A_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_TX2_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_A_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD1(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD2(pcie_port)));
-+ printk("PCIE_PHY_TX2_MOD3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD3(pcie_port)));
-+
-+ printk("RX1 REGFILE\n");
-+ printk("PCIE_PHY_RX1_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CTRL1(pcie_port)));
-+ printk("PCIE_PHY_RX1_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CTRL2(pcie_port)));
-+ printk("PCIE_PHY_RX1_CDR 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CDR(pcie_port)));
-+ printk("PCIE_PHY_RX1_EI 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_EI(pcie_port)));
-+ printk("PCIE_PHY_RX1_A_CTRL 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_A_CTRL(pcie_port)));
-+}
-+#endif /* IFX_PCI_PHY_REG_DUMP */
-+
-+static void
-+pcie_phy_comm_setup(int pcie_port)
-+{
-+ /* PLL Setting */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
-+
-+ /* increase the bias reference voltage */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF);
-+
-+ /* Endcnt */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF);
-+
-+ /* force */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
-+
-+ /* ctrl_lim */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
-+
-+ /* ctrl */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
-+
-+ /* RTERM*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
-+
-+ /* Improved 100MHz clock output */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF);
-+
-+ /* Reduced CDR BW to avoid glitches */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
-+}
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+static void
-+pcie_phy_36mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE
-+static void
-+pcie_phy_36mhz_ssc_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+
-+ /* PLL Setting */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
-+
-+ /* Increase the bias reference voltage */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF);
-+
-+ /* Endcnt */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF);
-+
-+ /* Force */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
-+
-+ /* Predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
-+
-+ /* ctrl_lim */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
-+
-+ /* ctrl */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
-+
-+ /* predrv_ser_en */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
-+
-+ /* RTERM*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
-+
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0400, 0x0400);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0100);
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1c72, 0xFFFF);
-+
-+ /* improved 100MHz clock output */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF);
-+
-+ /* reduced CDR BW to avoid glitches */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_25MHZ_MODE
-+static void
-+pcie_phy_25mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0200);
-+
-+ /* en_ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0002, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0040, 0x0070);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x6000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x4000, 0x4000);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_25MHZ_MODE */
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_100MHZ_MODE
-+static void
-+pcie_phy_100mhz_mode_setup(int pcie_port)
-+{
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+ /* en_ext_mmd_div_ratio */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
-+
-+ /* ext_mmd_div_ratio*/
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
-+
-+ /* pll_ensdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
-+
-+ /* en_const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
-+
-+ /* mmd */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
-+
-+ /* lf_mode */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
-+
-+ /* const_sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
-+
-+ /* const sdm */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
-+
-+ /* pllmod */
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF);
-+
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
-+}
-+#endif /* CONFIG_IFX_PCIE_PHY_100MHZ_MODE */
-+
-+static int
-+pcie_phy_wait_startup_ready(int pcie_port)
-+{
-+ int i;
-+
-+ for (i = 0; i < IFX_PCIE_PLL_TIMEOUT; i++) {
-+ if ((IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)) & 0x0040) != 0) {
-+ break;
-+ }
-+ udelay(10);
-+ }
-+ if (i >= IFX_PCIE_PLL_TIMEOUT) {
-+ printk(KERN_ERR "%s PLL Link timeout\n", __func__);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+static void
-+pcie_phy_load_enable(int pcie_port, int slice)
-+{
-+ /* Set the load_en of tx/rx slice to '1' */
-+ switch (slice) {
-+ case 1:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0010, 0x0010);
-+ break;
-+ case 2:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0010, 0x0010);
-+ break;
-+ case 3:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0002, 0x0002);
-+ break;
-+ }
-+}
-+
-+static void
-+pcie_phy_load_disable(int pcie_port, int slice)
-+{
-+ /* set the load_en of tx/rx slice to '0' */
-+ switch (slice) {
-+ case 1:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0000, 0x0010);
-+ break;
-+ case 2:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0000, 0x0010);
-+ break;
-+ case 3:
-+ IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0000, 0x0002);
-+ break;
-+ }
-+}
-+
-+static void
-+pcie_phy_load_war(int pcie_port)
-+{
-+ int slice;
-+
-+ for (slice = 1; slice < 4; slice++) {
-+ pcie_phy_load_enable(pcie_port, slice);
-+ udelay(1);
-+ pcie_phy_load_disable(pcie_port, slice);
-+ }
-+}
-+
-+static void
-+pcie_phy_tx2_modulation(int pcie_port)
-+{
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD1(pcie_port), 0x1FFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD2(pcie_port), 0xFFFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0601, 0xFFFF);
-+ mdelay(1);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0001, 0xFFFF);
-+}
-+
-+static void
-+pcie_phy_tx1_modulation(int pcie_port)
-+{
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD1(pcie_port), 0x1FFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD2(pcie_port), 0xFFFE, 0xFFFF);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0601, 0xFFFF);
-+ mdelay(1);
-+ IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0001, 0xFFFF);
-+}
-+
-+static void
-+pcie_phy_tx_modulation_war(int pcie_port)
-+{
-+ int i;
-+
-+#define PCIE_PHY_MODULATION_NUM 5
-+ for (i = 0; i < PCIE_PHY_MODULATION_NUM; i++) {
-+ pcie_phy_tx2_modulation(pcie_port);
-+ pcie_phy_tx1_modulation(pcie_port);
-+ }
-+#undef PCIE_PHY_MODULATION_NUM
-+}
-+
-+void
-+pcie_phy_clock_mode_setup(int pcie_port)
-+{
-+ pcie_pdi_big_endian(pcie_port);
-+
-+ /* Enable PDI to access PCIe PHY register */
-+ pcie_pdi_pmu_enable(pcie_port);
-+
-+ /* Configure PLL and PHY clock */
-+ pcie_phy_comm_setup(pcie_port);
-+
-+#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+ pcie_phy_36mhz_mode_setup(pcie_port);
-+#elif defined(CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE)
-+ pcie_phy_36mhz_ssc_mode_setup(pcie_port);
-+#elif defined(CONFIG_IFX_PCIE_PHY_25MHZ_MODE)
-+ pcie_phy_25mhz_mode_setup(pcie_port);
-+#elif defined (CONFIG_IFX_PCIE_PHY_100MHZ_MODE)
-+ pcie_phy_100mhz_mode_setup(pcie_port);
-+#else
-+ #error "PCIE PHY Clock Mode must be chosen first!!!!"
-+#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
-+
-+ /* Enable PCIe PHY and make PLL setting take effect */
-+ pcie_phy_pmu_enable(pcie_port);
-+
-+ /* Check if we are in startup_ready status */
-+ pcie_phy_wait_startup_ready(pcie_port);
-+
-+ pcie_phy_load_war(pcie_port);
-+
-+ /* Apply TX modulation workarounds */
-+ pcie_phy_tx_modulation_war(pcie_port);
-+
-+#ifdef IFX_PCI_PHY_REG_DUMP
-+ IFX_PCIE_PRINT(PCIE_MSG_PHY, "Modified PHY register dump\n");
-+ pcie_phy_reg_dump(pcie_port);
-+#endif
-+}
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_pm.c
-@@ -0,0 +1,176 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_pm.c
-+** PROJECT : IFX UEIP
-+** MODULES : PCIE Root Complex Driver
-+**
-+** DATE : 21 Dec 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIE Root Complex Driver Power Managment
-+** COPYRIGHT : Copyright (c) 2009
-+** Lantiq Deutschland GmbH
-+** Am Campeon 3, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 21 Dec,2009 Lei Chuanhua First UEIP release
-+*******************************************************************************/
-+/*!
-+ \defgroup IFX_PCIE_PM Power Management functions
-+ \ingroup IFX_PCIE
-+ \brief IFX PCIE Root Complex Driver power management functions
-+*/
-+
-+/*!
-+ \file ifxmips_pcie_pm.c
-+ \ingroup IFX_PCIE
-+ \brief source file for PCIE Root Complex Driver Power Management
-+*/
-+
-+#ifndef EXPORT_SYMTAB
-+#define EXPORT_SYMTAB
-+#endif
-+#ifndef AUTOCONF_INCLUDED
-+#include <linux/config.h>
-+#endif /* AUTOCONF_INCLUDED */
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <asm/system.h>
-+
-+/* Project header */
-+#include <asm/ifx/ifx_types.h>
-+#include <asm/ifx/ifx_regs.h>
-+#include <asm/ifx/common_routines.h>
-+#include <asm/ifx/ifx_pmcu.h>
-+#include "ifxmips_pcie_pm.h"
-+
-+/**
-+ * \fn static IFX_PMCU_RETURN_t ifx_pcie_pmcu_state_change(IFX_PMCU_STATE_t pmcuState)
-+ * \brief the callback function to request pmcu state in the power management hardware-dependent module
-+ *
-+ * \param pmcuState This parameter is a PMCU state.
-+ *
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \return IFX_PMCU_RETURN_DENIED Not allowed to operate power state
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_state_change(IFX_PMCU_STATE_t pmcuState)
-+{
-+ switch(pmcuState)
-+ {
-+ case IFX_PMCU_STATE_D0:
-+ return IFX_PMCU_RETURN_SUCCESS;
-+ case IFX_PMCU_STATE_D1: // Not Applicable
-+ return IFX_PMCU_RETURN_DENIED;
-+ case IFX_PMCU_STATE_D2: // Not Applicable
-+ return IFX_PMCU_RETURN_DENIED;
-+ case IFX_PMCU_STATE_D3: // Module clock gating and Power gating
-+ return IFX_PMCU_RETURN_SUCCESS;
-+ default:
-+ return IFX_PMCU_RETURN_DENIED;
-+ }
-+}
-+
-+/**
-+ * \fn static IFX_PMCU_RETURN_t ifx_pcie_pmcu_state_get(IFX_PMCU_STATE_t *pmcuState)
-+ * \brief the callback function to get pmcu state in the power management hardware-dependent module
-+
-+ * \param pmcuState Pointer to return power state.
-+ *
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \return IFX_PMCU_RETURN_DENIED Not allowed to operate power state
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_state_get(IFX_PMCU_STATE_t *pmcuState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn IFX_PMCU_RETURN_t ifx_pcie_pmcu_prechange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+ * \brief Apply all callbacks registered to be executed before a state change for pmcuModule
-+ *
-+ * \param pmcuModule Module
-+ * \param newState New state
-+ * \param oldState Old state
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_prechange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn IFX_PMCU_RETURN_t ifx_pcie_pmcu_postchange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+ * \brief Apply all callbacks registered to be executed before a state change for pmcuModule
-+ *
-+ * \param pmcuModule Module
-+ * \param newState New state
-+ * \param oldState Old state
-+ * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
-+ * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
-+ * \ingroup IFX_PCIE_PM
-+ */
-+static IFX_PMCU_RETURN_t
-+ifx_pcie_pmcu_postchange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
-+{
-+ return IFX_PMCU_RETURN_SUCCESS;
-+}
-+
-+/**
-+ * \fn static void ifx_pcie_pmcu_init(void)
-+ * \brief Register with central PMCU module
-+ * \return none
-+ * \ingroup IFX_PCIE_PM
-+ */
-+void
-+ifx_pcie_pmcu_init(void)
-+{
-+ IFX_PMCU_REGISTER_t pmcuRegister;
-+
-+ /* XXX, hook driver context */
-+
-+ /* State function register */
-+ memset(&pmcuRegister, 0, sizeof(IFX_PMCU_REGISTER_t));
-+ pmcuRegister.pmcuModule = IFX_PMCU_MODULE_PCIE;
-+ pmcuRegister.pmcuModuleNr = 0;
-+ pmcuRegister.ifx_pmcu_state_change = ifx_pcie_pmcu_state_change;
-+ pmcuRegister.ifx_pmcu_state_get = ifx_pcie_pmcu_state_get;
-+ pmcuRegister.pre = ifx_pcie_pmcu_prechange;
-+ pmcuRegister.post= ifx_pcie_pmcu_postchange;
-+ ifx_pmcu_register(&pmcuRegister);
-+}
-+
-+/**
-+ * \fn static void ifx_pcie_pmcu_exit(void)
-+ * \brief Unregister with central PMCU module
-+ *
-+ * \return none
-+ * \ingroup IFX_PCIE_PM
-+ */
-+void
-+ifx_pcie_pmcu_exit(void)
-+{
-+ IFX_PMCU_REGISTER_t pmcuUnRegister;
-+
-+ /* XXX, hook driver context */
-+
-+ pmcuUnRegister.pmcuModule = IFX_PMCU_MODULE_PCIE;
-+ pmcuUnRegister.pmcuModuleNr = 0;
-+ ifx_pmcu_unregister(&pmcuUnRegister);
-+}
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_pm.h
-@@ -0,0 +1,36 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_pm.h
-+** PROJECT : IFX UEIP
-+** MODULES : PCIe Root Complex Driver
-+**
-+** DATE : 21 Dec 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver Power Managment
-+** COPYRIGHT : Copyright (c) 2009
-+** Lantiq Deutschland GmbH
-+** Am Campeon 3, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 21 Dec,2009 Lei Chuanhua First UEIP release
-+*******************************************************************************/
-+/*!
-+ \file ifxmips_pcie_pm.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe Root Complex Driver Power Management
-+*/
-+
-+#ifndef IFXMIPS_PCIE_PM_H
-+#define IFXMIPS_PCIE_PM_H
-+
-+void ifx_pcie_pmcu_init(void);
-+void ifx_pcie_pmcu_exit(void);
-+
-+#endif /* IFXMIPS_PCIE_PM_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_reg.h
-@@ -0,0 +1,1001 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_reg.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_REG_H
-+#define IFXMIPS_PCIE_REG_H
-+/*!
-+ \file ifxmips_pcie_reg.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module register definition
-+*/
-+/* PCIe Address Mapping Base */
-+#define PCIE_CFG_PHY_BASE 0x1D000000UL
-+#define PCIE_CFG_BASE (KSEG1 + PCIE_CFG_PHY_BASE)
-+#define PCIE_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE_MEM_PHY_BASE 0x1C000000UL
-+#define PCIE_MEM_BASE (KSEG1 + PCIE_MEM_PHY_BASE)
-+#define PCIE_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE_MEM_PHY_END (PCIE_MEM_PHY_BASE + PCIE_MEM_SIZE - 1)
-+
-+#define PCIE_IO_PHY_BASE 0x1D800000UL
-+#define PCIE_IO_BASE (KSEG1 + PCIE_IO_PHY_BASE)
-+#define PCIE_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE_IO_PHY_END (PCIE_IO_PHY_BASE + PCIE_IO_SIZE - 1)
-+
-+#define PCIE_RC_CFG_BASE (KSEG1 + 0x1D900000)
-+#define PCIE_APP_LOGIC_REG (KSEG1 + 0x1E100900)
-+#define PCIE_MSI_PHY_BASE 0x1F600000UL
-+
-+#define PCIE_PDI_PHY_BASE 0x1F106800UL
-+#define PCIE_PDI_BASE (KSEG1 + PCIE_PDI_PHY_BASE)
-+#define PCIE_PDI_SIZE 0x400
-+
-+#define PCIE1_CFG_PHY_BASE 0x19000000UL
-+#define PCIE1_CFG_BASE (KSEG1 + PCIE1_CFG_PHY_BASE)
-+#define PCIE1_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE1_MEM_PHY_BASE 0x18000000UL
-+#define PCIE1_MEM_BASE (KSEG1 + PCIE1_MEM_PHY_BASE)
-+#define PCIE1_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE1_MEM_PHY_END (PCIE1_MEM_PHY_BASE + PCIE1_MEM_SIZE - 1)
-+
-+#define PCIE1_IO_PHY_BASE 0x19800000UL
-+#define PCIE1_IO_BASE (KSEG1 + PCIE1_IO_PHY_BASE)
-+#define PCIE1_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE1_IO_PHY_END (PCIE1_IO_PHY_BASE + PCIE1_IO_SIZE - 1)
-+
-+#define PCIE1_RC_CFG_BASE (KSEG1 + 0x19900000)
-+#define PCIE1_APP_LOGIC_REG (KSEG1 + 0x1E100700)
-+#define PCIE1_MSI_PHY_BASE 0x1F400000UL
-+
-+#define PCIE1_PDI_PHY_BASE 0x1F700400UL
-+#define PCIE1_PDI_BASE (KSEG1 + PCIE1_PDI_PHY_BASE)
-+#define PCIE1_PDI_SIZE 0x400
-+
-+#define PCIE_CFG_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_CFG_BASE) : (PCIE_CFG_BASE))
-+#define PCIE_MEM_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_BASE) : (PCIE_MEM_BASE))
-+#define PCIE_IO_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_BASE) : (PCIE_IO_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_PHY_BASE) : (PCIE_MEM_PHY_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_MEM_PHY_END) : (PCIE_MEM_PHY_END))
-+#define PCIE_IO_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_PHY_BASE) : (PCIE_IO_PHY_BASE))
-+#define PCIE_IO_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_IO_PHY_END) : (PCIE_IO_PHY_END))
-+#define PCIE_APP_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_APP_LOGIC_REG) : (PCIE_APP_LOGIC_REG))
-+#define PCIE_RC_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_RC_CFG_BASE) : (PCIE_RC_CFG_BASE))
-+#define PCIE_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_PDI_BASE) : (PCIE_PDI_BASE))
-+
-+/* PCIe Application Logic Register */
-+/* RC Core Control Register */
-+#define PCIE_RC_CCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x10)
-+/* This should be enabled after initializing configuratin registers
-+ * Also should check link status retraining bit
-+ */
-+#define PCIE_RC_CCR_LTSSM_ENABLE 0x00000001 /* Enable LTSSM to continue link establishment */
-+
-+/* RC Core Debug Register */
-+#define PCIE_RC_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x14)
-+#define PCIE_RC_DR_DLL_UP 0x00000001 /* Data Link Layer Up */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE 0x0000000E /* Current Power State */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE_S 1
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE 0x000001F0 /* Current LTSSM State */
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE_S 4
-+
-+#define PCIE_RC_DR_PM_DEV_STATE 0x00000E00 /* Power Management D-State */
-+#define PCIE_RC_DR_PM_DEV_STATE_S 9
-+
-+#define PCIE_RC_DR_PM_ENABLED 0x00001000 /* Power Management State from PMU */
-+#define PCIE_RC_DR_PME_EVENT_ENABLED 0x00002000 /* Power Management Event Enable State */
-+#define PCIE_RC_DR_AUX_POWER_ENABLED 0x00004000 /* Auxiliary Power Enable */
-+
-+/* Current Power State Definition */
-+enum {
-+ PCIE_RC_DR_D0 = 0,
-+ PCIE_RC_DR_D1, /* Not supported */
-+ PCIE_RC_DR_D2, /* Not supported */
-+ PCIE_RC_DR_D3,
-+ PCIE_RC_DR_UN,
-+};
-+
-+/* PHY Link Status Register */
-+#define PCIE_PHY_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x18)
-+#define PCIE_PHY_SR_PHY_LINK_UP 0x00000001 /* PHY Link Up/Down Indicator */
-+
-+/* Electromechanical Control Register */
-+#define PCIE_EM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x1C)
-+#define PCIE_EM_CR_CARD_IS_PRESENT 0x00000001 /* Card Presence Detect State */
-+#define PCIE_EM_CR_MRL_OPEN 0x00000002 /* MRL Sensor State */
-+#define PCIE_EM_CR_POWER_FAULT_SET 0x00000004 /* Power Fault Detected */
-+#define PCIE_EM_CR_MRL_SENSOR_SET 0x00000008 /* MRL Sensor Changed */
-+#define PCIE_EM_CR_PRESENT_DETECT_SET 0x00000010 /* Card Presense Detect Changed */
-+#define PCIE_EM_CR_CMD_CPL_INT_SET 0x00000020 /* Command Complete Interrupt */
-+#define PCIE_EM_CR_SYS_INTERLOCK_SET 0x00000040 /* System Electromechanical IterLock Engaged */
-+#define PCIE_EM_CR_ATTENTION_BUTTON_SET 0x00000080 /* Attention Button Pressed */
-+
-+/* Interrupt Status Register */
-+#define PCIE_IR_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x20)
-+#define PCIE_IR_SR_PME_CAUSE_MSI 0x00000002 /* MSI caused by PME */
-+#define PCIE_IR_SR_HP_PME_WAKE_GEN 0x00000004 /* Hotplug PME Wake Generation */
-+#define PCIE_IR_SR_HP_MSI 0x00000008 /* Hotplug MSI */
-+#define PCIE_IR_SR_AHB_LU_ERR 0x00000030 /* AHB Bridge Lookup Error Signals */
-+#define PCIE_IR_SR_AHB_LU_ERR_S 4
-+#define PCIE_IR_SR_INT_MSG_NUM 0x00003E00 /* Interrupt Message Number */
-+#define PCIE_IR_SR_INT_MSG_NUM_S 9
-+#define PCIE_IR_SR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_IR_SR_AER_INT_MSG_NUM_S 27
-+
-+/* Message Control Register */
-+#define PCIE_MSG_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x30)
-+#define PCIE_MSG_CR_GEN_PME_TURN_OFF_MSG 0x00000001 /* Generate PME Turn Off Message */
-+#define PCIE_MSG_CR_GEN_UNLOCK_MSG 0x00000002 /* Generate Unlock Message */
-+
-+#define PCIE_VDM_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x34)
-+
-+/* Vendor-Defined Message Requester ID Register */
-+#define PCIE_VDM_RID(X) (PCIE_APP_PORT_TO_BASE (X) + 0x38)
-+#define PCIE_VDM_RID_VENROR_MSG_REQ_ID 0x0000FFFF
-+#define PCIE_VDM_RID_VDMRID_S 0
-+
-+/* ASPM Control Register */
-+#define PCIE_ASPM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x40)
-+#define PCIE_ASPM_CR_HOT_RST 0x00000001 /* Hot Reset Request to the downstream device */
-+#define PCIE_ASPM_CR_REQ_EXIT_L1 0x00000002 /* Request to Exit L1 */
-+#define PCIE_ASPM_CR_REQ_ENTER_L1 0x00000004 /* Request to Enter L1 */
-+
-+/* Vendor Message DW0 Register */
-+#define PCIE_VM_MSG_DW0(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x50)
-+#define PCIE_VM_MSG_DW0_TYPE 0x0000001F /* Message type */
-+#define PCIE_VM_MSG_DW0_TYPE_S 0
-+#define PCIE_VM_MSG_DW0_FORMAT 0x00000060 /* Format */
-+#define PCIE_VM_MSG_DW0_FORMAT_S 5
-+#define PCIE_VM_MSG_DW0_TC 0x00007000 /* Traffic Class */
-+#define PCIE_VM_MSG_DW0_TC_S 12
-+#define PCIE_VM_MSG_DW0_ATTR 0x000C0000 /* Atrributes */
-+#define PCIE_VM_MSG_DW0_ATTR_S 18
-+#define PCIE_VM_MSG_DW0_EP_TLP 0x00100000 /* Poisoned TLP */
-+#define PCIE_VM_MSG_DW0_TD 0x00200000 /* TLP Digest */
-+#define PCIE_VM_MSG_DW0_LEN 0xFFC00000 /* Length */
-+#define PCIE_VM_MSG_DW0_LEN_S 22
-+
-+/* Format Definition */
-+enum {
-+ PCIE_VM_MSG_FORMAT_00 = 0, /* 3DW Hdr, no data*/
-+ PCIE_VM_MSG_FORMAT_01, /* 4DW Hdr, no data */
-+ PCIE_VM_MSG_FORMAT_10, /* 3DW Hdr, with data */
-+ PCIE_VM_MSG_FORMAT_11, /* 4DW Hdr, with data */
-+};
-+
-+/* Traffic Class Definition */
-+enum {
-+ PCIE_VM_MSG_TC0 = 0,
-+ PCIE_VM_MSG_TC1,
-+ PCIE_VM_MSG_TC2,
-+ PCIE_VM_MSG_TC3,
-+ PCIE_VM_MSG_TC4,
-+ PCIE_VM_MSG_TC5,
-+ PCIE_VM_MSG_TC6,
-+ PCIE_VM_MSG_TC7,
-+};
-+
-+/* Attributes Definition */
-+enum {
-+ PCIE_VM_MSG_ATTR_00 = 0, /* RO and No Snoop cleared */
-+ PCIE_VM_MSG_ATTR_01, /* RO cleared , No Snoop set */
-+ PCIE_VM_MSG_ATTR_10, /* RO set, No Snoop cleared*/
-+ PCIE_VM_MSG_ATTR_11, /* RO and No Snoop set */
-+};
-+
-+/* Payload Size Definition */
-+#define PCIE_VM_MSG_LEN_MIN 0
-+#define PCIE_VM_MSG_LEN_MAX 1024
-+
-+/* Vendor Message DW1 Register */
-+#define PCIE_VM_MSG_DW1(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x54)
-+#define PCIE_VM_MSG_DW1_FUNC_NUM 0x00000070 /* Function Number */
-+#define PCIE_VM_MSG_DW1_FUNC_NUM_S 8
-+#define PCIE_VM_MSG_DW1_CODE 0x00FF0000 /* Message Code */
-+#define PCIE_VM_MSG_DW1_CODE_S 16
-+#define PCIE_VM_MSG_DW1_TAG 0xFF000000 /* Tag */
-+#define PCIE_VM_MSG_DW1_TAG_S 24
-+
-+#define PCIE_VM_MSG_DW2(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x58)
-+#define PCIE_VM_MSG_DW3(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x5C)
-+
-+/* Vendor Message Request Register */
-+#define PCIE_VM_MSG_REQR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x60)
-+#define PCIE_VM_MSG_REQR_REQ 0x00000001 /* Vendor Message Request */
-+
-+
-+/* AHB Slave Side Band Control Register */
-+#define PCIE_AHB_SSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x70)
-+#define PCIE_AHB_SSB_REQ_BCM 0x00000001 /* Slave Reques BCM filed */
-+#define PCIE_AHB_SSB_REQ_EP 0x00000002 /* Slave Reques EP filed */
-+#define PCIE_AHB_SSB_REQ_TD 0x00000004 /* Slave Reques TD filed */
-+#define PCIE_AHB_SSB_REQ_ATTR 0x00000018 /* Slave Reques Attribute number */
-+#define PCIE_AHB_SSB_REQ_ATTR_S 3
-+#define PCIE_AHB_SSB_REQ_TC 0x000000E0 /* Slave Request TC Field */
-+#define PCIE_AHB_SSB_REQ_TC_S 5
-+
-+/* AHB Master SideBand Ctrl Register */
-+#define PCIE_AHB_MSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x74)
-+#define PCIE_AHB_MSB_RESP_ATTR 0x00000003 /* Master Response Attribute number */
-+#define PCIE_AHB_MSB_RESP_ATTR_S 0
-+#define PCIE_AHB_MSB_RESP_BAD_EOT 0x00000004 /* Master Response Badeot filed */
-+#define PCIE_AHB_MSB_RESP_BCM 0x00000008 /* Master Response BCM filed */
-+#define PCIE_AHB_MSB_RESP_EP 0x00000010 /* Master Response EP filed */
-+#define PCIE_AHB_MSB_RESP_TD 0x00000020 /* Master Response TD filed */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM 0x000003C0 /* Master Response Function number */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM_S 6
-+
-+/* AHB Control Register, fixed bus enumeration exception */
-+#define PCIE_AHB_CTRL(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x78)
-+#define PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS 0x00000001
-+
-+/* Interrupt Enalbe Register */
-+#define PCIE_IRNEN(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF4)
-+#define PCIE_IRNCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF8)
-+#define PCIE_IRNICR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xFC)
-+
-+/* PCIe interrupt enable/control/capture register definition */
-+#define PCIE_IRN_AER_REPORT 0x00000001 /* AER Interrupt */
-+#define PCIE_IRN_AER_MSIX 0x00000002 /* Advanced Error MSI-X Interrupt */
-+#define PCIE_IRN_PME 0x00000004 /* PME Interrupt */
-+#define PCIE_IRN_HOTPLUG 0x00000008 /* Hotplug Interrupt */
-+#define PCIE_IRN_RX_VDM_MSG 0x00000010 /* Vendor-Defined Message Interrupt */
-+#define PCIE_IRN_RX_CORRECTABLE_ERR_MSG 0x00000020 /* Correctable Error Message Interrupt */
-+#define PCIE_IRN_RX_NON_FATAL_ERR_MSG 0x00000040 /* Non-fatal Error Message */
-+#define PCIE_IRN_RX_FATAL_ERR_MSG 0x00000080 /* Fatal Error Message */
-+#define PCIE_IRN_RX_PME_MSG 0x00000100 /* PME Message Interrupt */
-+#define PCIE_IRN_RX_PME_TURNOFF_ACK 0x00000200 /* PME Turnoff Ack Message Interrupt */
-+#define PCIE_IRN_AHB_BR_FATAL_ERR 0x00000400 /* AHB Fatal Error Interrupt */
-+#define PCIE_IRN_LINK_AUTO_BW_STATUS 0x00000800 /* Link Auto Bandwidth Status Interrupt */
-+#define PCIE_IRN_BW_MGT 0x00001000 /* Bandwidth Managment Interrupt */
-+#define PCIE_IRN_INTA 0x00002000 /* INTA */
-+#define PCIE_IRN_INTB 0x00004000 /* INTB */
-+#define PCIE_IRN_INTC 0x00008000 /* INTC */
-+#define PCIE_IRN_INTD 0x00010000 /* INTD */
-+#define PCIE_IRN_WAKEUP 0x00020000 /* Wake up Interrupt */
-+
-+#define PCIE_RC_CORE_COMBINED_INT (PCIE_IRN_AER_REPORT | PCIE_IRN_AER_MSIX | PCIE_IRN_PME | \
-+ PCIE_IRN_HOTPLUG | PCIE_IRN_RX_VDM_MSG | PCIE_IRN_RX_CORRECTABLE_ERR_MSG |\
-+ PCIE_IRN_RX_NON_FATAL_ERR_MSG | PCIE_IRN_RX_FATAL_ERR_MSG | \
-+ PCIE_IRN_RX_PME_MSG | PCIE_IRN_RX_PME_TURNOFF_ACK | PCIE_IRN_AHB_BR_FATAL_ERR | \
-+ PCIE_IRN_LINK_AUTO_BW_STATUS | PCIE_IRN_BW_MGT)
-+/* PCIe RC Configuration Register */
-+#define PCIE_VDID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x00)
-+
-+/* Bit definition from pci_reg.h */
-+#define PCIE_PCICMDSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x04)
-+#define PCIE_CCRID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x08)
-+#define PCIE_CLSLTHTBR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x0C) /* EP only */
-+/* BAR0, BAR1,Only necessary if the bridges implements a device-specific register set or memory buffer */
-+#define PCIE_BAR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10) /* Not used*/
-+#define PCIE_BAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14) /* Not used */
-+
-+#define PCIE_BNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x18) /* Mandatory */
-+/* Bus Number Register bits */
-+#define PCIE_BNR_PRIMARY_BUS_NUM 0x000000FF
-+#define PCIE_BNR_PRIMARY_BUS_NUM_S 0
-+#define PCIE_PNR_SECONDARY_BUS_NUM 0x0000FF00
-+#define PCIE_PNR_SECONDARY_BUS_NUM_S 8
-+#define PCIE_PNR_SUB_BUS_NUM 0x00FF0000
-+#define PCIE_PNR_SUB_BUS_NUM_S 16
-+
-+/* IO Base/Limit Register bits */
-+#define PCIE_IOBLSECS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x1C) /* RC only */
-+#define PCIE_IOBLSECS_32BIT_IO_ADDR 0x00000001
-+#define PCIE_IOBLSECS_IO_BASE_ADDR 0x000000F0
-+#define PCIE_IOBLSECS_IO_BASE_ADDR_S 4
-+#define PCIE_IOBLSECS_32BIT_IOLIMT 0x00000100
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR 0x0000F000
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR_S 12
-+
-+/* Non-prefetchable Memory Base/Limit Register bit */
-+#define PCIE_MBML(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x20) /* RC only */
-+#define PCIE_MBML_MEM_BASE_ADDR 0x0000FFF0
-+#define PCIE_MBML_MEM_BASE_ADDR_S 4
-+#define PCIE_MBML_MEM_LIMIT_ADDR 0xFFF00000
-+#define PCIE_MBML_MEM_LIMIT_ADDR_S 20
-+
-+/* Prefetchable Memory Base/Limit Register bit */
-+#define PCIE_PMBL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x24) /* RC only */
-+#define PCIE_PMBL_64BIT_ADDR 0x00000001
-+#define PCIE_PMBL_UPPER_12BIT 0x0000FFF0
-+#define PCIE_PMBL_UPPER_12BIT_S 4
-+#define PCIE_PMBL_E64MA 0x00010000
-+#define PCIE_PMBL_END_ADDR 0xFFF00000
-+#define PCIE_PMBL_END_ADDR_S 20
-+#define PCIE_PMBU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x28) /* RC only */
-+#define PCIE_PMLU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x2C) /* RC only */
-+
-+/* I/O Base/Limit Upper 16 bits register */
-+#define PCIE_IO_BANDL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x30) /* RC only */
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE 0x0000FFFF
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE_S 0
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT 0xFFFF0000
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT_S 16
-+
-+#define PCIE_CPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x34)
-+#define PCIE_EBBAR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x38)
-+
-+/* Interrupt and Secondary Bridge Control Register */
-+#define PCIE_INTRBCTRL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x3C)
-+
-+#define PCIE_INTRBCTRL_INT_LINE 0x000000FF
-+#define PCIE_INTRBCTRL_INT_LINE_S 0
-+#define PCIE_INTRBCTRL_INT_PIN 0x0000FF00
-+#define PCIE_INTRBCTRL_INT_PIN_S 8
-+#define PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE 0x00010000 /* #PERR */
-+#define PCIE_INTRBCTRL_SERR_ENABLE 0x00020000 /* #SERR */
-+#define PCIE_INTRBCTRL_ISA_ENABLE 0x00040000 /* ISA enable, IO 64KB only */
-+#define PCIE_INTRBCTRL_VGA_ENABLE 0x00080000 /* VGA enable */
-+#define PCIE_INTRBCTRL_VGA_16BIT_DECODE 0x00100000 /* VGA 16bit decode */
-+#define PCIE_INTRBCTRL_RST_SECONDARY_BUS 0x00400000 /* Secondary bus rest, hot rest, 1ms */
-+/* Others are read only */
-+enum {
-+ PCIE_INTRBCTRL_INT_NON = 0,
-+ PCIE_INTRBCTRL_INTA,
-+ PCIE_INTRBCTRL_INTB,
-+ PCIE_INTRBCTRL_INTC,
-+ PCIE_INTRBCTRL_INTD,
-+};
-+
-+#define PCIE_PM_CAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x40)
-+
-+/* Power Management Control and Status Register */
-+#define PCIE_PM_CSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x44)
-+
-+#define PCIE_PM_CSR_POWER_STATE 0x00000003 /* Power State */
-+#define PCIE_PM_CSR_POWER_STATE_S 0
-+#define PCIE_PM_CSR_SW_RST 0x00000008 /* Soft Reset Enabled */
-+#define PCIE_PM_CSR_PME_ENABLE 0x00000100 /* PME Enable */
-+#define PCIE_PM_CSR_PME_STATUS 0x00008000 /* PME status */
-+
-+/* MSI Capability Register for EP */
-+#define PCIE_MCAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x50)
-+
-+#define PCIE_MCAPR_MSI_CAP_ID 0x000000FF /* MSI Capability ID */
-+#define PCIE_MCAPR_MSI_CAP_ID_S 0
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR_S 8
-+#define PCIE_MCAPR_MSI_ENABLE 0x00010000 /* MSI Enable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP 0x000E0000 /* Multiple Message Capable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP_S 17
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE 0x00700000 /* Multiple Message Enable */
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE_S 20
-+#define PCIE_MCAPR_ADDR64_CAP 0X00800000 /* 64-bit Address Capable */
-+
-+/* MSI Message Address Register */
-+#define PCIE_MA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x54)
-+
-+#define PCIE_MA_ADDR_MASK 0xFFFFFFFC /* Message Address */
-+
-+/* MSI Message Upper Address Register */
-+#define PCIE_MUA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x58)
-+
-+/* MSI Message Data Register */
-+#define PCIE_MD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x5C)
-+
-+#define PCIE_MD_DATA 0x0000FFFF /* Message Data */
-+#define PCIE_MD_DATA_S 0
-+
-+/* PCI Express Capability Register */
-+#define PCIE_XCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70)
-+
-+#define PCIE_XCAP_ID 0x000000FF /* PCI Express Capability ID */
-+#define PCIE_XCAP_ID_S 0
-+#define PCIE_XCAP_NEXT_CAP 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_XCAP_NEXT_CAP_S 8
-+#define PCIE_XCAP_VER 0x000F0000 /* PCI Express Capability Version */
-+#define PCIE_XCAP_VER_S 16
-+#define PCIE_XCAP_DEV_PORT_TYPE 0x00F00000 /* Device Port Type */
-+#define PCIE_XCAP_DEV_PORT_TYPE_S 20
-+#define PCIE_XCAP_SLOT_IMPLEMENTED 0x01000000 /* Slot Implemented */
-+#define PCIE_XCAP_MSG_INT_NUM 0x3E000000 /* Interrupt Message Number */
-+#define PCIE_XCAP_MSG_INT_NUM_S 25
-+
-+/* Device Capability Register */
-+#define PCIE_DCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74)
-+
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE 0x00000007 /* Max Payload size */
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE_S 0
-+#define PCIE_DCAP_PHANTOM_FUNC 0x00000018 /* Phanton Function, not supported */
-+#define PCIE_DCAP_PHANTOM_FUNC_S 3
-+#define PCIE_DCAP_EXT_TAG 0x00000020 /* Extended Tag Field */
-+#define PCIE_DCAP_EP_L0S_LATENCY 0x000001C0 /* EP L0s latency only */
-+#define PCIE_DCAP_EP_L0S_LATENCY_S 6
-+#define PCIE_DCAP_EP_L1_LATENCY 0x00000E00 /* EP L1 latency only */
-+#define PCIE_DCAP_EP_L1_LATENCY_S 9
-+#define PCIE_DCAP_ROLE_BASE_ERR_REPORT 0x00008000 /* Role Based ERR */
-+
-+/* Maximum payload size supported */
-+enum {
-+ PCIE_MAX_PAYLOAD_128 = 0,
-+ PCIE_MAX_PAYLOAD_256,
-+ PCIE_MAX_PAYLOAD_512,
-+ PCIE_MAX_PAYLOAD_1024,
-+ PCIE_MAX_PAYLOAD_2048,
-+ PCIE_MAX_PAYLOAD_4096,
-+};
-+
-+/* Device Control and Status Register */
-+#define PCIE_DCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x78)
-+
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR_EN 0x00000001 /* COR-ERR */
-+#define PCIE_DCTLSTS_NONFATAL_ERR_EN 0x00000002 /* Non-fatal ERR */
-+#define PCIE_DCTLSTS_FATAL_ERR_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_DCTLSYS_UR_REQ_EN 0x00000008 /* UR ERR */
-+#define PCIE_DCTLSTS_RELAXED_ORDERING_EN 0x00000010 /* Enable relaxing ordering */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE 0x000000E0 /* Max payload mask */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE_S 5
-+#define PCIE_DCTLSTS_EXT_TAG_EN 0x00000100 /* Extended tag field */
-+#define PCIE_DCTLSTS_PHANTOM_FUNC_EN 0x00000200 /* Phantom Function Enable */
-+#define PCIE_DCTLSTS_AUX_PM_EN 0x00000400 /* AUX Power PM Enable */
-+#define PCIE_DCTLSTS_NO_SNOOP_EN 0x00000800 /* Enable no snoop, except root port*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE 0x00007000 /* Max Read Request size*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE_S 12
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR 0x00010000 /* COR-ERR Detected */
-+#define PCIE_DCTLSTS_NONFATAL_ERR 0x00020000 /* Non-Fatal ERR Detected */
-+#define PCIE_DCTLSTS_FATAL_ER 0x00040000 /* Fatal ERR Detected */
-+#define PCIE_DCTLSTS_UNSUPPORTED_REQ 0x00080000 /* UR Detected */
-+#define PCIE_DCTLSTS_AUX_POWER 0x00100000 /* Aux Power Detected */
-+#define PCIE_DCTLSTS_TRANSACT_PENDING 0x00200000 /* Transaction pending */
-+
-+#define PCIE_DCTLSTS_ERR_EN (PCIE_DCTLSTS_CORRECTABLE_ERR_EN | \
-+ PCIE_DCTLSTS_NONFATAL_ERR_EN | PCIE_DCTLSTS_FATAL_ERR_EN | \
-+ PCIE_DCTLSYS_UR_REQ_EN)
-+
-+/* Link Capability Register */
-+#define PCIE_LCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7C)
-+#define PCIE_LCAP_MAX_LINK_SPEED 0x0000000F /* Max link speed, 0x1 by default */
-+#define PCIE_LCAP_MAX_LINK_SPEED_S 0
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH 0x000003F0 /* Maxium Length Width */
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH_S 4
-+#define PCIE_LCAP_ASPM_LEVEL 0x00000C00 /* Active State Link PM Support */
-+#define PCIE_LCAP_ASPM_LEVEL_S 10
-+#define PCIE_LCAP_L0S_EIXT_LATENCY 0x00007000 /* L0s Exit Latency */
-+#define PCIE_LCAP_L0S_EIXT_LATENCY_S 12
-+#define PCIE_LCAP_L1_EXIT_LATENCY 0x00038000 /* L1 Exit Latency */
-+#define PCIE_LCAP_L1_EXIT_LATENCY_S 15
-+#define PCIE_LCAP_CLK_PM 0x00040000 /* Clock Power Management */
-+#define PCIE_LCAP_SDER 0x00080000 /* Surprise Down Error Reporting */
-+#define PCIE_LCAP_DLL_ACTIVE_REPROT 0x00100000 /* Data Link Layer Active Reporting Capable */
-+#define PCIE_LCAP_PORT_NUM 0xFF0000000 /* Port number */
-+#define PCIE_LCAP_PORT_NUM_S 24
-+
-+/* Maximum Length width definition */
-+#define PCIE_MAX_LENGTH_WIDTH_RES 0x00
-+#define PCIE_MAX_LENGTH_WIDTH_X1 0x01 /* Default */
-+#define PCIE_MAX_LENGTH_WIDTH_X2 0x02
-+#define PCIE_MAX_LENGTH_WIDTH_X4 0x04
-+#define PCIE_MAX_LENGTH_WIDTH_X8 0x08
-+#define PCIE_MAX_LENGTH_WIDTH_X12 0x0C
-+#define PCIE_MAX_LENGTH_WIDTH_X16 0x10
-+#define PCIE_MAX_LENGTH_WIDTH_X32 0x20
-+
-+/* Active State Link PM definition */
-+enum {
-+ PCIE_ASPM_RES0 = 0,
-+ PCIE_ASPM_L0S_ENTRY_SUPPORT, /* L0s */
-+ PCIE_ASPM_RES1,
-+ PCIE_ASPM_L0S_L1_ENTRY_SUPPORT, /* L0s and L1, default */
-+};
-+
-+/* L0s Exit Latency definition */
-+enum {
-+ PCIE_L0S_EIXT_LATENCY_L64NS = 0, /* < 64 ns */
-+ PCIE_L0S_EIXT_LATENCY_B64A128, /* > 64 ns < 128 ns */
-+ PCIE_L0S_EIXT_LATENCY_B128A256, /* > 128 ns < 256 ns */
-+ PCIE_L0S_EIXT_LATENCY_B256A512, /* > 256 ns < 512 ns */
-+ PCIE_L0S_EIXT_LATENCY_B512TO1U, /* > 512 ns < 1 us */
-+ PCIE_L0S_EIXT_LATENCY_B1A2U, /* > 1 us < 2 us */
-+ PCIE_L0S_EIXT_LATENCY_B2A4U, /* > 2 us < 4 us */
-+ PCIE_L0S_EIXT_LATENCY_M4US, /* > 4 us */
-+};
-+
-+/* L1 Exit Latency definition */
-+enum {
-+ PCIE_L1_EXIT_LATENCY_L1US = 0, /* < 1 us */
-+ PCIE_L1_EXIT_LATENCY_B1A2, /* > 1 us < 2 us */
-+ PCIE_L1_EXIT_LATENCY_B2A4, /* > 2 us < 4 us */
-+ PCIE_L1_EXIT_LATENCY_B4A8, /* > 4 us < 8 us */
-+ PCIE_L1_EXIT_LATENCY_B8A16, /* > 8 us < 16 us */
-+ PCIE_L1_EXIT_LATENCY_B16A32, /* > 16 us < 32 us */
-+ PCIE_L1_EXIT_LATENCY_B32A64, /* > 32 us < 64 us */
-+ PCIE_L1_EXIT_LATENCY_M64US, /* > 64 us */
-+};
-+
-+/* Link Control and Status Register */
-+#define PCIE_LCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x80)
-+#define PCIE_LCTLSTS_ASPM_ENABLE 0x00000003 /* Active State Link PM Control */
-+#define PCIE_LCTLSTS_ASPM_ENABLE_S 0
-+#define PCIE_LCTLSTS_RCB128 0x00000008 /* Read Completion Boundary 128*/
-+#define PCIE_LCTLSTS_LINK_DISABLE 0x00000010 /* Link Disable */
-+#define PCIE_LCTLSTS_RETRIAN_LINK 0x00000020 /* Retrain Link */
-+#define PCIE_LCTLSTS_COM_CLK_CFG 0x00000040 /* Common Clock Configuration */
-+#define PCIE_LCTLSTS_EXT_SYNC 0x00000080 /* Extended Synch */
-+#define PCIE_LCTLSTS_CLK_PM_EN 0x00000100 /* Enable Clock Powerm Management */
-+#define PCIE_LCTLSTS_LINK_SPEED 0x000F0000 /* Link Speed */
-+#define PCIE_LCTLSTS_LINK_SPEED_S 16
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH 0x03F00000 /* Negotiated Link Width */
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH_S 20
-+#define PCIE_LCTLSTS_RETRAIN_PENDING 0x08000000 /* Link training is ongoing */
-+#define PCIE_LCTLSTS_SLOT_CLK_CFG 0x10000000 /* Slot Clock Configuration */
-+#define PCIE_LCTLSTS_DLL_ACTIVE 0x20000000 /* Data Link Layer Active */
-+
-+/* Slot Capabilities Register */
-+#define PCIE_SLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x84)
-+
-+/* Slot Capabilities */
-+#define PCIE_SLCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x88)
-+
-+/* Root Control and Capability Register */
-+#define PCIE_RCTLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x8C)
-+#define PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR 0x00000001 /* #SERR on COR-ERR */
-+#define PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR 0x00000002 /* #SERR on Non-Fatal ERR */
-+#define PCIE_RCTLCAP_SERR_ON_FATAL_ERR 0x00000004 /* #SERR on Fatal ERR */
-+#define PCIE_RCTLCAP_PME_INT_EN 0x00000008 /* PME Interrupt Enable */
-+#define PCIE_RCTLCAP_SERR_ENABLE (PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR | \
-+ PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR | PCIE_RCTLCAP_SERR_ON_FATAL_ERR)
-+/* Root Status Register */
-+#define PCIE_RSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x90)
-+#define PCIE_RSTS_PME_REQ_ID 0x0000FFFF /* PME Request ID */
-+#define PCIE_RSTS_PME_REQ_ID_S 0
-+#define PCIE_RSTS_PME_STATUS 0x00010000 /* PME Status */
-+#define PCIE_RSTS_PME_PENDING 0x00020000 /* PME Pending */
-+
-+/* PCI Express Enhanced Capability Header */
-+#define PCIE_ENHANCED_CAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x100)
-+#define PCIE_ENHANCED_CAP_ID 0x0000FFFF /* PCI Express Extended Capability ID */
-+#define PCIE_ENHANCED_CAP_ID_S 0
-+#define PCIE_ENHANCED_CAP_VER 0x000F0000 /* Capability Version */
-+#define PCIE_ENHANCED_CAP_VER_S 16
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET 0xFFF00000 /* Next Capability Offset */
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET_S 20
-+
-+/* Uncorrectable Error Status Register */
-+#define PCIE_UES_R(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x104)
-+#define PCIE_DATA_LINK_PROTOCOL_ERR 0x00000010 /* Data Link Protocol Error Status */
-+#define PCIE_SURPRISE_DOWN_ERROR 0x00000020 /* Surprise Down Error Status */
-+#define PCIE_POISONED_TLP 0x00001000 /* Poisoned TLP Status */
-+#define PCIE_FC_PROTOCOL_ERR 0x00002000 /* Flow Control Protocol Error Status */
-+#define PCIE_COMPLETION_TIMEOUT 0x00004000 /* Completion Timeout Status */
-+#define PCIE_COMPLETOR_ABORT 0x00008000 /* Completer Abort Error */
-+#define PCIE_UNEXPECTED_COMPLETION 0x00010000 /* Unexpected Completion Status */
-+#define PCIE_RECEIVER_OVERFLOW 0x00020000 /* Receive Overflow Status */
-+#define PCIE_MALFORNED_TLP 0x00040000 /* Malformed TLP Stauts */
-+#define PCIE_ECRC_ERR 0x00080000 /* ECRC Error Stauts */
-+#define PCIE_UR_REQ 0x00100000 /* Unsupported Request Error Status */
-+#define PCIE_ALL_UNCORRECTABLE_ERR (PCIE_DATA_LINK_PROTOCOL_ERR | PCIE_SURPRISE_DOWN_ERROR | \
-+ PCIE_POISONED_TLP | PCIE_FC_PROTOCOL_ERR | PCIE_COMPLETION_TIMEOUT | \
-+ PCIE_COMPLETOR_ABORT | PCIE_UNEXPECTED_COMPLETION | PCIE_RECEIVER_OVERFLOW |\
-+ PCIE_MALFORNED_TLP | PCIE_ECRC_ERR | PCIE_UR_REQ)
-+
-+/* Uncorrectable Error Mask Register, Mask means no report */
-+#define PCIE_UEMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x108)
-+
-+/* Uncorrectable Error Severity Register */
-+#define PCIE_UESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10C)
-+
-+/* Correctable Error Status Register */
-+#define PCIE_CESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x110)
-+#define PCIE_RX_ERR 0x00000001 /* Receive Error Status */
-+#define PCIE_BAD_TLP 0x00000040 /* Bad TLP Status */
-+#define PCIE_BAD_DLLP 0x00000080 /* Bad DLLP Status */
-+#define PCIE_REPLAY_NUM_ROLLOVER 0x00000100 /* Replay Number Rollover Status */
-+#define PCIE_REPLAY_TIMER_TIMEOUT_ERR 0x00001000 /* Reply Timer Timeout Status */
-+#define PCIE_ADVISORY_NONFTAL_ERR 0x00002000 /* Advisory Non-Fatal Error Status */
-+#define PCIE_CORRECTABLE_ERR (PCIE_RX_ERR | PCIE_BAD_TLP | PCIE_BAD_DLLP | PCIE_REPLAY_NUM_ROLLOVER |\
-+ PCIE_REPLAY_TIMER_TIMEOUT_ERR | PCIE_ADVISORY_NONFTAL_ERR)
-+
-+/* Correctable Error Mask Register */
-+#define PCIE_CEMR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x114)
-+
-+/* Advanced Error Capabilities and Control Register */
-+#define PCIE_AECCR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x118)
-+#define PCIE_AECCR_FIRST_ERR_PTR 0x0000001F /* First Error Pointer */
-+#define PCIE_AECCR_FIRST_ERR_PTR_S 0
-+#define PCIE_AECCR_ECRC_GEN_CAP 0x00000020 /* ECRC Generation Capable */
-+#define PCIE_AECCR_ECRC_GEN_EN 0x00000040 /* ECRC Generation Enable */
-+#define PCIE_AECCR_ECRC_CHECK_CAP 0x00000080 /* ECRC Check Capable */
-+#define PCIE_AECCR_ECRC_CHECK_EN 0x00000100 /* ECRC Check Enable */
-+
-+/* Header Log Register 1 */
-+#define PCIE_HLR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x11C)
-+
-+/* Header Log Register 2 */
-+#define PCIE_HLR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x120)
-+
-+/* Header Log Register 3 */
-+#define PCIE_HLR3(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x124)
-+
-+/* Header Log Register 4 */
-+#define PCIE_HLR4(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x128)
-+
-+/* Root Error Command Register */
-+#define PCIE_RECR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x12C)
-+#define PCIE_RECR_CORRECTABLE_ERR_REPORT_EN 0x00000001 /* COR-ERR */
-+#define PCIE_RECR_NONFATAL_ERR_REPORT_EN 0x00000002 /* Non-Fatal ERR */
-+#define PCIE_RECR_FATAL_ERR_REPORT_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_RECR_ERR_REPORT_EN (PCIE_RECR_CORRECTABLE_ERR_REPORT_EN | \
-+ PCIE_RECR_NONFATAL_ERR_REPORT_EN | PCIE_RECR_FATAL_ERR_REPORT_EN)
-+
-+/* Root Error Status Register */
-+#define PCIE_RESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x130)
-+#define PCIE_RESR_CORRECTABLE_ERR 0x00000001 /* COR-ERR Receveid */
-+#define PCIE_RESR_MULTI_CORRECTABLE_ERR 0x00000002 /* Multiple COR-ERR Received */
-+#define PCIE_RESR_FATAL_NOFATAL_ERR 0x00000004 /* ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_MULTI_FATAL_NOFATAL_ERR 0x00000008 /* Multiple ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_FIRST_UNCORRECTABLE_FATAL_ERR 0x00000010 /* First UN-COR Fatal */
-+#define PCIR_RESR_NON_FATAL_ERR 0x00000020 /* Non-Fatal Error Message Received */
-+#define PCIE_RESR_FATAL_ERR 0x00000040 /* Fatal Message Received */
-+#define PCIE_RESR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_RESR_AER_INT_MSG_NUM_S 27
-+
-+/* Error Source Indentification Register */
-+#define PCIE_ESIR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x134)
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID 0x0000FFFF
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID_S 0
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID 0xFFFF0000
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID_S 16
-+
-+/* VC Enhanced Capability Header */
-+#define PCIE_VC_ECH(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x140)
-+
-+/* Port VC Capability Register */
-+#define PCIE_PVC1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x144)
-+#define PCIE_PVC1_EXT_VC_CNT 0x00000007 /* Extended VC Count */
-+#define PCIE_PVC1_EXT_VC_CNT_S 0
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT 0x00000070 /* Low Priority Extended VC Count */
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT_S 4
-+#define PCIE_PVC1_REF_CLK 0x00000300 /* Reference Clock */
-+#define PCIE_PVC1_REF_CLK_S 8
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE 0x00000C00 /* Port Arbitration Table Entry Size */
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE_S 10
-+
-+/* Extended Virtual Channel Count Defintion */
-+#define PCIE_EXT_VC_CNT_MIN 0
-+#define PCIE_EXT_VC_CNT_MAX 7
-+
-+/* Port Arbitration Table Entry Size Definition */
-+enum {
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S1BIT = 0,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S2BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S4BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S8BIT,
-+};
-+
-+/* Port VC Capability Register 2 */
-+#define PCIE_PVC2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x148)
-+#define PCIE_PVC2_VC_ARB_16P_FIXED_WRR 0x00000001 /* HW Fixed arbitration, 16 phase WRR */
-+#define PCIE_PVC2_VC_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_PVC2_VC_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_PVC2_VC_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_PVC2_VC_ARB_WRR 0x0000000F
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET 0xFF000000 /* VC arbitration table offset, not support */
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET_S 24
-+
-+/* Port VC Control and Status Register */
-+#define PCIE_PVCCRSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14C)
-+#define PCIE_PVCCRSR_LOAD_VC_ARB_TAB 0x00000001 /* Load VC Arbitration Table */
-+#define PCIE_PVCCRSR_VC_ARB_SEL 0x0000000E /* VC Arbitration Select */
-+#define PCIE_PVCCRSR_VC_ARB_SEL_S 1
-+#define PCIE_PVCCRSR_VC_ARB_TAB_STATUS 0x00010000 /* Arbitration Status */
-+
-+/* VC0 Resource Capability Register */
-+#define PCIE_VC0_RC(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x150)
-+#define PCIE_VC0_RC_PORT_ARB_HW_FIXED 0x00000001 /* HW Fixed arbitration */
-+#define PCIE_VC0_RC_PORT_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_128P_WRR 0x00000010 /* Time-based 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_256P_WRR 0x00000020 /* Time-based 256 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB (PCIE_VC0_RC_PORT_ARB_HW_FIXED | PCIE_VC0_RC_PORT_ARB_32P_WRR |\
-+ PCIE_VC0_RC_PORT_ARB_64P_WRR | PCIE_VC0_RC_PORT_ARB_128P_WRR | \
-+ PCIE_VC0_RC_PORT_ARB_TM_128P_WRR | PCIE_VC0_RC_PORT_ARB_TM_256P_WRR)
-+
-+#define PCIE_VC0_RC_REJECT_SNOOP 0x00008000 /* Reject Snoop Transactioin */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS 0x007F0000 /* Maximum time Slots */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS_S 16
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET 0xFF000000 /* Port Arbitration Table Offset */
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET_S 24
-+
-+/* VC0 Resource Control Register */
-+#define PCIE_VC0_RC0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x154)
-+#define PCIE_VC0_RC0_TVM0 0x00000001 /* TC0 and VC0 */
-+#define PCIE_VC0_RC0_TVM1 0x00000002 /* TC1 and VC1 */
-+#define PCIE_VC0_RC0_TVM2 0x00000004 /* TC2 and VC2 */
-+#define PCIE_VC0_RC0_TVM3 0x00000008 /* TC3 and VC3 */
-+#define PCIE_VC0_RC0_TVM4 0x00000010 /* TC4 and VC4 */
-+#define PCIE_VC0_RC0_TVM5 0x00000020 /* TC5 and VC5 */
-+#define PCIE_VC0_RC0_TVM6 0x00000040 /* TC6 and VC6 */
-+#define PCIE_VC0_RC0_TVM7 0x00000080 /* TC7 and VC7 */
-+#define PCIE_VC0_RC0_TC_VC 0x000000FF /* TC/VC mask */
-+
-+#define PCIE_VC0_RC0_LOAD_PORT_ARB_TAB 0x00010000 /* Load Port Arbitration Table */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL 0x000E0000 /* Port Arbitration Select */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL_S 17
-+#define PCIE_VC0_RC0_VC_ID 0x07000000 /* VC ID */
-+#define PCIE_VC0_RC0_VC_ID_S 24
-+#define PCIE_VC0_RC0_VC_EN 0x80000000 /* VC Enable */
-+
-+/* VC0 Resource Status Register */
-+#define PCIE_VC0_RSR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x158)
-+#define PCIE_VC0_RSR0_PORT_ARB_TAB_STATUS 0x00010000 /* Port Arbitration Table Status,not used */
-+#define PCIE_VC0_RSR0_VC_NEG_PENDING 0x00020000 /* VC Negotiation Pending */
-+
-+/* Ack Latency Timer and Replay Timer Register */
-+#define PCIE_ALTRT(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x700)
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT 0x0000FFFF /* Round Trip Latency Time Limit */
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT_S 0
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT 0xFFFF0000 /* Replay Time Limit */
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT_S 16
-+
-+/* Other Message Register */
-+#define PCIE_OMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x704)
-+
-+/* Port Force Link Register */
-+#define PCIE_PFLR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x708)
-+#define PCIE_PFLR_LINK_NUM 0x000000FF /* Link Number */
-+#define PCIE_PFLR_LINK_NUM_S 0
-+#define PCIE_PFLR_FORCE_LINK 0x00008000 /* Force link */
-+#define PCIE_PFLR_LINK_STATE 0x003F0000 /* Link State */
-+#define PCIE_PFLR_LINK_STATE_S 16
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT 0xFF000000 /* Low Power Entrance Count, only for EP */
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT_S 24
-+
-+/* Ack Frequency Register */
-+#define PCIE_AFR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70C)
-+#define PCIE_AFR_AF 0x000000FF /* Ack Frequency */
-+#define PCIE_AFR_AF_S 0
-+#define PCIE_AFR_FTS_NUM 0x0000FF00 /* The number of Fast Training Sequence from L0S to L0 */
-+#define PCIE_AFR_FTS_NUM_S 8
-+#define PCIE_AFR_COM_FTS_NUM 0x00FF0000 /* N_FTS; when common clock is used*/
-+#define PCIE_AFR_COM_FTS_NUM_S 16
-+#define PCIE_AFR_L0S_ENTRY_LATENCY 0x07000000 /* L0s Entrance Latency */
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_S 24
-+#define PCIE_AFR_L1_ENTRY_LATENCY 0x38000000 /* L1 Entrance Latency */
-+#define PCIE_AFR_L1_ENTRY_LATENCY_S 27
-+#define PCIE_AFR_FTS_NUM_DEFAULT 32
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT 7
-+#define PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT 5
-+
-+/* Port Link Control Register */
-+#define PCIE_PLCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x710)
-+#define PCIE_PLCR_OTHER_MSG_REQ 0x00000001 /* Other Message Request */
-+#define PCIE_PLCR_SCRAMBLE_DISABLE 0x00000002 /* Scramble Disable */
-+#define PCIE_PLCR_LOOPBACK_EN 0x00000004 /* Loopback Enable */
-+#define PCIE_PLCR_LTSSM_HOT_RST 0x00000008 /* Force LTSSM to the hot reset */
-+#define PCIE_PLCR_DLL_LINK_EN 0x00000020 /* Enable Link initialization */
-+#define PCIE_PLCR_FAST_LINK_SIM_EN 0x00000080 /* Sets all internal timers to fast mode for simulation purposes */
-+#define PCIE_PLCR_LINK_MODE 0x003F0000 /* Link Mode Enable Mask */
-+#define PCIE_PLCR_LINK_MODE_S 16
-+#define PCIE_PLCR_CORRUPTED_CRC_EN 0x02000000 /* Enabled Corrupt CRC */
-+
-+/* Lane Skew Register */
-+#define PCIE_LSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x714)
-+#define PCIE_LSR_LANE_SKEW_NUM 0x00FFFFFF /* Insert Lane Skew for Transmit, not applicable */
-+#define PCIE_LSR_LANE_SKEW_NUM_S 0
-+#define PCIE_LSR_FC_DISABLE 0x01000000 /* Disable of Flow Control */
-+#define PCIE_LSR_ACKNAK_DISABLE 0x02000000 /* Disable of Ack/Nak */
-+#define PCIE_LSR_LANE_DESKEW_DISABLE 0x80000000 /* Disable of Lane-to-Lane Skew */
-+
-+/* Symbol Number Register */
-+#define PCIE_SNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x718)
-+#define PCIE_SNR_TS 0x0000000F /* Number of TS Symbol */
-+#define PCIE_SNR_TS_S 0
-+#define PCIE_SNR_SKP 0x00000700 /* Number of SKP Symbol */
-+#define PCIE_SNR_SKP_S 8
-+#define PCIE_SNR_REPLAY_TIMER 0x0007C000 /* Timer Modifier for Replay Timer */
-+#define PCIE_SNR_REPLAY_TIMER_S 14
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER 0x00F80000 /* Timer Modifier for Ack/Nak Latency Timer */
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER_S 19
-+#define PCIE_SNR_FC_TIMER 0x1F000000 /* Timer Modifier for Flow Control Watchdog Timer */
-+#define PCIE_SNR_FC_TIMER_S 28
-+
-+/* Symbol Timer Register and Filter Mask Register 1 */
-+#define PCIE_STRFMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x71C)
-+#define PCIE_STRFMR_SKP_INTERVAL 0x000007FF /* SKP lnterval Value */
-+#define PCIE_STRFMR_SKP_INTERVAL_S 0
-+#define PCIE_STRFMR_FC_WDT_DISABLE 0x00008000 /* Disable of FC Watchdog Timer */
-+#define PCIE_STRFMR_TLP_FUNC_MISMATCH_OK 0x00010000 /* Mask Function Mismatch Filtering for Incoming Requests */
-+#define PCIE_STRFMR_POISONED_TLP_OK 0x00020000 /* Mask Poisoned TLP Filtering */
-+#define PCIE_STRFMR_BAR_MATCH_OK 0x00040000 /* Mask BAR Match Filtering */
-+#define PCIE_STRFMR_TYPE1_CFG_REQ_OK 0x00080000 /* Mask Type 1 Configuration Request Filtering */
-+#define PCIE_STRFMR_LOCKED_REQ_OK 0x00100000 /* Mask Locked Request Filtering */
-+#define PCIE_STRFMR_CPL_TAG_ERR_RULES_OK 0x00200000 /* Mask Tag Error Rules for Received Completions */
-+#define PCIE_STRFMR_CPL_REQUESTOR_ID_MISMATCH_OK 0x00400000 /* Mask Requester ID Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_FUNC_MISMATCH_OK 0x00800000 /* Mask Function Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_TC_MISMATCH_OK 0x01000000 /* Mask Traffic Class Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_ATTR_MISMATCH_OK 0x02000000 /* Mask Attribute Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_LENGTH_MISMATCH_OK 0x04000000 /* Mask Length Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_TLP_ECRC_ERR_OK 0x08000000 /* Mask ECRC Error Filtering */
-+#define PCIE_STRFMR_CPL_TLP_ECRC_OK 0x10000000 /* Mask ECRC Error Filtering for Completions */
-+#define PCIE_STRFMR_RX_TLP_MSG_NO_DROP 0x20000000 /* Send Message TLPs */
-+#define PCIE_STRFMR_RX_IO_TRANS_ENABLE 0x40000000 /* Mask Filtering of received I/O Requests */
-+#define PCIE_STRFMR_RX_CFG_TRANS_ENABLE 0x80000000 /* Mask Filtering of Received Configuration Requests */
-+
-+#define PCIE_DEF_SKP_INTERVAL 700 /* 1180 ~1538 , 125MHz * 2, 250MHz * 1 */
-+
-+/* Filter Masker Register 2 */
-+#define PCIE_FMR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x720)
-+#define PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1 0x00000001 /* Mask RADM Filtering and Error Handling Rules */
-+#define PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 0x00000002 /* Mask RADM Filtering and Error Handling Rules */
-+
-+/* Debug Register 0 */
-+#define PCIE_DBR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x728)
-+
-+/* Debug Register 1 */
-+#define PCIE_DBR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x72C)
-+
-+/* Transmit Posted FC Credit Status Register */
-+#define PCIE_TPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x730)
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS 0x00000FFF /* Transmit Posted Data FC Credits */
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS_S 0
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS 0x000FF000 /* Transmit Posted Header FC Credits */
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Non-Posted FC Credit Status */
-+#define PCIE_TNPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x734)
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS 0x00000FFF /* Transmit Non-Posted Data FC Credits */
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS_S 0
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS 0x000FF000 /* Transmit Non-Posted Header FC Credits */
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Complete FC Credit Status Register */
-+#define PCIE_TCFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x738)
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS 0x00000FFF /* Transmit Completion Data FC Credits */
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS_S 0
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS 0x000FF000 /* Transmit Completion Header FC Credits */
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS_S 12
-+
-+/* Queue Status Register */
-+#define PCIE_QSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x73C)
-+#define PCIE_QSR_WAIT_UPDATE_FC_DLL 0x00000001 /* Received TLP FC Credits Not Returned */
-+#define PCIE_QSR_TX_RETRY_BUF_NOT_EMPTY 0x00000002 /* Transmit Retry Buffer Not Empty */
-+#define PCIE_QSR_RX_QUEUE_NOT_EMPTY 0x00000004 /* Received Queue Not Empty */
-+
-+/* VC Transmit Arbitration Register 1 */
-+#define PCIE_VCTAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x740)
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC0 0x000000FF /* WRR Weight for VC0 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC1 0x0000FF00 /* WRR Weight for VC1 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC2 0x00FF0000 /* WRR Weight for VC2 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC3 0xFF000000 /* WRR Weight for VC3 */
-+
-+/* VC Transmit Arbitration Register 2 */
-+#define PCIE_VCTAR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x744)
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC4 0x000000FF /* WRR Weight for VC4 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC5 0x0000FF00 /* WRR Weight for VC5 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC6 0x00FF0000 /* WRR Weight for VC6 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC7 0xFF000000 /* WRR Weight for VC7 */
-+
-+/* VC0 Posted Receive Queue Control Register */
-+#define PCIE_VC0_PRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x748)
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS 0x00000FFF /* VC0 Posted Data Credits */
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS_S 0
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS 0x000FF000 /* VC0 Posted Header Credits */
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS_S 12
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE 0x00E00000 /* VC0 Posted TLP Queue Mode */
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE_S 20
-+#define PCIE_VC0_PRQCR_TLP_RELAX_ORDER 0x40000000 /* TLP Type Ordering for VC0 */
-+#define PCIE_VC0_PRQCR_VC_STRICT_ORDER 0x80000000 /* VC0 Ordering for Receive Queues */
-+
-+/* VC0 Non-Posted Receive Queue Control */
-+#define PCIE_VC0_NPRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74C)
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS 0x00000FFF /* VC0 Non-Posted Data Credits */
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS_S 0
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS 0x000FF000 /* VC0 Non-Posted Header Credits */
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS_S 12
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE 0x00E00000 /* VC0 Non-Posted TLP Queue Mode */
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE_S 20
-+
-+/* VC0 Completion Receive Queue Control */
-+#define PCIE_VC0_CRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x750)
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS 0x00000FFF /* VC0 Completion TLP Queue Mode */
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS_S 0
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS 0x000FF000 /* VC0 Completion Header Credits */
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS_S 12
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE 0x00E00000 /* VC0 Completion Data Credits */
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE_S 21
-+
-+/* Applicable to the above three registers */
-+enum {
-+ PCIE_VC0_TLP_QUEUE_MODE_STORE_FORWARD = 1,
-+ PCIE_VC0_TLP_QUEUE_MODE_CUT_THROUGH = 2,
-+ PCIE_VC0_TLP_QUEUE_MODE_BYPASS = 4,
-+};
-+
-+/* VC0 Posted Buffer Depth Register */
-+#define PCIE_VC0_PBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7A8)
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Posted Data Queue Depth */
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Posted Header Queue Depth */
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Non-Posted Buffer Depth Register */
-+#define PCIE_VC0_NPBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7AC)
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Non-Posted Data Queue Depth */
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Non-Posted Header Queue Depth */
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Completion Buffer Depth Register */
-+#define PCIE_VC0_CBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7B0)
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES 0x00003FFF /* C0 Completion Data Queue Depth */
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Completion Header Queue Depth */
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES_S 16
-+
-+/* PHY Status Register, all zeros in VR9 */
-+#define PCIE_PHYSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x810)
-+
-+/* PHY Control Register, all zeros in VR9 */
-+#define PCIE_PHYCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x814)
-+
-+/*
-+ * PCIe PDI PHY register definition, suppose all the following
-+ * stuff is confidential.
-+ * XXX, detailed bit definition
-+ */
-+#define PCIE_PHY_PLL_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x22 << 1))
-+#define PCIE_PHY_PLL_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x23 << 1))
-+#define PCIE_PHY_PLL_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x24 << 1))
-+#define PCIE_PHY_PLL_CTRL4(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x25 << 1))
-+#define PCIE_PHY_PLL_CTRL5(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x26 << 1))
-+#define PCIE_PHY_PLL_CTRL6(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x27 << 1))
-+#define PCIE_PHY_PLL_CTRL7(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x28 << 1))
-+#define PCIE_PHY_PLL_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x29 << 1))
-+#define PCIE_PHY_PLL_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2A << 1))
-+#define PCIE_PHY_PLL_A_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2B << 1))
-+#define PCIE_PHY_PLL_STATUS(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2C << 1))
-+
-+#define PCIE_PHY_TX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x30 << 1))
-+#define PCIE_PHY_TX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x31 << 1))
-+#define PCIE_PHY_TX1_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x32 << 1))
-+#define PCIE_PHY_TX1_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x33 << 1))
-+#define PCIE_PHY_TX1_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x34 << 1))
-+#define PCIE_PHY_TX1_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x35 << 1))
-+#define PCIE_PHY_TX1_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x36 << 1))
-+#define PCIE_PHY_TX1_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x37 << 1))
-+
-+#define PCIE_PHY_TX2_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x38 << 1))
-+#define PCIE_PHY_TX2_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x39 << 1))
-+#define PCIE_PHY_TX2_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3B << 1))
-+#define PCIE_PHY_TX2_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3C << 1))
-+#define PCIE_PHY_TX2_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3D << 1))
-+#define PCIE_PHY_TX2_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3E << 1))
-+#define PCIE_PHY_TX2_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3F << 1))
-+
-+#define PCIE_PHY_RX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x50 << 1))
-+#define PCIE_PHY_RX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x51 << 1))
-+#define PCIE_PHY_RX1_CDR(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x52 << 1))
-+#define PCIE_PHY_RX1_EI(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x53 << 1))
-+#define PCIE_PHY_RX1_A_CTRL(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x55 << 1))
-+
-+/* Interrupt related stuff */
-+#define PCIE_LEGACY_DISABLE 0
-+#define PCIE_LEGACY_INTA 1
-+#define PCIE_LEGACY_INTB 2
-+#define PCIE_LEGACY_INTC 3
-+#define PCIE_LEGACY_INTD 4
-+#define PCIE_LEGACY_INT_MAX PCIE_LEGACY_INTD
-+
-+#endif /* IFXMIPS_PCIE_REG_H */
-+
---- /dev/null
-+++ b/arch/mips/pci/ifxmips_pcie_vr9.h
-@@ -0,0 +1,284 @@
-+/****************************************************************************
-+ Copyright (c) 2010
-+ Lantiq Deutschland GmbH
-+ Am Campeon 3; 85579 Neubiberg, Germany
-+
-+ For licensing information, see the file 'LICENSE' in the root folder of
-+ this software module.
-+
-+ *****************************************************************************/
-+/*!
-+ \file ifxmips_pcie_vr9.h
-+ \ingroup IFX_PCIE
-+ \brief PCIe RC driver vr9 specific file
-+*/
-+
-+#ifndef IFXMIPS_PCIE_VR9_H
-+#define IFXMIPS_PCIE_VR9_H
-+
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+
-+#include <linux/gpio.h>
-+#include <lantiq_soc.h>
-+
-+#define IFX_PCIE_GPIO_RESET 494
-+
-+#define IFX_REG_R32 ltq_r32
-+#define IFX_REG_W32 ltq_w32
-+#define CONFIG_IFX_PCIE_HW_SWAP
-+#define IFX_RCU_AHB_ENDIAN ((volatile u32*)(IFX_RCU + 0x004C))
-+#define IFX_RCU_RST_REQ ((volatile u32*)(IFX_RCU + 0x0010))
-+#define IFX_RCU_AHB_BE_PCIE_PDI 0x00000080 /* Configure PCIE PDI module in big endian*/
-+
-+#define IFX_RCU (KSEG1 | 0x1F203000)
-+#define IFX_RCU_AHB_BE_PCIE_M 0x00000001 /* Configure AHB master port that connects to PCIe RC in big endian */
-+#define IFX_RCU_AHB_BE_PCIE_S 0x00000010 /* Configure AHB slave port that connects to PCIe RC in little endian */
-+#define IFX_RCU_AHB_BE_XBAR_M 0x00000002 /* Configure AHB master port that connects to XBAR in big endian */
-+#define IFX_RCU_AHB_BE_XBAR_S 0x00000008 /* Configure AHB slave port that connects to XBAR in big endian */
-+#define CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+
-+#define IFX_PMU1_MODULE_PCIE_PHY (0)
-+#define IFX_PMU1_MODULE_PCIE_CTRL (1)
-+#define IFX_PMU1_MODULE_PDI (4)
-+#define IFX_PMU1_MODULE_MSI (5)
-+
-+#define IFX_PMU_MODULE_PCIE_L0_CLK (31)
-+
-+
-+#define IFX_GPIO (KSEG1 | 0x1E100B00)
-+#define ALT0 ((volatile u32*)(IFX_GPIO + 0x007c))
-+#define ALT1 ((volatile u32*)(IFX_GPIO + 0x0080))
-+#define OD ((volatile u32*)(IFX_GPIO + 0x0084))
-+#define DIR ((volatile u32*)(IFX_GPIO + 0x0078))
-+#define OUT ((volatile u32*)(IFX_GPIO + 0x0070))
-+
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+
-+ gpio_request(IFX_PCIE_GPIO_RESET, "pcie-reset");
-+ gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+
-+/* ifx_gpio_pin_reserve(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_dir_out_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_altsel0_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_altsel1_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+ ifx_gpio_open_drain_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);*/
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ /* Enable AHB bus master/slave */
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "ahb");
-+ clk_enable(clk);
-+
-+ //AHBM_PMU_SETUP(IFX_PMU_ENABLE);
-+ //AHBS_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg |= IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#else
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "phy");
-+ clk_enable(clk);
-+
-+ //PCIE_PHY_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "phy");
-+ clk_disable(clk);
-+
-+// PCIE_PHY_PMU_SETUP(IFX_PMU_DISABLE);
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* SRAM2PDI endianness control. */
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ /* Enable PDI to access PCIe PHY register */
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "pdi");
-+ clk_enable(clk);
-+ //PDI_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-+ reg |= 0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ /* Reset PCIe PHY & Core, bit 22 */
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg |= 0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
-+// ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-+// gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+ //ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("1d900000.pcie", "ctl");
-+ clk_enable(clk);
-+ clk = clk_get_sys("1d900000.pcie", "bus");
-+ clk_enable(clk);
-+
-+ /* PCIe Core controller enabled */
-+// PCIE_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
-+
-+ /* Enable PCIe L0 Clock */
-+// PCIE_L0_CLK_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ struct clk *clk;
-+ pcie_msi_pic_init(pcie_port);
-+ clk = clk_get_sys("ltq_pcie", "msi");
-+ clk_enable(clk);
-+// MSI_PMU_SETUP(IFX_PMU_ENABLE);
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+#endif /* CONFIG_PCI_LANTIQ */
-+ return tbus_number;
-+}
-+
-+static inline struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ #endif /* CONFIG_PCI_LANTIQ */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_VR9_H */
---- a/arch/mips/pci/pci-legacy.c
-+++ b/arch/mips/pci/pci-legacy.c
-@@ -305,3 +305,30 @@ char *__init pcibios_setup(char *str)
- return pcibios_plat_setup(str);
- return str;
- }
-+
-+int pcibios_host_nr(void)
-+{
-+ int count = 0;
-+ struct pci_controller *hose;
-+ list_for_each_entry(hose, &controllers, list) {
-+ count++;
-+ }
-+ return count;
-+}
-+EXPORT_SYMBOL(pcibios_host_nr);
-+
-+int pcibios_1st_host_bus_nr(void)
-+{
-+ int bus_nr = 0;
-+ struct pci_controller *hose;
-+
-+ hose = list_first_entry_or_null(&controllers, struct pci_controller, list);
-+
-+ if (hose != NULL) {
-+ if (hose->bus != NULL) {
-+ bus_nr = hose->bus->number + 1;
-+ }
-+ }
-+ return bus_nr;
-+}
-+EXPORT_SYMBOL(pcibios_1st_host_bus_nr);
---- /dev/null
-+++ b/arch/mips/pci/pcie-lantiq.h
-@@ -0,0 +1,1316 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifxmips_pcie_reg.h
-+** PROJECT : IFX UEIP for VRX200
-+** MODULES : PCIe module
-+**
-+** DATE : 02 Mar 2009
-+** AUTHOR : Lei Chuanhua
-+** DESCRIPTION : PCIe Root Complex Driver
-+** COPYRIGHT : Copyright (c) 2009
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+** HISTORY
-+** $Version $Date $Author $Comment
-+** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
-+*******************************************************************************/
-+#ifndef IFXMIPS_PCIE_REG_H
-+#define IFXMIPS_PCIE_REG_H
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/pci.h>
-+#include <linux/interrupt.h>
-+/*!
-+ \file ifxmips_pcie_reg.h
-+ \ingroup IFX_PCIE
-+ \brief header file for PCIe module register definition
-+*/
-+/* PCIe Address Mapping Base */
-+#define PCIE_CFG_PHY_BASE 0x1D000000UL
-+#define PCIE_CFG_BASE (KSEG1 + PCIE_CFG_PHY_BASE)
-+#define PCIE_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE_MEM_PHY_BASE 0x1C000000UL
-+#define PCIE_MEM_BASE (KSEG1 + PCIE_MEM_PHY_BASE)
-+#define PCIE_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE_MEM_PHY_END (PCIE_MEM_PHY_BASE + PCIE_MEM_SIZE - 1)
-+
-+#define PCIE_IO_PHY_BASE 0x1D800000UL
-+#define PCIE_IO_BASE (KSEG1 + PCIE_IO_PHY_BASE)
-+#define PCIE_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE_IO_PHY_END (PCIE_IO_PHY_BASE + PCIE_IO_SIZE - 1)
-+
-+#define PCIE_RC_CFG_BASE (KSEG1 + 0x1D900000)
-+#define PCIE_APP_LOGIC_REG (KSEG1 + 0x1E100900)
-+#define PCIE_MSI_PHY_BASE 0x1F600000UL
-+
-+#define PCIE_PDI_PHY_BASE 0x1F106800UL
-+#define PCIE_PDI_BASE (KSEG1 + PCIE_PDI_PHY_BASE)
-+#define PCIE_PDI_SIZE 0x400
-+
-+#define PCIE1_CFG_PHY_BASE 0x19000000UL
-+#define PCIE1_CFG_BASE (KSEG1 + PCIE1_CFG_PHY_BASE)
-+#define PCIE1_CFG_SIZE (8 * 1024 * 1024)
-+
-+#define PCIE1_MEM_PHY_BASE 0x18000000UL
-+#define PCIE1_MEM_BASE (KSEG1 + PCIE1_MEM_PHY_BASE)
-+#define PCIE1_MEM_SIZE (16 * 1024 * 1024)
-+#define PCIE1_MEM_PHY_END (PCIE1_MEM_PHY_BASE + PCIE1_MEM_SIZE - 1)
-+
-+#define PCIE1_IO_PHY_BASE 0x19800000UL
-+#define PCIE1_IO_BASE (KSEG1 + PCIE1_IO_PHY_BASE)
-+#define PCIE1_IO_SIZE (1 * 1024 * 1024)
-+#define PCIE1_IO_PHY_END (PCIE1_IO_PHY_BASE + PCIE1_IO_SIZE - 1)
-+
-+#define PCIE1_RC_CFG_BASE (KSEG1 + 0x19900000)
-+#define PCIE1_APP_LOGIC_REG (KSEG1 + 0x1E100700)
-+#define PCIE1_MSI_PHY_BASE 0x1F400000UL
-+
-+#define PCIE1_PDI_PHY_BASE 0x1F700400UL
-+#define PCIE1_PDI_BASE (KSEG1 + PCIE1_PDI_PHY_BASE)
-+#define PCIE1_PDI_SIZE 0x400
-+
-+#define PCIE_CFG_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_CFG_BASE) : (PCIE_CFG_BASE))
-+#define PCIE_MEM_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_BASE) : (PCIE_MEM_BASE))
-+#define PCIE_IO_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_BASE) : (PCIE_IO_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_MEM_PHY_BASE) : (PCIE_MEM_PHY_BASE))
-+#define PCIE_MEM_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_MEM_PHY_END) : (PCIE_MEM_PHY_END))
-+#define PCIE_IO_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_IO_PHY_BASE) : (PCIE_IO_PHY_BASE))
-+#define PCIE_IO_PHY_PORT_TO_END(X) ((X) > 0 ? (PCIE1_IO_PHY_END) : (PCIE_IO_PHY_END))
-+#define PCIE_APP_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_APP_LOGIC_REG) : (PCIE_APP_LOGIC_REG))
-+#define PCIE_RC_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_RC_CFG_BASE) : (PCIE_RC_CFG_BASE))
-+#define PCIE_PHY_PORT_TO_BASE(X) ((X) > 0 ? (PCIE1_PDI_BASE) : (PCIE_PDI_BASE))
-+
-+/* PCIe Application Logic Register */
-+/* RC Core Control Register */
-+#define PCIE_RC_CCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x10)
-+/* This should be enabled after initializing configuratin registers
-+ * Also should check link status retraining bit
-+ */
-+#define PCIE_RC_CCR_LTSSM_ENABLE 0x00000001 /* Enable LTSSM to continue link establishment */
-+
-+/* RC Core Debug Register */
-+#define PCIE_RC_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x14)
-+#define PCIE_RC_DR_DLL_UP 0x00000001 /* Data Link Layer Up */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE 0x0000000E /* Current Power State */
-+#define PCIE_RC_DR_CURRENT_POWER_STATE_S 1
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE 0x000001F0 /* Current LTSSM State */
-+#define PCIE_RC_DR_CURRENT_LTSSM_STATE_S 4
-+
-+#define PCIE_RC_DR_PM_DEV_STATE 0x00000E00 /* Power Management D-State */
-+#define PCIE_RC_DR_PM_DEV_STATE_S 9
-+
-+#define PCIE_RC_DR_PM_ENABLED 0x00001000 /* Power Management State from PMU */
-+#define PCIE_RC_DR_PME_EVENT_ENABLED 0x00002000 /* Power Management Event Enable State */
-+#define PCIE_RC_DR_AUX_POWER_ENABLED 0x00004000 /* Auxiliary Power Enable */
-+
-+/* Current Power State Definition */
-+enum {
-+ PCIE_RC_DR_D0 = 0,
-+ PCIE_RC_DR_D1, /* Not supported */
-+ PCIE_RC_DR_D2, /* Not supported */
-+ PCIE_RC_DR_D3,
-+ PCIE_RC_DR_UN,
-+};
-+
-+/* PHY Link Status Register */
-+#define PCIE_PHY_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x18)
-+#define PCIE_PHY_SR_PHY_LINK_UP 0x00000001 /* PHY Link Up/Down Indicator */
-+
-+/* Electromechanical Control Register */
-+#define PCIE_EM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x1C)
-+#define PCIE_EM_CR_CARD_IS_PRESENT 0x00000001 /* Card Presence Detect State */
-+#define PCIE_EM_CR_MRL_OPEN 0x00000002 /* MRL Sensor State */
-+#define PCIE_EM_CR_POWER_FAULT_SET 0x00000004 /* Power Fault Detected */
-+#define PCIE_EM_CR_MRL_SENSOR_SET 0x00000008 /* MRL Sensor Changed */
-+#define PCIE_EM_CR_PRESENT_DETECT_SET 0x00000010 /* Card Presense Detect Changed */
-+#define PCIE_EM_CR_CMD_CPL_INT_SET 0x00000020 /* Command Complete Interrupt */
-+#define PCIE_EM_CR_SYS_INTERLOCK_SET 0x00000040 /* System Electromechanical IterLock Engaged */
-+#define PCIE_EM_CR_ATTENTION_BUTTON_SET 0x00000080 /* Attention Button Pressed */
-+
-+/* Interrupt Status Register */
-+#define PCIE_IR_SR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x20)
-+#define PCIE_IR_SR_PME_CAUSE_MSI 0x00000002 /* MSI caused by PME */
-+#define PCIE_IR_SR_HP_PME_WAKE_GEN 0x00000004 /* Hotplug PME Wake Generation */
-+#define PCIE_IR_SR_HP_MSI 0x00000008 /* Hotplug MSI */
-+#define PCIE_IR_SR_AHB_LU_ERR 0x00000030 /* AHB Bridge Lookup Error Signals */
-+#define PCIE_IR_SR_AHB_LU_ERR_S 4
-+#define PCIE_IR_SR_INT_MSG_NUM 0x00003E00 /* Interrupt Message Number */
-+#define PCIE_IR_SR_INT_MSG_NUM_S 9
-+#define PCIE_IR_SR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_IR_SR_AER_INT_MSG_NUM_S 27
-+
-+/* Message Control Register */
-+#define PCIE_MSG_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x30)
-+#define PCIE_MSG_CR_GEN_PME_TURN_OFF_MSG 0x00000001 /* Generate PME Turn Off Message */
-+#define PCIE_MSG_CR_GEN_UNLOCK_MSG 0x00000002 /* Generate Unlock Message */
-+
-+#define PCIE_VDM_DR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x34)
-+
-+/* Vendor-Defined Message Requester ID Register */
-+#define PCIE_VDM_RID(X) (PCIE_APP_PORT_TO_BASE (X) + 0x38)
-+#define PCIE_VDM_RID_VENROR_MSG_REQ_ID 0x0000FFFF
-+#define PCIE_VDM_RID_VDMRID_S 0
-+
-+/* ASPM Control Register */
-+#define PCIE_ASPM_CR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x40)
-+#define PCIE_ASPM_CR_HOT_RST 0x00000001 /* Hot Reset Request to the downstream device */
-+#define PCIE_ASPM_CR_REQ_EXIT_L1 0x00000002 /* Request to Exit L1 */
-+#define PCIE_ASPM_CR_REQ_ENTER_L1 0x00000004 /* Request to Enter L1 */
-+
-+/* Vendor Message DW0 Register */
-+#define PCIE_VM_MSG_DW0(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x50)
-+#define PCIE_VM_MSG_DW0_TYPE 0x0000001F /* Message type */
-+#define PCIE_VM_MSG_DW0_TYPE_S 0
-+#define PCIE_VM_MSG_DW0_FORMAT 0x00000060 /* Format */
-+#define PCIE_VM_MSG_DW0_FORMAT_S 5
-+#define PCIE_VM_MSG_DW0_TC 0x00007000 /* Traffic Class */
-+#define PCIE_VM_MSG_DW0_TC_S 12
-+#define PCIE_VM_MSG_DW0_ATTR 0x000C0000 /* Atrributes */
-+#define PCIE_VM_MSG_DW0_ATTR_S 18
-+#define PCIE_VM_MSG_DW0_EP_TLP 0x00100000 /* Poisoned TLP */
-+#define PCIE_VM_MSG_DW0_TD 0x00200000 /* TLP Digest */
-+#define PCIE_VM_MSG_DW0_LEN 0xFFC00000 /* Length */
-+#define PCIE_VM_MSG_DW0_LEN_S 22
-+
-+/* Format Definition */
-+enum {
-+ PCIE_VM_MSG_FORMAT_00 = 0, /* 3DW Hdr, no data*/
-+ PCIE_VM_MSG_FORMAT_01, /* 4DW Hdr, no data */
-+ PCIE_VM_MSG_FORMAT_10, /* 3DW Hdr, with data */
-+ PCIE_VM_MSG_FORMAT_11, /* 4DW Hdr, with data */
-+};
-+
-+/* Traffic Class Definition */
-+enum {
-+ PCIE_VM_MSG_TC0 = 0,
-+ PCIE_VM_MSG_TC1,
-+ PCIE_VM_MSG_TC2,
-+ PCIE_VM_MSG_TC3,
-+ PCIE_VM_MSG_TC4,
-+ PCIE_VM_MSG_TC5,
-+ PCIE_VM_MSG_TC6,
-+ PCIE_VM_MSG_TC7,
-+};
-+
-+/* Attributes Definition */
-+enum {
-+ PCIE_VM_MSG_ATTR_00 = 0, /* RO and No Snoop cleared */
-+ PCIE_VM_MSG_ATTR_01, /* RO cleared , No Snoop set */
-+ PCIE_VM_MSG_ATTR_10, /* RO set, No Snoop cleared*/
-+ PCIE_VM_MSG_ATTR_11, /* RO and No Snoop set */
-+};
-+
-+/* Payload Size Definition */
-+#define PCIE_VM_MSG_LEN_MIN 0
-+#define PCIE_VM_MSG_LEN_MAX 1024
-+
-+/* Vendor Message DW1 Register */
-+#define PCIE_VM_MSG_DW1(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x54)
-+#define PCIE_VM_MSG_DW1_FUNC_NUM 0x00000070 /* Function Number */
-+#define PCIE_VM_MSG_DW1_FUNC_NUM_S 8
-+#define PCIE_VM_MSG_DW1_CODE 0x00FF0000 /* Message Code */
-+#define PCIE_VM_MSG_DW1_CODE_S 16
-+#define PCIE_VM_MSG_DW1_TAG 0xFF000000 /* Tag */
-+#define PCIE_VM_MSG_DW1_TAG_S 24
-+
-+#define PCIE_VM_MSG_DW2(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x58)
-+#define PCIE_VM_MSG_DW3(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x5C)
-+
-+/* Vendor Message Request Register */
-+#define PCIE_VM_MSG_REQR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x60)
-+#define PCIE_VM_MSG_REQR_REQ 0x00000001 /* Vendor Message Request */
-+
-+
-+/* AHB Slave Side Band Control Register */
-+#define PCIE_AHB_SSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x70)
-+#define PCIE_AHB_SSB_REQ_BCM 0x00000001 /* Slave Reques BCM filed */
-+#define PCIE_AHB_SSB_REQ_EP 0x00000002 /* Slave Reques EP filed */
-+#define PCIE_AHB_SSB_REQ_TD 0x00000004 /* Slave Reques TD filed */
-+#define PCIE_AHB_SSB_REQ_ATTR 0x00000018 /* Slave Reques Attribute number */
-+#define PCIE_AHB_SSB_REQ_ATTR_S 3
-+#define PCIE_AHB_SSB_REQ_TC 0x000000E0 /* Slave Request TC Field */
-+#define PCIE_AHB_SSB_REQ_TC_S 5
-+
-+/* AHB Master SideBand Ctrl Register */
-+#define PCIE_AHB_MSB(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x74)
-+#define PCIE_AHB_MSB_RESP_ATTR 0x00000003 /* Master Response Attribute number */
-+#define PCIE_AHB_MSB_RESP_ATTR_S 0
-+#define PCIE_AHB_MSB_RESP_BAD_EOT 0x00000004 /* Master Response Badeot filed */
-+#define PCIE_AHB_MSB_RESP_BCM 0x00000008 /* Master Response BCM filed */
-+#define PCIE_AHB_MSB_RESP_EP 0x00000010 /* Master Response EP filed */
-+#define PCIE_AHB_MSB_RESP_TD 0x00000020 /* Master Response TD filed */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM 0x000003C0 /* Master Response Function number */
-+#define PCIE_AHB_MSB_RESP_FUN_NUM_S 6
-+
-+/* AHB Control Register, fixed bus enumeration exception */
-+#define PCIE_AHB_CTRL(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0x78)
-+#define PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS 0x00000001
-+
-+/* Interrupt Enalbe Register */
-+#define PCIE_IRNEN(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF4)
-+#define PCIE_IRNCR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xF8)
-+#define PCIE_IRNICR(X) (volatile u32*)(PCIE_APP_PORT_TO_BASE(X) + 0xFC)
-+
-+/* PCIe interrupt enable/control/capture register definition */
-+#define PCIE_IRN_AER_REPORT 0x00000001 /* AER Interrupt */
-+#define PCIE_IRN_AER_MSIX 0x00000002 /* Advanced Error MSI-X Interrupt */
-+#define PCIE_IRN_PME 0x00000004 /* PME Interrupt */
-+#define PCIE_IRN_HOTPLUG 0x00000008 /* Hotplug Interrupt */
-+#define PCIE_IRN_RX_VDM_MSG 0x00000010 /* Vendor-Defined Message Interrupt */
-+#define PCIE_IRN_RX_CORRECTABLE_ERR_MSG 0x00000020 /* Correctable Error Message Interrupt */
-+#define PCIE_IRN_RX_NON_FATAL_ERR_MSG 0x00000040 /* Non-fatal Error Message */
-+#define PCIE_IRN_RX_FATAL_ERR_MSG 0x00000080 /* Fatal Error Message */
-+#define PCIE_IRN_RX_PME_MSG 0x00000100 /* PME Message Interrupt */
-+#define PCIE_IRN_RX_PME_TURNOFF_ACK 0x00000200 /* PME Turnoff Ack Message Interrupt */
-+#define PCIE_IRN_AHB_BR_FATAL_ERR 0x00000400 /* AHB Fatal Error Interrupt */
-+#define PCIE_IRN_LINK_AUTO_BW_STATUS 0x00000800 /* Link Auto Bandwidth Status Interrupt */
-+#define PCIE_IRN_BW_MGT 0x00001000 /* Bandwidth Managment Interrupt */
-+#define PCIE_IRN_INTA 0x00002000 /* INTA */
-+#define PCIE_IRN_INTB 0x00004000 /* INTB */
-+#define PCIE_IRN_INTC 0x00008000 /* INTC */
-+#define PCIE_IRN_INTD 0x00010000 /* INTD */
-+#define PCIE_IRN_WAKEUP 0x00020000 /* Wake up Interrupt */
-+
-+#define PCIE_RC_CORE_COMBINED_INT (PCIE_IRN_AER_REPORT | PCIE_IRN_AER_MSIX | PCIE_IRN_PME | \
-+ PCIE_IRN_HOTPLUG | PCIE_IRN_RX_VDM_MSG | PCIE_IRN_RX_CORRECTABLE_ERR_MSG |\
-+ PCIE_IRN_RX_NON_FATAL_ERR_MSG | PCIE_IRN_RX_FATAL_ERR_MSG | \
-+ PCIE_IRN_RX_PME_MSG | PCIE_IRN_RX_PME_TURNOFF_ACK | PCIE_IRN_AHB_BR_FATAL_ERR | \
-+ PCIE_IRN_LINK_AUTO_BW_STATUS | PCIE_IRN_BW_MGT)
-+/* PCIe RC Configuration Register */
-+#define PCIE_VDID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x00)
-+
-+/* Bit definition from pci_reg.h */
-+#define PCIE_PCICMDSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x04)
-+#define PCIE_CCRID(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x08)
-+#define PCIE_CLSLTHTBR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x0C) /* EP only */
-+/* BAR0, BAR1,Only necessary if the bridges implements a device-specific register set or memory buffer */
-+#define PCIE_BAR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10) /* Not used*/
-+#define PCIE_BAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14) /* Not used */
-+
-+#define PCIE_BNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x18) /* Mandatory */
-+/* Bus Number Register bits */
-+#define PCIE_BNR_PRIMARY_BUS_NUM 0x000000FF
-+#define PCIE_BNR_PRIMARY_BUS_NUM_S 0
-+#define PCIE_PNR_SECONDARY_BUS_NUM 0x0000FF00
-+#define PCIE_PNR_SECONDARY_BUS_NUM_S 8
-+#define PCIE_PNR_SUB_BUS_NUM 0x00FF0000
-+#define PCIE_PNR_SUB_BUS_NUM_S 16
-+
-+/* IO Base/Limit Register bits */
-+#define PCIE_IOBLSECS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x1C) /* RC only */
-+#define PCIE_IOBLSECS_32BIT_IO_ADDR 0x00000001
-+#define PCIE_IOBLSECS_IO_BASE_ADDR 0x000000F0
-+#define PCIE_IOBLSECS_IO_BASE_ADDR_S 4
-+#define PCIE_IOBLSECS_32BIT_IOLIMT 0x00000100
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR 0x0000F000
-+#define PCIE_IOBLSECS_IO_LIMIT_ADDR_S 12
-+
-+/* Non-prefetchable Memory Base/Limit Register bit */
-+#define PCIE_MBML(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x20) /* RC only */
-+#define PCIE_MBML_MEM_BASE_ADDR 0x0000FFF0
-+#define PCIE_MBML_MEM_BASE_ADDR_S 4
-+#define PCIE_MBML_MEM_LIMIT_ADDR 0xFFF00000
-+#define PCIE_MBML_MEM_LIMIT_ADDR_S 20
-+
-+/* Prefetchable Memory Base/Limit Register bit */
-+#define PCIE_PMBL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x24) /* RC only */
-+#define PCIE_PMBL_64BIT_ADDR 0x00000001
-+#define PCIE_PMBL_UPPER_12BIT 0x0000FFF0
-+#define PCIE_PMBL_UPPER_12BIT_S 4
-+#define PCIE_PMBL_E64MA 0x00010000
-+#define PCIE_PMBL_END_ADDR 0xFFF00000
-+#define PCIE_PMBL_END_ADDR_S 20
-+#define PCIE_PMBU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x28) /* RC only */
-+#define PCIE_PMLU32(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x2C) /* RC only */
-+
-+/* I/O Base/Limit Upper 16 bits register */
-+#define PCIE_IO_BANDL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x30) /* RC only */
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE 0x0000FFFF
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_BASE_S 0
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT 0xFFFF0000
-+#define PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT_S 16
-+
-+#define PCIE_CPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x34)
-+#define PCIE_EBBAR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x38)
-+
-+/* Interrupt and Secondary Bridge Control Register */
-+#define PCIE_INTRBCTRL(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x3C)
-+
-+#define PCIE_INTRBCTRL_INT_LINE 0x000000FF
-+#define PCIE_INTRBCTRL_INT_LINE_S 0
-+#define PCIE_INTRBCTRL_INT_PIN 0x0000FF00
-+#define PCIE_INTRBCTRL_INT_PIN_S 8
-+#define PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE 0x00010000 /* #PERR */
-+#define PCIE_INTRBCTRL_SERR_ENABLE 0x00020000 /* #SERR */
-+#define PCIE_INTRBCTRL_ISA_ENABLE 0x00040000 /* ISA enable, IO 64KB only */
-+#define PCIE_INTRBCTRL_VGA_ENABLE 0x00080000 /* VGA enable */
-+#define PCIE_INTRBCTRL_VGA_16BIT_DECODE 0x00100000 /* VGA 16bit decode */
-+#define PCIE_INTRBCTRL_RST_SECONDARY_BUS 0x00400000 /* Secondary bus rest, hot rest, 1ms */
-+/* Others are read only */
-+enum {
-+ PCIE_INTRBCTRL_INT_NON = 0,
-+ PCIE_INTRBCTRL_INTA,
-+ PCIE_INTRBCTRL_INTB,
-+ PCIE_INTRBCTRL_INTC,
-+ PCIE_INTRBCTRL_INTD,
-+};
-+
-+#define PCIE_PM_CAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x40)
-+
-+/* Power Management Control and Status Register */
-+#define PCIE_PM_CSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x44)
-+
-+#define PCIE_PM_CSR_POWER_STATE 0x00000003 /* Power State */
-+#define PCIE_PM_CSR_POWER_STATE_S 0
-+#define PCIE_PM_CSR_SW_RST 0x00000008 /* Soft Reset Enabled */
-+#define PCIE_PM_CSR_PME_ENABLE 0x00000100 /* PME Enable */
-+#define PCIE_PM_CSR_PME_STATUS 0x00008000 /* PME status */
-+
-+/* MSI Capability Register for EP */
-+#define PCIE_MCAPR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x50)
-+
-+#define PCIE_MCAPR_MSI_CAP_ID 0x000000FF /* MSI Capability ID */
-+#define PCIE_MCAPR_MSI_CAP_ID_S 0
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_MCAPR_MSI_NEXT_CAP_PTR_S 8
-+#define PCIE_MCAPR_MSI_ENABLE 0x00010000 /* MSI Enable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP 0x000E0000 /* Multiple Message Capable */
-+#define PCIE_MCAPR_MULTI_MSG_CAP_S 17
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE 0x00700000 /* Multiple Message Enable */
-+#define PCIE_MCAPR_MULTI_MSG_ENABLE_S 20
-+#define PCIE_MCAPR_ADDR64_CAP 0X00800000 /* 64-bit Address Capable */
-+
-+/* MSI Message Address Register */
-+#define PCIE_MA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x54)
-+
-+#define PCIE_MA_ADDR_MASK 0xFFFFFFFC /* Message Address */
-+
-+/* MSI Message Upper Address Register */
-+#define PCIE_MUA(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x58)
-+
-+/* MSI Message Data Register */
-+#define PCIE_MD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x5C)
-+
-+#define PCIE_MD_DATA 0x0000FFFF /* Message Data */
-+#define PCIE_MD_DATA_S 0
-+
-+/* PCI Express Capability Register */
-+#define PCIE_XCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70)
-+
-+#define PCIE_XCAP_ID 0x000000FF /* PCI Express Capability ID */
-+#define PCIE_XCAP_ID_S 0
-+#define PCIE_XCAP_NEXT_CAP 0x0000FF00 /* Next Capability Pointer */
-+#define PCIE_XCAP_NEXT_CAP_S 8
-+#define PCIE_XCAP_VER 0x000F0000 /* PCI Express Capability Version */
-+#define PCIE_XCAP_VER_S 16
-+#define PCIE_XCAP_DEV_PORT_TYPE 0x00F00000 /* Device Port Type */
-+#define PCIE_XCAP_DEV_PORT_TYPE_S 20
-+#define PCIE_XCAP_SLOT_IMPLEMENTED 0x01000000 /* Slot Implemented */
-+#define PCIE_XCAP_MSG_INT_NUM 0x3E000000 /* Interrupt Message Number */
-+#define PCIE_XCAP_MSG_INT_NUM_S 25
-+
-+/* Device Capability Register */
-+#define PCIE_DCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74)
-+
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE 0x00000007 /* Max Payload size */
-+#define PCIE_DCAP_MAX_PAYLOAD_SIZE_S 0
-+#define PCIE_DCAP_PHANTOM_FUNC 0x00000018 /* Phanton Function, not supported */
-+#define PCIE_DCAP_PHANTOM_FUNC_S 3
-+#define PCIE_DCAP_EXT_TAG 0x00000020 /* Extended Tag Field */
-+#define PCIE_DCAP_EP_L0S_LATENCY 0x000001C0 /* EP L0s latency only */
-+#define PCIE_DCAP_EP_L0S_LATENCY_S 6
-+#define PCIE_DCAP_EP_L1_LATENCY 0x00000E00 /* EP L1 latency only */
-+#define PCIE_DCAP_EP_L1_LATENCY_S 9
-+#define PCIE_DCAP_ROLE_BASE_ERR_REPORT 0x00008000 /* Role Based ERR */
-+
-+/* Maximum payload size supported */
-+enum {
-+ PCIE_MAX_PAYLOAD_128 = 0,
-+ PCIE_MAX_PAYLOAD_256,
-+ PCIE_MAX_PAYLOAD_512,
-+ PCIE_MAX_PAYLOAD_1024,
-+ PCIE_MAX_PAYLOAD_2048,
-+ PCIE_MAX_PAYLOAD_4096,
-+};
-+
-+/* Device Control and Status Register */
-+#define PCIE_DCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x78)
-+
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR_EN 0x00000001 /* COR-ERR */
-+#define PCIE_DCTLSTS_NONFATAL_ERR_EN 0x00000002 /* Non-fatal ERR */
-+#define PCIE_DCTLSTS_FATAL_ERR_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_DCTLSYS_UR_REQ_EN 0x00000008 /* UR ERR */
-+#define PCIE_DCTLSTS_RELAXED_ORDERING_EN 0x00000010 /* Enable relaxing ordering */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE 0x000000E0 /* Max payload mask */
-+#define PCIE_DCTLSTS_MAX_PAYLOAD_SIZE_S 5
-+#define PCIE_DCTLSTS_EXT_TAG_EN 0x00000100 /* Extended tag field */
-+#define PCIE_DCTLSTS_PHANTOM_FUNC_EN 0x00000200 /* Phantom Function Enable */
-+#define PCIE_DCTLSTS_AUX_PM_EN 0x00000400 /* AUX Power PM Enable */
-+#define PCIE_DCTLSTS_NO_SNOOP_EN 0x00000800 /* Enable no snoop, except root port*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE 0x00007000 /* Max Read Request size*/
-+#define PCIE_DCTLSTS_MAX_READ_SIZE_S 12
-+#define PCIE_DCTLSTS_CORRECTABLE_ERR 0x00010000 /* COR-ERR Detected */
-+#define PCIE_DCTLSTS_NONFATAL_ERR 0x00020000 /* Non-Fatal ERR Detected */
-+#define PCIE_DCTLSTS_FATAL_ER 0x00040000 /* Fatal ERR Detected */
-+#define PCIE_DCTLSTS_UNSUPPORTED_REQ 0x00080000 /* UR Detected */
-+#define PCIE_DCTLSTS_AUX_POWER 0x00100000 /* Aux Power Detected */
-+#define PCIE_DCTLSTS_TRANSACT_PENDING 0x00200000 /* Transaction pending */
-+
-+#define PCIE_DCTLSTS_ERR_EN (PCIE_DCTLSTS_CORRECTABLE_ERR_EN | \
-+ PCIE_DCTLSTS_NONFATAL_ERR_EN | PCIE_DCTLSTS_FATAL_ERR_EN | \
-+ PCIE_DCTLSYS_UR_REQ_EN)
-+
-+/* Link Capability Register */
-+#define PCIE_LCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7C)
-+#define PCIE_LCAP_MAX_LINK_SPEED 0x0000000F /* Max link speed, 0x1 by default */
-+#define PCIE_LCAP_MAX_LINK_SPEED_S 0
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH 0x000003F0 /* Maxium Length Width */
-+#define PCIE_LCAP_MAX_LENGTH_WIDTH_S 4
-+#define PCIE_LCAP_ASPM_LEVEL 0x00000C00 /* Active State Link PM Support */
-+#define PCIE_LCAP_ASPM_LEVEL_S 10
-+#define PCIE_LCAP_L0S_EIXT_LATENCY 0x00007000 /* L0s Exit Latency */
-+#define PCIE_LCAP_L0S_EIXT_LATENCY_S 12
-+#define PCIE_LCAP_L1_EXIT_LATENCY 0x00038000 /* L1 Exit Latency */
-+#define PCIE_LCAP_L1_EXIT_LATENCY_S 15
-+#define PCIE_LCAP_CLK_PM 0x00040000 /* Clock Power Management */
-+#define PCIE_LCAP_SDER 0x00080000 /* Surprise Down Error Reporting */
-+#define PCIE_LCAP_DLL_ACTIVE_REPROT 0x00100000 /* Data Link Layer Active Reporting Capable */
-+#define PCIE_LCAP_PORT_NUM 0xFF0000000 /* Port number */
-+#define PCIE_LCAP_PORT_NUM_S 24
-+
-+/* Maximum Length width definition */
-+#define PCIE_MAX_LENGTH_WIDTH_RES 0x00
-+#define PCIE_MAX_LENGTH_WIDTH_X1 0x01 /* Default */
-+#define PCIE_MAX_LENGTH_WIDTH_X2 0x02
-+#define PCIE_MAX_LENGTH_WIDTH_X4 0x04
-+#define PCIE_MAX_LENGTH_WIDTH_X8 0x08
-+#define PCIE_MAX_LENGTH_WIDTH_X12 0x0C
-+#define PCIE_MAX_LENGTH_WIDTH_X16 0x10
-+#define PCIE_MAX_LENGTH_WIDTH_X32 0x20
-+
-+/* Active State Link PM definition */
-+enum {
-+ PCIE_ASPM_RES0 = 0,
-+ PCIE_ASPM_L0S_ENTRY_SUPPORT, /* L0s */
-+ PCIE_ASPM_RES1,
-+ PCIE_ASPM_L0S_L1_ENTRY_SUPPORT, /* L0s and L1, default */
-+};
-+
-+/* L0s Exit Latency definition */
-+enum {
-+ PCIE_L0S_EIXT_LATENCY_L64NS = 0, /* < 64 ns */
-+ PCIE_L0S_EIXT_LATENCY_B64A128, /* > 64 ns < 128 ns */
-+ PCIE_L0S_EIXT_LATENCY_B128A256, /* > 128 ns < 256 ns */
-+ PCIE_L0S_EIXT_LATENCY_B256A512, /* > 256 ns < 512 ns */
-+ PCIE_L0S_EIXT_LATENCY_B512TO1U, /* > 512 ns < 1 us */
-+ PCIE_L0S_EIXT_LATENCY_B1A2U, /* > 1 us < 2 us */
-+ PCIE_L0S_EIXT_LATENCY_B2A4U, /* > 2 us < 4 us */
-+ PCIE_L0S_EIXT_LATENCY_M4US, /* > 4 us */
-+};
-+
-+/* L1 Exit Latency definition */
-+enum {
-+ PCIE_L1_EXIT_LATENCY_L1US = 0, /* < 1 us */
-+ PCIE_L1_EXIT_LATENCY_B1A2, /* > 1 us < 2 us */
-+ PCIE_L1_EXIT_LATENCY_B2A4, /* > 2 us < 4 us */
-+ PCIE_L1_EXIT_LATENCY_B4A8, /* > 4 us < 8 us */
-+ PCIE_L1_EXIT_LATENCY_B8A16, /* > 8 us < 16 us */
-+ PCIE_L1_EXIT_LATENCY_B16A32, /* > 16 us < 32 us */
-+ PCIE_L1_EXIT_LATENCY_B32A64, /* > 32 us < 64 us */
-+ PCIE_L1_EXIT_LATENCY_M64US, /* > 64 us */
-+};
-+
-+/* Link Control and Status Register */
-+#define PCIE_LCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x80)
-+#define PCIE_LCTLSTS_ASPM_ENABLE 0x00000003 /* Active State Link PM Control */
-+#define PCIE_LCTLSTS_ASPM_ENABLE_S 0
-+#define PCIE_LCTLSTS_RCB128 0x00000008 /* Read Completion Boundary 128*/
-+#define PCIE_LCTLSTS_LINK_DISABLE 0x00000010 /* Link Disable */
-+#define PCIE_LCTLSTS_RETRIAN_LINK 0x00000020 /* Retrain Link */
-+#define PCIE_LCTLSTS_COM_CLK_CFG 0x00000040 /* Common Clock Configuration */
-+#define PCIE_LCTLSTS_EXT_SYNC 0x00000080 /* Extended Synch */
-+#define PCIE_LCTLSTS_CLK_PM_EN 0x00000100 /* Enable Clock Powerm Management */
-+#define PCIE_LCTLSTS_LINK_SPEED 0x000F0000 /* Link Speed */
-+#define PCIE_LCTLSTS_LINK_SPEED_S 16
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH 0x03F00000 /* Negotiated Link Width */
-+#define PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH_S 20
-+#define PCIE_LCTLSTS_RETRAIN_PENDING 0x08000000 /* Link training is ongoing */
-+#define PCIE_LCTLSTS_SLOT_CLK_CFG 0x10000000 /* Slot Clock Configuration */
-+#define PCIE_LCTLSTS_DLL_ACTIVE 0x20000000 /* Data Link Layer Active */
-+
-+/* Slot Capabilities Register */
-+#define PCIE_SLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x84)
-+
-+/* Slot Capabilities */
-+#define PCIE_SLCTLSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x88)
-+
-+/* Root Control and Capability Register */
-+#define PCIE_RCTLCAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x8C)
-+#define PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR 0x00000001 /* #SERR on COR-ERR */
-+#define PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR 0x00000002 /* #SERR on Non-Fatal ERR */
-+#define PCIE_RCTLCAP_SERR_ON_FATAL_ERR 0x00000004 /* #SERR on Fatal ERR */
-+#define PCIE_RCTLCAP_PME_INT_EN 0x00000008 /* PME Interrupt Enable */
-+#define PCIE_RCTLCAP_SERR_ENABLE (PCIE_RCTLCAP_SERR_ON_CORRECTABLE_ERR | \
-+ PCIE_RCTLCAP_SERR_ON_NONFATAL_ERR | PCIE_RCTLCAP_SERR_ON_FATAL_ERR)
-+/* Root Status Register */
-+#define PCIE_RSTS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x90)
-+#define PCIE_RSTS_PME_REQ_ID 0x0000FFFF /* PME Request ID */
-+#define PCIE_RSTS_PME_REQ_ID_S 0
-+#define PCIE_RSTS_PME_STATUS 0x00010000 /* PME Status */
-+#define PCIE_RSTS_PME_PENDING 0x00020000 /* PME Pending */
-+
-+/* PCI Express Enhanced Capability Header */
-+#define PCIE_ENHANCED_CAP(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x100)
-+#define PCIE_ENHANCED_CAP_ID 0x0000FFFF /* PCI Express Extended Capability ID */
-+#define PCIE_ENHANCED_CAP_ID_S 0
-+#define PCIE_ENHANCED_CAP_VER 0x000F0000 /* Capability Version */
-+#define PCIE_ENHANCED_CAP_VER_S 16
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET 0xFFF00000 /* Next Capability Offset */
-+#define PCIE_ENHANCED_CAP_NEXT_OFFSET_S 20
-+
-+/* Uncorrectable Error Status Register */
-+#define PCIE_UES_R(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x104)
-+#define PCIE_DATA_LINK_PROTOCOL_ERR 0x00000010 /* Data Link Protocol Error Status */
-+#define PCIE_SURPRISE_DOWN_ERROR 0x00000020 /* Surprise Down Error Status */
-+#define PCIE_POISONED_TLP 0x00001000 /* Poisoned TLP Status */
-+#define PCIE_FC_PROTOCOL_ERR 0x00002000 /* Flow Control Protocol Error Status */
-+#define PCIE_COMPLETION_TIMEOUT 0x00004000 /* Completion Timeout Status */
-+#define PCIE_COMPLETOR_ABORT 0x00008000 /* Completer Abort Error */
-+#define PCIE_UNEXPECTED_COMPLETION 0x00010000 /* Unexpected Completion Status */
-+#define PCIE_RECEIVER_OVERFLOW 0x00020000 /* Receive Overflow Status */
-+#define PCIE_MALFORNED_TLP 0x00040000 /* Malformed TLP Stauts */
-+#define PCIE_ECRC_ERR 0x00080000 /* ECRC Error Stauts */
-+#define PCIE_UR_REQ 0x00100000 /* Unsupported Request Error Status */
-+#define PCIE_ALL_UNCORRECTABLE_ERR (PCIE_DATA_LINK_PROTOCOL_ERR | PCIE_SURPRISE_DOWN_ERROR | \
-+ PCIE_POISONED_TLP | PCIE_FC_PROTOCOL_ERR | PCIE_COMPLETION_TIMEOUT | \
-+ PCIE_COMPLETOR_ABORT | PCIE_UNEXPECTED_COMPLETION | PCIE_RECEIVER_OVERFLOW |\
-+ PCIE_MALFORNED_TLP | PCIE_ECRC_ERR | PCIE_UR_REQ)
-+
-+/* Uncorrectable Error Mask Register, Mask means no report */
-+#define PCIE_UEMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x108)
-+
-+/* Uncorrectable Error Severity Register */
-+#define PCIE_UESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x10C)
-+
-+/* Correctable Error Status Register */
-+#define PCIE_CESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x110)
-+#define PCIE_RX_ERR 0x00000001 /* Receive Error Status */
-+#define PCIE_BAD_TLP 0x00000040 /* Bad TLP Status */
-+#define PCIE_BAD_DLLP 0x00000080 /* Bad DLLP Status */
-+#define PCIE_REPLAY_NUM_ROLLOVER 0x00000100 /* Replay Number Rollover Status */
-+#define PCIE_REPLAY_TIMER_TIMEOUT_ERR 0x00001000 /* Reply Timer Timeout Status */
-+#define PCIE_ADVISORY_NONFTAL_ERR 0x00002000 /* Advisory Non-Fatal Error Status */
-+#define PCIE_CORRECTABLE_ERR (PCIE_RX_ERR | PCIE_BAD_TLP | PCIE_BAD_DLLP | PCIE_REPLAY_NUM_ROLLOVER |\
-+ PCIE_REPLAY_TIMER_TIMEOUT_ERR | PCIE_ADVISORY_NONFTAL_ERR)
-+
-+/* Correctable Error Mask Register */
-+#define PCIE_CEMR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x114)
-+
-+/* Advanced Error Capabilities and Control Register */
-+#define PCIE_AECCR(X) (volatile u32*)(PCIE_RC_CFG_BASE + 0x118)
-+#define PCIE_AECCR_FIRST_ERR_PTR 0x0000001F /* First Error Pointer */
-+#define PCIE_AECCR_FIRST_ERR_PTR_S 0
-+#define PCIE_AECCR_ECRC_GEN_CAP 0x00000020 /* ECRC Generation Capable */
-+#define PCIE_AECCR_ECRC_GEN_EN 0x00000040 /* ECRC Generation Enable */
-+#define PCIE_AECCR_ECRC_CHECK_CAP 0x00000080 /* ECRC Check Capable */
-+#define PCIE_AECCR_ECRC_CHECK_EN 0x00000100 /* ECRC Check Enable */
-+
-+/* Header Log Register 1 */
-+#define PCIE_HLR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x11C)
-+
-+/* Header Log Register 2 */
-+#define PCIE_HLR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x120)
-+
-+/* Header Log Register 3 */
-+#define PCIE_HLR3(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x124)
-+
-+/* Header Log Register 4 */
-+#define PCIE_HLR4(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x128)
-+
-+/* Root Error Command Register */
-+#define PCIE_RECR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x12C)
-+#define PCIE_RECR_CORRECTABLE_ERR_REPORT_EN 0x00000001 /* COR-ERR */
-+#define PCIE_RECR_NONFATAL_ERR_REPORT_EN 0x00000002 /* Non-Fatal ERR */
-+#define PCIE_RECR_FATAL_ERR_REPORT_EN 0x00000004 /* Fatal ERR */
-+#define PCIE_RECR_ERR_REPORT_EN (PCIE_RECR_CORRECTABLE_ERR_REPORT_EN | \
-+ PCIE_RECR_NONFATAL_ERR_REPORT_EN | PCIE_RECR_FATAL_ERR_REPORT_EN)
-+
-+/* Root Error Status Register */
-+#define PCIE_RESR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x130)
-+#define PCIE_RESR_CORRECTABLE_ERR 0x00000001 /* COR-ERR Receveid */
-+#define PCIE_RESR_MULTI_CORRECTABLE_ERR 0x00000002 /* Multiple COR-ERR Received */
-+#define PCIE_RESR_FATAL_NOFATAL_ERR 0x00000004 /* ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_MULTI_FATAL_NOFATAL_ERR 0x00000008 /* Multiple ERR Fatal/Non-Fatal Received */
-+#define PCIE_RESR_FIRST_UNCORRECTABLE_FATAL_ERR 0x00000010 /* First UN-COR Fatal */
-+#define PCIR_RESR_NON_FATAL_ERR 0x00000020 /* Non-Fatal Error Message Received */
-+#define PCIE_RESR_FATAL_ERR 0x00000040 /* Fatal Message Received */
-+#define PCIE_RESR_AER_INT_MSG_NUM 0xF8000000 /* Advanced Error Interrupt Message Number */
-+#define PCIE_RESR_AER_INT_MSG_NUM_S 27
-+
-+/* Error Source Indentification Register */
-+#define PCIE_ESIR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x134)
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID 0x0000FFFF
-+#define PCIE_ESIR_CORRECTABLE_ERR_SRC_ID_S 0
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID 0xFFFF0000
-+#define PCIE_ESIR_FATAL_NON_FATAL_SRC_ID_S 16
-+
-+/* VC Enhanced Capability Header */
-+#define PCIE_VC_ECH(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x140)
-+
-+/* Port VC Capability Register */
-+#define PCIE_PVC1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x144)
-+#define PCIE_PVC1_EXT_VC_CNT 0x00000007 /* Extended VC Count */
-+#define PCIE_PVC1_EXT_VC_CNT_S 0
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT 0x00000070 /* Low Priority Extended VC Count */
-+#define PCIE_PVC1_LOW_PRI_EXT_VC_CNT_S 4
-+#define PCIE_PVC1_REF_CLK 0x00000300 /* Reference Clock */
-+#define PCIE_PVC1_REF_CLK_S 8
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE 0x00000C00 /* Port Arbitration Table Entry Size */
-+#define PCIE_PVC1_PORT_ARB_TAB_ENTRY_SIZE_S 10
-+
-+/* Extended Virtual Channel Count Defintion */
-+#define PCIE_EXT_VC_CNT_MIN 0
-+#define PCIE_EXT_VC_CNT_MAX 7
-+
-+/* Port Arbitration Table Entry Size Definition */
-+enum {
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S1BIT = 0,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S2BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S4BIT,
-+ PCIE_PORT_ARB_TAB_ENTRY_SIZE_S8BIT,
-+};
-+
-+/* Port VC Capability Register 2 */
-+#define PCIE_PVC2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x148)
-+#define PCIE_PVC2_VC_ARB_16P_FIXED_WRR 0x00000001 /* HW Fixed arbitration, 16 phase WRR */
-+#define PCIE_PVC2_VC_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_PVC2_VC_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_PVC2_VC_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_PVC2_VC_ARB_WRR 0x0000000F
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET 0xFF000000 /* VC arbitration table offset, not support */
-+#define PCIE_PVC2_VC_ARB_TAB_OFFSET_S 24
-+
-+/* Port VC Control and Status Register */
-+#define PCIE_PVCCRSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x14C)
-+#define PCIE_PVCCRSR_LOAD_VC_ARB_TAB 0x00000001 /* Load VC Arbitration Table */
-+#define PCIE_PVCCRSR_VC_ARB_SEL 0x0000000E /* VC Arbitration Select */
-+#define PCIE_PVCCRSR_VC_ARB_SEL_S 1
-+#define PCIE_PVCCRSR_VC_ARB_TAB_STATUS 0x00010000 /* Arbitration Status */
-+
-+/* VC0 Resource Capability Register */
-+#define PCIE_VC0_RC(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x150)
-+#define PCIE_VC0_RC_PORT_ARB_HW_FIXED 0x00000001 /* HW Fixed arbitration */
-+#define PCIE_VC0_RC_PORT_ARB_32P_WRR 0x00000002 /* 32 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_64P_WRR 0x00000004 /* 64 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_128P_WRR 0x00000008 /* 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_128P_WRR 0x00000010 /* Time-based 128 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB_TM_256P_WRR 0x00000020 /* Time-based 256 phase WRR */
-+#define PCIE_VC0_RC_PORT_ARB (PCIE_VC0_RC_PORT_ARB_HW_FIXED | PCIE_VC0_RC_PORT_ARB_32P_WRR |\
-+ PCIE_VC0_RC_PORT_ARB_64P_WRR | PCIE_VC0_RC_PORT_ARB_128P_WRR | \
-+ PCIE_VC0_RC_PORT_ARB_TM_128P_WRR | PCIE_VC0_RC_PORT_ARB_TM_256P_WRR)
-+
-+#define PCIE_VC0_RC_REJECT_SNOOP 0x00008000 /* Reject Snoop Transactioin */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS 0x007F0000 /* Maximum time Slots */
-+#define PCIE_VC0_RC_MAX_TIMESLOTS_S 16
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET 0xFF000000 /* Port Arbitration Table Offset */
-+#define PCIE_VC0_RC_PORT_ARB_TAB_OFFSET_S 24
-+
-+/* VC0 Resource Control Register */
-+#define PCIE_VC0_RC0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x154)
-+#define PCIE_VC0_RC0_TVM0 0x00000001 /* TC0 and VC0 */
-+#define PCIE_VC0_RC0_TVM1 0x00000002 /* TC1 and VC1 */
-+#define PCIE_VC0_RC0_TVM2 0x00000004 /* TC2 and VC2 */
-+#define PCIE_VC0_RC0_TVM3 0x00000008 /* TC3 and VC3 */
-+#define PCIE_VC0_RC0_TVM4 0x00000010 /* TC4 and VC4 */
-+#define PCIE_VC0_RC0_TVM5 0x00000020 /* TC5 and VC5 */
-+#define PCIE_VC0_RC0_TVM6 0x00000040 /* TC6 and VC6 */
-+#define PCIE_VC0_RC0_TVM7 0x00000080 /* TC7 and VC7 */
-+#define PCIE_VC0_RC0_TC_VC 0x000000FF /* TC/VC mask */
-+
-+#define PCIE_VC0_RC0_LOAD_PORT_ARB_TAB 0x00010000 /* Load Port Arbitration Table */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL 0x000E0000 /* Port Arbitration Select */
-+#define PCIE_VC0_RC0_PORT_ARB_SEL_S 17
-+#define PCIE_VC0_RC0_VC_ID 0x07000000 /* VC ID */
-+#define PCIE_VC0_RC0_VC_ID_S 24
-+#define PCIE_VC0_RC0_VC_EN 0x80000000 /* VC Enable */
-+
-+/* VC0 Resource Status Register */
-+#define PCIE_VC0_RSR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x158)
-+#define PCIE_VC0_RSR0_PORT_ARB_TAB_STATUS 0x00010000 /* Port Arbitration Table Status,not used */
-+#define PCIE_VC0_RSR0_VC_NEG_PENDING 0x00020000 /* VC Negotiation Pending */
-+
-+/* Ack Latency Timer and Replay Timer Register */
-+#define PCIE_ALTRT(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x700)
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT 0x0000FFFF /* Round Trip Latency Time Limit */
-+#define PCIE_ALTRT_ROUND_TRIP_LATENCY_LIMIT_S 0
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT 0xFFFF0000 /* Replay Time Limit */
-+#define PCIE_ALTRT_REPLAY_TIME_LIMIT_S 16
-+
-+/* Other Message Register */
-+#define PCIE_OMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x704)
-+
-+/* Port Force Link Register */
-+#define PCIE_PFLR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x708)
-+#define PCIE_PFLR_LINK_NUM 0x000000FF /* Link Number */
-+#define PCIE_PFLR_LINK_NUM_S 0
-+#define PCIE_PFLR_FORCE_LINK 0x00008000 /* Force link */
-+#define PCIE_PFLR_LINK_STATE 0x003F0000 /* Link State */
-+#define PCIE_PFLR_LINK_STATE_S 16
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT 0xFF000000 /* Low Power Entrance Count, only for EP */
-+#define PCIE_PFLR_LOW_POWER_ENTRY_CNT_S 24
-+
-+/* Ack Frequency Register */
-+#define PCIE_AFR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x70C)
-+#define PCIE_AFR_AF 0x000000FF /* Ack Frequency */
-+#define PCIE_AFR_AF_S 0
-+#define PCIE_AFR_FTS_NUM 0x0000FF00 /* The number of Fast Training Sequence from L0S to L0 */
-+#define PCIE_AFR_FTS_NUM_S 8
-+#define PCIE_AFR_COM_FTS_NUM 0x00FF0000 /* N_FTS; when common clock is used*/
-+#define PCIE_AFR_COM_FTS_NUM_S 16
-+#define PCIE_AFR_L0S_ENTRY_LATENCY 0x07000000 /* L0s Entrance Latency */
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_S 24
-+#define PCIE_AFR_L1_ENTRY_LATENCY 0x38000000 /* L1 Entrance Latency */
-+#define PCIE_AFR_L1_ENTRY_LATENCY_S 27
-+#define PCIE_AFR_FTS_NUM_DEFAULT 32
-+#define PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT 7
-+#define PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT 5
-+
-+/* Port Link Control Register */
-+#define PCIE_PLCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x710)
-+#define PCIE_PLCR_OTHER_MSG_REQ 0x00000001 /* Other Message Request */
-+#define PCIE_PLCR_SCRAMBLE_DISABLE 0x00000002 /* Scramble Disable */
-+#define PCIE_PLCR_LOOPBACK_EN 0x00000004 /* Loopback Enable */
-+#define PCIE_PLCR_LTSSM_HOT_RST 0x00000008 /* Force LTSSM to the hot reset */
-+#define PCIE_PLCR_DLL_LINK_EN 0x00000020 /* Enable Link initialization */
-+#define PCIE_PLCR_FAST_LINK_SIM_EN 0x00000080 /* Sets all internal timers to fast mode for simulation purposes */
-+#define PCIE_PLCR_LINK_MODE 0x003F0000 /* Link Mode Enable Mask */
-+#define PCIE_PLCR_LINK_MODE_S 16
-+#define PCIE_PLCR_CORRUPTED_CRC_EN 0x02000000 /* Enabled Corrupt CRC */
-+
-+/* Lane Skew Register */
-+#define PCIE_LSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x714)
-+#define PCIE_LSR_LANE_SKEW_NUM 0x00FFFFFF /* Insert Lane Skew for Transmit, not applicable */
-+#define PCIE_LSR_LANE_SKEW_NUM_S 0
-+#define PCIE_LSR_FC_DISABLE 0x01000000 /* Disable of Flow Control */
-+#define PCIE_LSR_ACKNAK_DISABLE 0x02000000 /* Disable of Ack/Nak */
-+#define PCIE_LSR_LANE_DESKEW_DISABLE 0x80000000 /* Disable of Lane-to-Lane Skew */
-+
-+/* Symbol Number Register */
-+#define PCIE_SNR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x718)
-+#define PCIE_SNR_TS 0x0000000F /* Number of TS Symbol */
-+#define PCIE_SNR_TS_S 0
-+#define PCIE_SNR_SKP 0x00000700 /* Number of SKP Symbol */
-+#define PCIE_SNR_SKP_S 8
-+#define PCIE_SNR_REPLAY_TIMER 0x0007C000 /* Timer Modifier for Replay Timer */
-+#define PCIE_SNR_REPLAY_TIMER_S 14
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER 0x00F80000 /* Timer Modifier for Ack/Nak Latency Timer */
-+#define PCIE_SNR_ACKNAK_LATENCY_TIMER_S 19
-+#define PCIE_SNR_FC_TIMER 0x1F000000 /* Timer Modifier for Flow Control Watchdog Timer */
-+#define PCIE_SNR_FC_TIMER_S 28
-+
-+/* Symbol Timer Register and Filter Mask Register 1 */
-+#define PCIE_STRFMR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x71C)
-+#define PCIE_STRFMR_SKP_INTERVAL 0x000007FF /* SKP lnterval Value */
-+#define PCIE_STRFMR_SKP_INTERVAL_S 0
-+#define PCIE_STRFMR_FC_WDT_DISABLE 0x00008000 /* Disable of FC Watchdog Timer */
-+#define PCIE_STRFMR_TLP_FUNC_MISMATCH_OK 0x00010000 /* Mask Function Mismatch Filtering for Incoming Requests */
-+#define PCIE_STRFMR_POISONED_TLP_OK 0x00020000 /* Mask Poisoned TLP Filtering */
-+#define PCIE_STRFMR_BAR_MATCH_OK 0x00040000 /* Mask BAR Match Filtering */
-+#define PCIE_STRFMR_TYPE1_CFG_REQ_OK 0x00080000 /* Mask Type 1 Configuration Request Filtering */
-+#define PCIE_STRFMR_LOCKED_REQ_OK 0x00100000 /* Mask Locked Request Filtering */
-+#define PCIE_STRFMR_CPL_TAG_ERR_RULES_OK 0x00200000 /* Mask Tag Error Rules for Received Completions */
-+#define PCIE_STRFMR_CPL_REQUESTOR_ID_MISMATCH_OK 0x00400000 /* Mask Requester ID Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_FUNC_MISMATCH_OK 0x00800000 /* Mask Function Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_TC_MISMATCH_OK 0x01000000 /* Mask Traffic Class Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_ATTR_MISMATCH_OK 0x02000000 /* Mask Attribute Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_CPL_LENGTH_MISMATCH_OK 0x04000000 /* Mask Length Mismatch Error for Received Completions */
-+#define PCIE_STRFMR_TLP_ECRC_ERR_OK 0x08000000 /* Mask ECRC Error Filtering */
-+#define PCIE_STRFMR_CPL_TLP_ECRC_OK 0x10000000 /* Mask ECRC Error Filtering for Completions */
-+#define PCIE_STRFMR_RX_TLP_MSG_NO_DROP 0x20000000 /* Send Message TLPs */
-+#define PCIE_STRFMR_RX_IO_TRANS_ENABLE 0x40000000 /* Mask Filtering of received I/O Requests */
-+#define PCIE_STRFMR_RX_CFG_TRANS_ENABLE 0x80000000 /* Mask Filtering of Received Configuration Requests */
-+
-+#define PCIE_DEF_SKP_INTERVAL 700 /* 1180 ~1538 , 125MHz * 2, 250MHz * 1 */
-+
-+/* Filter Masker Register 2 */
-+#define PCIE_FMR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x720)
-+#define PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1 0x00000001 /* Mask RADM Filtering and Error Handling Rules */
-+#define PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 0x00000002 /* Mask RADM Filtering and Error Handling Rules */
-+
-+/* Debug Register 0 */
-+#define PCIE_DBR0(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x728)
-+
-+/* Debug Register 1 */
-+#define PCIE_DBR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x72C)
-+
-+/* Transmit Posted FC Credit Status Register */
-+#define PCIE_TPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x730)
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS 0x00000FFF /* Transmit Posted Data FC Credits */
-+#define PCIE_TPFCS_TX_P_DATA_FC_CREDITS_S 0
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS 0x000FF000 /* Transmit Posted Header FC Credits */
-+#define PCIE_TPFCS_TX_P_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Non-Posted FC Credit Status */
-+#define PCIE_TNPFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x734)
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS 0x00000FFF /* Transmit Non-Posted Data FC Credits */
-+#define PCIE_TNPFCS_TX_NP_DATA_FC_CREDITS_S 0
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS 0x000FF000 /* Transmit Non-Posted Header FC Credits */
-+#define PCIE_TNPFCS_TX_NP_HDR_FC_CREDITS_S 12
-+
-+/* Transmit Complete FC Credit Status Register */
-+#define PCIE_TCFCS(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x738)
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS 0x00000FFF /* Transmit Completion Data FC Credits */
-+#define PCIE_TCFCS_TX_CPL_DATA_FC_CREDITS_S 0
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS 0x000FF000 /* Transmit Completion Header FC Credits */
-+#define PCIE_TCFCS_TX_CPL_HDR_FC_CREDITS_S 12
-+
-+/* Queue Status Register */
-+#define PCIE_QSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x73C)
-+#define PCIE_QSR_WAIT_UPDATE_FC_DLL 0x00000001 /* Received TLP FC Credits Not Returned */
-+#define PCIE_QSR_TX_RETRY_BUF_NOT_EMPTY 0x00000002 /* Transmit Retry Buffer Not Empty */
-+#define PCIE_QSR_RX_QUEUE_NOT_EMPTY 0x00000004 /* Received Queue Not Empty */
-+
-+/* VC Transmit Arbitration Register 1 */
-+#define PCIE_VCTAR1(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x740)
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC0 0x000000FF /* WRR Weight for VC0 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC1 0x0000FF00 /* WRR Weight for VC1 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC2 0x00FF0000 /* WRR Weight for VC2 */
-+#define PCIE_VCTAR1_WRR_WEIGHT_VC3 0xFF000000 /* WRR Weight for VC3 */
-+
-+/* VC Transmit Arbitration Register 2 */
-+#define PCIE_VCTAR2(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x744)
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC4 0x000000FF /* WRR Weight for VC4 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC5 0x0000FF00 /* WRR Weight for VC5 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC6 0x00FF0000 /* WRR Weight for VC6 */
-+#define PCIE_VCTAR2_WRR_WEIGHT_VC7 0xFF000000 /* WRR Weight for VC7 */
-+
-+/* VC0 Posted Receive Queue Control Register */
-+#define PCIE_VC0_PRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x748)
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS 0x00000FFF /* VC0 Posted Data Credits */
-+#define PCIE_VC0_PRQCR_P_DATA_CREDITS_S 0
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS 0x000FF000 /* VC0 Posted Header Credits */
-+#define PCIE_VC0_PRQCR_P_HDR_CREDITS_S 12
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE 0x00E00000 /* VC0 Posted TLP Queue Mode */
-+#define PCIE_VC0_PRQCR_P_TLP_QUEUE_MODE_S 20
-+#define PCIE_VC0_PRQCR_TLP_RELAX_ORDER 0x40000000 /* TLP Type Ordering for VC0 */
-+#define PCIE_VC0_PRQCR_VC_STRICT_ORDER 0x80000000 /* VC0 Ordering for Receive Queues */
-+
-+/* VC0 Non-Posted Receive Queue Control */
-+#define PCIE_VC0_NPRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x74C)
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS 0x00000FFF /* VC0 Non-Posted Data Credits */
-+#define PCIE_VC0_NPRQCR_NP_DATA_CREDITS_S 0
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS 0x000FF000 /* VC0 Non-Posted Header Credits */
-+#define PCIE_VC0_NPRQCR_NP_HDR_CREDITS_S 12
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE 0x00E00000 /* VC0 Non-Posted TLP Queue Mode */
-+#define PCIE_VC0_NPRQCR_NP_TLP_QUEUE_MODE_S 20
-+
-+/* VC0 Completion Receive Queue Control */
-+#define PCIE_VC0_CRQCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x750)
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS 0x00000FFF /* VC0 Completion TLP Queue Mode */
-+#define PCIE_VC0_CRQCR_CPL_DATA_CREDITS_S 0
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS 0x000FF000 /* VC0 Completion Header Credits */
-+#define PCIE_VC0_CRQCR_CPL_HDR_CREDITS_S 12
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE 0x00E00000 /* VC0 Completion Data Credits */
-+#define PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE_S 21
-+
-+/* Applicable to the above three registers */
-+enum {
-+ PCIE_VC0_TLP_QUEUE_MODE_STORE_FORWARD = 1,
-+ PCIE_VC0_TLP_QUEUE_MODE_CUT_THROUGH = 2,
-+ PCIE_VC0_TLP_QUEUE_MODE_BYPASS = 4,
-+};
-+
-+/* VC0 Posted Buffer Depth Register */
-+#define PCIE_VC0_PBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7A8)
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Posted Data Queue Depth */
-+#define PCIE_VC0_PBD_P_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Posted Header Queue Depth */
-+#define PCIE_VC0_PBD_P_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Non-Posted Buffer Depth Register */
-+#define PCIE_VC0_NPBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7AC)
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES 0x00003FFF /* VC0 Non-Posted Data Queue Depth */
-+#define PCIE_VC0_NPBD_NP_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Non-Posted Header Queue Depth */
-+#define PCIE_VC0_NPBD_NP_HDR_QUEUE_ENTRIES_S 16
-+
-+/* VC0 Completion Buffer Depth Register */
-+#define PCIE_VC0_CBD(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x7B0)
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES 0x00003FFF /* C0 Completion Data Queue Depth */
-+#define PCIE_VC0_CBD_CPL_DATA_QUEUE_ENTRIES_S 0
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES 0x03FF0000 /* VC0 Completion Header Queue Depth */
-+#define PCIE_VC0_CBD_CPL_HDR_QUEUE_ENTRIES_S 16
-+
-+/* PHY Status Register, all zeros in VR9 */
-+#define PCIE_PHYSR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x810)
-+
-+/* PHY Control Register, all zeros in VR9 */
-+#define PCIE_PHYCR(X) (volatile u32*)(PCIE_RC_PORT_TO_BASE(X) + 0x814)
-+
-+/*
-+ * PCIe PDI PHY register definition, suppose all the following
-+ * stuff is confidential.
-+ * XXX, detailed bit definition
-+ */
-+#define PCIE_PHY_PLL_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x22 << 1))
-+#define PCIE_PHY_PLL_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x23 << 1))
-+#define PCIE_PHY_PLL_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x24 << 1))
-+#define PCIE_PHY_PLL_CTRL4(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x25 << 1))
-+#define PCIE_PHY_PLL_CTRL5(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x26 << 1))
-+#define PCIE_PHY_PLL_CTRL6(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x27 << 1))
-+#define PCIE_PHY_PLL_CTRL7(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x28 << 1))
-+#define PCIE_PHY_PLL_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x29 << 1))
-+#define PCIE_PHY_PLL_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2A << 1))
-+#define PCIE_PHY_PLL_A_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2B << 1))
-+#define PCIE_PHY_PLL_STATUS(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x2C << 1))
-+
-+#define PCIE_PHY_TX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x30 << 1))
-+#define PCIE_PHY_TX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x31 << 1))
-+#define PCIE_PHY_TX1_CTRL3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x32 << 1))
-+#define PCIE_PHY_TX1_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x33 << 1))
-+#define PCIE_PHY_TX1_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x34 << 1))
-+#define PCIE_PHY_TX1_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x35 << 1))
-+#define PCIE_PHY_TX1_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x36 << 1))
-+#define PCIE_PHY_TX1_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x37 << 1))
-+
-+#define PCIE_PHY_TX2_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x38 << 1))
-+#define PCIE_PHY_TX2_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x39 << 1))
-+#define PCIE_PHY_TX2_A_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3B << 1))
-+#define PCIE_PHY_TX2_A_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3C << 1))
-+#define PCIE_PHY_TX2_MOD1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3D << 1))
-+#define PCIE_PHY_TX2_MOD2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3E << 1))
-+#define PCIE_PHY_TX2_MOD3(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x3F << 1))
-+
-+#define PCIE_PHY_RX1_CTRL1(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x50 << 1))
-+#define PCIE_PHY_RX1_CTRL2(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x51 << 1))
-+#define PCIE_PHY_RX1_CDR(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x52 << 1))
-+#define PCIE_PHY_RX1_EI(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x53 << 1))
-+#define PCIE_PHY_RX1_A_CTRL(X) (PCIE_PHY_PORT_TO_BASE(X) + (0x55 << 1))
-+
-+/* Interrupt related stuff */
-+#define PCIE_LEGACY_DISABLE 0
-+#define PCIE_LEGACY_INTA 1
-+#define PCIE_LEGACY_INTB 2
-+#define PCIE_LEGACY_INTC 3
-+#define PCIE_LEGACY_INTD 4
-+#define PCIE_LEGACY_INT_MAX PCIE_LEGACY_INTD
-+
-+#define PCIE_IRQ_LOCK(lock) do { \
-+ unsigned long flags; \
-+ spin_lock_irqsave(&(lock), flags);
-+#define PCIE_IRQ_UNLOCK(lock) \
-+ spin_unlock_irqrestore(&(lock), flags); \
-+} while (0)
-+
-+#define PCIE_MSG_MSI 0x00000001
-+#define PCIE_MSG_ISR 0x00000002
-+#define PCIE_MSG_FIXUP 0x00000004
-+#define PCIE_MSG_READ_CFG 0x00000008
-+#define PCIE_MSG_WRITE_CFG 0x00000010
-+#define PCIE_MSG_CFG (PCIE_MSG_READ_CFG | PCIE_MSG_WRITE_CFG)
-+#define PCIE_MSG_REG 0x00000020
-+#define PCIE_MSG_INIT 0x00000040
-+#define PCIE_MSG_ERR 0x00000080
-+#define PCIE_MSG_PHY 0x00000100
-+#define PCIE_MSG_ANY 0x000001ff
-+
-+#define IFX_PCIE_PORT0 0
-+#define IFX_PCIE_PORT1 1
-+
-+#ifdef CONFIG_IFX_PCIE_2ND_CORE
-+#define IFX_PCIE_CORE_NR 2
-+#else
-+#define IFX_PCIE_CORE_NR 1
-+#endif
-+
-+//#define IFX_PCIE_ERROR_INT
-+
-+//#define IFX_PCIE_DBG
-+
-+#if defined(IFX_PCIE_DBG)
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) do { \
-+ if (g_pcie_debug_flag & (_m)) { \
-+ ifx_pcie_debug((_fmt), ##args); \
-+ } \
-+} while (0)
-+
-+#define INLINE
-+#else
-+#define IFX_PCIE_PRINT(_m, _fmt, args...) \
-+ do {} while(0)
-+#define INLINE inline
-+#endif
-+
-+struct ifx_pci_controller {
-+ struct pci_controller pcic;
-+
-+ /* RC specific, per host bus information */
-+ u32 port; /* Port index, 0 -- 1st core, 1 -- 2nd core */
-+};
-+
-+typedef struct ifx_pcie_ir_irq {
-+ const unsigned int irq;
-+ const char name[16];
-+}ifx_pcie_ir_irq_t;
-+
-+typedef struct ifx_pcie_legacy_irq{
-+ const u32 irq_bit;
-+ const int irq;
-+}ifx_pcie_legacy_irq_t;
-+
-+typedef struct ifx_pcie_irq {
-+ ifx_pcie_ir_irq_t ir_irq;
-+ ifx_pcie_legacy_irq_t legacy_irq[PCIE_LEGACY_INT_MAX];
-+}ifx_pcie_irq_t;
-+
-+extern u32 g_pcie_debug_flag;
-+extern void ifx_pcie_debug(const char *fmt, ...);
-+extern void pcie_phy_clock_mode_setup(int pcie_port);
-+extern void pcie_msi_pic_init(int pcie_port);
-+extern u32 ifx_pcie_bus_enum_read_hack(int where, u32 value);
-+extern u32 ifx_pcie_bus_enum_write_hack(int where, u32 value);
-+
-+
-+#include <linux/types.h>
-+#include <linux/delay.h>
-+#include <linux/gpio.h>
-+#include <linux/clk.h>
-+
-+#include <lantiq_soc.h>
-+
-+#define IFX_PCIE_GPIO_RESET 38
-+#define IFX_REG_R32 ltq_r32
-+#define IFX_REG_W32 ltq_w32
-+#define CONFIG_IFX_PCIE_HW_SWAP
-+#define IFX_RCU_AHB_ENDIAN ((volatile u32*)(IFX_RCU + 0x004C))
-+#define IFX_RCU_RST_REQ ((volatile u32*)(IFX_RCU + 0x0010))
-+#define IFX_RCU_AHB_BE_PCIE_PDI 0x00000080 /* Configure PCIE PDI module in big endian*/
-+
-+#define IFX_RCU (KSEG1 | 0x1F203000)
-+#define IFX_RCU_AHB_BE_PCIE_M 0x00000001 /* Configure AHB master port that connects to PCIe RC in big endian */
-+#define IFX_RCU_AHB_BE_PCIE_S 0x00000010 /* Configure AHB slave port that connects to PCIe RC in little endian */
-+#define IFX_RCU_AHB_BE_XBAR_M 0x00000002 /* Configure AHB master port that connects to XBAR in big endian */
-+#define CONFIG_IFX_PCIE_PHY_36MHZ_MODE
-+
-+#define IFX_PMU1_MODULE_PCIE_PHY (0)
-+#define IFX_PMU1_MODULE_PCIE_CTRL (1)
-+#define IFX_PMU1_MODULE_PDI (4)
-+#define IFX_PMU1_MODULE_MSI (5)
-+
-+#define IFX_PMU_MODULE_PCIE_L0_CLK (31)
-+
-+
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+}
-+
-+static inline void pcie_ahb_pmu_setup(void)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "ahb");
-+ clk_enable(clk);
-+ //ltq_pmu_enable(PMU_AHBM | PMU_AHBS);
-+}
-+
-+static inline void pcie_rcu_endian_setup(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg |= IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#else
-+ reg |= IFX_RCU_AHB_BE_PCIE_M;
-+ reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-+ reg &= ~IFX_RCU_AHB_BE_XBAR_M;
-+#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+ IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
-+}
-+
-+static inline void pcie_phy_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "phy");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1<<IFX_PMU1_MODULE_PCIE_PHY);
-+}
-+
-+static inline void pcie_phy_pmu_disable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "phy");
-+ clk_disable(clk);
-+ //ltq_pmu1_disable(1<<IFX_PMU1_MODULE_PCIE_PHY);
-+}
-+
-+static inline void pcie_pdi_big_endian(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* SRAM2PDI endianness control. */
-+ reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-+ /* Config AHB->PCIe and PDI endianness */
-+ reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-+ IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-+}
-+
-+static inline void pcie_pdi_pmu_enable(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "pdi");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1<<IFX_PMU1_MODULE_PDI);
-+}
-+
-+static inline void pcie_core_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+
-+ /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-+ reg |= 0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_core_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ /* Reset PCIe PHY & Core, bit 22 */
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00400000;
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_assert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg |= 0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_phy_rst_deassert(int pcie_port)
-+{
-+ u32 reg;
-+
-+ /* Make sure one micro-second delay */
-+ udelay(1);
-+
-+ reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-+ reg &= ~0x00001000; /* Bit 12 */
-+ IFX_REG_W32(reg, IFX_RCU_RST_REQ);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
-+ // ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-+// ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-+}
-+
-+static inline void pcie_core_pmu_setup(int pcie_port)
-+{
-+ struct clk *clk;
-+ clk = clk_get_sys("ltq_pcie", "ctl");
-+ clk_enable(clk);
-+ clk = clk_get_sys("ltq_pcie", "bus");
-+ clk_enable(clk);
-+
-+ //ltq_pmu1_enable(1 << IFX_PMU1_MODULE_PCIE_CTRL);
-+ //ltq_pmu_enable(1 << IFX_PMU_MODULE_PCIE_L0_CLK);
-+}
-+
-+static inline void pcie_msi_init(int pcie_port)
-+{
-+ struct clk *clk;
-+ pcie_msi_pic_init(pcie_port);
-+ clk = clk_get_sys("ltq_pcie", "msi");
-+ clk_enable(clk);
-+ //ltq_pmu1_enable(1 << IFX_PMU1_MODULE_MSI);
-+}
-+
-+static inline u32
-+ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
-+{
-+ u32 tbus_number = bus_number;
-+
-+#ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tbus_number -= pcibios_1st_host_bus_nr();
-+ }
-+#endif /* CONFIG_PCI_LANTIQ */
-+ return tbus_number;
-+}
-+
-+static struct pci_dev *ifx_pci_get_slot(struct pci_bus *bus, unsigned int devfn)
-+{
-+ struct pci_dev *dev;
-+
-+ list_for_each_entry(dev, &bus->devices, bus_list) {
-+ if (dev->devfn == devfn)
-+ goto out;
-+ }
-+
-+ dev = NULL;
-+ out:
-+ pci_dev_get(dev);
-+ return dev;
-+}
-+
-+static inline u32
-+ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
-+{
-+ struct pci_dev *pdev;
-+ u32 tvalue = value;
-+
-+ /* Sanity check */
-+ pdev = ifx_pci_get_slot(bus, devfn);
-+ if (pdev == NULL) {
-+ return tvalue;
-+ }
-+
-+ /* Only care about PCI bridge */
-+ if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
-+ return tvalue;
-+ }
-+
-+ if (read) { /* Read hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
-+ }
-+ #endif /* CONFIG_PCI_LANTIQ */
-+ }
-+ else { /* Write hack */
-+ #ifdef CONFIG_PCI_LANTIQ
-+ if (pcibios_host_nr() > 1) {
-+ tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
-+ }
-+ #endif
-+ }
-+ return tvalue;
-+}
-+
-+#endif /* IFXMIPS_PCIE_VR9_H */
-+
---- a/drivers/pci/pcie/Kconfig
-+++ b/drivers/pci/pcie/Kconfig
-@@ -51,6 +51,7 @@ config PCIEAER_INJECT
- config PCIE_ECRC
- bool "PCI Express ECRC settings control"
- depends on PCIEAER
-+ default n
- help
- Used to override firmware/bios settings for PCI Express ECRC
- (transaction layer end-to-end CRC checking).
---- a/include/linux/pci.h
-+++ b/include/linux/pci.h
-@@ -1483,6 +1483,8 @@ void pci_walk_bus(struct pci_bus *top, i
- void *userdata);
- int pci_cfg_space_size(struct pci_dev *dev);
- unsigned char pci_bus_max_busnr(struct pci_bus *bus);
-+int pcibios_host_nr(void);
-+int pcibios_1st_host_bus_nr(void);
- void pci_setup_bridge(struct pci_bus *bus);
- resource_size_t pcibios_window_alignment(struct pci_bus *bus,
- unsigned long type);
---- a/include/linux/pci_ids.h
-+++ b/include/linux/pci_ids.h
-@@ -1086,6 +1086,12 @@
- #define PCI_DEVICE_ID_SGI_IOC3 0x0003
- #define PCI_DEVICE_ID_SGI_LITHIUM 0x1002
-
-+#define PCI_VENDOR_ID_INFINEON 0x15D1
-+#define PCI_DEVICE_ID_INFINEON_DANUBE 0x000F
-+#define PCI_DEVICE_ID_INFINEON_PCIE 0x0011
-+#define PCI_VENDOR_ID_LANTIQ 0x1BEF
-+#define PCI_DEVICE_ID_LANTIQ_PCIE 0x0011
-+
- #define PCI_VENDOR_ID_WINBOND 0x10ad
- #define PCI_DEVICE_ID_WINBOND_82C105 0x0105
- #define PCI_DEVICE_ID_WINBOND_83C553 0x0565
+++ /dev/null
-From 9afadf01b1be371ee88491819aa67364684461f9 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Fri, 3 Aug 2012 10:27:25 +0200
-Subject: [PATCH 04/36] MIPS: lantiq: add atm hack
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/include/asm/mach-lantiq/lantiq_atm.h | 196 +++++++++++++++++++++++
- arch/mips/include/asm/mach-lantiq/lantiq_ptm.h | 203 ++++++++++++++++++++++++
- arch/mips/lantiq/irq.c | 2 +
- arch/mips/mm/cache.c | 4 +
- include/uapi/linux/atm.h | 6 +
- net/atm/common.c | 6 +
- net/atm/proc.c | 2 +-
- 7 files changed, 416 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_atm.h
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_ptm.h
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_atm.h
-@@ -0,0 +1,196 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifx_atm.h
-+** PROJECT : UEIP
-+** MODULES : ATM
-+**
-+** DATE : 17 Jun 2009
-+** AUTHOR : Xu Liang
-+** DESCRIPTION : Global ATM driver header file
-+** COPYRIGHT : Copyright (c) 2006
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 07 JUL 2009 Xu Liang Init Version
-+*******************************************************************************/
-+
-+#ifndef IFX_ATM_H
-+#define IFX_ATM_H
-+
-+
-+
-+/*!
-+ \defgroup IFX_ATM UEIP Project - ATM driver module
-+ \brief UEIP Project - ATM driver module, support Danube, Amazon-SE, AR9, VR9.
-+ */
-+
-+/*!
-+ \defgroup IFX_ATM_IOCTL IOCTL Commands
-+ \ingroup IFX_ATM
-+ \brief IOCTL Commands used by user application.
-+ */
-+
-+/*!
-+ \defgroup IFX_ATM_STRUCT Structures
-+ \ingroup IFX_ATM
-+ \brief Structures used by user application.
-+ */
-+
-+/*!
-+ \file ifx_atm.h
-+ \ingroup IFX_ATM
-+ \brief ATM driver header file
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_ATM_STRUCT
-+ */
-+/*@{*/
-+
-+/*
-+ * ATM MIB
-+ */
-+
-+/*!
-+ \struct atm_cell_ifEntry_t
-+ \brief Structure used for Cell Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_CELL".
-+ */
-+typedef struct {
-+ __u32 ifHCInOctets_h; /*!< byte counter of ingress cells (upper 32 bits, total 64 bits) */
-+ __u32 ifHCInOctets_l; /*!< byte counter of ingress cells (lower 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_h; /*!< byte counter of egress cells (upper 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_l; /*!< byte counter of egress cells (lower 32 bits, total 64 bits) */
-+ __u32 ifInErrors; /*!< counter of error ingress cells */
-+ __u32 ifInUnknownProtos; /*!< counter of unknown ingress cells */
-+ __u32 ifOutErrors; /*!< counter of error egress cells */
-+} atm_cell_ifEntry_t;
-+
-+/*!
-+ \struct atm_aal5_ifEntry_t
-+ \brief Structure used for AAL5 Frame Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_AAL5".
-+ */
-+typedef struct {
-+ __u32 ifHCInOctets_h; /*!< byte counter of ingress packets (upper 32 bits, total 64 bits) */
-+ __u32 ifHCInOctets_l; /*!< byte counter of ingress packets (lower 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_h; /*!< byte counter of egress packets (upper 32 bits, total 64 bits) */
-+ __u32 ifHCOutOctets_l; /*!< byte counter of egress packets (lower 32 bits, total 64 bits) */
-+ __u32 ifInUcastPkts; /*!< counter of ingress packets */
-+ __u32 ifOutUcastPkts; /*!< counter of egress packets */
-+ __u32 ifInErrors; /*!< counter of error ingress packets */
-+ __u32 ifInDiscards; /*!< counter of dropped ingress packets */
-+ __u32 ifOutErros; /*!< counter of error egress packets */
-+ __u32 ifOutDiscards; /*!< counter of dropped egress packets */
-+} atm_aal5_ifEntry_t;
-+
-+/*!
-+ \struct atm_aal5_vcc_t
-+ \brief Structure used for per PVC AAL5 Frame Level MIB Counters.
-+
-+ This structure is a part of structure "atm_aal5_vcc_x_t".
-+ */
-+typedef struct {
-+ __u32 aal5VccCrcErrors; /*!< counter of ingress packets with CRC error */
-+ __u32 aal5VccSarTimeOuts; /*!< counter of ingress packets with Re-assemble timeout */ //no timer support yet
-+ __u32 aal5VccOverSizedSDUs; /*!< counter of oversized ingress packets */
-+} atm_aal5_vcc_t;
-+
-+/*!
-+ \struct atm_aal5_vcc_x_t
-+ \brief Structure used for per PVC AAL5 Frame Level MIB Counters.
-+
-+ User application use this structure to call IOCTL command "PPE_ATM_MIB_VCC".
-+ */
-+typedef struct {
-+ int vpi; /*!< VPI of the VCC to get MIB counters */
-+ int vci; /*!< VCI of the VCC to get MIB counters */
-+ atm_aal5_vcc_t mib_vcc; /*!< structure to get MIB counters */
-+} atm_aal5_vcc_x_t;
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * IOCTL
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_ATM_IOCTL
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Command
-+ */
-+/*!
-+ \brief ATM IOCTL Magic Number
-+ */
-+#define PPE_ATM_IOC_MAGIC 'o'
-+/*!
-+ \brief ATM IOCTL Command - Get Cell Level MIB Counters
-+
-+ This command is obsolete. User can get cell level MIB from DSL API.
-+ This command uses structure "atm_cell_ifEntry_t" as parameter for output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_CELL _IOW(PPE_ATM_IOC_MAGIC, 0, atm_cell_ifEntry_t)
-+/*!
-+ \brief ATM IOCTL Command - Get AAL5 Level MIB Counters
-+
-+ Get AAL5 packet counters.
-+ This command uses structure "atm_aal5_ifEntry_t" as parameter for output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_AAL5 _IOW(PPE_ATM_IOC_MAGIC, 1, atm_aal5_ifEntry_t)
-+/*!
-+ \brief ATM IOCTL Command - Get Per PVC MIB Counters
-+
-+ Get AAL5 packet counters for each PVC.
-+ This command uses structure "atm_aal5_vcc_x_t" as parameter for input of VPI/VCI information and output of MIB counters.
-+ */
-+#define PPE_ATM_MIB_VCC _IOWR(PPE_ATM_IOC_MAGIC, 2, atm_aal5_vcc_x_t)
-+/*!
-+ \brief Total Number of ATM IOCTL Commands
-+ */
-+#define PPE_ATM_IOC_MAXNR 3
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * API
-+ * ####################################
-+ */
-+
-+#ifdef __KERNEL__
-+struct port_cell_info {
-+ unsigned int port_num;
-+ unsigned int tx_link_rate[2];
-+};
-+#endif
-+
-+
-+
-+#endif // IFX_ATM_H
-+
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_ptm.h
-@@ -0,0 +1,203 @@
-+/******************************************************************************
-+**
-+** FILE NAME : ifx_ptm.h
-+** PROJECT : UEIP
-+** MODULES : PTM
-+**
-+** DATE : 17 Jun 2009
-+** AUTHOR : Xu Liang
-+** DESCRIPTION : Global PTM driver header file
-+** COPYRIGHT : Copyright (c) 2006
-+** Infineon Technologies AG
-+** Am Campeon 1-12, 85579 Neubiberg, Germany
-+**
-+** 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.
-+**
-+** HISTORY
-+** $Date $Author $Comment
-+** 07 JUL 2009 Xu Liang Init Version
-+*******************************************************************************/
-+
-+#ifndef IFX_PTM_H
-+#define IFX_PTM_H
-+
-+
-+
-+/*!
-+ \defgroup IFX_PTM UEIP Project - PTM driver module
-+ \brief UEIP Project - PTM driver module, support Danube, Amazon-SE, AR9, VR9.
-+ */
-+
-+/*!
-+ \defgroup IFX_PTM_IOCTL IOCTL Commands
-+ \ingroup IFX_PTM
-+ \brief IOCTL Commands used by user application.
-+ */
-+
-+/*!
-+ \defgroup IFX_PTM_STRUCT Structures
-+ \ingroup IFX_PTM
-+ \brief Structures used by user application.
-+ */
-+
-+/*!
-+ \file ifx_ptm.h
-+ \ingroup IFX_PTM
-+ \brief PTM driver header file
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+
-+
-+/*
-+ * ####################################
-+ * IOCTL
-+ * ####################################
-+ */
-+
-+/*!
-+ \addtogroup IFX_PTM_IOCTL
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Command
-+ */
-+/*!
-+ \brief PTM IOCTL Command - Get codeword MIB counters.
-+
-+ This command uses structure "PTM_CW_IF_ENTRY_T" to get codeword level MIB counters.
-+ */
-+#define IFX_PTM_MIB_CW_GET SIOCDEVPRIVATE + 1
-+/*!
-+ \brief PTM IOCTL Command - Get packet MIB counters.
-+
-+ This command uses structure "PTM_FRAME_MIB_T" to get packet level MIB counters.
-+ */
-+#define IFX_PTM_MIB_FRAME_GET SIOCDEVPRIVATE + 2
-+/*!
-+ \brief PTM IOCTL Command - Get firmware configuration (CRC).
-+
-+ This command uses structure "IFX_PTM_CFG_T" to get firmware configuration (CRC).
-+ */
-+#define IFX_PTM_CFG_GET SIOCDEVPRIVATE + 3
-+/*!
-+ \brief PTM IOCTL Command - Set firmware configuration (CRC).
-+
-+ This command uses structure "IFX_PTM_CFG_T" to set firmware configuration (CRC).
-+ */
-+#define IFX_PTM_CFG_SET SIOCDEVPRIVATE + 4
-+/*!
-+ \brief PTM IOCTL Command - Program priority value to TX queue mapping.
-+
-+ This command uses structure "IFX_PTM_PRIO_Q_MAP_T" to program priority value to TX queue mapping.
-+ */
-+#define IFX_PTM_MAP_PKT_PRIO_TO_Q SIOCDEVPRIVATE + 14
-+
-+/*@}*/
-+
-+
-+/*!
-+ \addtogroup IFX_PTM_STRUCT
-+ */
-+/*@{*/
-+
-+/*
-+ * ioctl Data Type
-+ */
-+
-+/*!
-+ \typedef PTM_CW_IF_ENTRY_T
-+ \brief Wrapping of structure "ptm_cw_ifEntry_t".
-+ */
-+/*!
-+ \struct ptm_cw_ifEntry_t
-+ \brief Structure used for CodeWord level MIB counters.
-+ */
-+typedef struct ptm_cw_ifEntry_t {
-+ uint32_t ifRxNoIdleCodewords; /*!< output, number of ingress user codeword */
-+ uint32_t ifRxIdleCodewords; /*!< output, number of ingress idle codeword */
-+ uint32_t ifRxCodingViolation; /*!< output, number of error ingress codeword */
-+ uint32_t ifTxNoIdleCodewords; /*!< output, number of egress user codeword */
-+ uint32_t ifTxIdleCodewords; /*!< output, number of egress idle codeword */
-+} PTM_CW_IF_ENTRY_T;
-+
-+/*!
-+ \typedef PTM_FRAME_MIB_T
-+ \brief Wrapping of structure "ptm_frame_mib_t".
-+ */
-+/*!
-+ \struct ptm_frame_mib_t
-+ \brief Structure used for packet level MIB counters.
-+ */
-+typedef struct ptm_frame_mib_t {
-+ uint32_t RxCorrect; /*!< output, number of ingress packet */
-+ uint32_t TC_CrcError; /*!< output, number of egress packet with CRC error */
-+ uint32_t RxDropped; /*!< output, number of dropped ingress packet */
-+ uint32_t TxSend; /*!< output, number of egress packet */
-+} PTM_FRAME_MIB_T;
-+
-+/*!
-+ \typedef IFX_PTM_CFG_T
-+ \brief Wrapping of structure "ptm_cfg_t".
-+ */
-+/*!
-+ \struct ptm_cfg_t
-+ \brief Structure used for ETH/TC CRC configuration.
-+ */
-+typedef struct ptm_cfg_t {
-+ uint32_t RxEthCrcPresent; /*!< input/output, ingress packet has ETH CRC */
-+ uint32_t RxEthCrcCheck; /*!< input/output, check ETH CRC of ingress packet */
-+ uint32_t RxTcCrcCheck; /*!< input/output, check TC CRC of ingress codeword */
-+ uint32_t RxTcCrcLen; /*!< input/output, length of TC CRC of ingress codeword */
-+ uint32_t TxEthCrcGen; /*!< input/output, generate ETH CRC for egress packet */
-+ uint32_t TxTcCrcGen; /*!< input/output, generate TC CRC for egress codeword */
-+ uint32_t TxTcCrcLen; /*!< input/output, length of TC CRC of egress codeword */
-+} IFX_PTM_CFG_T;
-+
-+/*!
-+ \typedef IFX_PTM_PRIO_Q_MAP_T
-+ \brief Wrapping of structure "ppe_prio_q_map".
-+ */
-+/*!
-+ \struct ppe_prio_q_map
-+ \brief Structure used for Priority Value to TX Queue mapping.
-+ */
-+typedef struct ppe_prio_q_map {
-+ int pkt_prio;
-+ int qid;
-+ int vpi; // ignored in eth interface
-+ int vci; // ignored in eth interface
-+} IFX_PTM_PRIO_Q_MAP_T;
-+
-+/*@}*/
-+
-+
-+
-+/*
-+ * ####################################
-+ * API
-+ * ####################################
-+ */
-+
-+#ifdef __KERNEL__
-+struct port_cell_info {
-+ unsigned int port_num;
-+ unsigned int tx_link_rate[2];
-+};
-+#endif
-+
-+
-+
-+#endif // IFX_PTM_H
-+
---- a/arch/mips/lantiq/irq.c
-+++ b/arch/mips/lantiq/irq.c
-@@ -13,6 +13,7 @@
- #include <linux/of_platform.h>
- #include <linux/of_address.h>
- #include <linux/of_irq.h>
-+#include <linux/module.h>
-
- #include <asm/bootinfo.h>
- #include <asm/irq_cpu.h>
-@@ -92,6 +93,7 @@ void ltq_disable_irq(struct irq_data *d)
- }
- raw_spin_unlock_irqrestore(<q_icu_lock, flags);
- }
-+EXPORT_SYMBOL(ltq_mask_and_ack_irq);
-
- void ltq_mask_and_ack_irq(struct irq_data *d)
- {
---- a/arch/mips/mm/cache.c
-+++ b/arch/mips/mm/cache.c
-@@ -63,6 +63,10 @@ void (*_dma_cache_wback_inv)(unsigned lo
- void (*_dma_cache_wback)(unsigned long start, unsigned long size);
- void (*_dma_cache_inv)(unsigned long start, unsigned long size);
-
-+EXPORT_SYMBOL(_dma_cache_wback_inv);
-+EXPORT_SYMBOL(_dma_cache_wback);
-+EXPORT_SYMBOL(_dma_cache_inv);
-+
- #endif /* CONFIG_DMA_NONCOHERENT */
-
- /*
---- a/include/uapi/linux/atm.h
-+++ b/include/uapi/linux/atm.h
-@@ -131,8 +131,14 @@
- #define ATM_ABR 4
- #define ATM_ANYCLASS 5 /* compatible with everything */
-
-+#define ATM_VBR_NRT ATM_VBR
-+#define ATM_VBR_RT 6
-+#define ATM_UBR_PLUS 7
-+#define ATM_GFR 8
-+
- #define ATM_MAX_PCR -1 /* maximum available PCR */
-
-+
- struct atm_trafprm {
- unsigned char traffic_class; /* traffic class (ATM_UBR, ...) */
- int max_pcr; /* maximum PCR in cells per second */
---- a/net/atm/proc.c
-+++ b/net/atm/proc.c
-@@ -141,7 +141,7 @@ static void *vcc_seq_next(struct seq_fil
- static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc)
- {
- static const char *const class_name[] = {
-- "off", "UBR", "CBR", "VBR", "ABR"};
-+ "off","UBR","CBR","NTR-VBR","ABR","ANY","RT-VBR","UBR+","GFR"};
- static const char *const aal_name[] = {
- "---", "1", "2", "3/4", /* 0- 3 */
- "???", "5", "???", "???", /* 4- 7 */
+++ /dev/null
-From 94800350cb8d2f29dda2206b5e9a3772024ee168 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:30:56 +0200
-Subject: [PATCH 08/36] MIPS: lantiq: backport old timer code
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- arch/mips/include/asm/mach-lantiq/lantiq_timer.h | 155 ++++
- arch/mips/lantiq/xway/Makefile | 2 +-
- arch/mips/lantiq/xway/timer.c | 845 ++++++++++++++++++++++
- 3 files changed, 1001 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/include/asm/mach-lantiq/lantiq_timer.h
- create mode 100644 arch/mips/lantiq/xway/timer.c
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/lantiq_timer.h
-@@ -0,0 +1,155 @@
-+#ifndef __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
-+#define __DANUBE_GPTU_DEV_H__2005_07_26__10_19__
-+
-+
-+/******************************************************************************
-+ Copyright (c) 2002, Infineon Technologies. All rights reserved.
-+
-+ No Warranty
-+ Because the program is licensed free of charge, there is no warranty for
-+ the program, to the extent permitted by applicable law. Except when
-+ otherwise stated in writing the copyright holders and/or other parties
-+ provide the program "as is" without warranty of any kind, either
-+ expressed or implied, including, but not limited to, the implied
-+ warranties of merchantability and fitness for a particular purpose. The
-+ entire risk as to the quality and performance of the program is with
-+ you. should the program prove defective, you assume the cost of all
-+ necessary servicing, repair or correction.
-+
-+ In no event unless required by applicable law or agreed to in writing
-+ will any copyright holder, or any other party who may modify and/or
-+ redistribute the program as permitted above, be liable to you for
-+ damages, including any general, special, incidental or consequential
-+ damages arising out of the use or inability to use the program
-+ (including but not limited to loss of data or data being rendered
-+ inaccurate or losses sustained by you or third parties or a failure of
-+ the program to operate with any other programs), even if such holder or
-+ other party has been advised of the possibility of such damages.
-+******************************************************************************/
-+
-+
-+/*
-+ * ####################################
-+ * Definition
-+ * ####################################
-+ */
-+
-+/*
-+ * Available Timer/Counter Index
-+ */
-+#define TIMER(n, X) (n * 2 + (X ? 1 : 0))
-+#define TIMER_ANY 0x00
-+#define TIMER1A TIMER(1, 0)
-+#define TIMER1B TIMER(1, 1)
-+#define TIMER2A TIMER(2, 0)
-+#define TIMER2B TIMER(2, 1)
-+#define TIMER3A TIMER(3, 0)
-+#define TIMER3B TIMER(3, 1)
-+
-+/*
-+ * Flag of Timer/Counter
-+ * These flags specify the way in which timer is configured.
-+ */
-+/* Bit size of timer/counter. */
-+#define TIMER_FLAG_16BIT 0x0000
-+#define TIMER_FLAG_32BIT 0x0001
-+/* Switch between timer and counter. */
-+#define TIMER_FLAG_TIMER 0x0000
-+#define TIMER_FLAG_COUNTER 0x0002
-+/* Stop or continue when overflowing/underflowing. */
-+#define TIMER_FLAG_ONCE 0x0000
-+#define TIMER_FLAG_CYCLIC 0x0004
-+/* Count up or counter down. */
-+#define TIMER_FLAG_UP 0x0000
-+#define TIMER_FLAG_DOWN 0x0008
-+/* Count on specific level or edge. */
-+#define TIMER_FLAG_HIGH_LEVEL_SENSITIVE 0x0000
-+#define TIMER_FLAG_LOW_LEVEL_SENSITIVE 0x0040
-+#define TIMER_FLAG_RISE_EDGE 0x0010
-+#define TIMER_FLAG_FALL_EDGE 0x0020
-+#define TIMER_FLAG_ANY_EDGE 0x0030
-+/* Signal is syncronous to module clock or not. */
-+#define TIMER_FLAG_UNSYNC 0x0000
-+#define TIMER_FLAG_SYNC 0x0080
-+/* Different interrupt handle type. */
-+#define TIMER_FLAG_NO_HANDLE 0x0000
-+#if defined(__KERNEL__)
-+ #define TIMER_FLAG_CALLBACK_IN_IRQ 0x0100
-+#endif // defined(__KERNEL__)
-+#define TIMER_FLAG_SIGNAL 0x0300
-+/* Internal clock source or external clock source */
-+#define TIMER_FLAG_INT_SRC 0x0000
-+#define TIMER_FLAG_EXT_SRC 0x1000
-+
-+
-+/*
-+ * ioctl Command
-+ */
-+#define GPTU_REQUEST_TIMER 0x01 /* General method to setup timer/counter. */
-+#define GPTU_FREE_TIMER 0x02 /* Free timer/counter. */
-+#define GPTU_START_TIMER 0x03 /* Start or resume timer/counter. */
-+#define GPTU_STOP_TIMER 0x04 /* Suspend timer/counter. */
-+#define GPTU_GET_COUNT_VALUE 0x05 /* Get current count value. */
-+#define GPTU_CALCULATE_DIVIDER 0x06 /* Calculate timer divider from given freq.*/
-+#define GPTU_SET_TIMER 0x07 /* Simplified method to setup timer. */
-+#define GPTU_SET_COUNTER 0x08 /* Simplified method to setup counter. */
-+
-+/*
-+ * Data Type Used to Call ioctl
-+ */
-+struct gptu_ioctl_param {
-+ unsigned int timer; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
-+ * GPTU_SET_COUNTER, this field is ID of expected *
-+ * timer/counter. If it's zero, a timer/counter would *
-+ * be dynamically allocated and ID would be stored in *
-+ * this field. *
-+ * In command GPTU_GET_COUNT_VALUE, this field is *
-+ * ignored. *
-+ * In other command, this field is ID of timer/counter *
-+ * allocated. */
-+ unsigned int flag; /* In command GPTU_REQUEST_TIMER, GPTU_SET_TIMER, and *
-+ * GPTU_SET_COUNTER, this field contains flags to *
-+ * specify how to configure timer/counter. *
-+ * In command GPTU_START_TIMER, zero indicate start *
-+ * and non-zero indicate resume timer/counter. *
-+ * In other command, this field is ignored. */
-+ unsigned long value; /* In command GPTU_REQUEST_TIMER, this field contains *
-+ * init/reload value. *
-+ * In command GPTU_SET_TIMER, this field contains *
-+ * frequency (0.001Hz) of timer. *
-+ * In command GPTU_GET_COUNT_VALUE, current count *
-+ * value would be stored in this field. *
-+ * In command GPTU_CALCULATE_DIVIDER, this field *
-+ * contains frequency wanted, and after calculation, *
-+ * divider would be stored in this field to overwrite *
-+ * the frequency. *
-+ * In other command, this field is ignored. */
-+ int pid; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
-+ * if signal is required, this field contains process *
-+ * ID to which signal would be sent. *
-+ * In other command, this field is ignored. */
-+ int sig; /* In command GPTU_REQUEST_TIMER and GPTU_SET_TIMER, *
-+ * if signal is required, this field contains signal *
-+ * number which would be sent. *
-+ * In other command, this field is ignored. */
-+};
-+
-+/*
-+ * ####################################
-+ * Data Type
-+ * ####################################
-+ */
-+typedef void (*timer_callback)(unsigned long arg);
-+
-+extern int lq_request_timer(unsigned int, unsigned int, unsigned long, unsigned long, unsigned long);
-+extern int lq_free_timer(unsigned int);
-+extern int lq_start_timer(unsigned int, int);
-+extern int lq_stop_timer(unsigned int);
-+extern int lq_reset_counter_flags(u32 timer, u32 flags);
-+extern int lq_get_count_value(unsigned int, unsigned long *);
-+extern u32 lq_cal_divider(unsigned long);
-+extern int lq_set_timer(unsigned int, unsigned int, int, int, unsigned int, unsigned long, unsigned long);
-+extern int lq_set_counter(unsigned int timer, unsigned int flag,
-+ u32 reload, unsigned long arg1, unsigned long arg2);
-+
-+#endif /* __DANUBE_GPTU_DEV_H__2005_07_26__10_19__ */
---- a/arch/mips/lantiq/xway/Makefile
-+++ b/arch/mips/lantiq/xway/Makefile
-@@ -1,4 +1,10 @@
- # SPDX-License-Identifier: GPL-2.0-only
--obj-y := prom.o sysctrl.o clk.o dma.o gptu.o dcdc.o
-+obj-y := prom.o sysctrl.o clk.o dma.o dcdc.o
-+
-+ifdef CONFIG_SOC_AMAZON_SE
-+obj-y += gptu.o
-+else
-+obj-y += timer.o
-+endif
-
- obj-y += vmmc.o
---- /dev/null
-+++ b/arch/mips/lantiq/xway/timer.c
-@@ -0,0 +1,887 @@
-+#ifndef CONFIG_SOC_AMAZON_SE
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/version.h>
-+#include <linux/types.h>
-+#include <linux/fs.h>
-+#include <linux/miscdevice.h>
-+#include <linux/init.h>
-+#include <linux/uaccess.h>
-+#include <linux/unistd.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/sched.h>
-+#include <linux/sched/signal.h>
-+
-+#include <linux/of_platform.h>
-+
-+#include <asm/irq.h>
-+#include <asm/div64.h>
-+#include "../clk.h"
-+
-+#include <lantiq_soc.h>
-+#include <lantiq_irq.h>
-+#include <lantiq_timer.h>
-+
-+#define MAX_NUM_OF_32BIT_TIMER_BLOCKS 6
-+
-+#ifdef TIMER1A
-+#define FIRST_TIMER TIMER1A
-+#else
-+#define FIRST_TIMER 2
-+#endif
-+
-+/*
-+ * GPTC divider is set or not.
-+ */
-+#define GPTU_CLC_RMC_IS_SET 0
-+
-+/*
-+ * Timer Interrupt (IRQ)
-+ */
-+/* Must be adjusted when ICU driver is available */
-+#define TIMER_INTERRUPT (INT_NUM_IM3_IRL0 + 22)
-+
-+/*
-+ * Bits Operation
-+ */
-+#define GET_BITS(x, msb, lsb) \
-+ (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb))
-+#define SET_BITS(x, msb, lsb, value) \
-+ (((x) & ~(((1 << ((msb) + 1)) - 1) ^ ((1 << (lsb)) - 1))) | \
-+ (((value) & ((1 << (1 + (msb) - (lsb))) - 1)) << (lsb)))
-+
-+/*
-+ * GPTU Register Mapping
-+ */
-+#define LQ_GPTU (KSEG1 + 0x1E100A00)
-+#define LQ_GPTU_CLC ((volatile u32 *)(LQ_GPTU + 0x0000))
-+#define LQ_GPTU_ID ((volatile u32 *)(LQ_GPTU + 0x0008))
-+#define LQ_GPTU_CON(n, X) ((volatile u32 *)(LQ_GPTU + 0x0010 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_RUN(n, X) ((volatile u32 *)(LQ_GPTU + 0x0018 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_RELOAD(n, X) ((volatile u32 *)(LQ_GPTU + 0x0020 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_COUNT(n, X) ((volatile u32 *)(LQ_GPTU + 0x0028 + ((X) * 4) + ((n) - 1) * 0x0020)) /* X must be either A or B */
-+#define LQ_GPTU_IRNEN ((volatile u32 *)(LQ_GPTU + 0x00F4))
-+#define LQ_GPTU_IRNICR ((volatile u32 *)(LQ_GPTU + 0x00F8))
-+#define LQ_GPTU_IRNCR ((volatile u32 *)(LQ_GPTU + 0x00FC))
-+
-+/*
-+ * Clock Control Register
-+ */
-+#define GPTU_CLC_SMC GET_BITS(*LQ_GPTU_CLC, 23, 16)
-+#define GPTU_CLC_RMC GET_BITS(*LQ_GPTU_CLC, 15, 8)
-+#define GPTU_CLC_FSOE (*LQ_GPTU_CLC & (1 << 5))
-+#define GPTU_CLC_EDIS (*LQ_GPTU_CLC & (1 << 3))
-+#define GPTU_CLC_SPEN (*LQ_GPTU_CLC & (1 << 2))
-+#define GPTU_CLC_DISS (*LQ_GPTU_CLC & (1 << 1))
-+#define GPTU_CLC_DISR (*LQ_GPTU_CLC & (1 << 0))
-+
-+#define GPTU_CLC_SMC_SET(value) SET_BITS(0, 23, 16, (value))
-+#define GPTU_CLC_RMC_SET(value) SET_BITS(0, 15, 8, (value))
-+#define GPTU_CLC_FSOE_SET(value) ((value) ? (1 << 5) : 0)
-+#define GPTU_CLC_SBWE_SET(value) ((value) ? (1 << 4) : 0)
-+#define GPTU_CLC_EDIS_SET(value) ((value) ? (1 << 3) : 0)
-+#define GPTU_CLC_SPEN_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_CLC_DISR_SET(value) ((value) ? (1 << 0) : 0)
-+
-+/*
-+ * ID Register
-+ */
-+#define GPTU_ID_ID GET_BITS(*LQ_GPTU_ID, 15, 8)
-+#define GPTU_ID_CFG GET_BITS(*LQ_GPTU_ID, 7, 5)
-+#define GPTU_ID_REV GET_BITS(*LQ_GPTU_ID, 4, 0)
-+
-+/*
-+ * Control Register of Timer/Counter nX
-+ * n is the index of block (1 based index)
-+ * X is either A or B
-+ */
-+#define GPTU_CON_SRC_EG(n, X) (*LQ_GPTU_CON(n, X) & (1 << 10))
-+#define GPTU_CON_SRC_EXT(n, X) (*LQ_GPTU_CON(n, X) & (1 << 9))
-+#define GPTU_CON_SYNC(n, X) (*LQ_GPTU_CON(n, X) & (1 << 8))
-+#define GPTU_CON_EDGE(n, X) GET_BITS(*LQ_GPTU_CON(n, X), 7, 6)
-+#define GPTU_CON_INV(n, X) (*LQ_GPTU_CON(n, X) & (1 << 5))
-+#define GPTU_CON_EXT(n, X) (*LQ_GPTU_CON(n, A) & (1 << 4)) /* Timer/Counter B does not have this bit */
-+#define GPTU_CON_STP(n, X) (*LQ_GPTU_CON(n, X) & (1 << 3))
-+#define GPTU_CON_CNT(n, X) (*LQ_GPTU_CON(n, X) & (1 << 2))
-+#define GPTU_CON_DIR(n, X) (*LQ_GPTU_CON(n, X) & (1 << 1))
-+#define GPTU_CON_EN(n, X) (*LQ_GPTU_CON(n, X) & (1 << 0))
-+
-+#define GPTU_CON_SRC_EG_SET(value) ((value) ? 0 : (1 << 10))
-+#define GPTU_CON_SRC_EXT_SET(value) ((value) ? (1 << 9) : 0)
-+#define GPTU_CON_SYNC_SET(value) ((value) ? (1 << 8) : 0)
-+#define GPTU_CON_EDGE_SET(value) SET_BITS(0, 7, 6, (value))
-+#define GPTU_CON_INV_SET(value) ((value) ? (1 << 5) : 0)
-+#define GPTU_CON_EXT_SET(value) ((value) ? (1 << 4) : 0)
-+#define GPTU_CON_STP_SET(value) ((value) ? (1 << 3) : 0)
-+#define GPTU_CON_CNT_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_CON_DIR_SET(value) ((value) ? (1 << 1) : 0)
-+
-+#define GPTU_RUN_RL_SET(value) ((value) ? (1 << 2) : 0)
-+#define GPTU_RUN_CEN_SET(value) ((value) ? (1 << 1) : 0)
-+#define GPTU_RUN_SEN_SET(value) ((value) ? (1 << 0) : 0)
-+
-+#define GPTU_IRNEN_TC_SET(n, X, value) ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
-+#define GPTU_IRNCR_TC_SET(n, X, value) ((value) ? (1 << (((n) - 1) * 2 + (X))) : 0)
-+
-+#define TIMER_FLAG_MASK_SIZE(x) (x & 0x0001)
-+#define TIMER_FLAG_MASK_TYPE(x) (x & 0x0002)
-+#define TIMER_FLAG_MASK_STOP(x) (x & 0x0004)
-+#define TIMER_FLAG_MASK_DIR(x) (x & 0x0008)
-+#define TIMER_FLAG_NONE_EDGE 0x0000
-+#define TIMER_FLAG_MASK_EDGE(x) (x & 0x0030)
-+#define TIMER_FLAG_REAL 0x0000
-+#define TIMER_FLAG_INVERT 0x0040
-+#define TIMER_FLAG_MASK_INVERT(x) (x & 0x0040)
-+#define TIMER_FLAG_MASK_TRIGGER(x) (x & 0x0070)
-+#define TIMER_FLAG_MASK_SYNC(x) (x & 0x0080)
-+#define TIMER_FLAG_CALLBACK_IN_HB 0x0200
-+#define TIMER_FLAG_MASK_HANDLE(x) (x & 0x0300)
-+#define TIMER_FLAG_MASK_SRC(x) (x & 0x1000)
-+
-+struct timer_dev_timer {
-+ unsigned int f_irq_on;
-+ unsigned int irq;
-+ unsigned int flag;
-+ unsigned long arg1;
-+ unsigned long arg2;
-+};
-+
-+struct timer_dev {
-+ struct mutex gptu_mutex;
-+ unsigned int number_of_timers;
-+ unsigned int occupation;
-+ unsigned int f_gptu_on;
-+ struct timer_dev_timer timer[MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2];
-+};
-+
-+
-+unsigned int ltq_get_fpi_bus_clock(int fpi) {
-+ struct clk *clk = clk_get_fpi();
-+ return clk_get_rate(clk);
-+}
-+
-+
-+static long gptu_ioctl(struct file *, unsigned int, unsigned long);
-+static int gptu_open(struct inode *, struct file *);
-+static int gptu_release(struct inode *, struct file *);
-+
-+static struct file_operations gptu_fops = {
-+ .owner = THIS_MODULE,
-+ .unlocked_ioctl = gptu_ioctl,
-+ .open = gptu_open,
-+ .release = gptu_release
-+};
-+
-+static struct miscdevice gptu_miscdev = {
-+ .minor = MISC_DYNAMIC_MINOR,
-+ .name = "gptu",
-+ .fops = &gptu_fops,
-+};
-+
-+static struct timer_dev timer_dev;
-+
-+static irqreturn_t timer_irq_handler(int irq, void *p)
-+{
-+ unsigned int timer;
-+ unsigned int flag;
-+ struct timer_dev_timer *dev_timer = (struct timer_dev_timer *)p;
-+
-+ timer = irq - TIMER_INTERRUPT;
-+ if (timer < timer_dev.number_of_timers
-+ && dev_timer == &timer_dev.timer[timer]) {
-+ /* Clear interrupt. */
-+ ltq_w32(1 << timer, LQ_GPTU_IRNCR);
-+
-+ /* Call user hanler or signal. */
-+ flag = dev_timer->flag;
-+ if (!(timer & 0x01)
-+ || TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT) {
-+ /* 16-bit timer or timer A of 32-bit timer */
-+ switch (TIMER_FLAG_MASK_HANDLE(flag)) {
-+ case TIMER_FLAG_CALLBACK_IN_IRQ:
-+ case TIMER_FLAG_CALLBACK_IN_HB:
-+ if (dev_timer->arg1)
-+ (*(timer_callback)dev_timer->arg1)(dev_timer->arg2);
-+ break;
-+ case TIMER_FLAG_SIGNAL:
-+ send_sig((int)dev_timer->arg2, (struct task_struct *)dev_timer->arg1, 0);
-+ break;
-+ }
-+ }
-+ }
-+ return IRQ_HANDLED;
-+}
-+
-+static inline void lq_enable_gptu(void)
-+{
-+ struct clk *clk = clk_get_sys("1e100a00.gptu", NULL);
-+ clk_enable(clk);
-+
-+ //ltq_pmu_enable(PMU_GPT);
-+
-+ /* Set divider as 1, disable write protection for SPEN, enable module. */
-+ *LQ_GPTU_CLC =
-+ GPTU_CLC_SMC_SET(0x00) |
-+ GPTU_CLC_RMC_SET(0x01) |
-+ GPTU_CLC_FSOE_SET(0) |
-+ GPTU_CLC_SBWE_SET(1) |
-+ GPTU_CLC_EDIS_SET(0) |
-+ GPTU_CLC_SPEN_SET(0) |
-+ GPTU_CLC_DISR_SET(0);
-+}
-+
-+static inline void lq_disable_gptu(void)
-+{
-+ struct clk *clk = clk_get_sys("1e100a00.gptu", NULL);
-+ ltq_w32(0x00, LQ_GPTU_IRNEN);
-+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
-+
-+ /* Set divider as 0, enable write protection for SPEN, disable module. */
-+ *LQ_GPTU_CLC =
-+ GPTU_CLC_SMC_SET(0x00) |
-+ GPTU_CLC_RMC_SET(0x00) |
-+ GPTU_CLC_FSOE_SET(0) |
-+ GPTU_CLC_SBWE_SET(0) |
-+ GPTU_CLC_EDIS_SET(0) |
-+ GPTU_CLC_SPEN_SET(0) |
-+ GPTU_CLC_DISR_SET(1);
-+
-+ clk_enable(clk);
-+}
-+
-+int lq_request_timer(unsigned int timer, unsigned int flag,
-+ unsigned long value, unsigned long arg1, unsigned long arg2)
-+{
-+ int ret = 0;
-+ unsigned int con_reg, irnen_reg;
-+ int n, X;
-+
-+ if (timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ printk(KERN_INFO "request_timer(%d, 0x%08X, %lu)...",
-+ timer, flag, value);
-+
-+ if (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT)
-+ value &= 0xFFFF;
-+ else
-+ timer &= ~0x01;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ /*
-+ * Allocate timer.
-+ */
-+ if (timer < FIRST_TIMER) {
-+ unsigned int mask;
-+ unsigned int shift;
-+ /* This takes care of TIMER1B which is the only choice for Voice TAPI system */
-+ unsigned int offset = TIMER2A;
-+
-+ /*
-+ * Pick up a free timer.
-+ */
-+ if (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT) {
-+ mask = 1 << offset;
-+ shift = 1;
-+ } else {
-+ mask = 3 << offset;
-+ shift = 2;
-+ }
-+ for (timer = offset;
-+ timer < offset + timer_dev.number_of_timers;
-+ timer += shift, mask <<= shift)
-+ if (!(timer_dev.occupation & mask)) {
-+ timer_dev.occupation |= mask;
-+ break;
-+ }
-+ if (timer >= offset + timer_dev.number_of_timers) {
-+ printk("failed![%d]\n", __LINE__);
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ } else
-+ ret = timer;
-+ } else {
-+ register unsigned int mask;
-+
-+ /*
-+ * Check if the requested timer is free.
-+ */
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if ((timer_dev.occupation & mask)) {
-+ printk("failed![%d] mask %#x, timer_dev.occupation %#x\n",
-+ __LINE__, mask, timer_dev.occupation);
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EBUSY;
-+ } else {
-+ timer_dev.occupation |= mask;
-+ ret = 0;
-+ }
-+ }
-+
-+ /*
-+ * Prepare control register value.
-+ */
-+ switch (TIMER_FLAG_MASK_EDGE(flag)) {
-+ default:
-+ case TIMER_FLAG_NONE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x00);
-+ break;
-+ case TIMER_FLAG_RISE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x01);
-+ break;
-+ case TIMER_FLAG_FALL_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x02);
-+ break;
-+ case TIMER_FLAG_ANY_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x03);
-+ break;
-+ }
-+ if (TIMER_FLAG_MASK_TYPE(flag) == TIMER_FLAG_TIMER)
-+ con_reg |=
-+ TIMER_FLAG_MASK_SRC(flag) ==
-+ TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET(1) :
-+ GPTU_CON_SRC_EXT_SET(0);
-+ else
-+ con_reg |=
-+ TIMER_FLAG_MASK_SRC(flag) ==
-+ TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET(1) :
-+ GPTU_CON_SRC_EG_SET(0);
-+ con_reg |=
-+ TIMER_FLAG_MASK_SYNC(flag) ==
-+ TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET(0) :
-+ GPTU_CON_SYNC_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_INVERT(flag) ==
-+ TIMER_FLAG_REAL ? GPTU_CON_INV_SET(0) : GPTU_CON_INV_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_SIZE(flag) ==
-+ TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET(0) :
-+ GPTU_CON_EXT_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_STOP(flag) ==
-+ TIMER_FLAG_ONCE ? GPTU_CON_STP_SET(1) : GPTU_CON_STP_SET(0);
-+ con_reg |=
-+ TIMER_FLAG_MASK_TYPE(flag) ==
-+ TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET(0) :
-+ GPTU_CON_CNT_SET(1);
-+ con_reg |=
-+ TIMER_FLAG_MASK_DIR(flag) ==
-+ TIMER_FLAG_UP ? GPTU_CON_DIR_SET(1) : GPTU_CON_DIR_SET(0);
-+
-+ /*
-+ * Fill up running data.
-+ */
-+ timer_dev.timer[timer - FIRST_TIMER].flag = flag;
-+ timer_dev.timer[timer - FIRST_TIMER].arg1 = arg1;
-+ timer_dev.timer[timer - FIRST_TIMER].arg2 = arg2;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer_dev.timer[timer - FIRST_TIMER + 1].flag = flag;
-+
-+ /*
-+ * Enable GPTU module.
-+ */
-+ if (!timer_dev.f_gptu_on) {
-+ lq_enable_gptu();
-+ timer_dev.f_gptu_on = 1;
-+ }
-+
-+ /*
-+ * Enable IRQ.
-+ */
-+ if (TIMER_FLAG_MASK_HANDLE(flag) != TIMER_FLAG_NO_HANDLE) {
-+ if (TIMER_FLAG_MASK_HANDLE(flag) == TIMER_FLAG_SIGNAL)
-+ timer_dev.timer[timer - FIRST_TIMER].arg1 =
-+ (unsigned long) find_task_by_vpid((int) arg1);
-+
-+ irnen_reg = 1 << (timer - FIRST_TIMER);
-+
-+ if (TIMER_FLAG_MASK_HANDLE(flag) == TIMER_FLAG_SIGNAL
-+ || (TIMER_FLAG_MASK_HANDLE(flag) ==
-+ TIMER_FLAG_CALLBACK_IN_IRQ
-+ && timer_dev.timer[timer - FIRST_TIMER].arg1)) {
-+ enable_irq(timer_dev.timer[timer - FIRST_TIMER].irq);
-+ timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 1;
-+ }
-+ } else
-+ irnen_reg = 0;
-+
-+ /*
-+ * Write config register, reload value and enable interrupt.
-+ */
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+ *LQ_GPTU_CON(n, X) = con_reg;
-+ *LQ_GPTU_RELOAD(n, X) = value;
-+ /* printk("reload value = %d\n", (u32)value); */
-+ *LQ_GPTU_IRNEN |= irnen_reg;
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ printk("successful!\n");
-+ return ret;
-+}
-+EXPORT_SYMBOL(lq_request_timer);
-+
-+int lq_free_timer(unsigned int timer)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ if (GPTU_CON_EN(n, X))
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_CEN_SET(1);
-+
-+ *LQ_GPTU_IRNEN &= ~GPTU_IRNEN_TC_SET(n, X, 1);
-+ *LQ_GPTU_IRNCR |= GPTU_IRNCR_TC_SET(n, X, 1);
-+
-+ if (timer_dev.timer[timer - FIRST_TIMER].f_irq_on) {
-+ disable_irq(timer_dev.timer[timer - FIRST_TIMER].irq);
-+ timer_dev.timer[timer - FIRST_TIMER].f_irq_on = 0;
-+ }
-+
-+ timer_dev.occupation &= ~mask;
-+ if (!timer_dev.occupation && timer_dev.f_gptu_on) {
-+ lq_disable_gptu();
-+ timer_dev.f_gptu_on = 0;
-+ }
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_free_timer);
-+
-+int lq_start_timer(unsigned int timer, int is_resume)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) ==
-+ TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_RL_SET(!is_resume) | GPTU_RUN_SEN_SET(1);
-+
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_start_timer);
-+
-+int lq_stop_timer(unsigned int timer)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER
-+ || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_RUN(n, X) = GPTU_RUN_CEN_SET(1);
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_stop_timer);
-+
-+int lq_reset_counter_flags(u32 timer, u32 flags)
-+{
-+ unsigned int oflag;
-+ unsigned int mask, con_reg;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ oflag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(oflag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(oflag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ switch (TIMER_FLAG_MASK_EDGE(flags)) {
-+ default:
-+ case TIMER_FLAG_NONE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x00);
-+ break;
-+ case TIMER_FLAG_RISE_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x01);
-+ break;
-+ case TIMER_FLAG_FALL_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x02);
-+ break;
-+ case TIMER_FLAG_ANY_EDGE:
-+ con_reg = GPTU_CON_EDGE_SET(0x03);
-+ break;
-+ }
-+ if (TIMER_FLAG_MASK_TYPE(flags) == TIMER_FLAG_TIMER)
-+ con_reg |= TIMER_FLAG_MASK_SRC(flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EXT_SET(1) : GPTU_CON_SRC_EXT_SET(0);
-+ else
-+ con_reg |= TIMER_FLAG_MASK_SRC(flags) == TIMER_FLAG_EXT_SRC ? GPTU_CON_SRC_EG_SET(1) : GPTU_CON_SRC_EG_SET(0);
-+ con_reg |= TIMER_FLAG_MASK_SYNC(flags) == TIMER_FLAG_UNSYNC ? GPTU_CON_SYNC_SET(0) : GPTU_CON_SYNC_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_INVERT(flags) == TIMER_FLAG_REAL ? GPTU_CON_INV_SET(0) : GPTU_CON_INV_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_SIZE(flags) == TIMER_FLAG_16BIT ? GPTU_CON_EXT_SET(0) : GPTU_CON_EXT_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_STOP(flags) == TIMER_FLAG_ONCE ? GPTU_CON_STP_SET(1) : GPTU_CON_STP_SET(0);
-+ con_reg |= TIMER_FLAG_MASK_TYPE(flags) == TIMER_FLAG_TIMER ? GPTU_CON_CNT_SET(0) : GPTU_CON_CNT_SET(1);
-+ con_reg |= TIMER_FLAG_MASK_DIR(flags) == TIMER_FLAG_UP ? GPTU_CON_DIR_SET(1) : GPTU_CON_DIR_SET(0);
-+
-+ timer_dev.timer[timer - FIRST_TIMER].flag = flags;
-+ if (TIMER_FLAG_MASK_SIZE(flags) != TIMER_FLAG_16BIT)
-+ timer_dev.timer[timer - FIRST_TIMER + 1].flag = flags;
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *LQ_GPTU_CON(n, X) = con_reg;
-+ smp_wmb();
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_reset_counter_flags);
-+
-+int lq_get_count_value(unsigned int timer, unsigned long *value)
-+{
-+ unsigned int flag;
-+ unsigned int mask;
-+ int n, X;
-+
-+ if (!timer_dev.f_gptu_on)
-+ return -EINVAL;
-+
-+ if (timer < FIRST_TIMER
-+ || timer >= FIRST_TIMER + timer_dev.number_of_timers)
-+ return -EINVAL;
-+
-+ mutex_lock(&timer_dev.gptu_mutex);
-+
-+ flag = timer_dev.timer[timer - FIRST_TIMER].flag;
-+ if (TIMER_FLAG_MASK_SIZE(flag) != TIMER_FLAG_16BIT)
-+ timer &= ~0x01;
-+
-+ mask = (TIMER_FLAG_MASK_SIZE(flag) == TIMER_FLAG_16BIT ? 1 : 3) << timer;
-+ if (((timer_dev.occupation & mask) ^ mask)) {
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+ return -EINVAL;
-+ }
-+
-+ n = timer >> 1;
-+ X = timer & 0x01;
-+
-+ *value = *LQ_GPTU_COUNT(n, X);
-+
-+
-+ mutex_unlock(&timer_dev.gptu_mutex);
-+
-+ return 0;
-+}
-+EXPORT_SYMBOL(lq_get_count_value);
-+
-+u32 lq_cal_divider(unsigned long freq)
-+{
-+ u64 module_freq, fpi = ltq_get_fpi_bus_clock(2);
-+ u32 clock_divider = 1;
-+ module_freq = fpi * 1000;
-+ do_div(module_freq, clock_divider * freq);
-+ return module_freq;
-+}
-+EXPORT_SYMBOL(lq_cal_divider);
-+
-+int lq_set_timer(unsigned int timer, unsigned int freq, int is_cyclic,
-+ int is_ext_src, unsigned int handle_flag, unsigned long arg1,
-+ unsigned long arg2)
-+{
-+ unsigned long divider;
-+ unsigned int flag;
-+
-+ divider = lq_cal_divider(freq);
-+ if (divider == 0)
-+ return -EINVAL;
-+ flag = ((divider & ~0xFFFF) ? TIMER_FLAG_32BIT : TIMER_FLAG_16BIT)
-+ | (is_cyclic ? TIMER_FLAG_CYCLIC : TIMER_FLAG_ONCE)
-+ | (is_ext_src ? TIMER_FLAG_EXT_SRC : TIMER_FLAG_INT_SRC)
-+ | TIMER_FLAG_TIMER | TIMER_FLAG_DOWN
-+ | TIMER_FLAG_MASK_HANDLE(handle_flag);
-+
-+ printk(KERN_INFO "lq_set_timer(%d, %d), divider = %lu\n",
-+ timer, freq, divider);
-+ return lq_request_timer(timer, flag, divider, arg1, arg2);
-+}
-+EXPORT_SYMBOL(lq_set_timer);
-+
-+int lq_set_counter(unsigned int timer, unsigned int flag, u32 reload,
-+ unsigned long arg1, unsigned long arg2)
-+{
-+ printk(KERN_INFO "lq_set_counter(%d, %#x, %d)\n", timer, flag, reload);
-+ return lq_request_timer(timer, flag, reload, arg1, arg2);
-+}
-+EXPORT_SYMBOL(lq_set_counter);
-+
-+static long gptu_ioctl(struct file *file, unsigned int cmd,
-+ unsigned long arg)
-+{
-+ int ret;
-+ struct gptu_ioctl_param param;
-+
-+ if (!access_ok((void __user *)arg, sizeof(struct gptu_ioctl_param)))
-+ return -EFAULT;
-+ if (copy_from_user(¶m, (void __user *)arg, sizeof(param)))
-+ return -EFAULT;
-+
-+ if ((((cmd == GPTU_REQUEST_TIMER || cmd == GPTU_SET_TIMER
-+ || GPTU_SET_COUNTER) && param.timer < 2)
-+ || cmd == GPTU_GET_COUNT_VALUE || cmd == GPTU_CALCULATE_DIVIDER)
-+ && !access_ok((void __user *)arg,
-+ sizeof(struct gptu_ioctl_param)))
-+ return -EFAULT;
-+
-+ switch (cmd) {
-+ case GPTU_REQUEST_TIMER:
-+ ret = lq_request_timer(param.timer, param.flag, param.value,
-+ (unsigned long) param.pid,
-+ (unsigned long) param.sig);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ case GPTU_FREE_TIMER:
-+ ret = lq_free_timer(param.timer);
-+ break;
-+ case GPTU_START_TIMER:
-+ ret = lq_start_timer(param.timer, param.flag);
-+ break;
-+ case GPTU_STOP_TIMER:
-+ ret = lq_stop_timer(param.timer);
-+ break;
-+ case GPTU_GET_COUNT_VALUE:
-+ ret = lq_get_count_value(param.timer, ¶m.value);
-+ if (!ret && copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ value, ¶m.value,sizeof(param.value)))
-+ ret = -EFAULT;
-+ break;
-+ case GPTU_CALCULATE_DIVIDER:
-+ param.value = lq_cal_divider(param.value);
-+ if (param.value == 0)
-+ ret = -EINVAL;
-+ else if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ value, ¶m.value,
-+ sizeof(param.value)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ break;
-+ case GPTU_SET_TIMER:
-+ ret = lq_set_timer(param.timer, param.value,
-+ TIMER_FLAG_MASK_STOP(param.flag) !=
-+ TIMER_FLAG_ONCE ? 1 : 0,
-+ TIMER_FLAG_MASK_SRC(param.flag) ==
-+ TIMER_FLAG_EXT_SRC ? 1 : 0,
-+ TIMER_FLAG_MASK_HANDLE(param.flag) ==
-+ TIMER_FLAG_SIGNAL ? TIMER_FLAG_SIGNAL :
-+ TIMER_FLAG_NO_HANDLE,
-+ (unsigned long) param.pid,
-+ (unsigned long) param.sig);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ case GPTU_SET_COUNTER:
-+ lq_set_counter(param.timer, param.flag, param.value, 0, 0);
-+ if (ret > 0) {
-+ if (copy_to_user(&((struct gptu_ioctl_param *) arg)->
-+ timer, &ret, sizeof(&ret)))
-+ ret = -EFAULT;
-+ else
-+ ret = 0;
-+ }
-+ break;
-+ default:
-+ ret = -ENOTTY;
-+ }
-+
-+ return ret;
-+}
-+
-+static int gptu_open(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+static int gptu_release(struct inode *inode, struct file *file)
-+{
-+ return 0;
-+}
-+
-+static int gptu_probe(struct platform_device *pdev)
-+{
-+ int ret;
-+ int i;
-+
-+ ltq_w32(0, LQ_GPTU_IRNEN);
-+ ltq_w32(0xfff, LQ_GPTU_IRNCR);
-+
-+ memset(&timer_dev, 0, sizeof(timer_dev));
-+ mutex_init(&timer_dev.gptu_mutex);
-+
-+ lq_enable_gptu();
-+ timer_dev.number_of_timers = GPTU_ID_CFG * 2;
-+ lq_disable_gptu();
-+ if (timer_dev.number_of_timers > MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2)
-+ timer_dev.number_of_timers = MAX_NUM_OF_32BIT_TIMER_BLOCKS * 2;
-+ printk(KERN_INFO "gptu: totally %d 16-bit timers/counters\n", timer_dev.number_of_timers);
-+
-+ ret = misc_register(&gptu_miscdev);
-+ if (ret) {
-+ printk(KERN_ERR "gptu: can't misc_register, get error %d\n", -ret);
-+ return ret;
-+ } else {
-+ printk(KERN_INFO "gptu: misc_register on minor %d\n", gptu_miscdev.minor);
-+ }
-+
-+ for (i = 0; i < timer_dev.number_of_timers; i++) {
-+ int irq = platform_get_irq(pdev, i);
-+ if (irq < 0) {
-+ printk(KERN_ERR "gptu: failed in getting irq (%d), get error %d\n", i, irq);
-+ for (i--; i >= 0; i--)
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ misc_deregister(&gptu_miscdev);
-+ return irq;
-+ }
-+
-+ ret = request_irq(irq, timer_irq_handler, IRQF_TIMER, gptu_miscdev.name, &timer_dev.timer[i]);
-+ if (ret) {
-+ printk(KERN_ERR "gptu: failed in requesting irq (%d), get error %d\n", i, -ret);
-+ for (i--; i >= 0; i--)
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ misc_deregister(&gptu_miscdev);
-+ return ret;
-+ } else {
-+ timer_dev.timer[i].irq = irq;
-+ disable_irq(timer_dev.timer[i].irq);
-+ printk(KERN_INFO "gptu: succeeded to request irq %d\n", timer_dev.timer[i].irq);
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+static const struct of_device_id gptu_match[] = {
-+ { .compatible = "lantiq,gptu-xway" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, gptu_match);
-+
-+static struct platform_driver gptu_driver = {
-+ .probe = gptu_probe,
-+ .driver = {
-+ .name = "gptu-xway",
-+ .owner = THIS_MODULE,
-+ .of_match_table = gptu_match,
-+ },
-+};
-+
-+int __init lq_gptu_init(void)
-+{
-+ int ret = platform_driver_register(&gptu_driver);
-+
-+ if (ret)
-+ pr_info("gptu: Error registering platform driver\n");
-+ return ret;
-+}
-+
-+void __exit lq_gptu_exit(void)
-+{
-+ unsigned int i;
-+
-+ for (i = 0; i < timer_dev.number_of_timers; i++) {
-+ if (timer_dev.timer[i].f_irq_on)
-+ disable_irq(timer_dev.timer[i].irq);
-+ free_irq(timer_dev.timer[i].irq, &timer_dev.timer[i]);
-+ }
-+ lq_disable_gptu();
-+ misc_deregister(&gptu_miscdev);
-+}
-+
-+module_init(lq_gptu_init);
-+module_exit(lq_gptu_exit);
-+
-+#endif
+++ /dev/null
-From 997a8965db8417266bea3fbdcfa3e5655a1b52fa Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 9 Sep 2014 23:12:15 +0200
-Subject: [PATCH 18/36] MTD: nand: lots of xrx200 fixes
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mtd/nand/raw/xway_nand.c | 63 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 63 insertions(+)
-
---- a/drivers/mtd/nand/raw/xway_nand.c
-+++ b/drivers/mtd/nand/raw/xway_nand.c
-@@ -61,6 +61,24 @@
- #define NAND_CON_CSMUX (1 << 1)
- #define NAND_CON_NANDM 1
-
-+#define DANUBE_PCI_REG32( addr ) (*(volatile u32 *)(addr))
-+#define PCI_CR_PR_OFFSET (KSEG1+0x1E105400)
-+#define PCI_CR_PC_ARB (PCI_CR_PR_OFFSET + 0x0080)
-+
-+/*
-+ * req_mask provides a mechanism to prevent interference between
-+ * nand and pci (probably only relevant for the BT Home Hub 2B).
-+ * Setting it causes the corresponding pci req pins to be masked
-+ * during nand access, and also moves ebu locking from the read/write
-+ * functions to the chip select function to ensure that the whole
-+ * operation runs with interrupts disabled.
-+ * In addition it switches on some extra waiting in xway_cmd_ctrl().
-+ * This seems to be necessary if the ebu_cs1 pin has open-drain disabled,
-+ * which in turn seems to be necessary for the nor chip to be recognised
-+ * reliably, on a board (Home Hub 2B again) which has both nor and nand.
-+ */
-+static __be32 req_mask = 0;
-+
- struct xway_nand_data {
- struct nand_controller controller;
- struct nand_chip chip;
-@@ -92,10 +110,22 @@ static void xway_select_chip(struct nand
- case -1:
- ltq_ebu_w32_mask(NAND_CON_CE, 0, EBU_NAND_CON);
- ltq_ebu_w32_mask(NAND_CON_NANDM, 0, EBU_NAND_CON);
-+
-+ if (req_mask) {
-+ /* Unmask all external PCI request */
-+ DANUBE_PCI_REG32(PCI_CR_PC_ARB) &= ~(req_mask << 16);
-+ }
-+
- spin_unlock_irqrestore(&ebu_lock, data->csflags);
- break;
- case 0:
- spin_lock_irqsave(&ebu_lock, data->csflags);
-+
-+ if (req_mask) {
-+ /* Mask all external PCI request */
-+ DANUBE_PCI_REG32(PCI_CR_PC_ARB) |= (req_mask << 16);
-+ }
-+
- ltq_ebu_w32_mask(0, NAND_CON_NANDM, EBU_NAND_CON);
- ltq_ebu_w32_mask(0, NAND_CON_CE, EBU_NAND_CON);
- break;
-@@ -108,6 +138,11 @@ static void xway_cmd_ctrl(struct nand_ch
- {
- struct mtd_info *mtd = nand_to_mtd(chip);
-
-+ if (req_mask) {
-+ if (cmd != NAND_CMD_STATUS)
-+ ltq_ebu_w32(0, EBU_NAND_WAIT); /* Clear nand ready */
-+ }
-+
- if (cmd == NAND_CMD_NONE)
- return;
-
-@@ -118,6 +153,24 @@ static void xway_cmd_ctrl(struct nand_ch
-
- while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_WR_C) == 0)
- ;
-+
-+ if (req_mask) {
-+ /*
-+ * program and erase have their own busy handlers
-+ * status and sequential in needs no delay
-+ */
-+ switch (cmd) {
-+ case NAND_CMD_ERASE1:
-+ case NAND_CMD_SEQIN:
-+ case NAND_CMD_STATUS:
-+ case NAND_CMD_READID:
-+ return;
-+ }
-+
-+ /* wait until command is processed */
-+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD) == 0)
-+ ;
-+ }
- }
-
- static int xway_dev_ready(struct nand_chip *chip)
-@@ -170,6 +223,7 @@ static int xway_nand_probe(struct platfo
- int err;
- u32 cs;
- u32 cs_flag = 0;
-+ const __be32 *req_mask_ptr;
-
- /* Allocate memory for the device structure (and zero it) */
- data = devm_kzalloc(&pdev->dev, sizeof(struct xway_nand_data),
-@@ -206,6 +260,15 @@ static int xway_nand_probe(struct platfo
- if (!err && cs == 1)
- cs_flag = NAND_CON_IN_CS1 | NAND_CON_OUT_CS1;
-
-+ req_mask_ptr = of_get_property(pdev->dev.of_node,
-+ "req-mask", NULL);
-+
-+ /*
-+ * Load the PCI req lines to mask from the device tree. If the
-+ * property is not present, setting req_mask to 0 disables masking.
-+ */
-+ req_mask = (req_mask_ptr ? *req_mask_ptr : 0);
-+
- /* setup the EBU to run in NAND mode on our base addr */
- ltq_ebu_w32(CPHYSADDR(data->nandaddr)
- | ADDSEL1_MASK(3) | ADDSEL1_REGEN, EBU_ADDSEL1);
+++ /dev/null
-From e3b20f04e9f9cae1babe091fdc1d08d7703ae344 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:18:00 +0200
-Subject: [PATCH 20/36] MTD: lantiq: handle NO_XIP on cfi0001 flash
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/mtd/maps/lantiq-flash.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/maps/lantiq-flash.c
-+++ b/drivers/mtd/maps/lantiq-flash.c
-@@ -129,7 +129,11 @@ ltq_mtd_probe(struct platform_device *pd
- if (!ltq_mtd->map)
- return -ENOMEM;
-
-- ltq_mtd->map->phys = ltq_mtd->res->start;
-+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-+ ltq_mtd->map->phys = NO_XIP;
-+ else
-+ ltq_mtd->map->phys = ltq_mtd->res->start;
-+ ltq_mtd->res->start;
- ltq_mtd->map->size = resource_size(ltq_mtd->res);
- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
- if (IS_ERR(ltq_mtd->map->virt))
+++ /dev/null
-From 0a63ab263725c427051a8bbaa0732b749627da27 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:15:36 +0200
-Subject: [PATCH 23/36] NET: PHY: adds driver for lantiq PHY11G
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/phy/Kconfig | 5 +
- drivers/net/phy/Makefile | 1 +
- drivers/net/phy/lantiq.c | 231 ++++++++++++++++++++++++++++++++++++++++++++++
- 3 files changed, 237 insertions(+)
- create mode 100644 drivers/net/phy/lantiq.c
-
---- a/drivers/net/phy/intel-xway.c
-+++ b/drivers/net/phy/intel-xway.c
-@@ -229,6 +229,51 @@ static int xway_gphy_rgmii_init(struct p
- XWAY_MDIO_MIICTRL_TXSKEW_MASK, val);
- }
-
-+#if IS_ENABLED(CONFIG_OF_MDIO)
-+static int vr9_gphy_of_reg_init(struct phy_device *phydev)
-+{
-+ u32 tmp;
-+
-+ /* store the led values if one was passed by the devicetree */
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,ledch", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCH, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,ledcl", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LEDCL, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led0h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led0l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED0L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led1h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led1l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED1L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led2h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led2l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED2L, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led3h", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED3H, tmp);
-+
-+ if (!of_property_read_u32(phydev->mdio.dev.of_node, "lantiq,led3l", &tmp))
-+ phy_write_mmd(phydev, MDIO_MMD_VEND2, XWAY_MMD_LED3L, tmp);
-+
-+ return 0;
-+}
-+#else
-+static int vr9_gphy_of_reg_init(struct phy_device *phydev)
-+{
-+ return 0;
-+}
-+#endif /* CONFIG_OF_MDIO */
-+
- static int xway_gphy_config_init(struct phy_device *phydev)
- {
- int err;
-@@ -280,6 +325,7 @@ static int xway_gphy_config_init(struct
- if (err)
- return err;
-
-+ vr9_gphy_of_reg_init(phydev);
- return 0;
- }
-
---- /dev/null
-+++ b/Documentation/devicetree/bindings/phy/phy-lanitq.txt
-@@ -0,0 +1,216 @@
-+Lanitq PHY binding
-+============================================
-+
-+This devicetree binding controls the lantiq ethernet phys led functionality.
-+
-+Example:
-+ mdio@0 {
-+ #address-cells = <1>;
-+ #size-cells = <0>;
-+ compatible = "lantiq,xrx200-mdio";
-+ phy5: ethernet-phy@5 {
-+ reg = <0x1>;
-+ compatible = "lantiq,phy11g", "ethernet-phy-ieee802.3-c22";
-+ };
-+ phy11: ethernet-phy@11 {
-+ reg = <0x11>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led2h = <0x00>;
-+ lantiq,led2l = <0x03>;
-+ };
-+ phy12: ethernet-phy@12 {
-+ reg = <0x12>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led1h = <0x00>;
-+ lantiq,led1l = <0x03>;
-+ };
-+ phy13: ethernet-phy@13 {
-+ reg = <0x13>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led2h = <0x00>;
-+ lantiq,led2l = <0x03>;
-+ };
-+ phy14: ethernet-phy@14 {
-+ reg = <0x14>;
-+ compatible = "lantiq,phy22f", "ethernet-phy-ieee802.3-c22";
-+ lantiq,led1h = <0x00>;
-+ lantiq,led1l = <0x03>;
-+ };
-+ };
-+
-+Register Description
-+============================================
-+
-+LEDCH:
-+
-+Name Hardware Reset Value
-+LEDCH 0x00C5
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| FBF | SBF |RES | NACS |
-+=========================================
-+
-+Field Bits Type Description
-+FBF 7:6 RW Fast Blink Frequency
-+ ---
-+ 0x0 (00b) F02HZ 2 Hz blinking frequency
-+ 0x1 (01b) F04HZ 4 Hz blinking frequency
-+ 0x2 (10b) F08HZ 8 Hz blinking frequency
-+ 0x3 (11b) F16HZ 16 Hz blinking frequency
-+
-+SBF 5:4 RW Slow Blink Frequency
-+ ---
-+ 0x0 (00b) F02HZ 2 Hz blinking frequency
-+ 0x1 (01b) F04HZ 4 Hz blinking frequency
-+ 0x2 (10b) F08HZ 8 Hz blinking frequency
-+ 0x3 (11b) F16HZ 16 Hz blinking frequency
-+
-+NACS 2:0 RW Inverse of Scan Function
-+ ---
-+ 0x0 (000b) NONE No Function
-+ 0x1 (001b) LINK Complex function enabled when link is up
-+ 0x2 (010b) PDOWN Complex function enabled when device is powered-down
-+ 0x3 (011b) EEE Complex function enabled when device is in EEE mode
-+ 0x4 (100b) ANEG Complex function enabled when auto-negotiation is running
-+ 0x5 (101b) ABIST Complex function enabled when analog self-test is running
-+ 0x6 (110b) CDIAG Complex function enabled when cable diagnostics are running
-+ 0x7 (111b) TEST Complex function enabled when test mode is running
-+
-+LEDCL:
-+
-+Name Hardware Reset Value
-+LEDCL 0x0067
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+|RES | SCAN |RES | CBLINK |
-+=========================================
-+
-+Field Bits Type Description
-+SCAN 6:4 RW Complex Scan Configuration
-+ ---
-+ 000 B NONE No Function
-+ 001 B LINK Complex function enabled when link is up
-+ 010 B PDOWN Complex function enabled when device is powered-down
-+ 011 B EEE Complex function enabled when device is in EEE mode
-+ 100 B ANEG Complex function enabled when auto-negotiation is running
-+ 101 B ABIST Complex function enabled when analog self-test is running
-+ 110 B CDIAG Complex function enabled when cable diagnostics are running
-+ 111 B TEST Complex function enabled when test mode is running
-+
-+CBLINK 2:0 RW Complex Blinking Configuration
-+ ---
-+ 000 B NONE No Function
-+ 001 B LINK Complex function enabled when link is up
-+ 010 B PDOWN Complex function enabled when device is powered-down
-+ 011 B EEE Complex function enabled when device is in EEE mode
-+ 100 B ANEG Complex function enabled when auto-negotiation is running
-+ 101 B ABIST Complex function enabled when analog self-test is running
-+ 110 B CDIAG Complex function enabled when cable diagnostics are running
-+ 111 B TEST Complex function enabled when test mode is running
-+
-+LEDxH:
-+
-+Name Hardware Reset Value
-+LED0H 0x0070
-+LED1H 0x0020
-+LED2H 0x0040
-+LED3H 0x0040
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| CON | BLINKF |
-+=========================================
-+
-+Field Bits Type Description
-+CON 7:4 RW Constant On Configuration
-+ ---
-+ 0x0 (0000b) NONE LED does not light up constantly
-+ 0x1 (0001b) LINK10 LED is on when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 LED is on when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X LED is on when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 LED is on when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 LED is on when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X LED is on when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX LED is on when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN LED is on when device is powered-down
-+ 0x9 (1001b) EEE LED is on when device is in EEE mode
-+ 0xA (1010b) ANEG LED is on when auto-negotiation is running
-+ 0xB (1011b) ABIST LED is on when analog self-test is running
-+ 0xC (1100b) CDIAG LED is on when cable diagnostics are running
-+
-+BLINKF 3:0 RW Fast Blinking Configuration
-+ ---
-+ 0x0 (0000b) NONE No Blinking
-+ 0x1 (0001b) LINK10 Blink when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 Blink when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X Blink when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 Blink when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 Blink when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X Blink when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX Blink when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN Blink when device is powered-down
-+ 0x9 (1001b) EEE Blink when device is in EEE mode
-+ 0xA (1010b) ANEG Blink when auto-negotiation is running
-+ 0xB (1011b) ABIST Blink when analog self-test is running
-+ 0xC (1100b) CDIAG Blink when cable diagnostics are running
-+
-+LEDxL:
-+
-+Name Hardware Reset Value
-+LED0L 0x0003
-+LED1L 0x0000
-+LED2L 0x0000
-+LED3L 0x0020
-+
-+| 15 | | | | | | | 8 |
-+=========================================
-+| RES |
-+=========================================
-+
-+| 7 | | | | | | | 0 |
-+=========================================
-+| BLINKS | PULSE |
-+=========================================
-+
-+Field Bits Type Description
-+BLINKS 7:4 RW Slow Blinkin Configuration
-+ ---
-+ 0x0 (0000b) NONE No Blinking
-+ 0x1 (0001b) LINK10 Blink when link is 10 Mbit/s
-+ 0x2 (0010b) LINK100 Blink when link is 100 Mbit/s
-+ 0x3 (0011b) LINK10X Blink when link is 10/100 Mbit/s
-+ 0x4 (0100b) LINK1000 Blink when link is 1000 Mbit/s
-+ 0x5 (0101b) LINK10_0 Blink when link is 10/1000 Mbit/s
-+ 0x6 (0110b) LINK100X Blink when link is 100/1000 Mbit/s
-+ 0x7 (0111b) LINK10XX Blink when link is 10/100/1000 Mbit/s
-+ 0x8 (1000b) PDOWN Blink when device is powered-down
-+ 0x9 (1001b) EEE Blink when device is in EEE mode
-+ 0xA (1010b) ANEG Blink when auto-negotiation is running
-+ 0xB (1011b) ABIST Blink when analog self-test is running
-+ 0xC (1100b) CDIAG Blink when cable diagnostics are runningning
-+
-+PULSE 3:0 RW Pulsing Configuration
-+ The pulse field is a mask field by which certain events can be combined
-+ ---
-+ 0x0 (0000b) NONE No pulsing
-+ 0x1 (0001b) TXACT Transmit activity
-+ 0x2 (0010b) RXACT Receive activity
-+ 0x4 (0100b) COL Collision
-+ 0x8 (1000b) RES Reserved
+++ /dev/null
-From 870ed9cae083ff8a60a739ef7e74c5a1800533be Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Tue, 9 Sep 2014 22:45:34 +0200
-Subject: [PATCH 28/36] NET: lantiq: various etop fixes
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
- 1 file changed, 389 insertions(+), 166 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -1,7 +1,7 @@
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- *
-- * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
-+ * Copyright (C) 2011-12 John Crispin <blogic@openwrt.org>
- */
-
- #include <linux/kernel.h>
-@@ -20,11 +20,16 @@
- #include <linux/mm.h>
- #include <linux/platform_device.h>
- #include <linux/ethtool.h>
-+#include <linux/if_vlan.h>
- #include <linux/init.h>
- #include <linux/delay.h>
- #include <linux/io.h>
- #include <linux/dma-mapping.h>
- #include <linux/module.h>
-+#include <linux/clk.h>
-+#include <linux/of_net.h>
-+#include <linux/of_irq.h>
-+#include <linux/of_platform.h>
-
- #include <asm/checksum.h>
-
-@@ -32,7 +37,7 @@
- #include <xway_dma.h>
- #include <lantiq_platform.h>
-
--#define LTQ_ETOP_MDIO 0x11804
-+#define LTQ_ETOP_MDIO_ACC 0x11804
- #define MDIO_REQUEST 0x80000000
- #define MDIO_READ 0x40000000
- #define MDIO_ADDR_MASK 0x1f
-@@ -41,44 +46,91 @@
- #define MDIO_REG_OFFSET 0x10
- #define MDIO_VAL_MASK 0xffff
-
--#define PPE32_CGEN 0x800
--#define LQ_PPE32_ENET_MAC_CFG 0x1840
-+#define LTQ_ETOP_MDIO_CFG 0x11800
-+#define MDIO_CFG_MASK 0x6
-+
-+#define LTQ_ETOP_CFG 0x11808
-+#define LTQ_ETOP_IGPLEN 0x11820
-+#define LTQ_ETOP_MAC_CFG 0x11840
-
- #define LTQ_ETOP_ENETS0 0x11850
- #define LTQ_ETOP_MAC_DA0 0x1186C
- #define LTQ_ETOP_MAC_DA1 0x11870
--#define LTQ_ETOP_CFG 0x16020
--#define LTQ_ETOP_IGPLEN 0x16080
-+
-+#define MAC_CFG_MASK 0xfff
-+#define MAC_CFG_CGEN (1 << 11)
-+#define MAC_CFG_DUPLEX (1 << 2)
-+#define MAC_CFG_SPEED (1 << 1)
-+#define MAC_CFG_LINK (1 << 0)
-
- #define MAX_DMA_CHAN 0x8
- #define MAX_DMA_CRC_LEN 0x4
- #define MAX_DMA_DATA_LEN 0x600
-
- #define ETOP_FTCU BIT(28)
--#define ETOP_MII_MASK 0xf
--#define ETOP_MII_NORMAL 0xd
--#define ETOP_MII_REVERSE 0xe
- #define ETOP_PLEN_UNDER 0x40
--#define ETOP_CGEN 0x800
-+#define ETOP_CFG_MII0 0x01
-
--/* use 2 static channels for TX/RX */
--#define LTQ_ETOP_TX_CHANNEL 1
--#define LTQ_ETOP_RX_CHANNEL 6
--#define IS_TX(x) (x == LTQ_ETOP_TX_CHANNEL)
--#define IS_RX(x) (x == LTQ_ETOP_RX_CHANNEL)
-+#define ETOP_CFG_MASK 0xfff
-+#define ETOP_CFG_FEN0 (1 << 8)
-+#define ETOP_CFG_SEN0 (1 << 6)
-+#define ETOP_CFG_OFF1 (1 << 3)
-+#define ETOP_CFG_REMII0 (1 << 1)
-+#define ETOP_CFG_OFF0 (1 << 0)
-+
-+#define LTQ_GBIT_MDIO_CTL 0xCC
-+#define LTQ_GBIT_MDIO_DATA 0xd0
-+#define LTQ_GBIT_GCTL0 0x68
-+#define LTQ_GBIT_PMAC_HD_CTL 0x8c
-+#define LTQ_GBIT_P0_CTL 0x4
-+#define LTQ_GBIT_PMAC_RX_IPG 0xa8
-+#define LTQ_GBIT_RGMII_CTL 0x78
-+
-+#define PMAC_HD_CTL_AS (1 << 19)
-+#define PMAC_HD_CTL_RXSH (1 << 22)
-+
-+/* Switch Enable (0=disable, 1=enable) */
-+#define GCTL0_SE 0x80000000
-+/* Disable MDIO auto polling (0=disable, 1=enable) */
-+#define PX_CTL_DMDIO 0x00400000
-+
-+/* MDC clock divider, clock = 25MHz/((MDC_CLOCK + 1) * 2) */
-+#define MDC_CLOCK_MASK 0xff000000
-+#define MDC_CLOCK_OFFSET 24
-+
-+/* register information for the gbit's MDIO bus */
-+#define MDIO_XR9_REQUEST 0x00008000
-+#define MDIO_XR9_READ 0x00000800
-+#define MDIO_XR9_WRITE 0x00000400
-+#define MDIO_XR9_REG_MASK 0x1f
-+#define MDIO_XR9_ADDR_MASK 0x1f
-+#define MDIO_XR9_RD_MASK 0xffff
-+#define MDIO_XR9_REG_OFFSET 0
-+#define MDIO_XR9_ADDR_OFFSET 5
-+#define MDIO_XR9_WR_OFFSET 16
-
-+#define LTQ_DMA_ETOP ((of_machine_is_compatible("lantiq,ase")) ? \
-+ (INT_NUM_IM3_IRL0) : (INT_NUM_IM2_IRL0))
-+
-+/* the newer xway socks have a embedded 3/7 port gbit multiplexer */
- #define ltq_etop_r32(x) ltq_r32(ltq_etop_membase + (x))
- #define ltq_etop_w32(x, y) ltq_w32(x, ltq_etop_membase + (y))
- #define ltq_etop_w32_mask(x, y, z) \
- ltq_w32_mask(x, y, ltq_etop_membase + (z))
-
--#define DRV_VERSION "1.0"
-+#define ltq_gbit_r32(x) ltq_r32(ltq_gbit_membase + (x))
-+#define ltq_gbit_w32(x, y) ltq_w32(x, ltq_gbit_membase + (y))
-+#define ltq_gbit_w32_mask(x, y, z) \
-+ ltq_w32_mask(x, y, ltq_gbit_membase + (z))
-+
-+#define DRV_VERSION "1.2"
-
- static void __iomem *ltq_etop_membase;
-+static void __iomem *ltq_gbit_membase;
-
- struct ltq_etop_chan {
-- int idx;
- int tx_free;
-+ int irq;
- struct net_device *netdev;
- struct napi_struct napi;
- struct ltq_dma_channel dma;
-@@ -88,23 +140,36 @@ struct ltq_etop_chan {
- struct ltq_etop_priv {
- struct net_device *netdev;
- struct platform_device *pdev;
-- struct ltq_eth_data *pldata;
- struct resource *res;
-
- struct mii_bus *mii_bus;
-
-- struct ltq_etop_chan ch[MAX_DMA_CHAN];
-- int tx_free[MAX_DMA_CHAN >> 1];
-+ struct ltq_etop_chan txch;
-+ struct ltq_etop_chan rxch;
-
-- spinlock_t lock;
-+ int tx_irq;
-+ int rx_irq;
-+
-+ unsigned char mac[6];
-+ phy_interface_t mii_mode;
-+
-+ spinlock_t lock;
-+
-+ struct clk *clk_ppe;
-+ struct clk *clk_switch;
-+ struct clk *clk_ephy;
-+ struct clk *clk_ephycgu;
- };
-
-+static int ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data);
-+
- static int
- ltq_etop_alloc_skb(struct ltq_etop_chan *ch)
- {
- struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
-
-- ch->skb[ch->dma.desc] = netdev_alloc_skb(ch->netdev, MAX_DMA_DATA_LEN);
-+ ch->skb[ch->dma.desc] = dev_alloc_skb(MAX_DMA_DATA_LEN);
- if (!ch->skb[ch->dma.desc])
- return -ENOMEM;
- ch->dma.desc_base[ch->dma.desc].addr = dma_map_single(&priv->pdev->dev,
-@@ -139,8 +204,11 @@ ltq_etop_hw_receive(struct ltq_etop_chan
- spin_unlock_irqrestore(&priv->lock, flags);
-
- skb_put(skb, len);
-+ skb->dev = ch->netdev;
- skb->protocol = eth_type_trans(skb, ch->netdev);
- netif_receive_skb(skb);
-+ ch->netdev->stats.rx_packets++;
-+ ch->netdev->stats.rx_bytes += len;
- }
-
- static int
-@@ -148,7 +216,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
- {
- struct ltq_etop_chan *ch = container_of(napi,
- struct ltq_etop_chan, napi);
-+ struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
- int work_done = 0;
-+ unsigned long flags;
-
- while (work_done < budget) {
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-@@ -160,7 +230,9 @@ ltq_etop_poll_rx(struct napi_struct *nap
- }
- if (work_done < budget) {
- napi_complete_done(&ch->napi, work_done);
-+ spin_lock_irqsave(&priv->lock, flags);
- ltq_dma_ack_irq(&ch->dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
- }
- return work_done;
- }
-@@ -172,12 +244,14 @@ ltq_etop_poll_tx(struct napi_struct *nap
- container_of(napi, struct ltq_etop_chan, napi);
- struct ltq_etop_priv *priv = netdev_priv(ch->netdev);
- struct netdev_queue *txq =
-- netdev_get_tx_queue(ch->netdev, ch->idx >> 1);
-+ netdev_get_tx_queue(ch->netdev, ch->dma.nr >> 1);
- unsigned long flags;
-
- spin_lock_irqsave(&priv->lock, flags);
- while ((ch->dma.desc_base[ch->tx_free].ctl &
- (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
-+ ch->netdev->stats.tx_packets++;
-+ ch->netdev->stats.tx_bytes += ch->skb[ch->tx_free]->len;
- dev_kfree_skb_any(ch->skb[ch->tx_free]);
- ch->skb[ch->tx_free] = NULL;
- memset(&ch->dma.desc_base[ch->tx_free], 0,
-@@ -190,7 +264,9 @@ ltq_etop_poll_tx(struct napi_struct *nap
- if (netif_tx_queue_stopped(txq))
- netif_tx_start_queue(txq);
- napi_complete(&ch->napi);
-+ spin_lock_irqsave(&priv->lock, flags);
- ltq_dma_ack_irq(&ch->dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
- return 1;
- }
-
-@@ -198,9 +274,10 @@ static irqreturn_t
- ltq_etop_dma_irq(int irq, void *_priv)
- {
- struct ltq_etop_priv *priv = _priv;
-- int ch = irq - LTQ_DMA_CH0_INT;
--
-- napi_schedule(&priv->ch[ch].napi);
-+ if (irq == priv->txch.dma.irq)
-+ napi_schedule(&priv->txch.napi);
-+ else
-+ napi_schedule(&priv->rxch.napi);
- return IRQ_HANDLED;
- }
-
-@@ -212,7 +289,7 @@ ltq_etop_free_channel(struct net_device
- ltq_dma_free(&ch->dma);
- if (ch->dma.irq)
- free_irq(ch->dma.irq, priv);
-- if (IS_RX(ch->idx)) {
-+ if (ch == &priv->txch) {
- int desc;
- for (desc = 0; desc < LTQ_DESC_NUM; desc++)
- dev_kfree_skb_any(ch->skb[ch->dma.desc]);
-@@ -223,66 +300,135 @@ static void
- ltq_etop_hw_exit(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-
-- ltq_pmu_disable(PMU_PPE);
-- for (i = 0; i < MAX_DMA_CHAN; i++)
-- if (IS_TX(i) || IS_RX(i))
-- ltq_etop_free_channel(dev, &priv->ch[i]);
-+ clk_disable(priv->clk_ppe);
-+
-+ if (of_machine_is_compatible("lantiq,ar9"))
-+ clk_disable(priv->clk_switch);
-+
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ clk_disable(priv->clk_ephy);
-+ clk_disable(priv->clk_ephycgu);
-+ }
-+
-+ ltq_etop_free_channel(dev, &priv->txch);
-+ ltq_etop_free_channel(dev, &priv->rxch);
-+}
-+
-+static void
-+ltq_etop_gbit_init(struct net_device *dev)
-+{
-+ struct ltq_etop_priv *priv = netdev_priv(dev);
-+
-+ clk_enable(priv->clk_switch);
-+
-+ /* enable gbit port0 on the SoC */
-+ ltq_gbit_w32_mask((1 << 17), (1 << 18), LTQ_GBIT_P0_CTL);
-+
-+ ltq_gbit_w32_mask(0, GCTL0_SE, LTQ_GBIT_GCTL0);
-+ /* disable MDIO auto polling mode */
-+ ltq_gbit_w32_mask(0, PX_CTL_DMDIO, LTQ_GBIT_P0_CTL);
-+ /* set 1522 packet size */
-+ ltq_gbit_w32_mask(0x300, 0, LTQ_GBIT_GCTL0);
-+ /* disable pmac & dmac headers */
-+ ltq_gbit_w32_mask(PMAC_HD_CTL_AS | PMAC_HD_CTL_RXSH, 0,
-+ LTQ_GBIT_PMAC_HD_CTL);
-+ /* Due to traffic halt when burst length 8,
-+ replace default IPG value with 0x3B */
-+ ltq_gbit_w32(0x3B, LTQ_GBIT_PMAC_RX_IPG);
-+ /* set mdc clock to 2.5 MHz */
-+ ltq_gbit_w32_mask(MDC_CLOCK_MASK, 4 << MDC_CLOCK_OFFSET,
-+ LTQ_GBIT_RGMII_CTL);
- }
-
- static int
- ltq_etop_hw_init(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-+ phy_interface_t mii_mode = priv->mii_mode;
-
-- ltq_pmu_enable(PMU_PPE);
-+ clk_enable(priv->clk_ppe);
-
-- switch (priv->pldata->mii_mode) {
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ ltq_etop_gbit_init(dev);
-+ /* force the etops link to the gbit to MII */
-+ mii_mode = PHY_INTERFACE_MODE_MII;
-+ }
-+ ltq_etop_w32_mask(MDIO_CFG_MASK, 0, LTQ_ETOP_MDIO_CFG);
-+ ltq_etop_w32_mask(MAC_CFG_MASK, MAC_CFG_CGEN | MAC_CFG_DUPLEX |
-+ MAC_CFG_SPEED | MAC_CFG_LINK, LTQ_ETOP_MAC_CFG);
-+
-+ switch (mii_mode) {
- case PHY_INTERFACE_MODE_RMII:
-- ltq_etop_w32_mask(ETOP_MII_MASK,
-- ETOP_MII_REVERSE, LTQ_ETOP_CFG);
-+ ltq_etop_w32_mask(ETOP_CFG_MASK, ETOP_CFG_REMII0 | ETOP_CFG_OFF1 |
-+ ETOP_CFG_SEN0 | ETOP_CFG_FEN0, LTQ_ETOP_CFG);
- break;
-
- case PHY_INTERFACE_MODE_MII:
-- ltq_etop_w32_mask(ETOP_MII_MASK,
-- ETOP_MII_NORMAL, LTQ_ETOP_CFG);
-+ ltq_etop_w32_mask(ETOP_CFG_MASK, ETOP_CFG_OFF1 |
-+ ETOP_CFG_SEN0 | ETOP_CFG_FEN0, LTQ_ETOP_CFG);
- break;
-
- default:
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ clk_enable(priv->clk_ephy);
-+ /* disable external MII */
-+ ltq_etop_w32_mask(0, ETOP_CFG_MII0, LTQ_ETOP_CFG);
-+ /* enable clock for internal PHY */
-+ clk_enable(priv->clk_ephycgu);
-+ /* we need to write this magic to the internal phy to
-+ make it work */
-+ ltq_etop_mdio_wr(NULL, 0x8, 0x12, 0xC020);
-+ pr_info("Selected EPHY mode\n");
-+ break;
-+ }
- netdev_err(dev, "unknown mii mode %d\n",
-- priv->pldata->mii_mode);
-+ mii_mode);
- return -ENOTSUPP;
- }
-
-- /* enable crc generation */
-- ltq_etop_w32(PPE32_CGEN, LQ_PPE32_ENET_MAC_CFG);
-+ return 0;
-+}
-+
-+static int
-+ltq_etop_dma_init(struct net_device *dev)
-+{
-+ struct ltq_etop_priv *priv = netdev_priv(dev);
-+ int tx = priv->tx_irq - LTQ_DMA_ETOP;
-+ int rx = priv->rx_irq - LTQ_DMA_ETOP;
-+ int err;
-
- ltq_dma_init_port(DMA_PORT_ETOP);
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- int irq = LTQ_DMA_CH0_INT + i;
-- struct ltq_etop_chan *ch = &priv->ch[i];
--
-- ch->idx = ch->dma.nr = i;
-- ch->dma.dev = &priv->pdev->dev;
--
-- if (IS_TX(i)) {
-- ltq_dma_alloc_tx(&ch->dma);
-- request_irq(irq, ltq_etop_dma_irq, 0, "etop_tx", priv);
-- } else if (IS_RX(i)) {
-- ltq_dma_alloc_rx(&ch->dma);
-- for (ch->dma.desc = 0; ch->dma.desc < LTQ_DESC_NUM;
-- ch->dma.desc++)
-- if (ltq_etop_alloc_skb(ch))
-- return -ENOMEM;
-- ch->dma.desc = 0;
-- request_irq(irq, ltq_etop_dma_irq, 0, "etop_rx", priv);
-+ priv->txch.dma.nr = tx;
-+ priv->txch.dma.dev = &priv->pdev->dev;
-+ ltq_dma_alloc_tx(&priv->txch.dma);
-+ err = request_irq(priv->tx_irq, ltq_etop_dma_irq, 0, "eth_tx", priv);
-+ if (err) {
-+ netdev_err(dev, "failed to allocate tx irq\n");
-+ goto err_out;
-+ }
-+ priv->txch.dma.irq = priv->tx_irq;
-+
-+ priv->rxch.dma.nr = rx;
-+ priv->rxch.dma.dev = &priv->pdev->dev;
-+ ltq_dma_alloc_rx(&priv->rxch.dma);
-+ for (priv->rxch.dma.desc = 0; priv->rxch.dma.desc < LTQ_DESC_NUM;
-+ priv->rxch.dma.desc++) {
-+ if (ltq_etop_alloc_skb(&priv->rxch)) {
-+ netdev_err(dev, "failed to allocate skbs\n");
-+ err = -ENOMEM;
-+ goto err_out;
- }
-- ch->dma.irq = irq;
- }
-- return 0;
-+ priv->rxch.dma.desc = 0;
-+ err = request_irq(priv->rx_irq, ltq_etop_dma_irq, 0, "eth_rx", priv);
-+ if (err)
-+ netdev_err(dev, "failed to allocate rx irq\n");
-+ else
-+ priv->rxch.dma.irq = priv->rx_irq;
-+err_out:
-+ return err;
- }
-
- static void
-@@ -301,6 +447,39 @@ static const struct ethtool_ops ltq_etop
- };
-
- static int
-+ltq_etop_mdio_wr_xr9(struct mii_bus *bus, int phy_addr,
-+ int phy_reg, u16 phy_data)
-+{
-+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_WRITE |
-+ (phy_data << MDIO_XR9_WR_OFFSET) |
-+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
-+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
-+
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ return 0;
-+}
-+
-+static int
-+ltq_etop_mdio_rd_xr9(struct mii_bus *bus, int phy_addr, int phy_reg)
-+{
-+ u32 val = MDIO_XR9_REQUEST | MDIO_XR9_READ |
-+ ((phy_addr & MDIO_XR9_ADDR_MASK) << MDIO_XR9_ADDR_OFFSET) |
-+ ((phy_reg & MDIO_XR9_REG_MASK) << MDIO_XR9_REG_OFFSET);
-+
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ ltq_gbit_w32(val, LTQ_GBIT_MDIO_CTL);
-+ while (ltq_gbit_r32(LTQ_GBIT_MDIO_CTL) & MDIO_XR9_REQUEST)
-+ ;
-+ val = ltq_gbit_r32(LTQ_GBIT_MDIO_DATA) & MDIO_XR9_RD_MASK;
-+ return val;
-+}
-+
-+static int
- ltq_etop_mdio_wr(struct mii_bus *bus, int phy_addr, int phy_reg, u16 phy_data)
- {
- u32 val = MDIO_REQUEST |
-@@ -308,9 +487,9 @@ ltq_etop_mdio_wr(struct mii_bus *bus, in
- ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET) |
- phy_data;
-
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- ltq_etop_w32(val, LTQ_ETOP_MDIO);
-+ ltq_etop_w32(val, LTQ_ETOP_MDIO_ACC);
- return 0;
- }
-
-@@ -321,12 +500,12 @@ ltq_etop_mdio_rd(struct mii_bus *bus, in
- ((phy_addr & MDIO_ADDR_MASK) << MDIO_ADDR_OFFSET) |
- ((phy_reg & MDIO_REG_MASK) << MDIO_REG_OFFSET);
-
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- ltq_etop_w32(val, LTQ_ETOP_MDIO);
-- while (ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_REQUEST)
-+ ltq_etop_w32(val, LTQ_ETOP_MDIO_ACC);
-+ while (ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_REQUEST)
- ;
-- val = ltq_etop_r32(LTQ_ETOP_MDIO) & MDIO_VAL_MASK;
-+ val = ltq_etop_r32(LTQ_ETOP_MDIO_ACC) & MDIO_VAL_MASK;
- return val;
- }
-
-@@ -342,7 +521,10 @@ ltq_etop_mdio_probe(struct net_device *d
- struct ltq_etop_priv *priv = netdev_priv(dev);
- struct phy_device *phydev;
-
-- phydev = phy_find_first(priv->mii_bus);
-+ if (of_machine_is_compatible("lantiq,ase"))
-+ phydev = mdiobus_get_phy(priv->mii_bus, 8);
-+ else
-+ phydev = mdiobus_get_phy(priv->mii_bus, 0);
-
- if (!phydev) {
- netdev_err(dev, "no PHY found\n");
-@@ -350,14 +532,17 @@ ltq_etop_mdio_probe(struct net_device *d
- }
-
- phydev = phy_connect(dev, phydev_name(phydev),
-- <q_etop_mdio_link, priv->pldata->mii_mode);
-+ <q_etop_mdio_link, priv->mii_mode);
-
- if (IS_ERR(phydev)) {
- netdev_err(dev, "Could not attach to PHY\n");
- return PTR_ERR(phydev);
- }
-
-- phy_set_max_speed(phydev, SPEED_100);
-+ if (of_machine_is_compatible("lantiq,ar9"))
-+ phy_set_max_speed(phydev, SPEED_1000);
-+ else
-+ phy_set_max_speed(phydev, SPEED_100);
-
- phy_attached_info(phydev);
-
-@@ -378,8 +563,13 @@ ltq_etop_mdio_init(struct net_device *de
- }
-
- priv->mii_bus->priv = dev;
-- priv->mii_bus->read = ltq_etop_mdio_rd;
-- priv->mii_bus->write = ltq_etop_mdio_wr;
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ priv->mii_bus->read = ltq_etop_mdio_rd_xr9;
-+ priv->mii_bus->write = ltq_etop_mdio_wr_xr9;
-+ } else {
-+ priv->mii_bus->read = ltq_etop_mdio_rd;
-+ priv->mii_bus->write = ltq_etop_mdio_wr;
-+ }
- priv->mii_bus->name = "ltq_mii";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- priv->pdev->name, priv->pdev->id);
-@@ -416,18 +606,21 @@ static int
- ltq_etop_open(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-+ unsigned long flags;
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- struct ltq_etop_chan *ch = &priv->ch[i];
-+ napi_enable(&priv->txch.napi);
-+ napi_enable(&priv->rxch.napi);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ ltq_dma_open(&priv->txch.dma);
-+ ltq_dma_enable_irq(&priv->txch.dma);
-+ ltq_dma_open(&priv->rxch.dma);
-+ ltq_dma_enable_irq(&priv->rxch.dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
-+ if (dev->phydev)
-+ phy_start(dev->phydev);
-
-- if (!IS_TX(i) && (!IS_RX(i)))
-- continue;
-- ltq_dma_open(&ch->dma);
-- ltq_dma_enable_irq(&ch->dma);
-- napi_enable(&ch->napi);
-- }
-- phy_start(dev->phydev);
- netif_tx_start_all_queues(dev);
- return 0;
- }
-@@ -436,18 +629,19 @@ static int
- ltq_etop_stop(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int i;
-+ unsigned long flags;
-
- netif_tx_stop_all_queues(dev);
-- phy_stop(dev->phydev);
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- struct ltq_etop_chan *ch = &priv->ch[i];
--
-- if (!IS_RX(i) && !IS_TX(i))
-- continue;
-- napi_disable(&ch->napi);
-- ltq_dma_close(&ch->dma);
-- }
-+ if (dev->phydev)
-+ phy_stop(dev->phydev);
-+ napi_disable(&priv->txch.napi);
-+ napi_disable(&priv->rxch.napi);
-+
-+ spin_lock_irqsave(&priv->lock, flags);
-+ ltq_dma_close(&priv->txch.dma);
-+ ltq_dma_close(&priv->rxch.dma);
-+ spin_unlock_irqrestore(&priv->lock, flags);
-+
- return 0;
- }
-
-@@ -457,15 +651,16 @@ ltq_etop_tx(struct sk_buff *skb, struct
- int queue = skb_get_queue_mapping(skb);
- struct netdev_queue *txq = netdev_get_tx_queue(dev, queue);
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- struct ltq_etop_chan *ch = &priv->ch[(queue << 1) | 1];
-- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-- int len;
-+ struct ltq_dma_desc *desc =
-+ &priv->txch.dma.desc_base[priv->txch.dma.desc];
- unsigned long flags;
- u32 byte_offset;
-+ int len;
-
- len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
-
-- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) || ch->skb[ch->dma.desc]) {
-+ if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) ||
-+ priv->txch.skb[priv->txch.dma.desc]) {
- netdev_err(dev, "tx ring full\n");
- netif_tx_stop_queue(txq);
- return NETDEV_TX_BUSY;
-@@ -473,7 +668,7 @@ ltq_etop_tx(struct sk_buff *skb, struct
-
- /* dma needs to start on a 16 byte aligned address */
- byte_offset = CPHYSADDR(skb->data) % 16;
-- ch->skb[ch->dma.desc] = skb;
-+ priv->txch.skb[priv->txch.dma.desc] = skb;
-
- netif_trans_update(dev);
-
-@@ -483,11 +678,11 @@ ltq_etop_tx(struct sk_buff *skb, struct
- wmb();
- desc->ctl = LTQ_DMA_OWN | LTQ_DMA_SOP | LTQ_DMA_EOP |
- LTQ_DMA_TX_OFFSET(byte_offset) | (len & LTQ_DMA_SIZE_MASK);
-- ch->dma.desc++;
-- ch->dma.desc %= LTQ_DESC_NUM;
-+ priv->txch.dma.desc++;
-+ priv->txch.dma.desc %= LTQ_DESC_NUM;
- spin_unlock_irqrestore(&priv->lock, flags);
-
-- if (ch->dma.desc_base[ch->dma.desc].ctl & LTQ_DMA_OWN)
-+ if (priv->txch.dma.desc_base[priv->txch.dma.desc].ctl & LTQ_DMA_OWN)
- netif_tx_stop_queue(txq);
-
- return NETDEV_TX_OK;
-@@ -498,11 +693,14 @@ ltq_etop_change_mtu(struct net_device *d
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
- unsigned long flags;
-+ int max;
-
- dev->mtu = new_mtu;
-
-+ max = ETH_HLEN + VLAN_HLEN + new_mtu + ETH_FCS_LEN;
-+
- spin_lock_irqsave(&priv->lock, flags);
-- ltq_etop_w32((ETOP_PLEN_UNDER << 16) | new_mtu, LTQ_ETOP_IGPLEN);
-+ ltq_etop_w32((ETOP_PLEN_UNDER << 16) | max, LTQ_ETOP_IGPLEN);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-@@ -555,6 +753,9 @@ ltq_etop_init(struct net_device *dev)
- if (err)
- goto err_hw;
- ltq_etop_change_mtu(dev, 1500);
-+ err = ltq_etop_dma_init(dev);
-+ if (err)
-+ goto err_hw;
-
- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
- if (!is_valid_ether_addr(mac.sa_data)) {
-@@ -572,9 +773,10 @@ ltq_etop_init(struct net_device *dev)
- dev->addr_assign_type = NET_ADDR_RANDOM;
-
- ltq_etop_set_multicast_list(dev);
-- err = ltq_etop_mdio_init(dev);
-- if (err)
-- goto err_netdev;
-+ if (!ltq_etop_mdio_init(dev))
-+ dev->ethtool_ops = <q_etop_ethtool_ops;
-+ else
-+ pr_warn("etop: mdio probe failed\n");;
- return 0;
-
- err_netdev:
-@@ -594,6 +796,9 @@ ltq_etop_tx_timeout(struct net_device *d
- err = ltq_etop_hw_init(dev);
- if (err)
- goto err_hw;
-+ err = ltq_etop_dma_init(dev);
-+ if (err)
-+ goto err_hw;
- netif_trans_update(dev);
- netif_wake_queue(dev);
- return;
-@@ -617,14 +822,18 @@ static const struct net_device_ops ltq_e
- .ndo_tx_timeout = ltq_etop_tx_timeout,
- };
-
--static int __init
--ltq_etop_probe(struct platform_device *pdev)
-+static int ltq_etop_probe(struct platform_device *pdev)
- {
- struct net_device *dev;
- struct ltq_etop_priv *priv;
-- struct resource *res;
-+ struct resource *res, *gbit_res, irqres[2];
- int err;
-- int i;
-+
-+ err = of_irq_to_resource_table(pdev->dev.of_node, irqres, 2);
-+ if (err != 2) {
-+ dev_err(&pdev->dev, "failed to get etop irqs\n");
-+ return -EINVAL;
-+ }
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
-@@ -650,31 +859,62 @@ ltq_etop_probe(struct platform_device *p
- goto err_out;
- }
-
-- dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
-- if (!dev) {
-- err = -ENOMEM;
-- goto err_out;
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ gbit_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
-+ if (!gbit_res) {
-+ dev_err(&pdev->dev, "failed to get gbit resource\n");
-+ err = -ENOENT;
-+ goto err_out;
-+ }
-+ ltq_gbit_membase = devm_ioremap(&pdev->dev,
-+ gbit_res->start, resource_size(gbit_res));
-+ if (!ltq_gbit_membase) {
-+ dev_err(&pdev->dev, "failed to remap gigabit switch %d\n",
-+ pdev->id);
-+ err = -ENOMEM;
-+ goto err_out;
-+ }
- }
-+
-+ dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4);
- strcpy(dev->name, "eth%d");
- dev->netdev_ops = <q_eth_netdev_ops;
-- dev->ethtool_ops = <q_etop_ethtool_ops;
- priv = netdev_priv(dev);
- priv->res = res;
- priv->pdev = pdev;
-- priv->pldata = dev_get_platdata(&pdev->dev);
- priv->netdev = dev;
-+ priv->tx_irq = irqres[0].start;
-+ priv->rx_irq = irqres[1].start;
-+ err = of_get_phy_mode(pdev->dev.of_node, &priv->mii_mode);
-+ if (err)
-+ pr_err("Can't find phy-mode for port\n");
-+
-+ of_get_mac_address(pdev->dev.of_node, priv->mac);
-+
-+ priv->clk_ppe = clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->clk_ppe))
-+ return PTR_ERR(priv->clk_ppe);
-+ if (of_machine_is_compatible("lantiq,ar9")) {
-+ priv->clk_switch = clk_get(&pdev->dev, "switch");
-+ if (IS_ERR(priv->clk_switch))
-+ return PTR_ERR(priv->clk_switch);
-+ }
-+ if (of_machine_is_compatible("lantiq,ase")) {
-+ priv->clk_ephy = clk_get(&pdev->dev, "ephy");
-+ if (IS_ERR(priv->clk_ephy))
-+ return PTR_ERR(priv->clk_ephy);
-+ priv->clk_ephycgu = clk_get(&pdev->dev, "ephycgu");
-+ if (IS_ERR(priv->clk_ephycgu))
-+ return PTR_ERR(priv->clk_ephycgu);
-+ }
-+
- spin_lock_init(&priv->lock);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
-- for (i = 0; i < MAX_DMA_CHAN; i++) {
-- if (IS_TX(i))
-- netif_napi_add(dev, &priv->ch[i].napi,
-- ltq_etop_poll_tx, 8);
-- else if (IS_RX(i))
-- netif_napi_add(dev, &priv->ch[i].napi,
-- ltq_etop_poll_rx, 32);
-- priv->ch[i].netdev = dev;
-- }
-+ netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
-+ netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
-+ priv->txch.netdev = dev;
-+ priv->rxch.netdev = dev;
-
- err = register_netdev(dev);
- if (err)
-@@ -703,31 +943,22 @@ ltq_etop_remove(struct platform_device *
- return 0;
- }
-
-+static const struct of_device_id ltq_etop_match[] = {
-+ { .compatible = "lantiq,etop-xway" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ltq_etop_match);
-+
- static struct platform_driver ltq_mii_driver = {
-+ .probe = ltq_etop_probe,
- .remove = ltq_etop_remove,
- .driver = {
- .name = "ltq_etop",
-+ .of_match_table = ltq_etop_match,
- },
- };
-
--int __init
--init_ltq_etop(void)
--{
-- int ret = platform_driver_probe(<q_mii_driver, ltq_etop_probe);
--
-- if (ret)
-- pr_err("ltq_etop: Error registering platform driver!");
-- return ret;
--}
--
--static void __exit
--exit_ltq_etop(void)
--{
-- platform_driver_unregister(<q_mii_driver);
--}
--
--module_init(init_ltq_etop);
--module_exit(exit_ltq_etop);
-+module_platform_driver(ltq_mii_driver);
-
- MODULE_AUTHOR("John Crispin <blogic@openwrt.org>");
- MODULE_DESCRIPTION("Lantiq SoC ETOP");
+++ /dev/null
-From f17e50f67fa3c77624edf2ca03fae0d50f0ce39b Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Thu, 7 Aug 2014 18:26:42 +0200
-Subject: [PATCH 31/36] I2C: MIPS: lantiq: add FALC-ON i2c bus master
-
-This patch adds the driver needed to make the I2C bus work on FALC-ON SoCs.
-
-Signed-off-by: Thomas Langer <thomas.langer@lantiq.com>
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- drivers/i2c/busses/Kconfig | 10 +
- drivers/i2c/busses/Makefile | 1 +
- drivers/i2c/busses/i2c-lantiq.c | 747 +++++++++++++++++++++++++++++++++++++++
- drivers/i2c/busses/i2c-lantiq.h | 234 ++++++++++++
- 4 files changed, 992 insertions(+)
- create mode 100644 drivers/i2c/busses/i2c-lantiq.c
- create mode 100644 drivers/i2c/busses/i2c-lantiq.h
-
---- a/drivers/i2c/busses/Kconfig
-+++ b/drivers/i2c/busses/Kconfig
-@@ -757,6 +757,16 @@ config I2C_MESON
- If you say yes to this option, support will be included for the
- I2C interface on the Amlogic Meson family of SoCs.
-
-+config I2C_LANTIQ
-+ tristate "Lantiq I2C interface"
-+ depends on LANTIQ && SOC_FALCON
-+ help
-+ If you say yes to this option, support will be included for the
-+ Lantiq I2C core.
-+
-+ This driver can also be built as a module. If so, the module
-+ will be called i2c-lantiq.
-+
- config I2C_MPC
- tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
- depends on PPC
---- a/drivers/i2c/busses/Makefile
-+++ b/drivers/i2c/busses/Makefile
-@@ -72,6 +72,7 @@ obj-$(CONFIG_I2C_IMX_LPI2C) += i2c-imx-l
- obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
- obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o
- obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o
-+obj-$(CONFIG_I2C_LANTIQ) += i2c-lantiq.o
- obj-$(CONFIG_I2C_LPC2K) += i2c-lpc2k.o
- obj-$(CONFIG_I2C_MESON) += i2c-meson.o
- obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-lantiq.c
-@@ -0,0 +1,747 @@
-+
-+/*
-+ * Lantiq I2C bus adapter
-+ *
-+ * Parts based on i2c-designware.c and other i2c drivers from Linux 2.6.33
-+ *
-+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ *
-+ * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com>
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/delay.h>
-+#include <linux/slab.h> /* for kzalloc, kfree */
-+#include <linux/i2c.h>
-+#include <linux/errno.h>
-+#include <linux/completion.h>
-+#include <linux/interrupt.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/of_irq.h>
-+
-+#include <lantiq_soc.h>
-+#include "i2c-lantiq.h"
-+
-+/*
-+ * CURRENT ISSUES:
-+ * - no high speed support
-+ * - ten bit mode is not tested (no slave devices)
-+ */
-+
-+/* access macros */
-+#define i2c_r32(reg) \
-+ __raw_readl(&(priv->membase)->reg)
-+#define i2c_w32(val, reg) \
-+ __raw_writel(val, &(priv->membase)->reg)
-+#define i2c_w32_mask(clear, set, reg) \
-+ i2c_w32((i2c_r32(reg) & ~(clear)) | (set), reg)
-+
-+#define DRV_NAME "i2c-lantiq"
-+#define DRV_VERSION "1.00"
-+
-+#define LTQ_I2C_BUSY_TIMEOUT 20 /* ms */
-+
-+#ifdef DEBUG
-+#define LTQ_I2C_XFER_TIMEOUT (25*HZ)
-+#else
-+#define LTQ_I2C_XFER_TIMEOUT HZ
-+#endif
-+
-+#define LTQ_I2C_IMSC_DEFAULT_MASK (I2C_IMSC_I2C_P_INT_EN | \
-+ I2C_IMSC_I2C_ERR_INT_EN)
-+
-+#define LTQ_I2C_ARB_LOST (1 << 0)
-+#define LTQ_I2C_NACK (1 << 1)
-+#define LTQ_I2C_RX_UFL (1 << 2)
-+#define LTQ_I2C_RX_OFL (1 << 3)
-+#define LTQ_I2C_TX_UFL (1 << 4)
-+#define LTQ_I2C_TX_OFL (1 << 5)
-+
-+struct ltq_i2c {
-+ struct mutex mutex;
-+
-+
-+ /* active clock settings */
-+ unsigned int input_clock; /* clock input for i2c hardware block */
-+ unsigned int i2c_clock; /* approximated bus clock in kHz */
-+
-+ struct clk *clk_gate;
-+ struct clk *clk_input;
-+
-+
-+ /* resources (memory and interrupts) */
-+ int irq_lb; /* last burst irq */
-+
-+ struct lantiq_reg_i2c __iomem *membase; /* base of mapped registers */
-+
-+ struct i2c_adapter adap;
-+ struct device *dev;
-+
-+ struct completion cmd_complete;
-+
-+
-+ /* message transfer data */
-+ struct i2c_msg *current_msg; /* current message */
-+ int msgs_num; /* number of messages to handle */
-+ u8 *msg_buf; /* current buffer */
-+ u32 msg_buf_len; /* remaining length of current buffer */
-+ int msg_err; /* error status of the current transfer */
-+
-+
-+ /* master status codes */
-+ enum {
-+ STATUS_IDLE,
-+ STATUS_ADDR, /* address phase */
-+ STATUS_WRITE,
-+ STATUS_READ,
-+ STATUS_READ_END,
-+ STATUS_STOP
-+ } status;
-+};
-+
-+static irqreturn_t ltq_i2c_isr(int irq, void *dev_id);
-+
-+static inline void enable_burst_irq(struct ltq_i2c *priv)
-+{
-+ i2c_w32_mask(0, I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, imsc);
-+}
-+static inline void disable_burst_irq(struct ltq_i2c *priv)
-+{
-+ i2c_w32_mask(I2C_IMSC_LBREQ_INT_EN | I2C_IMSC_BREQ_INT_EN, 0, imsc);
-+}
-+
-+static void prepare_msg_send_addr(struct ltq_i2c *priv)
-+{
-+ struct i2c_msg *msg = priv->current_msg;
-+ int rd = !!(msg->flags & I2C_M_RD); /* extends to 0 or 1 */
-+ u16 addr = msg->addr;
-+
-+ /* new i2c_msg */
-+ priv->msg_buf = msg->buf;
-+ priv->msg_buf_len = msg->len;
-+ if (rd)
-+ priv->status = STATUS_READ;
-+ else
-+ priv->status = STATUS_WRITE;
-+
-+ /* send slave address */
-+ if (msg->flags & I2C_M_TEN) {
-+ i2c_w32(0xf0 | ((addr & 0x300) >> 7) | rd, txd);
-+ i2c_w32(addr & 0xff, txd);
-+ } else {
-+ i2c_w32((addr & 0x7f) << 1 | rd, txd);
-+ }
-+}
-+
-+static void ltq_i2c_set_tx_len(struct ltq_i2c *priv)
-+{
-+ struct i2c_msg *msg = priv->current_msg;
-+ int len = (msg->flags & I2C_M_TEN) ? 2 : 1;
-+
-+ pr_debug("set_tx_len %cX\n", (msg->flags & I2C_M_RD) ? 'R' : 'T');
-+
-+ priv->status = STATUS_ADDR;
-+
-+ if (!(msg->flags & I2C_M_RD))
-+ len += msg->len;
-+ else
-+ /* set maximum received packet size (before rx int!) */
-+ i2c_w32(msg->len, mrps_ctrl);
-+ i2c_w32(len, tps_ctrl);
-+ enable_burst_irq(priv);
-+}
-+
-+static int ltq_i2c_hw_set_clock(struct i2c_adapter *adap)
-+{
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+ unsigned int input_clock = clk_get_rate(priv->clk_input);
-+ u32 dec, inc = 1;
-+
-+ /* clock changed? */
-+ if (priv->input_clock == input_clock)
-+ return 0;
-+
-+ /*
-+ * this formula is only an approximation, found by the recommended
-+ * values in the "I2C Architecture Specification 1.7.1"
-+ */
-+ dec = input_clock / (priv->i2c_clock * 2);
-+ if (dec <= 6)
-+ return -ENXIO;
-+
-+ i2c_w32(0, fdiv_high_cfg);
-+ i2c_w32((inc << I2C_FDIV_CFG_INC_OFFSET) |
-+ (dec << I2C_FDIV_CFG_DEC_OFFSET),
-+ fdiv_cfg);
-+
-+ dev_info(priv->dev, "setup clocks (in %d kHz, bus %d kHz, dec=%d)\n",
-+ input_clock, priv->i2c_clock, dec);
-+
-+ priv->input_clock = input_clock;
-+ return 0;
-+}
-+
-+static int ltq_i2c_hw_init(struct i2c_adapter *adap)
-+{
-+ int ret = 0;
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+
-+ /* disable bus */
-+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
-+
-+#ifndef DEBUG
-+ /* set normal operation clock divider */
-+ i2c_w32(1 << I2C_CLC_RMC_OFFSET, clc);
-+#else
-+ /* for debugging a higher divider value! */
-+ i2c_w32(0xF0 << I2C_CLC_RMC_OFFSET, clc);
-+#endif
-+
-+ /* setup clock */
-+ ret = ltq_i2c_hw_set_clock(adap);
-+ if (ret != 0) {
-+ dev_warn(priv->dev, "invalid clock settings\n");
-+ return ret;
-+ }
-+
-+ /* configure fifo */
-+ i2c_w32(I2C_FIFO_CFG_TXFC | /* tx fifo as flow controller */
-+ I2C_FIFO_CFG_RXFC | /* rx fifo as flow controller */
-+ I2C_FIFO_CFG_TXFA_TXFA2 | /* tx fifo 4-byte aligned */
-+ I2C_FIFO_CFG_RXFA_RXFA2 | /* rx fifo 4-byte aligned */
-+ I2C_FIFO_CFG_TXBS_TXBS0 | /* tx fifo burst size is 1 word */
-+ I2C_FIFO_CFG_RXBS_RXBS0, /* rx fifo burst size is 1 word */
-+ fifo_cfg);
-+
-+ /* configure address */
-+ i2c_w32(I2C_ADDR_CFG_SOPE_EN | /* generate stop when no more data in
-+ the fifo */
-+ I2C_ADDR_CFG_SONA_EN | /* generate stop when NA received */
-+ I2C_ADDR_CFG_MnS_EN | /* we are master device */
-+ 0, /* our slave address (not used!) */
-+ addr_cfg);
-+
-+ /* enable bus */
-+ i2c_w32_mask(0, I2C_RUN_CTRL_RUN_EN, run_ctrl);
-+
-+ return 0;
-+}
-+
-+static int ltq_i2c_wait_bus_not_busy(struct ltq_i2c *priv)
-+{
-+ unsigned long timeout;
-+
-+ timeout = jiffies + msecs_to_jiffies(LTQ_I2C_BUSY_TIMEOUT);
-+
-+ do {
-+ u32 stat = i2c_r32(bus_stat);
-+
-+ if ((stat & I2C_BUS_STAT_BS_MASK) == I2C_BUS_STAT_BS_FREE)
-+ return 0;
-+
-+ cond_resched();
-+ } while (!time_after_eq(jiffies, timeout));
-+
-+ dev_err(priv->dev, "timeout waiting for bus ready\n");
-+ return -ETIMEDOUT;
-+}
-+
-+static void ltq_i2c_tx(struct ltq_i2c *priv, int last)
-+{
-+ if (priv->msg_buf_len && priv->msg_buf) {
-+ i2c_w32(*priv->msg_buf, txd);
-+
-+ if (--priv->msg_buf_len)
-+ priv->msg_buf++;
-+ else
-+ priv->msg_buf = NULL;
-+ } else {
-+ last = 1;
-+ }
-+
-+ if (last)
-+ disable_burst_irq(priv);
-+}
-+
-+static void ltq_i2c_rx(struct ltq_i2c *priv, int last)
-+{
-+ u32 fifo_stat, timeout;
-+ if (priv->msg_buf_len && priv->msg_buf) {
-+ timeout = 5000000;
-+ do {
-+ fifo_stat = i2c_r32(ffs_stat);
-+ } while (!fifo_stat && --timeout);
-+ if (!timeout) {
-+ last = 1;
-+ pr_debug("\nrx timeout\n");
-+ goto err;
-+ }
-+ while (fifo_stat) {
-+ *priv->msg_buf = i2c_r32(rxd);
-+ if (--priv->msg_buf_len) {
-+ priv->msg_buf++;
-+ } else {
-+ priv->msg_buf = NULL;
-+ last = 1;
-+ break;
-+ }
-+ /*
-+ * do not read more than burst size, otherwise no "last
-+ * burst" is generated and the transaction is blocked!
-+ */
-+ fifo_stat = 0;
-+ }
-+ } else {
-+ last = 1;
-+ }
-+err:
-+ if (last) {
-+ disable_burst_irq(priv);
-+
-+ if (priv->status == STATUS_READ_END) {
-+ /*
-+ * do the STATUS_STOP and complete() here, as sometimes
-+ * the tx_end is already seen before this is finished
-+ */
-+ priv->status = STATUS_STOP;
-+ complete(&priv->cmd_complete);
-+ } else {
-+ i2c_w32(I2C_ENDD_CTRL_SETEND, endd_ctrl);
-+ priv->status = STATUS_READ_END;
-+ }
-+ }
-+}
-+
-+static void ltq_i2c_xfer_init(struct ltq_i2c *priv)
-+{
-+ /* enable interrupts */
-+ i2c_w32(LTQ_I2C_IMSC_DEFAULT_MASK, imsc);
-+
-+ /* trigger transfer of first msg */
-+ ltq_i2c_set_tx_len(priv);
-+}
-+
-+static void dump_msgs(struct i2c_msg msgs[], int num, int rx)
-+{
-+#if defined(DEBUG)
-+ int i, j;
-+ pr_debug("Messages %d %s\n", num, rx ? "out" : "in");
-+ for (i = 0; i < num; i++) {
-+ pr_debug("%2d %cX Msg(%d) addr=0x%X: ", i,
-+ (msgs[i].flags & I2C_M_RD) ? 'R' : 'T',
-+ msgs[i].len, msgs[i].addr);
-+ if (!(msgs[i].flags & I2C_M_RD) || rx) {
-+ for (j = 0; j < msgs[i].len; j++)
-+ pr_debug("%02X ", msgs[i].buf[j]);
-+ }
-+ pr_debug("\n");
-+ }
-+#endif
-+}
-+
-+static void ltq_i2c_release_bus(struct ltq_i2c *priv)
-+{
-+ if ((i2c_r32(bus_stat) & I2C_BUS_STAT_BS_MASK) == I2C_BUS_STAT_BS_BM)
-+ i2c_w32(I2C_ENDD_CTRL_SETEND, endd_ctrl);
-+}
-+
-+static int ltq_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
-+ int num)
-+{
-+ struct ltq_i2c *priv = i2c_get_adapdata(adap);
-+ int ret;
-+
-+ dev_dbg(priv->dev, "xfer %u messages\n", num);
-+ dump_msgs(msgs, num, 0);
-+
-+ mutex_lock(&priv->mutex);
-+
-+ init_completion(&priv->cmd_complete);
-+ priv->current_msg = msgs;
-+ priv->msgs_num = num;
-+ priv->msg_err = 0;
-+ priv->status = STATUS_IDLE;
-+
-+ /* wait for the bus to become ready */
-+ ret = ltq_i2c_wait_bus_not_busy(priv);
-+ if (ret)
-+ goto done;
-+
-+ while (priv->msgs_num) {
-+ /* start the transfers */
-+ ltq_i2c_xfer_init(priv);
-+
-+ /* wait for transfers to complete */
-+ ret = wait_for_completion_interruptible_timeout(
-+ &priv->cmd_complete, LTQ_I2C_XFER_TIMEOUT);
-+ if (ret == 0) {
-+ dev_err(priv->dev, "controller timed out\n");
-+ ltq_i2c_hw_init(adap);
-+ ret = -ETIMEDOUT;
-+ goto done;
-+ } else if (ret < 0)
-+ goto done;
-+
-+ if (priv->msg_err) {
-+ if (priv->msg_err & LTQ_I2C_NACK)
-+ ret = -ENXIO;
-+ else
-+ ret = -EREMOTEIO;
-+ goto done;
-+ }
-+ if (--priv->msgs_num)
-+ priv->current_msg++;
-+ }
-+ /* no error? */
-+ ret = num;
-+
-+done:
-+ ltq_i2c_release_bus(priv);
-+
-+ mutex_unlock(&priv->mutex);
-+
-+ if (ret >= 0)
-+ dump_msgs(msgs, num, 1);
-+
-+ pr_debug("XFER ret %d\n", ret);
-+ return ret;
-+}
-+
-+static irqreturn_t ltq_i2c_isr_burst(int irq, void *dev_id)
-+{
-+ struct ltq_i2c *priv = dev_id;
-+ struct i2c_msg *msg = priv->current_msg;
-+ int last = (irq == priv->irq_lb);
-+
-+ if (last)
-+ pr_debug("LB ");
-+ else
-+ pr_debug("B ");
-+
-+ if (msg->flags & I2C_M_RD) {
-+ switch (priv->status) {
-+ case STATUS_ADDR:
-+ pr_debug("X");
-+ prepare_msg_send_addr(priv);
-+ disable_burst_irq(priv);
-+ break;
-+ case STATUS_READ:
-+ case STATUS_READ_END:
-+ pr_debug("R");
-+ ltq_i2c_rx(priv, last);
-+ break;
-+ default:
-+ disable_burst_irq(priv);
-+ pr_warn("Status R %d\n", priv->status);
-+ break;
-+ }
-+ } else {
-+ switch (priv->status) {
-+ case STATUS_ADDR:
-+ pr_debug("x");
-+ prepare_msg_send_addr(priv);
-+ break;
-+ case STATUS_WRITE:
-+ pr_debug("w");
-+ ltq_i2c_tx(priv, last);
-+ break;
-+ default:
-+ disable_burst_irq(priv);
-+ pr_warn("Status W %d\n", priv->status);
-+ break;
-+ }
-+ }
-+
-+ i2c_w32(I2C_ICR_BREQ_INT_CLR | I2C_ICR_LBREQ_INT_CLR, icr);
-+ return IRQ_HANDLED;
-+}
-+
-+static void ltq_i2c_isr_prot(struct ltq_i2c *priv)
-+{
-+ u32 i_pro = i2c_r32(p_irqss);
-+
-+ pr_debug("i2c-p");
-+
-+ /* not acknowledge */
-+ if (i_pro & I2C_P_IRQSS_NACK) {
-+ priv->msg_err |= LTQ_I2C_NACK;
-+ pr_debug(" nack");
-+ }
-+
-+ /* arbitration lost */
-+ if (i_pro & I2C_P_IRQSS_AL) {
-+ priv->msg_err |= LTQ_I2C_ARB_LOST;
-+ pr_debug(" arb-lost");
-+ }
-+ /* tx -> rx switch */
-+ if (i_pro & I2C_P_IRQSS_RX)
-+ pr_debug(" rx");
-+
-+ /* tx end */
-+ if (i_pro & I2C_P_IRQSS_TX_END)
-+ pr_debug(" txend");
-+ pr_debug("\n");
-+
-+ if (!priv->msg_err) {
-+ /* tx -> rx switch */
-+ if (i_pro & I2C_P_IRQSS_RX) {
-+ priv->status = STATUS_READ;
-+ enable_burst_irq(priv);
-+ }
-+ if (i_pro & I2C_P_IRQSS_TX_END) {
-+ if (priv->status == STATUS_READ)
-+ priv->status = STATUS_READ_END;
-+ else {
-+ disable_burst_irq(priv);
-+ priv->status = STATUS_STOP;
-+ }
-+ }
-+ }
-+
-+ i2c_w32(i_pro, p_irqsc);
-+}
-+
-+static irqreturn_t ltq_i2c_isr(int irq, void *dev_id)
-+{
-+ u32 i_raw, i_err = 0;
-+ struct ltq_i2c *priv = dev_id;
-+
-+ i_raw = i2c_r32(mis);
-+ pr_debug("i_raw 0x%08X\n", i_raw);
-+
-+ /* error interrupt */
-+ if (i_raw & I2C_RIS_I2C_ERR_INT_INTOCC) {
-+ i_err = i2c_r32(err_irqss);
-+ pr_debug("i_err 0x%08X bus_stat 0x%04X\n",
-+ i_err, i2c_r32(bus_stat));
-+
-+ /* tx fifo overflow (8) */
-+ if (i_err & I2C_ERR_IRQSS_TXF_OFL)
-+ priv->msg_err |= LTQ_I2C_TX_OFL;
-+
-+ /* tx fifo underflow (4) */
-+ if (i_err & I2C_ERR_IRQSS_TXF_UFL)
-+ priv->msg_err |= LTQ_I2C_TX_UFL;
-+
-+ /* rx fifo overflow (2) */
-+ if (i_err & I2C_ERR_IRQSS_RXF_OFL)
-+ priv->msg_err |= LTQ_I2C_RX_OFL;
-+
-+ /* rx fifo underflow (1) */
-+ if (i_err & I2C_ERR_IRQSS_RXF_UFL)
-+ priv->msg_err |= LTQ_I2C_RX_UFL;
-+
-+ i2c_w32(i_err, err_irqsc);
-+ }
-+
-+ /* protocol interrupt */
-+ if (i_raw & I2C_RIS_I2C_P_INT_INTOCC)
-+ ltq_i2c_isr_prot(priv);
-+
-+ if ((priv->msg_err) || (priv->status == STATUS_STOP))
-+ complete(&priv->cmd_complete);
-+
-+ return IRQ_HANDLED;
-+}
-+
-+static u32 ltq_i2c_functionality(struct i2c_adapter *adap)
-+{
-+ return I2C_FUNC_I2C |
-+ I2C_FUNC_10BIT_ADDR |
-+ I2C_FUNC_SMBUS_EMUL;
-+}
-+
-+static struct i2c_algorithm ltq_i2c_algorithm = {
-+ .master_xfer = ltq_i2c_xfer,
-+ .functionality = ltq_i2c_functionality,
-+};
-+
-+static int ltq_i2c_probe(struct platform_device *pdev)
-+{
-+ struct device_node *node = pdev->dev.of_node;
-+ struct ltq_i2c *priv;
-+ struct i2c_adapter *adap;
-+ struct resource *mmres, irqres[4];
-+ int ret = 0;
-+
-+ dev_dbg(&pdev->dev, "probing\n");
-+
-+ mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+ ret = of_irq_to_resource_table(node, irqres, 4);
-+ if (!mmres || (ret != 4)) {
-+ dev_err(&pdev->dev, "no resources\n");
-+ return -ENODEV;
-+ }
-+
-+ /* allocate private data */
-+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
-+ if (!priv) {
-+ dev_err(&pdev->dev, "can't allocate private data\n");
-+ return -ENOMEM;
-+ }
-+
-+ adap = &priv->adap;
-+ i2c_set_adapdata(adap, priv);
-+ adap->owner = THIS_MODULE;
-+ adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
-+ strlcpy(adap->name, DRV_NAME "-adapter", sizeof(adap->name));
-+ adap->algo = <q_i2c_algorithm;
-+ adap->dev.parent = &pdev->dev;
-+ adap->dev.of_node = pdev->dev.of_node;
-+
-+ if (of_property_read_u32(node, "clock-frequency", &priv->i2c_clock)) {
-+ dev_warn(&pdev->dev, "No I2C speed selected, using 100kHz\n");
-+ priv->i2c_clock = 100000;
-+ }
-+
-+ init_completion(&priv->cmd_complete);
-+ mutex_init(&priv->mutex);
-+
-+ priv->membase = devm_ioremap_resource(&pdev->dev, mmres);
-+ if (IS_ERR(priv->membase))
-+ return PTR_ERR(priv->membase);
-+
-+ priv->dev = &pdev->dev;
-+ priv->irq_lb = irqres[0].start;
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[0].start, ltq_i2c_isr_burst,
-+ 0x0, "i2c lb", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get last burst IRQ %d\n",
-+ irqres[0].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[1].start, ltq_i2c_isr_burst,
-+ 0x0, "i2c b", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get burst IRQ %d\n",
-+ irqres[1].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[2].start, ltq_i2c_isr,
-+ 0x0, "i2c err", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get error IRQ %d\n",
-+ irqres[2].start);
-+ return -ENODEV;
-+ }
-+
-+ ret = devm_request_irq(&pdev->dev, irqres[3].start, ltq_i2c_isr,
-+ 0x0, "i2c p", priv);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't get protocol IRQ %d\n",
-+ irqres[3].start);
-+ return -ENODEV;
-+ }
-+
-+ dev_dbg(&pdev->dev, "mapped io-space to %p\n", priv->membase);
-+ dev_dbg(&pdev->dev, "use IRQs %d, %d, %d, %d\n", irqres[0].start,
-+ irqres[1].start, irqres[2].start, irqres[3].start);
-+
-+ priv->clk_gate = devm_clk_get(&pdev->dev, NULL);
-+ if (IS_ERR(priv->clk_gate)) {
-+ dev_err(&pdev->dev, "failed to get i2c clk\n");
-+ return -ENOENT;
-+ }
-+
-+ /* this is a static clock, which has no refcounting */
-+ priv->clk_input = clk_get_fpi();
-+ if (IS_ERR(priv->clk_input)) {
-+ dev_err(&pdev->dev, "failed to get fpi clk\n");
-+ return -ENOENT;
-+ }
-+
-+ clk_activate(priv->clk_gate);
-+
-+ /* add our adapter to the i2c stack */
-+ ret = i2c_add_numbered_adapter(adap);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't register I2C adapter\n");
-+ goto out;
-+ }
-+
-+ platform_set_drvdata(pdev, priv);
-+ i2c_set_adapdata(adap, priv);
-+
-+ /* print module version information */
-+ dev_dbg(&pdev->dev, "module id=%u revision=%u\n",
-+ (i2c_r32(id) & I2C_ID_ID_MASK) >> I2C_ID_ID_OFFSET,
-+ (i2c_r32(id) & I2C_ID_REV_MASK) >> I2C_ID_REV_OFFSET);
-+
-+ /* initialize HW */
-+ ret = ltq_i2c_hw_init(adap);
-+ if (ret) {
-+ dev_err(&pdev->dev, "can't configure adapter\n");
-+ i2c_del_adapter(adap);
-+ platform_set_drvdata(pdev, NULL);
-+ goto out;
-+ } else {
-+ dev_info(&pdev->dev, "version %s\n", DRV_VERSION);
-+ }
-+
-+out:
-+ /* if init failed, we need to deactivate the clock gate */
-+ if (ret)
-+ clk_deactivate(priv->clk_gate);
-+
-+ return ret;
-+}
-+
-+static int ltq_i2c_remove(struct platform_device *pdev)
-+{
-+ struct ltq_i2c *priv = platform_get_drvdata(pdev);
-+
-+ /* disable bus */
-+ i2c_w32_mask(I2C_RUN_CTRL_RUN_EN, 0, run_ctrl);
-+
-+ /* power down the core */
-+ clk_deactivate(priv->clk_gate);
-+
-+ /* remove driver */
-+ i2c_del_adapter(&priv->adap);
-+ kfree(priv);
-+
-+ dev_dbg(&pdev->dev, "removed\n");
-+ platform_set_drvdata(pdev, NULL);
-+
-+ return 0;
-+}
-+static const struct of_device_id ltq_i2c_match[] = {
-+ { .compatible = "lantiq,lantiq-i2c" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ltq_i2c_match);
-+
-+static struct platform_driver ltq_i2c_driver = {
-+ .probe = ltq_i2c_probe,
-+ .remove = ltq_i2c_remove,
-+ .driver = {
-+ .name = DRV_NAME,
-+ .owner = THIS_MODULE,
-+ .of_match_table = ltq_i2c_match,
-+ },
-+};
-+
-+module_platform_driver(ltq_i2c_driver);
-+
-+MODULE_DESCRIPTION("Lantiq I2C bus adapter");
-+MODULE_AUTHOR("Thomas Langer <thomas.langer@lantiq.com>");
-+MODULE_ALIAS("platform:" DRV_NAME);
-+MODULE_LICENSE("GPL");
-+MODULE_VERSION(DRV_VERSION);
---- /dev/null
-+++ b/drivers/i2c/busses/i2c-lantiq.h
-@@ -0,0 +1,234 @@
-+#ifndef I2C_LANTIQ_H
-+#define I2C_LANTIQ_H
-+
-+/* I2C register structure */
-+struct lantiq_reg_i2c {
-+ /* I2C Kernel Clock Control Register */
-+ unsigned int clc; /* 0x00000000 */
-+ /* Reserved */
-+ unsigned int res_0; /* 0x00000004 */
-+ /* I2C Identification Register */
-+ unsigned int id; /* 0x00000008 */
-+ /* Reserved */
-+ unsigned int res_1; /* 0x0000000C */
-+ /*
-+ * I2C RUN Control Register
-+ * This register enables and disables the I2C peripheral. Before
-+ * enabling, the I2C has to be configured properly. After enabling
-+ * no configuration is possible
-+ */
-+ unsigned int run_ctrl; /* 0x00000010 */
-+ /*
-+ * I2C End Data Control Register
-+ * This register is used to either turn around the data transmission
-+ * direction or to address another slave without sending a stop
-+ * condition. Also the software can stop the slave-transmitter by
-+ * sending a not-accolade when working as master-receiver or even
-+ * stop data transmission immediately when operating as
-+ * master-transmitter. The writing to the bits of this control
-+ * register is only effective when in MASTER RECEIVES BYTES, MASTER
-+ * TRANSMITS BYTES, MASTER RESTART or SLAVE RECEIVE BYTES state
-+ */
-+ unsigned int endd_ctrl; /* 0x00000014 */
-+ /*
-+ * I2C Fractional Divider Configuration Register
-+ * These register is used to program the fractional divider of the I2C
-+ * bus. Before the peripheral is switched on by setting the RUN-bit the
-+ * two (fixed) values for the two operating frequencies are programmed
-+ * into these (configuration) registers. The Register FDIV_HIGH_CFG has
-+ * the same layout as I2C_FDIV_CFG.
-+ */
-+ unsigned int fdiv_cfg; /* 0x00000018 */
-+ /*
-+ * I2C Fractional Divider (highspeed mode) Configuration Register
-+ * These register is used to program the fractional divider of the I2C
-+ * bus. Before the peripheral is switched on by setting the RUN-bit the
-+ * two (fixed) values for the two operating frequencies are programmed
-+ * into these (configuration) registers. The Register FDIV_CFG has the
-+ * same layout as I2C_FDIV_CFG.
-+ */
-+ unsigned int fdiv_high_cfg; /* 0x0000001C */
-+ /* I2C Address Configuration Register */
-+ unsigned int addr_cfg; /* 0x00000020 */
-+ /* I2C Bus Status Register
-+ * This register gives a status information of the I2C. This additional
-+ * information can be used by the software to start proper actions.
-+ */
-+ unsigned int bus_stat; /* 0x00000024 */
-+ /* I2C FIFO Configuration Register */
-+ unsigned int fifo_cfg; /* 0x00000028 */
-+ /* I2C Maximum Received Packet Size Register */
-+ unsigned int mrps_ctrl; /* 0x0000002C */
-+ /* I2C Received Packet Size Status Register */
-+ unsigned int rps_stat; /* 0x00000030 */
-+ /* I2C Transmit Packet Size Register */
-+ unsigned int tps_ctrl; /* 0x00000034 */
-+ /* I2C Filled FIFO Stages Status Register */
-+ unsigned int ffs_stat; /* 0x00000038 */
-+ /* Reserved */
-+ unsigned int res_2; /* 0x0000003C */
-+ /* I2C Timing Configuration Register */
-+ unsigned int tim_cfg; /* 0x00000040 */
-+ /* Reserved */
-+ unsigned int res_3[7]; /* 0x00000044 */
-+ /* I2C Error Interrupt Request Source Mask Register */
-+ unsigned int err_irqsm; /* 0x00000060 */
-+ /* I2C Error Interrupt Request Source Status Register */
-+ unsigned int err_irqss; /* 0x00000064 */
-+ /* I2C Error Interrupt Request Source Clear Register */
-+ unsigned int err_irqsc; /* 0x00000068 */
-+ /* Reserved */
-+ unsigned int res_4; /* 0x0000006C */
-+ /* I2C Protocol Interrupt Request Source Mask Register */
-+ unsigned int p_irqsm; /* 0x00000070 */
-+ /* I2C Protocol Interrupt Request Source Status Register */
-+ unsigned int p_irqss; /* 0x00000074 */
-+ /* I2C Protocol Interrupt Request Source Clear Register */
-+ unsigned int p_irqsc; /* 0x00000078 */
-+ /* Reserved */
-+ unsigned int res_5; /* 0x0000007C */
-+ /* I2C Raw Interrupt Status Register */
-+ unsigned int ris; /* 0x00000080 */
-+ /* I2C Interrupt Mask Control Register */
-+ unsigned int imsc; /* 0x00000084 */
-+ /* I2C Masked Interrupt Status Register */
-+ unsigned int mis; /* 0x00000088 */
-+ /* I2C Interrupt Clear Register */
-+ unsigned int icr; /* 0x0000008C */
-+ /* I2C Interrupt Set Register */
-+ unsigned int isr; /* 0x00000090 */
-+ /* I2C DMA Enable Register */
-+ unsigned int dmae; /* 0x00000094 */
-+ /* Reserved */
-+ unsigned int res_6[8154]; /* 0x00000098 */
-+ /* I2C Transmit Data Register */
-+ unsigned int txd; /* 0x00008000 */
-+ /* Reserved */
-+ unsigned int res_7[4095]; /* 0x00008004 */
-+ /* I2C Receive Data Register */
-+ unsigned int rxd; /* 0x0000C000 */
-+ /* Reserved */
-+ unsigned int res_8[4095]; /* 0x0000C004 */
-+};
-+
-+/*
-+ * Clock Divider for Normal Run Mode
-+ * Max 8-bit divider value. IF RMC is 0 the module is disabled. Note: As long
-+ * as the new divider value RMC is not valid, the register returns 0x0000 00xx
-+ * on reading.
-+ */
-+#define I2C_CLC_RMC_MASK 0x0000FF00
-+/* field offset */
-+#define I2C_CLC_RMC_OFFSET 8
-+
-+/* Fields of "I2C Identification Register" */
-+/* Module ID */
-+#define I2C_ID_ID_MASK 0x0000FF00
-+/* field offset */
-+#define I2C_ID_ID_OFFSET 8
-+/* Revision */
-+#define I2C_ID_REV_MASK 0x000000FF
-+/* field offset */
-+#define I2C_ID_REV_OFFSET 0
-+
-+/* Fields of "I2C Interrupt Mask Control Register" */
-+/* Enable */
-+#define I2C_IMSC_BREQ_INT_EN 0x00000008
-+/* Enable */
-+#define I2C_IMSC_LBREQ_INT_EN 0x00000004
-+
-+/* Fields of "I2C Fractional Divider Configuration Register" */
-+/* field offset */
-+#define I2C_FDIV_CFG_INC_OFFSET 16
-+
-+/* Fields of "I2C Interrupt Mask Control Register" */
-+/* Enable */
-+#define I2C_IMSC_I2C_P_INT_EN 0x00000020
-+/* Enable */
-+#define I2C_IMSC_I2C_ERR_INT_EN 0x00000010
-+
-+/* Fields of "I2C Error Interrupt Request Source Status Register" */
-+/* TXF_OFL */
-+#define I2C_ERR_IRQSS_TXF_OFL 0x00000008
-+/* TXF_UFL */
-+#define I2C_ERR_IRQSS_TXF_UFL 0x00000004
-+/* RXF_OFL */
-+#define I2C_ERR_IRQSS_RXF_OFL 0x00000002
-+/* RXF_UFL */
-+#define I2C_ERR_IRQSS_RXF_UFL 0x00000001
-+
-+/* Fields of "I2C Raw Interrupt Status Register" */
-+/* Read: Interrupt occurred. */
-+#define I2C_RIS_I2C_ERR_INT_INTOCC 0x00000010
-+/* Read: Interrupt occurred. */
-+#define I2C_RIS_I2C_P_INT_INTOCC 0x00000020
-+
-+/* Fields of "I2C FIFO Configuration Register" */
-+/* TX FIFO Flow Control */
-+#define I2C_FIFO_CFG_TXFC 0x00020000
-+/* RX FIFO Flow Control */
-+#define I2C_FIFO_CFG_RXFC 0x00010000
-+/* Word aligned (character alignment of four characters) */
-+#define I2C_FIFO_CFG_TXFA_TXFA2 0x00002000
-+/* Word aligned (character alignment of four characters) */
-+#define I2C_FIFO_CFG_RXFA_RXFA2 0x00000200
-+/* 1 word */
-+#define I2C_FIFO_CFG_TXBS_TXBS0 0x00000000
-+
-+/* Fields of "I2C FIFO Configuration Register" */
-+/* 1 word */
-+#define I2C_FIFO_CFG_RXBS_RXBS0 0x00000000
-+/* Stop on Packet End Enable */
-+#define I2C_ADDR_CFG_SOPE_EN 0x00200000
-+/* Stop on Not Acknowledge Enable */
-+#define I2C_ADDR_CFG_SONA_EN 0x00100000
-+/* Enable */
-+#define I2C_ADDR_CFG_MnS_EN 0x00080000
-+
-+/* Fields of "I2C Interrupt Clear Register" */
-+/* Clear */
-+#define I2C_ICR_BREQ_INT_CLR 0x00000008
-+/* Clear */
-+#define I2C_ICR_LBREQ_INT_CLR 0x00000004
-+
-+/* Fields of "I2C Fractional Divider Configuration Register" */
-+/* field offset */
-+#define I2C_FDIV_CFG_DEC_OFFSET 0
-+
-+/* Fields of "I2C Bus Status Register" */
-+/* Bus Status */
-+#define I2C_BUS_STAT_BS_MASK 0x00000003
-+/* Read from I2C Bus. */
-+#define I2C_BUS_STAT_RNW_READ 0x00000004
-+/* I2C Bus is free. */
-+#define I2C_BUS_STAT_BS_FREE 0x00000000
-+/*
-+ * The device is working as master and has claimed the control on the
-+ * I2C-bus (busy master).
-+ */
-+#define I2C_BUS_STAT_BS_BM 0x00000002
-+
-+/* Fields of "I2C RUN Control Register" */
-+/* Enable */
-+#define I2C_RUN_CTRL_RUN_EN 0x00000001
-+
-+/* Fields of "I2C End Data Control Register" */
-+/*
-+ * Set End of Transmission
-+ * Note:Do not write '1' to this bit when bus is free. This will cause an
-+ * abort after the first byte when a new transfer is started.
-+ */
-+#define I2C_ENDD_CTRL_SETEND 0x00000002
-+
-+/* Fields of "I2C Protocol Interrupt Request Source Status Register" */
-+/* NACK */
-+#define I2C_P_IRQSS_NACK 0x00000010
-+/* AL */
-+#define I2C_P_IRQSS_AL 0x00000008
-+/* RX */
-+#define I2C_P_IRQSS_RX 0x00000040
-+/* TX_END */
-+#define I2C_P_IRQSS_TX_END 0x00000020
-+
-+
-+#endif /* I2C_LANTIQ_H */
+++ /dev/null
-From f8c5db89e793a4bc6c1e87bd7b3a5cec16b75bc3 Mon Sep 17 00:00:00 2001
-From: John Crispin <blogic@openwrt.org>
-Date: Wed, 10 Sep 2014 22:42:14 +0200
-Subject: [PATCH 35/36] owrt: lantiq: wifi and ethernet eeprom handling
-
-Signed-off-by: John Crispin <blogic@openwrt.org>
----
- .../mips/include/asm/mach-lantiq/xway/lantiq_soc.h | 3 +
- arch/mips/lantiq/xway/Makefile | 3 +
- arch/mips/lantiq/xway/ath5k_eep.c | 136 +++++++++++++++++++++
- arch/mips/lantiq/xway/eth_mac.c | 25 ++++
- drivers/net/ethernet/lantiq_etop.c | 6 +-
- 5 files changed, 172 insertions(+), 1 deletion(-)
- create mode 100644 arch/mips/lantiq/xway/ath5k_eep.c
- create mode 100644 arch/mips/lantiq/xway/eth_mac.c
-
---- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
-+++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h
-@@ -102,5 +102,8 @@ int xrx200_gphy_boot(struct device *dev,
- extern void ltq_pmu_enable(unsigned int module);
- extern void ltq_pmu_disable(unsigned int module);
-
-+/* allow the ethernet driver to load a flash mapped mac addr */
-+const u8* ltq_get_eth_mac(void);
-+
- #endif /* CONFIG_SOC_TYPE_XWAY */
- #endif /* _LTQ_XWAY_H__ */
---- a/arch/mips/lantiq/xway/Makefile
-+++ b/arch/mips/lantiq/xway/Makefile
-@@ -8,3 +8,6 @@ obj-y += timer.o
- endif
-
- obj-y += vmmc.o
-+
-+obj-y += eth_mac.o
-+obj-$(CONFIG_PCI) += ath5k_eep.o
---- /dev/null
-+++ b/arch/mips/lantiq/xway/ath5k_eep.c
-@@ -0,0 +1,136 @@
-+/*
-+ * Copyright (C) 2011 Luca Olivetti <luca@ventoso.org>
-+ * Copyright (C) 2011 John Crispin <blogic@openwrt.org>
-+ * Copyright (C) 2011 Andrej Vlašić <andrej.vlasic0@gmail.com>
-+ * Copyright (C) 2013 Álvaro Fernández Rojas <noltari@gmail.com>
-+ * Copyright (C) 2013 Daniel Gimpelevich <daniel@gimpelevich.san-francisco.ca.us>
-+ * Copyright (C) 2015 Vittorio Gambaletta <openwrt@vittgam.net>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/platform_device.h>
-+#include <linux/etherdevice.h>
-+#include <linux/ath5k_platform.h>
-+#include <linux/pci.h>
-+#include <linux/err.h>
-+#include <linux/mtd/mtd.h>
-+#include <lantiq_soc.h>
-+
-+extern int (*ltq_pci_plat_dev_init)(struct pci_dev *dev);
-+struct ath5k_platform_data ath5k_pdata;
-+static u8 athxk_eeprom_mac[6];
-+
-+static int ath5k_pci_plat_dev_init(struct pci_dev *dev)
-+{
-+ dev->dev.platform_data = &ath5k_pdata;
-+ return 0;
-+}
-+
-+static int ath5k_eep_load;
-+int __init of_ath5k_eeprom_probe(struct platform_device *pdev)
-+{
-+ struct device_node *np = pdev->dev.of_node, *mtd_np = NULL;
-+ int mac_offset;
-+ u32 mac_inc = 0;
-+ int i;
-+ struct mtd_info *the_mtd;
-+ size_t flash_readlen;
-+ const __be32 *list;
-+ const char *part;
-+ phandle phandle;
-+
-+ list = of_get_property(np, "ath,eep-flash", &i);
-+ if (!list || (i != (2 * sizeof(*list))))
-+ return -ENODEV;
-+
-+ phandle = be32_to_cpup(list++);
-+ if (phandle)
-+ mtd_np = of_find_node_by_phandle(phandle);
-+
-+ if (!mtd_np)
-+ return -ENODEV;
-+
-+ part = of_get_property(mtd_np, "label", NULL);
-+ if (!part)
-+ part = mtd_np->name;
-+
-+ the_mtd = get_mtd_device_nm(part);
-+ if (IS_ERR(the_mtd))
-+ return -ENODEV;
-+
-+ ath5k_pdata.eeprom_data = kmalloc(ATH5K_PLAT_EEP_MAX_WORDS<<1, GFP_KERNEL);
-+
-+ i = mtd_read(the_mtd, be32_to_cpup(list), ATH5K_PLAT_EEP_MAX_WORDS << 1,
-+ &flash_readlen, (void *) ath5k_pdata.eeprom_data);
-+
-+ if (!of_property_read_u32(np, "ath,mac-offset", &mac_offset)) {
-+ size_t mac_readlen;
-+ mtd_read(the_mtd, mac_offset, 6, &mac_readlen,
-+ (void *) athxk_eeprom_mac);
-+ }
-+ put_mtd_device(the_mtd);
-+
-+ if (((ATH5K_PLAT_EEP_MAX_WORDS<<1) != flash_readlen) || i) {
-+ dev_err(&pdev->dev, "failed to load eeprom from mtd\n");
-+ return -ENODEV;
-+ }
-+
-+ if (of_find_property(np, "ath,eep-swap", NULL))
-+ for (i = 0; i < ATH5K_PLAT_EEP_MAX_WORDS; i++)
-+ ath5k_pdata.eeprom_data[i] = swab16(ath5k_pdata.eeprom_data[i]);
-+
-+ if (!is_valid_ether_addr(athxk_eeprom_mac) && ltq_get_eth_mac())
-+ ether_addr_copy(athxk_eeprom_mac, ltq_get_eth_mac());
-+
-+ if (!is_valid_ether_addr(athxk_eeprom_mac)) {
-+ dev_warn(&pdev->dev, "using random mac\n");
-+ eth_random_addr(athxk_eeprom_mac);
-+ }
-+
-+ if (!of_property_read_u32(np, "ath,mac-increment", &mac_inc))
-+ athxk_eeprom_mac[5] += mac_inc;
-+
-+ ath5k_pdata.macaddr = athxk_eeprom_mac;
-+ ltq_pci_plat_dev_init = ath5k_pci_plat_dev_init;
-+
-+ dev_info(&pdev->dev, "loaded ath5k eeprom\n");
-+
-+ return 0;
-+}
-+
-+static struct of_device_id ath5k_eeprom_ids[] = {
-+ { .compatible = "ath5k,eeprom" },
-+ { }
-+};
-+
-+static struct platform_driver ath5k_eeprom_driver = {
-+ .driver = {
-+ .name = "ath5k,eeprom",
-+ .owner = THIS_MODULE,
-+ .of_match_table = of_match_ptr(ath5k_eeprom_ids),
-+ },
-+};
-+
-+static int __init of_ath5k_eeprom_init(void)
-+{
-+ int ret = platform_driver_probe(&ath5k_eeprom_driver, of_ath5k_eeprom_probe);
-+
-+ if (ret)
-+ ath5k_eep_load = 1;
-+
-+ return ret;
-+}
-+
-+static int __init of_ath5k_eeprom_init_late(void)
-+{
-+ if (!ath5k_eep_load)
-+ return 0;
-+
-+ return platform_driver_probe(&ath5k_eeprom_driver, of_ath5k_eeprom_probe);
-+}
-+late_initcall(of_ath5k_eeprom_init_late);
-+subsys_initcall(of_ath5k_eeprom_init);
---- /dev/null
-+++ b/arch/mips/lantiq/xway/eth_mac.c
-@@ -0,0 +1,25 @@
-+/*
-+ * Copyright (C) 2012 John Crispin <blogic@openwrt.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms of the GNU General Public License version 2 as published
-+ * by the Free Software Foundation.
-+ */
-+
-+#include <linux/init.h>
-+#include <linux/if_ether.h>
-+
-+static u8 eth_mac[6];
-+static int eth_mac_set;
-+
-+const u8* ltq_get_eth_mac(void)
-+{
-+ return eth_mac;
-+}
-+
-+static int __init setup_ethaddr(char *str)
-+{
-+ eth_mac_set = mac_pton(str, eth_mac);
-+ return !eth_mac_set;
-+}
-+early_param("ethaddr", setup_ethaddr);
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -757,7 +757,11 @@ ltq_etop_init(struct net_device *dev)
- if (err)
- goto err_hw;
-
-- memcpy(&mac, &priv->pldata->mac, sizeof(struct sockaddr));
-+ memcpy(&mac.sa_data, ltq_get_eth_mac(), ETH_ALEN);
-+
-+ if (!is_valid_ether_addr(mac.sa_data))
-+ memcpy(&mac.sa_data, priv->mac, ETH_ALEN);
-+
- if (!is_valid_ether_addr(mac.sa_data)) {
- pr_warn("etop: invalid MAC, using random\n");
- eth_random_addr(mac.sa_data);
+++ /dev/null
-From 9807eb80a1b3bad7a4a89aa6566497bb1cadd6ef Mon Sep 17 00:00:00 2001
-From: John Crispin <john@phrozen.org>
-Date: Fri, 3 Jun 2016 13:12:20 +0200
-Subject: [PATCH] arch: mips: increase io_space_limit
-
-this value comes from x86 and breaks some pci devices
-
-Signed-off-by: John Crispin <john@phrozen.org>
----
- arch/mips/include/asm/mach-lantiq/spaces.h | 8 ++++++++
- 1 file changed, 8 insertions(+)
- create mode 100644 arch/mips/include/asm/mach-lantiq/spaces.h
-
---- /dev/null
-+++ b/arch/mips/include/asm/mach-lantiq/spaces.h
-@@ -0,0 +1,8 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+#ifndef __ASM_MACH_LANTIQ_SPACES_H_
-+#define __ASM_MACH_LANTIQ_SPACES_H_
-+
-+#define IO_SPACE_LIMIT 0xffffffff
-+
-+#include <asm/mach-generic/spaces.h>
-+#endif
+++ /dev/null
-From de2cad82c4d0872066f83ce59462603852b47f03 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 6 Jan 2017 17:55:24 +0100
-Subject: [PATCH 2/2] usb: dwc2: add support for other Lantiq SoCs
-
-The size of the internal RAM of the DesignWare USB controller changed
-between the different Lantiq SoCs. We have the following sizes:
-
-Amazon + Danube: 8 KByte
-Amazon SE + arx100: 2 KByte
-xrx200 + xrx300: 2.5 KByte
-
-For Danube SoC we do not provide the params and let the driver decide
-to use sane defaults, for the Amazon SE and arx100 we use small fifos
-and for the xrx200 and xrx300 SCs a little bit bigger periodic fifo.
-The auto detection of max_transfer_size and max_packet_count should
-work, so remove it.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- drivers/usb/dwc2/platform.c | 46 ++++++++++++++++++++++++++++++++++++++-------
- 1 file changed, 39 insertions(+), 7 deletions(-)
-
---- a/drivers/usb/dwc2/params.c
-+++ b/drivers/usb/dwc2/params.c
-@@ -93,7 +93,14 @@ static void dwc2_set_rk_params(struct dw
- p->power_down = DWC2_POWER_DOWN_PARAM_NONE;
- }
-
--static void dwc2_set_ltq_params(struct dwc2_hsotg *hsotg)
-+static void dwc2_set_ltq_danube_params(struct dwc2_hsotg *hsotg)
-+{
-+ struct dwc2_core_params *p = &hsotg->params;
-+
-+ p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
-+}
-+
-+static void dwc2_set_ltq_ase_params(struct dwc2_hsotg *hsotg)
- {
- struct dwc2_core_params *p = &hsotg->params;
-
-@@ -101,12 +108,20 @@ static void dwc2_set_ltq_params(struct d
- p->host_rx_fifo_size = 288;
- p->host_nperio_tx_fifo_size = 128;
- p->host_perio_tx_fifo_size = 96;
-- p->max_transfer_size = 65535;
-- p->max_packet_count = 511;
- p->ahbcfg = GAHBCFG_HBSTLEN_INCR16 <<
- GAHBCFG_HBSTLEN_SHIFT;
- }
-
-+static void dwc2_set_ltq_xrx200_params(struct dwc2_hsotg *hsotg)
-+{
-+ struct dwc2_core_params *p = &hsotg->params;
-+
-+ p->otg_cap = DWC2_CAP_PARAM_NO_HNP_SRP_CAPABLE;
-+ p->host_rx_fifo_size = 288;
-+ p->host_nperio_tx_fifo_size = 128;
-+ p->host_perio_tx_fifo_size = 136;
-+}
-+
- static void dwc2_set_amlogic_params(struct dwc2_hsotg *hsotg)
- {
- struct dwc2_core_params *p = &hsotg->params;
-@@ -205,8 +220,11 @@ const struct of_device_id dwc2_of_match_
- { .compatible = "brcm,bcm2835-usb", .data = dwc2_set_bcm_params },
- { .compatible = "hisilicon,hi6220-usb", .data = dwc2_set_his_params },
- { .compatible = "rockchip,rk3066-usb", .data = dwc2_set_rk_params },
-- { .compatible = "lantiq,arx100-usb", .data = dwc2_set_ltq_params },
-- { .compatible = "lantiq,xrx200-usb", .data = dwc2_set_ltq_params },
-+ { .compatible = "lantiq,danube-usb", .data = &dwc2_set_ltq_danube_params },
-+ { .compatible = "lantiq,ase-usb", .data = &dwc2_set_ltq_ase_params },
-+ { .compatible = "lantiq,arx100-usb", .data = &dwc2_set_ltq_ase_params },
-+ { .compatible = "lantiq,xrx200-usb", .data = &dwc2_set_ltq_xrx200_params },
-+ { .compatible = "lantiq,xrx300-usb", .data = &dwc2_set_ltq_xrx200_params },
- { .compatible = "snps,dwc2" },
- { .compatible = "samsung,s3c6400-hsotg",
- .data = dwc2_set_s3c6400_params },
+++ /dev/null
-From 14909c4e4e836925668e74fc6e0e85ba0283cbf9 Mon Sep 17 00:00:00 2001
-From: Hauke Mehrtens <hauke@hauke-m.de>
-Date: Fri, 6 Jan 2017 17:40:12 +0100
-Subject: [PATCH 2/2] MIPS: lantiq: improve USB initialization
-
-This adds code to initialize the USB controller and PHY also on Danube,
-Amazon SE and AR10. This code is based on the Vendor driver from
-different UGW versions and compared to the hardware documentation.
-
-Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
----
- arch/mips/lantiq/xway/sysctrl.c | 20 +++++++
- 2 files changed, 110 insertions(+), 30 deletions(-)
-
-
---- a/arch/mips/lantiq/xway/sysctrl.c
-+++ b/arch/mips/lantiq/xway/sysctrl.c
-@@ -248,6 +248,25 @@ static void pmu_disable(struct clk *clk)
- pr_warn("deactivating PMU module failed!");
- }
-
-+static void usb_set_clock(void)
-+{
-+ unsigned int val = ltq_cgu_r32(ifccr);
-+
-+ if (of_machine_is_compatible("lantiq,ar10") ||
-+ of_machine_is_compatible("lantiq,grx390")) {
-+ val &= ~0x03; /* XTAL divided by 3 */
-+ } else if (of_machine_is_compatible("lantiq,ar9") ||
-+ of_machine_is_compatible("lantiq,vr9")) {
-+ /* TODO: this depends on the XTAL frequency */
-+ val |= 0x03; /* XTAL divided by 3 */
-+ } else if (of_machine_is_compatible("lantiq,ase")) {
-+ val |= 0x20; /* from XTAL */
-+ } else if (of_machine_is_compatible("lantiq,danube")) {
-+ val |= 0x30; /* 12 MHz, generated from 36 MHz */
-+ }
-+ ltq_cgu_w32(val, ifccr);
-+}
-+
- /* the pci enable helper */
- static int pci_enable(struct clk *clk)
- {
-@@ -585,4 +604,5 @@ void __init ltq_soc_init(void)
- clkdev_add_pmu("1e116000.mei", "dfe", 1, 0, PMU_DFE);
- clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
- }
-+ usb_set_clock();
- }
+++ /dev/null
-From 2c82524000cca691c89c9fda251b55ef04eabcb6 Mon Sep 17 00:00:00 2001
-From: Mathias Kresin <openwrt@kresin.me>
-Date: Mon, 2 May 2016 18:50:00 +0000
-Subject: [PATCH] find active root
-
-Signed-off-by: Mathias Kresin <openwrt@kresin.me>
----
- drivers/mtd/parsers/ofpart_core.c | 49 ++++++++++++++++++++++++++++++-
- 1 file changed, 48 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/parsers/ofpart_core.c
-+++ b/drivers/mtd/parsers/ofpart_core.c
-@@ -38,6 +38,38 @@ static bool node_has_compatible(struct d
- return of_get_property(pp, "compatible", NULL);
- }
-
-+static uint8_t * brnboot_get_selected_root_part(struct mtd_info *master,
-+ loff_t offset)
-+{
-+ static uint8_t root_id;
-+ int err, len;
-+
-+ err = mtd_read(master, offset, 0x01, &len, &root_id);
-+
-+ if (mtd_is_bitflip(err) || !err)
-+ return &root_id;
-+
-+ return NULL;
-+}
-+
-+static void brnboot_set_active_root_part(struct mtd_partition *pparts,
-+ struct device_node **part_nodes,
-+ int nr_parts,
-+ uint8_t *root_id)
-+{
-+ int i;
-+
-+ for (i = 0; i < nr_parts; i++) {
-+ int part_root_id;
-+
-+ if (!of_property_read_u32(part_nodes[i], "brnboot,root-id", &part_root_id)
-+ && part_root_id == *root_id) {
-+ pparts[i].name = "firmware";
-+ break;
-+ }
-+ }
-+}
-+
- static int parse_fixed_partitions(struct mtd_info *master,
- const struct mtd_partition **pparts,
- struct mtd_part_parser_data *data)
-@@ -51,6 +83,8 @@ static int parse_fixed_partitions(struct
- struct device_node *pp;
- int nr_parts, i, ret = 0;
- bool dedicated = true;
-+ uint8_t *proot_id = NULL;
-+ struct device_node **part_nodes;
-
- /* Pull of_node from the master device node */
- mtd_node = mtd_get_of_node(master);
-@@ -95,7 +129,9 @@ static int parse_fixed_partitions(struct
- return 0;
-
- parts = kcalloc(nr_parts, sizeof(*parts), GFP_KERNEL);
-- if (!parts)
-+ part_nodes = kcalloc(nr_parts, sizeof(*part_nodes), GFP_KERNEL);
-+
-+ if (!parts || !part_nodes)
- return -ENOMEM;
-
- i = 0;
-@@ -147,6 +183,11 @@ static int parse_fixed_partitions(struct
- if (of_property_read_bool(pp, "slc-mode"))
- parts[i].add_flags |= MTD_SLC_ON_MLC_EMULATION;
-
-+ if (!proot_id && of_device_is_compatible(pp, "brnboot,root-selector"))
-+ proot_id = brnboot_get_selected_root_part(master, parts[i].offset);
-+
-+ part_nodes[i] = pp;
-+
- i++;
- }
-
-@@ -156,6 +197,11 @@ static int parse_fixed_partitions(struct
- if (quirks && quirks->post_parse)
- quirks->post_parse(master, parts, nr_parts);
-
-+ if (proot_id)
-+ brnboot_set_active_root_part(parts, part_nodes, nr_parts, proot_id);
-+
-+ kfree(part_nodes);
-+
- *pparts = parts;
- return nr_parts;
-
-@@ -166,6 +212,7 @@ ofpart_fail:
- ofpart_none:
- of_node_put(pp);
- kfree(parts);
-+ kfree(part_nodes);
- return ret;
- }
-
+++ /dev/null
-From 1d1885f4a7abd7272f47b835b03d8662fb981d19 Mon Sep 17 00:00:00 2001
-From: Eddi De Pieri <eddi@depieri.net>
-Date: Tue, 14 Oct 2014 11:04:00 +0000
-Subject: [PATCH] MIPS: lantiq: ifxmips_pcie: use of
-
-Signed-off-by: Eddi De Pieri <eddi@depieri.net>
----
- arch/mips/pci/Makefile | 2 +-
- arch/mips/pci/ifxmips_pcie.c | 151 +++++++++++++++++++++++++++----
- arch/mips/pci/ifxmips_pcie_vr9.h | 105 ---------------------
- 3 files changed, 133 insertions(+), 125 deletions(-)
-
---- a/arch/mips/pci/Makefile
-+++ b/arch/mips/pci/Makefile
-@@ -43,7 +43,7 @@ obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o
- obj-$(CONFIG_SOC_MT7620) += pci-mt7620.o
- obj-$(CONFIG_SOC_RT288X) += pci-rt2880.o
- obj-$(CONFIG_SOC_RT3883) += pci-rt3883.o
--obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie_phy.o ifxmips_pcie.o fixup-lantiq-pcie.o
-+obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie.o fixup-lantiq-pcie.o
- obj-$(CONFIG_PCIE_LANTIQ_MSI) += pcie-lantiq-msi.o
- obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
- obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
---- a/arch/mips/pci/ifxmips_pcie.c
-+++ b/arch/mips/pci/ifxmips_pcie.c
-@@ -16,8 +16,15 @@
- #include <asm/paccess.h>
- #include <linux/pci.h>
- #include <linux/pci_regs.h>
-+#include <linux/phy/phy.h>
-+#include <linux/regmap.h>
-+#include <linux/reset.h>
-+#include <linux/mfd/syscon.h>
- #include <linux/module.h>
-
-+#include <linux/of_gpio.h>
-+#include <linux/of_platform.h>
-+
- #include "ifxmips_pcie.h"
- #include "ifxmips_pcie_reg.h"
-
-@@ -25,11 +32,6 @@
- #define IFX_PCIE_ERROR_INT
- #define IFX_PCIE_IO_32BIT
-
--#define IFX_PCIE_IR (INT_NUM_IM4_IRL0 + 25)
--#define IFX_PCIE_INTA (INT_NUM_IM4_IRL0 + 8)
--#define IFX_PCIE_INTB (INT_NUM_IM4_IRL0 + 9)
--#define IFX_PCIE_INTC (INT_NUM_IM4_IRL0 + 10)
--#define IFX_PCIE_INTD (INT_NUM_IM4_IRL0 + 11)
- #define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
- #define SM(_v, _f) (((_v) << _f##_S) & (_f))
- #define IFX_REG_SET_BIT(_f, _r) \
-@@ -40,30 +42,30 @@
- static DEFINE_SPINLOCK(ifx_pcie_lock);
-
- u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
-+static int pcie_reset_gpio;
-+static struct phy *ltq_pcie_phy;
-+static struct reset_control *ltq_pcie_reset;
-+static struct regmap *ltq_rcu_regmap;
-+static bool switch_pcie_endianess;
-
- static ifx_pcie_irq_t pcie_irqs[IFX_PCIE_CORE_NR] = {
- {
- .ir_irq = {
-- .irq = IFX_PCIE_IR,
- .name = "ifx_pcie_rc0",
- },
-
- .legacy_irq = {
- {
- .irq_bit = PCIE_IRN_INTA,
-- .irq = IFX_PCIE_INTA,
- },
- {
- .irq_bit = PCIE_IRN_INTB,
-- .irq = IFX_PCIE_INTB,
- },
- {
- .irq_bit = PCIE_IRN_INTC,
-- .irq = IFX_PCIE_INTC,
- },
- {
- .irq_bit = PCIE_IRN_INTD,
-- .irq = IFX_PCIE_INTD,
- },
- },
- },
-@@ -82,6 +84,22 @@ void ifx_pcie_debug(const char *fmt, ...
- printk("%s", buf);
- }
-
-+static inline void pcie_ep_gpio_rst_init(int pcie_port)
-+{
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+ gpio_set_value(pcie_reset_gpio, 1);
-+}
-+
-+static inline void pcie_device_rst_assert(int pcie_port)
-+{
-+ gpio_set_value(pcie_reset_gpio, 0);
-+}
-+
-+static inline void pcie_device_rst_deassert(int pcie_port)
-+{
-+ mdelay(100);
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+}
-
- static inline int pcie_ltssm_enable(int pcie_port)
- {
-@@ -857,7 +875,8 @@ pcie_rc_core_int_init(int pcie_port)
- ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, 0,
- pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
- if (ret)
-- printk(KERN_ERR "%s request irq %d failed\n", __func__, IFX_PCIE_IR);
-+ printk(KERN_ERR "%s request irq %d failed\n", __func__,
-+ pcie_irqs[pcie_port].ir_irq.irq);
-
- return ret;
- }
-@@ -988,10 +1007,26 @@ int ifx_pcie_bios_plat_dev_init(struct
- static int
- pcie_rc_initialize(int pcie_port)
- {
-- int i;
-+ int i, ret;
- #define IFX_PCIE_PHY_LOOP_CNT 5
-
-- pcie_rcu_endian_setup(pcie_port);
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_M,
-+ IFX_RCU_AHB_BE_PCIE_M);
-+
-+#ifdef CONFIG_IFX_PCIE_HW_SWAP
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_S,
-+ IFX_RCU_AHB_BE_PCIE_S);
-+ if (switch_pcie_endianess) {
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_XBAR_S,
-+ IFX_RCU_AHB_BE_XBAR_S);
-+ }
-+#else
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_PCIE_S,
-+ 0x0);
-+#endif
-+
-+ regmap_update_bits(ltq_rcu_regmap, 0x4c, IFX_RCU_AHB_BE_XBAR_M,
-+ 0x0);
-
- pcie_ep_gpio_rst_init(pcie_port);
-
-@@ -1000,26 +1035,21 @@ pcie_rc_initialize(int pcie_port)
- * reset PCIe PHY will solve this issue
- */
- for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
-- /* Disable PCIe PHY Analog part for sanity check */
-- pcie_phy_pmu_disable(pcie_port);
--
-- pcie_phy_rst_assert(pcie_port);
-- pcie_phy_rst_deassert(pcie_port);
--
-- /* Make sure PHY PLL is stable */
-- udelay(20);
--
-- /* PCIe Core reset enabled, low active, sw programmed */
-- pcie_core_rst_assert(pcie_port);
-+ ret = phy_init(ltq_pcie_phy);
-+ if (ret)
-+ continue;
-
- /* Put PCIe EP in reset status */
- pcie_device_rst_assert(pcie_port);
-
-- /* PCI PHY & Core reset disabled, high active, sw programmed */
-- pcie_core_rst_deassert(pcie_port);
-+ udelay(1);
-+ reset_control_deassert(ltq_pcie_reset);
-
-- /* Already in a quiet state, program PLL, enable PHY, check ready bit */
-- pcie_phy_clock_mode_setup(pcie_port);
-+ ret = phy_power_on(ltq_pcie_phy);
-+ if (ret) {
-+ phy_exit(ltq_pcie_phy);
-+ continue;
-+ }
-
- /* Enable PCIe PHY and Clock */
- pcie_core_pmu_setup(pcie_port);
-@@ -1035,6 +1065,10 @@ pcie_rc_initialize(int pcie_port)
- /* Once link is up, break out */
- if (pcie_app_loigc_setup(pcie_port) == 0)
- break;
-+
-+ phy_power_off(ltq_pcie_phy);
-+ reset_control_assert(ltq_pcie_reset);
-+ phy_exit(ltq_pcie_phy);
- }
- if (i >= IFX_PCIE_PHY_LOOP_CNT) {
- printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
-@@ -1045,17 +1079,73 @@ pcie_rc_initialize(int pcie_port)
- return 0;
- }
-
--static int __init ifx_pcie_bios_init(void)
-+static int ifx_pcie_bios_probe(struct platform_device *pdev)
- {
-+ struct device_node *node = pdev->dev.of_node;
- void __iomem *io_map_base;
- int pcie_port;
- int startup_port;
-+ struct device_node *np;
-+ struct pci_bus *bus;
-+
-+ /*
-+ * In case a PCI device is physical present, the Lantiq PCI driver need
-+ * to be loaded prior to the Lantiq PCIe driver. Otherwise none of them
-+ * will work.
-+ *
-+ * In case the lantiq PCI driver is enabled in the device tree, check if
-+ * a PCI bus (hopefully the one of the Lantiq PCI driver one) is already
-+ * registered.
-+ *
-+ * It will fail if there is another PCI controller, this controller is
-+ * registered before the Lantiq PCIe driver is probe and the lantiq PCI
-+ */
-+ np = of_find_compatible_node(NULL, NULL, "lantiq,pci-xway");
-+
-+ if (of_device_is_available(np)) {
-+ bus = pci_find_next_bus(bus);
-+
-+ if (!bus)
-+ return -EPROBE_DEFER;
-+ }
-
- /* Enable AHB Master/ Slave */
- pcie_ahb_pmu_setup();
-
- startup_port = IFX_PCIE_PORT0;
--
-+
-+ ltq_pcie_phy = devm_phy_get(&pdev->dev, "pcie");
-+ if (IS_ERR(ltq_pcie_phy))
-+ return dev_err_probe(&pdev->dev, PTR_ERR(ltq_pcie_phy),
-+ "failed to get the PCIe PHY\n");
-+
-+ ltq_pcie_reset = devm_reset_control_get_shared(&pdev->dev, NULL);
-+ if (IS_ERR(ltq_pcie_reset)) {
-+ dev_err(&pdev->dev, "failed to get the PCIe reset line\n");
-+ return PTR_ERR(ltq_pcie_reset);
-+ }
-+
-+ if (of_property_read_bool(node, "lantiq,switch-pcie-endianess")) {
-+ switch_pcie_endianess = true;
-+ dev_info(&pdev->dev, "switch pcie endianess requested\n");
-+ } else {
-+ switch_pcie_endianess = false;
-+ }
-+
-+ ltq_rcu_regmap = syscon_regmap_lookup_by_phandle(node, "lantiq,rcu");
-+ if (IS_ERR(ltq_rcu_regmap))
-+ return PTR_ERR(ltq_rcu_regmap);
-+
-+ pcie_reset_gpio = of_get_named_gpio(node, "gpio-reset", 0);
-+ if (gpio_is_valid(pcie_reset_gpio)) {
-+ int ret = devm_gpio_request(&pdev->dev, pcie_reset_gpio, "pcie-reset");
-+ if (ret) {
-+ dev_err(&pdev->dev, "failed to request gpio %d\n", pcie_reset_gpio);
-+ return ret;
-+ }
-+ gpio_direction_output(pcie_reset_gpio, 1);
-+ }
-+
- for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
- if (pcie_rc_initialize(pcie_port) == 0) {
- IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
-@@ -1066,7 +1156,19 @@ static int __init ifx_pcie_bios_init(voi
- IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
- return -ENOMEM;
- }
-+ pcie_irqs[pcie_port].ir_irq.irq = platform_get_irq(pdev, 0);
-+ if (pcie_irqs[pcie_port].ir_irq.irq < 0)
-+ return pcie_irqs[pcie_port].ir_irq.irq;
-+
-+ for (int i = 0; i <= 3; i++){
-+ pcie_irqs[pcie_port].legacy_irq[i].irq = platform_get_irq(pdev, i + 1);
-+
-+ if (pcie_irqs[pcie_port].legacy_irq[i].irq < 0)
-+ return pcie_irqs[pcie_port].legacy_irq[i].irq;
-+ }
-+
- ifx_pcie_controller[pcie_port].pcic.io_map_base = (unsigned long)io_map_base;
-+ pci_load_of_ranges(&ifx_pcie_controller[pcie_port].pcic, node);
-
- register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
- /* XXX, clear error status */
-@@ -1083,6 +1185,30 @@ static int __init ifx_pcie_bios_init(voi
-
- return 0;
- }
-+
-+static const struct of_device_id ifxmips_pcie_match[] = {
-+ { .compatible = "lantiq,pcie-xrx200" },
-+ {},
-+};
-+MODULE_DEVICE_TABLE(of, ifxmips_pcie_match);
-+
-+static struct platform_driver ltq_pci_driver = {
-+ .probe = ifx_pcie_bios_probe,
-+ .driver = {
-+ .name = "pcie-xrx200",
-+ .owner = THIS_MODULE,
-+ .of_match_table = ifxmips_pcie_match,
-+ },
-+};
-+
-+int __init ifx_pcie_bios_init(void)
-+{
-+ int ret = platform_driver_register(<q_pci_driver);
-+ if (ret)
-+ pr_info("pcie-xrx200: Error registering platform driver!");
-+ return ret;
-+}
-+
- arch_initcall(ifx_pcie_bios_init);
-
- MODULE_LICENSE("GPL");
---- a/arch/mips/pci/ifxmips_pcie_vr9.h
-+++ b/arch/mips/pci/ifxmips_pcie_vr9.h
-@@ -22,8 +22,6 @@
- #include <linux/gpio.h>
- #include <lantiq_soc.h>
-
--#define IFX_PCIE_GPIO_RESET 494
--
- #define IFX_REG_R32 ltq_r32
- #define IFX_REG_W32 ltq_w32
- #define CONFIG_IFX_PCIE_HW_SWAP
-@@ -54,21 +52,6 @@
- #define OUT ((volatile u32*)(IFX_GPIO + 0x0070))
-
-
--static inline void pcie_ep_gpio_rst_init(int pcie_port)
--{
--
-- gpio_request(IFX_PCIE_GPIO_RESET, "pcie-reset");
-- gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
-- gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
--
--/* ifx_gpio_pin_reserve(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_dir_out_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_altsel0_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_altsel1_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
-- ifx_gpio_open_drain_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);*/
--}
--
- static inline void pcie_ahb_pmu_setup(void)
- {
- /* Enable AHB bus master/slave */
-@@ -80,24 +63,6 @@ static inline void pcie_ahb_pmu_setup(vo
- //AHBS_PMU_SETUP(IFX_PMU_ENABLE);
- }
-
--static inline void pcie_rcu_endian_setup(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
--#ifdef CONFIG_IFX_PCIE_HW_SWAP
-- reg |= IFX_RCU_AHB_BE_PCIE_M;
-- reg |= IFX_RCU_AHB_BE_PCIE_S;
-- reg &= ~IFX_RCU_AHB_BE_XBAR_M;
--#else
-- reg |= IFX_RCU_AHB_BE_PCIE_M;
-- reg &= ~IFX_RCU_AHB_BE_PCIE_S;
-- reg &= ~IFX_RCU_AHB_BE_XBAR_M;
--#endif /* CONFIG_IFX_PCIE_HW_SWAP */
-- IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
-- IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
--}
--
- static inline void pcie_phy_pmu_enable(int pcie_port)
- {
- struct clk *clk;
-@@ -116,17 +81,6 @@ static inline void pcie_phy_pmu_disable(
- // PCIE_PHY_PMU_SETUP(IFX_PMU_DISABLE);
- }
-
--static inline void pcie_pdi_big_endian(int pcie_port)
--{
-- u32 reg;
--
-- /* SRAM2PDI endianness control. */
-- reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
-- /* Config AHB->PCIe and PDI endianness */
-- reg |= IFX_RCU_AHB_BE_PCIE_PDI;
-- IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
--}
--
- static inline void pcie_pdi_pmu_enable(int pcie_port)
- {
- /* Enable PDI to access PCIe PHY register */
-@@ -136,65 +90,6 @@ static inline void pcie_pdi_pmu_enable(i
- //PDI_PMU_SETUP(IFX_PMU_ENABLE);
- }
-
--static inline void pcie_core_rst_assert(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
--
-- /* Reset PCIe PHY & Core, bit 22, bit 26 may be affected if write it directly */
-- reg |= 0x00400000;
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_core_rst_deassert(int pcie_port)
--{
-- u32 reg;
--
-- /* Make sure one micro-second delay */
-- udelay(1);
--
-- /* Reset PCIe PHY & Core, bit 22 */
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg &= ~0x00400000;
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_phy_rst_assert(int pcie_port)
--{
-- u32 reg;
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg |= 0x00001000; /* Bit 12 */
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_phy_rst_deassert(int pcie_port)
--{
-- u32 reg;
--
-- /* Make sure one micro-second delay */
-- udelay(1);
--
-- reg = IFX_REG_R32(IFX_RCU_RST_REQ);
-- reg &= ~0x00001000; /* Bit 12 */
-- IFX_REG_W32(reg, IFX_RCU_RST_REQ);
--}
--
--static inline void pcie_device_rst_assert(int pcie_port)
--{
-- gpio_set_value(IFX_PCIE_GPIO_RESET, 0);
--// ifx_gpio_output_clear(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
--}
--
--static inline void pcie_device_rst_deassert(int pcie_port)
--{
-- mdelay(100);
-- gpio_direction_output(IFX_PCIE_GPIO_RESET, 1);
--// gpio_set_value(IFX_PCIE_GPIO_RESET, 1);
-- //ifx_gpio_output_set(IFX_PCIE_GPIO_RESET, ifx_pcie_gpio_module_id);
--}
--
- static inline void pcie_core_pmu_setup(int pcie_port)
- {
- struct clk *clk;
---- a/arch/mips/pci/ifxmips_pcie.h
-+++ b/arch/mips/pci/ifxmips_pcie.h
-@@ -96,13 +96,13 @@ struct ifx_pci_controller {
- };
-
- typedef struct ifx_pcie_ir_irq {
-- const unsigned int irq;
-+ unsigned int irq;
- const char name[16];
- }ifx_pcie_ir_irq_t;
-
- typedef struct ifx_pcie_legacy_irq{
- const u32 irq_bit;
-- const int irq;
-+ int irq;
- }ifx_pcie_legacy_irq_t;
-
- typedef struct ifx_pcie_irq {
+++ /dev/null
-From 4d48a3d1ef6f8d036bd926e3c1f70b56fcc679b2 Mon Sep 17 00:00:00 2001
-From: Stefan Koch <stefan.koch10@gmail.com>
-Date: Thu, 20 Oct 2016 21:32:00 +0200
-Subject: [PATCH] lantiq: vpe
-
-Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
----
- arch/mips/Kconfig | 6 ++++
- arch/mips/include/asm/mipsmtregs.h | 5 ++++
- arch/mips/include/asm/vpe.h | 9 ++++++
- arch/mips/kernel/vpe-mt.c | 47 ++++++++++++++++++++++++++++++
- arch/mips/kernel/vpe.c | 35 ++++++++++++++++++++++
- arch/mips/lantiq/prom.c | 4 +++
- 6 files changed, 106 insertions(+)
-
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -2433,6 +2433,12 @@ config MIPS_VPE_LOADER
- Includes a loader for loading an elf relocatable object
- onto another VPE and running it.
-
-+config IFX_VPE_EXT
-+ bool "IFX APRP Extensions"
-+ depends on MIPS_VPE_LOADER
-+ help
-+ IFX included extensions in APRP
-+
- config MIPS_VPE_LOADER_CMP
- bool
- default "y"
---- a/arch/mips/include/asm/mipsmtregs.h
-+++ b/arch/mips/include/asm/mipsmtregs.h
-@@ -32,6 +32,9 @@
- #define read_c0_vpeconf1() __read_32bit_c0_register($1, 3)
- #define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val)
-
-+#define read_c0_vpeopt() __read_32bit_c0_register($1, 7)
-+#define write_c0_vpeopt(val) __write_32bit_c0_register($1, 7, val)
-+
- #define read_c0_tcstatus() __read_32bit_c0_register($2, 1)
- #define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val)
-
-@@ -378,6 +381,8 @@ do { \
- #define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
- #define read_vpe_c0_vpeconf1() mftc0(1, 3)
- #define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val)
-+#define read_vpe_c0_vpeopt() mftc0(1, 7)
-+#define write_vpe_c0_vpeopt(val) mttc0(1, 7, val)
- #define read_vpe_c0_count() mftc0(9, 0)
- #define write_vpe_c0_count(val) mttc0(9, 0, val)
- #define read_vpe_c0_status() mftc0(12, 0)
---- a/arch/mips/include/asm/vpe.h
-+++ b/arch/mips/include/asm/vpe.h
-@@ -123,4 +123,13 @@ void cleanup_tc(struct tc *tc);
-
- int __init vpe_module_init(void);
- void __exit vpe_module_exit(void);
-+
-+/* For the explanation of the APIs please refer the section "MT APRP Kernel
-+ * Programming" in AR9 SW Architecture Specification
-+ */
-+int32_t vpe1_sw_start(void *sw_start_addr, uint32_t tcmask, uint32_t flags);
-+int32_t vpe1_sw_stop(uint32_t flags);
-+uint32_t vpe1_get_load_addr(uint32_t flags);
-+uint32_t vpe1_get_max_mem(uint32_t flags);
-+
- #endif /* _ASM_VPE_H */
---- a/arch/mips/kernel/vpe-mt.c
-+++ b/arch/mips/kernel/vpe-mt.c
-@@ -415,6 +415,8 @@ int __init vpe_module_init(void)
- }
-
- v->ntcs = hw_tcs - aprp_cpu_index();
-+ write_tc_c0_tcbind((read_tc_c0_tcbind() &
-+ ~TCBIND_CURVPE) | 1);
-
- /* add the tc to the list of this vpe's tc's. */
- list_add(&t->tc, &v->tc);
-@@ -518,3 +520,47 @@ void __exit vpe_module_exit(void)
- release_vpe(v);
- }
- }
-+
-+#ifdef CONFIG_IFX_VPE_EXT
-+int32_t vpe1_sw_start(void *sw_start_addr, uint32_t tcmask, uint32_t flags)
-+{
-+ enum vpe_state state;
-+ struct vpe *v = get_vpe(tclimit);
-+ struct vpe_notifications *not;
-+
-+ if (tcmask || flags) {
-+ pr_warn("Currently tcmask and flags should be 0. Other values are not supported\n");
-+ return -1;
-+ }
-+
-+ state = xchg(&v->state, VPE_STATE_INUSE);
-+ if (state != VPE_STATE_UNUSED) {
-+ vpe_stop(v);
-+
-+ list_for_each_entry(not, &v->notify, list) {
-+ not->stop(tclimit);
-+ }
-+ }
-+
-+ v->__start = (unsigned long)sw_start_addr;
-+
-+ if (!vpe_run(v)) {
-+ pr_debug("VPE loader: VPE1 running successfully\n");
-+ return 0;
-+ }
-+ return -1;
-+}
-+EXPORT_SYMBOL(vpe1_sw_start);
-+
-+int32_t vpe1_sw_stop(uint32_t flags)
-+{
-+ struct vpe *v = get_vpe(tclimit);
-+
-+ if (!vpe_free(v)) {
-+ pr_debug("RP Stopped\n");
-+ return 0;
-+ } else
-+ return -1;
-+}
-+EXPORT_SYMBOL(vpe1_sw_stop);
-+#endif
---- a/arch/mips/kernel/vpe.c
-+++ b/arch/mips/kernel/vpe.c
-@@ -49,6 +49,41 @@ struct vpe_control vpecontrol = {
- .tc_list = LIST_HEAD_INIT(vpecontrol.tc_list)
- };
-
-+#ifdef CONFIG_IFX_VPE_EXT
-+unsigned int vpe1_load_addr;
-+
-+static int __init load_address(char *str)
-+{
-+ get_option(&str, &vpe1_load_addr);
-+ return 1;
-+}
-+__setup("vpe1_load_addr=", load_address);
-+
-+static unsigned int vpe1_mem;
-+static int __init vpe1mem(char *str)
-+{
-+ vpe1_mem = memparse(str, &str);
-+ return 1;
-+}
-+__setup("vpe1_mem=", vpe1mem);
-+
-+uint32_t vpe1_get_load_addr(uint32_t flags)
-+{
-+ return vpe1_load_addr;
-+}
-+EXPORT_SYMBOL(vpe1_get_load_addr);
-+
-+uint32_t vpe1_get_max_mem(uint32_t flags)
-+{
-+ if (!vpe1_mem)
-+ return P_SIZE;
-+ else
-+ return vpe1_mem;
-+}
-+EXPORT_SYMBOL(vpe1_get_max_mem);
-+
-+#endif
-+
- /* get the vpe associated with this minor */
- struct vpe *get_vpe(int minor)
- {
---- a/arch/mips/lantiq/prom.c
-+++ b/arch/mips/lantiq/prom.c
-@@ -28,10 +28,14 @@ EXPORT_SYMBOL_GPL(ebu_lock);
- */
- static struct ltq_soc_info soc_info;
-
-+/* for Multithreading (APRP), vpe.c will use it */
-+unsigned long cp0_memsize;
-+
- const char *get_system_type(void)
- {
- return soc_info.sys_type;
- }
-+EXPORT_SYMBOL(ltq_soc_type);
-
- int ltq_soc_type(void)
- {
+++ /dev/null
-From 3c92a781de062064e36b867c0ab22f9aba48f3d3 Mon Sep 17 00:00:00 2001
-From: Eddi De Pieri <eddi@depieri.net>
-Date: Tue, 8 Nov 2016 17:38:00 +0100
-Subject: [PATCH] lantiq: pci: bar11mask fix
-
-Signed-off-by: Eddi De Pieri <eddi@depieri.net>
----
- arch/mips/pci/pci-lantiq.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/arch/mips/pci/pci-lantiq.c
-+++ b/arch/mips/pci/pci-lantiq.c
-@@ -59,6 +59,8 @@
- #define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y))
- #define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x))
-
-+extern u32 max_low_pfn;
-+
- __iomem void *ltq_pci_mapped_cfg;
- static __iomem void *ltq_pci_membase;
-
-@@ -84,8 +86,8 @@ static inline u32 ltq_calc_bar11mask(voi
- u32 mem, bar11mask;
-
- /* BAR11MASK value depends on available memory on system. */
-- mem = get_num_physpages() * PAGE_SIZE;
-- bar11mask = (0x0ffffff0 & ~((1 << (fls(mem) - 1)) - 1)) | 8;
-+ mem = max_low_pfn << PAGE_SHIFT;
-+ bar11mask = ((-roundup_pow_of_two(mem)) & 0x0F000000) | 8;
-
- return bar11mask;
- }
+++ /dev/null
-From 07ce9e9bc4dcd5ac4728e587901112eef95bbe7b Mon Sep 17 00:00:00 2001
-From: Stefan Koch <stefan.koch10@gmail.com>
-Date: Mon, 13 Mar 2017 23:42:00 +0100
-Subject: [PATCH] lantiq: vpe nosmp
-
-Signed-off-by: Stefan Koch <stefan.koch10@gmail.com>
----
- arch/mips/kernel/vpe-mt.c | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
---- a/arch/mips/kernel/vpe-mt.c
-+++ b/arch/mips/kernel/vpe-mt.c
-@@ -130,7 +130,10 @@ int vpe_run(struct vpe *v)
- * kernels need to turn it on, even if that wasn't the pre-dvpe() state.
- */
- #ifdef CONFIG_SMP
-- evpe(vpeflags);
-+ if (!setup_max_cpus) /* nosmp is set */
-+ evpe(EVPE_ENABLE);
-+ else
-+ evpe(vpeflags);
- #else
- evpe(EVPE_ENABLE);
- #endif
+++ /dev/null
-From ebaae1cd68cd79c7eee67c9c5c0fa45809e84525 Mon Sep 17 00:00:00 2001
-From: Maikel Bloemendal <openwrt@maikelenyvonne.nl>
-Date: Fri, 14 Nov 2014 17:06:00 +0000
-Subject: [PATCH] owrt: lantiq: multiple flash
-
-Signed-off-by: Maikel Bloemendal <openwrt@maikelenyvonne.nl>
----
- drivers/mtd/maps/lantiq-flash.c | 168 +++++++++++++++++++++-----------
- 1 file changed, 109 insertions(+), 59 deletions(-)
-
---- a/drivers/mtd/maps/lantiq-flash.c
-+++ b/drivers/mtd/maps/lantiq-flash.c
-@@ -17,6 +17,7 @@
- #include <linux/mtd/cfi.h>
- #include <linux/platform_device.h>
- #include <linux/mtd/physmap.h>
-+#include <linux/mtd/concat.h>
- #include <linux/of.h>
-
- #include <lantiq_soc.h>
-@@ -36,13 +37,16 @@ enum {
- LTQ_NOR_NORMAL
- };
-
-+#define MAX_RESOURCES 4
-+
- struct ltq_mtd {
-- struct resource *res;
-- struct mtd_info *mtd;
-- struct map_info *map;
-+ struct mtd_info *mtd[MAX_RESOURCES];
-+ struct mtd_info *cmtd;
-+ struct map_info map[MAX_RESOURCES];
- };
-
- static const char ltq_map_name[] = "ltq_nor";
-+static const char * const ltq_probe_types[] = { "cmdlinepart", "ofpart", NULL };
-
- static map_word
- ltq_read16(struct map_info *map, unsigned long adr)
-@@ -106,11 +110,43 @@ ltq_copy_to(struct map_info *map, unsign
- }
-
- static int
-+ltq_mtd_remove(struct platform_device *pdev)
-+{
-+ struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
-+ int i;
-+
-+ if (ltq_mtd == NULL)
-+ return 0;
-+
-+ if (ltq_mtd->cmtd) {
-+ mtd_device_unregister(ltq_mtd->cmtd);
-+ if (ltq_mtd->cmtd != ltq_mtd->mtd[0])
-+ mtd_concat_destroy(ltq_mtd->cmtd);
-+ }
-+
-+ for (i = 0; i < MAX_RESOURCES; i++) {
-+ if (ltq_mtd->mtd[i] != NULL)
-+ map_destroy(ltq_mtd->mtd[i]);
-+ }
-+
-+ kfree(ltq_mtd);
-+
-+ return 0;
-+}
-+
-+static int
- ltq_mtd_probe(struct platform_device *pdev)
- {
- struct ltq_mtd *ltq_mtd;
- struct cfi_private *cfi;
-- int err;
-+ int err = 0;
-+ int i;
-+ int devices_found = 0;
-+
-+ static const char *rom_probe_types[] = {
-+ "cfi_probe", "jedec_probe", NULL
-+ };
-+ const char **type;
-
- ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL);
- if (!ltq_mtd)
-@@ -118,75 +154,89 @@ ltq_mtd_probe(struct platform_device *pd
-
- platform_set_drvdata(pdev, ltq_mtd);
-
-- ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-- if (!ltq_mtd->res) {
-- dev_err(&pdev->dev, "failed to get memory resource\n");
-- return -ENOENT;
-+ for (i = 0; i < pdev->num_resources; i++) {
-+ printk(KERN_NOTICE "lantiq nor flash device: %.8llx at %.8llx\n",
-+ (unsigned long long)resource_size(&pdev->resource[i]),
-+ (unsigned long long)pdev->resource[i].start);
-+
-+ if (!devm_request_mem_region(&pdev->dev,
-+ pdev->resource[i].start,
-+ resource_size(&pdev->resource[i]),
-+ dev_name(&pdev->dev))) {
-+ dev_err(&pdev->dev, "Could not reserve memory region\n");
-+ return -ENOMEM;
-+ }
-+
-+ ltq_mtd->map[i].name = ltq_map_name;
-+ ltq_mtd->map[i].bankwidth = 2;
-+ ltq_mtd->map[i].read = ltq_read16;
-+ ltq_mtd->map[i].write = ltq_write16;
-+ ltq_mtd->map[i].copy_from = ltq_copy_from;
-+ ltq_mtd->map[i].copy_to = ltq_copy_to;
-+
-+ if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-+ ltq_mtd->map[i].phys = NO_XIP;
-+ else
-+ ltq_mtd->map[i].phys = pdev->resource[i].start;
-+ ltq_mtd->map[i].size = resource_size(&pdev->resource[i]);
-+ ltq_mtd->map[i].virt = devm_ioremap(&pdev->dev, pdev->resource[i].start,
-+ ltq_mtd->map[i].size);
-+ if (IS_ERR(ltq_mtd->map[i].virt))
-+ return PTR_ERR(ltq_mtd->map[i].virt);
-+
-+ if (ltq_mtd->map[i].virt == NULL) {
-+ dev_err(&pdev->dev, "Failed to ioremap flash region\n");
-+ err = PTR_ERR(ltq_mtd->map[i].virt);
-+ goto err_out;
-+ }
-+
-+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_PROBING;
-+ for (type = rom_probe_types; !ltq_mtd->mtd[i] && *type; type++)
-+ ltq_mtd->mtd[i] = do_map_probe(*type, <q_mtd->map[i]);
-+ ltq_mtd->map[i].map_priv_1 = LTQ_NOR_NORMAL;
-+
-+ if (!ltq_mtd->mtd[i]) {
-+ dev_err(&pdev->dev, "probing failed\n");
-+ return -ENXIO;
-+ } else {
-+ devices_found++;
-+ }
-+
-+ ltq_mtd->mtd[i]->owner = THIS_MODULE;
-+ ltq_mtd->mtd[i]->dev.parent = &pdev->dev;
-+
-+ cfi = ltq_mtd->map[i].fldrv_priv;
-+ cfi->addr_unlock1 ^= 1;
-+ cfi->addr_unlock2 ^= 1;
- }
-
-- ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info),
-- GFP_KERNEL);
-- if (!ltq_mtd->map)
-- return -ENOMEM;
--
-- if (of_find_property(pdev->dev.of_node, "lantiq,noxip", NULL))
-- ltq_mtd->map->phys = NO_XIP;
-- else
-- ltq_mtd->map->phys = ltq_mtd->res->start;
-- ltq_mtd->res->start;
-- ltq_mtd->map->size = resource_size(ltq_mtd->res);
-- ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res);
-- if (IS_ERR(ltq_mtd->map->virt))
-- return PTR_ERR(ltq_mtd->map->virt);
--
-- ltq_mtd->map->name = ltq_map_name;
-- ltq_mtd->map->bankwidth = 2;
-- ltq_mtd->map->read = ltq_read16;
-- ltq_mtd->map->write = ltq_write16;
-- ltq_mtd->map->copy_from = ltq_copy_from;
-- ltq_mtd->map->copy_to = ltq_copy_to;
--
-- ltq_mtd->map->map_priv_1 = LTQ_NOR_PROBING;
-- ltq_mtd->mtd = do_map_probe("cfi_probe", ltq_mtd->map);
-- ltq_mtd->map->map_priv_1 = LTQ_NOR_NORMAL;
--
-- if (!ltq_mtd->mtd) {
-- dev_err(&pdev->dev, "probing failed\n");
-- return -ENXIO;
-+ if (devices_found == 1) {
-+ ltq_mtd->cmtd = ltq_mtd->mtd[0];
-+ } else if (devices_found > 1) {
-+ /*
-+ * We detected multiple devices. Concatenate them together.
-+ */
-+ ltq_mtd->cmtd = mtd_concat_create(ltq_mtd->mtd, devices_found, dev_name(&pdev->dev));
-+ if (ltq_mtd->cmtd == NULL)
-+ err = -ENXIO;
- }
-
-- ltq_mtd->mtd->dev.parent = &pdev->dev;
-- mtd_set_of_node(ltq_mtd->mtd, pdev->dev.of_node);
--
-- cfi = ltq_mtd->map->fldrv_priv;
-- cfi->addr_unlock1 ^= 1;
-- cfi->addr_unlock2 ^= 1;
-+ ltq_mtd->cmtd->dev.parent = &pdev->dev;
-+ mtd_set_of_node(ltq_mtd->cmtd, pdev->dev.of_node);
-
-- err = mtd_device_register(ltq_mtd->mtd, NULL, 0);
-+ err = mtd_device_register(ltq_mtd->cmtd, NULL, 0);
- if (err) {
- dev_err(&pdev->dev, "failed to add partitions\n");
-- goto err_destroy;
-+ goto err_out;
- }
-
- return 0;
-
--err_destroy:
-- map_destroy(ltq_mtd->mtd);
-+err_out:
-+ ltq_mtd_remove(pdev);
- return err;
- }
-
--static int
--ltq_mtd_remove(struct platform_device *pdev)
--{
-- struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev);
--
-- if (ltq_mtd && ltq_mtd->mtd) {
-- mtd_device_unregister(ltq_mtd->mtd);
-- map_destroy(ltq_mtd->mtd);
-- }
-- return 0;
--}
--
- static const struct of_device_id ltq_mtd_match[] = {
- { .compatible = "lantiq,nor" },
- {},
+++ /dev/null
-From 2b873c59fd313aee57864f96d64a228f2ea7c208 Mon Sep 17 00:00:00 2001
-From: Martin Schiller <ms@dev.tdt.de>
-Date: Mon, 13 May 2024 10:42:24 +0200
-Subject: [PATCH] MIPS: lantiq: xway: vmmc: use platform_get_irq to get irqs
- from dts
-
-Let's fetch the irqs from the dts here and expose them to the voice
-driver like it is done for the cp1 base memory.
-
-ToDo:
-Maybe it is possible to drop this driver completely and merge this
-handling to the voice driver.
-
-Signed-off-by: Martin Schiller <ms@dev.tdt.de>
----
- arch/mips/lantiq/xway/vmmc.c | 53 ++++++++++++++++++++++++++++++++++++
- 1 file changed, 53 insertions(+)
-
---- a/arch/mips/lantiq/xway/vmmc.c
-+++ b/arch/mips/lantiq/xway/vmmc.c
-@@ -13,6 +13,10 @@
-
- static unsigned int *cp1_base;
-
-+static int ad0_irq;
-+static int ad1_irq;
-+static int vc_irq[4];
-+
- unsigned int *ltq_get_cp1_base(void)
- {
- if (!cp1_base)
-@@ -22,16 +26,65 @@ unsigned int *ltq_get_cp1_base(void)
- }
- EXPORT_SYMBOL(ltq_get_cp1_base);
-
-+unsigned int ltq_get_mps_ad0_irq(void)
-+{
-+ if (!ad0_irq)
-+ panic("no ad0 irq was set\n");
-+
-+ return ad0_irq;
-+}
-+EXPORT_SYMBOL(ltq_get_mps_ad0_irq);
-+
-+unsigned int ltq_get_mps_ad1_irq(void)
-+{
-+ if (!ad1_irq)
-+ panic("no ad1 irq was set\n");
-+
-+ return ad1_irq;
-+}
-+EXPORT_SYMBOL(ltq_get_mps_ad1_irq);
-+
-+unsigned int ltq_get_mps_vc_irq(int idx)
-+{
-+ if (!vc_irq[idx])
-+ panic("no vc%d irq was set\n", idx);
-+
-+ return vc_irq[idx];
-+}
-+EXPORT_SYMBOL(ltq_get_mps_vc_irq);
-+
- static int vmmc_probe(struct platform_device *pdev)
- {
- #define CP1_SIZE (1 << 20)
- int gpio_count;
- dma_addr_t dma;
-+ int i;
-
- cp1_base =
- (void *) CPHYSADDR(dma_alloc_coherent(&pdev->dev, CP1_SIZE,
- &dma, GFP_KERNEL));
-
-+ ad0_irq = platform_get_irq(pdev, 4);
-+ if (ad0_irq < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS AD0 irq: %d\n", ad0_irq);
-+ return ad0_irq;
-+ }
-+
-+ ad1_irq = platform_get_irq(pdev, 5);
-+ if (ad1_irq < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS AD1 irq: %d\n", ad1_irq);
-+ return ad1_irq;
-+ }
-+
-+ for (i = 0; i < 4; i++) {
-+ vc_irq[i] = platform_get_irq(pdev, i);
-+ if (vc_irq[i] < 0) {
-+ dev_err(&pdev->dev, "failed to get MPS VC%d irq: %d\n",
-+ i, vc_irq[i]);
-+ return vc_irq[i];
-+ }
-+ }
-+
- gpio_count = of_gpio_count(pdev->dev.of_node);
- while (gpio_count > 0) {
- enum of_gpio_flags flags;
+++ /dev/null
-From 5e93c85ac3e5626d1aa7e7f9c0a008b2a4224f04 Mon Sep 17 00:00:00 2001
-From: Matti Laakso <malaakso@elisanet.fi>
-Date: Sat, 14 Feb 2015 20:48:00 +0000
-Subject: [PATCH] MTD: cfi_cmdset_0001: disable buffered writes
-
-Signed-off-by: Matti Laakso <malaakso@elisanet.fi>
----
- drivers/mtd/chips/cfi_cmdset_0001.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/mtd/chips/cfi_cmdset_0001.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
-@@ -39,7 +39,7 @@
- /* #define CMDSET0001_DISABLE_WRITE_SUSPEND */
-
- // debugging, turns off buffer write mode if set to 1
--#define FORCE_WORD_WRITE 0
-+#define FORCE_WORD_WRITE 1
-
- /* Intel chips */
- #define I82802AB 0x00ad
+++ /dev/null
-From 5502ef9d40ab20b2ac683660d1565a7c4968bcc8 Mon Sep 17 00:00:00 2001
-From: Mathias Kresin <openwrt@kresin.me>
-Date: Mon, 2 May 2016 18:50:00 +0000
-Subject: [PATCH] xrx200: add gphy clk src device tree binding
-
-Signed-off-by: Mathias Kresin <openwrt@kresin.me>
----
- arch/mips/lantiq/xway/sysctrl.c | 16 ++++++++++++++++
- 1 file changed, 16 insertions(+)
-
---- a/arch/mips/lantiq/xway/sysctrl.c
-+++ b/arch/mips/lantiq/xway/sysctrl.c
-@@ -440,6 +440,20 @@ static void clkdev_add_clkout(void)
- }
- }
-
-+static void set_phy_clock_source(struct device_node *np_cgu)
-+{
-+ u32 phy_clk_src, ifcc;
-+
-+ if (!np_cgu)
-+ return;
-+
-+ if (of_property_read_u32(np_cgu, "lantiq,phy-clk-src", &phy_clk_src))
-+ return;
-+
-+ ifcc = ltq_cgu_r32(ifccr) & ~(0x1c);
-+ ltq_cgu_w32(ifcc | (phy_clk_src << 2), ifccr);
-+}
-+
- /* bring up all register ranges that we need for basic system control */
- void __init ltq_soc_init(void)
- {
-@@ -605,4 +619,6 @@ void __init ltq_soc_init(void)
- clkdev_add_pmu("1e100400.serial", NULL, 1, 0, PMU_ASC0);
- }
- usb_set_clock();
-+
-+ set_phy_clock_source(np_cgu);
- }
+++ /dev/null
-From 118fe2c88b35482711adeee0d8758bddfe958701 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Sat, 6 May 2023 14:32:00 +0200
-Subject: [PATCH] mtd: cfi_cmdset_0001: Disable write buffer functions if
- FORCE_WORD_WRITE is 1
-
-Some write buffer functions are not used when FORCE_WORD_WRITE is set to 1.
-So the compile warning messages are output if FORCE_WORD_WRITE is 1. To
-resolve this disable the write buffer functions if FORCE_WORD_WRITE is 1.
-
-This is similar fix to: 557c759036fc3976a5358cef23e65a263853b93f.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
----
- drivers/mtd/chips/cfi_cmdset_0001.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/mtd/chips/cfi_cmdset_0001.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
-@@ -61,8 +61,10 @@
-
- static int cfi_intelext_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
- static int cfi_intelext_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
-+#if !FORCE_WORD_WRITE
- static int cfi_intelext_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
- static int cfi_intelext_writev(struct mtd_info *, const struct kvec *, unsigned long, loff_t, size_t *);
-+#endif
- static int cfi_intelext_erase_varsize(struct mtd_info *, struct erase_info *);
- static void cfi_intelext_sync (struct mtd_info *);
- static int cfi_intelext_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
-@@ -304,6 +306,7 @@ static void fixup_use_point(struct mtd_i
- }
- }
-
-+#if !FORCE_WORD_WRITE
- static void fixup_use_write_buffers(struct mtd_info *mtd)
- {
- struct map_info *map = mtd->priv;
-@@ -314,6 +317,7 @@ static void fixup_use_write_buffers(stru
- mtd->_writev = cfi_intelext_writev;
- }
- }
-+#endif /* !FORCE_WORD_WRITE */
-
- /*
- * Some chips power-up with all sectors locked by default.
-@@ -1719,6 +1723,7 @@ static int cfi_intelext_write_words (str
- }
-
-
-+#if !FORCE_WORD_WRITE
- static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
- unsigned long adr, const struct kvec **pvec,
- unsigned long *pvec_seek, int len)
-@@ -1947,6 +1952,7 @@ static int cfi_intelext_write_buffers (s
-
- return cfi_intelext_writev(mtd, &vec, 1, to, retlen);
- }
-+#endif /* !FORCE_WORD_WRITE */
-
- static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
- unsigned long adr, int len, void *thunk)
+++ /dev/null
-From 49293bbc50cb7d44223eb49e0f7cb38e7dac2361 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 14 Sep 2021 23:21:01 +0200
-Subject: [PATCH 4/5] MIPS: lantiq: dma: make the burst length configurable by
- the drivers
-
-Make the burst length configurable by the drivers.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- .../include/asm/mach-lantiq/xway/xway_dma.h | 2 +-
- arch/mips/lantiq/xway/dma.c | 38 ++++++++++++++++---
- 2 files changed, 34 insertions(+), 6 deletions(-)
-
---- a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
-+++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
-@@ -45,6 +45,6 @@ extern void ltq_dma_close(struct ltq_dma
- extern void ltq_dma_alloc_tx(struct ltq_dma_channel *ch);
- extern void ltq_dma_alloc_rx(struct ltq_dma_channel *ch);
- extern void ltq_dma_free(struct ltq_dma_channel *ch);
--extern void ltq_dma_init_port(int p);
-+extern void ltq_dma_init_port(int p, int tx_burst, int rx_burst);
-
- #endif
---- a/arch/mips/lantiq/xway/dma.c
-+++ b/arch/mips/lantiq/xway/dma.c
-@@ -182,7 +182,7 @@ ltq_dma_free(struct ltq_dma_channel *ch)
- EXPORT_SYMBOL_GPL(ltq_dma_free);
-
- void
--ltq_dma_init_port(int p)
-+ltq_dma_init_port(int p, int tx_burst, int rx_burst)
- {
- ltq_dma_w32(p, LTQ_DMA_PS);
- switch (p) {
-@@ -191,16 +191,44 @@ ltq_dma_init_port(int p)
- * Tell the DMA engine to swap the endianness of data frames and
- * drop packets if the channel arbitration fails.
- */
-- ltq_dma_w32_mask(0, DMA_ETOP_ENDIANNESS | DMA_PDEN,
-+ ltq_dma_w32_mask(0, (DMA_ETOP_ENDIANNESS | DMA_PDEN),
- LTQ_DMA_PCTRL);
- break;
-
-- case DMA_PORT_DEU:
-- ltq_dma_w32((DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT) |
-- (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT),
-+ default:
-+ break;
-+ }
-+
-+ switch (rx_burst) {
-+ case 8:
-+ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_8W_BURST << DMA_RX_BURST_SHIFT),
- LTQ_DMA_PCTRL);
- break;
-+ case 4:
-+ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_4W_BURST << DMA_RX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
-+ case 2:
-+ ltq_dma_w32_mask(0x0c, (DMA_PCTRL_2W_BURST << DMA_RX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
-+ default:
-+ break;
-+ }
-
-+ switch (tx_burst) {
-+ case 8:
-+ ltq_dma_w32_mask(0x30, (DMA_PCTRL_8W_BURST << DMA_TX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
-+ case 4:
-+ ltq_dma_w32_mask(0x30, (DMA_PCTRL_4W_BURST << DMA_TX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
-+ case 2:
-+ ltq_dma_w32_mask(0x30, (DMA_PCTRL_2W_BURST << DMA_TX_BURST_SHIFT),
-+ LTQ_DMA_PCTRL);
-+ break;
- default:
- break;
- }
+++ /dev/null
-From 730320fd770d4114a2ecb6fb223dcc8c3cecdc5b Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 21 Sep 2022 22:59:44 +0200
-Subject: [PATCH] MIPS: lantiq: enable all hardware interrupts on second VPE
-
-This patch is needed to handle interrupts by the second VPE on the Lantiq
-ARX100, xRX200, xRX300 and xRX330 SoCs. Switching some ICU interrupts to
-the second VPE results in a hang. Currently, the vsmp_init_secondary()
-function is responsible for enabling these interrupts. It only enables
-Malta-specific interrupts (SW0, SW1, HW4 and HW5).
-
-The MIPS core has 8 interrupts defined. On Lantiq SoCs, hardware
-interrupts are wired to an ICU instance. Each VPE has an independent
-instance of the ICU. The mapping of the ICU interrupts is shown below:
-SW0(IP0) - IPI call,
-SW1(IP1) - IPI resched,
-HW0(IP2) - ICU 0-31,
-HW1(IP3) - ICU 32-63,
-HW2(IP4) - ICU 64-95,
-HW3(IP5) - ICU 96-127,
-HW4(IP6) - ICU 128-159,
-HW5(IP7) - timer.
-
-This patch enables all interrupt lines on the second VPE.
-
-This problem affects multithreaded SoCs with a custom interrupt controller.
-SOCs with 1004Kc core and newer use the MIPS GIC. At this point, I am aware
-that the Realtek RTL839x and RTL930x SoCs may need a similar fix. In the
-future, this may be replaced with some generic solution.
-
-Tested on Lantiq xRX200.
-
-Suggested-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/lantiq/prom.c | 26 ++++++++++++++++++++++++--
- 1 file changed, 24 insertions(+), 2 deletions(-)
-
---- a/arch/mips/lantiq/prom.c
-+++ b/arch/mips/lantiq/prom.c
-@@ -31,6 +31,14 @@ static struct ltq_soc_info soc_info;
- /* for Multithreading (APRP), vpe.c will use it */
- unsigned long cp0_memsize;
-
-+/*
-+ * These structs are used to override vsmp_init_secondary()
-+ */
-+#if defined(CONFIG_MIPS_MT_SMP)
-+extern const struct plat_smp_ops vsmp_smp_ops;
-+static struct plat_smp_ops lantiq_smp_ops;
-+#endif
-+
- const char *get_system_type(void)
- {
- return soc_info.sys_type;
-@@ -87,6 +95,17 @@ void __init device_tree_init(void)
- unflatten_and_copy_device_tree();
- }
-
-+#if defined(CONFIG_MIPS_MT_SMP)
-+static void lantiq_init_secondary(void)
-+{
-+ /*
-+ * MIPS CPU startup function vsmp_init_secondary() will only
-+ * enable some of the interrupts for the second CPU/VPE.
-+ */
-+ set_c0_status(ST0_IM);
-+}
-+#endif
-+
- void __init prom_init(void)
- {
- /* call the soc specific detetcion code and get it to fill soc_info */
-@@ -98,7 +117,10 @@ void __init prom_init(void)
- prom_init_cmdline();
-
- #if defined(CONFIG_MIPS_MT_SMP)
-- if (register_vsmp_smp_ops())
-- panic("failed to register_vsmp_smp_ops()");
-+ if (cpu_has_mipsmt) {
-+ lantiq_smp_ops = vsmp_smp_ops;
-+ lantiq_smp_ops.init_secondary = lantiq_init_secondary;
-+ register_smp_ops(&lantiq_smp_ops);
-+ }
- #endif
- }
+++ /dev/null
-From 4bf2a626dc4bb46f0754d8ac02ec8584ff114ad5 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Mon, 22 Jan 2024 19:47:09 +0100
-Subject: [PATCH] MIPS: lantiq: register smp_ops on non-smp platforms
-
-Lantiq uses a common kernel config for devices with 24Kc and 34Kc cores.
-The changes made previously to add support for interrupts on all cores
-work on 24Kc platforms with SMP disabled and 34Kc platforms with SMP
-enabled. This patch fixes boot issues on Danube (single core 24Kc) with
-SMP enabled.
-
-Fixes: 730320fd770d ("MIPS: lantiq: enable all hardware interrupts on second VPE")
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
----
- arch/mips/lantiq/prom.c | 7 +++----
- 1 file changed, 3 insertions(+), 4 deletions(-)
-
---- a/arch/mips/lantiq/prom.c
-+++ b/arch/mips/lantiq/prom.c
-@@ -117,10 +117,9 @@ void __init prom_init(void)
- prom_init_cmdline();
-
- #if defined(CONFIG_MIPS_MT_SMP)
-- if (cpu_has_mipsmt) {
-- lantiq_smp_ops = vsmp_smp_ops;
-+ lantiq_smp_ops = vsmp_smp_ops;
-+ if (cpu_has_mipsmt)
- lantiq_smp_ops.init_secondary = lantiq_init_secondary;
-- register_smp_ops(&lantiq_smp_ops);
-- }
-+ register_smp_ops(&lantiq_smp_ops);
- #endif
- }
+++ /dev/null
-From 416f25a948d11ef15733f2e31658d31b5cc7bef6 Mon Sep 17 00:00:00 2001
-From: Thomas Nixon <tom@tomn.co.uk>
-Date: Sun, 26 Mar 2023 11:08:49 +0100
-Subject: [PATCH] mtd: rawnand: xway: don't yield while holding spinlock
-
-The nand driver normally while waiting for the device to become ready;
-this is normally fine, but xway_nand holds the ebu_lock spinlock, and
-this can cause lockups if other threads which use ebu_lock are
-interleaved. Fix this by waiting instead of polling.
-
-This mainly showed up as crashes in ath9k_pci_owl_loader (see
-https://github.com/openwrt/openwrt/issues/9829 ), but turning on
-spinlock debugging shows this happening in other places too.
-
-This doesn't seem to measurably impact boot time.
-
-Signed-off-by: Thomas Nixon <tom@tomn.co.uk>
----
- drivers/mtd/nand/raw/xway_nand.c | 8 +++++++-
- 1 file changed, 7 insertions(+), 1 deletion(-)
-
---- a/drivers/mtd/nand/raw/xway_nand.c
-+++ b/drivers/mtd/nand/raw/xway_nand.c
-@@ -175,7 +175,13 @@ static void xway_cmd_ctrl(struct nand_ch
-
- static int xway_dev_ready(struct nand_chip *chip)
- {
-- return ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD;
-+ /*
-+ * wait until ready, as otherwise the driver will yield in nand_wait or
-+ * nand_wait_ready, which is a bad idea when we're holding ebu_lock
-+ */
-+ while ((ltq_ebu_r32(EBU_NAND_WAIT) & NAND_WAIT_RD) == 0)
-+ cpu_relax();
-+ return 1;
- }
-
- static unsigned char xway_read_byte(struct nand_chip *chip)
+++ /dev/null
-From 870ed9cae083ff8a60a739ef7e74c5a1800533be Mon Sep 17 00:00:00 2001
-From: Johann Neuhauser <johann@it-neuhauser.de>
-Date: Thu, 17 May 2018 19:12:35 +0200
-Subject: [PATCH] net: lantiq_etop: of mdio
-
-Signed-off-by: Johann Neuhauser <johann@it-neuhauser.de>
----
- drivers/net/ethernet/lantiq_etop.c | 555 +++++++++++++++++++++++++-----------
- 1 file changed, 389 insertions(+), 166 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -30,6 +30,7 @@
- #include <linux/of_net.h>
- #include <linux/of_irq.h>
- #include <linux/of_platform.h>
-+#include <linux/of_mdio.h>
-
- #include <asm/checksum.h>
-
-@@ -553,7 +554,8 @@ static int
- ltq_etop_mdio_init(struct net_device *dev)
- {
- struct ltq_etop_priv *priv = netdev_priv(dev);
-- int err;
-+ struct device_node *mdio_np = NULL;
-+ int err, ret;
-
- priv->mii_bus = mdiobus_alloc();
- if (!priv->mii_bus) {
-@@ -573,7 +575,15 @@ ltq_etop_mdio_init(struct net_device *de
- priv->mii_bus->name = "ltq_mii";
- snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
- priv->pdev->name, priv->pdev->id);
-- if (mdiobus_register(priv->mii_bus)) {
-+
-+ mdio_np = of_get_child_by_name(priv->pdev->dev.of_node, "mdio-bus");
-+
-+ if (mdio_np)
-+ ret = of_mdiobus_register(priv->mii_bus, mdio_np);
-+ else
-+ ret = mdiobus_register(priv->mii_bus);
-+
-+ if (ret) {
- err = -ENXIO;
- goto err_out_free_mdiobus;
- }
+++ /dev/null
-From 998ac358019e491217e752bc6dcbb3afb2a6fa3e Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Sun, 19 Sep 2021 20:24:28 +0200
-Subject: [PATCH] net: lantiq: add support for jumbo frames
-
-Add support for jumbo frames. Full support for jumbo frames requires
-changes in the DSA switch driver (lantiq_gswip.c).
-
-Tested on BT Hone Hub 5A.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_xrx200.c | 64 +++++++++++++++++++++++++---
- 1 file changed, 57 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -14,13 +14,15 @@
- #include <linux/clk.h>
- #include <linux/delay.h>
-
-+#include <linux/if_vlan.h>
-+
- #include <linux/of_net.h>
- #include <linux/of_platform.h>
-
- #include <xway_dma.h>
-
- /* DMA */
--#define XRX200_DMA_DATA_LEN 0x600
-+#define XRX200_DMA_DATA_LEN (SZ_64K - 1)
- #define XRX200_DMA_RX 0
- #define XRX200_DMA_TX 1
-
-@@ -106,7 +108,8 @@ static void xrx200_flush_dma(struct xrx2
- break;
-
- desc->ctl = LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
-- XRX200_DMA_DATA_LEN;
-+ (ch->priv->net_dev->mtu + VLAN_ETH_HLEN +
-+ ETH_FCS_LEN);
- ch->dma.desc++;
- ch->dma.desc %= LTQ_DESC_NUM;
- }
-@@ -154,19 +157,20 @@ static int xrx200_close(struct net_devic
-
- static int xrx200_alloc_skb(struct xrx200_chan *ch)
- {
-+ int len = ch->priv->net_dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
- struct sk_buff *skb = ch->skb[ch->dma.desc];
- dma_addr_t mapping;
- int ret = 0;
-
- ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(ch->priv->net_dev,
-- XRX200_DMA_DATA_LEN);
-+ len);
- if (!ch->skb[ch->dma.desc]) {
- ret = -ENOMEM;
- goto skip;
- }
-
- mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data,
-- XRX200_DMA_DATA_LEN, DMA_FROM_DEVICE);
-+ len, DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) {
- dev_kfree_skb_any(ch->skb[ch->dma.desc]);
- ch->skb[ch->dma.desc] = skb;
-@@ -179,8 +183,7 @@ static int xrx200_alloc_skb(struct xrx20
- wmb();
- skip:
- ch->dma.desc_base[ch->dma.desc].ctl =
-- LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
-- XRX200_DMA_DATA_LEN;
-+ LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | len;
-
- return ret;
- }
-@@ -340,10 +343,57 @@ err_drop:
- return NETDEV_TX_OK;
- }
-
-+static int
-+xrx200_change_mtu(struct net_device *net_dev, int new_mtu)
-+{
-+ struct xrx200_priv *priv = netdev_priv(net_dev);
-+ struct xrx200_chan *ch_rx = &priv->chan_rx;
-+ int old_mtu = net_dev->mtu;
-+ bool running = false;
-+ struct sk_buff *skb;
-+ int curr_desc;
-+ int ret = 0;
-+
-+ net_dev->mtu = new_mtu;
-+
-+ if (new_mtu <= old_mtu)
-+ return ret;
-+
-+ running = netif_running(net_dev);
-+ if (running) {
-+ napi_disable(&ch_rx->napi);
-+ ltq_dma_close(&ch_rx->dma);
-+ }
-+
-+ xrx200_poll_rx(&ch_rx->napi, LTQ_DESC_NUM);
-+ curr_desc = ch_rx->dma.desc;
-+
-+ for (ch_rx->dma.desc = 0; ch_rx->dma.desc < LTQ_DESC_NUM;
-+ ch_rx->dma.desc++) {
-+ skb = ch_rx->skb[ch_rx->dma.desc];
-+ ret = xrx200_alloc_skb(ch_rx);
-+ if (ret) {
-+ net_dev->mtu = old_mtu;
-+ break;
-+ }
-+ dev_kfree_skb_any(skb);
-+ }
-+
-+ ch_rx->dma.desc = curr_desc;
-+ if (running) {
-+ napi_enable(&ch_rx->napi);
-+ ltq_dma_open(&ch_rx->dma);
-+ ltq_dma_enable_irq(&ch_rx->dma);
-+ }
-+
-+ return ret;
-+}
-+
- static const struct net_device_ops xrx200_netdev_ops = {
- .ndo_open = xrx200_open,
- .ndo_stop = xrx200_close,
- .ndo_start_xmit = xrx200_start_xmit,
-+ .ndo_change_mtu = xrx200_change_mtu,
- .ndo_set_mac_address = eth_mac_addr,
- .ndo_validate_addr = eth_validate_addr,
- };
-@@ -453,7 +503,7 @@ static int xrx200_probe(struct platform_
- net_dev->netdev_ops = &xrx200_netdev_ops;
- SET_NETDEV_DEV(net_dev, dev);
- net_dev->min_mtu = ETH_ZLEN;
-- net_dev->max_mtu = XRX200_DMA_DATA_LEN;
-+ net_dev->max_mtu = XRX200_DMA_DATA_LEN - VLAN_ETH_HLEN - ETH_FCS_LEN;
-
- /* load the memory ranges */
- priv->pmac_reg = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+++ /dev/null
-From 1488fc204568f707fe2a42a913788c00a95af30e Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Fri, 17 Dec 2021 01:07:40 +0100
-Subject: [PATCH] net: lantiq_xrx200: increase buffer reservation
-
-If the user sets a lower mtu on the CPU port than on the switch,
-then DMA inserts a few more bytes into the buffer than expected.
-In the worst case, it may exceed the size of the buffer. The
-experiments showed that the buffer should be a multiple of the
-burst length value. This patch rounds the length of the rx buffer
-upwards and fixes this bug. The reservation of FCS space in the
-buffer has been removed as PMAC strips the FCS.
-
-Fixes: 998ac358019e ("net: lantiq: add support for jumbo frames")
-Reported-by: Thomas Nixon <tom@tomn.co.uk>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 34 ++++++++++++++++++++--------
- 1 file changed, 24 insertions(+), 10 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -70,6 +70,8 @@ struct xrx200_priv {
- struct xrx200_chan chan_tx;
- struct xrx200_chan chan_rx;
-
-+ u16 rx_buf_size;
-+
- struct net_device *net_dev;
- struct device *dev;
-
-@@ -96,6 +98,16 @@ static void xrx200_pmac_mask(struct xrx2
- xrx200_pmac_w32(priv, val, offset);
- }
-
-+static int xrx200_max_frame_len(int mtu)
-+{
-+ return VLAN_ETH_HLEN + mtu;
-+}
-+
-+static int xrx200_buffer_size(int mtu)
-+{
-+ return round_up(xrx200_max_frame_len(mtu), 4 * XRX200_DMA_BURST_LEN);
-+}
-+
- /* drop all the packets from the DMA ring */
- static void xrx200_flush_dma(struct xrx200_chan *ch)
- {
-@@ -108,8 +120,7 @@ static void xrx200_flush_dma(struct xrx2
- break;
-
- desc->ctl = LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) |
-- (ch->priv->net_dev->mtu + VLAN_ETH_HLEN +
-- ETH_FCS_LEN);
-+ ch->priv->rx_buf_size;
- ch->dma.desc++;
- ch->dma.desc %= LTQ_DESC_NUM;
- }
-@@ -157,21 +168,21 @@ static int xrx200_close(struct net_devic
-
- static int xrx200_alloc_skb(struct xrx200_chan *ch)
- {
-- int len = ch->priv->net_dev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
- struct sk_buff *skb = ch->skb[ch->dma.desc];
-+ struct xrx200_priv *priv = ch->priv;
- dma_addr_t mapping;
- int ret = 0;
-
-- ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(ch->priv->net_dev,
-- len);
-+ ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(priv->net_dev,
-+ priv->rx_buf_size);
- if (!ch->skb[ch->dma.desc]) {
- ret = -ENOMEM;
- goto skip;
- }
-
-- mapping = dma_map_single(ch->priv->dev, ch->skb[ch->dma.desc]->data,
-- len, DMA_FROM_DEVICE);
-- if (unlikely(dma_mapping_error(ch->priv->dev, mapping))) {
-+ mapping = dma_map_single(priv->dev, ch->skb[ch->dma.desc]->data,
-+ priv->rx_buf_size, DMA_FROM_DEVICE);
-+ if (unlikely(dma_mapping_error(priv->dev, mapping))) {
- dev_kfree_skb_any(ch->skb[ch->dma.desc]);
- ch->skb[ch->dma.desc] = skb;
- ret = -ENOMEM;
-@@ -183,7 +194,7 @@ static int xrx200_alloc_skb(struct xrx20
- wmb();
- skip:
- ch->dma.desc_base[ch->dma.desc].ctl =
-- LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | len;
-+ LTQ_DMA_OWN | LTQ_DMA_RX_OFFSET(NET_IP_ALIGN) | priv->rx_buf_size;
-
- return ret;
- }
-@@ -355,6 +366,7 @@ xrx200_change_mtu(struct net_device *net
- int ret = 0;
-
- net_dev->mtu = new_mtu;
-+ priv->rx_buf_size = xrx200_buffer_size(new_mtu);
-
- if (new_mtu <= old_mtu)
- return ret;
-@@ -374,6 +386,7 @@ xrx200_change_mtu(struct net_device *net
- ret = xrx200_alloc_skb(ch_rx);
- if (ret) {
- net_dev->mtu = old_mtu;
-+ priv->rx_buf_size = xrx200_buffer_size(old_mtu);
- break;
- }
- dev_kfree_skb_any(skb);
-@@ -503,7 +516,8 @@ static int xrx200_probe(struct platform_
- net_dev->netdev_ops = &xrx200_netdev_ops;
- SET_NETDEV_DEV(net_dev, dev);
- net_dev->min_mtu = ETH_ZLEN;
-- net_dev->max_mtu = XRX200_DMA_DATA_LEN - VLAN_ETH_HLEN - ETH_FCS_LEN;
-+ net_dev->max_mtu = XRX200_DMA_DATA_LEN - xrx200_max_frame_len(0);
-+ priv->rx_buf_size = xrx200_buffer_size(ETH_DATA_LEN);
-
- /* load the memory ranges */
- priv->pmac_reg = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+++ /dev/null
-From c3e6b2c35b34214c58c1e90d65dab5f5393608e7 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Mon, 3 Jan 2022 20:43:16 +0100
-Subject: [PATCH] net: lantiq_xrx200: add ingress SG DMA support
-
-This patch adds support for scatter gather DMA. DMA in PMAC splits
-the packet into several buffers when the MTU on the CPU port is
-less than the MTU of the switch. The first buffer starts at an
-offset of NET_IP_ALIGN. In subsequent buffers, dma ignores the
-offset. Thanks to this patch, the user can still connect to the
-device in such a situation. For normal configurations, the patch
-has no effect on performance.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_xrx200.c | 47 +++++++++++++++++++++++-----
- 1 file changed, 40 insertions(+), 7 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -26,6 +26,9 @@
- #define XRX200_DMA_RX 0
- #define XRX200_DMA_TX 1
-
-+#define XRX200_DMA_PACKET_COMPLETE 0
-+#define XRX200_DMA_PACKET_IN_PROGRESS 1
-+
- /* cpu port mac */
- #define PMAC_RX_IPG 0x0024
- #define PMAC_RX_IPG_MASK 0xf
-@@ -61,6 +64,9 @@ struct xrx200_chan {
- struct ltq_dma_channel dma;
- struct sk_buff *skb[LTQ_DESC_NUM];
-
-+ struct sk_buff *skb_head;
-+ struct sk_buff *skb_tail;
-+
- struct xrx200_priv *priv;
- };
-
-@@ -204,7 +210,8 @@ static int xrx200_hw_receive(struct xrx2
- struct xrx200_priv *priv = ch->priv;
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
- struct sk_buff *skb = ch->skb[ch->dma.desc];
-- int len = (desc->ctl & LTQ_DMA_SIZE_MASK);
-+ u32 ctl = desc->ctl;
-+ int len = (ctl & LTQ_DMA_SIZE_MASK);
- struct net_device *net_dev = priv->net_dev;
- int ret;
-
-@@ -220,12 +227,36 @@ static int xrx200_hw_receive(struct xrx2
- }
-
- skb_put(skb, len);
-- skb->protocol = eth_type_trans(skb, net_dev);
-- netif_receive_skb(skb);
-- net_dev->stats.rx_packets++;
-- net_dev->stats.rx_bytes += len;
-
-- return 0;
-+ /* add buffers to skb via skb->frag_list */
-+ if (ctl & LTQ_DMA_SOP) {
-+ ch->skb_head = skb;
-+ ch->skb_tail = skb;
-+ } else if (ch->skb_head) {
-+ if (ch->skb_head == ch->skb_tail)
-+ skb_shinfo(ch->skb_tail)->frag_list = skb;
-+ else
-+ ch->skb_tail->next = skb;
-+ ch->skb_tail = skb;
-+ skb_reserve(ch->skb_tail, -NET_IP_ALIGN);
-+ ch->skb_head->len += skb->len;
-+ ch->skb_head->data_len += skb->len;
-+ ch->skb_head->truesize += skb->truesize;
-+ }
-+
-+ if (ctl & LTQ_DMA_EOP) {
-+ ch->skb_head->protocol = eth_type_trans(ch->skb_head, net_dev);
-+ netif_receive_skb(ch->skb_head);
-+ net_dev->stats.rx_packets++;
-+ net_dev->stats.rx_bytes += ch->skb_head->len;
-+ ch->skb_head = NULL;
-+ ch->skb_tail = NULL;
-+ ret = XRX200_DMA_PACKET_COMPLETE;
-+ } else {
-+ ret = XRX200_DMA_PACKET_IN_PROGRESS;
-+ }
-+
-+ return ret;
- }
-
- static int xrx200_poll_rx(struct napi_struct *napi, int budget)
-@@ -240,7 +271,9 @@ static int xrx200_poll_rx(struct napi_st
-
- if ((desc->ctl & (LTQ_DMA_OWN | LTQ_DMA_C)) == LTQ_DMA_C) {
- ret = xrx200_hw_receive(ch);
-- if (ret)
-+ if (ret == XRX200_DMA_PACKET_IN_PROGRESS)
-+ continue;
-+ if (ret != XRX200_DMA_PACKET_COMPLETE)
- return ret;
- rx++;
- } else {
+++ /dev/null
-From c40bb4fedcd6b8b6a714da5dd466eb88ed2652d1 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 9 Mar 2022 00:04:57 +0100
-Subject: net: dsa: lantiq_gswip: enable jumbo frames on GSWIP
-
-This enables non-standard MTUs on a per-port basis, with the overall
-frame size set based on the CPU port.
-
-When the MTU is not changed, this should have no effect.
-
-Long packets crash the switch with MTUs of greater than 2526, so the
-maximum is limited for now. Medium packets are sometimes dropped (e.g.
-TCP over 2477, UDP over 2516-2519, ICMP over 2526), Hence an MTU value
-of 2400 seems safe.
-
-Signed-off-by: Thomas Nixon <tom@tomn.co.uk>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Link: https://lore.kernel.org/r/20220308230457.1599237-1-olek2@wp.pl
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/dsa/lantiq_gswip.c | 53 ++++++++++++++++++++++++++++++++++++++----
- 1 file changed, 49 insertions(+), 4 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -213,6 +213,7 @@
- #define GSWIP_MAC_CTRL_0_GMII_MII 0x0001
- #define GSWIP_MAC_CTRL_0_GMII_RGMII 0x0002
- #define GSWIP_MAC_CTRL_2p(p) (0x905 + ((p) * 0xC))
-+#define GSWIP_MAC_CTRL_2_LCHKL BIT(2) /* Frame Length Check Long Enable */
- #define GSWIP_MAC_CTRL_2_MLEN BIT(3) /* Maximum Untagged Frame Lnegth */
-
- /* Ethernet Switch Fetch DMA Port Control Register */
-@@ -239,6 +240,15 @@
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-+/* Maximum packet size supported by the switch. In theory this should be 10240,
-+ * but long packets currently cause lock-ups with an MTU of over 2526. Medium
-+ * packets are sometimes dropped (e.g. TCP over 2477, UDP over 2516-2519, ICMP
-+ * over 2526), hence an MTU value of 2400 seems safe. This issue only affects
-+ * packet reception. This is probably caused by the PPA engine, which is on the
-+ * RX part of the device. Packet transmission works properly up to 10240.
-+ */
-+#define GSWIP_MAX_PACKET_LENGTH 2400
-+
- struct gswip_hw_info {
- int max_ports;
- int cpu_port;
-@@ -846,10 +856,6 @@ static int gswip_setup(struct dsa_switch
- gswip_switch_mask(priv, 0, GSWIP_PCE_PCTRL_0_INGRESS,
- GSWIP_PCE_PCTRL_0p(cpu_port));
-
-- gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
-- GSWIP_MAC_CTRL_2p(cpu_port));
-- gswip_switch_w(priv, VLAN_ETH_FRAME_LEN + 8 + ETH_FCS_LEN,
-- GSWIP_MAC_FLEN);
- gswip_switch_mask(priv, 0, GSWIP_BM_QUEUE_GCTRL_GL_MOD,
- GSWIP_BM_QUEUE_GCTRL);
-
-@@ -866,6 +872,8 @@ static int gswip_setup(struct dsa_switch
- return err;
- }
-
-+ ds->mtu_enforcement_ingress = true;
-+
- gswip_port_enable(ds, cpu_port, NULL);
-
- ds->configure_vlan_while_not_filtering = false;
-@@ -1456,6 +1464,39 @@ static void gswip_phylink_set_capab(unsi
- linkmode_and(state->advertising, state->advertising, mask);
- }
-
-+static int gswip_port_max_mtu(struct dsa_switch *ds, int port)
-+{
-+ /* Includes 8 bytes for special header. */
-+ return GSWIP_MAX_PACKET_LENGTH - VLAN_ETH_HLEN - ETH_FCS_LEN;
-+}
-+
-+static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
-+{
-+ struct gswip_priv *priv = ds->priv;
-+ int cpu_port = priv->hw_info->cpu_port;
-+
-+ /* CPU port always has maximum mtu of user ports, so use it to set
-+ * switch frame size, including 8 byte special header.
-+ */
-+ if (port == cpu_port) {
-+ new_mtu += 8;
-+ gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
-+ GSWIP_MAC_FLEN);
-+ }
-+
-+ /* Enable MLEN for ports with non-standard MTUs, including the special
-+ * header on the CPU port added above.
-+ */
-+ if (new_mtu != ETH_DATA_LEN)
-+ gswip_switch_mask(priv, 0, GSWIP_MAC_CTRL_2_MLEN,
-+ GSWIP_MAC_CTRL_2p(port));
-+ else
-+ gswip_switch_mask(priv, GSWIP_MAC_CTRL_2_MLEN, 0,
-+ GSWIP_MAC_CTRL_2p(port));
-+
-+ return 0;
-+}
-+
- static void gswip_xrx200_phylink_validate(struct dsa_switch *ds, int port,
- unsigned long *supported,
- struct phylink_link_state *state)
-@@ -1812,6 +1853,8 @@ static const struct dsa_switch_ops gswip
- .port_fdb_add = gswip_port_fdb_add,
- .port_fdb_del = gswip_port_fdb_del,
- .port_fdb_dump = gswip_port_fdb_dump,
-+ .port_change_mtu = gswip_port_change_mtu,
-+ .port_max_mtu = gswip_port_max_mtu,
- .phylink_validate = gswip_xrx200_phylink_validate,
- .phylink_mac_config = gswip_phylink_mac_config,
- .phylink_mac_link_down = gswip_phylink_mac_link_down,
-@@ -1836,6 +1879,8 @@ static const struct dsa_switch_ops gswip
- .port_fdb_add = gswip_port_fdb_add,
- .port_fdb_del = gswip_port_fdb_del,
- .port_fdb_dump = gswip_port_fdb_dump,
-+ .port_change_mtu = gswip_port_change_mtu,
-+ .port_max_mtu = gswip_port_max_mtu,
- .phylink_validate = gswip_xrx300_phylink_validate,
- .phylink_mac_config = gswip_phylink_mac_config,
- .phylink_mac_link_down = gswip_phylink_mac_link_down,
+++ /dev/null
-From 14d4e308e0aa0b78dc7a059716861a4380de3535 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 14 Sep 2021 23:21:02 +0200
-Subject: [PATCH 5/5] net: lantiq: configure the burst length in ethernet
- drivers
-
-Configure the burst length in Ethernet drivers. This improves
-Ethernet performance by 58%. According to the vendor BSP,
-8W burst length is supported by ar9 and newer SoCs.
-
-The NAT benchmark results on xRX200 (Down/Up):
-* 2W: 330 Mb/s
-* 4W: 432 Mb/s 372 Mb/s
-* 8W: 520 Mb/s 389 Mb/s
-
-Tested on xRX200 and xRX330.
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_etop.c | 21 ++++++++++++++++++---
- drivers/net/ethernet/lantiq_xrx200.c | 21 ++++++++++++++++++---
- 2 files changed, 36 insertions(+), 6 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -148,6 +148,9 @@ struct ltq_etop_priv {
- struct ltq_etop_chan txch;
- struct ltq_etop_chan rxch;
-
-+ int tx_burst_len;
-+ int rx_burst_len;
-+
- int tx_irq;
- int rx_irq;
-
-@@ -399,7 +402,7 @@ ltq_etop_dma_init(struct net_device *dev
- int rx = priv->rx_irq - LTQ_DMA_ETOP;
- int err;
-
-- ltq_dma_init_port(DMA_PORT_ETOP);
-+ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
-
- priv->txch.dma.nr = tx;
- priv->txch.dma.dev = &priv->pdev->dev;
-@@ -676,8 +679,8 @@ ltq_etop_tx(struct sk_buff *skb, struct
- return NETDEV_TX_BUSY;
- }
-
-- /* dma needs to start on a 16 byte aligned address */
-- byte_offset = CPHYSADDR(skb->data) % 16;
-+ /* dma needs to start on a burst length value aligned address */
-+ byte_offset = CPHYSADDR(skb->data) % (priv->tx_burst_len * 4);
- priv->txch.skb[priv->txch.dma.desc] = skb;
-
- netif_trans_update(dev);
-@@ -925,6 +928,18 @@ static int ltq_etop_probe(struct platfor
- spin_lock_init(&priv->lock);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
-+ err = device_property_read_u32(&pdev->dev, "lantiq,tx-burst-length", &priv->tx_burst_len);
-+ if (err < 0) {
-+ dev_err(&pdev->dev, "unable to read tx-burst-length property\n");
-+ return err;
-+ }
-+
-+ err = device_property_read_u32(&pdev->dev, "lantiq,rx-burst-length", &priv->rx_burst_len);
-+ if (err < 0) {
-+ dev_err(&pdev->dev, "unable to read rx-burst-length property\n");
-+ return err;
-+ }
-+
- netif_napi_add(dev, &priv->txch.napi, ltq_etop_poll_tx, 8);
- netif_napi_add(dev, &priv->rxch.napi, ltq_etop_poll_rx, 32);
- priv->txch.netdev = dev;
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -81,6 +81,9 @@ struct xrx200_priv {
- struct net_device *net_dev;
- struct device *dev;
-
-+ int tx_burst_len;
-+ int rx_burst_len;
-+
- __iomem void *pmac_reg;
- };
-
-@@ -363,8 +366,8 @@ static netdev_tx_t xrx200_start_xmit(str
- if (unlikely(dma_mapping_error(priv->dev, mapping)))
- goto err_drop;
-
-- /* dma needs to start on a 16 byte aligned address */
-- byte_offset = mapping % 16;
-+ /* dma needs to start on a burst length value aligned address */
-+ byte_offset = mapping % (priv->tx_burst_len * 4);
-
- desc->addr = mapping - byte_offset;
- /* Make sure the address is written before we give it to HW */
-@@ -465,7 +468,7 @@ static int xrx200_dma_init(struct xrx200
- int ret = 0;
- int i;
-
-- ltq_dma_init_port(DMA_PORT_ETOP);
-+ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
-
- ch_rx->dma.nr = XRX200_DMA_RX;
- ch_rx->dma.dev = priv->dev;
-@@ -575,6 +578,18 @@ static int xrx200_probe(struct platform_
- if (err)
- eth_hw_addr_random(net_dev);
-
-+ err = device_property_read_u32(dev, "lantiq,tx-burst-length", &priv->tx_burst_len);
-+ if (err < 0) {
-+ dev_err(dev, "unable to read tx-burst-length property\n");
-+ return err;
-+ }
-+
-+ err = device_property_read_u32(dev, "lantiq,rx-burst-length", &priv->rx_burst_len);
-+ if (err < 0) {
-+ dev_err(dev, "unable to read rx-burst-length property\n");
-+ return err;
-+ }
-+
- /* bring up the dma engine and IP core */
- err = xrx200_dma_init(priv);
- if (err)
+++ /dev/null
-From 7e553c44f09a8f536090904c6db5b8c9dbafa03b Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 26 Oct 2021 22:59:01 +0200
-Subject: [PATCH] net: lantiq_xrx200: Hardcode the burst length value
-
-All SoCs with this IP core support 8 burst length. Hauke
-suggested to hardcode this value and simplify the driver.
-
-Link: https://lkml.org/lkml/2021/9/14/1533
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_xrx200.c | 21 ++++-----------------
- 1 file changed, 4 insertions(+), 17 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -25,6 +25,7 @@
- #define XRX200_DMA_DATA_LEN (SZ_64K - 1)
- #define XRX200_DMA_RX 0
- #define XRX200_DMA_TX 1
-+#define XRX200_DMA_BURST_LEN 8
-
- #define XRX200_DMA_PACKET_COMPLETE 0
- #define XRX200_DMA_PACKET_IN_PROGRESS 1
-@@ -81,9 +82,6 @@ struct xrx200_priv {
- struct net_device *net_dev;
- struct device *dev;
-
-- int tx_burst_len;
-- int rx_burst_len;
--
- __iomem void *pmac_reg;
- };
-
-@@ -367,7 +365,7 @@ static netdev_tx_t xrx200_start_xmit(str
- goto err_drop;
-
- /* dma needs to start on a burst length value aligned address */
-- byte_offset = mapping % (priv->tx_burst_len * 4);
-+ byte_offset = mapping % (XRX200_DMA_BURST_LEN * 4);
-
- desc->addr = mapping - byte_offset;
- /* Make sure the address is written before we give it to HW */
-@@ -468,7 +466,8 @@ static int xrx200_dma_init(struct xrx200
- int ret = 0;
- int i;
-
-- ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
-+ ltq_dma_init_port(DMA_PORT_ETOP, XRX200_DMA_BURST_LEN,
-+ XRX200_DMA_BURST_LEN);
-
- ch_rx->dma.nr = XRX200_DMA_RX;
- ch_rx->dma.dev = priv->dev;
-@@ -578,18 +577,6 @@ static int xrx200_probe(struct platform_
- if (err)
- eth_hw_addr_random(net_dev);
-
-- err = device_property_read_u32(dev, "lantiq,tx-burst-length", &priv->tx_burst_len);
-- if (err < 0) {
-- dev_err(dev, "unable to read tx-burst-length property\n");
-- return err;
-- }
--
-- err = device_property_read_u32(dev, "lantiq,rx-burst-length", &priv->rx_burst_len);
-- if (err < 0) {
-- dev_err(dev, "unable to read rx-burst-length property\n");
-- return err;
-- }
--
- /* bring up the dma engine and IP core */
- err = xrx200_dma_init(priv);
- if (err)
+++ /dev/null
-From 68eabc348148ae051631e8dab13c3b1a85c82896 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 9 Nov 2021 23:23:54 +0100
-Subject: [PATCH] net: ethernet: lantiq_etop: Fix compilation error
-
-This fixes the error detected when compiling the driver.
-
-Fixes: 14d4e308e0aa ("net: lantiq: configure the burst length in ethernet drivers")
-Reported-by: kernel test robot <lkp@intel.com>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_etop.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/lantiq_etop.c
-+++ b/drivers/net/ethernet/lantiq_etop.c
-@@ -402,7 +402,7 @@ ltq_etop_dma_init(struct net_device *dev
- int rx = priv->rx_irq - LTQ_DMA_ETOP;
- int err;
-
-- ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, rx_burst_len);
-+ ltq_dma_init_port(DMA_PORT_ETOP, priv->tx_burst_len, priv->rx_burst_len);
-
- priv->txch.dma.nr = tx;
- priv->txch.dma.dev = &priv->pdev->dev;
+++ /dev/null
-From 5112e9234bbb89f8dd15c983206bd9107b8436d5 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 4 Jan 2022 16:11:42 +0100
-Subject: [PATCH 713/715] MIPS: lantiq: dma: increase descritor count
-
-NAT Performance results on BT Home Hub 5A (kernel 5.10.89, mtu 1500):
-
- Down Up
-Before 539 Mbps 599 Mbps
-After 545 Mbps 625 Mbps
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- arch/mips/include/asm/mach-lantiq/xway/xway_dma.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
-+++ b/arch/mips/include/asm/mach-lantiq/xway/xway_dma.h
-@@ -8,7 +8,7 @@
- #define LTQ_DMA_H__
-
- #define LTQ_DESC_SIZE 0x08 /* each descriptor is 64bit */
--#define LTQ_DESC_NUM 0x40 /* 64 descriptors / channel */
-+#define LTQ_DESC_NUM 0xC0 /* 192 descriptors / channel */
-
- #define LTQ_DMA_OWN BIT(31) /* owner bit */
- #define LTQ_DMA_C BIT(30) /* complete bit */
+++ /dev/null
-From 768818d772d5d4ddc0c7eb2e62848929270ab7a3 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 4 Jan 2022 16:11:43 +0100
-Subject: [PATCH 714/715] net: lantiq_xrx200: increase napi poll weigth
-
-NAT Performance results on BT Home Hub 5A (kernel 5.10.89, mtu 1500):
-
- Down Up
-Before 545 Mbps 625 Mbps
-After 577 Mbps 648 Mbps
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 6 ++++--
- 1 file changed, 4 insertions(+), 2 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -597,8 +597,10 @@ static int xrx200_probe(struct platform_
- PMAC_HD_CTL);
-
- /* setup NAPI */
-- netif_napi_add(net_dev, &priv->chan_rx.napi, xrx200_poll_rx, 32);
-- netif_tx_napi_add(net_dev, &priv->chan_tx.napi, xrx200_tx_housekeeping, 32);
-+ netif_napi_add(net_dev, &priv->chan_rx.napi, xrx200_poll_rx,
-+ NAPI_POLL_WEIGHT);
-+ netif_tx_napi_add(net_dev, &priv->chan_tx.napi, xrx200_tx_housekeeping,
-+ NAPI_POLL_WEIGHT);
-
- platform_set_drvdata(pdev, priv);
-
+++ /dev/null
-From e015593573b3e3f74bd8a63c05fa92902194a354 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Tue, 4 Jan 2022 16:11:44 +0100
-Subject: [PATCH 715/715] net: lantiq_xrx200: convert to build_skb
-
-We can increase the efficiency of rx path by using buffers to receive
-packets then build SKBs around them just before passing into the network
-stack. In contrast, preallocating SKBs too early reduces CPU cache
-efficiency.
-
-NAT Performance results on BT Home Hub 5A (kernel 5.10.89, mtu 1500):
-
- Down Up
-Before 577 Mbps 648 Mbps
-After 624 Mbps 695 Mbps
-
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 56 ++++++++++++++++++----------
- 1 file changed, 36 insertions(+), 20 deletions(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -63,7 +63,11 @@ struct xrx200_chan {
-
- struct napi_struct napi;
- struct ltq_dma_channel dma;
-- struct sk_buff *skb[LTQ_DESC_NUM];
-+
-+ union {
-+ struct sk_buff *skb[LTQ_DESC_NUM];
-+ void *rx_buff[LTQ_DESC_NUM];
-+ };
-
- struct sk_buff *skb_head;
- struct sk_buff *skb_tail;
-@@ -78,6 +82,7 @@ struct xrx200_priv {
- struct xrx200_chan chan_rx;
-
- u16 rx_buf_size;
-+ u16 rx_skb_size;
-
- struct net_device *net_dev;
- struct device *dev;
-@@ -115,6 +120,12 @@ static int xrx200_buffer_size(int mtu)
- return round_up(xrx200_max_frame_len(mtu), 4 * XRX200_DMA_BURST_LEN);
- }
-
-+static int xrx200_skb_size(u16 buf_size)
-+{
-+ return SKB_DATA_ALIGN(buf_size + NET_SKB_PAD + NET_IP_ALIGN) +
-+ SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
-+}
-+
- /* drop all the packets from the DMA ring */
- static void xrx200_flush_dma(struct xrx200_chan *ch)
- {
-@@ -173,30 +184,29 @@ static int xrx200_close(struct net_devic
- return 0;
- }
-
--static int xrx200_alloc_skb(struct xrx200_chan *ch)
-+static int xrx200_alloc_buf(struct xrx200_chan *ch, void *(*alloc)(unsigned int size))
- {
-- struct sk_buff *skb = ch->skb[ch->dma.desc];
-+ void *buf = ch->rx_buff[ch->dma.desc];
- struct xrx200_priv *priv = ch->priv;
- dma_addr_t mapping;
- int ret = 0;
-
-- ch->skb[ch->dma.desc] = netdev_alloc_skb_ip_align(priv->net_dev,
-- priv->rx_buf_size);
-- if (!ch->skb[ch->dma.desc]) {
-+ ch->rx_buff[ch->dma.desc] = alloc(priv->rx_skb_size);
-+ if (!ch->rx_buff[ch->dma.desc]) {
- ret = -ENOMEM;
- goto skip;
- }
-
-- mapping = dma_map_single(priv->dev, ch->skb[ch->dma.desc]->data,
-+ mapping = dma_map_single(priv->dev, ch->rx_buff[ch->dma.desc],
- priv->rx_buf_size, DMA_FROM_DEVICE);
- if (unlikely(dma_mapping_error(priv->dev, mapping))) {
-- dev_kfree_skb_any(ch->skb[ch->dma.desc]);
-- ch->skb[ch->dma.desc] = skb;
-+ skb_free_frag(ch->rx_buff[ch->dma.desc]);
-+ ch->rx_buff[ch->dma.desc] = buf;
- ret = -ENOMEM;
- goto skip;
- }
-
-- ch->dma.desc_base[ch->dma.desc].addr = mapping;
-+ ch->dma.desc_base[ch->dma.desc].addr = mapping + NET_SKB_PAD + NET_IP_ALIGN;
- /* Make sure the address is written before we give it to HW */
- wmb();
- skip:
-@@ -210,13 +220,14 @@ static int xrx200_hw_receive(struct xrx2
- {
- struct xrx200_priv *priv = ch->priv;
- struct ltq_dma_desc *desc = &ch->dma.desc_base[ch->dma.desc];
-- struct sk_buff *skb = ch->skb[ch->dma.desc];
-+ void *buf = ch->rx_buff[ch->dma.desc];
- u32 ctl = desc->ctl;
- int len = (ctl & LTQ_DMA_SIZE_MASK);
- struct net_device *net_dev = priv->net_dev;
-+ struct sk_buff *skb;
- int ret;
-
-- ret = xrx200_alloc_skb(ch);
-+ ret = xrx200_alloc_buf(ch, napi_alloc_frag);
-
- ch->dma.desc++;
- ch->dma.desc %= LTQ_DESC_NUM;
-@@ -227,19 +238,21 @@ static int xrx200_hw_receive(struct xrx2
- return ret;
- }
-
-+ skb = build_skb(buf, priv->rx_skb_size);
-+ skb_reserve(skb, NET_SKB_PAD);
- skb_put(skb, len);
-
- /* add buffers to skb via skb->frag_list */
- if (ctl & LTQ_DMA_SOP) {
- ch->skb_head = skb;
- ch->skb_tail = skb;
-+ skb_reserve(skb, NET_IP_ALIGN);
- } else if (ch->skb_head) {
- if (ch->skb_head == ch->skb_tail)
- skb_shinfo(ch->skb_tail)->frag_list = skb;
- else
- ch->skb_tail->next = skb;
- ch->skb_tail = skb;
-- skb_reserve(ch->skb_tail, -NET_IP_ALIGN);
- ch->skb_head->len += skb->len;
- ch->skb_head->data_len += skb->len;
- ch->skb_head->truesize += skb->truesize;
-@@ -395,12 +408,13 @@ xrx200_change_mtu(struct net_device *net
- struct xrx200_chan *ch_rx = &priv->chan_rx;
- int old_mtu = net_dev->mtu;
- bool running = false;
-- struct sk_buff *skb;
-+ void *buff;
- int curr_desc;
- int ret = 0;
-
- net_dev->mtu = new_mtu;
- priv->rx_buf_size = xrx200_buffer_size(new_mtu);
-+ priv->rx_skb_size = xrx200_skb_size(priv->rx_buf_size);
-
- if (new_mtu <= old_mtu)
- return ret;
-@@ -416,14 +430,15 @@ xrx200_change_mtu(struct net_device *net
-
- for (ch_rx->dma.desc = 0; ch_rx->dma.desc < LTQ_DESC_NUM;
- ch_rx->dma.desc++) {
-- skb = ch_rx->skb[ch_rx->dma.desc];
-- ret = xrx200_alloc_skb(ch_rx);
-+ buff = ch_rx->rx_buff[ch_rx->dma.desc];
-+ ret = xrx200_alloc_buf(ch_rx, netdev_alloc_frag);
- if (ret) {
- net_dev->mtu = old_mtu;
- priv->rx_buf_size = xrx200_buffer_size(old_mtu);
-+ priv->rx_skb_size = xrx200_skb_size(priv->rx_buf_size);
- break;
- }
-- dev_kfree_skb_any(skb);
-+ skb_free_frag(buff);
- }
-
- ch_rx->dma.desc = curr_desc;
-@@ -476,7 +491,7 @@ static int xrx200_dma_init(struct xrx200
- ltq_dma_alloc_rx(&ch_rx->dma);
- for (ch_rx->dma.desc = 0; ch_rx->dma.desc < LTQ_DESC_NUM;
- ch_rx->dma.desc++) {
-- ret = xrx200_alloc_skb(ch_rx);
-+ ret = xrx200_alloc_buf(ch_rx, netdev_alloc_frag);
- if (ret)
- goto rx_free;
- }
-@@ -511,7 +526,7 @@ rx_ring_free:
- /* free the allocated RX ring */
- for (i = 0; i < LTQ_DESC_NUM; i++) {
- if (priv->chan_rx.skb[i])
-- dev_kfree_skb_any(priv->chan_rx.skb[i]);
-+ skb_free_frag(priv->chan_rx.rx_buff[i]);
- }
-
- rx_free:
-@@ -528,7 +543,7 @@ static void xrx200_hw_cleanup(struct xrx
-
- /* free the allocated RX ring */
- for (i = 0; i < LTQ_DESC_NUM; i++)
-- dev_kfree_skb_any(priv->chan_rx.skb[i]);
-+ skb_free_frag(priv->chan_rx.rx_buff[i]);
- }
-
- static int xrx200_probe(struct platform_device *pdev)
-@@ -553,6 +568,7 @@ static int xrx200_probe(struct platform_
- net_dev->min_mtu = ETH_ZLEN;
- net_dev->max_mtu = XRX200_DMA_DATA_LEN - xrx200_max_frame_len(0);
- priv->rx_buf_size = xrx200_buffer_size(ETH_DATA_LEN);
-+ priv->rx_skb_size = xrx200_skb_size(priv->rx_buf_size);
-
- /* load the memory ranges */
- priv->pmac_reg = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
+++ /dev/null
-From dd830aed23c6e07cd8e2a163742bf3d63c9add08 Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Sat, 5 Mar 2022 12:20:39 +0100
-Subject: net: lantiq_xrx200: fix use after free bug
-
-The skb->len field is read after the packet is sent to the network
-stack. In the meantime, skb can be freed. This patch fixes this bug.
-
-Fixes: c3e6b2c35b34 ("net: lantiq_xrx200: add ingress SG DMA support")
-Reported-by: Eric Dumazet <eric.dumazet@gmail.com>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Acked-by: Hauke Mehrtens <hauke@hauke-m.de>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
- drivers/net/ethernet/lantiq_xrx200.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -260,9 +260,9 @@ static int xrx200_hw_receive(struct xrx2
-
- if (ctl & LTQ_DMA_EOP) {
- ch->skb_head->protocol = eth_type_trans(ch->skb_head, net_dev);
-- netif_receive_skb(ch->skb_head);
- net_dev->stats.rx_packets++;
- net_dev->stats.rx_bytes += ch->skb_head->len;
-+ netif_receive_skb(ch->skb_head);
- ch->skb_head = NULL;
- ch->skb_tail = NULL;
- ret = XRX200_DMA_PACKET_COMPLETE;
+++ /dev/null
-From c8b043702dc0894c07721c5b019096cebc8c798f Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 24 Aug 2022 23:54:06 +0200
-Subject: [PATCH] net: lantiq_xrx200: confirm skb is allocated before using
-
-xrx200_hw_receive() assumes build_skb() always works and goes straight
-to skb_reserve(). However, build_skb() can fail under memory pressure.
-
-Add a check in case build_skb() failed to allocate and return NULL.
-
-Fixes: e015593573b3 ("net: lantiq_xrx200: convert to build_skb")
-Reported-by: Eric Dumazet <edumazet@google.com>
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -239,6 +239,12 @@ static int xrx200_hw_receive(struct xrx2
- }
-
- skb = build_skb(buf, priv->rx_skb_size);
-+ if (!skb) {
-+ skb_free_frag(buf);
-+ net_dev->stats.rx_dropped++;
-+ return -ENOMEM;
-+ }
-+
- skb_reserve(skb, NET_SKB_PAD);
- skb_put(skb, len);
-
+++ /dev/null
-From c4b6e9341f930e4dd089231c0414758f5f1f9dbd Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 24 Aug 2022 23:54:07 +0200
-Subject: [PATCH] net: lantiq_xrx200: fix lock under memory pressure
-
-When the xrx200_hw_receive() function returns -ENOMEM, the NAPI poll
-function immediately returns an error.
-This is incorrect for two reasons:
-* the function terminates without enabling interrupts or scheduling NAPI,
-* the error code (-ENOMEM) is returned instead of the number of received
-packets.
-
-After the first memory allocation failure occurs, packet reception is
-locked due to disabled interrupts from DMA..
-
-Fixes: fe1a56420cf2 ("net: lantiq: Add Lantiq / Intel VRX200 Ethernet driver")
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -294,7 +294,7 @@ static int xrx200_poll_rx(struct napi_st
- if (ret == XRX200_DMA_PACKET_IN_PROGRESS)
- continue;
- if (ret != XRX200_DMA_PACKET_COMPLETE)
-- return ret;
-+ break;
- rx++;
- } else {
- break;
+++ /dev/null
-From c9c3b1775f80fa21f5bff874027d2ccb10f5d90c Mon Sep 17 00:00:00 2001
-From: Aleksander Jan Bajkowski <olek2@wp.pl>
-Date: Wed, 24 Aug 2022 23:54:08 +0200
-Subject: [PATCH] net: lantiq_xrx200: restore buffer if memory allocation
- failed
-
-In a situation where memory allocation fails, an invalid buffer address
-is stored. When this descriptor is used again, the system panics in the
-build_skb() function when accessing memory.
-
-Fixes: 7ea6cd16f159 ("lantiq: net: fix duplicated skb in rx descriptor ring")
-Signed-off-by: Aleksander Jan Bajkowski <olek2@wp.pl>
-Signed-off-by: Jakub Kicinski <kuba@kernel.org>
----
- drivers/net/ethernet/lantiq_xrx200.c | 1 +
- 1 file changed, 1 insertion(+)
-
---- a/drivers/net/ethernet/lantiq_xrx200.c
-+++ b/drivers/net/ethernet/lantiq_xrx200.c
-@@ -193,6 +193,7 @@ static int xrx200_alloc_buf(struct xrx20
-
- ch->rx_buff[ch->dma.desc] = alloc(priv->rx_skb_size);
- if (!ch->rx_buff[ch->dma.desc]) {
-+ ch->rx_buff[ch->dma.desc] = buf;
- ret = -ENOMEM;
- goto skip;
- }
+++ /dev/null
-From 82ea7c7fb4e90620beba8b6436fc12df2379ef8d Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 10 Oct 2022 16:52:25 +0200
-Subject: [PATCH 731/768] dt-bindings: net: dsa: lantiq_gswip: Add missing
- phy-mode and fixed-link
-
-The CPU port has to specify a phy-mode and either a phy or a fixed-link.
-Since GSWIP is connected using a SoC internal protocol there's no PHY
-involved. Add phy-mode = "internal" and a fixed-link to describe the
-communication between the PMAC (Ethernet controller) and GSWIP switch.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt | 6 ++++++
- 1 file changed, 6 insertions(+)
-
---- a/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
-+++ b/Documentation/devicetree/bindings/net/dsa/lantiq-gswip.txt
-@@ -97,7 +97,13 @@ switch@e108000 {
- port@6 {
- reg = <0x6>;
- label = "cpu";
-+ phy-mode = "internal";
- ethernet = <ð0>;
-+
-+ fixed-link {
-+ speed = <1000>;
-+ full-duplex;
-+ };
- };
- };
-
+++ /dev/null
-From a55b9d802e11baceb35bd312419ad82086065b08 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 10 Oct 2022 16:59:35 +0200
-Subject: [PATCH 732/768] net: dsa: lantiq_gswip: Only allow phy-mode =
- "internal" on the CPU port
-
-Add the CPU port to gswip_xrx200_phylink_get_caps() and
-gswip_xrx300_phylink_get_caps(). It connects through a SoC-internal bus,
-so the only allowed phy-mode is PHY_INTERFACE_MODE_INTERNAL.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 ++
- 1 file changed, 2 insertions(+)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1513,6 +1513,7 @@ static void gswip_xrx200_phylink_validat
- case 2:
- case 3:
- case 4:
-+ case 6:
- if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
- goto unsupported;
- break;
-@@ -1552,6 +1553,7 @@ static void gswip_xrx300_phylink_validat
- case 2:
- case 3:
- case 4:
-+ case 6:
- if (state->interface != PHY_INTERFACE_MODE_INTERNAL)
- goto unsupported;
- break;
+++ /dev/null
-From 4d3dd68a1c56674ff666d0622b545992fac31754 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Sun, 31 Jul 2022 22:54:52 +0200
-Subject: [PATCH 733/768] net: dsa: lantiq_gswip: Use dev_err_probe where
- appropriate
-
-dev_err_probe() can be used to simplify the existing code. Also it means
-we get rid of the following warning which is seen whenever the PMAC
-(Ethernet controller which connects to GSWIP's CPU port) has not been
-probed yet:
- gswip 1e108000.switch: dsa switch register failed: -517
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 53 ++++++++++++++++------------------
- 1 file changed, 25 insertions(+), 28 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1939,11 +1939,9 @@ static int gswip_gphy_fw_load(struct gsw
- msleep(200);
-
- ret = request_firmware(&fw, gphy_fw->fw_name, dev);
-- if (ret) {
-- dev_err(dev, "failed to load firmware: %s, error: %i\n",
-- gphy_fw->fw_name, ret);
-- return ret;
-- }
-+ if (ret)
-+ return dev_err_probe(dev, ret, "failed to load firmware: %s\n",
-+ gphy_fw->fw_name);
-
- /* GPHY cores need the firmware code in a persistent and contiguous
- * memory area with a 16 kB boundary aligned start address.
-@@ -1956,9 +1954,9 @@ static int gswip_gphy_fw_load(struct gsw
- dev_addr = ALIGN(dma_addr, XRX200_GPHY_FW_ALIGN);
- memcpy(fw_addr, fw->data, fw->size);
- } else {
-- dev_err(dev, "failed to alloc firmware memory\n");
- release_firmware(fw);
-- return -ENOMEM;
-+ return dev_err_probe(dev, -ENOMEM,
-+ "failed to alloc firmware memory\n");
- }
-
- release_firmware(fw);
-@@ -1985,8 +1983,8 @@ static int gswip_gphy_fw_probe(struct gs
-
- gphy_fw->clk_gate = devm_clk_get(dev, gphyname);
- if (IS_ERR(gphy_fw->clk_gate)) {
-- dev_err(dev, "Failed to lookup gate clock\n");
-- return PTR_ERR(gphy_fw->clk_gate);
-+ return dev_err_probe(dev, PTR_ERR(gphy_fw->clk_gate),
-+ "Failed to lookup gate clock\n");
- }
-
- ret = of_property_read_u32(gphy_fw_np, "reg", &gphy_fw->fw_addr_offset);
-@@ -2006,8 +2004,8 @@ static int gswip_gphy_fw_probe(struct gs
- gphy_fw->fw_name = priv->gphy_fw_name_cfg->ge_firmware_name;
- break;
- default:
-- dev_err(dev, "Unknown GPHY mode %d\n", gphy_mode);
-- return -EINVAL;
-+ return dev_err_probe(dev, -EINVAL, "Unknown GPHY mode %d\n",
-+ gphy_mode);
- }
-
- gphy_fw->reset = of_reset_control_array_get_exclusive(gphy_fw_np);
-@@ -2060,8 +2058,9 @@ static int gswip_gphy_fw_list(struct gsw
- priv->gphy_fw_name_cfg = &xrx200a2x_gphy_data;
- break;
- default:
-- dev_err(dev, "unknown GSWIP version: 0x%x", version);
-- return -ENOENT;
-+ return dev_err_probe(dev, -ENOENT,
-+ "unknown GSWIP version: 0x%x",
-+ version);
- }
- }
-
-@@ -2069,10 +2068,9 @@ static int gswip_gphy_fw_list(struct gsw
- if (match && match->data)
- priv->gphy_fw_name_cfg = match->data;
-
-- if (!priv->gphy_fw_name_cfg) {
-- dev_err(dev, "GPHY compatible type not supported");
-- return -ENOENT;
-- }
-+ if (!priv->gphy_fw_name_cfg)
-+ return dev_err_probe(dev, -ENOENT,
-+ "GPHY compatible type not supported");
-
- priv->num_gphy_fw = of_get_available_child_count(gphy_fw_list_np);
- if (!priv->num_gphy_fw)
-@@ -2171,8 +2169,8 @@ static int gswip_probe(struct platform_d
- return -EINVAL;
- break;
- default:
-- dev_err(dev, "unknown GSWIP version: 0x%x", version);
-- return -ENOENT;
-+ return dev_err_probe(dev, -ENOENT,
-+ "unknown GSWIP version: 0x%x", version);
- }
-
- /* bring up the mdio bus */
-@@ -2180,10 +2178,9 @@ static int gswip_probe(struct platform_d
- if (gphy_fw_np) {
- err = gswip_gphy_fw_list(priv, gphy_fw_np, version);
- of_node_put(gphy_fw_np);
-- if (err) {
-- dev_err(dev, "gphy fw probe failed\n");
-- return err;
-- }
-+ if (err)
-+ return dev_err_probe(dev, err,
-+ "gphy fw probe failed\n");
- }
-
- /* bring up the mdio bus */
-@@ -2191,20 +2188,20 @@ static int gswip_probe(struct platform_d
- if (mdio_np) {
- err = gswip_mdio(priv, mdio_np);
- if (err) {
-- dev_err(dev, "mdio probe failed\n");
-+ dev_err_probe(dev, err, "mdio probe failed\n");
- goto put_mdio_node;
- }
- }
-
- err = dsa_register_switch(priv->ds);
- if (err) {
-- dev_err(dev, "dsa switch register failed: %i\n", err);
-+ dev_err_probe(dev, err, "dsa switch registration failed\n");
- goto mdio_bus;
- }
- if (!dsa_is_cpu_port(priv->ds, priv->hw_info->cpu_port)) {
-- dev_err(dev, "wrong CPU port defined, HW only supports port: %i",
-- priv->hw_info->cpu_port);
-- err = -EINVAL;
-+ err = dev_err_probe(dev, -EINVAL,
-+ "wrong CPU port defined, HW only supports port: %i",
-+ priv->hw_info->cpu_port);
- goto disable_switch;
- }
-
+++ /dev/null
-From 8cf0b680abc157adeec3fb93a10354c470694535 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Thu, 28 Jul 2022 22:37:11 +0200
-Subject: [PATCH 734/768] net: dsa: lantiq_gswip: Don't manually call
- gswip_port_enable()
-
-We don't need to manually call gswip_port_enable() from within
-gswip_setup() for the CPU port. DSA does this automatically for us.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 --
- 1 file changed, 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -874,8 +874,6 @@ static int gswip_setup(struct dsa_switch
-
- ds->mtu_enforcement_ingress = true;
-
-- gswip_port_enable(ds, cpu_port, NULL);
--
- ds->configure_vlan_while_not_filtering = false;
-
- return 0;
+++ /dev/null
-From 54a2f7f2c134738bd3f4ea0a213138d169f2726e Mon Sep 17 00:00:00 2001
-From: Martin Schiller <ms@dev.tdt.de>
-Date: Fri, 10 May 2024 13:52:10 +0200
-Subject: [PATCH] net: dsa: lantiq_gswip: do also enable or disable cpu port
-
-Before commit 74be4babe72f ("net: dsa: do not enable or disable non user
-ports"), gswip_port_enable/disable() were also executed for the cpu port
-in gswip_setup() which disabled the cpu port during initialization.
-
-Let's restore this by removing the dsa_is_user_port checks. Also, let's
-clean up the gswip_port_enable() function so that we only have to check
-for the cpu port once.
-
-Fixes: 74be4babe72f ("net: dsa: do not enable or disable non user ports")
-Signed-off-by: Martin Schiller <ms@dev.tdt.de>
----
- drivers/net/dsa/lantiq_gswip.c | 24 ++++++++----------------
- 1 file changed, 8 insertions(+), 16 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -671,13 +671,18 @@ static int gswip_port_enable(struct dsa_
- struct gswip_priv *priv = ds->priv;
- int err;
-
-- if (!dsa_is_user_port(ds, port))
-- return 0;
--
- if (!dsa_is_cpu_port(ds, port)) {
-+ u32 mdio_phy = 0;
-+
- err = gswip_add_single_port_br(priv, port, true);
- if (err)
- return err;
-+
-+ if (phydev)
-+ mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
-+
-+ gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
-+ GSWIP_MDIO_PHYp(port));
- }
-
- /* RMON Counter Enable for port */
-@@ -690,16 +695,6 @@ static int gswip_port_enable(struct dsa_
- gswip_switch_mask(priv, 0, GSWIP_SDMA_PCTRL_EN,
- GSWIP_SDMA_PCTRLp(port));
-
-- if (!dsa_is_cpu_port(ds, port)) {
-- u32 mdio_phy = 0;
--
-- if (phydev)
-- mdio_phy = phydev->mdio.addr & GSWIP_MDIO_PHY_ADDR_MASK;
--
-- gswip_mdio_mask(priv, GSWIP_MDIO_PHY_ADDR_MASK, mdio_phy,
-- GSWIP_MDIO_PHYp(port));
-- }
--
- return 0;
- }
-
-@@ -707,9 +702,6 @@ static void gswip_port_disable(struct ds
- {
- struct gswip_priv *priv = ds->priv;
-
-- if (!dsa_is_user_port(ds, port))
-- return;
--
- gswip_switch_mask(priv, GSWIP_FDMA_PCTRL_EN, 0,
- GSWIP_FDMA_PCTRLp(port));
- gswip_switch_mask(priv, GSWIP_SDMA_PCTRL_EN, 0,
+++ /dev/null
-From 8ab55ac9678ca1f50f786c84484599dd675c5a9f Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Wed, 18 May 2022 23:53:09 +0200
-Subject: [PATCH 736/768] net: dsa: lantiq_gswip: Use dsa_is_cpu_port() in
- gswip_port_change_mtu()
-
-Make the check for the CPU port in gswip_port_change_mtu() consistent
-with other areas of the driver by using dsa_is_cpu_port().
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1463,12 +1463,11 @@ static int gswip_port_max_mtu(struct dsa
- static int gswip_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
- {
- struct gswip_priv *priv = ds->priv;
-- int cpu_port = priv->hw_info->cpu_port;
-
- /* CPU port always has maximum mtu of user ports, so use it to set
- * switch frame size, including 8 byte special header.
- */
-- if (port == cpu_port) {
-+ if (dsa_is_cpu_port(ds, port)) {
- new_mtu += 8;
- gswip_switch_w(priv, VLAN_ETH_HLEN + new_mtu + ETH_FCS_LEN,
- GSWIP_MAC_FLEN);
+++ /dev/null
-From ef98b183d8fc7187a2efcc21c8f54f3cf061d556 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Tue, 17 May 2022 22:39:58 +0200
-Subject: [PATCH 737/768] net: dsa: lantiq_gswip: Change literal 6 to ETH_ALEN
-
-The addr variable in gswip_port_fdb_dump() stores a mac address. Use
-ETH_ALEN to make this consistent across other drivers.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1383,7 +1383,7 @@ static int gswip_port_fdb_dump(struct ds
- {
- struct gswip_priv *priv = ds->priv;
- struct gswip_pce_table_entry mac_bridge = {0,};
-- unsigned char addr[6];
-+ unsigned char addr[ETH_ALEN];
- int i;
- int err;
-
+++ /dev/null
-From 61e9b19f6e6174afa7540f0b468a69bc940b91d4 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 21:23:49 +0200
-Subject: [PATCH 738/768] net: dsa: lantiq_gswip: Consistently use macros for
- the mac bridge table
-
-Introduce a new GSWIP_TABLE_MAC_BRIDGE_PORT macro and use it throughout
-the driver. Also update GSWIP_TABLE_MAC_BRIDGE_STATIC to use the BIT()
-macro. This makes the driver code easier to understand.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 9 ++++++---
- 1 file changed, 6 insertions(+), 3 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -236,7 +236,8 @@
- #define GSWIP_TABLE_ACTIVE_VLAN 0x01
- #define GSWIP_TABLE_VLAN_MAPPING 0x02
- #define GSWIP_TABLE_MAC_BRIDGE 0x0b
--#define GSWIP_TABLE_MAC_BRIDGE_STATIC 0x01 /* Static not, aging entry */
-+#define GSWIP_TABLE_MAC_BRIDGE_STATIC BIT(0) /* Static not, aging entry */
-+#define GSWIP_TABLE_MAC_BRIDGE_PORT GENMASK(7, 4) /* Port on learned entries */
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-@@ -1279,7 +1280,8 @@ static void gswip_port_fast_age(struct d
- if (mac_bridge.val[1] & GSWIP_TABLE_MAC_BRIDGE_STATIC)
- continue;
-
-- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) != port)
-+ if (port != FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_PORT,
-+ mac_bridge.val[0]))
- continue;
-
- mac_bridge.valid = false;
-@@ -1414,7 +1416,8 @@ static int gswip_port_fdb_dump(struct ds
- return err;
- }
- } else {
-- if (((mac_bridge.val[0] & GENMASK(7, 4)) >> 4) == port) {
-+ if (port == FIELD_GET(GSWIP_TABLE_MAC_BRIDGE_PORT,
-+ mac_bridge.val[0])) {
- err = cb(addr, 0, false, data);
- if (err)
- return err;
+++ /dev/null
-From 7a9e185075ababa827d1d3a33b787ad6d718c8ec Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 22:24:24 +0200
-Subject: [PATCH 739/768] net: dsa: lantiq_gswip: Forbid
- gswip_add_single_port_br on the CPU port
-
-Calling gswip_add_single_port_br() with the CPU port would be a bug
-because then only the CPU port could talk to itself. Add the CPU port to
-the validation at the beginning of gswip_add_single_port_br().
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -633,7 +633,7 @@ static int gswip_add_single_port_br(stru
- unsigned int max_ports = priv->hw_info->max_ports;
- int err;
-
-- if (port >= max_ports) {
-+ if (port >= max_ports || dsa_is_cpu_port(priv->ds, port)) {
- dev_err(priv->dev, "single port for %i supported\n", port);
- return -EIO;
- }
+++ /dev/null
-From 28be6bfb735d851e646abb05b8e24eb6764596f5 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Mon, 1 Aug 2022 22:26:20 +0200
-Subject: [PATCH 740/768] net: dsa: lantiq_gswip: Fix error message in
- gswip_add_single_port_br()
-
-The error message is printed when the port cannot be used. Update the
-error message to reflect that.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -634,7 +634,8 @@ static int gswip_add_single_port_br(stru
- int err;
-
- if (port >= max_ports || dsa_is_cpu_port(priv->ds, port)) {
-- dev_err(priv->dev, "single port for %i supported\n", port);
-+ dev_err(priv->dev, "single port for %i is not supported\n",
-+ port);
- return -EIO;
- }
-
+++ /dev/null
-From 45a0371568b1f050d787564875653f41a1f6fb98 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 14:06:40 +0200
-Subject: [PATCH 741/768] net: dsa: lantiq_gswip: Fix comments in
- gswip_port_vlan_filtering()
-
-Update the comments in gswip_port_vlan_filtering() so it's clear that
-there are two separate cases, one for "tag based VLAN" and another one
-for "port based VLAN".
-
-Suggested-by: Martin Schiller <ms@dev.tdt.de>
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -762,7 +762,7 @@ static int gswip_port_vlan_filtering(str
- }
-
- if (vlan_filtering) {
-- /* Use port based VLAN tag */
-+ /* Use tag based VLAN */
- gswip_switch_mask(priv,
- GSWIP_PCE_VCTRL_VSR,
- GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
-@@ -771,7 +771,7 @@ static int gswip_port_vlan_filtering(str
- gswip_switch_mask(priv, GSWIP_PCE_PCTRL_0_TVM, 0,
- GSWIP_PCE_PCTRL_0p(port));
- } else {
-- /* Use port based VLAN tag */
-+ /* Use port based VLAN */
- gswip_switch_mask(priv,
- GSWIP_PCE_VCTRL_UVR | GSWIP_PCE_VCTRL_VIMR |
- GSWIP_PCE_VCTRL_VEMR,
+++ /dev/null
-From 4775f9543e691d9a2f5dd9aa5d46c66d37928250 Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 14:19:05 +0200
-Subject: [PATCH 742/768] net: dsa: lantiq_gswip: Add and use a
- GSWIP_TABLE_MAC_BRIDGE_FID macro
-
-Only bits [5:0] in mac_bridge.key[3] are reserved for the FID. Add a
-macro so this becomes obvious when reading the driver code.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -238,6 +238,7 @@
- #define GSWIP_TABLE_MAC_BRIDGE 0x0b
- #define GSWIP_TABLE_MAC_BRIDGE_STATIC BIT(0) /* Static not, aging entry */
- #define GSWIP_TABLE_MAC_BRIDGE_PORT GENMASK(7, 4) /* Port on learned entries */
-+#define GSWIP_TABLE_MAC_BRIDGE_FID GENMASK(5, 0) /* Filtering identifier */
-
- #define XRX200_GPHY_FW_ALIGN (16 * 1024)
-
-@@ -1357,7 +1358,7 @@ static int gswip_port_fdb(struct dsa_swi
- mac_bridge.key[0] = addr[5] | (addr[4] << 8);
- mac_bridge.key[1] = addr[3] | (addr[2] << 8);
- mac_bridge.key[2] = addr[1] | (addr[0] << 8);
-- mac_bridge.key[3] = fid;
-+ mac_bridge.key[3] = FIELD_PREP(GSWIP_TABLE_MAC_BRIDGE_FID, fid);
- mac_bridge.val[0] = add ? BIT(port) : 0; /* port map */
- mac_bridge.val[1] = GSWIP_TABLE_MAC_BRIDGE_STATIC;
- mac_bridge.valid = add;
+++ /dev/null
-From 00b5121435ccd4ce54f79179dd9ee3e2610d7dcf Mon Sep 17 00:00:00 2001
-From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
-Date: Fri, 14 Oct 2022 16:31:57 +0200
-Subject: [PATCH 743/768] net: dsa: lantiq_gswip: Improve error message in
- gswip_port_fdb()
-
-Print the port which is not found to be part of a bridge so it's easier
-to investigate the underlying issue.
-
-Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
----
- drivers/net/dsa/lantiq_gswip.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/drivers/net/dsa/lantiq_gswip.c
-+++ b/drivers/net/dsa/lantiq_gswip.c
-@@ -1349,7 +1349,8 @@ static int gswip_port_fdb(struct dsa_swi
- }
-
- if (fid == -1) {
-- dev_err(priv->dev, "Port not part of a bridge\n");
-+ dev_err(priv->dev,
-+ "Port %d is not known to be part of bridge\n", port);
- return -EINVAL;
- }
-
+++ /dev/null
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_EXTRA_FIRMWARE="lantiq/xrx200_phy11g_a14.bin lantiq/xrx200_phy11g_a22.bin lantiq/xrx200_phy22f_a14.bin lantiq/xrx200_phy22f_a22.bin"
-CONFIG_EXTRA_FIRMWARE_DIR="firmware"
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_GRO_CELLS=y
-CONFIG_HWMON=y
-CONFIG_HW_RANDOM=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_IFX_VPE_EXT=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_INTEL_XWAY_PHY=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_XRX200=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MIPS_MT=y
-# CONFIG_MIPS_MT_FPAFF is not set
-CONFIG_MIPS_MT_SMP=y
-CONFIG_MIPS_NR_CPU_NR_MAP=2
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MIPS_VPE_APSP_API=y
-CONFIG_MIPS_VPE_APSP_API_MT=y
-CONFIG_MIPS_VPE_LOADER=y
-CONFIG_MIPS_VPE_LOADER_MT=y
-CONFIG_MIPS_VPE_LOADER_TOM=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_MTD_NAND_XWAY=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NET_DEVLINK=y
-CONFIG_NET_DSA=y
-CONFIG_NET_DSA_LANTIQ_GSWIP=y
-CONFIG_NET_DSA_TAG_GSWIP=y
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NET_SWITCHDEV=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=2
-CONFIG_PADATA=y
-CONFIG_PCI=y
-CONFIG_PCIEPORTBUS=y
-CONFIG_PCIE_LANTIQ=y
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_PHYLINK=y
-CONFIG_PHY_LANTIQ_VRX200_PCIE=y
-CONFIG_POWER_RESET_GPIO=y
-CONFIG_POWER_SUPPLY=y
-CONFIG_POWER_SUPPLY_HWMON=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_SENSORS_LTQ_CPUTEMP=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
+++ /dev/null
-CONFIG_ADM6996_PHY=y
-CONFIG_AR8216_PHY=y
-CONFIG_AT803X_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CPU_MIPSR2_IRQ_EI=y
-CONFIG_CPU_MIPSR2_IRQ_VI=y
-CONFIG_CPU_RMAP=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_HASH_INFO=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_CRYPTO_ZSTD=y
-CONFIG_ETHERNET_PACKET_MANGLE=y
-CONFIG_GENERIC_ALLOCATOR=y
-CONFIG_HW_RANDOM=y
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-CONFIG_IRQ_DOMAIN_HIERARCHY=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_MIPS_MT=y
-CONFIG_MIPS_MT_FPAFF=y
-CONFIG_MIPS_MT_SMP=y
-CONFIG_MIPS_NR_CPU_NR_MAP=2
-CONFIG_MIPS_PERF_SHARED_TC_COUNTERS=y
-CONFIG_MTD_NAND_CORE=y
-CONFIG_MTD_NAND_ECC=y
-CONFIG_MTD_NAND_ECC_SW_HAMMING=y
-CONFIG_MTD_NAND_XWAY=y
-CONFIG_MTD_RAW_NAND=y
-CONFIG_MTD_UBI=y
-CONFIG_MTD_UBI_BEB_LIMIT=20
-CONFIG_MTD_UBI_BLOCK=y
-CONFIG_MTD_UBI_WL_THRESHOLD=4096
-CONFIG_NET_FLOW_LIMIT=y
-CONFIG_NLS=y
-CONFIG_NR_CPUS=2
-CONFIG_PADATA=y
-CONFIG_PCI=y
-# CONFIG_PCIE_LANTIQ is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_PSB6970_PHY=y
-CONFIG_QUEUED_RWLOCKS=y
-CONFIG_QUEUED_SPINLOCKS=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RFS_ACCEL=y
-CONFIG_RPS=y
-CONFIG_RTL8306_PHY=y
-CONFIG_RTL8366RB_PHY=y
-CONFIG_RTL8366_SMI=y
-# CONFIG_SCHED_CORE is not set
-CONFIG_SCHED_SMT=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SMP=y
-CONFIG_SMP_UP=y
-CONFIG_SOCK_RX_QUEUE_MAPPING=y
-CONFIG_SWCONFIG=y
-CONFIG_SYNC_R4K=y
-CONFIG_SYS_SUPPORTS_SCHED_SMT=y
-CONFIG_SYS_SUPPORTS_SMP=y
-CONFIG_TREE_RCU=y
-CONFIG_TREE_SRCU=y
-CONFIG_UBIFS_FS=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_XPS=y
-CONFIG_XXHASH=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZSTD_COMPRESS=y
-CONFIG_ZSTD_DECOMPRESS=y
+++ /dev/null
-CONFIG_ADM6996_PHY=y
-CONFIG_BLK_MQ_PCI=y
-CONFIG_CRC16=y
-CONFIG_CRYPTO_DEFLATE=y
-CONFIG_CRYPTO_LZO=y
-CONFIG_GENERIC_ALLOCATOR=y
-# CONFIG_GPIO_CDEV is not set
-# CONFIG_GPIO_SYSFS is not set
-CONFIG_INPUT=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_ISDN is not set
-CONFIG_LANTIQ_ETOP=y
-# CONFIG_LEDS_TRIGGER_TIMER is not set
-CONFIG_LZO_COMPRESS=y
-CONFIG_LZO_DECOMPRESS=y
-CONFIG_NLS=y
-CONFIG_PCI=y
-# CONFIG_PCIE_LANTIQ is not set
-CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LANTIQ=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_RTL8306_PHY=y
-CONFIG_SGL_ALLOC=y
-CONFIG_SWCONFIG=y
-CONFIG_USB=y
-CONFIG_USB_COMMON=y
-CONFIG_USB_SUPPORT=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y