summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAndrew Howe <ahowe@nvidia.com>2010-07-19 14:01:11 +0300
committerJanne Hellsten <jhellsten@nvidia.com>2010-07-29 04:41:50 -0700
commita91a0fdac15143e19335d837798133ad7dc22045 (patch)
tree455f46b5bf081660acc6eb18fd12279630f54003 /arch
parent78ea3763bef4ec4bf87eabf7a6b66b3282e4d372 (diff)
tegra video: add driver for host1x hardware
The graphics hardware modules on Tegra family of SOCs are accessed via the host1x dma and synchronization engine. This driver exposes an userspace interface for submitting command buffers to 2d, 3d, display and mpe hardware modules and accessing the module register apertures for exclusive use hardware modules. Additional features of the driver include: - interrupt-driven hardware module usage synchronization - automatic clock management for hw modules - hardware context switching for 3d registers Change-Id: I693582249597fd307526ff3c7e35889d37406017 Reviewed-on: http://git-master/r/4091 Reviewed-by: Janne Hellsten <jhellsten@nvidia.com> Tested-by: Janne Hellsten <jhellsten@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/configs/tegra_harmony_android_defconfig2
-rw-r--r--arch/arm/configs/tegra_harmony_gnu_linux_defconfig10
-rwxr-xr-xarch/arm/configs/tegra_ventana_android_defconfig2
-rw-r--r--arch/arm/configs/tegra_whistler_android_defconfig2
-rw-r--r--arch/arm/configs/tegra_whistler_gnu_linux_defconfig2
-rw-r--r--arch/arm/mach-tegra/board-common.c62
-rw-r--r--arch/arm/mach-tegra/clock_nvrm.c64
-rw-r--r--arch/arm/mach-tegra/common.c2
-rw-r--r--arch/arm/mach-tegra/include/mach/iomap.h12
-rw-r--r--arch/arm/mach-tegra/include/mach/irqs.h7
-rw-r--r--arch/arm/mach-tegra/include/mach/nvmem.h158
-rw-r--r--arch/arm/mach-tegra/irq.c75
12 files changed, 214 insertions, 184 deletions
diff --git a/arch/arm/configs/tegra_harmony_android_defconfig b/arch/arm/configs/tegra_harmony_android_defconfig
index c4dcf77001d7..2eeb145dacd4 100644
--- a/arch/arm/configs/tegra_harmony_android_defconfig
+++ b/arch/arm/configs/tegra_harmony_android_defconfig
@@ -1339,6 +1339,8 @@ CONFIG_FB_TEGRA=y
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
+CONFIG_FB_TEGRA_DUMMY=y
+CONFIG_FB_TEGRA_GRHOST=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_LMS283GF05 is not set
diff --git a/arch/arm/configs/tegra_harmony_gnu_linux_defconfig b/arch/arm/configs/tegra_harmony_gnu_linux_defconfig
index aa5a9c250557..bdd316cbbef6 100644
--- a/arch/arm/configs/tegra_harmony_gnu_linux_defconfig
+++ b/arch/arm/configs/tegra_harmony_gnu_linux_defconfig
@@ -949,9 +949,6 @@ CONFIG_HW_CONSOLE=y
CONFIG_VT_HW_CONSOLE_BINDING=y
CONFIG_DEVMEM=y
# CONFIG_DEVKMEM is not set
-CONFIG_DEVNVMAP=y
-# CONFIG_DEVNVMAP_PARANOID is not set
-CONFIG_DEVNVMAP_RECLAIM_UNPINNED_VM=y
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NOZOMI is not set
@@ -1194,7 +1191,6 @@ CONFIG_FB_TILEBLITTING=y
# CONFIG_FB_S1D13XXX is not set
# CONFIG_FB_NVIDIA is not set
# CONFIG_FB_RIVA is not set
-CONFIG_FB_TEGRA=y
# CONFIG_FB_MATROX is not set
# CONFIG_FB_RADEON is not set
# CONFIG_FB_ATY128 is not set
@@ -1216,6 +1212,12 @@ CONFIG_FB_TEGRA=y
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
+CONFIG_FB_TEGRA=y
+CONFIG_FB_TEGRA_DUMMY=y
+CONFIG_FB_TEGRA_GRHOST=y
+CONFIG_DEVNVMAP=y
+# CONFIG_DEVNVMAP_PARANOID is not set
+CONFIG_DEVNVMAP_RECLAIM_UNPINNED_VM=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_LMS283GF05 is not set
diff --git a/arch/arm/configs/tegra_ventana_android_defconfig b/arch/arm/configs/tegra_ventana_android_defconfig
index fd2fc1697254..c0c64f728223 100755
--- a/arch/arm/configs/tegra_ventana_android_defconfig
+++ b/arch/arm/configs/tegra_ventana_android_defconfig
@@ -1046,6 +1046,8 @@ CONFIG_FB_TEGRA=y
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
+CONFIG_FB_TEGRA_DUMMY=y
+CONFIG_FB_TEGRA_GRHOST=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_LMS283GF05 is not set
diff --git a/arch/arm/configs/tegra_whistler_android_defconfig b/arch/arm/configs/tegra_whistler_android_defconfig
index 6ed4b376de64..c749c4c1a285 100644
--- a/arch/arm/configs/tegra_whistler_android_defconfig
+++ b/arch/arm/configs/tegra_whistler_android_defconfig
@@ -1204,6 +1204,8 @@ CONFIG_FB_TEGRA=y
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
+CONFIG_FB_TEGRA_DUMMY=y
+CONFIG_FB_TEGRA_GRHOST=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_LMS283GF05 is not set
diff --git a/arch/arm/configs/tegra_whistler_gnu_linux_defconfig b/arch/arm/configs/tegra_whistler_gnu_linux_defconfig
index 06f299d6e40c..4c927c138eab 100644
--- a/arch/arm/configs/tegra_whistler_gnu_linux_defconfig
+++ b/arch/arm/configs/tegra_whistler_gnu_linux_defconfig
@@ -1057,6 +1057,8 @@ CONFIG_FB_TEGRA=y
# CONFIG_FB_METRONOME is not set
# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
+CONFIG_FB_TEGRA_DUMMY=y
+CONFIG_FB_TEGRA_GRHOST=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
# CONFIG_LCD_LMS283GF05 is not set
diff --git a/arch/arm/mach-tegra/board-common.c b/arch/arm/mach-tegra/board-common.c
index 1cc943ddaa18..f0d5259ef36c 100644
--- a/arch/arm/mach-tegra/board-common.c
+++ b/arch/arm/mach-tegra/board-common.c
@@ -184,6 +184,65 @@ static struct platform_device tegra_gart_device = {
};
#endif
+#ifdef CONFIG_FB_TEGRA_GRHOST
+static struct resource tegra_grhost_resources[] = {
+ [0] = {
+ .name = "host1x",
+ .start = TEGRA_HOST1X_BASE,
+ .end = TEGRA_HOST1X_BASE + TEGRA_HOST1X_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "display",
+ .start = TEGRA_DISPLAY_BASE,
+ .end = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .name = "display2",
+ .start = TEGRA_DISPLAY2_BASE,
+ .end = TEGRA_DISPLAY2_BASE + TEGRA_DISPLAY2_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .name = "vi",
+ .start = TEGRA_VI_BASE,
+ .end = TEGRA_VI_BASE + TEGRA_VI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [4] = {
+ .name = "isp",
+ .start = TEGRA_ISP_BASE,
+ .end = TEGRA_ISP_BASE + TEGRA_ISP_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [5] = {
+ .name = "mpe",
+ .start = TEGRA_MPE_BASE,
+ .end = TEGRA_MPE_BASE + TEGRA_MPE_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [6] = {
+ .name = "syncpt_thresh",
+ .start = INT_SYNCPT_THRESH_BASE,
+ .end = INT_SYNCPT_THRESH_BASE + INT_SYNCPT_THRESH_NR - 1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [7] = {
+ .name = "host1x_mpcore_general",
+ .start = INT_HOST1X_MPCORE_GENERAL,
+ .end = INT_HOST1X_MPCORE_GENERAL,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device tegra_grhost_device = {
+ .name = "tegra_grhost",
+ .id = -1,
+ .resource = tegra_grhost_resources,
+ .num_resources = ARRAY_SIZE(tegra_grhost_resources),
+};
+#endif
+
#ifdef CONFIG_USB_GADGET_TEGRA
static u64 tegra_udc_dma_mask = DMA_BIT_MASK(32);
static struct fsl_usb2_platform_data tegra_udc_platform = {
@@ -234,6 +293,9 @@ static struct platform_device *tegra_devices[] __initdata = {
#ifdef CONFIG_TEGRA_IOVMM_GART
&tegra_gart_device,
#endif
+#ifdef CONFIG_FB_TEGRA_GRHOST
+ &tegra_grhost_device,
+#endif
};
void __init tegra_register_socdev(void)
diff --git a/arch/arm/mach-tegra/clock_nvrm.c b/arch/arm/mach-tegra/clock_nvrm.c
index c94dfd6a54a7..9bd5e7fb571a 100644
--- a/arch/arm/mach-tegra/clock_nvrm.c
+++ b/arch/arm/mach-tegra/clock_nvrm.c
@@ -100,6 +100,12 @@ static int tegra_periph_clk_enable(struct clk *c)
return -ENXIO;
}
+ /* max out emc when 3d is on */
+ if (NVRM_MODULE_ID_MODULE(c->module) == NvRmModuleID_3D) {
+ NvRmPowerBusyHint(s_hRmGlobal, NvRmDfsClockId_Emc, clk_pwr_client,
+ 0xffffffff, NvRmFreqMaximum);
+ }
+
return 0;
}
@@ -107,6 +113,10 @@ static void tegra_periph_clk_disable(struct clk *c)
{
NvError e;
+ if (NVRM_MODULE_ID_MODULE(c->module) == NvRmModuleID_3D) {
+ NvRmPowerBusyHint(s_hRmGlobal, NvRmDfsClockId_Emc, clk_pwr_client, 0, 0);
+ }
+
e = NvRmPowerModuleClockControl(s_hRmGlobal, c->module,
clk_pwr_client, NV_FALSE);
@@ -170,6 +180,16 @@ static unsigned long tegra_periph_clk_get_rate(struct clk *c)
return (unsigned long)freq * 1000;
}
+static long tegra_periph_clk_round_rate(struct clk *c, unsigned long rate)
+{
+ NvRmFreqKHz max;
+ /* TODO: rm reports an unachievable max rate for host */
+ if (c->module == NvRmModuleID_GraphicsHost)
+ max = 111000;
+ else
+ max = NvRmPowerModuleGetMaxFrequency(s_hRmGlobal, c->module);
+ return min(((unsigned long)max) * 1000, rate);
+}
static struct clk_ops tegra_periph_clk_ops = {
.init = tegra_periph_clk_init,
@@ -177,6 +197,7 @@ static struct clk_ops tegra_periph_clk_ops = {
.disable = tegra_periph_clk_disable,
.set_rate = tegra_periph_clk_set_rate,
.get_rate = tegra_periph_clk_get_rate,
+ .round_rate = tegra_periph_clk_round_rate,
};
static unsigned long tegra_clksrc_clk_get_rate(struct clk *c)
@@ -212,11 +233,12 @@ static struct clk_ops dfs_clk_ops = {
#define NvRmModuleID_Afi NvRmPrivModuleID_Afi
#define NvRmModuleID_PcieXclk NvRmPrivModuleID_PcieXclk
-#define PERIPH_CLK(_name, _dev, _modname, _instance, _tol, _min, _pow) \
+#define PERIPH_CLK(_name, _dev, _con, _modname, _instance, _tol, _min, _pow) \
{ \
.name = _name, \
.lookup = { \
.dev_id = _dev, \
+ .con_id = _con, \
}, \
.module = NVRM_MODULE_ID(NvRmModuleID_##_modname, _instance), \
.ops = &tegra_periph_clk_ops, \
@@ -226,19 +248,23 @@ static struct clk_ops dfs_clk_ops = {
}
static struct clk tegra_periph_clk[] = {
- PERIPH_CLK("rtc", "rtc-tegra", Rtc, 0, 0, 0, false),
- PERIPH_CLK("kbc", "tegra-kbc", Kbc, 0, 0, 0, false),
- PERIPH_CLK("uarta", "uart.0", Uart, 0, 5, 0, true),
- PERIPH_CLK("uartb", "uart.1", Uart, 1, 5, 0, true),
- PERIPH_CLK("uartc", "uart.2", Uart, 2, 5, 0, true),
- PERIPH_CLK("uartd", "uart.3", Uart, 3, 5, 0, true),
- PERIPH_CLK("uarte", "uart.4", Uart, 4, 5, 0, true),
- PERIPH_CLK("sdmmc1", "tegra-sdhci.0", Sdio, 0, 0, 400, false),
- PERIPH_CLK("sdmmc2", "tegra-sdhci.1", Sdio, 1, 0, 400, false),
- PERIPH_CLK("sdmmc3", "tegra-sdhci.2", Sdio, 2, 0, 400, false),
- PERIPH_CLK("sdmmc4", "tegra-sdhci.3", Sdio, 3, 0, 400, false),
- PERIPH_CLK("pcie", "tegra_pcie", Pcie, 0, 0, 0, true),
- PERIPH_CLK("pcie_xclk", "tegra_pcie_xclk", PcieXclk, 0, 0, 0, false),
+ PERIPH_CLK("rtc", "rtc-tegra", NULL, Rtc, 0, 0, 0, false),
+ PERIPH_CLK("kbc", "tegra-kbc", NULL, Kbc, 0, 0, 0, false),
+ PERIPH_CLK("uarta", "uart.0", NULL, Uart, 0, 5, 0, true),
+ PERIPH_CLK("uartb", "uart.1", NULL, Uart, 1, 5, 0, true),
+ PERIPH_CLK("uartc", "uart.2", NULL, Uart, 2, 5, 0, true),
+ PERIPH_CLK("uartd", "uart.3", NULL, Uart, 3, 5, 0, true),
+ PERIPH_CLK("uarte", "uart.4", NULL, Uart, 4, 5, 0, true),
+ PERIPH_CLK("sdmmc1", "tegra-sdhci.0", NULL, Sdio, 0, 0, 400, false),
+ PERIPH_CLK("sdmmc2", "tegra-sdhci.1", NULL, Sdio, 1, 0, 400, false),
+ PERIPH_CLK("sdmmc3", "tegra-sdhci.2", NULL, Sdio, 2, 0, 400, false),
+ PERIPH_CLK("sdmmc4", "tegra-sdhci.3", NULL, Sdio, 3, 0, 400, false),
+ PERIPH_CLK("pcie", "tegra_pcie", NULL, Pcie, 0, 0, 0, true),
+ PERIPH_CLK("pcie_xclk", "tegra_pcie_xclk", NULL, PcieXclk, 0, 0, 0, false),
+ PERIPH_CLK("gr3d", "tegra_grhost", "gr3d", 3D, 0, 0, 0, true),
+ PERIPH_CLK("gr2d", "tegra_grhost", "gr2d", 2D, 0, 0, 0, true),
+ PERIPH_CLK("host1x", "tegra_grhost", "host1x", GraphicsHost, 0, 0, 0, true),
+ PERIPH_CLK("epp", "tegra_grhost", "epp", Epp, 0, 0, 0, true),
};
static struct clk tegra_clk_cpu = {
@@ -390,6 +416,16 @@ unsigned long clk_get_rate(struct clk *c)
}
EXPORT_SYMBOL(clk_get_rate);
+long clk_round_rate(struct clk *c, unsigned long rate)
+{
+ if (c->ops && c->ops->round_rate)
+ return c->ops->round_rate(c, rate);
+
+ return -ENOSYS;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+
void __init tegra_init_clock(void)
{
NvError e;
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index ce9decb0dfa2..d6bee1d29bdf 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -20,6 +20,7 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/cpu.h>
+#include <linux/nvmap.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/cacheflush.h>
@@ -27,7 +28,6 @@
#include <mach/iomap.h>
#include <mach/dma.h>
-#include <mach/nvmem.h>
#include "board.h"
diff --git a/arch/arm/mach-tegra/include/mach/iomap.h b/arch/arm/mach-tegra/include/mach/iomap.h
index bd28f03dd4fc..d5fb089864ad 100644
--- a/arch/arm/mach-tegra/include/mach/iomap.h
+++ b/arch/arm/mach-tegra/include/mach/iomap.h
@@ -26,6 +26,9 @@
#define TEGRA_IRAM_BASE 0x40000000
#define TEGRA_IRAM_SIZE SZ_256K
+#define TEGRA_HOST1X_BASE 0x50000000
+#define TEGRA_HOST1X_SIZE 0x24000
+
#define TEGRA_ARM_PERIF_BASE 0x50040000
#define TEGRA_ARM_PERIF_SIZE SZ_8K
@@ -35,6 +38,15 @@
#define TEGRA_ARM_INT_DIST_BASE 0x50041000
#define TEGRA_ARM_INT_DIST_SIZE SZ_4K
+#define TEGRA_MPE_BASE 0x54040000
+#define TEGRA_MPE_SIZE SZ_256K
+
+#define TEGRA_VI_BASE 0x54080000
+#define TEGRA_VI_SIZE SZ_256K
+
+#define TEGRA_ISP_BASE 0x54100000
+#define TEGRA_ISP_SIZE SZ_256K
+
#define TEGRA_DISPLAY_BASE 0x54200000
#define TEGRA_DISPLAY_SIZE SZ_256K
diff --git a/arch/arm/mach-tegra/include/mach/irqs.h b/arch/arm/mach-tegra/include/mach/irqs.h
index abd8449b72d7..91388d8967fc 100644
--- a/arch/arm/mach-tegra/include/mach/irqs.h
+++ b/arch/arm/mach-tegra/include/mach/irqs.h
@@ -166,9 +166,12 @@
#define INT_QUAD_RES_30 (INT_QUAD_BASE + 30)
#define INT_QUAD_RES_31 (INT_QUAD_BASE + 31)
-#define INT_GPIO_BASE (INT_QUAD_BASE + 32)
-#define INT_GPIO_NR (28 * 8)
+#define INT_SYNCPT_THRESH_BASE (INT_QUAD_BASE + 32)
+#define INT_SYNCPT_THRESH_NR 32
+#define INT_GPIO_BASE (INT_SYNCPT_THRESH_BASE + \
+ INT_SYNCPT_THRESH_NR)
+#define INT_GPIO_NR (28 * 8)
#endif
#define NR_IRQS (INT_GPIO_BASE + INT_GPIO_NR)
diff --git a/arch/arm/mach-tegra/include/mach/nvmem.h b/arch/arm/mach-tegra/include/mach/nvmem.h
deleted file mode 100644
index 3be28fff8856..000000000000
--- a/arch/arm/mach-tegra/include/mach/nvmem.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * arch/arm/mach-tegra/include/linux/nvmem_ioctl.h
- *
- * structure declarations for nvmem and nvmap user-space ioctls
- *
- * Copyright (c) 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 <linux/ioctl.h>
-
-#if !defined(__KERNEL__)
-#define __user
-#endif
-
-#ifndef _MACH_TEGRA_NVMEM_IOCTL_H_
-#define _MACH_TEGRA_NVMEM_IOCTL_H_
-
-struct nvmem_create_handle {
- union {
- __u32 key; /* ClaimPreservedHandle */
- __u32 id; /* FromId */
- __u32 size; /* CreateHandle */
- };
- __u32 handle;
-};
-
-#define NVMEM_HEAP_SYSMEM (1ul<<31)
-#define NVMEM_HEAP_IOVMM (1ul<<30)
-
-/* common carveout heaps */
-#define NVMEM_HEAP_CARVEOUT_IRAM (1ul<<29)
-#define NVMEM_HEAP_CARVEOUT_GENERIC (1ul<<0)
-
-#define NVMEM_HEAP_CARVEOUT_MASK (NVMEM_HEAP_IOVMM - 1)
-
-#define NVMEM_HANDLE_UNCACHEABLE (0x0ul << 0)
-#define NVMEM_HANDLE_WRITE_COMBINE (0x1ul << 0)
-#define NVMEM_HANDLE_INNER_CACHEABLE (0x2ul << 0)
-#define NVMEM_HANDLE_CACHEABLE (0x3ul << 0)
-
-#define NVMEM_HANDLE_SECURE (0x1ul << 2)
-
-struct nvmem_alloc_handle {
- __u32 handle;
- __u32 heap_mask;
- __u32 flags;
- __u32 align;
-};
-
-struct nvmem_map_caller {
- __u32 handle; /* hmem */
- __u32 offset; /* offset into hmem; should be page-aligned */
- __u32 length; /* number of bytes to map */
- __u32 flags;
- unsigned long addr; /* user pointer */
-};
-
-struct nvmem_rw_handle {
- unsigned long addr; /* user pointer */
- __u32 handle; /* hmem */
- __u32 offset; /* offset into hmem */
- __u32 elem_size; /* individual atom size */
- __u32 hmem_stride; /* delta in bytes between atoms in hmem */
- __u32 user_stride; /* delta in bytes between atoms in user */
- __u32 count; /* number of atoms to copy */
-};
-
-struct nvmem_pin_handle {
- unsigned long handles; /* array of handles to pin/unpin */
- unsigned long addr; /* array of addresses to return */
- __u32 count; /* number of entries in handles */
-};
-
-struct nvmem_handle_param {
- __u32 handle;
- __u32 param;
- unsigned long result;
-};
-
-enum {
- NVMEM_HANDLE_PARAM_SIZE = 1,
- NVMEM_HANDLE_PARAM_ALIGNMENT,
- NVMEM_HANDLE_PARAM_BASE,
- NVMEM_HANDLE_PARAM_HEAP,
-};
-
-enum {
- NVMEM_CACHE_OP_WB = 0,
- NVMEM_CACHE_OP_INV,
- NVMEM_CACHE_OP_WB_INV,
-};
-
-struct nvmem_cache_op {
- unsigned long addr;
- __u32 handle;
- __u32 len;
- __s32 op;
-};
-
-#define NVMEM_IOC_MAGIC 'N'
-
-/* Creates a new memory handle. On input, the argument is the size of the new
- * handle; on return, the argument is the name of the new handle
- */
-#define NVMEM_IOC_CREATE _IOWR(NVMEM_IOC_MAGIC, 0, struct nvmem_create_handle)
-#define NVMEM_IOC_CLAIM _IOWR(NVMEM_IOC_MAGIC, 1, struct nvmem_create_handle)
-#define NVMEM_IOC_FROM_ID _IOWR(NVMEM_IOC_MAGIC, 2, struct nvmem_create_handle)
-
-/* Actually allocates memory for the specified handle */
-#define NVMEM_IOC_ALLOC _IOW (NVMEM_IOC_MAGIC, 3, struct nvmem_alloc_handle)
-
-/* Frees a memory handle, unpinning any pinned pages and unmapping any mappings
- */
-#define NVMEM_IOC_FREE _IO (NVMEM_IOC_MAGIC, 4)
-
-/* Maps the region of the specified handle into a user-provided virtual address
- * that was previously created via an mmap syscall on this fd */
-#define NVMEM_IOC_MMAP _IOWR(NVMEM_IOC_MAGIC, 5, struct nvmem_map_caller)
-
-/* Reads/writes data (possibly strided) from a user-provided buffer into the
- * hmem at the specified offset */
-#define NVMEM_IOC_WRITE _IOW (NVMEM_IOC_MAGIC, 6, struct nvmem_rw_handle)
-#define NVMEM_IOC_READ _IOW (NVMEM_IOC_MAGIC, 7, struct nvmem_rw_handle)
-
-#define NVMEM_IOC_PARAM _IOWR(NVMEM_IOC_MAGIC, 8, struct nvmem_handle_param)
-
-/* Pins a list of memory handles into IO-addressable memory (either IOVMM
- * space or physical memory, depending on the allocation), and returns the
- * address. Handles may be pinned recursively. */
-#define NVMEM_IOC_PIN_MULT _IOWR(NVMEM_IOC_MAGIC, 10, struct nvmem_pin_handle)
-#define NVMEM_IOC_UNPIN_MULT _IOW (NVMEM_IOC_MAGIC, 11, struct nvmem_pin_handle)
-
-#define NVMEM_IOC_CACHE _IOW (NVMEM_IOC_MAGIC, 12, struct nvmem_cache_op)
-
-/* Returns a global ID usable to allow a remote process to create a handle
- * reference to the same handle */
-#define NVMEM_IOC_GET_ID _IOWR(NVMEM_IOC_MAGIC, 13, struct nvmem_create_handle)
-
-#define NVMEM_IOC_MAXNR (_IOC_NR(NVMEM_IOC_GET_ID))
-
-int nvmap_add_carveout_heap(unsigned long base, size_t size,
- const char *name, unsigned int bitmask);
-
-#endif
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index 687a5474191a..7101a9458b6a 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -33,10 +33,6 @@
#define INT_SYS_SZ (INT_SEC_BASE - INT_PRI_BASE)
#define PPI_NR ((INT_SYS_NR+INT_SYS_SZ-1)/INT_SYS_SZ)
-#define APBDMA_IRQ_STA_CPU 0x14
-#define APBDMA_IRQ_MASK_SET 0x20
-#define APBDMA_IRQ_MASK_CLR 0x24
-
#define ICTLR_CPU_IER 0x20
#define ICTLR_CPU_IER_SET 0x24
#define ICTLR_CPU_IER_CLR 0x28
@@ -46,6 +42,13 @@
#define ICTLR_COP_IER_CLR 0x38
#define ICTLR_COP_IEP_CLASS 0x3c
+#define HOST1X_SYNC_OFFSET 0x3000
+#define HOST1X_SYNC_SIZE 0x800
+enum {
+ HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS = 0x40,
+ HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE = 0x60
+};
+
static void (*gic_mask_irq)(unsigned int irq) = NULL;
static void (*gic_unmask_irq)(unsigned int irq) = NULL;
@@ -84,6 +87,66 @@ static struct irq_chip tegra_irq = {
#endif
};
+static void syncpt_thresh_mask(unsigned int irq)
+{
+ (void)irq;
+}
+
+static void syncpt_thresh_unmask(unsigned int irq)
+{
+ (void)irq;
+}
+
+static void syncpt_thresh_cascade(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *sync_regs = get_irq_desc_data(desc);
+ u32 reg;
+ int id;
+
+ desc->chip->ack(irq);
+
+ reg = readl(sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
+
+ while ((id = __fls(reg)) >= 0) {
+ reg ^= BIT(id);
+ generic_handle_irq(id + INT_SYNCPT_THRESH_BASE);
+ }
+
+ desc->chip->unmask(irq);
+}
+
+static struct irq_chip syncpt_thresh_irq = {
+ .name = "syncpt",
+ .mask = syncpt_thresh_mask,
+ .unmask = syncpt_thresh_unmask
+};
+
+void __init syncpt_init_irq(void)
+{
+ void __iomem *sync_regs;
+ unsigned int i;
+
+ sync_regs = ioremap(TEGRA_HOST1X_BASE + HOST1X_SYNC_OFFSET,
+ HOST1X_SYNC_SIZE);
+ BUG_ON(!sync_regs);
+
+ writel(0xffffffffUL,
+ sync_regs + HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE);
+ writel(0xffffffffUL,
+ sync_regs + HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS);
+
+ for (i = INT_SYNCPT_THRESH_BASE; i < INT_GPIO_BASE; i++) {
+ set_irq_chip(i, &syncpt_thresh_irq);
+ set_irq_chip_data(i, sync_regs);
+ set_irq_handler(i, handle_simple_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ if (set_irq_data(INT_HOST1X_MPCORE_SYNCPT, sync_regs))
+ BUG();
+ set_irq_chained_handler(INT_HOST1X_MPCORE_SYNCPT,
+ syncpt_thresh_cascade);
+}
+
void __init tegra_init_irq(void)
{
struct irq_chip *gic;
@@ -105,11 +168,13 @@ void __init tegra_init_irq(void)
tegra_irq.set_affinity = gic->set_affinity;
#endif
- for (i=INT_PRI_BASE; i<INT_GPIO_BASE; i++) {
+ for (i=INT_PRI_BASE; i<INT_SYNCPT_THRESH_BASE; i++) {
set_irq_chip(i, &tegra_irq);
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
+
+ syncpt_init_irq();
}
#ifdef CONFIG_PM