diff options
-rw-r--r-- | arch/arm/mach-tegra/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board_nvodm.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-tegra/dma.c | 29 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/dma.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/nvrm_linux.h | 35 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/pci.h | 323 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/platform.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/init_common.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvec_user.c | 61 | ||||
-rwxr-xr-x[-rw-r--r--] | arch/arm/mach-tegra/nvodm/nvodm_services.c | 21 | ||||
-rwxr-xr-x[-rw-r--r--] | arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_analog.c | 1909 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c | 23 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pci-enum.c | 637 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pci.c | 561 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra_exports.c | 58 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra_sysmap.c | 2 | ||||
-rw-r--r-- | drivers/mtd/devices/tegra_mtd_nand.c | 20 | ||||
-rw-r--r-- | drivers/net/usb/usbnet.c | 11 | ||||
-rw-r--r-- | drivers/serial/Kconfig | 33 | ||||
-rw-r--r-- | drivers/serial/tegra_hsuart.c | 36 |
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]; |