summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/board_nvodm.c28
-rw-r--r--arch/arm/mach-tegra/dma.c29
-rw-r--r--arch/arm/mach-tegra/include/mach/dma.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/nvrm_linux.h35
-rw-r--r--arch/arm/mach-tegra/include/mach/pci.h323
-rw-r--r--arch/arm/mach-tegra/include/mach/platform.h1
-rw-r--r--arch/arm/mach-tegra/init_common.c13
-rw-r--r--arch/arm/mach-tegra/nvec_user.c61
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-tegra/nvodm/nvodm_services.c21
-rwxr-xr-x[-rw-r--r--]arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_analog.c1909
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c23
-rw-r--r--arch/arm/mach-tegra/pci-enum.c637
-rw-r--r--arch/arm/mach-tegra/pci.c561
-rw-r--r--arch/arm/mach-tegra/tegra_exports.c58
-rw-r--r--arch/arm/mach-tegra/tegra_sysmap.c2
-rw-r--r--drivers/mtd/devices/tegra_mtd_nand.c20
-rw-r--r--drivers/net/usb/usbnet.c11
-rw-r--r--drivers/serial/Kconfig33
-rw-r--r--drivers/serial/tegra_hsuart.c36
20 files changed, 1752 insertions, 2052 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index 6b8ac3027872..075d18a45193 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -65,4 +65,5 @@ obj-$(CONFIG_TEGRA_NVEC_USER) += nvec_user.o
# PCIe support
obj-$(CONFIG_TEGRA_PCI) += pci.o
+obj-$(CONFIG_TEGRA_PCI) += pci-enum.o
diff --git a/arch/arm/mach-tegra/board_nvodm.c b/arch/arm/mach-tegra/board_nvodm.c
index 458067b3a1e1..61a54f02e99d 100644
--- a/arch/arm/mach-tegra/board_nvodm.c
+++ b/arch/arm/mach-tegra/board_nvodm.c
@@ -33,7 +33,7 @@
#include <mach/board.h>
-#include <linux/mtd/mtd.h>
+#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/io.h>
@@ -97,6 +97,14 @@ static struct platform_device android_usb_device =
};
#endif
+#ifdef CONFIG_TEGRA_NVEC_USER
+static struct platform_device tegra_nvec =
+{
+ .name = "nvec",
+ .id = -1,
+};
+#endif
+
#if defined(CONFIG_USB_GADGETFS) || defined(CONFIG_USB_GADGETFS_MODULE)
static struct platform_device android_gadgetfs_device =
{
@@ -123,7 +131,7 @@ static struct platform_device tegra_nand_device =
#ifdef CONFIG_RTC_DRV_TEGRA_ODM
-static struct platform_device tegra_rtc_device =
+static struct platform_device tegra_rtc_device =
{
.name = "tegra_rtc",
.id = -1,
@@ -131,7 +139,7 @@ static struct platform_device tegra_rtc_device =
#endif
#ifdef CONFIG_TOUCHSCREEN_TEGRA_ODM
-static struct platform_device tegra_touch_device =
+static struct platform_device tegra_touch_device =
{
.name = "tegra_touch",
.id = -1,
@@ -139,7 +147,7 @@ static struct platform_device tegra_touch_device =
#endif
#ifdef CONFIG_INPUT_TEGRA_ODM_ACCEL
-static struct platform_device tegra_accelerometer_device =
+static struct platform_device tegra_accelerometer_device =
{
.name = "tegra_accelerometer",
.id = -1,
@@ -147,7 +155,7 @@ static struct platform_device tegra_accelerometer_device =
#endif
#ifdef CONFIG_KEYBOARD_TEGRA
-static struct platform_device tegra_kbc_device =
+static struct platform_device tegra_kbc_device =
{
.name = "tegra_kbc",
.id = -1,
@@ -155,7 +163,7 @@ static struct platform_device tegra_kbc_device =
#endif
#ifdef CONFIG_INPUT_TEGRA_ODM_SCROLL
-static struct platform_device tegra_scrollwheel_device =
+static struct platform_device tegra_scrollwheel_device =
{
.name = "tegra_scrollwheel",
.id = -1,
@@ -169,7 +177,7 @@ static struct timed_output_dev tegra_vibrator_device = {
#endif
#ifdef CONFIG_TEGRA_ODM_RFKILL
-static struct platform_device tegra_rfkill =
+static struct platform_device tegra_rfkill =
{
.name = "tegra_rfkill",
.id = -1,
@@ -296,7 +304,7 @@ static void __init register_enc28j60(void)
int i;
const NvOdmQuerySpiDeviceInfo *pSpiDeviceInfo;
- pConnectivity =
+ pConnectivity =
NvOdmPeripheralGetGuid(NV_ODM_GUID('e','n','c','2','8','j','6','0'));
if (!pConnectivity)
return;
@@ -362,6 +370,10 @@ static void __init tegra_machine_init(void)
tegra_init_snor_controller();
#endif
+#ifdef CONFIG_TEGRA_NVEC_USER
+ (void) platform_device_register(&tegra_nvec);
+#endif
+
#ifdef CONFIG_TOUCHSCREEN_TEGRA_ODM
(void) platform_device_register(&tegra_touch_device);
#endif
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index 3d6ed3e3c56e..064ac861a3c7 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -90,11 +90,6 @@ struct tegra_dma_channel {
#define NV_DMA_MAX_CHANNELS 32
-/* We are only allowed to use the channels in the following range, others are
- * used by different code base */
-#define NV_DMA_CHANNEL_MIN 12
-#define NV_DMA_CHANNEL_MAX 12
-
static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS);
static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS];
@@ -263,14 +258,14 @@ int tegra_dma_allocate_channel(int mode)
int channel;
struct tegra_dma_channel *ch;
- /* NV_DMA_CHANNEL_MIN in the shared channel */
+ /* first channel is the shared channel */
if (mode & TEGRA_DMA_SHARED) {
- channel = NV_DMA_CHANNEL_MIN;
+ channel = TEGRA_SYSTEM_DMA_CH_MIN;
}
else {
channel = find_first_zero_bit(channel_usage,
- NV_DMA_MAX_CHANNELS);
- if (channel > NV_DMA_MAX_CHANNELS)
+ ARRAY_SIZE(dma_channels));
+ if (channel >= ARRAY_SIZE(dma_channels))
return -ENODEV;
}
__set_bit(channel, channel_usage);
@@ -284,7 +279,8 @@ void tegra_dma_free_channel(int channel)
{
struct tegra_dma_channel *ch;
- if (channel < NV_DMA_CHANNEL_MIN && channel >= NV_DMA_CHANNEL_MAX)
+ if (channel < TEGRA_SYSTEM_DMA_CH_MIN ||
+ channel >= TEGRA_SYSTEM_DMA_CH_MAX)
return;
ch = &dma_channels[channel];
@@ -565,12 +561,13 @@ int __init tegra_dma_init(void)
BUG_ON(max_channels > NV_DMA_MAX_CHANNELS);
/* Reserve all the channels we are not supposed to touch */
- for (i=0; i< NV_DMA_MAX_CHANNELS; i++) {
- if ((i < NV_DMA_CHANNEL_MIN) || (i >= NV_DMA_CHANNEL_MAX))
- __set_bit(i, channel_usage);
- }
+ for (i=0; i<TEGRA_SYSTEM_DMA_CH_MIN; i++)
+ __set_bit(i, channel_usage);
+
+ for (i=TEGRA_SYSTEM_DMA_CH_MAX; i<ARRAY_SIZE(dma_channels); i++)
+ __set_bit(i, channel_usage);
- for (i = NV_DMA_CHANNEL_MIN; i < NV_DMA_CHANNEL_MAX; i++) {
+ for (i=TEGRA_SYSTEM_DMA_CH_MIN; i<TEGRA_SYSTEM_DMA_CH_MAX; i++) {
struct tegra_dma_channel *ch = &dma_channels[i];
ch->id = i;
@@ -591,7 +588,7 @@ int __init tegra_dma_init(void)
tegra_dma_init_hw(ch);
}
- for (i = NV_DMA_CHANNEL_MIN; i < NV_DMA_CHANNEL_MAX; i++) {
+ for (i=TEGRA_SYSTEM_DMA_CH_MIN; i<TEGRA_SYSTEM_DMA_CH_MAX; i++) {
irq = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal,
NvRmPrivModuleID_ApbDma, i);
printk("Irq value = %d\n", irq);
diff --git a/arch/arm/mach-tegra/include/mach/dma.h b/arch/arm/mach-tegra/include/mach/dma.h
index 01fedd06e7f5..964af099a392 100644
--- a/arch/arm/mach-tegra/include/mach/dma.h
+++ b/arch/arm/mach-tegra/include/mach/dma.h
@@ -44,6 +44,8 @@ struct tegra_dma_req {
* 0 to copy from the memory to device FIFO */
int to_memory;
+ void *virt_addr;
+
unsigned long source_addr;
unsigned long dest_addr;
unsigned long dest_wrap;
diff --git a/arch/arm/mach-tegra/include/mach/nvrm_linux.h b/arch/arm/mach-tegra/include/mach/nvrm_linux.h
index efb9375dc521..035de018f01d 100644
--- a/arch/arm/mach-tegra/include/mach/nvrm_linux.h
+++ b/arch/arm/mach-tegra/include/mach/nvrm_linux.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-2009 NVIDIA Corporation.
+ * Copyright (c) 2008-2010 NVIDIA Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -56,20 +56,31 @@
extern NvRmDeviceHandle s_hRmGlobal;
extern NvRmGpioHandle s_hGpioGlobal;
-int tegra_get_partition_info_by_name(
- const char *PartName,
- NvU64 *pSectorStart,
- NvU64 *pSectorLength,
- NvU32 *pSectorSize);
+int tegra_get_partition_info_by_name(const char *PartName,
+ NvU64 *pSectorStart, NvU64 *pSectorLength, NvU32 *pSectorSize);
-int tegra_get_partition_info_by_num(
- int PartitionNum,
- char **pName,
- NvU64 *pSectorStart,
- NvU64 *pSectorEnd,
- NvU32 *pSectorSize);
+int tegra_get_partition_info_by_num(int PartitionNum, char **pName,
+ NvU64 *pSectorStart, NvU64 *pSectorEnd, NvU32 *pSectorSize);
int tegra_was_boot_device(const char *pBootDev);
+NvU32 NvRmDmaUnreservedChannels(void);
+
+#ifndef CONFIG_SERIAL_TEGRA_UARTS
+#define TEGRA_SYSTEM_DMA_CH_UART 0
+#else
+#define TEGRA_SYSTEM_DMA_CH_UART (2*CONFIG_SERIAL_TEGRA_UARTS)
+#endif
+
+#ifdef CONFIG_TEGRA_SYSTEM_DMA
+#define TEGRA_SYSTEM_DMA_CH_NUM (1 + TEGRA_SYSTEM_DMA_CH_UART)
+#else
+#define TEGRA_SYSTEM_DMA_CH_NUM (0)
+#endif
+
+/* DMA channels available to system DMA driver */
+#define TEGRA_SYSTEM_DMA_CH_MIN NvRmDmaUnreservedChannels()
+#define TEGRA_SYSTEM_DMA_CH_MAX \
+ (TEGRA_SYSTEM_DMA_CH_MIN+TEGRA_SYSTEM_DMA_CH_NUM)
#endif
diff --git a/arch/arm/mach-tegra/include/mach/pci.h b/arch/arm/mach-tegra/include/mach/pci.h
new file mode 100644
index 000000000000..e5eac3ad5640
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/pci.h
@@ -0,0 +1,323 @@
+/*
+ * arch/arm/mach-tegra/include/mach/pci.h
+ *
+ * Header file containing constants for the tegra PCIe driver.
+ *
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_TEGRA_PCI_H
+
+#include <linux/pci.h>
+#include <mach/platform.h>
+
+#include "nvrm_drf.h"
+#include "ap20/dev_ap_pcie2_root_port.h"
+#include "ap20/dev_ap_pcie2_pads.h"
+#include "ap20/arafi.h"
+
+extern void __iomem * volatile pci_tegra_regs;
+
+/*
+ * AXI address map for the PCIe aperture. AP20, defines 1GB in the AXI
+ * address map for PCIe.
+ *
+ * That address space is split into different regions, with sizes and
+ * offsets as follows. Exepct for the Register space, SW is free to slice the
+ * regions as it chooces.
+ *
+ * The split below seems to work fine for now.
+ *
+ * 0x8000_0000 to 0x80ff_ffff - Register space 16MB.
+ * 0x8100_0000 to 0x81ff_ffff - Config space 16MB.
+ * 0x8200_0000 to 0x82ff_ffff - Extended config space 16MB.
+ * 0x8300_0000 to 0x83ff_ffff - Downstream IO space
+ * ... Will be filled with other BARS like MSI/upstream IO etc.
+ * 0x9000_0000 to 0x9fff_ffff - non-prefetchable memory aperture
+ * 0xa000_0000 to 0xbfff_ffff - Prefetchable memory aperture
+ *
+ * Config and Extended config sizes are choosen to support
+ * maximum of 256 devices,
+ * which is good enough for all the AP20 use cases.
+ * */
+
+#define PCIE_REGS_SIZE 0x01000000UL
+#define PCIE_CONFIG_OFFSET PCIE_REGS_SIZE
+#define PCIE_CONFIG_SIZE 0x01000000UL
+#define PCIE_EXTENDED_CONFIG_OFFSET (PCIE_CONFIG_SIZE + PCIE_CONFIG_OFFSET)
+#define PCIE_EXTENDED_CONFIG_SIZE 0x01000000UL
+#define PCIE_DOWNSTREAM_IO_OFFSET (PCIE_EXTENDED_CONFIG_SIZE + \
+ PCIE_EXTENDED_CONFIG_OFFSET)
+#define PCIE_DOWNSTREAM_IO_SIZE 0x00100000UL
+
+#define PCIE_NON_PREFETCH_MEMORY_OFFSET 0x10000000UL
+#define PCIE_NON_PREFETCH_MEMORY_SIZE 0x10000000UL
+#define PCIE_PREFETCH_MEMORY_OFFSET (PCIE_NON_PREFETCH_MEMORY_OFFSET + \
+ PCIE_NON_PREFETCH_MEMORY_SIZE)
+#define PCIE_PREFETCH_MEMORY_SIZE 0x20000000UL
+
+/* PCIe registers can be classified into 4 regions.
+ *
+ * 1. AFI registers - AFI is a wrapper between PCIE and ARM AXI bus. These
+ * registers define the address translation registers, interrupt registers and
+ * some configuration (a.k.a CYA) registers.
+ * 2. PAD registers - PAD control registers which are inside the PCIE CORE.
+ * 3. Configuration 0 and Configuration 1 registers - These registers are PCIe
+ * configuration registers of Root port 0 and root port 1.
+ *
+ * Check the PcieRegType enumeration for the list of Registers banks inside the
+ * PCIE aperture.
+ *
+ * */
+#define NV_PCIE_AXI_AFI_REGS_OFSET 0x3800UL
+#define NV_PCIE_AXI_PADS_OFSET 0x3000UL
+#define NV_PCIE_AXI_RP_T0C0_OFFSET 0x0000UL
+#define NV_PCIE_AXI_RP_T0C1_OFFSET 0x1000UL
+
+/* During the boot only registers/config and extended config apertures are
+ * mapped. Rest are mapped on demand by the PCI device drivers.
+ */
+#define PCI_TEGRA_IOMAPPED_REG_APERTURE_SIZE \
+ (PCIE_REGS_SIZE + PCIE_CONFIG_SIZE + PCIE_EXTENDED_CONFIG_SIZE)
+
+/*
+ * PCI address map for memory mapped devices. Still using 32-bit aperture.
+ *
+ * 1GB for the system memory.
+ * Everything mapped as cpu physical = pci
+ *
+ */
+#define FPCI_SYSTEM_MEMORY_OFFSET 0x0UL
+#define FPCI_SYSTEM_MEMORY_SIZE 0x40000000UL
+#define FPCI_NON_PREFETCH_MEMORY_OFFSET 0x90000000UL
+#define FPCI_NON_PREFETCH_MEMORY_SIZE PCIE_NON_PREFETCH_MEMORY_SIZE
+#define FPCI_PREFETCH_MEMORY_OFFSET (FPCI_NON_PREFETCH_MEMORY_OFFSET+ \
+ FPCI_NON_PREFETCH_MEMORY_SIZE)
+#define FPCI_PREFETCH_MEMORY_SIZE 0x40000000UL
+
+
+
+
+/* PCIE DRF macros to read and write PRI registers */
+
+/** NVPCIE_DRF_DEF - define a new register value.
+
+ @param d register domain (hardware block)
+ @param r register name
+ @param f register field
+ @param c defined value for the field
+ */
+#define NVPCIE_DRF_DEF(d,r,f,c) \
+ ((NV_PROJ__PCIE2_##d##_##r##_##f##_##c) \
+ << NV_FIELD_SHIFT(NV_PROJ__PCIE2_##d##_##r##_##f))
+
+/** NVPCIE_DRF_NUM - define a new register value.
+
+ @param d register domain (hardware block)
+ @param r register name
+ @param f register field
+ @param n numeric value for the field
+ */
+#define NVPCIE_DRF_NUM(d,r,f,n) \
+ (((n)& NV_FIELD_MASK(NV_PROJ__PCIE2_##d##_##r##_##f)) << \
+ NV_FIELD_SHIFT(NV_PROJ__PCIE2_##d##_##r##_##f))
+
+/** NVPCIE_DRF_VAL - read a field from a register.
+
+ @param d register domain (hardware block)
+ @param r register name
+ @param f register field
+ @param v register value
+ */
+#define NVPCIE_DRF_VAL(d,r,f,v) \
+ (((v)>> NV_FIELD_SHIFT(NV_PROJ__PCIE2_##d##_##r##_##f)) & \
+ NV_FIELD_MASK(NV_PROJ__PCIE2_##d##_##r##_##f))
+
+/** NVPCIE_FLD_SET_DRF_NUM - modify a register field.
+
+ @param d register domain (hardware block)
+ @param r register name
+ @param f register field
+ @param n numeric field value
+ @param v register value
+ */
+#define NVPCIE_FLD_SET_DRF_NUM(d,r,f,n,v) \
+ ((v & ~NV_FIELD_SHIFTMASK(NV_PROJ__PCIE2_##d##_##r##_##f)) | \
+ NVPCIE_DRF_NUM(d,r,f,n))
+
+/** NVPCIE_FLD_SET_DRF_DEF - modify a register field.
+
+ @param d register domain (hardware block)
+ @param r register name
+ @param f register field
+ @param c defined field value
+ @param v register value
+ */
+#define NVPCIE_FLD_SET_DRF_DEF(d,r,f,c,v) \
+ (((v) & ~NV_FIELD_SHIFTMASK(NV_PROJ__PCIE2_##d##_##r##_##f)) | \
+ NVPCIE_DRF_DEF(d,r,f,c))
+
+/** NVPCIE_RESETVAL - get the reset value for a register.
+
+ @param d register domain (hardware block)
+ @param r register name
+ */
+#define NVPCIE_RESETVAL(d,r) (d##_##r##_0_RESET_VAL)
+
+/* Register access inline functions */
+
+static inline void pci_tegra_afi_writel(u32 value,unsigned long offset)
+{
+ writel(value, offset + NV_PCIE_AXI_AFI_REGS_OFSET + pci_tegra_regs);
+}
+
+static inline void pci_tegra_rp_writel(u32 value, unsigned long offset, int rp)
+{
+ BUG_ON(rp != 0 && rp != 1);
+
+ if (rp == 0) offset += NV_PCIE_AXI_RP_T0C0_OFFSET;
+ if (rp == 1) offset += NV_PCIE_AXI_RP_T0C1_OFFSET;
+
+ writel(value, offset + pci_tegra_regs);
+}
+
+static inline void pci_tegra_rp_writew(u16 value, unsigned long offset, int rp)
+{
+ u32 reg;
+
+ BUG_ON(rp != 0 && rp != 1);
+
+ if (rp == 0) offset += NV_PCIE_AXI_RP_T0C0_OFFSET;
+ if (rp == 1) offset += NV_PCIE_AXI_RP_T0C1_OFFSET;
+
+ reg = readl((offset & ~0x3) + pci_tegra_regs);
+ reg &= ~(0xffff << ((offset & 0x3) * 8));
+ reg |= (u32)value << ((offset & 0x3) * 8);
+ writel(reg, (offset & ~0x3) + pci_tegra_regs);
+}
+
+static inline void pci_tegra_rp_writeb(u8 value, unsigned long offset, int rp)
+{
+ u32 reg;
+
+ BUG_ON(rp != 0 && rp != 1);
+
+ if (rp == 0) offset += NV_PCIE_AXI_RP_T0C0_OFFSET;
+ if (rp == 1) offset += NV_PCIE_AXI_RP_T0C1_OFFSET;
+
+ reg = readl((offset & ~0x3) + pci_tegra_regs);
+ reg &= ~(0xff << ((offset & 0x3) * 8));
+ reg |= (u32)value << ((offset & 0x3) * 8);
+ writel(reg, (offset & ~0x3) + pci_tegra_regs);
+}
+
+static inline void pci_tegra_pads_writel(u32 value, unsigned long offset)
+{
+ writel(value, offset + NV_PCIE_AXI_PADS_OFSET + pci_tegra_regs);
+}
+
+static inline u32 pci_tegra_afi_readl(unsigned long offset)
+{
+ return readl(offset + NV_PCIE_AXI_AFI_REGS_OFSET + pci_tegra_regs);
+}
+
+static inline u32 pci_tegra_rp_readl(unsigned long offset, int rp)
+{
+ BUG_ON(rp != 0 && rp != 1);
+
+ if (rp == 0) offset += NV_PCIE_AXI_RP_T0C0_OFFSET;
+ if (rp == 1) offset += NV_PCIE_AXI_RP_T0C1_OFFSET;
+
+ return readl(offset + pci_tegra_regs);
+}
+
+static inline u16 pci_tegra_rp_readw(unsigned long offset, int rp)
+{
+ u32 val;
+
+ BUG_ON(rp != 0 && rp != 1);
+
+ if (rp == 0) offset += NV_PCIE_AXI_RP_T0C0_OFFSET;
+ if (rp == 1) offset += NV_PCIE_AXI_RP_T0C1_OFFSET;
+
+ val = readl((offset & ~0x3) + pci_tegra_regs);
+ val >>= 8 * (offset & 3);
+ val &= 0xffff;
+
+ return (u16)val;
+}
+
+static inline u8 pci_tegra_rp_readb(unsigned long offset, int rp)
+{
+ u32 val;
+
+ BUG_ON(rp != 0 && rp != 1);
+
+ if (rp == 0) offset += NV_PCIE_AXI_RP_T0C0_OFFSET;
+ if (rp == 1) offset += NV_PCIE_AXI_RP_T0C1_OFFSET;
+
+ val = readl((offset & ~0x3) + pci_tegra_regs);
+ val >>= 8 * (offset & 3);
+ val &= 0xff;
+
+ return (u8)val;
+}
+
+static inline u32 pci_tegra_pads_reedl(unsigned long offset)
+{
+ return readl(offset + NV_PCIE_AXI_PADS_OFSET + pci_tegra_regs);
+}
+
+static inline bool pci_tegra_is_rp(u32 bus_number, int *rp)
+{
+ if (bus_number == pci_tegra_rp_readb(PCI_PRIMARY_BUS, 0)) {
+ *rp = 0;
+ return true;
+ } else if (bus_number == pci_tegra_rp_readb(PCI_PRIMARY_BUS, 1)) {
+ *rp = 1;
+ return true;
+ } else
+ return false;
+}
+
+/*
+ * Given the bus number, devfn and the offset this API returns the mapped
+ * address of the config space.
+ */
+static inline void __iomem *pci_tegra_config_addr(u8 bus_number,
+ u32 devfn, u32 where)
+{
+ void *addr;
+ u32 function;
+ u32 device;
+
+ function = PCI_FUNC(devfn);
+ device = PCI_SLOT(devfn);
+
+ addr = pci_tegra_regs;
+ addr += (where < 256) ? PCIE_CONFIG_OFFSET
+ : PCIE_EXTENDED_CONFIG_OFFSET;
+ addr += bus_number << 16;
+ addr += device << 11;
+ addr += function << 8;
+ addr += where;
+ return addr;
+}
+
+void pci_tegra_enumerate(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/platform.h b/arch/arm/mach-tegra/include/mach/platform.h
index 54cb086e58b3..f80632aff0a8 100644
--- a/arch/arm/mach-tegra/include/mach/platform.h
+++ b/arch/arm/mach-tegra/include/mach/platform.h
@@ -27,6 +27,7 @@ extern unsigned int tegra_get_module_inst_irq(const char *, int, int);
#define TEGRA_PL310_IRQ (tegra_get_module_inst_irq("pl310", 0, 0))
#define TEGRA_SCU_BASE (tegra_get_module_inst_base("scu", 0))
+#define TEGRA_PCIE_BASE (tegra_get_module_inst_base("pcie", 0))
#define TEGRA_SCU0_IRQ NO_IRQ
#define TEGRA_SCU1_IRQ NO_IRQ
diff --git a/arch/arm/mach-tegra/init_common.c b/arch/arm/mach-tegra/init_common.c
index 33c13b035a13..fa87882fc45e 100644
--- a/arch/arm/mach-tegra/init_common.c
+++ b/arch/arm/mach-tegra/init_common.c
@@ -377,7 +377,7 @@ static void __init tegra_register_i2c(void)
}
#endif
-#if !defined(CONFIG_SERIAL_TEGRA_DDK)
+#if !(defined(CONFIG_SERIAL_TEGRA_DDK) || defined(CONFIG_SERIAL_TEGRA))
#define tegra_register_uart() do {} while (0)
#else
@@ -390,11 +390,16 @@ void __init tegra_register_uart(void)
NvU32 i;
NvOdmDebugConsole Console;
NvU32 Port = ~0;
+ const NvU32 *pPinMuxes;
+ NvU32 NumPinMuxes;
+ NvU32 Cnt = 0;
Console = NvOdmQueryDebugConsole();
NumberOfUarts = NvRmModuleGetNumInstances(s_hRmGlobal,
NvRmModuleID_Uart);
+ NvOdmQueryPinMux(NvOdmIoModule_Uart, &pPinMuxes, &NumPinMuxes);
+
/* Skip the UART port used as a debug console */
if (((NvU32)Console >= (NvU32)NvOdmDebugConsole_UartA) &&
((NvU32)Console <= (NvU32)NvOdmDebugConsole_UartE))
@@ -402,12 +407,12 @@ void __init tegra_register_uart(void)
Port = (NvU32)(Console - NvOdmDebugConsole_UartA);
}
- for (i=0; i< NumberOfUarts ; i++)
+ for (i=0; i<NumberOfUarts && i<NumPinMuxes; i++)
{
- if (i == Port)
+ if (i==Port || !pPinMuxes[i])
continue;
- pDev = platform_device_alloc("tegra_uart", i);
+ pDev = platform_device_alloc("tegra_uart", Cnt++);
if (!pDev)
goto fail;
if (platform_device_add(pDev))
diff --git a/arch/arm/mach-tegra/nvec_user.c b/arch/arm/mach-tegra/nvec_user.c
index 621ebb61e346..b11c00e0c0c4 100644
--- a/arch/arm/mach-tegra/nvec_user.c
+++ b/arch/arm/mach-tegra/nvec_user.c
@@ -22,6 +22,7 @@
#include <linux/module.h>
#include <linux/proc_fs.h>
+#include <linux/platform_device.h>
#include <linux/miscdevice.h>
#include "linux/nvos_ioctl.h"
#include "nvec.h"
@@ -49,7 +50,7 @@ int nvec_open(struct inode *inode, struct file *file)
file->private_data = (void*)Client;
return 0;
}
-
+
int nvec_close(struct inode *inode, struct file *file)
{
NvRtClientHandle client = (NvRtClientHandle)file->private_data;
@@ -77,7 +78,7 @@ int nvec_close(struct inode *inode, struct file *file)
}
return 0;
}
-
+
long nvec_unlocked_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -183,7 +184,7 @@ static struct miscdevice nvec_dev =
static NvEcHandle s_NvEcHandle = NULL;
-static int __init nvec_init( void )
+static int __init nvec_probe(struct platform_device *pdev)
{
int e = 0;
NvError status;
@@ -213,14 +214,58 @@ static int __init nvec_init( void )
return e;
}
+static int nvec_remove(struct platform_device *pdev)
+{
+ NvEcClose(s_NvEcHandle);
+ misc_deregister( &nvec_dev );
+ NvRtDestroy(s_RtHandle);
+ s_RtHandle = NULL;
+ return 0;
+}
+
+static int nvec_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ NvError e = NvEcPowerSuspend(NvEcPowerState_Suspend);
+ if (e != NvSuccess)
+ return -1;
+
+ return 0;
+}
+
+static int nvec_resume(struct platform_device *pdev)
+{
+ NvError e = NvEcPowerResume();
+ if (e != NvSuccess)
+ return -1;
+
+ return 0;
+}
+
+static void nvec_shutdown(struct platform_device *pdev)
+{
+ NvEcPowerSuspend(NvEcPowerState_PowerDown);
+}
+
+static struct platform_driver tegra_nvec_driver = {
+ .probe = nvec_probe,
+ .remove = nvec_remove,
+ .suspend = nvec_suspend,
+ .resume = nvec_resume,
+ .shutdown = nvec_shutdown,
+ .driver = {
+ .name = "nvec",
+ },
+};
+
+static int __devinit nvec_init( void )
+{
+ return platform_driver_register(&tegra_nvec_driver);
+}
+
static void __exit nvec_deinit( void )
{
- NvEcClose(s_NvEcHandle);
- misc_deregister(&nvec_dev);
- NvRtDestroy(s_RtHandle);
- s_RtHandle = NULL;
+ return platform_driver_unregister(&tegra_nvec_driver);
}
module_init(nvec_init);
module_exit(nvec_deinit);
-
diff --git a/arch/arm/mach-tegra/nvodm/nvodm_services.c b/arch/arm/mach-tegra/nvodm/nvodm_services.c
index 76f1bb344760..97e950e59d9b 100644..100755
--- a/arch/arm/mach-tegra/nvodm/nvodm_services.c
+++ b/arch/arm/mach-tegra/nvodm/nvodm_services.c
@@ -937,24 +937,9 @@ NvOdmPwmConfig(NvOdmServicesPwmHandle hOdmPwm,
void NvOdmEnableOtgCircuitry(NvBool Enable)
{
- NvRmDeviceHandle hRmDevice;
- NvRmAnalogUsbConfig UsbConfig;
- NvError e;
-
- // Open RM device handle
- NV_CHECK_ERROR_CLEANUP(NvRmOpen(&hRmDevice, 0));
-
- UsbConfig.InParam = NvRmAnalogUsbInputParam_ConfigureUsbPhy;
- NV_CHECK_ERROR_CLEANUP(
- NvRmAnalogInterfaceControl(hRmDevice, NvRmAnalogInterface_Usb,
- NV_TRUE, &UsbConfig, sizeof(NvRmAnalogUsbConfig))
- );
-
- fail:
- if (hRmDevice)
- {
- NvRmClose(hRmDevice);
- }
+ // Rm analog interface calls related to usb are deleted. This API does nothing.
+ // This API should not be called for usb phy related operations
+ return;
}
NvBool NvOdmUsbIsConnected(void)
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_analog.c b/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_analog.c
index 3c6bc3e7c523..e0fdb14938b3 100644..100755
--- a/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_analog.c
+++ b/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_analog.c
@@ -44,129 +44,6 @@
#include "nvodm_pmu.h"
#include "nvrm_clocks.h"
#include "nvrm_module.h"
-#include "ap20/arusb.h"
-
-/**
- * Structure defining the fields for USB UTMI clocks delay Parameters.
- */
-typedef struct UsbPllDelayParamsRec
-{
- // Pll-U Enable Delay Count
- NvU8 EnableDelayCount;
- //PLL-U Stable count
- NvU8 StableCount;
- //Pll-U Active delay count
- NvU8 ActiveDelayCount;
- //PLL-U Xtal frequency count
- NvU8 XtalFreqCount;
-} UsbPllDelayParams;
-
-/*
- * Set of oscillator frequencies supported
- */
-typedef enum
-{
- NvRmClocksOscFreq_13_MHz = 0x0,
- NvRmClocksOscFreq_19_2_MHz,
- NvRmClocksOscFreq_12_MHz,
- NvRmClocksOscFreq_26_MHz,
- NvRmClocksOscFreq_Num, // dummy to get number of frequencies
- NvRmClocksOscFreq_Force32 = 0x7fffffff
-} NvRmClocksOscFreq;
-
-// Possible Oscillator Frequecies in KHz for mapping the index
-NvRmFreqKHz s_RmOscFrequecy [NvRmClocksOscFreq_Num] =
-{
- 13000, // 13 Mega Hertz
- 19200,// 19.2 Mega Hertz
- 12000,// 12 Mega Hertz
- 26000 // 26 Mega Hertz
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// USB PLL CONFIGURATION & PARAMETERS: refer to the arapb_misc_utmip.spec file.
-///////////////////////////////////////////////////////////////////////////////
-// PLL CONFIGURATION & PARAMETERS for different clock generators:
-//-----------------------------------------------------------------------------
-// Reference frequency 13.0MHz 19.2MHz 12.0MHz 26.0MHz
-// ----------------------------------------------------------------------------
-// PLLU_ENABLE_DLY_COUNT 02 (02h) 03 (03h) 02 (02h) 04 (04h)
-// PLLU_STABLE_COUNT 51 (33h) 75 (4Bh) 47 (2Fh) 102 (66h)
-// PLL_ACTIVE_DLY_COUNT 05 (05h) 06 (06h) 04 (04h) 09 (09h)
-// XTAL_FREQ_COUNT 127 (7Fh) 187 (BBh) 118 (76h) 254 (FEh)
-///////////////////////////////////////////////////////////////////////////////
-static const UsbPllDelayParams s_UsbPllDelayParams[NvRmClocksOscFreq_Num] =
-{
- //ENABLE_DLY, STABLE_CNT, ACTIVE_DLY, XTAL_FREQ_CNT
- {0x02, 0x33, 0x05, 0x7F}, // For NvRmClocksOscFreq_13_MHz,
- {0x03, 0x4B, 0x06, 0xBB}, // For NvRmClocksOscFreq_19_2_MHz
- {0x02, 0x2F, 0x04, 0x76}, // For NvRmClocksOscFreq_12_MHz
- {0x04, 0x66, 0x09, 0xFE} // For NvRmClocksOscFreq_26_MHz
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// USB Debounce values IdDig, Avalid, Bvalid, VbusValid, VbusWakeUp, and SessEnd.
-// Each of these signals have their own debouncer and for each of those one out
-// of 2 debouncing times can be chosen (BIAS_DEBOUNCE_A or BIAS_DEBOUNCE_B.)
-//
-// The values of DEBOUNCE_A and DEBOUNCE_B are calculated as follows:
-// 0xffff -> No debouncing at all
-// <n> ms = <n> *1000 / (1/19.2MHz) / 4
-// So to program a 1 ms debounce for BIAS_DEBOUNCE_A, we have:
-// BIAS_DEBOUNCE_A[15:0] = 1000 * 19.2 / 4 = 4800 = 0x12c0
-// We need to use only DebounceA, We dont need the DebounceB
-// values, so we can keep those to default.
-///////////////////////////////////////////////////////////////////////////////
-static const NvU32 s_UsbBiasDebounceATime[NvRmClocksOscFreq_Num] =
-{
- /* Ten milli second delay for BIAS_DEBOUNCE_A */
- 0x7EF4, // For NvRmClocksOscFreq_13_MHz,
- 0xBB80, // For NvRmClocksOscFreq_19_2_MHz
- 0x7530, // For NvRmClocksOscFreq_12_MHz
- 0xFDE8 // For NvRmClocksOscFreq_26_MHz
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// Tracking Length Time: The tracking circuit of the bias cell consumes a
-// measurable portion of the USB idle power To curtail this power consumption
-// the bias pad has added a PD_TDK signal to power down the bias cell. It is
-// estimated that after 20microsec of bias cell operation the PD_TRK signal can
-// be turned high to sve power. This can be automated by programming a timing
-// interval as given in the below structure.
-static const NvU32 s_UsbBiasTrkLengthTime[NvRmClocksOscFreq_Num] =
-{
- /* 20 micro seconds delay after bias cell operation */
- 5, // For NvBootClocksOscFreq_13,
- 7, // For NvBootClocksOscFreq_19_2
- 5, // For NvBootClocksOscFreq_12
- 9 // For NvBootClocksOscFreq_26
-};
-
-
-///////////////////////////////////////////////////////////////////////////////
-// The following arapb_misc_utmip.spec fields need to be programmed to ensure
-// correct operation of the UTMIP block:
-// Production settings :
-// 'HS_SYNC_START_DLY' : 9,
-// 'IDLE_WAIT' : 17,
-// 'ELASTIC_LIMIT' : 16,
-// All other fields can use the default reset values.
-// Setting the fields above, together with default values of the other fields,
-// results in programming the registers below as follows:
-// UTMIP_HSRX_CFG0 = 0x9168c000
-// UTMIP_HSRX_CFG1 = 0x13
-///////////////////////////////////////////////////////////////////////////////
-//UTMIP Idle Wait Delay
-static const NvU8 s_UtmipIdleWaitDelay = 17;
-//UTMIP Elastic limit
-static const NvU8 s_UtmipElasticLimit = 16;
-//UTMIP High Speed Sync Start Delay
-static const NvU8 s_UtmipHsSyncStartDelay = 9;
-
-// Reset USB host controller
-static NvBool s_IsUSBResetRequired = NV_TRUE;
static NvError
NvRmPrivTvDcControl( NvRmDeviceHandle hDevice, NvBool enable, NvU32 inst,
@@ -270,1788 +147,6 @@ NvRmPrivVideoInputControl( NvRmDeviceHandle hDevice, NvBool enable,
}
-static void
-NvRmPrivUsbfSetUlpiLinkTrimmers(
- NvRmDeviceHandle hDevice,
- NvU32 instance)
-{
- NvU32 RegVal = 0;
-
- // Bypass the Pin Mux on the ULPI outputs and set the trimmer values for inputs to 3
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_SPARE_CFG0_0);
- RegVal = RegVal & ( ~( (0x1 << 13) | (0xf << 4) | (0xf << 28) ) );
- //bit 13 : data output pinmux bypass enable: set to 1
- //bit 4 : data input trimmer load enable (toggle)
- //bit [7:5] : data input trimmer value: set to 3
- //bit 28 : data input trimmer2 load enable (toggle)
- //bit [31:29] : data input trimmer2 value: set to 3
- RegVal = RegVal | ( (0x1 << 13) | (0x0 << 5) | (0x0 << 4) | (0x0 << 29) | (0x0 << 28) );
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_SPARE_CFG0_0, RegVal);
-
- // wait 10 us
- NvOsWaitUS(10);
- // toggle bits 4 and 28 to latch the trimmer values
- RegVal = RegVal | ( (0x1 << 4) | (0x1 << 28) );
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_SPARE_CFG0_0, RegVal);
- // wait 10 us
- NvOsWaitUS(10);
-}
-
-
-static void
-NvRmPrivUsbfSetUlpiNullTrimmers(
- NvRmDeviceHandle hDevice,
- NvU32 instance)
-{
- NvU32 RegVal = 0;
- // Configure 60M clock for USB2 - ULPI controller
-
- // Set up to use PLLU at 60 MHz and keep USB PHY PLL in reset
- // bit 27 : bypass 60 MHz Div5 for PLLU - set to 1
- // bit 9 : nullphy_pll_source - use USB_PHY_PLL output (set to 0) :
- // Workaround: set to 1 to use PLLU Output at 12 MHz
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_SPARE_CFG0_0);
- RegVal &= (~( 0x1 << 27) );
- RegVal |= ((0x1 << 9));
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_SPARE_CFG0_0,
- RegVal);
-
- // Set the trimmers
- // bit 4 : data input trimmer load enable (toggle)
- // bit [7:5] : data input trimmer value - set to 3
- // bit 28 : data input trimmer2 load enable - (toggle)
- // bit [31:29] : data input trimmer2 value - set to 3
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_SPARE_CFG0_0);
- RegVal = RegVal | ( (0x7 << 29) | (0x0 << 28) | (0x7 << 5) | (0x0 << 4) );
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_SPARE_CFG0_0, RegVal);
-
- // wait 10 us
- NvOsWaitUS(10);
- // toggle bits 4 and 28 to latch the trimmer values
- RegVal = RegVal | ( (0x1 << 4) | (0x1 << 28) );
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_SPARE_CFG0_0, RegVal);
- // wait 10 us
- NvOsWaitUS(10);
-}
-
-
-static void
-NvRmPrivUsbfUlpiClockControl(
- NvRmDeviceHandle hDevice,
- NvU32 instance,
- NvBool Enable)
-{
- NvU32 RegVal = 0;
-
- if (Enable)
- {
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_RST, DISABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_CE, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
-
- NvOsMutexLock(hDevice->CarMutex);
- // Bring Out of reset
- RegVal = NV_REGR(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0);
- RegVal = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
- SWR_USBD_RST, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegVal);
-
- NvOsMutexUnlock(hDevice->CarMutex);
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_SPARE_CFG0_0);
- RegVal = RegVal & (0xf);
-
- RegVal = RegVal | ( (0x0 << 29) | (0x0 << 28) | (0x0 << 27) | (0 << 22) |
- (0x0 << 21) | (0x0 << 16) | (0x0 << 15) | (0x1 << 14) |
- (0x1 << 13) | (0x0 << 12) | (0x1 << 11) | (0x1 << 10) |
- (0x1 << 9) | (0x0 << 5) | (0x0 << 4) );
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_SPARE_CFG0_0, RegVal);
-
- // wait 10 us
- NvOsWaitUS(10);
- }
- else
- {
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_RST, ENABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_CE, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
-
- if (!(NV_DRF_VAL(APB_MISC_PP, MISC_USB_CLK_RST_CTL, MISC_USB_CE, RegVal)))
- {
- // Enable reset
- NvOsMutexLock(hDevice->CarMutex);
- RegVal = NV_REGR(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0);
- RegVal = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
- SWR_USBD_RST, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegVal);
- NvOsMutexUnlock(hDevice->CarMutex);
- }
- }
-}
-
-static void
-NvRmPrivUsbfEnableVbusInterrupt(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
-
- //enable VBUS interrupt for cable detection when controller is Off
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_SENSORS_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, USB_PHY_VBUS_SENSORS,
- A_SESS_VLD_INT_EN, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_SENSORS_0, RegVal);
-}
-
-
-static void
-NvRmPrivUsbfDisableVbusInterrupt(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
-
- //disable the VBUS interrupt,
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_SENSORS_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, USB_PHY_VBUS_SENSORS,
- A_SESS_VLD_INT_EN, DISABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, USB_PHY_VBUS_SENSORS,
- A_SESS_VLD_CHG_DET, SET, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_SENSORS_0, RegVal);
-}
-
-
-static NvBool
-NvRmPrivUsbfIsCableConnected(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
- NvBool CableConnected = NV_FALSE;
-
- // Check for cable connection
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_SENSORS_0);
- if (NV_DRF_VAL(APB_MISC, PP_USB_PHY_VBUS_SENSORS, A_SESS_VLD_STS, RegVal))
- {
- CableConnected = NV_TRUE;
- }
- //disable the interrupt, if we detect the cable connection/dis connection
- NvRmPrivUsbfDisableVbusInterrupt(hDevice);
-
- if (!CableConnected)
- {
- NvRmPrivUsbfEnableVbusInterrupt(hDevice);
- }
-
- return CableConnected;
-}
-
-static NvError
-NvRmPrivUsbfWaitForPhyClock(
- NvRmDeviceHandle hDevice,
- NvBool Enable)
-{
- NvU32 TimeOut = 100000; // 100 milli seconds timeout before H/W gives up;
- NvU32 PhyClockValidStatus = APB_MISC_PP_MISC_USB_OTG_0_PCLKVLD_UNSET;
- NvU32 PhyClkValid = 0;
- NvU32 RegVal = 0;
- // If Enable is true, check for PHY Clock Vailid Set
- // Else check for PHY Clock Unset
- if (Enable)
- PhyClockValidStatus = APB_MISC_PP_MISC_USB_OTG_0_PCLKVLD_SET;
- // Wait for the phy clock to become valid or hardware timeout
- do {
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_PP_MISC_USB_OTG_0);
- PhyClkValid = NV_DRF_VAL(APB_MISC_PP, MISC_USB_OTG, PCLKVLD, RegVal);
- if (!TimeOut)
- {
- return NvError_Timeout;
- }
- NvOsWaitUS(1);
- TimeOut--;
- } while (PhyClkValid != PhyClockValidStatus);
-
- return NvSuccess;
-}
-
-static NvBool
-NvRmPrivUsbfIsChargerDetected(
- NvRmDeviceHandle hDevice, NvBool EnableDetection)
-{
- NvU32 RegVal = 0;
- NvBool ChargerConnected = NV_FALSE;
- #define TDP_SRC_ON_MS 100
-
- if (EnableDetection)
- {
- // Enable charger detection logic
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_OP_SRC_EN, 1, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_ON_SINK_EN, 1, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0, RegVal);
- // Source should be on for 100 ms as per USB charging spec
- NvOsSleepMS(TDP_SRC_ON_MS);
- }
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0);
- if (NV_DRF_VAL(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID, VDAT_DET_STS, RegVal))
- {
- //disable the interrupt, if we detect the charger
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID,
- VDAT_DET_INT_EN, DISABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID,
- VDAT_DET_CHG_DET, SET, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0, RegVal);
- ChargerConnected = NV_TRUE;
- // Disable charger detection logic
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_OP_SRC_EN, 0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_ON_SINK_EN, 0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0, RegVal);
-
- }
-
- return ChargerConnected;
-}
-
-static void
-NvRmPrivUsbfChargerDetection(
- NvRmDeviceHandle hDevice,
- NvBool Enable)
-{
- // These values (in milli second) are taken from the battery charging spec.
- #define TDP_SRC_ON_MS 100
- #define TDPSRC_CON_MS 40
- NvU32 RegVal = 0;
-
- if (Enable)
- {
- // Enable charger detection logic
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_OP_SRC_EN, 1, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_ON_SINK_EN, 1, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0, RegVal);
- // Source should be on for 100 ms as per USB charging spec
- NvOsSleepMS(TDP_SRC_ON_MS);
- // Check if charger is connected, enable interrupt to get the event
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0);
- if (NV_DRF_VAL(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID, VDAT_DET_STS, RegVal))
- {
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0,
- NV_DRF_DEF(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID,
- VDAT_DET_INT_EN, ENABLE));
- }
- else
- {
- // If charger is not connected disable the interrupt
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID,
- VDAT_DET_INT_EN, DISABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID,
- VDAT_DET_CHG_DET, SET, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0, RegVal);
- }
- }
- else
- {
- // Disable charger detection logic
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_OP_SRC_EN, 0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_ON_SINK_EN, 0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0, RegVal);
- // Delay of 40 ms before we pull the D+ as per battery charger spec.
- NvOsSleepMS(TDPSRC_CON_MS);
- }
-}
-
-
-static NvError
-NvRmPrivUsb3ConfigureUtmipPhy(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
- NvU32 TimeOut = 100000; // 100 milli seconds timeout before H/W gives up;
- NvU32 PhyClkValid = 0;
- NvRmFreqKHz OscFreqKz = 0;
- NvU32 FreqIndex;
-
- // Get the Oscillator Frequency
- OscFreqKz = NvRmPowerGetPrimaryFrequency(hDevice);
-
- // Get the Oscillator Frequency Index
- for (FreqIndex = 0; FreqIndex < NvRmClocksOscFreq_Num; FreqIndex++)
- {
- if (OscFreqKz == s_RmOscFrequecy[FreqIndex])
- {
- // Bail Out if frequecy matches with the supported frequency
- break;
- }
- }
- // If Index is equal to the maximum supported frequency count
- // There is a mismatch of the frequecy, so returning since the
- // frequency is not supported.
- if (FreqIndex >= NvRmClocksOscFreq_Num)
- {
- return NvError_NotSupported;
- }
-
-
- /**Hold UTMIP3 PHY in reset by writing UTMIP_RESET bit in USB3_IF_USB_SUSP_CTRL
- register to 1. **/
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_IF_USB_SUSP_CTRL_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB3_IF, USB_SUSP_CTRL, UTMIP_RESET, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_IF_USB_SUSP_CTRL_0, RegVal);
-
-
- /*1. FORCE_PD_POWERDOWN, FORCE_PD2_POWERDOWN, FORCE_PDZI_POWERDOWN fields in
- UTMIP_XCVR_CFG0 register. **/
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_XCVR_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, XCVR_CFG0, UTMIP_FORCE_PD_POWERDOWN,
- 0x0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, XCVR_CFG0, UTMIP_FORCE_PD2_POWERDOWN,
- 0x0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, XCVR_CFG0, UTMIP_FORCE_PDZI_POWERDOWN,
- 0x0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_XCVR_CFG0_0, RegVal);
-
-
- // USB Power Up sequence
- // Power Up OTG and Bias circuitry
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_BIAS_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BIAS_CFG0,
- UTMIP_OTGPD, 0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BIAS_CFG0,
- UTMIP_BIASPD, 0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_BIAS_CFG0_0, RegVal);
-
- /**OTGOD and BIASPD fields in UTMIP_BIAS_CFG0 register. **/
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_BIAS_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, BIAS_CFG0, UTMIP_OTGPD,
- 0x0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, BIAS_CFG0, UTMIP_BIASPD,
- 0x0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_BIAS_CFG0_0, RegVal);
-
- /* FORCE_PDDISC_POWERDOWEN , FORCE_PDCHRP_POWERDOWN, FORCE_PDDR_POWERDOWN
- field in UTMIP_XCVR_CFG1 register. **/
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_XCVR_CFG1_0);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, XCVR_CFG1, UTMIP_FORCE_PDDISC_POWERDOWN,
- 0x0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, XCVR_CFG1, UTMIP_FORCE_PDCHRP_POWERDOWN,
- 0x0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, XCVR_CFG1, UTMIP_FORCE_PDDR_POWERDOWN,
- 0x0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_XCVR_CFG1_0, RegVal);
-
- /**Enable UTMIP3 interface by setting UTMIP_PHY_ENB in USB3_IF_USB_SUSP_CTRL
- register to 1. **/
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_IF_USB_SUSP_CTRL_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB3_IF, USB_SUSP_CTRL, UTMIP_PHY_ENB, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_IF_USB_SUSP_CTRL_0, RegVal);
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_MISC_CFG1_0);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, MISC_CFG1,
- UTMIP_PLLU_STABLE_COUNT,
- s_UsbPllDelayParams[FreqIndex].StableCount, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, MISC_CFG1,
- UTMIP_PLL_ACTIVE_DLY_COUNT,
- s_UsbPllDelayParams[FreqIndex].ActiveDelayCount, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_MISC_CFG1_0, RegVal);
-
-
- // Set PLL enable delay count and Crystal frequency count
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_PLL_CFG1_0);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, PLL_CFG1,
- UTMIP_PLLU_ENABLE_DLY_COUNT,
- s_UsbPllDelayParams[FreqIndex].EnableDelayCount, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP,
- PLL_CFG1, UTMIP_XTAL_FREQ_COUNT,
- s_UsbPllDelayParams[FreqIndex].XtalFreqCount, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_PLL_CFG1_0, RegVal);
-
- // Program 1ms Debounce time for VBUS to become valid.
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_DEBOUNCE_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, DEBOUNCE_CFG0, UTMIP_BIAS_DEBOUNCE_A,
- s_UsbBiasDebounceATime[FreqIndex], RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_DEBOUNCE_CFG0_0, RegVal);
-
- /** pll_parameters_configured **/
-
- // Configure the UTMIP_HS_SYNC_START_DLY
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_HSRX_CFG1_0);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, HSRX_CFG1,
- UTMIP_HS_SYNC_START_DLY,
- s_UtmipHsSyncStartDelay, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_HSRX_CFG1_0, RegVal);
-
- /* Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT
- * Setting these fields, together with default values of the other
- * fields, results in programming the registers below as follows:
- * UTMIP_HSRX_CFG0 = 0x9168c000
- * UTMIP_HSRX_CFG1 = 0x13
- */
-
- // Set PLL enable delay count and Crystal frequency count
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_HSRX_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP, HSRX_CFG0,
- UTMIP_IDLE_WAIT,
- s_UtmipIdleWaitDelay, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB3_UTMIP,
- HSRX_CFG0, UTMIP_ELASTIC_LIMIT,
- s_UtmipElasticLimit, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_UTMIP_HSRX_CFG0_0, RegVal);
-
- /**Release reset to UTMIP3 by writing 0 to UTMIP_RESET field in
- USB3_IF_USB_SUSP_CTRL register. ***/
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_IF_USB_SUSP_CTRL_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB3_IF, USB_SUSP_CTRL, UTMIP_RESET, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_IF_USB_SUSP_CTRL_0, RegVal);
-
-
- /**Wait until PHY clock comes up by checking for USB_PHY_CLK_VALID bit in
- USB3_IF_USB_SUSP_CTRL register **/
- do
- {
- //Wait for the phy clock to become valid
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_IF_USB_SUSP_CTRL_0);
- PhyClkValid = NV_DRF_VAL(USB3_IF, USB_SUSP_CTRL, USB_PHY_CLK_VALID, RegVal);
-
- if (!TimeOut)
- {
- break;
- }
- NvOsWaitUS(1);
- TimeOut--;
- } while (!PhyClkValid);
-
- /* We can only do this once PHY clock is up. Disable ICUSB interface (it is enabled by default) */
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB2_CONTROLLER_1_USB2D_ICUSB_CTRL_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ICUSB_CTRL, IC_ENB1, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB2_CONTROLLER_1_USB2D_ICUSB_CTRL_0, RegVal);
-
- /**Program the USB3 controller to use UTMIP3 PHY by setting the PTS field in
- USB2_CONTROLLER_USB2D_PORTSC1 register to UTMIP (2'b00). **/
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB2_CONTROLLER_USB2D_PORTSC1_0);
-
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER, USB2D_PORTSC1, PTS, UTMI, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER, USB2D_PORTSC1, STS, PARALLEL_IF, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 2, USB2_CONTROLLER_USB2D_PORTSC1_0, RegVal);
-
- return NvSuccess;
-}
-
-
-static NvError
-NvRmPrivUsbfConfigureUtmipPhy(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
- NvRmFreqKHz OscFreqKz = 0;
- NvU32 FreqIndex;
-
- // Get the Oscillator Frequency
- OscFreqKz = NvRmPowerGetPrimaryFrequency(hDevice);
-
- // Get the Oscillator Frequency Index
- for (FreqIndex = 0; FreqIndex < NvRmClocksOscFreq_Num; FreqIndex++)
- {
- if (OscFreqKz == s_RmOscFrequecy[FreqIndex])
- {
- // Bail Out if frequecy matches with the supported frequency
- break;
- }
- }
- // If Index is equal to the maximum supported frequency count
- // There is a mismatch of the frequecy, so returning since the
- // frequency is not supported.
- if (FreqIndex >= NvRmClocksOscFreq_Num)
- {
- return NvError_NotSupported;
- }
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_TX_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_TX_CFG0, UTMIP_FS_PREAMBLE_J,
- 0x1, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_TX_CFG0_0, RegVal);
-
- // Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT
- // Setting these fields, together with default values of the other
- // fields, results in programming the registers below as follows:
- // UTMIP_HSRX_CFG0 = 0x9168c000
- // UTMIP_HSRX_CFG1 = 0x13
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_HSRX_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_HSRX_CFG0, UTMIP_IDLE_WAIT,
- s_UtmipIdleWaitDelay, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_HSRX_CFG0, UTMIP_ELASTIC_LIMIT,
- s_UtmipElasticLimit, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_HSRX_CFG0_0, RegVal);
-
- // Configure the UTMIP_HS_SYNC_START_DLY
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_HSRX_CFG1_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_HSRX_CFG1,
- UTMIP_HS_SYNC_START_DLY, s_UtmipHsSyncStartDelay, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_HSRX_CFG1_0, RegVal);
-
- // Program 1ms Debounce time for VBUS to become valid.
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_DEBOUNCE_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_DEBOUNCE_CFG0,
- UTMIP_BIAS_DEBOUNCE_A,s_UsbBiasDebounceATime[FreqIndex],
- RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_DEBOUNCE_CFG0_0, RegVal);
-
- // PLL Delay CONFIGURATION settings
- // The following parameters control the bring up of the plls:
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_MISC_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_MISC_CFG0,
- UTMIP_SUSPEND_EXIT_ON_EDGE, 0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_MISC_CFG0_0, RegVal);
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_MISC_CFG1_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_MISC_CFG1,
- UTMIP_PLLU_STABLE_COUNT,
- s_UsbPllDelayParams[FreqIndex].StableCount, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_MISC_CFG1,
- UTMIP_PLL_ACTIVE_DLY_COUNT,
- s_UsbPllDelayParams[FreqIndex].ActiveDelayCount, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_MISC_CFG1_0, RegVal);
-
- // Set PLL enable delay count and Crystal frequency count
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_PLL_CFG1_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_PLL_CFG1,
- UTMIP_PLLU_ENABLE_DLY_COUNT,
- s_UsbPllDelayParams[FreqIndex].EnableDelayCount, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC,
- UTMIP_PLL_CFG1, UTMIP_XTAL_FREQ_COUNT,
- s_UsbPllDelayParams[FreqIndex].XtalFreqCount, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_PLL_CFG1_0, RegVal);
-
- // On AP20 FPGA we do not have VBUS_WAKEUP signal for cable detection.
- // We use A_SESS_VLD that comes from the external UTMIP PHY
- if (NvRmPrivGetExecPlatform(hDevice) == ExecPlatform_Fpga)
- {
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_PP_USB_PHY_PARAM_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC, PP_USB_PHY_PARAM, VS_CTL, A_SESS_VLD, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_PP_USB_PHY_PARAM_0, RegVal);
- }
- return NvSuccess;
-}
-
-static void
-NvRmPrivUsbfPowerControl(
- NvRmDeviceHandle hDevice,
- NvU32 Instance,
- NvBool Enable)
-{
- NvU32 RegVal = 0;
- const NvOdmUsbProperty *pUsbProperty = NULL;
- NvU32 TimeOut = 100000; // 100 milli seconds timeout before H/W gives up;
- static NvU32 s_XcvrSetupValue = 0;
- static NvBool s_ReadFuseValue = NV_FALSE;
-
- if (Enable)
- {
- // USB Power Up sequence
- // Power Up OTG and Bias circuitry
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_BIAS_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BIAS_CFG0,
- UTMIP_OTGPD, 0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BIAS_CFG0,
- UTMIP_BIASPD, 0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_BIAS_CFG0_0, RegVal);
-
- if (!s_ReadFuseValue)
- {
-#if NV_USE_FUSE_CLOCK_ENABLE
- // Enable fuse clock
- NvRmPowerModuleClockControl(hDevice, NvRmModuleID_Fuse, 0, NV_TRUE);
-#endif
- // Enable fuse values to be visible before reading the fuses.
- RegVal = NV_REGR( hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_MISC_CLK_ENB_0 );
- RegVal = NV_FLD_SET_DRF_NUM( CLK_RST_CONTROLLER, MISC_CLK_ENB,
- CFG_ALL_VISIBLE, 1, RegVal );
- NV_REGW( hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_MISC_CLK_ENB_0, RegVal );
-
- // Read the spare register fuses and redundancy fuses for setting up USB
- // UTMIP_XCVR_SETUP value for proper EYE diagram.
- RegVal = NV_REGR( hDevice, NvRmModuleID_Fuse, 0, FUSE_FUSEDATA21_0);
-
- s_XcvrSetupValue = (NV_DRF_VAL(FUSE, FUSEDATA21,FUSEDATA_SPARE_BIT_10__PRI_ALIAS_0, RegVal) |
- NV_DRF_VAL(FUSE, FUSEDATA21, FUSEDATA_SPARE_BIT_13__PRI_ALIAS_0, RegVal)) << 0;
- s_XcvrSetupValue |= (NV_DRF_VAL(FUSE, FUSEDATA21, FUSEDATA_SPARE_BIT_11__PRI_ALIAS_0, RegVal) |
- NV_DRF_VAL(FUSE, FUSEDATA21, FUSEDATA_SPARE_BIT_14__PRI_ALIAS_0, RegVal)) << 1;
- s_XcvrSetupValue |= (NV_DRF_VAL(FUSE, FUSEDATA21, FUSEDATA_SPARE_BIT_12__PRI_ALIAS_0, RegVal) |
- NV_DRF_VAL(FUSE, FUSEDATA21, FUSEDATA_SPARE_BIT_15__PRI_ALIAS_0, RegVal)) << 2;
- // Only UTMIP_XCVR_SETUP[3-1] need to be programmed with the fuse vlaue
- // UTMIP_XCVR_SETUP[0] must be equal to 0
- s_XcvrSetupValue = s_XcvrSetupValue << 1;
-
- // Disable fuse values visibility, we already read the data
- RegVal = NV_REGR( hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_MISC_CLK_ENB_0 );
- RegVal = NV_FLD_SET_DRF_NUM( CLK_RST_CONTROLLER, MISC_CLK_ENB,
- CFG_ALL_VISIBLE, 0, RegVal );
- NV_REGW( hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_MISC_CLK_ENB_0, RegVal );
- s_ReadFuseValue = NV_TRUE;
-#if NV_USE_FUSE_CLOCK_ENABLE
- // Disable fuse clock
- NvRmPowerModuleClockControl(hDevice, NvRmModuleID_Fuse, 0, NV_FALSE);
-#endif
- }
-
- //NvOsDebugPrintf("s_XcvrSetupValue from fuse [0x%x] \n", s_XcvrSetupValue);
-
- // Turn on power in the tranciver
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_XCVR_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_XCVR_CFG0,
- UTMIP_FORCE_PDZI_POWERDOWN, 0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_XCVR_CFG0,
- UTMIP_FORCE_PD2_POWERDOWN, 0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_XCVR_CFG0,
- UTMIP_FORCE_PD_POWERDOWN, 0, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_XCVR_CFG0,
- UTMIP_XCVR_SETUP, s_XcvrSetupValue, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_XCVR_CFG0_0, RegVal);
-
- // Enable Batery charge enabling bit, set to '0' for enable
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_PD_CHRG, 0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0, RegVal);
-
- if (hDevice->ChipId.Id == 0x16)
- {
- if(s_IsUSBResetRequired)
- {
- NvOsMutexLock(hDevice->CarMutex);
- // Put the controller in reset
- RegVal = NV_REGR(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0);
- RegVal = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
- SWR_USBD_RST, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegVal);
- NvOsMutexUnlock(hDevice->CarMutex);
- s_IsUSBResetRequired = NV_FALSE;
- }
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB_CE, ENABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB_RST, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
- }
- NvOsMutexLock(hDevice->CarMutex);
- // Bring Out of reset
- RegVal = NV_REGR(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0);
- RegVal = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
- SWR_USBD_RST, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegVal);
- NvOsMutexUnlock(hDevice->CarMutex);
-
- }
- else
- {
- // USB Power down sequence
- // Power down OTG and Bias circuitry
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_BIAS_CFG0_0);
- // Query if Internal Phy is going to wake up the usb controller upon cable insertion.
- pUsbProperty = NvOdmQueryGetUsbProperty(NvOdmIoModule_Usb, Instance);
- if (!pUsbProperty->UseInternalPhyWakeup)
- {
- /// If not internal Phy then Use PMU interrupt for VBUS detection.
- /// Disable the OTG bias circuitry.
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BIAS_CFG0,
- UTMIP_OTGPD, 1, RegVal);
- }
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BIAS_CFG0,
- UTMIP_BIASPD, 1, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_BIAS_CFG0_0, RegVal);
-
- // Disable Batery charge enabling bit set to '1' for disable
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_BAT_CHRG_CFG0,
- UTMIP_PD_CHRG, 1, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_UTMIP_BAT_CHRG_CFG0_0, RegVal);
-
- // Turn off power in the tranciver
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_XCVR_CFG0_0);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_XCVR_CFG0,
- UTMIP_FORCE_PDZI_POWERDOWN, 1, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_XCVR_CFG0,
- UTMIP_FORCE_PD2_POWERDOWN, 1, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(APB_MISC, UTMIP_XCVR_CFG0,
- UTMIP_FORCE_PD_POWERDOWN, 1, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_UTMIP_XCVR_CFG0_0, RegVal);
-
- if (hDevice->ChipId.Id == 0x16)
- {
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB_RST, ENABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB_CE, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
- if (!(NV_DRF_VAL(APB_MISC_PP, MISC_USB_CLK_RST_CTL, MISC_USB2_CE, RegVal)))
- {
- // Enable reset
- NvOsMutexLock(hDevice->CarMutex);
- RegVal = NV_REGR(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0);
- RegVal = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
- SWR_USBD_RST, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegVal);
- NvOsMutexUnlock(hDevice->CarMutex);
- }
- }
- else
- {
- // Enable reset
- NvOsMutexLock(hDevice->CarMutex);
- RegVal = NV_REGR(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0);
- RegVal = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
- SWR_USBD_RST, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegVal);
- NvOsMutexUnlock(hDevice->CarMutex);
- }
- // Wait till B Session end
- do {
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_SENSORS_0,
- NV_DRF_DEF(APB_MISC_PP, USB_PHY_VBUS_SENSORS,
- A_SESS_VLD_CHG_DET, SET));
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_SENSORS_0);
- if (NV_DRF_VAL(APB_MISC_PP, USB_PHY_VBUS_SENSORS, B_SESS_END_STS, RegVal))
- {
- // break here once the B Session end apears.
- break;
- }
- NvOsWaitUS(1);
- TimeOut--;
- } while (TimeOut);
- }
-}
-
-#if 0
-static void
-NvRmPrivUsbfDisableChargerInterrupt(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
-
- // disable the charger Interrupt
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0, APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID, VDAT_DET_INT_EN, DISABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC, PP_USB_PHY_VBUS_WAKEUP_ID, VDAT_DET_CHG_DET, SET, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0, APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0, RegVal);
-}
-#endif
-
-static void NvRmUsbPrivConfigureUsbPhy(
- NvRmDeviceHandle hDevice,
- NvBool Enable)
- {
- NvU32 RegVal;
- NvU32 TimeOut = 1000;
- NvU32 PhyClkValid = 0;
- NvU32 UlpiRunBit = 1;
- //NvU32 ReadValue = 0;
- //NvU32 i;
-
- if(Enable)
- {
-
- if(s_IsUSBResetRequired)
- {
- // If USB1 is active by this time by KITL, do not do a car reset
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- if (!(NV_DRF_VAL(APB_MISC_PP, MISC_USB_CLK_RST_CTL, MISC_USB_CE, RegVal)))
- {
- NvOsMutexLock(hDevice->CarMutex);
- // Put the controller in reset
- RegVal = NV_REGR(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0);
- RegVal = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
- SWR_USBD_RST, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegVal);
- NvOsMutexUnlock(hDevice->CarMutex);
- }
- s_IsUSBResetRequired = NV_FALSE;
- }
- // Bring controller out of reset
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_RST, DISABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_CE, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
-
- NvOsMutexLock(hDevice->CarMutex);
- // Bring Out of reset
- RegVal = NV_REGR(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0);
- RegVal = NV_FLD_SET_DRF_DEF(CLK_RST_CONTROLLER, RST_DEVICES_L,
- SWR_USBD_RST, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmPrivModuleID_ClockAndReset, 0,
- CLK_RST_CONTROLLER_RST_DEVICES_L_0, RegVal);
- NvOsMutexUnlock(hDevice->CarMutex);
- // Wake-up ULPI PHY generate a postive pulse
- //set
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_IF_USB_SUSP_CTRL_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_IF, USB_SUSP_CTRL, USB_SUSP_CLR, SET,
- RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_IF_USB_SUSP_CTRL_0, RegVal);
-
- // wait 10 us
- NvOsWaitUS(100);
-
- // clear
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_IF_USB_SUSP_CTRL_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_IF, USB_SUSP_CTRL,
- USB_SUSP_CLR, UNSET, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_IF_USB_SUSP_CTRL_0, RegVal);
-
- // Set the MISC_USB2_CLK_OVR_ON bit and update PP_MISC_USB_CLK_RST_CTL register.
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL, MISC_USB2_CLK_OVR_ON,
- ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
-
-
- // Setting the ULPI register IndicatorPassThru to 1
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0x8, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x40, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- // Setting ULPI register UseExternalVbusIndicator to 1.
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0xB, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x80, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- }
- else
- {
- // Programming the ULPI register functuion control
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0x4, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x4d, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
- // Resetting the ULPI register IndicatorPassThru
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0x7, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x0, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- // Resetting ULPI register UseExternalVbusIndicator
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0xa, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x86, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- // making sure vbus comparator and id are off
- // USB Interrupt Rising
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0x0d, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x00, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- // USB Interrupt Falling
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0x10, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x00, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0x19, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x00, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- // Disabling ID float Rise/Fall (Carkit Enable)
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0x1D, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x00, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, WRITE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, 0x39, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_DATA_WR, 0x00, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-#if 0
- // STARTING register
- // taking the register dump for all ULPI 3317 register
- // staring from FCR
- //Read FCR
- for (i = 0x4;i < 0x14;i+=0x3)
- {
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, READ, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, i, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- ReadValue = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_DATA_RD, RegVal);
-
- NvOsDebugPrintf("USB ULPI 3317 reg @ 0x%x value %x",i,ReadValue);
- }
-
- // USB IL
- i = 0x14;
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, READ, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, i, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- ReadValue = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_DATA_RD, RegVal);
-
- NvOsDebugPrintf("USB ULPI 3317 (USB IL)i @ 0x%x value %x",i,ReadValue);
-
-
- // USB CARKit
- i = 0x19;
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, READ, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, i, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- ReadValue = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_DATA_RD, RegVal);
-
- NvOsDebugPrintf("USB ULPI 3317 (USB CARKit)i @ 0x%x value %x",i,ReadValue);
-
- // USB CARKit IE
- i = 0x1D;
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, READ, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, i, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- ReadValue = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_DATA_RD, RegVal);
-
- NvOsDebugPrintf("USB ULPI 3317 (USB CARKit IE)i @ 0x%x value %x",i,ReadValue);
-
- // USB CARKit IS
- i = 0x20;
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, READ, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, i, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- ReadValue = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_DATA_RD, RegVal);
-
- NvOsDebugPrintf("USB ULPI 3317 (USB CARKit IS)i @ 0x%x value %x",i,ReadValue);
-
- // USB CARKit IL
- i = 0x21;
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, READ, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, i, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- ReadValue = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_DATA_RD, RegVal);
-
- NvOsDebugPrintf("USB ULPI 3317 (USB CARKit IL)i @ 0x%x value %x ",i,ReadValue);
-
-
- // USB I/0
- i = 0x39;
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_WAKEUP, CLEAR, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RUN, SET, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_RD_WR, READ, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_PORT, SW_DEFAULT, RegVal);
- RegVal = NV_FLD_SET_DRF_NUM(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT,
- ULPI_REG_ADDR, i, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0, RegVal);
-
- UlpiRunBit = 1;
- do
- {
- // check for run bit being cleared..
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_ULPI_VIEWPORT_0);
-
- UlpiRunBit = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_RUN, RegVal);
- } while (UlpiRunBit);
-
- ReadValue = NV_DRF_VAL(USB2_CONTROLLER_1, USB2D_ULPI_VIEWPORT, ULPI_DATA_RD, RegVal);
-
- NvOsDebugPrintf("USB ULPI 3317 (USB I/O)i @ 0x%x value %x",i,ReadValue);
-
- //// done with the register dump..
- // ENDING register dump programming..
-#endif
-
- // clear WKCN/WKDS/WKOC wake-on events that can cause the USB Controller to
- // immediately bring the ULPI PHY out of low power mode after setting PHCD
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_PORTSC1_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_USB2D, PORTSC1, WKCN,
- DISBLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_USB2D, PORTSC1, WKDS,
- DISBLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_USB2D, PORTSC1, WKOC,
- DISBLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_PORTSC1_0, RegVal);
-
- // before disabling clock.. put the phy to low power mode..
- // enter low power suspend mode
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_PORTSC1_0);
- RegVal = NV_FLD_SET_DRF_DEF(USB2_CONTROLLER_1, USB2D_PORTSC1, PHCD,
- ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Usb2Otg, 1,
- USB2_CONTROLLER_1_USB2D_PORTSC1_0, RegVal);
-
- // check for the phy in suspend..
- do
- {
- //Wait for the phy clock to stop or invalid
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 1 ,
- USB2_IF_USB_SUSP_CTRL_0);
-
- PhyClkValid = NV_DRF_VAL(USB2_IF, USB_SUSP_CTRL, USB_PHY_CLK_VALID,
- RegVal);
-
- if (!TimeOut)
- {
- break;
- }
- NvOsWaitUS(1);
- TimeOut--;
- } while (PhyClkValid);
-
-
- //NvRmAnalogUsbInputParam_ConfigureUsbPhy
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_CE, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
-
- s_IsUSBResetRequired = NV_TRUE;
- }
-}
-
-
-static void
-NvRmPrivUsbfEnableIdInterrupt(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
-
- //enable ID interrupt for A cable detection
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, USB_PHY_VBUS_WAKEUP_ID,
- ID_INT_EN, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0, RegVal);
-}
-
-static void
-NvRmPrivUsbfDisableIdInterrupt(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
-
- //disable the ID interrupt,
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, USB_PHY_VBUS_WAKEUP_ID,
- ID_INT_EN, DISABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, USB_PHY_VBUS_WAKEUP_ID,
- ID_CHG_DET, SET, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0, RegVal);
-}
-
-static NvBool
-NvRmPrivUsbfIsIdSetToLow(
- NvRmDeviceHandle hDevice)
-{
- NvU32 RegVal = 0;
- NvBool IdSetToLow = NV_FALSE;
-
- // Check for A cable connection
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0);
- if (!NV_DRF_VAL(APB_MISC_PP, USB_PHY_VBUS_WAKEUP_ID, ID_STS, RegVal))
- {
- IdSetToLow = NV_TRUE;
- }
-
- //Ack the ID interrupt,
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, USB_PHY_VBUS_WAKEUP_ID,
- ID_CHG_DET, SET, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_USB_PHY_VBUS_WAKEUP_ID_0, RegVal);
-
- return IdSetToLow;
-}
-static void NvRmUsbPrivEnableUsb2Clock( NvRmDeviceHandle hDevice )
-{
- NvU32 RegVal;
-
- // fist enable clocks to USB2
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_CE, ENABLE, RegVal);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB_CE, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
-
- // wait 10 us
- NvOsWaitUS(10);
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_RST, DISABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
-
- // wait 10 us
- NvOsWaitUS(10);
-
- RegVal = NV_REGR(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0);
- RegVal = NV_FLD_SET_DRF_DEF(APB_MISC_PP, MISC_USB_CLK_RST_CTL,
- MISC_USB2_RST, ENABLE, RegVal);
- NV_REGW(hDevice, NvRmModuleID_Misc, 0,
- APB_MISC_PP_MISC_USB_CLK_RST_CTL_0, RegVal);
-
- // wait 10 us
- NvOsWaitUS(10);
-}
-
-static NvError
-NvRmPrivUsbfControl(
- NvRmDeviceHandle hDevice,
- NvBool Enable,
- NvU32 inst,
- void *Config,
- NvU32 ConfigLength)
-{
- NvError error = NvSuccess;
- NvRmAnalogUsbConfig *pUsbConf = NULL;
- static NvBool s_IsUsb0PhyConfigured = NV_FALSE;
- static NvBool s_IsUsb2PhyConfigured = NV_FALSE;
- NvU32 TimeOut = 100000; // 100 milli seconds timeout before H/W gives up;
- NvU32 PhyClkValid = 0;
- NvU32 RegVal = 0;
-
-
- const NvOdmUsbProperty *pUsbProperty = NULL;
-
- NV_ASSERT(Config);
-
- pUsbConf = (NvRmAnalogUsbConfig *)Config;
-
- switch (pUsbConf->InParam)
- {
- case NvRmAnalogUsbInputParam_CheckCableStatus:
- if (inst == 0)
- {
- pUsbConf->UsbCableDetected = NvRmPrivUsbfIsCableConnected(hDevice);
- // At this time we don't know charger is connected or not
- pUsbConf->UsbChargerDetected = NV_FALSE;
- }
- break;
- case NvRmAnalogUsbInputParam_WaitForPhyClock:
- if (inst == 0)
- {
- // Wait for PHY clock to settle
- error = NvRmPrivUsbfWaitForPhyClock(hDevice, Enable);
- }
- if( inst == 2)
- {
- // wait for USB3 phy clock is settle
- /**Wait until PHY clock comes up by checking for USB_PHY_CLK_VALID bit in
- USB3_IF_USB_SUSP_CTRL register **/
-
- do {
- //Wait for the phy clock to become valid
- RegVal = NV_REGR(hDevice, NvRmModuleID_Usb2Otg, 2, USB3_IF_USB_SUSP_CTRL_0);
-
- PhyClkValid = NV_DRF_VAL(USB3_IF, USB_SUSP_CTRL, USB_PHY_CLK_VALID, RegVal);
-
- if (!TimeOut)
- {
- break;
- }
- NvOsWaitUS(1);
- TimeOut--;
- } while (!PhyClkValid);
- }
-
- break;
- case NvRmAnalogUsbInputParam_CheckChargerStatus:
- if (inst == 0)
- {
- // Check whether the Dumb charger is detected
- pUsbConf->UsbChargerDetected = NvRmPrivUsbfIsChargerDetected(hDevice, Enable);
- }
- break;
- case NvRmAnalogUsbInputParam_ChargerDetection:
- if (inst == 0)
- {
- // Enable Charger detection logic
- NvRmPrivUsbfChargerDetection(hDevice, Enable);
- }
- break;
- case NvRmAnalogUsbInputParam_ConfigureUsbPhy:
- if (inst == 1) // for ULPI
- {
- NvRmUsbPrivConfigureUsbPhy(hDevice, Enable);
- }
- else
- {
- // UTMIP settings
- if (Enable)
- {
- if ((inst == 0) && (s_IsUsb0PhyConfigured == NV_TRUE))
- {
- // If Usb0 Phy is already configure; nothing to do
- return NvSuccess;
- }
- else if((inst == 2) && (s_IsUsb2PhyConfigured == NV_TRUE))
- {
- // If Usb2 Phy is already configure; nothing to do
- return NvSuccess;
- }
- /** For AP20 instance 2 is utmip and we need to select this
- interface **/
- pUsbProperty = NvOdmQueryGetUsbProperty(NvOdmIoModule_Usb, inst);
- if ((inst == 2) && (pUsbProperty->UsbInterfaceType ==
- NvOdmUsbInterfaceType_Utmi))
- {
- // Select UTMIP3 incase of usb3 and UTMIP
- error = NvRmPrivUsb3ConfigureUtmipPhy(hDevice);
- if (error != NvSuccess)
- {
- return error;
- }
- s_IsUsb2PhyConfigured = NV_TRUE;
- }
- else
- {
- // Configure USB1 UTMIP Phy
- error = NvRmPrivUsbfConfigureUtmipPhy(hDevice);
- if (error != NvSuccess)
- {
- return error;
- }
- // Enable USB circuitry
- NvRmPrivUsbfPowerControl(hDevice, inst, Enable);
- s_IsUsb0PhyConfigured = NV_TRUE;
- }
- }
- else
- {
- if (inst == 0) // for UTMIP1
- {
- // Disable power to the USB phy
- NvRmPrivUsbfPowerControl(hDevice, inst, Enable);
- // Enable VBUS interrupt when USB controller is OFF
- NvRmPrivUsbfEnableVbusInterrupt(hDevice);
- }
- if (inst == 0)
- s_IsUsb0PhyConfigured = NV_FALSE;
- else if (inst == 2)
- s_IsUsb2PhyConfigured = NV_FALSE;
- }
- }
- break;
- case NvRmAnalogUsbInputParam_SetUlpiNullTrimmers:
- if (inst == 1)
- {
- NvRmPrivUsbfSetUlpiNullTrimmers(hDevice, inst);
- }
- break;
- case NvRmAnalogUsbInputParam_SetUlpiLinkTrimmers:
- if (inst == 1)
- {
- NvRmPrivUsbfSetUlpiLinkTrimmers(hDevice, inst);
- }
- break;
- case NvRmAnalogUsbInputParam_VbusInterrupt:
- if (inst == 0)
- {
- if (Enable)
- {
- // enable VBus Interrupt
- NvRmPrivUsbfEnableVbusInterrupt(hDevice);
- }
- else
- {
- // disable VBUS interrupt
- NvRmPrivUsbfDisableVbusInterrupt(hDevice);
- }
- }
- break;
- case NvRmAnalogUsbInputParam_ConfigureUlpiNullClock:
- break;
- case NvRmAnalogUsbInputParam_SetNullUlpiPinMux:
- if(inst == 1)
- {
- NvRmSetModuleTristate(hDevice,
- NVRM_MODULE_ID(NvRmModuleID_Usb2Otg, inst),
- NV_FALSE);
-
- // enb_usb2_clocks
- NvRmUsbPrivEnableUsb2Clock(hDevice);
- NvRmPrivUsbfUlpiClockControl(hDevice, inst, Enable);
- }
- break;
- case NvRmAnalogUsbInputParam_IdInterrupt:
- if (inst == 0)
- {
- if (Enable)
- {
- // enable ID Interrupt
- NvRmPrivUsbfEnableIdInterrupt(hDevice);
- }
- else
- {
- // disable ID interrupt
- NvRmPrivUsbfDisableIdInterrupt(hDevice);
- }
- }
- break;
- case NvRmAnalogUsbInputParam_CheckIdStatus:
- if (inst == 0)
- {
- pUsbConf->UsbIdDetected = NvRmPrivUsbfIsIdSetToLow(hDevice);
- }
- break;
- default:
- NV_ASSERT(NV_FALSE);
- break;
- }
-
- return error;
-}
-
-
NvError
NvRmAnalogInterfaceControl(
NvRmDeviceHandle hDevice,
@@ -2082,10 +177,6 @@ NvRmAnalogInterfaceControl(
break;
case NvRmAnalogInterface_Uart:
break;
- case NvRmAnalogInterface_Usb:
- err = NvRmPrivUsbfControl( hDevice, Enable, inst, Config,
- ConfigLength );
- break;
case NvRmAnalogInterface_Sdio:
break;
case NvRmAnalogInterface_Tv:
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c b/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c
index 0a798f4f4efe..a08f1d47a98b 100644
--- a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c
+++ b/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c
@@ -133,6 +133,7 @@
#include "rm_dma_hw_private.h"
#include "nvassert.h"
#include "nvrm_priv_ap_general.h"
+#include "mach/nvrm_linux.h"
/* FIXME move these to some header file */
NvError NvRmPrivDmaInit(NvRmDeviceHandle hDevice);
@@ -141,7 +142,6 @@ NvError NvRmPrivDmaSuspend(void);
NvError NvRmPrivDmaResume(void);
#define MAX_AVP_DMA_CHANNELS 3
-#define MAX_RESERVED_DMA_CHANNELS 3
// DMA capabilities -- these currently do not vary between chips
@@ -394,6 +394,13 @@ static DmaHwInterface s_ApbDmaInterface;
static NvOsInterruptHandle s_ApbDmaInterruptHandle = NULL;
#endif
+NvU32 NvRmDmaUnreservedChannels(void)
+{
+ return s_DmaInfo.NumApbDmaChannels - MAX_AVP_DMA_CHANNELS -
+ TEGRA_SYSTEM_DMA_CH_NUM;
+}
+
+
/**
* Deinitialize the apb dma physical/virtual addresses. This function will
* unmap the virtual mapping.
@@ -969,7 +976,6 @@ static NvError RegisterAllDmaInterrupt(NvRmDeviceHandle hDevice)
NvOsInterruptHandler DmaIntHandler = ApbDmaIsr;
NvU32 Irq = 0;
NvU32 i;
- NvU32 n;
/* Disable interrupts for all channels */
for (i=0; i < s_DmaInfo.NumApbDmaChannels; i++)
@@ -979,9 +985,7 @@ static NvError RegisterAllDmaInterrupt(NvRmDeviceHandle hDevice)
#if NVOS_IS_LINUX
/* Register same interrupt hanlder for all APB DMA channels. */
- n = s_DmaInfo.NumApbDmaChannels - MAX_RESERVED_DMA_CHANNELS -
- MAX_AVP_DMA_CHANNELS;
- for (i=0; i < n; i++)
+ for (i=0; i < NvRmDmaUnreservedChannels(); i++)
{
Irq = NvRmGetIrqForLogicalInterrupt(hDevice, ModuleId, i);
Error = NvRmInterruptRegister(hDevice, 1, &Irq,
@@ -1015,11 +1019,8 @@ static void UnregisterAllDmaInterrupt(NvRmDeviceHandle hDevice)
{
#if NVOS_IS_LINUX
NvU32 i;
- NvU32 n;
- n = s_DmaInfo.NumApbDmaChannels - MAX_RESERVED_DMA_CHANNELS -
- MAX_AVP_DMA_CHANNELS;
- for (i=0; i < n; i++)
+ for (i=0; i < NvRmDmaUnreservedChannels(); i++)
{
NvRmInterruptUnregister(hDevice,
s_DmaInfo.pListApbDmaChannel[i].hIntrHandle);
@@ -1326,7 +1327,6 @@ NvRmDmaAllocate(
NvU32 UniqueId;
RmDmaChannel *pDmaChannel = NULL;
NvRmDmaHandle hNewDma = NULL;
- NvU32 MaxChannel;
RmDmaChannel *pChannelList = NULL;
NvU32 ChanIndex;
@@ -1385,13 +1385,12 @@ NvRmDmaAllocate(
// For high priority dma channel request, use the free channel. And for low
// priority channel use the used channel low priority channels.
- MaxChannel = s_DmaInfo.NumApbDmaChannels - MAX_AVP_DMA_CHANNELS - MAX_RESERVED_DMA_CHANNELS;
pChannelList = s_DmaInfo.pListApbDmaChannel;
// Going to access the data which is shared across the different thread.
NvOsMutexLock(s_DmaInfo.hDmaAllocMutex);
- for (ChanIndex = 0; ChanIndex < MaxChannel; ++ChanIndex)
+ for (ChanIndex = 0; ChanIndex < NvRmDmaUnreservedChannels(); ++ChanIndex)
{
pDmaChannel = &pChannelList[ChanIndex];
if ((Priority == pDmaChannel->Priority) && (pDmaChannel->ChannelState == RmDmaChannelState_Free))
diff --git a/arch/arm/mach-tegra/pci-enum.c b/arch/arm/mach-tegra/pci-enum.c
new file mode 100644
index 000000000000..1dab1de0a86d
--- /dev/null
+++ b/arch/arm/mach-tegra/pci-enum.c
@@ -0,0 +1,637 @@
+/*
+ * arch/arm/mach-tegra/pci-enum.c
+ *
+ * Code to enumerate the PCI devices on the PCI bus. Unlike x86 we cannot
+ * rely on BIOS to allocate the PCIe resources for the devices.
+ *
+ * Copyright (c) 2008-2009, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <mach/pci.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+struct pci_tegra_device
+{
+ /* Bus number */
+ u8 bus;
+
+ /* Device + function encoding.
+ * Use macros PCI_DEVFN/PCI_SLOT/PCI_FUNC to encode and decode
+ * */
+ u32 devfn;
+
+ /* Secondary bus nummber. Non-zero only for bridge devices. */
+ u32 sec_bus;
+
+ /* Subordinate bus number. Non-zero only for the bridge devices. */
+ u32 sub_bus;
+
+ /* Device ID/vendor ID of the PCI device/bridge.
+ * Upper 16 bits are device ID and lower 16 bits are vendor ID.
+ */
+ u32 id;
+
+ /* For a bridge device only 3 bars are used.
+ */
+#define PCI_BRIDGE_IO_RES 0
+#define PCI_BRIDGE_MEM_RES 1
+#define PCI_BRIDGE_PREFETCH_RES 2
+
+ /* Here we are limiting to the standard PCI resources */
+ struct resource res[PCI_STD_RESOURCE_END + 1];
+
+ bool disabled;
+
+ struct pci_tegra_device *parent;
+ struct pci_tegra_device *next;
+ struct pci_tegra_device *prev;
+ struct pci_tegra_device *child;
+ bool root_port;
+};
+
+#define TEGRA_MAX_PCI_DEVICES 64
+static struct pci_tegra_device pci_devices[TEGRA_MAX_PCI_DEVICES];
+static int max_devices;
+static struct pci_tegra_device *pci_root;
+
+static u32 pci_tegra_io_base;
+static u32 pci_tegra_mem_base;
+static u32 pci_tegra_prefetech_base;
+
+static u32 pci_tegra_io_limt;
+static u32 pci_tegra_mem_limit;
+static u32 pci_tegra_prefetech_limit;
+
+static void pci_tegra_print_device_tree(struct pci_tegra_device *dev);
+static void pcie_scanbus(struct pci_tegra_device *dev_parent);
+static void pci_tegra_allocate_resources(struct pci_tegra_device *dev);
+
+
+static struct pci_tegra_device *alloc_pci_tegra_device(void)
+{
+ static u32 index = 0;
+ struct pci_tegra_device *dev;
+
+ if (index == 0)
+ memset(pci_devices, 0, sizeof(pci_devices));
+
+ dev = &pci_devices[index];
+ index++;
+ max_devices = index;
+ return dev;
+}
+
+static inline void pci_conf_write8(u8 bus, u32 devfn, u32 where , u8 val)
+{
+ u32 addr;
+ u32 temp;
+
+ addr = (u32)pci_tegra_config_addr(bus, devfn, where);
+ pr_err("Issuing pci_conf_write8 at addr 0x%x with data 0x%x\n",
+ addr, val);
+
+ temp = readl((addr & ~0x3));
+ temp &= ~(0xff << ((addr & 0x3) * 8));
+ temp |= (u32)val << ((addr & 0x3) * 8);
+ writel(temp, (addr & ~0x3));
+}
+
+static inline void pci_conf_write16(u8 bus, u32 devfn, u32 where, u16 val)
+{
+ u32 addr;
+ u32 temp;
+
+ BUG_ON(where & 0x1);
+
+ addr = (u32)pci_tegra_config_addr(bus, devfn, where);
+ pr_err("Issuing pci_conf_write16 at addr 0x%x with data 0x%x\n",
+ addr, val);
+
+ temp = readl((addr & ~0x3));
+ temp &= ~(0xffff << ((addr& 0x3) * 8));
+ temp |= (u32)val << ((addr & 0x3) * 8);
+ writel(temp, (addr & ~0x3));
+}
+
+static inline void pci_conf_write32(u8 bus, u32 devfn, u32 where, u32 val)
+{
+ u32 addr;
+
+ BUG_ON(where & 0x3);
+
+ addr = (u32)pci_tegra_config_addr(bus, devfn, where);
+ pr_err("Issuing pci_conf_write32 at addr 0x%x with data 0x%x\n",
+ addr, val);
+ writel(val, addr);
+}
+
+static inline u8 pci_conf_read8(u8 bus, u32 devfn, u32 where)
+{
+ u32 temp;
+ u32 addr;
+
+ addr = (u32)pci_tegra_config_addr(bus, devfn, where);
+ pr_err("Issuing pci_conf_read8 at 0x%x\n", addr);
+ temp = readl(addr & ~0x3);
+ temp >>= 8 * (addr & 3);
+ temp &= 0xff;
+ pr_err("pci_conf_read8 at 0x%x = %d\n", addr, temp);
+
+ return (u8)temp;
+}
+
+static u16 pci_conf_read16(u8 bus, u32 devfn, u32 where)
+{
+ u32 temp;
+ u32 addr;
+
+ BUG_ON(where & 0x1);
+
+ addr = (u32)pci_tegra_config_addr(bus, devfn, where);
+ pr_err("Issuing pci_conf_read16 at 0x%x\n", addr);
+ temp = readl(addr & ~0x3);
+ temp >>= 8 * (addr & 3);
+ temp &= 0xffff;
+ pr_err("pci_conf_read16 at 0x%x = %d\n", addr, temp);
+
+ return (u16)temp;
+}
+
+static u32 pci_conf_read32(u8 bus, u32 devfn, u32 where)
+{
+ u32 temp;
+
+ BUG_ON(where & 0x3);
+
+ pr_err("Issuing pci_conf_read32 at 0x%x\n",
+ (u32)(pci_tegra_config_addr(bus, devfn, where)));
+
+ temp = readl(pci_tegra_config_addr(bus, devfn, where));
+
+ pr_err("pci_conf_read32 at 0x%x = %d\n", where, temp);
+ return temp;
+}
+
+static void pcie_scanbus(struct pci_tegra_device *dev_parent)
+{
+ u8 subordinate_bus;
+ u8 hdr_type;
+ u8 next_bus_number;
+ u32 device = 0;
+ u32 id;
+ struct pci_tegra_device *dev;
+ u32 retry_count;
+
+ next_bus_number = dev_parent->sec_bus;
+
+next_device:
+ retry_count = 6;
+ if (device == 0x20) {
+ /* Termination condition: Max number of devices reached.
+ * PCIe bus segment can only have 32 devices.
+ * */
+ dev_parent->sub_bus = next_bus_number;
+ if (!dev_parent->root_port) {
+ /* Change the subordinate bus-number to the actual
+ * value of all buses on the hierarcy.
+ *
+ * Do this execpt for the root port.
+ */
+ pci_conf_write8(dev_parent->bus, dev_parent->devfn,
+ PCI_SUBORDINATE_BUS, next_bus_number);
+ }
+ return;
+ }
+
+ if (dev_parent->root_port && device != 0) {
+ /* Sepcial Exit condition for root port.
+ * Root port only connect to one bridge or device.
+ */
+ dev_parent->sub_bus = dev_parent->sec_bus;
+ return;
+ }
+
+ while (--retry_count) {
+ id = pci_conf_read32(dev_parent->sec_bus,
+ PCI_DEVFN(device, 0), 0);
+ if (id != 0xFFFFFFFF)
+ {
+ /* Found a valid device, break. Otherwise, retry a couple of
+ * times. It is possible that the bridges can take some time
+ * to settle and it will take couple of transcations to find
+ * the devcies behind the bridge.
+ * */
+ /* FIXME: What should be the delay? */
+ msleep(100);
+ break;
+ }
+ }
+ if (id == 0xFFFFFFFF) {
+ /* Invalid device. Skip that one and look for next device */
+ device++;
+ goto next_device;
+ }
+
+ dev = alloc_pci_tegra_device();
+
+ /* Fill the device information */
+ dev->parent = dev_parent;
+ dev->id = id;
+ dev->bus = dev_parent->sec_bus;
+ dev->devfn = PCI_DEVFN(device, 0);
+ if (dev_parent->child == NULL) {
+ dev_parent->child = dev;
+ dev->prev = NULL;
+ } else {
+ /* Add dev to the list of devices on the same bus */
+ struct pci_tegra_device *temp;
+
+ temp = dev_parent->child;
+ BUG_ON(temp != NULL);
+ while (temp->next != NULL)
+ temp = temp->next;
+ temp->next = dev;
+ dev->prev = temp;
+ }
+
+ hdr_type = pci_conf_read8(dev->bus, dev->devfn, PCI_HEADER_TYPE);
+ if ((hdr_type & 0x7f) == 0x1) {
+ /* Bridge device */
+
+ /* Temporarily assign 0xff for the subordinate bus number as
+ * we don't * know how many devices are preset behind this
+ * bridge.
+ * */
+ subordinate_bus = 0xff;
+ dev->sec_bus = next_bus_number + 1;
+
+ pci_conf_write8(dev->bus, dev->devfn, PCI_PRIMARY_BUS,
+ dev_parent->sec_bus);
+ pci_conf_write8(dev->bus, dev->devfn, PCI_SECONDARY_BUS,
+ dev->sec_bus);
+ pci_conf_write8(dev->bus, dev->devfn, PCI_SUBORDINATE_BUS,
+ subordinate_bus);
+
+ /* Scan all the buses behind this bridge */
+ pcie_scanbus(dev);
+
+ next_bus_number = dev->sub_bus;
+ } else if ((hdr_type & 0x7f) == 0x0) {
+
+ /* PCI endpoint - Can be single function or multie function */
+ pr_info("PCI endpoint (0x%x) is on bus = %d, device = %d\n",
+ id, dev_parent->sec_bus, device);
+
+ } else if ((hdr_type & 0x7f) == 0x2) {
+ /* PC card device - Not handled */
+ BUG();
+ } else {
+ BUG();
+ }
+ device++;
+ goto next_device;
+}
+
+static void pci_tegra_enumerate_root_port(int rp)
+{
+ struct pci_tegra_device *root;
+ u32 reg;
+
+ root = alloc_pci_tegra_device();
+
+ if (pci_root) {
+ pci_root->next = root;
+ root->bus = pci_root->sub_bus + 1;
+ } else {
+ pci_root = root;
+ root->bus = 0;
+ }
+
+ root->sec_bus = root->bus + 1;
+ root->root_port = true;
+ /* Set the Inital value to the max bus number */
+ root->sub_bus = 0xff;
+ root->id = pci_tegra_rp_readl(0, rp);
+
+ pci_tegra_rp_writeb(root->bus, PCI_PRIMARY_BUS, rp);
+ pci_tegra_rp_writeb(root->sec_bus, PCI_SECONDARY_BUS, rp);
+ pci_tegra_rp_writeb(root->sub_bus, PCI_SUBORDINATE_BUS, rp);
+
+ /* Just assigns the bus numbers and sets up the SW hirerarchy */
+ pcie_scanbus(root);
+
+ /* Write the udpated root port subordinate bus number */
+ pci_tegra_rp_writeb(root->sub_bus, PCI_SUBORDINATE_BUS, rp);
+
+ pci_tegra_allocate_resources(root);
+
+ /* IO base and limits */
+ reg = root->res[PCI_BRIDGE_IO_RES].start;
+ reg = ALIGN(reg, 0x1000);
+ pci_tegra_rp_writeb((((reg & 0xf000) >> 8) | PCI_IO_RANGE_TYPE_32),
+ PCI_IO_BASE, rp);
+ pci_tegra_rp_writew(reg>>16, PCI_IO_BASE_UPPER16, rp);
+
+ reg = root->res[PCI_BRIDGE_IO_RES].end;
+ reg = ALIGN(reg, 0x1000);
+ pci_tegra_rp_writeb((((reg & 0xf000) >> 8) | PCI_IO_RANGE_TYPE_32),
+ PCI_IO_LIMIT, rp);
+ pci_tegra_rp_writew(reg>>16, PCI_IO_LIMIT_UPPER16, rp);
+
+ /* Memory base and limits */
+ reg = root->res[PCI_BRIDGE_MEM_RES].start;
+ reg = ALIGN(reg, 0x100000);
+ pci_tegra_rp_writew(reg >> 16, PCI_MEMORY_BASE, rp);
+ reg = root->res[PCI_BRIDGE_MEM_RES].end;
+ reg = ALIGN(reg, 0x100000);
+ pci_tegra_rp_writew(reg >> 16, PCI_MEMORY_LIMIT, rp);
+
+ /* Prefetch base and limit - 32 bit addressing */
+ reg = root->res[PCI_BRIDGE_PREFETCH_RES].start;
+ reg = ALIGN(reg, 0x100000);
+ pci_tegra_rp_writew(reg >> 16, PCI_PREF_MEMORY_BASE, rp);
+ pci_tegra_rp_writel(0, PCI_PREF_BASE_UPPER32, rp);
+ reg = root->res[PCI_BRIDGE_PREFETCH_RES].end;
+ reg = ALIGN(reg, 0x100000);
+ pci_tegra_rp_writew(reg >> 16, PCI_PREF_MEMORY_LIMIT, rp);
+ pci_tegra_rp_writel(0, PCI_PREF_LIMIT_UPPER32, rp);
+
+ reg = 0;
+ reg |= PCI_COMMAND_IO;
+ reg |= PCI_COMMAND_MEMORY;
+ reg |= PCI_COMMAND_MASTER;
+ reg |= PCI_COMMAND_SERR;
+ pci_tegra_rp_writew(reg, PCI_COMMAND, rp);
+}
+
+static void pci_tegra_setup_pci_bridge(struct pci_tegra_device *dev)
+{
+ u32 reg;
+
+ dev->res[PCI_BRIDGE_IO_RES].end = pci_tegra_io_base;
+ dev->res[PCI_BRIDGE_MEM_RES].end = pci_tegra_mem_base;
+ dev->res[PCI_BRIDGE_PREFETCH_RES].end =
+ pci_tegra_prefetech_base;
+
+ /* Only set here for the non-root port devices */
+ if (dev->root_port)
+ return;
+
+ /* IO base and limits */
+ reg = dev->res[PCI_BRIDGE_IO_RES].start;
+ reg = ALIGN(reg, 0x1000);
+ pci_conf_write8(dev->bus, dev->devfn, PCI_IO_BASE,
+ (((reg & 0xf000) >> 8) | PCI_IO_RANGE_TYPE_32));
+ pci_conf_write16(dev->bus, dev->devfn, PCI_IO_BASE_UPPER16, reg>>16);
+
+ reg = dev->res[PCI_BRIDGE_IO_RES].end;
+ reg = ALIGN(reg, 0x1000);
+ pci_conf_write8(dev->bus, dev->devfn, PCI_IO_LIMIT,
+ (((reg & 0xf000) >> 8) | PCI_IO_RANGE_TYPE_32));
+ pci_conf_write16(dev->bus, dev->devfn, PCI_IO_LIMIT_UPPER16, reg>>16);
+
+ /* Memory base and limits */
+ reg = dev->res[PCI_BRIDGE_MEM_RES].start;
+ reg = ALIGN(reg, 0x100000);
+ pci_conf_write16(dev->bus, dev->devfn, PCI_MEMORY_BASE, reg >> 16);
+
+ reg = dev->res[PCI_BRIDGE_MEM_RES].end;
+ reg = ALIGN(reg, 0x100000);
+ pci_conf_write16(dev->bus, dev->devfn, PCI_MEMORY_LIMIT, reg >> 16);
+
+ /* Prefetch base and limit - 32 bit addressing */
+ reg = dev->res[PCI_BRIDGE_PREFETCH_RES].start;
+ reg = ALIGN(reg, 0x100000);
+ pci_conf_write16(dev->bus, dev->devfn, PCI_PREF_MEMORY_BASE,
+ reg >> 16);
+ pci_conf_write16(dev->bus, dev->devfn, PCI_PREF_BASE_UPPER32, 0);
+
+ reg = dev->res[PCI_BRIDGE_PREFETCH_RES].end;
+ reg = ALIGN(reg, 0x100000);
+ pci_conf_write16(dev->bus, dev->devfn, PCI_PREF_MEMORY_LIMIT,
+ reg >> 16);
+ pci_conf_write16(dev->bus, dev->devfn, PCI_PREF_LIMIT_UPPER32, 0);
+
+ reg = 0;
+ reg |= PCI_COMMAND_IO;
+ reg |= PCI_COMMAND_MEMORY;
+ reg |= PCI_COMMAND_MASTER;
+ reg |= PCI_COMMAND_SERR;
+ pci_conf_write16(dev->bus, dev->devfn, PCI_COMMAND, reg);
+
+ /* FIXME how to handle interrutps */
+ pci_conf_write8(dev->bus, dev->devfn, PCI_INTERRUPT_LINE, 0x82);
+ pci_conf_write8(dev->bus, dev->devfn, PCI_INTERRUPT_PIN, 0xa);
+}
+
+static void pci_tegra_setup_pci_device(struct pci_tegra_device *dev)
+{
+ u8 flags;
+ u32 bar_index;
+ u32 reg;
+ u32 addr;
+
+ for (bar_index = 0x0; bar_index <= PCI_STD_RESOURCE_END;
+ bar_index ++) {
+ u32 size;
+ pci_conf_write32(dev->bus, dev->devfn, bar_index * 4
+ + PCI_BASE_ADDRESS_0, 0xFFFFFFFFUL);
+
+ size = pci_conf_read32(dev->bus, dev->devfn, bar_index * 4
+ + PCI_BASE_ADDRESS_0);
+
+ if (size == 0xFFFFFFFFUL) continue;
+ if (size == 0) continue; /* A broken device? */
+ flags = (size & 0x000f);
+
+ /* Size align the addr and write that BAR offset */
+ if (flags & 0x1) {
+ size &= ~0xF; /* Ignore the last 4 bits */
+ /* some devices hardwire the high bits of IO bars to 0
+ * So, ignore those bits.
+ */
+ size |= 0xffff0000;
+ size = ~size + 1; /* Do the 1's complement */
+
+ addr = ALIGN(pci_tegra_io_base, size);
+
+ if (addr + size > pci_tegra_io_limt) {
+ pr_err("pci_tegra: "
+ "Cannot asign IO res\n");
+ continue;
+ }
+ dev->res[bar_index].flags = IORESOURCE_IO;
+ dev->res[bar_index].start = addr;
+ dev->res[bar_index].end = addr + size -1;
+
+ pci_tegra_io_base = addr + size;
+ } else {
+ size &= ~0xF; /* Ignore the last 4 bits */
+ size = ~size + 1; /* Do the 1's complement */
+
+ if (flags & 0x08) {
+ addr = ALIGN(pci_tegra_mem_base, size);
+
+ if (addr + size > pci_tegra_mem_limit) {
+ pr_err("pci_tegra: "
+ "Cannot asign mem res\n");
+ continue;
+ }
+
+ dev->res[bar_index].flags = IORESOURCE_MEM;
+ dev->res[bar_index].start = 0;
+ dev->res[bar_index].end =
+ dev->res[bar_index].start + size - 1;
+
+ pci_tegra_mem_base = addr + size;
+ } else {
+ addr = ALIGN(pci_tegra_prefetech_base, size);
+
+ if (addr + size > pci_tegra_prefetech_limit) {
+ pr_err("pci_tegra: "
+ "Cannot asign prefetch res\n");
+ continue;
+ }
+
+ dev->res[bar_index].flags =
+ IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ dev->res[bar_index].start = addr;
+ dev->res[bar_index].end = addr + size - 1;
+
+ pci_tegra_prefetech_base = addr + size;
+ }
+ }
+ pci_conf_write32(dev->bus, dev->devfn, bar_index * 4
+ + PCI_BASE_ADDRESS_0, dev->res[bar_index].start);
+
+ /* Handle 64 bit addresses by forcing to 32 bit addresses */
+ if ((flags == 0x0c) || (flags==0x04)) {
+ bar_index++;
+ BUG_ON(bar_index < 6);
+ pci_conf_write32(dev->bus, dev->devfn, bar_index * 4
+ + PCI_BASE_ADDRESS_0, 0);
+ }
+ }
+
+ reg = 0;
+ reg |= PCI_COMMAND_IO;
+ reg |= PCI_COMMAND_MEMORY;
+ reg |= PCI_COMMAND_MASTER;
+ reg |= PCI_COMMAND_SERR;
+ pci_conf_write16(dev->bus, dev->devfn, PCI_COMMAND, reg);
+
+ /* FIXME how to handle interrutps */
+
+}
+
+static void pci_tegra_print_device_tree(struct pci_tegra_device *dev)
+{
+ u32 i;
+
+ if (!dev)
+ return;
+
+ if (dev->sub_bus)
+ pr_err("PCIe bridge/Root port\n");
+ else
+ pr_err("PCIe device\n");
+
+ pr_err(" Vendor/Device = 0x%x bus = %d sec bus %d sub bus %d\n",
+ dev->id, dev->bus, dev->sec_bus, dev->sub_bus);
+ if (dev->disabled) {
+ pr_err(" Slot disabled\n");
+ } else {
+ for (i=0; i<= PCI_STD_RESOURCE_END; i++) {
+ /* Skip printing the empty ones */
+ if (!dev->res[i].start)
+ continue;
+ pr_err(" bar(%d) \n", i);
+ pr_err(" start = 0x%x\n", dev->res[i].start);
+ pr_err(" end = 0x%x\n", dev->res[i].end);
+ pr_err(" flags = 0x%lx\n", dev->res[i].flags);
+ }
+ }
+
+ if (dev->child != NULL)
+ pci_tegra_print_device_tree(dev->child);
+
+ if (dev->next != NULL)
+ pci_tegra_print_device_tree(dev->next);
+}
+
+static void pci_tegra_allocate_resources(struct pci_tegra_device *dev)
+{
+ /* Employing a depth first search for resource allocation. */
+ if (!dev)
+ return;
+
+ if (dev->sub_bus) {
+
+ dev->res[PCI_BRIDGE_IO_RES].flags = IORESOURCE_IO;
+ dev->res[PCI_BRIDGE_IO_RES].start = pci_tegra_io_base;
+
+ dev->res[PCI_BRIDGE_PREFETCH_RES].flags =
+ IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ dev->res[PCI_BRIDGE_PREFETCH_RES].start =
+ pci_tegra_prefetech_base;
+
+ dev->res[PCI_BRIDGE_MEM_RES].flags = IORESOURCE_MEM;
+ dev->res[PCI_BRIDGE_MEM_RES].start = pci_tegra_mem_base;
+ }
+
+ if (dev->child)
+ pci_tegra_allocate_resources(dev->child);
+ if (dev->next)
+ pci_tegra_allocate_resources(dev->next);
+
+ if (dev->sub_bus)
+ pci_tegra_setup_pci_bridge(dev);
+ else
+ pci_tegra_setup_pci_device(dev);
+}
+
+void pci_tegra_enumerate(void)
+{
+ u32 reg;
+
+ /* Disable all execptions */
+ pci_tegra_afi_writel(0, AFI_FPCI_ERROR_MASKS_0);
+
+ /* Set the base and limits of the resources */
+ pci_tegra_io_base = TEGRA_PCIE_BASE + PCIE_DOWNSTREAM_IO_OFFSET;
+ pci_tegra_io_limt = pci_tegra_io_base + PCIE_DOWNSTREAM_IO_SIZE;
+
+ pci_tegra_mem_base = FPCI_NON_PREFETCH_MEMORY_OFFSET;
+ pci_tegra_mem_limit = FPCI_NON_PREFETCH_MEMORY_OFFSET
+ + PCIE_NON_PREFETCH_MEMORY_SIZE;
+
+ pci_tegra_prefetech_base = FPCI_PREFETCH_MEMORY_OFFSET;
+ pci_tegra_prefetech_limit = FPCI_PREFETCH_MEMORY_OFFSET
+ + PCIE_PREFETCH_MEMORY_SIZE;
+
+ /* Enumerate only if the Link is UP. */
+ reg = pci_tegra_rp_readl(NV_PROJ__PCIE2_RP_VEND_XP, 0);
+ if (NVPCIE_DRF_VAL(RP, VEND_XP, DL_UP, reg) == 1)
+ pci_tegra_enumerate_root_port(0);
+
+ reg = pci_tegra_rp_readl(NV_PROJ__PCIE2_RP_VEND_XP, 1);
+ if (NVPCIE_DRF_VAL(RP, VEND_XP, DL_UP, reg) == 1)
+ pci_tegra_enumerate_root_port(1);
+
+ pci_tegra_print_device_tree(pci_root);
+}
diff --git a/arch/arm/mach-tegra/pci.c b/arch/arm/mach-tegra/pci.c
index dcfdb7981464..2ecba6015229 100644
--- a/arch/arm/mach-tegra/pci.c
+++ b/arch/arm/mach-tegra/pci.c
@@ -20,11 +20,29 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+#define DEBUG
+#define VERBOSE_DEBUG
+
+
#include <linux/kernel.h>
#include <linux/pci.h>
#include <asm/mach/pci.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/delay.h>
+
+#include <mach/pci.h>
+#include <mach/nvrm_linux.h>
+
+#include "nvrm_pmu.h"
+#include "nvodm_query_discovery.h"
+#include "nvrm_power.h"
+#include "nvrm_interrupt.h"
+
+
+void __iomem * volatile pci_tegra_regs;
+static bool pci_tegra_device_attached = false;
+static unsigned int pci_tegra_powerid;
static int __init pcie_tegra_init(void);
@@ -40,12 +58,20 @@ static int pci_tegra_read_conf(struct pci_bus *bus, u32 devfn,
static int __init pcie_tegra_init(void);
+
+static void pci_tegra_power(int on);
+static void pci_tegra_setup_translations(void);
+static irqreturn_t pci_tegra_isr(int irq, void *arg);
+static bool pci_tegra_check_rp(int rp);
+
unsigned long pci_tegra_get_base(char *aperture)
{
if (!strcmp(aperture, "mem"))
- return 0x90000000;
+ return TEGRA_PCIE_BASE +
+ PCIE_NON_PREFETCH_MEMORY_OFFSET;
else if (!strcmp(aperture, "io"))
- return 0x82000000;
+ return TEGRA_PCIE_BASE +
+ PCIE_DOWNSTREAM_IO_OFFSET;
else
return (unsigned long)-1;
}
@@ -54,32 +80,302 @@ static int pci_tegra_read_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 *val)
{
int i;
+ u32 v;
+ int rp;
+
+ pr_debug("Issuing read conf: bus %d, devfn 0x%x, where 0x%x size %d\n",
+ bus->number, devfn, where, size);
+
+ if (!pci_tegra_device_attached) goto fail;
+ if (where > 4096) goto fail;
+
+ /* Root port config registers are directly mapped in different
+ * aperture - not same as the config registers for devices on the PCI
+ * bus
+ */
+ if (pci_tegra_is_rp(bus->number, &rp)) {
+ /* Root port is just one bridge! */
+ if (devfn != 0) goto fail;
+ v = pci_tegra_rp_readl(where & ~3, rp);
+ } else {
+ void __iomem *addr;
+
+ /* Root is only attached to one device/bridge */
+ if (bus->number == 1 && PCI_SLOT(devfn) != 0) goto fail;
+ addr = pci_tegra_config_addr(bus->number, devfn, where & ~3);
+ v = readl(addr);
+ }
+
+ switch (size) {
+ case 1:
+ if (where & 2) v >>= 16;
+ if (where & 1) v >>= 8;
+ v &= 0xff;
+ break;
+ case 2:
+ if (where & 2) v >>= 16;
+ v &= 0xffff;
+ break;
+ default:
+ break;
+ }
+ *val = v;
+ pr_debug(" Value = 0x%x\n", v);
+
+ return PCIBIOS_SUCCESSFUL;
+fail:
for (i=0; i<size; i++)
((__u8 *)val)[i] = 0xff;
-
return PCIBIOS_SUCCESSFUL;
}
static int pci_tegra_write_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 val)
{
+ void __iomem *addr;
+ int rp;
+ u32 temp;
+
+ pr_debug("Issuing write conf: bus %d, devfn 0x%x, "
+ "where 0x%x size %d value = 0x%x\n",
+ bus->number, devfn, where, size, val);
+
+ if (!pci_tegra_device_attached) goto fail;
+
+ if (where > 4096) goto fail;
+
+ /* Root port config registers are directly mapped in different
+ * aperture - not same as the config registers for devices on the PCI
+ * bus.
+ */
+ if (pci_tegra_is_rp(bus->number, &rp)) {
+ /* Root port is just one bridge! */
+ if (devfn != 0) goto fail;
+ addr = pci_tegra_regs;
+ if (rp == 0) addr += NV_PCIE_AXI_RP_T0C0_OFFSET;
+ if (rp == 1) addr += NV_PCIE_AXI_RP_T0C1_OFFSET;
+ addr += where;
+ } else {
+ /* Root is only attached to one device/bridge */
+ if (bus->number == 1 && PCI_SLOT(devfn) != 0) goto fail;
+
+ addr = pci_tegra_config_addr(bus->number, devfn, where);
+ }
+
+ switch (size) {
+ case 1:
+ temp = readl((u32)addr & ~0x3);
+ temp &= ~(0xff << ((where & 0x3) * 8));
+ temp |= val << ((where & 0x3) * 8);
+ writel(temp, (u32)addr & ~0x3);
+ break;
+ case 2:
+ temp = readl((u32)addr & ~0x3);
+ temp &= ~(0xffff << ((where & 0x3) * 8));
+ temp |= val << ((where & 0x3) * 8);
+ writel(temp, (u32)addr & ~0x3);
+ break;
+ default:
+ writel(val, addr);
+ break;
+ }
+fail:
return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops pci_tegra_ops = {
- .read = pci_tegra_read_conf,
- .write = pci_tegra_write_conf,
+ .read = pci_tegra_read_conf,
+ .write = pci_tegra_write_conf,
};
static void __init pci_tegra_preinit(void)
{
-
+ pcibios_setup("firmware");
}
static int __init pci_tegra_setup(int nr, struct pci_sys_data *data)
{
- return (nr == 0);
+ u32 volatile reg;
+ unsigned int irq;
+
+ if (nr != 0) return 0;
+
+ pci_tegra_power(1);
+ if (NvRmSetModuleTristate(s_hRmGlobal,
+ NVRM_MODULE_ID(NvRmPrivModuleID_Pcie, 0), NV_FALSE)
+ != NvSuccess) {
+ /* No valid Pinmux for PCIe? */
+ return 0;
+ }
+
+ pci_tegra_regs = ioremap_nocache(TEGRA_PCIE_BASE,
+ PCI_TEGRA_IOMAPPED_REG_APERTURE_SIZE);
+ if (pci_tegra_regs == NULL) {
+ pr_err("pci_tegra_setup: Failed to map the PCI/AFI regs\n");
+ return 0;
+ }
+
+ if (NvRmPowerRegister(s_hRmGlobal, 0, &pci_tegra_powerid) != NvSuccess)
+ goto fail;
+ if (NvRmPowerModuleClockControl(s_hRmGlobal, NvRmPrivModuleID_Pcie,
+ pci_tegra_powerid, NV_TRUE) != NvSuccess)
+ goto fail;
+
+ NvRmModuleReset(s_hRmGlobal, NvRmPrivModuleID_Afi);
+ NvRmModuleReset(s_hRmGlobal, NvRmPrivModuleID_Pcie);
+ NvRmModuleResetWithHold(s_hRmGlobal, NvRmPrivModuleID_PcieXclk,
+ NV_TRUE);
+
+ /* Enable slot clock and pulse the reset signals */
+ reg = pci_tegra_afi_readl(AFI_PEX0_CTRL_0);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PEX0_CTRL, PEX0_REFCLK_EN, 1, reg);
+ pci_tegra_afi_writel(reg, AFI_PEX0_CTRL_0);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PEX0_CTRL, PEX0_RST_L, 0, reg);
+ pci_tegra_afi_writel(reg, AFI_PEX0_CTRL_0);
+
+ reg = pci_tegra_afi_readl(AFI_PEX1_CTRL_0);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PEX1_CTRL, PEX1_REFCLK_EN, 1, reg);
+ pci_tegra_afi_writel(reg, AFI_PEX1_CTRL_0);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PEX1_CTRL, PEX1_RST_L, 0, reg);
+ pci_tegra_afi_writel(reg, AFI_PEX1_CTRL_0);
+
+ msleep(100);
+
+ reg = pci_tegra_afi_readl(AFI_PEX0_CTRL_0);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PEX0_CTRL, PEX0_RST_L, 1, reg);
+ pci_tegra_afi_writel(reg, AFI_PEX0_CTRL_0);
+
+ reg = pci_tegra_afi_readl(AFI_PEX1_CTRL_0);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PEX1_CTRL, PEX1_RST_L, 1, reg);
+ pci_tegra_afi_writel(reg, AFI_PEX1_CTRL_0);
+
+ /* Validate by reading the ROOT port IDs that we are infact working on
+ * the TEGRA root port */
+ reg = pci_tegra_rp_readl(NV_PROJ__PCIE2_RP_DEV_ID, 0);
+ BUG_ON((NVPCIE_DRF_VAL(RP, DEV_ID, VENDOR_ID, reg)) !=
+ NV_PROJ__PCIE2_RP_DEV_ID_VENDOR_ID_NVIDIA);
+ reg = pci_tegra_rp_readl(NV_PROJ__PCIE2_RP_DEV_ID, 1);
+ BUG_ON((NVPCIE_DRF_VAL(RP, DEV_ID, VENDOR_ID, reg)) !=
+ NV_PROJ__PCIE2_RP_DEV_ID_VENDOR_ID_NVIDIA);
+
+ /* Enable dual controller and both ports*/
+ reg = pci_tegra_afi_readl(AFI_PCIE_CONFIG_0);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PCIE_CONFIG, PCIEC0_DISABLE_DEVICE, 0,
+ reg);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PCIE_CONFIG, SM2TMS0_XBAR_CONFIG, 1,
+ reg);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PCIE_CONFIG, PCIEC1_DISABLE_DEVICE, 0,
+ reg);
+ pci_tegra_afi_writel(reg, AFI_PCIE_CONFIG_0);
+
+ reg = pci_tegra_afi_readl(AFI_FUSE_0);
+ reg = NV_FLD_SET_DRF_NUM(AFI, FUSE, FUSE_PCIE_T0_GEN2_DIS, 0, reg);
+ pci_tegra_afi_writel(reg, AFI_FUSE_0);
+
+ /* Initialze AP20 internal PHY */
+ /* ENABLE up to 16 PCIE lanes */
+ pci_tegra_pads_writel(0x0, NV_PROJ__PCIE2_PADS_CTL_SEL_1);
+
+ /* override IDDQ to 1 on all 4 lanes */
+ reg = pci_tegra_pads_reedl(NV_PROJ__PCIE2_PADS_CTL_1);
+ reg = NVPCIE_FLD_SET_DRF_NUM(PADS, CTL_1, IDDQ_1L, 1, reg);
+ pci_tegra_pads_writel(reg, NV_PROJ__PCIE2_PADS_CTL_1);
+
+ /* set up PHY PLL inputs select PLLE output as refclock */
+ reg = pci_tegra_pads_reedl(NV_PROJ__PCIE2_PADS_PLL_CTL1);
+ reg = NVPCIE_FLD_SET_DRF_NUM(PADS, PLL_CTL1, PLL_REFCLK_SEL,
+ NV_PROJ__PCIE2_PADS_PLL_CTL1_PLL_REFCLK_SEL_INTERNAL_CML, reg);
+
+ /* set TX ref sel to div10 (not div5) */
+ reg = NVPCIE_FLD_SET_DRF_NUM(PADS, PLL_CTL1, PLL_TXCLKREF_SEL,
+ NV_PROJ__PCIE2_PADS_PLL_CTL1_PLL_TXCLKREF_SEL_DIV10, reg);
+ pci_tegra_pads_writel(reg, NV_PROJ__PCIE2_PADS_PLL_CTL1);
+
+ /* take PLL out of reset */
+ reg = pci_tegra_pads_reedl(NV_PROJ__PCIE2_PADS_PLL_CTL1);
+ reg = NVPCIE_FLD_SET_DRF_NUM(PADS, PLL_CTL1, PLL_RST_B4SM,
+ NV_PROJ__PCIE2_PADS_PLL_CTL1_PLL_RST_B4SM_DEASSERT, reg);
+ pci_tegra_pads_writel(reg, NV_PROJ__PCIE2_PADS_PLL_CTL1);
+
+ /* Hack, set the clock voltage to the DEFAULT provided by hw folks.
+ * This doesn't exist in the documentation
+ * */
+ reg = 0xFA5CFA5C;
+ pci_tegra_pads_writel(reg, 0xc8);
+
+ /* Wait for the PLL to lock */
+ reg = pci_tegra_pads_reedl(NV_PROJ__PCIE2_PADS_PLL_CTL1);
+ while (NVPCIE_DRF_VAL(PADS, PLL_CTL1, PLL_LOCKDET, reg)
+ != NV_PROJ__PCIE2_PADS_PLL_CTL1_PLL_LOCKDET_LOCKED)
+ {
+ reg = pci_tegra_pads_reedl(NV_PROJ__PCIE2_PADS_PLL_CTL1);
+ }
+
+ /* turn off IDDQ override */
+ reg = pci_tegra_pads_reedl(NV_PROJ__PCIE2_PADS_CTL_1);
+ reg = NVPCIE_FLD_SET_DRF_NUM(PADS, CTL_1, IDDQ_1L, 0, reg);
+ pci_tegra_pads_writel(reg, NV_PROJ__PCIE2_PADS_CTL_1);
+
+ /* ENABLE TX/RX data */
+ reg = pci_tegra_pads_reedl(NV_PROJ__PCIE2_PADS_CTL_1);
+ reg = NVPCIE_FLD_SET_DRF_NUM(PADS, CTL_1, TX_DATA_EN_1L,
+ NV_PROJ__PCIE2_PADS_CTL_1_TX_DATA_EN_1L_ENABLE, reg);
+ reg = NVPCIE_FLD_SET_DRF_NUM(PADS, CTL_1, RX_DATA_EN_1L,
+ NV_PROJ__PCIE2_PADS_CTL_1_RX_DATA_EN_1L_ENABLE, reg);
+ pci_tegra_pads_writel(reg, NV_PROJ__PCIE2_PADS_CTL_1);
+
+ irq = tegra_get_module_inst_irq("pcie", 0, 0);
+ BUG_ON(irq == NO_IRQ);
+ if (request_irq(irq, pci_tegra_isr, IRQF_SHARED, "PCIE", s_hRmGlobal))
+ {
+ pr_err("pci_tegra_setup: Cannot register the IRQ %d\n", irq);
+ }
+ set_irq_flags(irq, IRQF_VALID);
+
+ /* setup the AFI address translations */
+ pci_tegra_setup_translations();
+
+ /* Take the PCIe interface module out of reset to start the PCIe
+ * training sequence */
+ NvRmModuleResetWithHold(s_hRmGlobal, NvRmPrivModuleID_PcieXclk,
+ NV_FALSE);
+
+ /* Finally enable PCIe */
+ reg = pci_tegra_afi_readl(AFI_CONFIGURATION_0);
+ reg = reg | AFI_CONFIGURATION_0_EN_FPCI_DEFAULT_MASK;
+ pci_tegra_afi_writel(reg, AFI_CONFIGURATION_0);
+
+ if (!pci_tegra_check_rp(0) && !pci_tegra_check_rp(1)) {
+ pci_tegra_device_attached = false;
+ return 0;
+ }
+ pci_tegra_device_attached = true;
+
+ /* Enable PCIe interrupts */
+ reg = 0;
+ reg |= NV_DRF_NUM(AFI, AFI_INTR_ENABLE, EN_INI_SLVERR, 1);
+ reg |= NV_DRF_NUM(AFI, AFI_INTR_ENABLE, EN_INI_DECERR, 1);
+ reg |= NV_DRF_NUM(AFI, AFI_INTR_ENABLE, EN_TGT_SLVERR, 1);
+ reg |= NV_DRF_NUM(AFI, AFI_INTR_ENABLE, EN_TGT_DECERR, 1);
+ reg |= NV_DRF_NUM(AFI, AFI_INTR_ENABLE, EN_TGT_WRERR, 1);
+ reg |= NV_DRF_NUM(AFI, AFI_INTR_ENABLE, EN_DFPCI_DECERR, 1);
+ pci_tegra_afi_writel(reg, AFI_AFI_INTR_ENABLE_0);
+ pci_tegra_afi_writel(0xffffffff, AFI_SM_INTR_ENABLE_0);
+
+ reg = 0;
+ reg |= NV_DRF_NUM(AFI, INTR_MASK, INT_MASK, 1);
+ /* FIXME: No MSI for now */
+ reg |= NV_DRF_NUM(AFI, INTR_MASK, MSI_MASK, 0);
+ pci_tegra_afi_writel(reg, AFI_INTR_MASK_0);
+
+ pci_tegra_enumerate();
+
+ pr_err("pci_tegra_setup: Successfull\n");
+ return 1;
+fail:
+ pr_err("pci_tegra_setup: failed\n");
+ return 0;
}
static struct pci_bus __init *pci_tegra_scan_bus(int nr,
@@ -92,11 +388,11 @@ static struct pci_bus __init *pci_tegra_scan_bus(int nr,
}
static struct hw_pci pci_tegra_data __initdata = {
- .nr_controllers = 2,
- .preinit = pci_tegra_preinit,
- .setup = pci_tegra_setup,
- .scan = pci_tegra_scan_bus,
- .swizzle = pci_std_swizzle,
+ .nr_controllers = 2,
+ .preinit = pci_tegra_preinit,
+ .setup = pci_tegra_setup,
+ .scan = pci_tegra_scan_bus,
+ .swizzle = pci_std_swizzle,
};
late_initcall(pcie_tegra_init);
@@ -106,3 +402,244 @@ static int __init pcie_tegra_init(void)
pci_common_init(&pci_tegra_data);
return 0;
}
+
+/*
+ * PCIe support functions
+ */
+
+static void pci_tegra_power(int on)
+{
+ u32 settling_time;
+ const NvOdmPeripheralConnectivity *con = NULL;
+ int i;
+
+ con = NvOdmPeripheralGetGuid(NV_VDD_PEX_CLK_ODM_ID);
+ if (con == NULL)
+ return;
+
+ for (i = 0; i < con->NumAddress; i++) {
+ if (con->AddressList[i].Interface != NvOdmIoModule_Vdd)
+ continue;
+ if (on) {
+ NvRmPmuVddRailCapabilities rail;
+ NvRmPmuGetCapabilities(s_hRmGlobal,
+ con->AddressList[i].Address, &rail);
+ NvRmPmuSetVoltage(s_hRmGlobal,
+ con->AddressList[i].Address,
+ rail.requestMilliVolts, &settling_time);
+ } else
+ NvRmPmuSetVoltage(s_hRmGlobal,
+ con->AddressList[i].Address, NVODM_VOLTAGE_OFF,
+ &settling_time);
+ udelay(settling_time);
+ }
+}
+
+static void pci_tegra_setup_translations(void)
+{
+ u32 fpci_bar;
+ u32 size;
+ u32 axi_address;
+
+ /* Bar 0: Config Bar */
+ fpci_bar = ((u32)0xfdff << 16);
+ size = PCIE_CONFIG_SIZE;
+ axi_address = TEGRA_PCIE_BASE + PCIE_CONFIG_OFFSET;
+ pci_tegra_afi_writel(axi_address, AFI_AXI_BAR0_START_0);
+ pci_tegra_afi_writel(size>>12, AFI_AXI_BAR0_SZ_0);
+ pci_tegra_afi_writel(fpci_bar, AFI_FPCI_BAR0_0);
+
+ /* Bar 1: Extended config Bar */
+ fpci_bar = ((u32)0xfe1 << 20);
+ size = PCIE_EXTENDED_CONFIG_SIZE;
+ axi_address = TEGRA_PCIE_BASE + PCIE_EXTENDED_CONFIG_OFFSET;
+ pci_tegra_afi_writel(axi_address, AFI_AXI_BAR1_START_0);
+ pci_tegra_afi_writel(size >>12, AFI_AXI_BAR1_SZ_0);
+ pci_tegra_afi_writel(fpci_bar, AFI_FPCI_BAR1_0);
+
+ /* Bar 2: Downstream IO bar */
+ fpci_bar = ((__u32)0xfdfc << 16);
+ size = PCIE_DOWNSTREAM_IO_SIZE;
+ axi_address = TEGRA_PCIE_BASE + PCIE_DOWNSTREAM_IO_OFFSET;
+ pci_tegra_afi_writel(axi_address, AFI_AXI_BAR2_START_0);
+ pci_tegra_afi_writel(size>>12, AFI_AXI_BAR2_SZ_0);
+ pci_tegra_afi_writel(fpci_bar, AFI_FPCI_BAR2_0);
+
+ /* Bar 3: Pre-fetchable memory BAR */
+ /* Bits 39:12 of 40 bit FPCI address goes to bits 31:4 */
+ fpci_bar = (((FPCI_PREFETCH_MEMORY_OFFSET >> 12) & 0x0FFFFFFF) << 4);
+ fpci_bar |= 0x1;
+ size = PCIE_PREFETCH_MEMORY_SIZE;
+ axi_address = TEGRA_PCIE_BASE + PCIE_PREFETCH_MEMORY_OFFSET;
+ pci_tegra_afi_writel(axi_address, AFI_AXI_BAR3_START_0);
+ pci_tegra_afi_writel(size >> 12, AFI_AXI_BAR3_SZ_0);
+ pci_tegra_afi_writel(fpci_bar, AFI_FPCI_BAR3_0);
+
+ /* Bar 4: Non pre-fetchable memory BAR */
+ /* Bits 39:12 of 40 bit FPCI address goes to bits 31:4 */
+ fpci_bar = (((FPCI_NON_PREFETCH_MEMORY_OFFSET >> 12)
+ & 0x0FFFFFFF) << 4);
+ fpci_bar |= 0x1;
+ size = PCIE_NON_PREFETCH_MEMORY_SIZE;
+ axi_address = TEGRA_PCIE_BASE
+ + PCIE_NON_PREFETCH_MEMORY_OFFSET;
+ pci_tegra_afi_writel(axi_address, AFI_AXI_BAR4_START_0);
+ pci_tegra_afi_writel(size >> 12, AFI_AXI_BAR4_SZ_0);
+ pci_tegra_afi_writel(fpci_bar, AFI_FPCI_BAR4_0);
+
+ /* Bar 5: NULL out the remaining BAR as it is not used */
+ fpci_bar = 0;
+ size = 0;
+ axi_address = 0;
+ pci_tegra_afi_writel(axi_address, AFI_AXI_BAR5_START_0);
+ pci_tegra_afi_writel(size >> 12, AFI_AXI_BAR5_SZ_0);
+ pci_tegra_afi_writel(fpci_bar, AFI_FPCI_BAR5_0);
+
+ /* map all upstream transactions as uncached */
+ pci_tegra_afi_writel(FPCI_SYSTEM_MEMORY_OFFSET, AFI_CACHE_BAR0_ST_0);
+ pci_tegra_afi_writel(0, AFI_CACHE_BAR0_SZ_0);
+ pci_tegra_afi_writel(0, AFI_CACHE_BAR1_ST_0);
+ pci_tegra_afi_writel(0, AFI_CACHE_BAR1_SZ_0);
+
+ /* Map MSI bar */
+ pci_tegra_afi_writel(0, AFI_MSI_FPCI_BAR_ST_0);
+ pci_tegra_afi_writel(0, AFI_MSI_BAR_SZ_0);
+ pci_tegra_afi_writel(0, AFI_MSI_AXI_BAR_ST_0);
+ pci_tegra_afi_writel(0, AFI_MSI_BAR_SZ_0);
+}
+
+static irqreturn_t pci_tegra_isr(int irq, void *arg)
+{
+ u32 intr_info, intr_extended_info;
+ irqreturn_t ret = IRQ_HANDLED;
+
+ intr_info = pci_tegra_afi_readl(AFI_INTR_CODE_0);
+ intr_info = NV_DRF_VAL(AFI, INTR_CODE, INT_CODE, intr_info);
+ intr_extended_info = pci_tegra_afi_readl(AFI_INTR_SIGNATURE_0);
+
+ /* pr_err("+pci_tegra_isr\n"); */
+
+ switch (intr_info) {
+ case 6: /* legacy */
+ ret = IRQ_NONE;
+ break;
+ case 1: /* SLVERR */
+ pr_err("pci_tegra_isr: AXI slave error\n");
+ break;
+ case 2: /* DECERR */
+ pr_err("pci_tegra_isr: AXI decode error\n");
+ break;
+ case 3: /* PCIE target abort */
+ pr_err("pci_tegra_isr: Target abort\n");
+ break;
+ case 4: /* PCIE master abort */
+ /* Don't print this, as this error is a common error during
+ * enumeration.
+ */
+ /* pr_err("pci_tegra_isr: Master abort\n"); */
+ break;
+ case 5: /* Bufferable write to non-posted write */
+ pr_err("pci_tegra_isr: Invalid write"
+ " - Bufferable write to non-posted region\n");
+ break;
+ case 7: /* Response address mapping error */
+ pr_err("pci_tegra_isr: Response decoding error \n");
+ break;
+ case 8: /* Response address mapping error */
+ pr_err("pci_tegra_isr: AXI response decoding error\n");
+ break;
+ case 9: /* PCIE timeout */
+ pr_err("pci_tegra_isr: Transcation timeout\n");
+ break;
+ default:
+ pr_err("pci_tegra_isr: Unknown interrupt\n");
+ break;
+ }
+
+ /* Clear the interrupt code register to sample the next interrupt */
+ pci_tegra_afi_writel(0, AFI_INTR_CODE_0);
+
+ /* pr_err("-pci_tegra_isr\n"); */
+ return ret;
+}
+
+
+/*
+ * FIXME: If there are no PCIe cards attached, then calling this function
+ * can result in the increase of the bootup time as there are big timeout
+ * loops.
+ */
+static bool pci_tegra_check_rp(int rp)
+{
+#define PCI_TEGRA_LINKUP_TIMEOUT 50 /* i.e .2 seconds */
+ u32 reg;
+ int retry_count = 0;
+ int loop_counter;
+
+ BUG_ON(rp != 0 && rp != 1);
+retry:
+ if (retry_count > 2 ) {
+ pr_err("pci_tegra_check_rp: RP %d Failed\n", rp);
+ return false;
+ }
+
+ if (retry_count != 0) {
+ u32 offset;
+
+ /* Reset before retrying again. */
+ if (rp == 0) offset = AFI_PEX0_CTRL_0;
+ if (rp == 1) offset = AFI_PEX1_CTRL_0;
+
+ BUG_ON(AFI_PEX0_CTRL_0_PEX0_RST_L_SHIFT !=
+ AFI_PEX1_CTRL_0_PEX1_RST_L_SHIFT);
+
+ /* Pulse the PEX reset */
+ reg = pci_tegra_afi_readl(offset);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PEX0_CTRL, PEX0_RST_L, 1, reg);
+ pci_tegra_afi_writel(reg, offset);
+
+ msleep(100);
+
+ reg = pci_tegra_afi_readl(offset);
+ reg = NV_FLD_SET_DRF_NUM(AFI, PEX0_CTRL, PEX0_RST_L, 0, reg);
+ pci_tegra_afi_writel(reg, offset);
+ }
+
+ loop_counter = PCI_TEGRA_LINKUP_TIMEOUT;
+
+ reg = pci_tegra_rp_readl(NV_PROJ__PCIE2_RP_VEND_XP, rp);
+ while (loop_counter && (NVPCIE_DRF_VAL(RP, VEND_XP, DL_UP, reg)!= 1)) {
+ msleep(1);
+ reg = pci_tegra_rp_readl(NV_PROJ__PCIE2_RP_VEND_XP, rp);
+ loop_counter --;
+ }
+
+ if (!loop_counter) {
+ retry_count++;
+ pr_err("pci_tegra_check_rp: "
+ "RP %d LINK is not up...retrying...\n", rp);
+ goto retry;
+ }
+
+ loop_counter = PCI_TEGRA_LINKUP_TIMEOUT;
+
+ reg = pci_tegra_rp_readl(NV_PROJ__PCIE2_RP_LINK_CONTROL_STATUS, rp);
+ reg = NVPCIE_DRF_VAL(RP, LINK_CONTROL_STATUS, LINKSTAT, reg);
+ while (loop_counter && ((reg & 0x2000) != 0x2000)) {
+ msleep(1);
+ reg = pci_tegra_rp_readl(NV_PROJ__PCIE2_RP_LINK_CONTROL_STATUS,
+ rp);
+ reg = NVPCIE_DRF_VAL(RP, LINK_CONTROL_STATUS, LINKSTAT, reg);
+ pr_err("pci_tegra_check_rp: "
+ "RP %d LINK status 0x%x...retrying...\n", rp, reg);
+ loop_counter --;
+ }
+
+ if (!loop_counter) {
+ retry_count++;
+ goto retry;
+ }
+
+ pr_info("pci_tegra_check_rp: RP %d success\n", rp);
+ return true;
+}
diff --git a/arch/arm/mach-tegra/tegra_exports.c b/arch/arm/mach-tegra/tegra_exports.c
index d140eb707f60..e3f8fbe38db9 100644
--- a/arch/arm/mach-tegra/tegra_exports.c
+++ b/arch/arm/mach-tegra/tegra_exports.c
@@ -22,6 +22,25 @@
#include <linux/kernel.h>
#include <linux/module.h>
+#include "nvrm_analog.h"
+#include "nvrm_diag.h"
+#include "nvrm_dma.h"
+#include "nvrm_gpio.h"
+#include "nvrm_hardware_access.h"
+#include "nvrm_i2c.h"
+#include "nvrm_init.h"
+#include "nvrm_interrupt.h"
+#include "nvrm_keylist.h"
+#include "nvrm_memctrl.h"
+#include "nvrm_memmgr.h"
+#include "nvrm_module.h"
+#include "nvrm_owr.h"
+#include "nvrm_pcie.h"
+#include "nvrm_pinmux.h"
+#include "nvrm_pmu.h"
+#include "nvrm_power.h"
+#include "nvrm_pwm.h"
+#include "nvrm_rmctrace.h"
#include "nvrm_spi.h"
#include "nvodm_services.h"
#include "nvodm_query_discovery.h"
@@ -43,14 +62,41 @@ EXPORT_SYMBOL(NvOdmOsSemaphoreSignal);
EXPORT_SYMBOL(NvOdmOsSemaphoreWait);
EXPORT_SYMBOL(NvOdmOsSleepMS);
EXPORT_SYMBOL(NvOdmPeripheralGetGuid);
-EXPORT_SYMBOL(NvOsAlloc);
-EXPORT_SYMBOL(NvOsFree);
-EXPORT_SYMBOL(NvOsMemset);
-EXPORT_SYMBOL(NvOsThreadCreate);
-EXPORT_SYMBOL(NvOsThreadJoin);
-EXPORT_SYMBOL(NvOsDebugPrintf);
EXPORT_SYMBOL(NvRmOpen);
EXPORT_SYMBOL(NvRmClose);
+EXPORT_SYMBOL(NvRegrb);
+EXPORT_SYMBOL(NvRegrm);
+EXPORT_SYMBOL(NvRegwb);
+EXPORT_SYMBOL(NvRegwm);
+EXPORT_SYMBOL(NvRmGetIrqForLogicalInterrupt);
+EXPORT_SYMBOL(NvRmGetRmcFile);
+EXPORT_SYMBOL(NvRmInterruptDone);
+EXPORT_SYMBOL(NvRmInterruptRegister);
+EXPORT_SYMBOL(NvRmInterruptUnregister);
+EXPORT_SYMBOL(NvRmMemAlloc);
+EXPORT_SYMBOL(NvRmMemGetAddress);
+EXPORT_SYMBOL(NvRmMemGetId);
+EXPORT_SYMBOL(NvRmMemHandleCreate);
+EXPORT_SYMBOL(NvRmMemHandleFree);
+EXPORT_SYMBOL(NvRmMemHandleFromId);
+EXPORT_SYMBOL(NvRmMemMap);
+EXPORT_SYMBOL(NvRmMemPin);
+EXPORT_SYMBOL(NvRmMemRd32);
+EXPORT_SYMBOL(NvRmMemUnmap);
+EXPORT_SYMBOL(NvRmMemUnpin);
+EXPORT_SYMBOL(NvRmMemWr32);
+EXPORT_SYMBOL(NvRmMemWrite);
+EXPORT_SYMBOL(NvRmModuleGetBaseAddress);
+EXPORT_SYMBOL(NvRmModuleGetCapabilities);
+EXPORT_SYMBOL(NvRmPhysicalMemMap);
+EXPORT_SYMBOL(NvRmPhysicalMemUnmap);
+EXPORT_SYMBOL(NvRmPowerBusyHint);
+EXPORT_SYMBOL(NvRmPowerGetEvent);
+EXPORT_SYMBOL(NvRmPowerModuleClockConfig);
+EXPORT_SYMBOL(NvRmPowerModuleClockControl);
+EXPORT_SYMBOL(NvRmPowerRegister);
+EXPORT_SYMBOL(NvRmPowerVoltageControl);
+EXPORT_SYMBOL(NvRmRmcTrace);
EXPORT_SYMBOL(NvRmSpiOpen);
EXPORT_SYMBOL(NvRmSpiClose);
EXPORT_SYMBOL(NvRmSpiStartTransaction);
diff --git a/arch/arm/mach-tegra/tegra_sysmap.c b/arch/arm/mach-tegra/tegra_sysmap.c
index 13550ff45322..cb5b88ced984 100644
--- a/arch/arm/mach-tegra/tegra_sysmap.c
+++ b/arch/arm/mach-tegra/tegra_sysmap.c
@@ -34,6 +34,8 @@ static NvRmModuleID tegra_map_name_to_mod(const char *name, int inst)
return NVRM_MODULE_ID(NvRmPrivModuleID_Pl310, inst);
else if (!strcmp(name, "scu"))
return NVRM_MODULE_ID(NvRmPrivModuleID_ArmPerif, inst);
+ else if (!strcmp(name, "pcie"))
+ return NVRM_MODULE_ID(NvRmPrivModuleID_Pcie, inst);
return (NvRmModuleID) 0;
}
diff --git a/drivers/mtd/devices/tegra_mtd_nand.c b/drivers/mtd/devices/tegra_mtd_nand.c
index c6952ea5ef2e..a17b97252733 100644
--- a/drivers/mtd/devices/tegra_mtd_nand.c
+++ b/drivers/mtd/devices/tegra_mtd_nand.c
@@ -55,7 +55,6 @@ static const char *part_probes[] = { "cmdlinepart", NULL, };
#endif
static NvDdkNandHandle s_hNand;
-static struct wake_lock nand_wake_lock;
struct tegra_nand_chip {
spinlock_t lock;
@@ -219,11 +218,9 @@ static int tegra_nand_block_isbad(struct mtd_info *mtd, loff_t offs)
if (offs >= mtd->size)
return -EINVAL;
- wake_lock(&nand_wake_lock);
mutex_lock(&info->lock);
ret = check_block_isbad(mtd, offs, TagArea);
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return ret;
}
@@ -246,7 +243,6 @@ static int tegra_nand_block_markbad(struct mtd_info *mtd, loff_t offs)
pr_info("tegra_nand: setting block %d bad\n", block);
- wake_lock(&nand_wake_lock);
mutex_lock(&info->lock);
offs &= ~(mtd->erasesize - 1);
@@ -272,12 +268,10 @@ static int tegra_nand_block_markbad(struct mtd_info *mtd, loff_t offs)
NvDdkNandSuspendClocks(s_hNand);
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return 0;
fail:
NvDdkNandSuspendClocks(s_hNand);
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return -ENXIO;
}
@@ -383,7 +377,6 @@ static int tegra_nand_read(struct mtd_info *mtd, loff_t from, size_t len,
NvU32 PageNumber = 0, ChipNumber = 0;
NvU64 curAddr = from;
- wake_lock(&nand_wake_lock);
mutex_lock(&info->lock);
for (i=0;i<NDFLASH_CS_MAX;i++)
@@ -423,7 +416,6 @@ static int tegra_nand_read(struct mtd_info *mtd, loff_t from, size_t len,
NvDdkNandSuspendClocks(s_hNand);
*retlen = len;
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return 0;
fail:
@@ -431,7 +423,6 @@ fail:
NvDdkNandSuspendClocks(s_hNand);
*retlen = len - bytesLeft;
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return -EINVAL;
}
@@ -449,7 +440,6 @@ static int do_read_oob(struct mtd_info *mtd, loff_t from,
NvU32 PageNumber = 0, ChipNumber = 0;
NvU64 curAddr = from;
- wake_lock(&nand_wake_lock);
mutex_lock(&info->lock);
if (check_block_isbad(mtd, curAddr, tempSpareBuffer)) {
@@ -490,7 +480,6 @@ static int do_read_oob(struct mtd_info *mtd, loff_t from,
ops->oobretlen = 0;
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return 0;
fail:
@@ -500,7 +489,6 @@ fail:
NvDdkNandSuspendClocks(s_hNand);
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return -EINVAL;
}
@@ -552,7 +540,6 @@ static int tegra_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
pr_info("%s: write: to=0x%llx len=0x%x\n", __func__, to, len);
- wake_lock(&nand_wake_lock);
mutex_lock(&info->lock);
for (i=0;i<NDFLASH_CS_MAX;i++)
@@ -592,7 +579,6 @@ static int tegra_nand_write(struct mtd_info *mtd, loff_t to, size_t len,
*retlen = len;
NvDdkNandSuspendClocks(s_hNand);
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return 0;
fail:
@@ -600,7 +586,6 @@ fail:
pr_info("WriteError: NvDdkNandWrite failed error(0x%x)", e);
*retlen = len - bytesLeft;
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return -EINVAL;
}
@@ -617,7 +602,6 @@ static int do_write_oob(struct mtd_info *mtd, loff_t to,
NvU8 tempSpareBuffer[NAND_SPARE_SIZE];
NvU32 PageNumber = 0, ChipNumber = 0;
- wake_lock(&nand_wake_lock);
mutex_lock(&info->lock);
if (ooblen > info->chip.tagSize)
@@ -652,7 +636,6 @@ static int do_write_oob(struct mtd_info *mtd, loff_t to,
NvDdkNandSuspendClocks(s_hNand);
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return 0;
fail:
@@ -662,7 +645,6 @@ fail:
ops->oobretlen = 0;
mutex_unlock(&info->lock);
- wake_unlock(&nand_wake_lock);
return -EINVAL;
}
@@ -939,13 +921,11 @@ static struct platform_driver tegra_nand_driver = {
static int __init tegra_nand_init(void)
{
- wake_lock_init(&nand_wake_lock, WAKE_LOCK_IDLE, "tegra_nand");
return platform_driver_register(&tegra_nand_driver);
}
static void __exit tegra_nand_exit(void)
{
- wake_lock_destroy(&nand_wake_lock);
platform_driver_unregister(&tegra_nand_driver);
}
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index fa080e191ddf..056f6d91d226 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -930,6 +930,17 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net)
struct driver_info *info = dev->driver_info;
unsigned long flags;
+#ifdef CONFIG_ARCH_TEGRA
+ // check and do the proper 32 byte alignment for sk buff
+ if ((int)skb->data & 0x0000001F) {
+ struct sk_buff *new_skb = skb_copy_expand(skb, 32, 0, GFP_ATOMIC);
+ if(unlikely(!(new_skb)))
+ return -1;
+ kfree_skb(skb);
+ skb = new_skb;
+ }
+#endif
+
// some devices want funky USB-level framing, for
// win32 driver (usually) and/or hardware quirks
if (info->tx_fixup) {
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 26b1b1abd48e..09127fc6b799 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -445,16 +445,6 @@ config SERIAL_CLPS711X_CONSOLE
your boot loader (lilo or loadlin) about how to pass options to the
kernel at boot time.)
-config SERIAL_SAMSUNG
- tristate "Samsung SoC serial support"
- depends on ARM && PLAT_S3C
- select SERIAL_CORE
- help
- Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
- providing /dev/ttySAC0, 1 and 2 (note, some machines may not
- provide all of these ports, depending on how the serial port
- pins are configured.
-
config SERIAL_TEGRA_DDK
boolean "High speed serial support (DDK-based) for NVIDIA Tegra SoCs"
depends on ARCH_TEGRA
@@ -465,13 +455,34 @@ config SERIAL_TEGRA_DDK
config SERIAL_TEGRA
boolean "High speed serial support for NVIDIA Tegra SoCs"
- depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
+ depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA && !SERIAL_TEGRA_DDK
select SERIAL_CORE
help
Support for the on-chip UARTs on NVIDIA Tegra SoC, providing
/dev/ttyHSx, where x is determined by the number of UARTs on the
platform
+config SERIAL_TEGRA_UARTS
+ int "Number of high-speed (DMA) UARTs"
+ depends on SERIAL_TEGRA && MACH_TEGRA_GENERIC
+ default 1
+ help
+ When the Tegra RM is enabled (MACH_TEGRA_GENERIC), APB DMA
+ channels must be reserved for the system DMA driver at compile-
+ time; the number of reserved channels depends on the number of
+ high-speed DMA UARTs which will be used by the system; 8250 PIO
+ UARTs should not be counted toward this number.
+
+config SERIAL_SAMSUNG
+ tristate "Samsung SoC serial support"
+ depends on ARM && PLAT_S3C
+ select SERIAL_CORE
+ help
+ Support for the on-chip UARTs on the Samsung S3C24XX series CPUs,
+ providing /dev/ttySAC0, 1 and 2 (note, some machines may not
+ provide all of these ports, depending on how the serial port
+ pins are configured.
+
config SERIAL_SAMSUNG_UARTS
int
depends on ARM && PLAT_S3C
diff --git a/drivers/serial/tegra_hsuart.c b/drivers/serial/tegra_hsuart.c
index 1c4442b1973f..ba582f420a58 100644
--- a/drivers/serial/tegra_hsuart.c
+++ b/drivers/serial/tegra_hsuart.c
@@ -33,6 +33,7 @@
#include <linux/clk.h>
#include <linux/string.h>
#include <linux/pagemap.h>
+#include <linux/tegra_devices.h>
#include "nvos.h"
#include "mach/nvrm_linux.h"
@@ -106,8 +107,9 @@ static void tegra_set_baudrate(struct tegra_uart_port *t, unsigned int baud);
static inline int tegra_uart_isbreak(struct uart_port *u)
{
struct tegra_uart_port *t;
- t = container_of(u, struct tegra_uart_port, uport);
unsigned char lsr;
+
+ t = container_of(u, struct tegra_uart_port, uport);
lsr = readb(t->regs + UART_LSR_0);
if (lsr & NV_DRF_DEF(UART, LSR, BRK, BREAK)) {
/* If FIFO read error without any data, reset the Rx FIFO */
@@ -143,9 +145,10 @@ static inline void tegra_uart_set_rts(struct tegra_uart_port *t,
static void do_handle_rx_pio(struct uart_port *u)
{
struct tegra_uart_port *t;
- t = container_of(u, struct tegra_uart_port, uport);
struct tty_struct *tty = u->info->port.tty;
+ t = container_of(u, struct tegra_uart_port, uport);
+
do {
char flag = TTY_NORMAL;
unsigned char lsr;
@@ -387,7 +390,7 @@ static irqreturn_t tegra_uart_isr(int irq, void *data)
case 3: /* Receive error */
case 6: /* Rx timeout */
if (likely(use_rx_dma))
- do_handle_rx_dma(u);
+ do_handle_rx_dma(u, 0);
else
do_handle_rx_pio(u);
tty_flip_buffer_push(u->info->port.tty);
@@ -505,14 +508,14 @@ fail:
return -ENODEV;
}
-static void tegra_uart_init_rx_dma(struct tegra_uart_port *t)
+static int tegra_uart_init_rx_dma(struct tegra_uart_port *t)
{
int i;
/* Rx uses 1 DMA channel and 2 chained buffers */
t->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINOUS);
if (t->rx_dma < 0)
- goto fail;
+ return -ENODEV;
for (i=0; i<2; i++) {
dma_addr_t rx_dma_phys;
@@ -522,10 +525,12 @@ static void tegra_uart_init_rx_dma(struct tegra_uart_port *t)
/* Allocate receive DMA buffer
* This buffer can hold data for 50 ms with 4.5 Mbps data rate.
*/
- rx_dma_virt = dma_alloc_coherent(u->dev,
+ rx_dma_virt = dma_alloc_coherent(t->uport.dev,
t->rx_dma_req[i].size, &rx_dma_phys, GFP_KERNEL);
- if (!rx_dma_virt)
- dev_err(u->dev, "Could not allocate the dma buffers\n");
+ if (!rx_dma_virt) {
+ dev_err(t->uport.dev, "Could not allocate dma buffers\n");
+ return -ENODEV;
+ }
/* Polulate Rx DMA buffer */
t->rx_dma_req[i].source_addr = t->phys;
@@ -534,17 +539,18 @@ static void tegra_uart_init_rx_dma(struct tegra_uart_port *t)
t->rx_dma_req[i].dest_wrap = 0;
t->rx_dma_req[i].to_memory = 1;
t->rx_dma_req[i].modid = NvRmModuleID_Uart;
- t->rx_dma_req[i].instance = u->line;
+ t->rx_dma_req[i].instance = t->uport.line;
t->rx_dma_req[i].complete = tegra_rx_dma_complete_callback;
t->rx_dma_req[i].size = t->rx_dma_req[i].size;
- t->rx_dma_req[i].data = u;
+ t->rx_dma_req[i].data = &t->uport;
t->rx_dma_req[i].virt_addr = rx_dma_virt;
INIT_LIST_HEAD(&(t->rx_dma_req[i].list));
if (tegra_dma_enqueue_req(t->rx_dma, &t->rx_dma_req[i])) {
- dev_err(u->dev, "Could not enqueue Rx DMA request\n");
+ dev_err(t->uport.dev, "Could not enqueue Rx DMA req\n");
+ return -ENODEV;
}
}
-
+ return 0;
}
static int tegra_startup(struct uart_port *u)
@@ -552,7 +558,6 @@ static int tegra_startup(struct uart_port *u)
struct tegra_uart_port *t;
int ret = 0;
unsigned char ier;
- int i;
t = container_of(u, struct tegra_uart_port, uport);
sprintf(t->port_name, "tegra_uart_%d", u->line);
@@ -605,8 +610,8 @@ static int tegra_startup(struct uart_port *u)
t->tx_dma_req.source_wrap = 0;
t->tx_dma_req.data = &t->tasklet;
}
- if (use_rx_dma)
- tegra_uart_init_rx_dma(t);
+ if (use_rx_dma && tegra_uart_init_rx_dma(t))
+ goto fail;
/*
* Enable IE_RXS for the receive status interrupts like line errros.
* Enable IE_RX_TIMEOUT to get the bytes which cannot be DMA'd.
@@ -861,7 +866,6 @@ void tegra_set_termios(struct uart_port *u, struct ktermios *termios,
struct tegra_uart_port *t;
unsigned int baud;
unsigned long flags;
- unsigned int mcr;
unsigned int lcr;
unsigned int c_cflag = termios->c_cflag;
char debug_string[50];