Re: [PATCH] MAINTAINERS: Remove Terje Bergström as Tegra DRM maintainer

2016-03-07 Thread Terje Bergstrom
On 03/04/2016 03:58 AM, Thierry Reding wrote:
> From: Thierry Reding 
>
> Terje doesn't work on host1x anymore and doesn't have the time to help
> maintain the host1x and related drivers.
>
> Signed-off-by: Thierry Reding 
> ---
>   MAINTAINERS | 1 -
>   1 file changed, 1 deletion(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4a4edae9d2aa..d2a2864616e0 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -3844,7 +3844,6 @@ F:  include/drm/gma500*
>   
>   DRM DRIVERS FOR NVIDIA TEGRA
>   M:  Thierry Reding 
> -M:   Terje Bergström 
>   L:  dri-devel at lists.freedesktop.org
>   L:  linux-tegra at vger.kernel.org
>   T:  git git://anongit.freedesktop.org/tegra/linux.git

Acked-by: Terje Bergstrom 

Terje


[PATCH 2/2] drm/tegra: Set the DMA mask

2016-02-23 Thread Terje Bergstrom


On 02/23/2016 08:04 AM, Thierry Reding wrote:
> * PGP Signed by an unknown key  > > On Tue, Feb 23, 2016 at 03:25:54PM +0900, 
> Alexandre Courbot wrote: 
 >> The default DMA mask covers a 32 bits address range, but tegradrm >> 
can address more than that. Set the DMA mask to the actual >> 
addressable range to avoid the use of unneeded bounce buffers. >> >> 
Signed-off-by: Alexandre Courbot  --- Thierry, >> I 
am not absolutely sure whether the size is correct and applies to >> all 
Tegra generations - please let me know if this needs to be >> reworked. 
 >> >> drivers/gpu/drm/tegra/drm.c | 1 + 1 file changed, 1 insertion(+) 
 > > This kind of depends on whether or not the device is behind an 
IOMMU. > If it is, then the IOMMU DMA MASK would apply, which can be 
derived > from the number of address bits that the IOMMU can handle. The 
SMMU > supports 32 address bits on Tegra30 and Tegra114, 34 address bits 
on > more recent generations. > > I think for now it's safer to leave 
the DMA mask at the default (32 > bit) to avoid the need to distinguish 
between IOMMU and non-IOMMU > devices.

The GPUs after Tegra114 can choose per access whether they're using IOMMU
or not. The interface is 34 bits wide, so the physical addresses can be 
34 bits.
IOMMU addresses are limited by Tegra SMMU to 32-bit for gk20a. gm20b can use
34-bit if SMMU is configured to combine four ASIDs together.



[PATCH] gpu: host1x: Fix MLOCK's debug info

2015-07-02 Thread Terje Bergstrom

On 06/28/2015 12:27 PM, Dmitry Osipenko wrote:
> MLOCK's debug info, spewed on CDMA timeout, contains meaningless MLOCK
> owner channel ID because HOST1X_SYNC_MLOCK_OWNER_CHID_F() returns shifted
> value, while unshifted should be used. Fix it by changing '_F' to '_V'.
>
> Signed-off-by: Dmitry Osipenko 
> ---
>   drivers/gpu/host1x/hw/debug_hw.c | 2 +-
>   drivers/gpu/host1x/hw/hw_host1x01_sync.h | 8 
>   drivers/gpu/host1x/hw/hw_host1x02_sync.h | 8 
>   drivers/gpu/host1x/hw/hw_host1x04_sync.h | 8 
>   4 files changed, 13 insertions(+), 13 deletions(-)
>
> diff --git a/drivers/gpu/host1x/hw/debug_hw.c 
> b/drivers/gpu/host1x/hw/debug_hw.c
> index 791de93..cc3f182 100644
> --- a/drivers/gpu/host1x/hw/debug_hw.c
> +++ b/drivers/gpu/host1x/hw/debug_hw.c
> @@ -298,7 +298,7 @@ static void host1x_debug_show_mlocks(struct host1x *host, 
> struct output *o)
>   host1x_sync_readl(host, HOST1X_SYNC_MLOCK_OWNER(i));
>   if (HOST1X_SYNC_MLOCK_OWNER_CH_OWNS_V(owner))
>   host1x_debug_output(o, "%d: locked by channel %d\n",
> - i, HOST1X_SYNC_MLOCK_OWNER_CHID_F(owner));
> + i, HOST1X_SYNC_MLOCK_OWNER_CHID_V(owner));
>   else if (HOST1X_SYNC_MLOCK_OWNER_CPU_OWNS_V(owner))
>   host1x_debug_output(o, "%d: locked by cpu\n", i);
>   else
(...)

Looks good, and fixes a bad gotcha.

Reviewed-By: Terje Bergstrom 

Terje


[PATCHv9 9/9] drm: tegra: Add gr2d device

2013-03-22 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from
DRM.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|1 +
 drivers/gpu/host1x/dev.c   |7 +
 drivers/gpu/host1x/drm/Kconfig |9 ++
 drivers/gpu/host1x/drm/drm.c   |  212 -
 drivers/gpu/host1x/drm/drm.h   |   27 +++-
 drivers/gpu/host1x/drm/gr2d.c  |  339 
 drivers/gpu/host1x/host1x.h|4 +-
 include/uapi/drm/Kbuild|1 +
 include/uapi/drm/tegra_drm.h   |  136 
 9 files changed, 733 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/uapi/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 3768dbc..3b037b6 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 8ce9889..28e28a2 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -209,11 +209,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif

return 0;

 #ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -226,6 +232,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index f743540..6e3f567 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -13,6 +13,15 @@ config DRM_TEGRA

 if DRM_TEGRA

+config DRM_TEGRA_STAGING
+   bool "Enable HOST1X interface"
+   depends on STAGING
+   default n
+   help
+ Say yes if HOST1X should be available for userspace DRM users.
+
+ If unsure, choose N.
+
 config DRM_TEGRA_DEBUG
bool "NVIDIA Tegra DRM debug support"
help
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index c4e45c1..2b561c9 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +14,9 @@
 #include 
 #include 

+#include 
+#include 
+
 #include "host1x_client.h"
 #include "dev.h"
 #include "drm.h"
@@ -81,8 +84,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -277,9 +282,24 @@ static int tegra_drm_unload(struct drm_device *drm)

 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
+   struct host1x_drm_file *fpriv;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
return 0;
 }

+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+   context->client->ops->close_channel(context);
+   kfree(context);
+}
+
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
struct host1x_drm *host1x = drm->dev_private;
@@ -287,7 +307,190 @@ static void tegra_drm_lastclose(struct drm_device *drm)
tegra_fbdev_restore_mode(host1x->fbdev);
 }

+#ifdef CONFIG_DRM_TEGRA_STAGING
+static bool host1x_drm_file_owns_context(struct host1x_drm_file *file,
+st

[PATCHv9 8/9] gpu: host1x: drm: Add memory manager and fb

2013-03-22 Thread Terje Bergstrom
From: Arto Merilainen 

This patch introduces a memory manager for tegra drm and moves
existing parts to use it. As cma framebuffer helpers can no more
be used, this patch adds also a separate framebuffer driver for
tegra.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|1 +
 drivers/gpu/host1x/drm/Kconfig |8 +-
 drivers/gpu/host1x/drm/dc.c|   23 +--
 drivers/gpu/host1x/drm/drm.c   |   17 +-
 drivers/gpu/host1x/drm/drm.h   |   18 ++-
 drivers/gpu/host1x/drm/fb.c|  336 +++-
 drivers/gpu/host1x/drm/gem.c   |  270 
 drivers/gpu/host1x/drm/gem.h   |   59 +++
 8 files changed, 698 insertions(+), 34 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gem.c
 create mode 100644 drivers/gpu/host1x/drm/gem.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 9a6fc76..3768dbc 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -15,4 +15,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index 7db9b3a..f743540 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -2,11 +2,9 @@ config DRM_TEGRA
bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
select DRM_KMS_HELPER
-   select DRM_GEM_CMA_HELPER
-   select DRM_KMS_CMA_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
+   select FB_SYS_FILLRECT
+   select FB_SYS_COPYAREA
+   select FB_SYS_IMAGEBLIT
help
  Choose this option if you have an NVIDIA Tegra SoC.

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index 29a79b6..85ea616 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -14,9 +14,10 @@
 #include 
 #include 

-#include "drm.h"
-#include "dc.h"
 #include "host1x_client.h"
+#include "dc.h"
+#include "drm.h"
+#include "gem.h"

 struct tegra_plane {
struct drm_plane base;
@@ -52,9 +53,9 @@ static int tegra_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
window.bits_per_pixel = fb->bits_per_pixel;

for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
-   struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, i);
+   struct tegra_bo *bo = tegra_fb_get_plane(fb, i);

-   window.base[i] = gem->paddr + fb->offsets[i];
+   window.base[i] = bo->paddr + fb->offsets[i];

/*
 * Tegra doesn't support different strides for U and V planes
@@ -137,7 +138,7 @@ static int tegra_dc_add_planes(struct drm_device *drm, 
struct tegra_dc *dc)
 static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
 struct drm_framebuffer *fb)
 {
-   struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, 0);
+   struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
unsigned long value;

tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -145,7 +146,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, 
int y,
value = fb->offsets[0] + y * fb->pitches[0] +
x * fb->bits_per_pixel / 8;

-   tegra_dc_writel(dc, gem->paddr + value, DC_WINBUF_START_ADDR);
+   tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);

value = GENERAL_UPDATE | WIN_A_UPDATE;
@@ -187,20 +188,20 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
 {
struct drm_device *drm = dc->base.dev;
struct drm_crtc *crtc = &dc->base;
-   struct drm_gem_cma_object *gem;
unsigned long flags, base;
+   struct tegra_bo *bo;

if (!dc->event)
return;

-   gem = drm_fb_cma_get_gem_obj(crtc->fb, 0);
+   bo = tegra_fb_get_plane(crtc->fb, 0);

/* check if new start address has been latched */
tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);

-   if (base == gem->paddr + crtc->fb->offsets[0]) {
+   if (base == bo->paddr + crtc->fb->offsets[0]) {
spin_lock_irqsave(&drm->event_lock, flags);
drm_send_vblank_event(drm, dc->pipe, dc->event);
drm_vblank_put(drm, dc->pipe);
@@ -570,7 +571,7 @@ static int tegra_crtc_mode_set(

[PATCHv9 7/9] gpu: host1x: Remove second host1x driver

2013-03-22 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x
driver. The logic to parse device tree and track clients is moved
to drm.c.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 ++-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|5 +-
 drivers/gpu/host1x/drm/drm.c   |  214 ++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |5 +-
 drivers/gpu/host1x/drm/host1x.c|  329 
 drivers/gpu/host1x/host1x_client.h |   35 
 10 files changed, 317 insertions(+), 342 deletions(-)
 delete mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 4761e8a..9a6fc76 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -13,6 +13,6 @@ host1x-y = \
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 9689724..8ce9889 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -32,6 +32,19 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   return host1x->drm_data;
+}

 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -150,6 +163,8 @@ static int host1x_probe(struct platform_device *pdev)

host1x_debug_init(host);

+   host1x_drm_alloc(pdev);
+
return 0;

 fail_deinit_syncpt:
@@ -168,7 +183,7 @@ static int __exit host1x_remove(struct platform_device 
*pdev)
return 0;
 }

-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -178,8 +193,47 @@ static struct platform_driver platform_driver = {
},
 };

-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_DRM_TEGRA
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);

+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 4d16fe9..a1607d6 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -124,6 +124,8 @@ struct host1x {
unsigned int num_allocated_channels;

struct dentry *debugfs;
+
+   void *drm_data;
 };

 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -299,4 +301,8 @@ static inline void host1x_hw_show_mlocks(struct host1x 
*host, struct output *o)
host->debug_op->show_mlocks(host, o);
 }

+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index be1daf7..7db9b3a 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
select DRM_KMS_H

[PATCHv9 6/9] gpu: host1x: drm: Rename host1x to host1x_drm

2013-03-22 Thread Terje Bergstrom
From: Arto Merilainen 

Both host1x and drm drivers have host1x structures. This patch
renames the host1x structure under drm to follow name host1x_drm.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/drm/dc.c |4 ++--
 drivers/gpu/host1x/drm/drm.c|4 ++--
 drivers/gpu/host1x/drm/drm.h|   14 +++---
 drivers/gpu/host1x/drm/fb.c |6 +++---
 drivers/gpu/host1x/drm/hdmi.c   |4 ++--
 drivers/gpu/host1x/drm/host1x.c |   22 --
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index de94707..d1f6609 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -1097,7 +1097,7 @@ static const struct host1x_client_ops dc_client_ops = {

 static int tegra_dc_probe(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1160,7 +1160,7 @@ static int tegra_dc_probe(struct platform_device *pdev)

 static int tegra_dc_remove(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;

diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index 9d452df..6c59bcd 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -26,7 +26,7 @@
 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 {
struct device *dev = drm->dev;
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
int err;

host1x = dev_get_drvdata(dev);
@@ -69,7 +69,7 @@ static int tegra_drm_open(struct drm_device *drm, struct 
drm_file *filp)

 static void tegra_drm_lastclose(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index a6c011d..7fedb6c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -18,7 +18,7 @@
 #include 
 #include 

-struct host1x {
+struct host1x_drm {
struct drm_device *drm;
struct device *dev;
void __iomem *regs;
@@ -44,7 +44,7 @@ struct host1x_client_ops {
 };

 struct host1x_client {
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;

const struct host1x_client_ops *ops;
@@ -52,12 +52,12 @@ struct host1x_client {
struct list_head list;
 };

-extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm);
-extern int host1x_drm_exit(struct host1x *host1x);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);

-extern int host1x_register_client(struct host1x *host1x,
+extern int host1x_register_client(struct host1x_drm *host1x,
  struct host1x_client *client);
-extern int host1x_unregister_client(struct host1x *host1x,
+extern int host1x_unregister_client(struct host1x_drm *host1x,
struct host1x_client *client);

 struct tegra_output;
@@ -66,7 +66,7 @@ struct tegra_dc {
struct host1x_client client;
spinlock_t lock;

-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;

struct drm_crtc base;
diff --git a/drivers/gpu/host1x/drm/fb.c b/drivers/gpu/host1x/drm/fb.c
index 0391495..6ed885a 100644
--- a/drivers/gpu/host1x/drm/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -11,7 +11,7 @@

 static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_hotplug_event(host1x->fbdev);
 }
@@ -23,7 +23,7 @@ static const struct drm_mode_config_funcs 
tegra_drm_mode_funcs = {

 int tegra_drm_fb_init(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
struct drm_fbdev_cma *fbdev;

drm->mode_config.min_width = 0;
@@ -46,7 +46,7 @@ int tegra_drm_fb_init(struct drm_device *drm)

 void tegra_drm_fb_exit(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_fini(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index bb747f6..f438f80 100644
--- a/drivers/gpu/host1x/drm/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -1189,7 +1189,7 @@ static const struct

[PATCHv9 5/9] drm: tegra: Move drm to live under host1x

2013-03-22 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |2 ++
 drivers/gpu/host1x/Makefile|5 +
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 16 files changed, 10 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1e82882..9031bb7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -215,8 +215,6 @@ source "drivers/gpu/drm/cirrus/Kconfig"

 source "drivers/gpu/drm/shmobile/Kconfig"

-source "drivers/gpu/drm/tegra/Kconfig"
-
 source "drivers/gpu/drm/omapdrm/Kconfig"

 source "drivers/gpu/drm/tilcdc/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d59b24..847b830 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 00f0859..ee3af1e 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -18,4 +18,6 @@ config TEGRA_HOST1X_FIREWALL

  If unsure, choose Y.

+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 49fd580..4761e8a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -10,4 +10,9 @@ host1x-y = \
debug.o \
hw/host1x01.o

+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 6dd75a2..a6c011d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -7,8 +7,8 @@
  * published by the Free Software Foundation.
  */

-#ifndef TEGRA_DRM_H
-#define TEGRA_

[PATCHv9 4/9] gpu: host1x: Add debug support

2013-03-22 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |4 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |2 +
 drivers/gpu/host1x/hw/channel_hw.c  |   25 +++
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 807 insertions(+)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 06a995b..49fd580 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 33935de..de72172 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -439,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;

+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..3ec7d77
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2013 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
+   va_end(args);
+   o->fn(o->ctx, o->buf, len);
+}
+
+static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo)
+{
+   struct host1x *m = dev_get_drvdata(ch->dev->parent);
+   struct output *o = data;
+
+   mutex_lock(&ch->reflock);
+   if (ch->refcount) {
+   mutex_lock(&ch->cdma.lock);
+   if (show_fifo)
+   host1x_hw_show_channel_fifo(m, ch, o);
+   host1x_hw_show_channel_cdma(m, ch, o);
+   mutex_unlock(&ch->cdma.lock);
+   }
+   mutex_unlock(&ch->reflock);
+
+   return 0;
+}
+
+static void show_syncpts(struct host1x *m, struct output *o)
+{
+   int i;
+   host1x_debug_output(o, " syncpts \n");
+   for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
+   u32 max = host1x_syncpt_read_max(m->syncpt + i);
+   u32 min = host1x_syncpt_load(m->syncpt + i);
+   if (!min && !max)
+   continue;
+   host1x_debug_output(o, "id %d (%s) min %d max %d\n",
+   i, m->syncpt[i].name, min, max);
+   }
+
+   for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
+   u32 base_val;
+   base_val = host1x_syncpt_load_wait_base(m->syncpt + i);
+   if

[PATCHv9 3/9] gpu: host1x: Add channel support

2013-03-22 Thread Terje Bergstrom
Add support for host1x client modules, and host1x channels to submit
work to the clients.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Kconfig  |   12 +
 drivers/gpu/host1x/Makefile |3 +
 drivers/gpu/host1x/cdma.c   |  487 +
 drivers/gpu/host1x/cdma.h   |  100 +
 drivers/gpu/host1x/channel.c|  126 ++
 drivers/gpu/host1x/channel.h|   52 +++
 drivers/gpu/host1x/dev.c|   17 +
 drivers/gpu/host1x/dev.h|  113 +
 drivers/gpu/host1x/host1x.h |   28 ++
 drivers/gpu/host1x/host1x_bo.h  |   87 
 drivers/gpu/host1x/hw/cdma_hw.c |  324 ++
 drivers/gpu/host1x/hw/channel_hw.c  |  143 +++
 drivers/gpu/host1x/hw/host1x01.c|5 +
 drivers/gpu/host1x/hw/host1x01_hardware.h   |  116 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |  102 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|   12 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |  168 
 drivers/gpu/host1x/hw/syncpt_hw.c   |   11 +
 drivers/gpu/host1x/intr.c   |   28 +-
 drivers/gpu/host1x/intr.h   |6 +
 drivers/gpu/host1x/job.c|  603 +++
 drivers/gpu/host1x/job.h|  162 +++
 drivers/gpu/host1x/syncpt.c |   11 +
 drivers/gpu/host1x/syncpt.h |6 +
 include/trace/events/host1x.h   |  211 ++
 25 files changed, 2932 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/cdma.c
 create mode 100644 drivers/gpu/host1x/cdma.h
 create mode 100644 drivers/gpu/host1x/channel.c
 create mode 100644 drivers/gpu/host1x/channel.h
 create mode 100644 drivers/gpu/host1x/host1x.h
 create mode 100644 drivers/gpu/host1x/host1x_bo.h
 create mode 100644 drivers/gpu/host1x/hw/cdma_hw.c
 create mode 100644 drivers/gpu/host1x/hw/channel_hw.c
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_channel.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_uclass.h
 create mode 100644 drivers/gpu/host1x/job.c
 create mode 100644 drivers/gpu/host1x/job.h

diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index c01c450..00f0859 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -7,3 +7,15 @@ config TEGRA_HOST1X
  Tegra's graphics- and multimedia-related modules. The modules served
  by host1x are referred to as clients. host1x includes some other
  functionality, such as synchronization.
+
+if TEGRA_HOST1X
+
+config TEGRA_HOST1X_FIREWALL
+   bool "Enable HOST1X security firewall"
+   default y
+   help
+ Say yes if kernel should protect command streams from tampering.
+
+ If unsure, choose Y.
+
+endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 5ef47ff..06a995b 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -4,6 +4,9 @@ host1x-y = \
syncpt.o \
dev.o \
intr.o \
+   cdma.o \
+   channel.o \
+   job.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
new file mode 100644
index 000..33935de
--- /dev/null
+++ b/drivers/gpu/host1x/cdma.c
@@ -0,0 +1,487 @@
+/*
+ * Tegra host1x Command DMA
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "cdma.h"
+#include "channel.h"
+#include "dev.h"
+#include "debug.h"
+#include "host1x_bo.h"
+#include "job.h"
+
+/*
+ * push_buffer
+ *
+ * The push buffer is a circular array of words to be fetched by command DMA.
+ * Note that it works slightly differently to the sync queue; fence == pos
+ * means that the push buffer is full, not empty.
+ */
+
+#define HOST1X_PUSHBUFFER_SLOTS512
+
+/*
+ * Clean up push buffer resources
+ */
+static void host1x_pushbuffer_destroy(struct push_buffer *pb)
+{
+   struct host1x_cdma *cdma = pb_to_cdma(pb);
+   struct host1x *host1x = cdma_to_host1x(cdma);
+
+   if (pb-

[PATCHv9 2/9] gpu: host1x: Add syncpoint wait and interrupts

2013-03-22 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   12 ++
 drivers/gpu/host1x/dev.h |   51 +
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  143 +
 drivers/gpu/host1x/intr.c|  328 ++
 drivers/gpu/host1x/intr.h|   96 +
 drivers/gpu/host1x/syncpt.c  |  159 +++
 drivers/gpu/host1x/syncpt.h  |   12 ++
 10 files changed, 846 insertions(+)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 0d6002c..b967f6e 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
 #include 

 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"

 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
@@ -123,13 +124,24 @@ static int host1x_probe(struct platform_device *pdev)
return err;
}

+   err = host1x_intr_init(host, syncpt_irq);
+   if (err) {
+   dev_err(&pdev->dev, "failed to initialize interrupts\n");
+   goto fail_deinit_syncpt;
+   }
+
return 0;
+
+fail_deinit_syncpt:
+   host1x_syncpt_deinit(host);
+   return err;
 }

 static int __exit host1x_remove(struct platform_device *pdev)
 {
struct host1x *host = platform_get_drvdata(pdev);

+   host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);

diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index eaf6026..caf9cc6 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -21,6 +21,7 @@
 #include 

 #include "syncpt.h"
+#include "intr.h"

 struct host1x_syncpt;

@@ -33,6 +34,17 @@ struct host1x_syncpt_ops {
int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };

+struct host1x_intr_ops {
+   int (*init_host_sync)(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *work));
+   void (*set_syncpt_threshold)(
+   struct host1x *host, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x *host);
+   int (*free_syncpt_irq)(struct host1x *host);
+};
+
 struct host1x_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -50,7 +62,13 @@ struct host1x {
struct device *dev;
struct clk *clk;

+   struct mutex intr_mutex;
+   struct workqueue_struct *intr_wq;
+   int intr_syncpt_irq;
+
const struct host1x_syncpt_ops *syncpt_op;
+   const struct host1x_intr_ops *intr_op;
+
 };

 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -93,4 +111,37 @@ static inline int host1x_hw_syncpt_patch_wait(struct host1x 
*host,
return host->syncpt_op->patch_wait(sp, patch_addr);
 }

+static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *))
+{
+   return host->intr_op->init_host_sync(host, cpm, syncpt_thresh_work);
+}
+
+static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
+  u32 id, u32 thresh)
+{
+   host->intr_op->set_syncpt_threshold(host, id, thresh);
+}
+
+static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
+u32 id)
+{
+   host->intr_op->enable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
+ u32 id)
+{
+   host->intr_op->disable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
+{
+   host->intr_op->disable_all_syncpt_intrs(host);
+}
+
+static inline int host1x_hw_intr_free_syncpt_irq(struct

[PATCHv9 1/9] gpu: host1x: Add host1x driver

2013-03-22 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D. The Tegra
host1x module is the DMA engine for register access to Tegra's
graphics- and multimedia-related modules. The modules served by
host1x are referred to as clients. host1x includes some other
functionality, such as synchronization.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|9 ++
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  153 +
 drivers/gpu/host1x/dev.h  |   96 +
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   33 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   27 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   74 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  102 ++
 drivers/gpu/host1x/syncpt.c   |  212 +
 drivers/gpu/host1x/syncpt.h   |  147 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 +
 15 files changed, 956 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 30879df..d8a22c2 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..c01c450
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_HOST1X
+   tristate "NVIDIA Tegra host1x driver"
+   help
+ Driver for the NVIDIA Tegra host1x hardware.
+
+ The Tegra host1x module is the DMA engine for register access to
+ Tegra's graphics- and multimedia-related modules. The modules served
+ by host1x are referred to as clients. host1x includes some other
+ functionality, such as synchronization.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..0d6002c
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,153 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#include "dev.h"
+#include "hw/host1x01.h"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static const struct host1x_info host1x01_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_of_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_in

[PATCHv9 0/9] Support Tegra 2D hardware

2013-03-22 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130322 with RTC fixes applied.

Changes in this version:
 * Renaming in drivers/gpu/host1x/drm/drm.c to shorten function names
 * Whitespace and function order fixes
 * An extra struct (host1x_addr_reg) removed
 * Added uapi Kbuild entry

Changes in version 8:
 * Own version of framebuffer driver due to move to own allocator
   * Thanks to Thierry Reding for help
 * Miscellaneous variable name, whitespace and IOCTL interface cleanups
 * Bug fixes:
   * Validator enabled again
   * Added new class 2D strechblit
 * Dropped patch "Support CMA object preallocation"

Changes in version 7:
 * host1x memory data structures refactored
 * Some "nvhost" leftovers renamed to host1x

Changes in version 6:
 * Rebased on latest tegradrm
 * Renamed tegradrm's host1x to host1x_drm
 * Indentation and line split fixed to follow tegradrm convention
 * Pointers to platform_device replaced with pointers to device
 * Added host1x allocator, and wired it in
 * Debug spew code fixed to access mem handles from host1x_job
 * CDMA code doesn't keep the mem handles anymore
 * Push buffer ops have been made generic code
 * Removed the pin_array optimization in host1x_job to simplify code
 * Large number of smaller changes

The driver implements an allocator using the dma mapping API. Each buffer is
assigned an ops structure to operate on it.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page http://http.download.nvidia.com/tegra-public-appnotes/host1x.html
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

The changes to add support to libdrm are in
git at gitorious.org:linux-host1x/libdrm-host1x.git

Arto Merilainen (2):
  gpu: host1x: drm: Rename host1x to host1x_drm
  gpu: host1x: drm: Add memory manager and fb

Terje Bergstrom (7):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  drm: tegra: Add gr2d device

 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  217 
 drivers/gpu/drm/tegra/fb.c |   52 --
 drivers/gpu/drm/tegra/host1x.c |  327 
 drivers/gpu/host1x/Kconfig |   23 +
 drivers/gpu/host1x/Makefile|   20 +
 drivers/gpu/host1x/cdma.c  |  491 ++
 drivers/gpu/host1x/cdma.h  |  100 
 drivers/gpu/host1x/channel.c   |  126 +
 drivers/gpu/host1x/channel.h   |   52 ++
 drivers/gpu/host1x/debug.c |  210 
 drivers/gpu/host1x/debug.h |   51 ++
 drivers/gpu/host1x/dev.c   |  246 +
 drivers/gpu/host1x/dev.h   |  308 
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |   19 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |   26 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  640 
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   68 ++-
 drivers/gpu/host1x/drm/fb.c|  372 ++
 drivers/gpu/host1x/drm/gem.c   |  270 ++
 drivers/gpu/host1x/drm/gem.h   |   59 +++
 drivers/gpu/host1x/drm/gr2d.c  |  339 +
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   30 ++
 drivers/gpu/host1x/host1x_bo.h |   87 
 drivers/gpu/host1x/host1x_client.h |   35 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  326 
 drivers/gpu/host1x/hw/channel_hw.c |  168 +++
 drivers/gpu/host1x/hw/debug_hw.c   |  322 
 drivers/gpu/host1x/hw/hos

[PATCHv8 9/9] drm: tegra: Add gr2d device

2013-03-22 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from
DRM.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|1 +
 drivers/gpu/host1x/dev.c   |7 +
 drivers/gpu/host1x/drm/Kconfig |9 ++
 drivers/gpu/host1x/drm/drm.c   |  213 -
 drivers/gpu/host1x/drm/drm.h   |   27 +++-
 drivers/gpu/host1x/drm/gr2d.c  |  340 
 drivers/gpu/host1x/host1x.h|4 +-
 include/uapi/drm/tegra_drm.h   |  136 
 8 files changed, 734 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/uapi/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 3768dbc..3b037b6 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 8ce9889..28e28a2 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -209,11 +209,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif

return 0;

 #ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -226,6 +232,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index f743540..6e3f567 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -13,6 +13,15 @@ config DRM_TEGRA

 if DRM_TEGRA

+config DRM_TEGRA_STAGING
+   bool "Enable HOST1X interface"
+   depends on STAGING
+   default n
+   help
+ Say yes if HOST1X should be available for userspace DRM users.
+
+ If unsure, choose N.
+
 config DRM_TEGRA_DEBUG
bool "NVIDIA Tegra DRM debug support"
help
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index c4e45c1..6db1bd6 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +14,11 @@
 #include 
 #include 

+#include 
+#include 
+
+#include 
+
 #include "host1x_client.h"
 #include "dev.h"
 #include "drm.h"
@@ -81,8 +86,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -277,9 +284,24 @@ static int tegra_drm_unload(struct drm_device *drm)

 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
+   struct host1x_drm_file *fpriv;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
return 0;
 }

+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+   context->client->ops->close_channel(context);
+   kfree(context);
+}
+
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
struct host1x_drm *host1x = drm->dev_private;
@@ -287,7 +309,189 @@ static void tegra_drm_lastclose(struct drm_device *drm)
tegra_fbdev_restore_mode(host1x->fbdev);
 }

+#ifdef CONFIG_DRM_TEGRA_STAGING
+static int tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+  struct drm_file *file)

[PATCHv8 8/9] gpu: host1x: drm: Add memory manager and fb

2013-03-22 Thread Terje Bergstrom
From: Arto Merilainen 

This patch introduces a memory manager for tegra drm and moves
existing parts to use it. As cma framebuffer helpers can no more
be used, this patch adds also a separate framebuffer driver for
tegra.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|1 +
 drivers/gpu/host1x/drm/Kconfig |8 +-
 drivers/gpu/host1x/drm/dc.c|   23 +--
 drivers/gpu/host1x/drm/drm.c   |   17 +-
 drivers/gpu/host1x/drm/drm.h   |   18 ++-
 drivers/gpu/host1x/drm/fb.c|  338 +++-
 drivers/gpu/host1x/drm/gem.c   |  270 
 drivers/gpu/host1x/drm/gem.h   |   59 +++
 8 files changed, 700 insertions(+), 34 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gem.c
 create mode 100644 drivers/gpu/host1x/drm/gem.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 9a6fc76..3768dbc 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -15,4 +15,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index 7db9b3a..f743540 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -2,11 +2,9 @@ config DRM_TEGRA
bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
select DRM_KMS_HELPER
-   select DRM_GEM_CMA_HELPER
-   select DRM_KMS_CMA_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
+   select FB_SYS_FILLRECT
+   select FB_SYS_COPYAREA
+   select FB_SYS_IMAGEBLIT
help
  Choose this option if you have an NVIDIA Tegra SoC.

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index 29a79b6..85ea616 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -14,9 +14,10 @@
 #include 
 #include 

-#include "drm.h"
-#include "dc.h"
 #include "host1x_client.h"
+#include "dc.h"
+#include "drm.h"
+#include "gem.h"

 struct tegra_plane {
struct drm_plane base;
@@ -52,9 +53,9 @@ static int tegra_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
window.bits_per_pixel = fb->bits_per_pixel;

for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
-   struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, i);
+   struct tegra_bo *bo = tegra_fb_get_plane(fb, i);

-   window.base[i] = gem->paddr + fb->offsets[i];
+   window.base[i] = bo->paddr + fb->offsets[i];

/*
 * Tegra doesn't support different strides for U and V planes
@@ -137,7 +138,7 @@ static int tegra_dc_add_planes(struct drm_device *drm, 
struct tegra_dc *dc)
 static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
 struct drm_framebuffer *fb)
 {
-   struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, 0);
+   struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
unsigned long value;

tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -145,7 +146,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, 
int y,
value = fb->offsets[0] + y * fb->pitches[0] +
x * fb->bits_per_pixel / 8;

-   tegra_dc_writel(dc, gem->paddr + value, DC_WINBUF_START_ADDR);
+   tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);

value = GENERAL_UPDATE | WIN_A_UPDATE;
@@ -187,20 +188,20 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
 {
struct drm_device *drm = dc->base.dev;
struct drm_crtc *crtc = &dc->base;
-   struct drm_gem_cma_object *gem;
unsigned long flags, base;
+   struct tegra_bo *bo;

if (!dc->event)
return;

-   gem = drm_fb_cma_get_gem_obj(crtc->fb, 0);
+   bo = tegra_fb_get_plane(crtc->fb, 0);

/* check if new start address has been latched */
tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);

-   if (base == gem->paddr + crtc->fb->offsets[0]) {
+   if (base == bo->paddr + crtc->fb->offsets[0]) {
spin_lock_irqsave(&drm->event_lock, flags);
drm_send_vblank_event(drm, dc->pipe, dc->event);
drm_vblank_put(drm, dc->pipe);
@@ -570,7 +571,7 @@ static int tegra_crtc_mode_set(

[PATCHv8 7/9] gpu: host1x: Remove second host1x driver

2013-03-22 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x
driver. The logic to parse device tree and track clients is moved
to drm.c.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 ++-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|5 +-
 drivers/gpu/host1x/drm/drm.c   |  214 ++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |5 +-
 drivers/gpu/host1x/drm/host1x.c|  329 
 drivers/gpu/host1x/host1x_client.h |   35 
 10 files changed, 317 insertions(+), 342 deletions(-)
 delete mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 4761e8a..9a6fc76 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -13,6 +13,6 @@ host1x-y = \
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 9689724..8ce9889 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -32,6 +32,19 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   return host1x->drm_data;
+}

 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -150,6 +163,8 @@ static int host1x_probe(struct platform_device *pdev)

host1x_debug_init(host);

+   host1x_drm_alloc(pdev);
+
return 0;

 fail_deinit_syncpt:
@@ -168,7 +183,7 @@ static int __exit host1x_remove(struct platform_device 
*pdev)
return 0;
 }

-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -178,8 +193,47 @@ static struct platform_driver platform_driver = {
},
 };

-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_DRM_TEGRA
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);

+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 4d16fe9..a1607d6 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -124,6 +124,8 @@ struct host1x {
unsigned int num_allocated_channels;

struct dentry *debugfs;
+
+   void *drm_data;
 };

 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -299,4 +301,8 @@ static inline void host1x_hw_show_mlocks(struct host1x 
*host, struct output *o)
host->debug_op->show_mlocks(host, o);
 }

+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index be1daf7..7db9b3a 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
select DRM_KMS_H

[PATCHv8 6/9] gpu: host1x: drm: Rename host1x to host1x_drm

2013-03-22 Thread Terje Bergstrom
From: Arto Merilainen 

Both host1x and drm drivers have host1x structures. This patch
renames the host1x structure under drm to follow name host1x_drm.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/drm/dc.c |4 ++--
 drivers/gpu/host1x/drm/drm.c|4 ++--
 drivers/gpu/host1x/drm/drm.h|   14 +++---
 drivers/gpu/host1x/drm/fb.c |6 +++---
 drivers/gpu/host1x/drm/hdmi.c   |4 ++--
 drivers/gpu/host1x/drm/host1x.c |   22 --
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index de94707..d1f6609 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -1097,7 +1097,7 @@ static const struct host1x_client_ops dc_client_ops = {

 static int tegra_dc_probe(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1160,7 +1160,7 @@ static int tegra_dc_probe(struct platform_device *pdev)

 static int tegra_dc_remove(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;

diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index 9d452df..6c59bcd 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -26,7 +26,7 @@
 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 {
struct device *dev = drm->dev;
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
int err;

host1x = dev_get_drvdata(dev);
@@ -69,7 +69,7 @@ static int tegra_drm_open(struct drm_device *drm, struct 
drm_file *filp)

 static void tegra_drm_lastclose(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index a6c011d..7fedb6c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -18,7 +18,7 @@
 #include 
 #include 

-struct host1x {
+struct host1x_drm {
struct drm_device *drm;
struct device *dev;
void __iomem *regs;
@@ -44,7 +44,7 @@ struct host1x_client_ops {
 };

 struct host1x_client {
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;

const struct host1x_client_ops *ops;
@@ -52,12 +52,12 @@ struct host1x_client {
struct list_head list;
 };

-extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm);
-extern int host1x_drm_exit(struct host1x *host1x);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);

-extern int host1x_register_client(struct host1x *host1x,
+extern int host1x_register_client(struct host1x_drm *host1x,
  struct host1x_client *client);
-extern int host1x_unregister_client(struct host1x *host1x,
+extern int host1x_unregister_client(struct host1x_drm *host1x,
struct host1x_client *client);

 struct tegra_output;
@@ -66,7 +66,7 @@ struct tegra_dc {
struct host1x_client client;
spinlock_t lock;

-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;

struct drm_crtc base;
diff --git a/drivers/gpu/host1x/drm/fb.c b/drivers/gpu/host1x/drm/fb.c
index 0391495..6ed885a 100644
--- a/drivers/gpu/host1x/drm/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -11,7 +11,7 @@

 static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_hotplug_event(host1x->fbdev);
 }
@@ -23,7 +23,7 @@ static const struct drm_mode_config_funcs 
tegra_drm_mode_funcs = {

 int tegra_drm_fb_init(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
struct drm_fbdev_cma *fbdev;

drm->mode_config.min_width = 0;
@@ -46,7 +46,7 @@ int tegra_drm_fb_init(struct drm_device *drm)

 void tegra_drm_fb_exit(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_fini(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index bb747f6..f438f80 100644
--- a/drivers/gpu/host1x/drm/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -1189,7 +1189,7 @@ static const struct

[PATCHv8 5/9] drm: tegra: Move drm to live under host1x

2013-03-22 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |2 ++
 drivers/gpu/host1x/Makefile|5 +
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 16 files changed, 10 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1e82882..9031bb7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -215,8 +215,6 @@ source "drivers/gpu/drm/cirrus/Kconfig"

 source "drivers/gpu/drm/shmobile/Kconfig"

-source "drivers/gpu/drm/tegra/Kconfig"
-
 source "drivers/gpu/drm/omapdrm/Kconfig"

 source "drivers/gpu/drm/tilcdc/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d59b24..847b830 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 00f0859..ee3af1e 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -18,4 +18,6 @@ config TEGRA_HOST1X_FIREWALL

  If unsure, choose Y.

+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 49fd580..4761e8a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -10,4 +10,9 @@ host1x-y = \
debug.o \
hw/host1x01.o

+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 6dd75a2..a6c011d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -7,8 +7,8 @@
  * published by the Free Software Foundation.
  */

-#ifndef TEGRA_DRM_H
-#define TEGRA_

[PATCHv8 4/9] gpu: host1x: Add debug support

2013-03-22 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |4 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |2 +
 drivers/gpu/host1x/hw/channel_hw.c  |   25 +++
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 807 insertions(+)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 06a995b..49fd580 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 33935de..de72172 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -439,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;

+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..3ec7d77
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2013 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
+   va_end(args);
+   o->fn(o->ctx, o->buf, len);
+}
+
+static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo)
+{
+   struct host1x *m = dev_get_drvdata(ch->dev->parent);
+   struct output *o = data;
+
+   mutex_lock(&ch->reflock);
+   if (ch->refcount) {
+   mutex_lock(&ch->cdma.lock);
+   if (show_fifo)
+   host1x_hw_show_channel_fifo(m, ch, o);
+   host1x_hw_show_channel_cdma(m, ch, o);
+   mutex_unlock(&ch->cdma.lock);
+   }
+   mutex_unlock(&ch->reflock);
+
+   return 0;
+}
+
+static void show_syncpts(struct host1x *m, struct output *o)
+{
+   int i;
+   host1x_debug_output(o, " syncpts \n");
+   for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
+   u32 max = host1x_syncpt_read_max(m->syncpt + i);
+   u32 min = host1x_syncpt_load(m->syncpt + i);
+   if (!min && !max)
+   continue;
+   host1x_debug_output(o, "id %d (%s) min %d max %d\n",
+   i, m->syncpt[i].name, min, max);
+   }
+
+   for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
+   u32 base_val;
+   base_val = host1x_syncpt_load_wait_base(m->syncpt + i);
+   if

[PATCHv8 3/9] gpu: host1x: Add channel support

2013-03-22 Thread Terje Bergstrom
Add support for host1x client modules, and host1x channels to submit
work to the clients.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Kconfig  |   12 +
 drivers/gpu/host1x/Makefile |3 +
 drivers/gpu/host1x/cdma.c   |  487 +
 drivers/gpu/host1x/cdma.h   |  100 +
 drivers/gpu/host1x/channel.c|  126 ++
 drivers/gpu/host1x/channel.h|   52 +++
 drivers/gpu/host1x/dev.c|   17 +
 drivers/gpu/host1x/dev.h|  113 +
 drivers/gpu/host1x/host1x.h |   28 ++
 drivers/gpu/host1x/host1x_bo.h  |   87 
 drivers/gpu/host1x/hw/cdma_hw.c |  324 ++
 drivers/gpu/host1x/hw/channel_hw.c  |  143 +++
 drivers/gpu/host1x/hw/host1x01.c|5 +
 drivers/gpu/host1x/hw/host1x01_hardware.h   |  116 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |  102 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|   12 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |  168 
 drivers/gpu/host1x/hw/syncpt_hw.c   |   11 +
 drivers/gpu/host1x/intr.c   |   28 +-
 drivers/gpu/host1x/intr.h   |6 +
 drivers/gpu/host1x/job.c|  603 +++
 drivers/gpu/host1x/job.h|  167 
 drivers/gpu/host1x/syncpt.c |   11 +
 drivers/gpu/host1x/syncpt.h |6 +
 include/trace/events/host1x.h   |  211 ++
 25 files changed, 2937 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/cdma.c
 create mode 100644 drivers/gpu/host1x/cdma.h
 create mode 100644 drivers/gpu/host1x/channel.c
 create mode 100644 drivers/gpu/host1x/channel.h
 create mode 100644 drivers/gpu/host1x/host1x.h
 create mode 100644 drivers/gpu/host1x/host1x_bo.h
 create mode 100644 drivers/gpu/host1x/hw/cdma_hw.c
 create mode 100644 drivers/gpu/host1x/hw/channel_hw.c
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_channel.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_uclass.h
 create mode 100644 drivers/gpu/host1x/job.c
 create mode 100644 drivers/gpu/host1x/job.h

diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index c01c450..00f0859 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -7,3 +7,15 @@ config TEGRA_HOST1X
  Tegra's graphics- and multimedia-related modules. The modules served
  by host1x are referred to as clients. host1x includes some other
  functionality, such as synchronization.
+
+if TEGRA_HOST1X
+
+config TEGRA_HOST1X_FIREWALL
+   bool "Enable HOST1X security firewall"
+   default y
+   help
+ Say yes if kernel should protect command streams from tampering.
+
+ If unsure, choose Y.
+
+endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 5ef47ff..06a995b 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -4,6 +4,9 @@ host1x-y = \
syncpt.o \
dev.o \
intr.o \
+   cdma.o \
+   channel.o \
+   job.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
new file mode 100644
index 000..33935de
--- /dev/null
+++ b/drivers/gpu/host1x/cdma.c
@@ -0,0 +1,487 @@
+/*
+ * Tegra host1x Command DMA
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "cdma.h"
+#include "channel.h"
+#include "dev.h"
+#include "debug.h"
+#include "host1x_bo.h"
+#include "job.h"
+
+/*
+ * push_buffer
+ *
+ * The push buffer is a circular array of words to be fetched by command DMA.
+ * Note that it works slightly differently to the sync queue; fence == pos
+ * means that the push buffer is full, not empty.
+ */
+
+#define HOST1X_PUSHBUFFER_SLOTS512
+
+/*
+ * Clean up push buffer resources
+ */
+static void host1x_pushbuffer_destroy(struct push_buffer *pb)
+{
+   struct host1x_cdma *cdma = pb_to_cdma(pb);
+   struct host1x *host1x = cdma_to_host1x(cdma);
+
+   if (pb-

[PATCHv8 2/9] gpu: host1x: Add syncpoint wait and interrupts

2013-03-22 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   12 ++
 drivers/gpu/host1x/dev.h |   51 +
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  143 +
 drivers/gpu/host1x/intr.c|  328 ++
 drivers/gpu/host1x/intr.h|   96 +
 drivers/gpu/host1x/syncpt.c  |  159 +++
 drivers/gpu/host1x/syncpt.h  |   12 ++
 10 files changed, 846 insertions(+)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 0d6002c..b967f6e 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
 #include 

 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"

 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
@@ -123,13 +124,24 @@ static int host1x_probe(struct platform_device *pdev)
return err;
}

+   err = host1x_intr_init(host, syncpt_irq);
+   if (err) {
+   dev_err(&pdev->dev, "failed to initialize interrupts\n");
+   goto fail_deinit_syncpt;
+   }
+
return 0;
+
+fail_deinit_syncpt:
+   host1x_syncpt_deinit(host);
+   return err;
 }

 static int __exit host1x_remove(struct platform_device *pdev)
 {
struct host1x *host = platform_get_drvdata(pdev);

+   host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);

diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index eaf6026..caf9cc6 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -21,6 +21,7 @@
 #include 

 #include "syncpt.h"
+#include "intr.h"

 struct host1x_syncpt;

@@ -33,6 +34,17 @@ struct host1x_syncpt_ops {
int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };

+struct host1x_intr_ops {
+   int (*init_host_sync)(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *work));
+   void (*set_syncpt_threshold)(
+   struct host1x *host, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x *host);
+   int (*free_syncpt_irq)(struct host1x *host);
+};
+
 struct host1x_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -50,7 +62,13 @@ struct host1x {
struct device *dev;
struct clk *clk;

+   struct mutex intr_mutex;
+   struct workqueue_struct *intr_wq;
+   int intr_syncpt_irq;
+
const struct host1x_syncpt_ops *syncpt_op;
+   const struct host1x_intr_ops *intr_op;
+
 };

 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -93,4 +111,37 @@ static inline int host1x_hw_syncpt_patch_wait(struct host1x 
*host,
return host->syncpt_op->patch_wait(sp, patch_addr);
 }

+static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *))
+{
+   return host->intr_op->init_host_sync(host, cpm, syncpt_thresh_work);
+}
+
+static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
+  u32 id, u32 thresh)
+{
+   host->intr_op->set_syncpt_threshold(host, id, thresh);
+}
+
+static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
+u32 id)
+{
+   host->intr_op->enable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
+ u32 id)
+{
+   host->intr_op->disable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
+{
+   host->intr_op->disable_all_syncpt_intrs(host);
+}
+
+static inline int host1x_hw_intr_free_syncpt_irq(struct

[PATCHv8 1/9] gpu: host1x: Add host1x driver

2013-03-22 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D. The Tegra
host1x module is the DMA engine for register access to Tegra's
graphics- and multimedia-related modules. The modules served by
host1x are referred to as clients. host1x includes some other
functionality, such as synchronization.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|9 ++
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  153 +
 drivers/gpu/host1x/dev.h  |   96 +
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   33 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   27 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   74 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  102 ++
 drivers/gpu/host1x/syncpt.c   |  212 +
 drivers/gpu/host1x/syncpt.h   |  147 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 +
 15 files changed, 956 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 30879df..d8a22c2 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..c01c450
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_HOST1X
+   tristate "NVIDIA Tegra host1x driver"
+   help
+ Driver for the NVIDIA Tegra host1x hardware.
+
+ The Tegra host1x module is the DMA engine for register access to
+ Tegra's graphics- and multimedia-related modules. The modules served
+ by host1x are referred to as clients. host1x includes some other
+ functionality, such as synchronization.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..0d6002c
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,153 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#include "dev.h"
+#include "hw/host1x01.h"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static const struct host1x_info host1x01_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_of_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_in

[PATCHv8 0/9] Support for Tegra 2D hardware

2013-03-22 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130322 with RTC fixes applied.

Changes in this version:
 * Own version of framebuffer driver due to move to own allocator
   * Thanks to Thierry Reding for help
 * Miscellaneous variable name, whitespace and IOCTL interface cleanups
 * Bug fixes:
   * Validator enabled again
   * Added new class 2D strechblit
 * Dropped patch "Support CMA object preallocation"

Changes in version 7:
 * host1x memory data structures refactored
 * Some "nvhost" leftovers renamed to host1x

Changes in version 6:
 * Rebased on latest tegradrm
 * Renamed tegradrm's host1x to host1x_drm
 * Indentation and line split fixed to follow tegradrm convention
 * Pointers to platform_device replaced with pointers to device
 * Added host1x allocator, and wired it in
 * Debug spew code fixed to access mem handles from host1x_job
 * CDMA code doesn't keep the mem handles anymore
 * Push buffer ops have been made generic code
 * Removed the pin_array optimization in host1x_job to simplify code
 * Large number of smaller changes

The driver implements an allocator using the dma mapping API. Each buffer is
assigned an ops structure to operate on it.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page http://http.download.nvidia.com/tegra-public-appnotes/host1x.html
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

The changes to add support to libdrm are in
git at gitorious.org:linux-host1x/libdrm-host1x.git

Arto Merilainen (2):
  gpu: host1x: drm: Rename host1x to host1x_drm
  gpu: host1x: drm: Add memory manager and fb

Terje Bergstrom (7):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  drm: tegra: Add gr2d device

 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  217 
 drivers/gpu/drm/tegra/fb.c |   52 --
 drivers/gpu/drm/tegra/host1x.c |  327 
 drivers/gpu/host1x/Kconfig |   23 +
 drivers/gpu/host1x/Makefile|   20 +
 drivers/gpu/host1x/cdma.c  |  491 ++
 drivers/gpu/host1x/cdma.h  |  100 
 drivers/gpu/host1x/channel.c   |  126 +
 drivers/gpu/host1x/channel.h   |   52 ++
 drivers/gpu/host1x/debug.c |  210 
 drivers/gpu/host1x/debug.h |   51 ++
 drivers/gpu/host1x/dev.c   |  246 +
 drivers/gpu/host1x/dev.h   |  308 
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |   19 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |   26 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  641 
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   68 ++-
 drivers/gpu/host1x/drm/fb.c|  374 ++
 drivers/gpu/host1x/drm/gem.c   |  270 ++
 drivers/gpu/host1x/drm/gem.h   |   59 +++
 drivers/gpu/host1x/drm/gr2d.c  |  340 +
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   30 ++
 drivers/gpu/host1x/host1x_bo.h |   87 
 drivers/gpu/host1x/host1x_client.h |   35 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  326 
 drivers/gpu/host1x/hw/channel_hw.c |  168 +++
 drivers/gpu/host1x/hw/debug_hw.c   |  322 
 drivers/gpu/host1x/hw/host1x01.c   |   42 ++
 drivers/gpu/host1x/hw/host1x01.h   |   25 +
 drivers/gpu/host1x/hw/host1x01_hardware.h  |  143 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h

[PATCHv9 7/9] gpu: host1x: Remove second host1x driver

2013-03-22 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x
driver. The logic to parse device tree and track clients is moved
to drm.c.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 ++-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|5 +-
 drivers/gpu/host1x/drm/drm.c   |  214 ++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |5 +-
 drivers/gpu/host1x/drm/host1x.c|  329 
 drivers/gpu/host1x/host1x_client.h |   35 
 10 files changed, 317 insertions(+), 342 deletions(-)
 delete mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 4761e8a..9a6fc76 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -13,6 +13,6 @@ host1x-y = \
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 9689724..8ce9889 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -32,6 +32,19 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   return host1x->drm_data;
+}
 
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -150,6 +163,8 @@ static int host1x_probe(struct platform_device *pdev)
 
host1x_debug_init(host);
 
+   host1x_drm_alloc(pdev);
+
return 0;
 
 fail_deinit_syncpt:
@@ -168,7 +183,7 @@ static int __exit host1x_remove(struct platform_device 
*pdev)
return 0;
 }
 
-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -178,8 +193,47 @@ static struct platform_driver platform_driver = {
},
 };
 
-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_DRM_TEGRA
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);
 
+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 4d16fe9..a1607d6 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -124,6 +124,8 @@ struct host1x {
unsigned int num_allocated_channels;
 
struct dentry *debugfs;
+
+   void *drm_data;
 };
 
 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -299,4 +301,8 @@ static inline void host1x_hw_show_mlocks(struct host1x 
*host, struct output *o)
host->debug_op->show_mlocks(host, o);
 }
 
+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index be1daf7..7db9b3a 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
selec

[PATCHv9 9/9] drm: tegra: Add gr2d device

2013-03-22 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from
DRM.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|1 +
 drivers/gpu/host1x/dev.c   |7 +
 drivers/gpu/host1x/drm/Kconfig |9 ++
 drivers/gpu/host1x/drm/drm.c   |  212 -
 drivers/gpu/host1x/drm/drm.h   |   27 +++-
 drivers/gpu/host1x/drm/gr2d.c  |  339 
 drivers/gpu/host1x/host1x.h|4 +-
 include/uapi/drm/Kbuild|1 +
 include/uapi/drm/tegra_drm.h   |  136 
 9 files changed, 733 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/uapi/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 3768dbc..3b037b6 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 8ce9889..28e28a2 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -209,11 +209,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif
 
return 0;
 
 #ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -226,6 +232,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index f743540..6e3f567 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -13,6 +13,15 @@ config DRM_TEGRA
 
 if DRM_TEGRA
 
+config DRM_TEGRA_STAGING
+   bool "Enable HOST1X interface"
+   depends on STAGING
+   default n
+   help
+ Say yes if HOST1X should be available for userspace DRM users.
+
+ If unsure, choose N.
+
 config DRM_TEGRA_DEBUG
bool "NVIDIA Tegra DRM debug support"
help
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index c4e45c1..2b561c9 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +14,9 @@
 #include 
 #include 
 
+#include 
+#include 
+
 #include "host1x_client.h"
 #include "dev.h"
 #include "drm.h"
@@ -81,8 +84,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -277,9 +282,24 @@ static int tegra_drm_unload(struct drm_device *drm)
 
 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
+   struct host1x_drm_file *fpriv;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
return 0;
 }
 
+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+   context->client->ops->close_channel(context);
+   kfree(context);
+}
+
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
struct host1x_drm *host1x = drm->dev_private;
@@ -287,7 +307,190 @@ static void tegra_drm_lastclose(struct drm_device *drm)
tegra_fbdev_restore_mode(host1x->fbdev);
 }
 
+#ifdef CONFIG_DRM_TEGRA_STAGING
+static bool host1x_drm_file_owns_context(struct host1x_drm_file *file,
+   

[PATCHv9 4/9] gpu: host1x: Add debug support

2013-03-22 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |4 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |2 +
 drivers/gpu/host1x/hw/channel_hw.c  |   25 +++
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 807 insertions(+)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 06a995b..49fd580 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
hw/host1x01.o
 
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 33935de..de72172 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -439,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;
 
+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..3ec7d77
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2013 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
+   va_end(args);
+   o->fn(o->ctx, o->buf, len);
+}
+
+static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo)
+{
+   struct host1x *m = dev_get_drvdata(ch->dev->parent);
+   struct output *o = data;
+
+   mutex_lock(&ch->reflock);
+   if (ch->refcount) {
+   mutex_lock(&ch->cdma.lock);
+   if (show_fifo)
+   host1x_hw_show_channel_fifo(m, ch, o);
+   host1x_hw_show_channel_cdma(m, ch, o);
+   mutex_unlock(&ch->cdma.lock);
+   }
+   mutex_unlock(&ch->reflock);
+
+   return 0;
+}
+
+static void show_syncpts(struct host1x *m, struct output *o)
+{
+   int i;
+   host1x_debug_output(o, " syncpts \n");
+   for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
+   u32 max = host1x_syncpt_read_max(m->syncpt + i);
+   u32 min = host1x_syncpt_load(m->syncpt + i);
+   if (!min && !max)
+   continue;
+   host1x_debug_output(o, "id %d (%s) min %d max %d\n",
+   i, m->syncpt[i].name, min, max);
+   }
+
+   for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
+   u32 base_val;
+   base_val = host1x_syncpt_load_wait_base(m->syncpt + i);
+   if

[PATCHv9 8/9] gpu: host1x: drm: Add memory manager and fb

2013-03-22 Thread Terje Bergstrom
From: Arto Merilainen 

This patch introduces a memory manager for tegra drm and moves
existing parts to use it. As cma framebuffer helpers can no more
be used, this patch adds also a separate framebuffer driver for
tegra.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|1 +
 drivers/gpu/host1x/drm/Kconfig |8 +-
 drivers/gpu/host1x/drm/dc.c|   23 +--
 drivers/gpu/host1x/drm/drm.c   |   17 +-
 drivers/gpu/host1x/drm/drm.h   |   18 ++-
 drivers/gpu/host1x/drm/fb.c|  336 +++-
 drivers/gpu/host1x/drm/gem.c   |  270 
 drivers/gpu/host1x/drm/gem.h   |   59 +++
 8 files changed, 698 insertions(+), 34 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gem.c
 create mode 100644 drivers/gpu/host1x/drm/gem.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 9a6fc76..3768dbc 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -15,4 +15,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index 7db9b3a..f743540 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -2,11 +2,9 @@ config DRM_TEGRA
bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
select DRM_KMS_HELPER
-   select DRM_GEM_CMA_HELPER
-   select DRM_KMS_CMA_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
+   select FB_SYS_FILLRECT
+   select FB_SYS_COPYAREA
+   select FB_SYS_IMAGEBLIT
help
  Choose this option if you have an NVIDIA Tegra SoC.
 
diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index 29a79b6..85ea616 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -14,9 +14,10 @@
 #include 
 #include 
 
-#include "drm.h"
-#include "dc.h"
 #include "host1x_client.h"
+#include "dc.h"
+#include "drm.h"
+#include "gem.h"
 
 struct tegra_plane {
struct drm_plane base;
@@ -52,9 +53,9 @@ static int tegra_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
window.bits_per_pixel = fb->bits_per_pixel;
 
for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
-   struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, i);
+   struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
 
-   window.base[i] = gem->paddr + fb->offsets[i];
+   window.base[i] = bo->paddr + fb->offsets[i];
 
/*
 * Tegra doesn't support different strides for U and V planes
@@ -137,7 +138,7 @@ static int tegra_dc_add_planes(struct drm_device *drm, 
struct tegra_dc *dc)
 static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
 struct drm_framebuffer *fb)
 {
-   struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, 0);
+   struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
unsigned long value;
 
tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -145,7 +146,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, 
int y,
value = fb->offsets[0] + y * fb->pitches[0] +
x * fb->bits_per_pixel / 8;
 
-   tegra_dc_writel(dc, gem->paddr + value, DC_WINBUF_START_ADDR);
+   tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
 
value = GENERAL_UPDATE | WIN_A_UPDATE;
@@ -187,20 +188,20 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
 {
struct drm_device *drm = dc->base.dev;
struct drm_crtc *crtc = &dc->base;
-   struct drm_gem_cma_object *gem;
unsigned long flags, base;
+   struct tegra_bo *bo;
 
if (!dc->event)
return;
 
-   gem = drm_fb_cma_get_gem_obj(crtc->fb, 0);
+   bo = tegra_fb_get_plane(crtc->fb, 0);
 
/* check if new start address has been latched */
tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
 
-   if (base == gem->paddr + crtc->fb->offsets[0]) {
+   if (base == bo->paddr + crtc->fb->offsets[0]) {
spin_lock_irqsave(&drm->event_lock, flags);
drm_send_vblank_event(drm, dc->pipe, dc->event);
drm_vblank_put(drm, dc->pipe);
@@ -570,7 +571,7 @@ static int tegra_crtc_mode_set(

[PATCHv9 5/9] drm: tegra: Move drm to live under host1x

2013-03-22 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |2 ++
 drivers/gpu/host1x/Makefile|5 +
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 16 files changed, 10 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1e82882..9031bb7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -215,8 +215,6 @@ source "drivers/gpu/drm/cirrus/Kconfig"
 
 source "drivers/gpu/drm/shmobile/Kconfig"
 
-source "drivers/gpu/drm/tegra/Kconfig"
-
 source "drivers/gpu/drm/omapdrm/Kconfig"
 
 source "drivers/gpu/drm/tilcdc/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d59b24..847b830 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 00f0859..ee3af1e 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -18,4 +18,6 @@ config TEGRA_HOST1X_FIREWALL
 
  If unsure, choose Y.
 
+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 49fd580..4761e8a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -10,4 +10,9 @@ host1x-y = \
debug.o \
hw/host1x01.o
 
+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 6dd75a2..a6c011d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -7,8 +7,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef TEGRA_DRM_H
-#define TEGRA_D

[PATCHv9 6/9] gpu: host1x: drm: Rename host1x to host1x_drm

2013-03-22 Thread Terje Bergstrom
From: Arto Merilainen 

Both host1x and drm drivers have host1x structures. This patch
renames the host1x structure under drm to follow name host1x_drm.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/drm/dc.c |4 ++--
 drivers/gpu/host1x/drm/drm.c|4 ++--
 drivers/gpu/host1x/drm/drm.h|   14 +++---
 drivers/gpu/host1x/drm/fb.c |6 +++---
 drivers/gpu/host1x/drm/hdmi.c   |4 ++--
 drivers/gpu/host1x/drm/host1x.c |   22 --
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index de94707..d1f6609 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -1097,7 +1097,7 @@ static const struct host1x_client_ops dc_client_ops = {
 
 static int tegra_dc_probe(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1160,7 +1160,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
 
 static int tegra_dc_remove(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;
 
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index 9d452df..6c59bcd 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -26,7 +26,7 @@
 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 {
struct device *dev = drm->dev;
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
int err;
 
host1x = dev_get_drvdata(dev);
@@ -69,7 +69,7 @@ static int tegra_drm_open(struct drm_device *drm, struct 
drm_file *filp)
 
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index a6c011d..7fedb6c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -18,7 +18,7 @@
 #include 
 #include 
 
-struct host1x {
+struct host1x_drm {
struct drm_device *drm;
struct device *dev;
void __iomem *regs;
@@ -44,7 +44,7 @@ struct host1x_client_ops {
 };
 
 struct host1x_client {
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;
 
const struct host1x_client_ops *ops;
@@ -52,12 +52,12 @@ struct host1x_client {
struct list_head list;
 };
 
-extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm);
-extern int host1x_drm_exit(struct host1x *host1x);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);
 
-extern int host1x_register_client(struct host1x *host1x,
+extern int host1x_register_client(struct host1x_drm *host1x,
  struct host1x_client *client);
-extern int host1x_unregister_client(struct host1x *host1x,
+extern int host1x_unregister_client(struct host1x_drm *host1x,
struct host1x_client *client);
 
 struct tegra_output;
@@ -66,7 +66,7 @@ struct tegra_dc {
struct host1x_client client;
spinlock_t lock;
 
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;
 
struct drm_crtc base;
diff --git a/drivers/gpu/host1x/drm/fb.c b/drivers/gpu/host1x/drm/fb.c
index 0391495..6ed885a 100644
--- a/drivers/gpu/host1x/drm/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -11,7 +11,7 @@
 
 static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_hotplug_event(host1x->fbdev);
 }
@@ -23,7 +23,7 @@ static const struct drm_mode_config_funcs 
tegra_drm_mode_funcs = {
 
 int tegra_drm_fb_init(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
struct drm_fbdev_cma *fbdev;
 
drm->mode_config.min_width = 0;
@@ -46,7 +46,7 @@ int tegra_drm_fb_init(struct drm_device *drm)
 
 void tegra_drm_fb_exit(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_fini(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index bb747f6..f438f80 100644
--- a/drivers/gpu/host1x/drm/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -1189,7 +1189,7 @@ st

[PATCHv9 2/9] gpu: host1x: Add syncpoint wait and interrupts

2013-03-22 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   12 ++
 drivers/gpu/host1x/dev.h |   51 +
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  143 +
 drivers/gpu/host1x/intr.c|  328 ++
 drivers/gpu/host1x/intr.h|   96 +
 drivers/gpu/host1x/syncpt.c  |  159 +++
 drivers/gpu/host1x/syncpt.h  |   12 ++
 10 files changed, 846 insertions(+)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o
 
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 0d6002c..b967f6e 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
 #include 
 
 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"
 
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
@@ -123,13 +124,24 @@ static int host1x_probe(struct platform_device *pdev)
return err;
}
 
+   err = host1x_intr_init(host, syncpt_irq);
+   if (err) {
+   dev_err(&pdev->dev, "failed to initialize interrupts\n");
+   goto fail_deinit_syncpt;
+   }
+
return 0;
+
+fail_deinit_syncpt:
+   host1x_syncpt_deinit(host);
+   return err;
 }
 
 static int __exit host1x_remove(struct platform_device *pdev)
 {
struct host1x *host = platform_get_drvdata(pdev);
 
+   host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
 
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index eaf6026..caf9cc6 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -21,6 +21,7 @@
 #include 
 
 #include "syncpt.h"
+#include "intr.h"
 
 struct host1x_syncpt;
 
@@ -33,6 +34,17 @@ struct host1x_syncpt_ops {
int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };
 
+struct host1x_intr_ops {
+   int (*init_host_sync)(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *work));
+   void (*set_syncpt_threshold)(
+   struct host1x *host, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x *host);
+   int (*free_syncpt_irq)(struct host1x *host);
+};
+
 struct host1x_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -50,7 +62,13 @@ struct host1x {
struct device *dev;
struct clk *clk;
 
+   struct mutex intr_mutex;
+   struct workqueue_struct *intr_wq;
+   int intr_syncpt_irq;
+
const struct host1x_syncpt_ops *syncpt_op;
+   const struct host1x_intr_ops *intr_op;
+
 };
 
 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -93,4 +111,37 @@ static inline int host1x_hw_syncpt_patch_wait(struct host1x 
*host,
return host->syncpt_op->patch_wait(sp, patch_addr);
 }
 
+static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *))
+{
+   return host->intr_op->init_host_sync(host, cpm, syncpt_thresh_work);
+}
+
+static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
+  u32 id, u32 thresh)
+{
+   host->intr_op->set_syncpt_threshold(host, id, thresh);
+}
+
+static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
+u32 id)
+{
+   host->intr_op->enable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
+ u32 id)
+{
+   host->intr_op->disable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
+{
+   host->intr_op->disable_all_syncpt_intrs(host);
+}
+
+static inline int host1x_hw_intr_free_syn

[PATCHv9 1/9] gpu: host1x: Add host1x driver

2013-03-22 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D. The Tegra
host1x module is the DMA engine for register access to Tegra's
graphics- and multimedia-related modules. The modules served by
host1x are referred to as clients. host1x includes some other
functionality, such as synchronization.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|9 ++
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  153 +
 drivers/gpu/host1x/dev.h  |   96 +
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   33 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   27 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   74 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  102 ++
 drivers/gpu/host1x/syncpt.c   |  212 +
 drivers/gpu/host1x/syncpt.h   |  147 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 +
 15 files changed, 956 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 30879df..d8a22c2 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..c01c450
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_HOST1X
+   tristate "NVIDIA Tegra host1x driver"
+   help
+ Driver for the NVIDIA Tegra host1x hardware.
+
+ The Tegra host1x module is the DMA engine for register access to
+ Tegra's graphics- and multimedia-related modules. The modules served
+ by host1x are referred to as clients. host1x includes some other
+ functionality, such as synchronization.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..0d6002c
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,153 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#include "dev.h"
+#include "hw/host1x01.h"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static const struct host1x_info host1x01_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_of_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_in

[PATCHv9 0/9] Support Tegra 2D hardware

2013-03-22 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130322 with RTC fixes applied.

Changes in this version:
 * Renaming in drivers/gpu/host1x/drm/drm.c to shorten function names
 * Whitespace and function order fixes
 * An extra struct (host1x_addr_reg) removed
 * Added uapi Kbuild entry

Changes in version 8:
 * Own version of framebuffer driver due to move to own allocator
   * Thanks to Thierry Reding for help
 * Miscellaneous variable name, whitespace and IOCTL interface cleanups
 * Bug fixes:
   * Validator enabled again
   * Added new class 2D strechblit
 * Dropped patch "Support CMA object preallocation"

Changes in version 7:
 * host1x memory data structures refactored
 * Some "nvhost" leftovers renamed to host1x

Changes in version 6:
 * Rebased on latest tegradrm
 * Renamed tegradrm's host1x to host1x_drm
 * Indentation and line split fixed to follow tegradrm convention
 * Pointers to platform_device replaced with pointers to device
 * Added host1x allocator, and wired it in
 * Debug spew code fixed to access mem handles from host1x_job
 * CDMA code doesn't keep the mem handles anymore
 * Push buffer ops have been made generic code
 * Removed the pin_array optimization in host1x_job to simplify code
 * Large number of smaller changes

The driver implements an allocator using the dma mapping API. Each buffer is
assigned an ops structure to operate on it.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page http://http.download.nvidia.com/tegra-public-appnotes/host1x.html
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

The changes to add support to libdrm are in
g...@gitorious.org:linux-host1x/libdrm-host1x.git

Arto Merilainen (2):
  gpu: host1x: drm: Rename host1x to host1x_drm
  gpu: host1x: drm: Add memory manager and fb

Terje Bergstrom (7):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  drm: tegra: Add gr2d device

 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  217 
 drivers/gpu/drm/tegra/fb.c |   52 --
 drivers/gpu/drm/tegra/host1x.c |  327 
 drivers/gpu/host1x/Kconfig |   23 +
 drivers/gpu/host1x/Makefile|   20 +
 drivers/gpu/host1x/cdma.c  |  491 ++
 drivers/gpu/host1x/cdma.h  |  100 
 drivers/gpu/host1x/channel.c   |  126 +
 drivers/gpu/host1x/channel.h   |   52 ++
 drivers/gpu/host1x/debug.c |  210 
 drivers/gpu/host1x/debug.h |   51 ++
 drivers/gpu/host1x/dev.c   |  246 +
 drivers/gpu/host1x/dev.h   |  308 
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |   19 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |   26 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  640 
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   68 ++-
 drivers/gpu/host1x/drm/fb.c|  372 ++
 drivers/gpu/host1x/drm/gem.c   |  270 ++
 drivers/gpu/host1x/drm/gem.h   |   59 +++
 drivers/gpu/host1x/drm/gr2d.c  |  339 +
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   30 ++
 drivers/gpu/host1x/host1x_bo.h |   87 
 drivers/gpu/host1x/host1x_client.h |   35 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  326 
 drivers/gpu/host1x/hw/channel_hw.c |  168 +++
 drivers/gpu/host1x/hw/debug_hw.c   |  322 
 drivers/gpu/host1x/hw/hos

[PATCHv8 7/9] gpu: host1x: Remove second host1x driver

2013-03-22 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x
driver. The logic to parse device tree and track clients is moved
to drm.c.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 ++-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|5 +-
 drivers/gpu/host1x/drm/drm.c   |  214 ++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |5 +-
 drivers/gpu/host1x/drm/host1x.c|  329 
 drivers/gpu/host1x/host1x_client.h |   35 
 10 files changed, 317 insertions(+), 342 deletions(-)
 delete mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 4761e8a..9a6fc76 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -13,6 +13,6 @@ host1x-y = \
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 9689724..8ce9889 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -32,6 +32,19 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   return host1x->drm_data;
+}
 
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -150,6 +163,8 @@ static int host1x_probe(struct platform_device *pdev)
 
host1x_debug_init(host);
 
+   host1x_drm_alloc(pdev);
+
return 0;
 
 fail_deinit_syncpt:
@@ -168,7 +183,7 @@ static int __exit host1x_remove(struct platform_device 
*pdev)
return 0;
 }
 
-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -178,8 +193,47 @@ static struct platform_driver platform_driver = {
},
 };
 
-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_DRM_TEGRA
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);
 
+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 4d16fe9..a1607d6 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -124,6 +124,8 @@ struct host1x {
unsigned int num_allocated_channels;
 
struct dentry *debugfs;
+
+   void *drm_data;
 };
 
 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -299,4 +301,8 @@ static inline void host1x_hw_show_mlocks(struct host1x 
*host, struct output *o)
host->debug_op->show_mlocks(host, o);
 }
 
+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index be1daf7..7db9b3a 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
selec

[PATCHv8 9/9] drm: tegra: Add gr2d device

2013-03-22 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from
DRM.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|1 +
 drivers/gpu/host1x/dev.c   |7 +
 drivers/gpu/host1x/drm/Kconfig |9 ++
 drivers/gpu/host1x/drm/drm.c   |  213 -
 drivers/gpu/host1x/drm/drm.h   |   27 +++-
 drivers/gpu/host1x/drm/gr2d.c  |  340 
 drivers/gpu/host1x/host1x.h|4 +-
 include/uapi/drm/tegra_drm.h   |  136 
 8 files changed, 734 insertions(+), 3 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/uapi/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 3768dbc..3b037b6 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 8ce9889..28e28a2 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -209,11 +209,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif
 
return 0;
 
 #ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -226,6 +232,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index f743540..6e3f567 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -13,6 +13,15 @@ config DRM_TEGRA
 
 if DRM_TEGRA
 
+config DRM_TEGRA_STAGING
+   bool "Enable HOST1X interface"
+   depends on STAGING
+   default n
+   help
+ Say yes if HOST1X should be available for userspace DRM users.
+
+ If unsure, choose N.
+
 config DRM_TEGRA_DEBUG
bool "NVIDIA Tegra DRM debug support"
help
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index c4e45c1..6db1bd6 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -14,6 +14,11 @@
 #include 
 #include 
 
+#include 
+#include 
+
+#include 
+
 #include "host1x_client.h"
 #include "dev.h"
 #include "drm.h"
@@ -81,8 +86,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -277,9 +284,24 @@ static int tegra_drm_unload(struct drm_device *drm)
 
 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
+   struct host1x_drm_file *fpriv;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
return 0;
 }
 
+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+   context->client->ops->close_channel(context);
+   kfree(context);
+}
+
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
struct host1x_drm *host1x = drm->dev_private;
@@ -287,7 +309,189 @@ static void tegra_drm_lastclose(struct drm_device *drm)
tegra_fbdev_restore_mode(host1x->fbdev);
 }
 
+#ifdef CONFIG_DRM_TEGRA_STAGING
+static int tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+  struct drm_file *

[PATCHv8 8/9] gpu: host1x: drm: Add memory manager and fb

2013-03-22 Thread Terje Bergstrom
From: Arto Merilainen 

This patch introduces a memory manager for tegra drm and moves
existing parts to use it. As cma framebuffer helpers can no more
be used, this patch adds also a separate framebuffer driver for
tegra.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|1 +
 drivers/gpu/host1x/drm/Kconfig |8 +-
 drivers/gpu/host1x/drm/dc.c|   23 +--
 drivers/gpu/host1x/drm/drm.c   |   17 +-
 drivers/gpu/host1x/drm/drm.h   |   18 ++-
 drivers/gpu/host1x/drm/fb.c|  338 +++-
 drivers/gpu/host1x/drm/gem.c   |  270 
 drivers/gpu/host1x/drm/gem.h   |   59 +++
 8 files changed, 700 insertions(+), 34 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gem.c
 create mode 100644 drivers/gpu/host1x/drm/gem.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 9a6fc76..3768dbc 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -15,4 +15,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gem.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index 7db9b3a..f743540 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -2,11 +2,9 @@ config DRM_TEGRA
bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
select DRM_KMS_HELPER
-   select DRM_GEM_CMA_HELPER
-   select DRM_KMS_CMA_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
+   select FB_SYS_FILLRECT
+   select FB_SYS_COPYAREA
+   select FB_SYS_IMAGEBLIT
help
  Choose this option if you have an NVIDIA Tegra SoC.
 
diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index 29a79b6..85ea616 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -14,9 +14,10 @@
 #include 
 #include 
 
-#include "drm.h"
-#include "dc.h"
 #include "host1x_client.h"
+#include "dc.h"
+#include "drm.h"
+#include "gem.h"
 
 struct tegra_plane {
struct drm_plane base;
@@ -52,9 +53,9 @@ static int tegra_plane_update(struct drm_plane *plane, struct 
drm_crtc *crtc,
window.bits_per_pixel = fb->bits_per_pixel;
 
for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
-   struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, i);
+   struct tegra_bo *bo = tegra_fb_get_plane(fb, i);
 
-   window.base[i] = gem->paddr + fb->offsets[i];
+   window.base[i] = bo->paddr + fb->offsets[i];
 
/*
 * Tegra doesn't support different strides for U and V planes
@@ -137,7 +138,7 @@ static int tegra_dc_add_planes(struct drm_device *drm, 
struct tegra_dc *dc)
 static int tegra_dc_set_base(struct tegra_dc *dc, int x, int y,
 struct drm_framebuffer *fb)
 {
-   struct drm_gem_cma_object *gem = drm_fb_cma_get_gem_obj(fb, 0);
+   struct tegra_bo *bo = tegra_fb_get_plane(fb, 0);
unsigned long value;
 
tegra_dc_writel(dc, WINDOW_A_SELECT, DC_CMD_DISPLAY_WINDOW_HEADER);
@@ -145,7 +146,7 @@ static int tegra_dc_set_base(struct tegra_dc *dc, int x, 
int y,
value = fb->offsets[0] + y * fb->pitches[0] +
x * fb->bits_per_pixel / 8;
 
-   tegra_dc_writel(dc, gem->paddr + value, DC_WINBUF_START_ADDR);
+   tegra_dc_writel(dc, bo->paddr + value, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, fb->pitches[0], DC_WIN_LINE_STRIDE);
 
value = GENERAL_UPDATE | WIN_A_UPDATE;
@@ -187,20 +188,20 @@ static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
 {
struct drm_device *drm = dc->base.dev;
struct drm_crtc *crtc = &dc->base;
-   struct drm_gem_cma_object *gem;
unsigned long flags, base;
+   struct tegra_bo *bo;
 
if (!dc->event)
return;
 
-   gem = drm_fb_cma_get_gem_obj(crtc->fb, 0);
+   bo = tegra_fb_get_plane(crtc->fb, 0);
 
/* check if new start address has been latched */
tegra_dc_writel(dc, READ_MUX, DC_CMD_STATE_ACCESS);
base = tegra_dc_readl(dc, DC_WINBUF_START_ADDR);
tegra_dc_writel(dc, 0, DC_CMD_STATE_ACCESS);
 
-   if (base == gem->paddr + crtc->fb->offsets[0]) {
+   if (base == bo->paddr + crtc->fb->offsets[0]) {
spin_lock_irqsave(&drm->event_lock, flags);
drm_send_vblank_event(drm, dc->pipe, dc->event);
drm_vblank_put(drm, dc->pipe);
@@ -570,7 +571,7 @@ static int tegra_crtc_mode_set(

[PATCHv8 6/9] gpu: host1x: drm: Rename host1x to host1x_drm

2013-03-22 Thread Terje Bergstrom
From: Arto Merilainen 

Both host1x and drm drivers have host1x structures. This patch
renames the host1x structure under drm to follow name host1x_drm.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/drm/dc.c |4 ++--
 drivers/gpu/host1x/drm/drm.c|4 ++--
 drivers/gpu/host1x/drm/drm.h|   14 +++---
 drivers/gpu/host1x/drm/fb.c |6 +++---
 drivers/gpu/host1x/drm/hdmi.c   |4 ++--
 drivers/gpu/host1x/drm/host1x.c |   22 --
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index de94707..d1f6609 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -1097,7 +1097,7 @@ static const struct host1x_client_ops dc_client_ops = {
 
 static int tegra_dc_probe(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1160,7 +1160,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
 
 static int tegra_dc_remove(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;
 
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index 9d452df..6c59bcd 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -26,7 +26,7 @@
 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 {
struct device *dev = drm->dev;
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
int err;
 
host1x = dev_get_drvdata(dev);
@@ -69,7 +69,7 @@ static int tegra_drm_open(struct drm_device *drm, struct 
drm_file *filp)
 
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index a6c011d..7fedb6c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -18,7 +18,7 @@
 #include 
 #include 
 
-struct host1x {
+struct host1x_drm {
struct drm_device *drm;
struct device *dev;
void __iomem *regs;
@@ -44,7 +44,7 @@ struct host1x_client_ops {
 };
 
 struct host1x_client {
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;
 
const struct host1x_client_ops *ops;
@@ -52,12 +52,12 @@ struct host1x_client {
struct list_head list;
 };
 
-extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm);
-extern int host1x_drm_exit(struct host1x *host1x);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);
 
-extern int host1x_register_client(struct host1x *host1x,
+extern int host1x_register_client(struct host1x_drm *host1x,
  struct host1x_client *client);
-extern int host1x_unregister_client(struct host1x *host1x,
+extern int host1x_unregister_client(struct host1x_drm *host1x,
struct host1x_client *client);
 
 struct tegra_output;
@@ -66,7 +66,7 @@ struct tegra_dc {
struct host1x_client client;
spinlock_t lock;
 
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;
 
struct drm_crtc base;
diff --git a/drivers/gpu/host1x/drm/fb.c b/drivers/gpu/host1x/drm/fb.c
index 0391495..6ed885a 100644
--- a/drivers/gpu/host1x/drm/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -11,7 +11,7 @@
 
 static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_hotplug_event(host1x->fbdev);
 }
@@ -23,7 +23,7 @@ static const struct drm_mode_config_funcs 
tegra_drm_mode_funcs = {
 
 int tegra_drm_fb_init(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
struct drm_fbdev_cma *fbdev;
 
drm->mode_config.min_width = 0;
@@ -46,7 +46,7 @@ int tegra_drm_fb_init(struct drm_device *drm)
 
 void tegra_drm_fb_exit(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_fini(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index bb747f6..f438f80 100644
--- a/drivers/gpu/host1x/drm/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -1189,7 +1189,7 @@ st

[PATCHv8 1/9] gpu: host1x: Add host1x driver

2013-03-22 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D. The Tegra
host1x module is the DMA engine for register access to Tegra's
graphics- and multimedia-related modules. The modules served by
host1x are referred to as clients. host1x includes some other
functionality, such as synchronization.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|9 ++
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  153 +
 drivers/gpu/host1x/dev.h  |   96 +
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   33 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   27 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   74 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  102 ++
 drivers/gpu/host1x/syncpt.c   |  212 +
 drivers/gpu/host1x/syncpt.h   |  147 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 +
 15 files changed, 956 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 30879df..d8a22c2 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..c01c450
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_HOST1X
+   tristate "NVIDIA Tegra host1x driver"
+   help
+ Driver for the NVIDIA Tegra host1x hardware.
+
+ The Tegra host1x module is the DMA engine for register access to
+ Tegra's graphics- and multimedia-related modules. The modules served
+ by host1x are referred to as clients. host1x includes some other
+ functionality, such as synchronization.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..0d6002c
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,153 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#include "dev.h"
+#include "hw/host1x01.h"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static const struct host1x_info host1x01_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_of_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_in

[PATCHv8 2/9] gpu: host1x: Add syncpoint wait and interrupts

2013-03-22 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   12 ++
 drivers/gpu/host1x/dev.h |   51 +
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  143 +
 drivers/gpu/host1x/intr.c|  328 ++
 drivers/gpu/host1x/intr.h|   96 +
 drivers/gpu/host1x/syncpt.c  |  159 +++
 drivers/gpu/host1x/syncpt.h  |   12 ++
 10 files changed, 846 insertions(+)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o
 
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 0d6002c..b967f6e 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
 #include 
 
 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"
 
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
@@ -123,13 +124,24 @@ static int host1x_probe(struct platform_device *pdev)
return err;
}
 
+   err = host1x_intr_init(host, syncpt_irq);
+   if (err) {
+   dev_err(&pdev->dev, "failed to initialize interrupts\n");
+   goto fail_deinit_syncpt;
+   }
+
return 0;
+
+fail_deinit_syncpt:
+   host1x_syncpt_deinit(host);
+   return err;
 }
 
 static int __exit host1x_remove(struct platform_device *pdev)
 {
struct host1x *host = platform_get_drvdata(pdev);
 
+   host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
 
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index eaf6026..caf9cc6 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -21,6 +21,7 @@
 #include 
 
 #include "syncpt.h"
+#include "intr.h"
 
 struct host1x_syncpt;
 
@@ -33,6 +34,17 @@ struct host1x_syncpt_ops {
int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };
 
+struct host1x_intr_ops {
+   int (*init_host_sync)(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *work));
+   void (*set_syncpt_threshold)(
+   struct host1x *host, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x *host);
+   int (*free_syncpt_irq)(struct host1x *host);
+};
+
 struct host1x_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -50,7 +62,13 @@ struct host1x {
struct device *dev;
struct clk *clk;
 
+   struct mutex intr_mutex;
+   struct workqueue_struct *intr_wq;
+   int intr_syncpt_irq;
+
const struct host1x_syncpt_ops *syncpt_op;
+   const struct host1x_intr_ops *intr_op;
+
 };
 
 void host1x_sync_writel(struct host1x *host1x, u32 r, u32 v);
@@ -93,4 +111,37 @@ static inline int host1x_hw_syncpt_patch_wait(struct host1x 
*host,
return host->syncpt_op->patch_wait(sp, patch_addr);
 }
 
+static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *))
+{
+   return host->intr_op->init_host_sync(host, cpm, syncpt_thresh_work);
+}
+
+static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
+  u32 id, u32 thresh)
+{
+   host->intr_op->set_syncpt_threshold(host, id, thresh);
+}
+
+static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
+u32 id)
+{
+   host->intr_op->enable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
+ u32 id)
+{
+   host->intr_op->disable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
+{
+   host->intr_op->disable_all_syncpt_intrs(host);
+}
+
+static inline int host1x_hw_intr_free_syn

[PATCHv8 4/9] gpu: host1x: Add debug support

2013-03-22 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |4 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |2 +
 drivers/gpu/host1x/hw/channel_hw.c  |   25 +++
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 807 insertions(+)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 06a995b..49fd580 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
hw/host1x01.o
 
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 33935de..de72172 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -439,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;
 
+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..3ec7d77
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2013 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
+   va_end(args);
+   o->fn(o->ctx, o->buf, len);
+}
+
+static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo)
+{
+   struct host1x *m = dev_get_drvdata(ch->dev->parent);
+   struct output *o = data;
+
+   mutex_lock(&ch->reflock);
+   if (ch->refcount) {
+   mutex_lock(&ch->cdma.lock);
+   if (show_fifo)
+   host1x_hw_show_channel_fifo(m, ch, o);
+   host1x_hw_show_channel_cdma(m, ch, o);
+   mutex_unlock(&ch->cdma.lock);
+   }
+   mutex_unlock(&ch->reflock);
+
+   return 0;
+}
+
+static void show_syncpts(struct host1x *m, struct output *o)
+{
+   int i;
+   host1x_debug_output(o, " syncpts \n");
+   for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
+   u32 max = host1x_syncpt_read_max(m->syncpt + i);
+   u32 min = host1x_syncpt_load(m->syncpt + i);
+   if (!min && !max)
+   continue;
+   host1x_debug_output(o, "id %d (%s) min %d max %d\n",
+   i, m->syncpt[i].name, min, max);
+   }
+
+   for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
+   u32 base_val;
+   base_val = host1x_syncpt_load_wait_base(m->syncpt + i);
+   if

[PATCHv8 5/9] drm: tegra: Move drm to live under host1x

2013-03-22 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |2 ++
 drivers/gpu/host1x/Makefile|5 +
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 16 files changed, 10 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1e82882..9031bb7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -215,8 +215,6 @@ source "drivers/gpu/drm/cirrus/Kconfig"
 
 source "drivers/gpu/drm/shmobile/Kconfig"
 
-source "drivers/gpu/drm/tegra/Kconfig"
-
 source "drivers/gpu/drm/omapdrm/Kconfig"
 
 source "drivers/gpu/drm/tilcdc/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d59b24..847b830 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 00f0859..ee3af1e 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -18,4 +18,6 @@ config TEGRA_HOST1X_FIREWALL
 
  If unsure, choose Y.
 
+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 49fd580..4761e8a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -10,4 +10,9 @@ host1x-y = \
debug.o \
hw/host1x01.o
 
+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 6dd75a2..a6c011d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -7,8 +7,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef TEGRA_DRM_H
-#define TEGRA_D

[PATCHv8 0/9] Support for Tegra 2D hardware

2013-03-22 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130322 with RTC fixes applied.

Changes in this version:
 * Own version of framebuffer driver due to move to own allocator
   * Thanks to Thierry Reding for help
 * Miscellaneous variable name, whitespace and IOCTL interface cleanups
 * Bug fixes:
   * Validator enabled again
   * Added new class 2D strechblit
 * Dropped patch "Support CMA object preallocation"

Changes in version 7:
 * host1x memory data structures refactored
 * Some "nvhost" leftovers renamed to host1x

Changes in version 6:
 * Rebased on latest tegradrm
 * Renamed tegradrm's host1x to host1x_drm
 * Indentation and line split fixed to follow tegradrm convention
 * Pointers to platform_device replaced with pointers to device
 * Added host1x allocator, and wired it in
 * Debug spew code fixed to access mem handles from host1x_job
 * CDMA code doesn't keep the mem handles anymore
 * Push buffer ops have been made generic code
 * Removed the pin_array optimization in host1x_job to simplify code
 * Large number of smaller changes

The driver implements an allocator using the dma mapping API. Each buffer is
assigned an ops structure to operate on it.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page http://http.download.nvidia.com/tegra-public-appnotes/host1x.html
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

The changes to add support to libdrm are in
g...@gitorious.org:linux-host1x/libdrm-host1x.git

Arto Merilainen (2):
  gpu: host1x: drm: Rename host1x to host1x_drm
  gpu: host1x: drm: Add memory manager and fb

Terje Bergstrom (7):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  drm: tegra: Add gr2d device

 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  217 
 drivers/gpu/drm/tegra/fb.c |   52 --
 drivers/gpu/drm/tegra/host1x.c |  327 
 drivers/gpu/host1x/Kconfig |   23 +
 drivers/gpu/host1x/Makefile|   20 +
 drivers/gpu/host1x/cdma.c  |  491 ++
 drivers/gpu/host1x/cdma.h  |  100 
 drivers/gpu/host1x/channel.c   |  126 +
 drivers/gpu/host1x/channel.h   |   52 ++
 drivers/gpu/host1x/debug.c |  210 
 drivers/gpu/host1x/debug.h |   51 ++
 drivers/gpu/host1x/dev.c   |  246 +
 drivers/gpu/host1x/dev.h   |  308 
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |   19 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |   26 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  641 
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   68 ++-
 drivers/gpu/host1x/drm/fb.c|  374 ++
 drivers/gpu/host1x/drm/gem.c   |  270 ++
 drivers/gpu/host1x/drm/gem.h   |   59 +++
 drivers/gpu/host1x/drm/gr2d.c  |  340 +
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   30 ++
 drivers/gpu/host1x/host1x_bo.h |   87 
 drivers/gpu/host1x/host1x_client.h |   35 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  326 
 drivers/gpu/host1x/hw/channel_hw.c |  168 +++
 drivers/gpu/host1x/hw/debug_hw.c   |  322 
 drivers/gpu/host1x/hw/host1x01.c   |   42 ++
 drivers/gpu/host1x/hw/host1x01.h   |   25 +
 drivers/gpu/host1x/hw/host1x01_hardware.h  |  143 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h

[PATCHv7 10/10] drm: tegra: Add gr2d device

2013-03-13 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from
DRM.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile   |1 +
 drivers/gpu/host1x/dev.c  |7 +
 drivers/gpu/host1x/drm/drm.c  |  251 ++-
 drivers/gpu/host1x/drm/drm.h  |   28 +++-
 drivers/gpu/host1x/drm/gr2d.c |  330 +
 drivers/gpu/host1x/host1x.h   |3 +-
 include/drm/tegra_drm.h   |  131 
 7 files changed, 747 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index e85db5a..29c0c6b 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/cma.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 6af8081..0091632 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -211,11 +211,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif

return 0;

 #ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -228,6 +234,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index dbd4808..9f78f52 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -8,13 +8,21 @@
  */

 #include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 

+#include "cma.h"
+#include "dev.h"
 #include "drm.h"
+#include "host1x_bo.h"
 #include "host1x_client.h"
+#include "syncpt.h"

 #define DRIVER_NAME "tegra"
 #define DRIVER_DESC "NVIDIA Tegra graphics"
@@ -77,8 +85,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -273,9 +283,24 @@ static int tegra_drm_unload(struct drm_device *drm)

 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
+   struct host1x_drm_file *fpriv;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
return 0;
 }

+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+   context->client->ops->close_channel(context);
+   kfree(context);
+}
+
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
struct host1x_drm *host1x = drm->dev_private;
@@ -283,7 +308,222 @@ static void tegra_drm_lastclose(struct drm_device *drm)
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }

+static int tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+  struct drm_file *file_priv)
+{
+   struct tegra_drm_syncpt_read_args *args = data;
+   struct host1x *host = host1x_get_host(drm->dev);
+   struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id);
+
+   if (!sp)
+   return -EINVAL;
+
+   args->value = host1x_syncpt_read_min(sp);
+   return 0;
+}
+
+static int tegra_drm_ioctl_syncpt_incr(struct drm_device *drm, void *data,
+  

[PATCHv7 09/10] gpu: host1x: drm: Add CMA ops for host1x driver

2013-03-13 Thread Terje Bergstrom
From: Arto Merilainen 

This patch implements a CMA memory handler for the host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/drm/cma.c |   93 ++
 drivers/gpu/host1x/drm/cma.h |   35 
 3 files changed, 129 insertions(+)
 create mode 100644 drivers/gpu/host1x/drm/cma.c
 create mode 100644 drivers/gpu/host1x/drm/cma.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 9a6fc76..e85db5a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -15,4 +15,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/cma.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/drm/cma.c b/drivers/gpu/host1x/drm/cma.c
new file mode 100644
index 000..cf86fce
--- /dev/null
+++ b/drivers/gpu/host1x/drm/cma.c
@@ -0,0 +1,93 @@
+/*
+ * Tegra host1x CMA support
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "cma.h"
+#include "host1x_bo.h"
+
+static void cma_put(struct host1x_bo *bo)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   struct drm_device *drm = cma_bo->cma_obj.base.dev;
+
+   mutex_lock(&drm->struct_mutex);
+   drm_gem_object_unreference(&cma_bo->cma_obj.base);
+   mutex_unlock(&drm->struct_mutex);
+}
+
+static dma_addr_t cma_pin(struct host1x_bo *bo, struct sg_table **sgt)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   return cma_bo->cma_obj.paddr;
+}
+
+static void cma_unpin(struct host1x_bo *bo, struct sg_table *sgt)
+{
+}
+
+static void *cma_mmap(struct host1x_bo *bo)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   return cma_bo->cma_obj.vaddr;
+}
+
+static void cma_munmap(struct host1x_bo *bo, void *addr)
+{
+}
+
+static void *cma_kmap(struct host1x_bo *bo, unsigned int pagenum)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   return cma_bo->cma_obj.vaddr + pagenum * PAGE_SIZE;
+}
+
+static void cma_kunmap(struct host1x_bo *bo, unsigned int pagenum, void *addr)
+{
+}
+
+static struct host1x_bo *cma_get(struct host1x_bo *bo)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   struct drm_device *drm = cma_bo->cma_obj.base.dev;
+
+   mutex_lock(&drm->struct_mutex);
+   drm_gem_object_reference(&cma_bo->cma_obj.base);
+   mutex_unlock(&drm->struct_mutex);
+
+   return bo;
+}
+
+const struct host1x_bo_ops tegra_drm_bo_ops = {
+   .get = cma_get,
+   .put = cma_put,
+   .pin = cma_pin,
+   .unpin = cma_unpin,
+   .mmap = cma_mmap,
+   .munmap = cma_munmap,
+   .kmap = cma_kmap,
+   .kunmap = cma_kunmap,
+};
diff --git a/drivers/gpu/host1x/drm/cma.h b/drivers/gpu/host1x/drm/cma.h
new file mode 100644
index 000..f35cebd
--- /dev/null
+++ b/drivers/gpu/host1x/drm/cma.h
@@ -0,0 +1,35 @@
+/*
+ * Tegra host1x cma memory manager
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __HOST1X_CMA_H
+#define __HOST1X_CMA_H
+
+#include 
+#include 
+#include 
+
+#include "host1x_bo.h"
+
+struct tegra_drm_bo {
+   struct host1x_bo base;
+   struct drm_gem_cma_object cma_obj;
+};
+
+extern const struct host1x_bo_ops tegra_drm_bo_ops;
+
+#endif
-- 
1.7.9.5



[PATCHv7 08/10] gpu: host1x: Remove second host1x driver

2013-03-13 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x
driver. The logic to parse device tree and track clients is moved
to drm.c.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 ++-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|5 +-
 drivers/gpu/host1x/drm/drm.c   |  217 +++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |5 +-
 drivers/gpu/host1x/drm/host1x.c|  329 
 drivers/gpu/host1x/host1x_client.h |   35 
 10 files changed, 318 insertions(+), 344 deletions(-)
 delete mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 4761e8a..9a6fc76 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -13,6 +13,6 @@ host1x-y = \
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d7c6e3e..6af8081 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -32,6 +32,19 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   return host1x->drm_data;
+}

 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -154,6 +167,8 @@ static int host1x_probe(struct platform_device *pdev)

host1x_debug_init(host);

+   host1x_drm_alloc(pdev);
+
return 0;

 fail_deinit_syncpt:
@@ -170,7 +185,7 @@ static int __exit host1x_remove(struct platform_device 
*pdev)
return 0;
 }

-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -180,8 +195,47 @@ static struct platform_driver platform_driver = {
},
 };

-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_DRM_TEGRA
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);

+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 4a56233..ca2ba8a 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -124,6 +124,8 @@ struct host1x {
unsigned int num_allocated_channels;

struct dentry *debugfs;
+
+   void *drm_data;
 };

 static inline struct host1x *host1x_get_host(struct device *dev)
@@ -307,4 +309,8 @@ static inline void host1x_hw_show_mlocks(struct host1x 
*host, struct output *o)
host->debug_op->show_mlocks(host, o);
 }

+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index c92955d..8fb6545 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
select DRM_K

[PATCHv7 07/10] gpu: host1x: drm: Rename host1x to host1x_drm

2013-03-13 Thread Terje Bergstrom
From: Arto Merilainen 

Both host1x and drm drivers have host1x structures. This patch
renames the host1x structure under drm to follow name host1x_drm.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/drm/dc.c |4 ++--
 drivers/gpu/host1x/drm/drm.c|4 ++--
 drivers/gpu/host1x/drm/drm.h|   14 +++---
 drivers/gpu/host1x/drm/fb.c |6 +++---
 drivers/gpu/host1x/drm/hdmi.c   |4 ++--
 drivers/gpu/host1x/drm/host1x.c |   22 --
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index de94707..d1f6609 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -1097,7 +1097,7 @@ static const struct host1x_client_ops dc_client_ops = {

 static int tegra_dc_probe(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1160,7 +1160,7 @@ static int tegra_dc_probe(struct platform_device *pdev)

 static int tegra_dc_remove(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;

diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index 9d452df..6c59bcd 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -26,7 +26,7 @@
 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 {
struct device *dev = drm->dev;
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
int err;

host1x = dev_get_drvdata(dev);
@@ -69,7 +69,7 @@ static int tegra_drm_open(struct drm_device *drm, struct 
drm_file *filp)

 static void tegra_drm_lastclose(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index a6c011d..7fedb6c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -18,7 +18,7 @@
 #include 
 #include 

-struct host1x {
+struct host1x_drm {
struct drm_device *drm;
struct device *dev;
void __iomem *regs;
@@ -44,7 +44,7 @@ struct host1x_client_ops {
 };

 struct host1x_client {
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;

const struct host1x_client_ops *ops;
@@ -52,12 +52,12 @@ struct host1x_client {
struct list_head list;
 };

-extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm);
-extern int host1x_drm_exit(struct host1x *host1x);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);

-extern int host1x_register_client(struct host1x *host1x,
+extern int host1x_register_client(struct host1x_drm *host1x,
  struct host1x_client *client);
-extern int host1x_unregister_client(struct host1x *host1x,
+extern int host1x_unregister_client(struct host1x_drm *host1x,
struct host1x_client *client);

 struct tegra_output;
@@ -66,7 +66,7 @@ struct tegra_dc {
struct host1x_client client;
spinlock_t lock;

-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;

struct drm_crtc base;
diff --git a/drivers/gpu/host1x/drm/fb.c b/drivers/gpu/host1x/drm/fb.c
index 0391495..6ed885a 100644
--- a/drivers/gpu/host1x/drm/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -11,7 +11,7 @@

 static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_hotplug_event(host1x->fbdev);
 }
@@ -23,7 +23,7 @@ static const struct drm_mode_config_funcs 
tegra_drm_mode_funcs = {

 int tegra_drm_fb_init(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
struct drm_fbdev_cma *fbdev;

drm->mode_config.min_width = 0;
@@ -46,7 +46,7 @@ int tegra_drm_fb_init(struct drm_device *drm)

 void tegra_drm_fb_exit(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_fini(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index bb747f6..f438f80 100644
--- a/drivers/gpu/host1x/drm/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -1189,7 +1189,7 @@ static const struct

[PATCHv7 06/10] drm: tegra: Move drm to live under host1x

2013-03-13 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |2 ++
 drivers/gpu/host1x/Makefile|5 +
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 16 files changed, 10 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1e82882..9031bb7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -215,8 +215,6 @@ source "drivers/gpu/drm/cirrus/Kconfig"

 source "drivers/gpu/drm/shmobile/Kconfig"

-source "drivers/gpu/drm/tegra/Kconfig"
-
 source "drivers/gpu/drm/omapdrm/Kconfig"

 source "drivers/gpu/drm/tilcdc/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d59b24..847b830 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 00f0859..ee3af1e 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -18,4 +18,6 @@ config TEGRA_HOST1X_FIREWALL

  If unsure, choose Y.

+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 49fd580..4761e8a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -10,4 +10,9 @@ host1x-y = \
debug.o \
hw/host1x01.o

+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 6dd75a2..a6c011d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -7,8 +7,8 @@
  * published by the Free Software Foundation.
  */

-#ifndef TEGRA_DRM_H
-#define TEGRA_

[PATCHv7 05/10] gpu: host1x: Add debug support

2013-03-13 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |4 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |2 +
 drivers/gpu/host1x/hw/channel_hw.c  |   26 ++-
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 807 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 06a995b..49fd580 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 33935de..de72172 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -439,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;

+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..cb8aff9
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2013 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
+   va_end(args);
+   o->fn(o->ctx, o->buf, len);
+}
+
+static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo)
+{
+   struct host1x *m = host1x_get_host(ch->dev);
+   struct output *o = data;
+
+   mutex_lock(&ch->reflock);
+   if (ch->refcount) {
+   mutex_lock(&ch->cdma.lock);
+   if (show_fifo)
+   host1x_hw_show_channel_fifo(m, ch, o);
+   host1x_hw_show_channel_cdma(m, ch, o);
+   mutex_unlock(&ch->cdma.lock);
+   }
+   mutex_unlock(&ch->reflock);
+
+   return 0;
+}
+
+static void show_syncpts(struct host1x *m, struct output *o)
+{
+   int i;
+   host1x_debug_output(o, " syncpts \n");
+   for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
+   u32 max = host1x_syncpt_read_max(m->syncpt + i);
+   u32 min = host1x_syncpt_load(m->syncpt + i);
+   if (!min && !max)
+   continue;
+   host1x_debug_output(o, "id %d (%s) min %d max %d\n",
+   i, m->syncpt[i].name, min, max);
+   }
+
+   for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
+   u32 base_val;
+   base_val = host1x_syncpt_load_wait_base(m->syncpt + i);
+   if (b

[PATCHv7 04/10] gpu: host1x: Add channel support

2013-03-13 Thread Terje Bergstrom
Add support for host1x client modules, and host1x channels to submit
work to the clients.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Kconfig  |   12 +
 drivers/gpu/host1x/Makefile |3 +
 drivers/gpu/host1x/cdma.c   |  487 ++
 drivers/gpu/host1x/cdma.h   |  100 +
 drivers/gpu/host1x/channel.c|  120 ++
 drivers/gpu/host1x/channel.h|   52 +++
 drivers/gpu/host1x/dev.c|   17 +
 drivers/gpu/host1x/dev.h|  113 +
 drivers/gpu/host1x/host1x.h |   28 ++
 drivers/gpu/host1x/host1x_bo.h  |   92 +
 drivers/gpu/host1x/hw/cdma_hw.c |  324 +++
 drivers/gpu/host1x/hw/channel_hw.c  |  143 +++
 drivers/gpu/host1x/hw/host1x01.c|5 +
 drivers/gpu/host1x/hw/host1x01_hardware.h   |  116 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |  102 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|   12 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |  168 
 drivers/gpu/host1x/hw/syncpt_hw.c   |   11 +
 drivers/gpu/host1x/intr.c   |   28 +-
 drivers/gpu/host1x/intr.h   |6 +
 drivers/gpu/host1x/job.c|  597 +++
 drivers/gpu/host1x/job.h|  157 +++
 drivers/gpu/host1x/syncpt.c |   11 +
 drivers/gpu/host1x/syncpt.h |6 +
 include/trace/events/host1x.h   |  211 ++
 25 files changed, 2920 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/cdma.c
 create mode 100644 drivers/gpu/host1x/cdma.h
 create mode 100644 drivers/gpu/host1x/channel.c
 create mode 100644 drivers/gpu/host1x/channel.h
 create mode 100644 drivers/gpu/host1x/host1x.h
 create mode 100644 drivers/gpu/host1x/host1x_bo.h
 create mode 100644 drivers/gpu/host1x/hw/cdma_hw.c
 create mode 100644 drivers/gpu/host1x/hw/channel_hw.c
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_channel.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_uclass.h
 create mode 100644 drivers/gpu/host1x/job.c
 create mode 100644 drivers/gpu/host1x/job.h

diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index c01c450..00f0859 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -7,3 +7,15 @@ config TEGRA_HOST1X
  Tegra's graphics- and multimedia-related modules. The modules served
  by host1x are referred to as clients. host1x includes some other
  functionality, such as synchronization.
+
+if TEGRA_HOST1X
+
+config TEGRA_HOST1X_FIREWALL
+   bool "Enable HOST1X security firewall"
+   default y
+   help
+ Say yes if kernel should protect command streams from tampering.
+
+ If unsure, choose Y.
+
+endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 5ef47ff..06a995b 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -4,6 +4,9 @@ host1x-y = \
syncpt.o \
dev.o \
intr.o \
+   cdma.o \
+   channel.o \
+   job.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
new file mode 100644
index 000..33935de
--- /dev/null
+++ b/drivers/gpu/host1x/cdma.c
@@ -0,0 +1,487 @@
+/*
+ * Tegra host1x Command DMA
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "cdma.h"
+#include "channel.h"
+#include "dev.h"
+#include "debug.h"
+#include "host1x_bo.h"
+#include "job.h"
+
+/*
+ * push_buffer
+ *
+ * The push buffer is a circular array of words to be fetched by command DMA.
+ * Note that it works slightly differently to the sync queue; fence == pos
+ * means that the push buffer is full, not empty.
+ */
+
+#define HOST1X_PUSHBUFFER_SLOTS512
+
+/*
+ * Clean up push buffer resources
+ */
+static void host1x_pushbuffer_destroy(struct push_buffer *pb)
+{
+   struct host1x_cdma *cdma = pb_to_cdma(pb);
+   struct host1x *host1x = cdma_to_host1x(cdma);
+
+   if 

[PATCHv7 03/10] gpu: host1x: Add syncpoint wait and interrupts

2013-03-13 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   12 ++
 drivers/gpu/host1x/dev.h |   51 +
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  143 +
 drivers/gpu/host1x/intr.c|  328 ++
 drivers/gpu/host1x/intr.h|   96 +
 drivers/gpu/host1x/syncpt.c  |  159 +++
 drivers/gpu/host1x/syncpt.h  |   14 +-
 10 files changed, 847 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d95a9b2..4421e28 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
 #include 

 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"

 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
@@ -127,12 +128,23 @@ static int host1x_probe(struct platform_device *pdev)
return err;
}

+   err = host1x_intr_init(host, syncpt_irq);
+   if (err) {
+   dev_err(dev, "failed to init irq");
+   goto fail_deinit_syncpt;
+   }
+
return 0;
+
+fail_deinit_syncpt:
+   host1x_syncpt_deinit(host);
+   return err;
 }

 static int __exit host1x_remove(struct platform_device *pdev)
 {
struct host1x *host = platform_get_drvdata(pdev);
+   host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
return 0;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 750daa3..fb5f842 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -21,6 +21,7 @@
 #include 

 #include "syncpt.h"
+#include "intr.h"

 struct host1x_syncpt;

@@ -33,6 +34,17 @@ struct host1x_syncpt_ops {
int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };

+struct host1x_intr_ops {
+   int (*init_host_sync)(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *work));
+   void (*set_syncpt_threshold)(
+   struct host1x *host, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x *host);
+   int (*free_syncpt_irq)(struct host1x *host);
+};
+
 struct host1x_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -50,7 +62,13 @@ struct host1x {
struct device *dev;
struct clk *clk;

+   struct mutex intr_mutex;
+   struct workqueue_struct *intr_wq;
+   int intr_syncpt_irq;
+
const struct host1x_syncpt_ops *syncpt_op;
+   const struct host1x_intr_ops *intr_op;
+
 };

 static inline struct host1x *host1x_get_host(struct device *dev)
@@ -101,4 +119,37 @@ static inline int host1x_hw_syncpt_patch_wait(struct 
host1x *host,
return host->syncpt_op->patch_wait(sp, patch_addr);
 }

+static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *))
+{
+   return host->intr_op->init_host_sync(host, cpm, syncpt_thresh_work);
+}
+
+static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
+  u32 id, u32 thresh)
+{
+   host->intr_op->set_syncpt_threshold(host, id, thresh);
+}
+
+static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
+u32 id)
+{
+   host->intr_op->enable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
+ u32 id)
+{
+   host->intr_op->disable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
+{
+   host->intr_op->disable_all_syncpt_intrs(host);
+}
+
+static inline int host1x_hw_intr_free_syncpt_irq(s

[PATCHv7 02/10] gpu: host1x: Add host1x driver

2013-03-13 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D. The Tegra
host1x module is the DMA engine for register access to Tegra's
graphics- and multimedia-related modules. The modules served by
host1x are referred to as clients. host1x includes some other
functionality, such as synchronization.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|9 ++
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  155 +
 drivers/gpu/host1x/dev.h  |  104 ++
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   33 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   27 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   74 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  102 ++
 drivers/gpu/host1x/syncpt.c   |  212 +
 drivers/gpu/host1x/syncpt.h   |  147 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 +
 15 files changed, 966 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 30879df..d8a22c2 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..c01c450
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_HOST1X
+   tristate "NVIDIA Tegra host1x driver"
+   help
+ Driver for the NVIDIA Tegra host1x hardware.
+
+ The Tegra host1x module is the DMA engine for register access to
+ Tegra's graphics- and multimedia-related modules. The modules served
+ by host1x are referred to as clients. host1x includes some other
+ functionality, such as synchronization.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..d95a9b2
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,155 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#include "dev.h"
+#include "hw/host1x01.h"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static const struct host1x_info host1x01_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
+   { .compatible = &quo

[PATCHv7 01/10] gpu: drm: Support CMA object preallocation

2013-03-13 Thread Terje Bergstrom
From: Arto Merilainen 

This patch adds helper functions drm_gem_cma_init() and
drm_gem_cma_deinit() for handling CMA structures that already have
been allocated. This allows embedding the CMA structure inside other
structures.

Signed-off-by: Arto Merilainen 
---
 drivers/gpu/drm/drm_gem_cma_helper.c |   78 --
 include/drm/drm_gem_cma_helper.h |9 
 2 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
b/drivers/gpu/drm/drm_gem_cma_helper.c
index 0a7e011..3b14280 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -2,6 +2,7 @@
  * drm gem CMA (contiguous memory allocator) helper functions
  *
  * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ * Copyright (C) 2013 NVIDIA CORPORATION, All rights reserved.
  *
  * Based on Samsung Exynos code
  *
@@ -40,30 +41,25 @@ static void drm_gem_cma_buf_destroy(struct drm_device *drm,
 }

 /*
- * drm_gem_cma_create - allocate an object with the given size
+ * drm_gem_cma_object_init - allocate buffer and initialize given cma object
  *
- * returns a struct drm_gem_cma_object* on success or ERR_PTR values
- * on failure.
+ * this function allocates memory for a cma buffer and initializes the given
+ * cma object to use the allocated buffer.
  */
-struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
-   unsigned int size)
+
+int drm_gem_cma_object_init(struct drm_device *drm,
+   struct drm_gem_cma_object *cma_obj, unsigned int size)
 {
-   struct drm_gem_cma_object *cma_obj;
struct drm_gem_object *gem_obj;
int ret;

size = round_up(size, PAGE_SIZE);

-   cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
-   if (!cma_obj)
-   return ERR_PTR(-ENOMEM);
-
cma_obj->vaddr = dma_alloc_writecombine(drm->dev, size,
&cma_obj->paddr, GFP_KERNEL | __GFP_NOWARN);
if (!cma_obj->vaddr) {
dev_err(drm->dev, "failed to allocate buffer with size %d\n", 
size);
-   ret = -ENOMEM;
-   goto err_dma_alloc;
+   return -ENOMEM;
}

gem_obj = &cma_obj->base;
@@ -76,7 +72,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct 
drm_device *drm,
if (ret)
goto err_create_mmap_offset;

-   return cma_obj;
+   return 0;

 err_create_mmap_offset:
drm_gem_object_release(gem_obj);
@@ -84,10 +80,36 @@ err_create_mmap_offset:
 err_obj_init:
drm_gem_cma_buf_destroy(drm, cma_obj);

-err_dma_alloc:
-   kfree(cma_obj);
+   return ret;
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_object_init);
+
+/*
+ * drm_gem_cma_create - allocate an object with the given size
+ *
+ * returns a struct drm_gem_cma_object* on success or ERR_PTR values
+ * on failure.
+ */
+struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
+   unsigned int size)
+{
+   struct drm_gem_cma_object *cma_obj;
+   int ret;
+
+   size = round_up(size, PAGE_SIZE);
+
+   cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
+   if (!cma_obj)
+   return ERR_PTR(-ENOMEM);
+
+   ret = drm_gem_cma_object_init(drm, cma_obj, size);
+   if (ret) {
+   kfree(cma_obj);
+   return ERR_PTR(ret);
+   }
+
+   return cma_obj;

-   return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_create);

@@ -133,22 +155,32 @@ err_handle_create:
 }

 /*
- * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback
- * function
+ * drm_gem_cma_deinit_object - deinitialize cma object
+ *
+ * this function deinitializes the given cma object without releasing the
+ * object memory. this function is a counterpart for the function
+ * drm_gem_cma_object_init().
  */
-void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
+void drm_gem_cma_object_deinit(struct drm_gem_object *gem_obj)
 {
-   struct drm_gem_cma_object *cma_obj;
+   struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem_obj);

if (gem_obj->map_list.map)
drm_gem_free_mmap_offset(gem_obj);

drm_gem_object_release(gem_obj);
-
-   cma_obj = to_drm_gem_cma_obj(gem_obj);
-
drm_gem_cma_buf_destroy(gem_obj->dev, cma_obj);
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_object_deinit);

+/*
+ * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback
+ * function
+ */
+void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
+{
+   struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem_obj);
+   drm_gem_cma_object_deinit(gem_obj);
kfree(cma_obj);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_free_object);
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index 63397ce..5fdccb3 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -13,6 +13,10 @@ to_drm_gem_cma_obj(struct drm_gem_object *gem_obj)
   

[PATCHv7 00/10] Support for Tegra 2D hardware

2013-03-13 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130307.

Changes in this version:
 * host1x memory data structures refactored
 * Some "nvhost" leftovers renamed to host1x

Changes in previous version 6:
 * Rebased on latest tegradrm
 * Renamed tegradrm's host1x to host1x_drm
 * Indentation and line split fixed to follow tegradrm convention
 * Pointers to platform_device replaced with pointers to device
 * Added host1x allocator, and wired it in
 * Debug spew code fixed to access mem handles from host1x_job
 * CDMA code doesn't keep the mem handles anymore
 * Push buffer ops have been made generic code
 * Removed the pin_array optimization in host1x_job to simplify code
 * Large number of smaller changes

The driver implements an allocator using the DRM CMA helper. Each buffer is
assigned an ops structure to operate on it. In future the DRM CMA helper will
be replaced with an own allocator to implement IOMMU support.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page http://http.download.nvidia.com/tegra-public-appnotes/host1x.html
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

The changes to add support to libdrm are in
git at gitorious.org:linux-host1x/libdrm-host1x.git

Arto Merilainen (3):
  gpu: drm: Support CMA object preallocation
  gpu: host1x: drm: Rename host1x to host1x_drm
  gpu: host1x: drm: Add CMA ops for host1x driver

Terje Bergstrom (7):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  drm: tegra: Add gr2d device

 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/drm_gem_cma_helper.c   |   78 ++-
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  217 
 drivers/gpu/drm/tegra/host1x.c |  327 
 drivers/gpu/host1x/Kconfig |   23 +
 drivers/gpu/host1x/Makefile|   20 +
 drivers/gpu/host1x/cdma.c  |  491 +
 drivers/gpu/host1x/cdma.h  |  100 
 drivers/gpu/host1x/channel.c   |  120 +
 drivers/gpu/host1x/channel.h   |   52 ++
 drivers/gpu/host1x/debug.c |  210 
 drivers/gpu/host1x/debug.h |   51 ++
 drivers/gpu/host1x/dev.c   |  248 +
 drivers/gpu/host1x/dev.h   |  316 +++
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |2 +-
 drivers/gpu/host1x/drm/cma.c   |   93 
 drivers/gpu/host1x/drm/cma.h   |   35 ++
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  673 
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   51 +-
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |6 +-
 drivers/gpu/host1x/drm/gr2d.c  |  330 
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   29 +
 drivers/gpu/host1x/host1x_bo.h |   92 
 drivers/gpu/host1x/host1x_client.h |   35 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  326 
 drivers/gpu/host1x/hw/channel_hw.c |  167 ++
 drivers/gpu/host1x/hw/debug_hw.c   |  322 
 drivers/gpu/host1x/hw/host1x01.c   |   42 ++
 drivers/gpu/host1x/hw/host1x01.h   |   25 +
 drivers/gpu/host1x/hw/host1x01_hardware.h  |  143 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h|  120 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h   |  243 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h |  174 ++
 drivers/gpu/host1x/hw/intr_hw.c|  143 +
 drivers/gpu/host1x/hw/syncpt_hw

[PATCHv7 05/10] gpu: host1x: Add debug support

2013-03-13 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |4 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |2 +
 drivers/gpu/host1x/hw/channel_hw.c  |   26 ++-
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 807 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 06a995b..49fd580 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
hw/host1x01.o
 
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index 33935de..de72172 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -439,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;
 
+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..cb8aff9
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2013 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
+   va_end(args);
+   o->fn(o->ctx, o->buf, len);
+}
+
+static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo)
+{
+   struct host1x *m = host1x_get_host(ch->dev);
+   struct output *o = data;
+
+   mutex_lock(&ch->reflock);
+   if (ch->refcount) {
+   mutex_lock(&ch->cdma.lock);
+   if (show_fifo)
+   host1x_hw_show_channel_fifo(m, ch, o);
+   host1x_hw_show_channel_cdma(m, ch, o);
+   mutex_unlock(&ch->cdma.lock);
+   }
+   mutex_unlock(&ch->reflock);
+
+   return 0;
+}
+
+static void show_syncpts(struct host1x *m, struct output *o)
+{
+   int i;
+   host1x_debug_output(o, " syncpts \n");
+   for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
+   u32 max = host1x_syncpt_read_max(m->syncpt + i);
+   u32 min = host1x_syncpt_load(m->syncpt + i);
+   if (!min && !max)
+   continue;
+   host1x_debug_output(o, "id %d (%s) min %d max %d\n",
+   i, m->syncpt[i].name, min, max);
+   }
+
+   for (i = 0; i < host1x_syncpt_nb_bases(m); i++) {
+   u32 base_val;
+   base_val = host1x_syncpt_load_wait_base(m->syncpt + i);
+   if (b

[PATCHv7 10/10] drm: tegra: Add gr2d device

2013-03-13 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from
DRM.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile   |1 +
 drivers/gpu/host1x/dev.c  |7 +
 drivers/gpu/host1x/drm/drm.c  |  251 ++-
 drivers/gpu/host1x/drm/drm.h  |   28 +++-
 drivers/gpu/host1x/drm/gr2d.c |  330 +
 drivers/gpu/host1x/host1x.h   |3 +-
 include/drm/tegra_drm.h   |  131 
 7 files changed, 747 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index e85db5a..29c0c6b 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/cma.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 6af8081..0091632 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -211,11 +211,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif
 
return 0;
 
 #ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -228,6 +234,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index dbd4808..9f78f52 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -8,13 +8,21 @@
  */
 
 #include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
 #include 
 
+#include "cma.h"
+#include "dev.h"
 #include "drm.h"
+#include "host1x_bo.h"
 #include "host1x_client.h"
+#include "syncpt.h"
 
 #define DRIVER_NAME "tegra"
 #define DRIVER_DESC "NVIDIA Tegra graphics"
@@ -77,8 +85,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -273,9 +283,24 @@ static int tegra_drm_unload(struct drm_device *drm)
 
 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
+   struct host1x_drm_file *fpriv;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
return 0;
 }
 
+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+   context->client->ops->close_channel(context);
+   kfree(context);
+}
+
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
struct host1x_drm *host1x = drm->dev_private;
@@ -283,7 +308,222 @@ static void tegra_drm_lastclose(struct drm_device *drm)
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
 
+static int tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+  struct drm_file *file_priv)
+{
+   struct tegra_drm_syncpt_read_args *args = data;
+   struct host1x *host = host1x_get_host(drm->dev);
+   struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id);
+
+   if (!sp)
+   return -EINVAL;
+
+   args->value = host1x_syncpt_read_min(sp);
+   return 0;
+}
+
+static int tegra_drm_ioctl_syncpt_incr(struct drm_device *drm, void *data,
+  

[PATCHv7 08/10] gpu: host1x: Remove second host1x driver

2013-03-13 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x
driver. The logic to parse device tree and track clients is moved
to drm.c.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 ++-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|5 +-
 drivers/gpu/host1x/drm/drm.c   |  217 +++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |5 +-
 drivers/gpu/host1x/drm/host1x.c|  329 
 drivers/gpu/host1x/host1x_client.h |   35 
 10 files changed, 318 insertions(+), 344 deletions(-)
 delete mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 4761e8a..9a6fc76 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -13,6 +13,6 @@ host1x-y = \
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d7c6e3e..6af8081 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -32,6 +32,19 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   return host1x->drm_data;
+}
 
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -154,6 +167,8 @@ static int host1x_probe(struct platform_device *pdev)
 
host1x_debug_init(host);
 
+   host1x_drm_alloc(pdev);
+
return 0;
 
 fail_deinit_syncpt:
@@ -170,7 +185,7 @@ static int __exit host1x_remove(struct platform_device 
*pdev)
return 0;
 }
 
-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -180,8 +195,47 @@ static struct platform_driver platform_driver = {
},
 };
 
-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_DRM_TEGRA
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);
 
+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 4a56233..ca2ba8a 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -124,6 +124,8 @@ struct host1x {
unsigned int num_allocated_channels;
 
struct dentry *debugfs;
+
+   void *drm_data;
 };
 
 static inline struct host1x *host1x_get_host(struct device *dev)
@@ -307,4 +309,8 @@ static inline void host1x_hw_show_mlocks(struct host1x 
*host, struct output *o)
host->debug_op->show_mlocks(host, o);
 }
 
+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index c92955d..8fb6545 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
s

[PATCHv7 01/10] gpu: drm: Support CMA object preallocation

2013-03-13 Thread Terje Bergstrom
From: Arto Merilainen 

This patch adds helper functions drm_gem_cma_init() and
drm_gem_cma_deinit() for handling CMA structures that already have
been allocated. This allows embedding the CMA structure inside other
structures.

Signed-off-by: Arto Merilainen 
---
 drivers/gpu/drm/drm_gem_cma_helper.c |   78 --
 include/drm/drm_gem_cma_helper.h |9 
 2 files changed, 64 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c 
b/drivers/gpu/drm/drm_gem_cma_helper.c
index 0a7e011..3b14280 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -2,6 +2,7 @@
  * drm gem CMA (contiguous memory allocator) helper functions
  *
  * Copyright (C) 2012 Sascha Hauer, Pengutronix
+ * Copyright (C) 2013 NVIDIA CORPORATION, All rights reserved.
  *
  * Based on Samsung Exynos code
  *
@@ -40,30 +41,25 @@ static void drm_gem_cma_buf_destroy(struct drm_device *drm,
 }
 
 /*
- * drm_gem_cma_create - allocate an object with the given size
+ * drm_gem_cma_object_init - allocate buffer and initialize given cma object
  *
- * returns a struct drm_gem_cma_object* on success or ERR_PTR values
- * on failure.
+ * this function allocates memory for a cma buffer and initializes the given
+ * cma object to use the allocated buffer.
  */
-struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
-   unsigned int size)
+
+int drm_gem_cma_object_init(struct drm_device *drm,
+   struct drm_gem_cma_object *cma_obj, unsigned int size)
 {
-   struct drm_gem_cma_object *cma_obj;
struct drm_gem_object *gem_obj;
int ret;
 
size = round_up(size, PAGE_SIZE);
 
-   cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
-   if (!cma_obj)
-   return ERR_PTR(-ENOMEM);
-
cma_obj->vaddr = dma_alloc_writecombine(drm->dev, size,
&cma_obj->paddr, GFP_KERNEL | __GFP_NOWARN);
if (!cma_obj->vaddr) {
dev_err(drm->dev, "failed to allocate buffer with size %d\n", 
size);
-   ret = -ENOMEM;
-   goto err_dma_alloc;
+   return -ENOMEM;
}
 
gem_obj = &cma_obj->base;
@@ -76,7 +72,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct 
drm_device *drm,
if (ret)
goto err_create_mmap_offset;
 
-   return cma_obj;
+   return 0;
 
 err_create_mmap_offset:
drm_gem_object_release(gem_obj);
@@ -84,10 +80,36 @@ err_create_mmap_offset:
 err_obj_init:
drm_gem_cma_buf_destroy(drm, cma_obj);
 
-err_dma_alloc:
-   kfree(cma_obj);
+   return ret;
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_object_init);
+
+/*
+ * drm_gem_cma_create - allocate an object with the given size
+ *
+ * returns a struct drm_gem_cma_object* on success or ERR_PTR values
+ * on failure.
+ */
+struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
+   unsigned int size)
+{
+   struct drm_gem_cma_object *cma_obj;
+   int ret;
+
+   size = round_up(size, PAGE_SIZE);
+
+   cma_obj = kzalloc(sizeof(*cma_obj), GFP_KERNEL);
+   if (!cma_obj)
+   return ERR_PTR(-ENOMEM);
+
+   ret = drm_gem_cma_object_init(drm, cma_obj, size);
+   if (ret) {
+   kfree(cma_obj);
+   return ERR_PTR(ret);
+   }
+
+   return cma_obj;
 
-   return ERR_PTR(ret);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_create);
 
@@ -133,22 +155,32 @@ err_handle_create:
 }
 
 /*
- * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback
- * function
+ * drm_gem_cma_deinit_object - deinitialize cma object
+ *
+ * this function deinitializes the given cma object without releasing the
+ * object memory. this function is a counterpart for the function
+ * drm_gem_cma_object_init().
  */
-void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
+void drm_gem_cma_object_deinit(struct drm_gem_object *gem_obj)
 {
-   struct drm_gem_cma_object *cma_obj;
+   struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem_obj);
 
if (gem_obj->map_list.map)
drm_gem_free_mmap_offset(gem_obj);
 
drm_gem_object_release(gem_obj);
-
-   cma_obj = to_drm_gem_cma_obj(gem_obj);
-
drm_gem_cma_buf_destroy(gem_obj->dev, cma_obj);
+}
+EXPORT_SYMBOL_GPL(drm_gem_cma_object_deinit);
 
+/*
+ * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback
+ * function
+ */
+void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
+{
+   struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(gem_obj);
+   drm_gem_cma_object_deinit(gem_obj);
kfree(cma_obj);
 }
 EXPORT_SYMBOL_GPL(drm_gem_cma_free_object);
diff --git a/include/drm/drm_gem_cma_helper.h b/include/drm/drm_gem_cma_helper.h
index 63397ce..5fdccb3 100644
--- a/include/drm/drm_gem_cma_helper.h
+++ b/include/drm/drm_gem_cma_helper.h
@@ -13,6 +13,10 @@ to_drm_gem_cma_obj(struct drm_gem_object *gem

[PATCHv7 07/10] gpu: host1x: drm: Rename host1x to host1x_drm

2013-03-13 Thread Terje Bergstrom
From: Arto Merilainen 

Both host1x and drm drivers have host1x structures. This patch
renames the host1x structure under drm to follow name host1x_drm.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/drm/dc.c |4 ++--
 drivers/gpu/host1x/drm/drm.c|4 ++--
 drivers/gpu/host1x/drm/drm.h|   14 +++---
 drivers/gpu/host1x/drm/fb.c |6 +++---
 drivers/gpu/host1x/drm/hdmi.c   |4 ++--
 drivers/gpu/host1x/drm/host1x.c |   22 --
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index de94707..d1f6609 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -1097,7 +1097,7 @@ static const struct host1x_client_ops dc_client_ops = {
 
 static int tegra_dc_probe(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1160,7 +1160,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
 
 static int tegra_dc_remove(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;
 
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index 9d452df..6c59bcd 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -26,7 +26,7 @@
 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 {
struct device *dev = drm->dev;
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
int err;
 
host1x = dev_get_drvdata(dev);
@@ -69,7 +69,7 @@ static int tegra_drm_open(struct drm_device *drm, struct 
drm_file *filp)
 
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index a6c011d..7fedb6c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -18,7 +18,7 @@
 #include 
 #include 
 
-struct host1x {
+struct host1x_drm {
struct drm_device *drm;
struct device *dev;
void __iomem *regs;
@@ -44,7 +44,7 @@ struct host1x_client_ops {
 };
 
 struct host1x_client {
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;
 
const struct host1x_client_ops *ops;
@@ -52,12 +52,12 @@ struct host1x_client {
struct list_head list;
 };
 
-extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm);
-extern int host1x_drm_exit(struct host1x *host1x);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);
 
-extern int host1x_register_client(struct host1x *host1x,
+extern int host1x_register_client(struct host1x_drm *host1x,
  struct host1x_client *client);
-extern int host1x_unregister_client(struct host1x *host1x,
+extern int host1x_unregister_client(struct host1x_drm *host1x,
struct host1x_client *client);
 
 struct tegra_output;
@@ -66,7 +66,7 @@ struct tegra_dc {
struct host1x_client client;
spinlock_t lock;
 
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;
 
struct drm_crtc base;
diff --git a/drivers/gpu/host1x/drm/fb.c b/drivers/gpu/host1x/drm/fb.c
index 0391495..6ed885a 100644
--- a/drivers/gpu/host1x/drm/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -11,7 +11,7 @@
 
 static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_hotplug_event(host1x->fbdev);
 }
@@ -23,7 +23,7 @@ static const struct drm_mode_config_funcs 
tegra_drm_mode_funcs = {
 
 int tegra_drm_fb_init(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
struct drm_fbdev_cma *fbdev;
 
drm->mode_config.min_width = 0;
@@ -46,7 +46,7 @@ int tegra_drm_fb_init(struct drm_device *drm)
 
 void tegra_drm_fb_exit(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_fini(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index bb747f6..f438f80 100644
--- a/drivers/gpu/host1x/drm/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -1189,7 +1189,7 @@ st

[PATCHv7 02/10] gpu: host1x: Add host1x driver

2013-03-13 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D. The Tegra
host1x module is the DMA engine for register access to Tegra's
graphics- and multimedia-related modules. The modules served by
host1x are referred to as clients. host1x includes some other
functionality, such as synchronization.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|9 ++
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  155 +
 drivers/gpu/host1x/dev.h  |  104 ++
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   33 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   27 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   74 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  102 ++
 drivers/gpu/host1x/syncpt.c   |  212 +
 drivers/gpu/host1x/syncpt.h   |  147 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 +
 15 files changed, 966 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 30879df..d8a22c2 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..c01c450
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_HOST1X
+   tristate "NVIDIA Tegra host1x driver"
+   help
+ Driver for the NVIDIA Tegra host1x hardware.
+
+ The Tegra host1x module is the DMA engine for register access to
+ Tegra's graphics- and multimedia-related modules. The modules served
+ by host1x are referred to as clients. host1x includes some other
+ functionality, such as synchronization.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..d95a9b2
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,155 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#include "dev.h"
+#include "hw/host1x01.h"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static const struct host1x_info host1x01_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
+   { .compatible = &quo

[PATCHv7 09/10] gpu: host1x: drm: Add CMA ops for host1x driver

2013-03-13 Thread Terje Bergstrom
From: Arto Merilainen 

This patch implements a CMA memory handler for the host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/drm/cma.c |   93 ++
 drivers/gpu/host1x/drm/cma.h |   35 
 3 files changed, 129 insertions(+)
 create mode 100644 drivers/gpu/host1x/drm/cma.c
 create mode 100644 drivers/gpu/host1x/drm/cma.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 9a6fc76..e85db5a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -15,4 +15,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/cma.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/drm/cma.c b/drivers/gpu/host1x/drm/cma.c
new file mode 100644
index 000..cf86fce
--- /dev/null
+++ b/drivers/gpu/host1x/drm/cma.c
@@ -0,0 +1,93 @@
+/*
+ * Tegra host1x CMA support
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "cma.h"
+#include "host1x_bo.h"
+
+static void cma_put(struct host1x_bo *bo)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   struct drm_device *drm = cma_bo->cma_obj.base.dev;
+
+   mutex_lock(&drm->struct_mutex);
+   drm_gem_object_unreference(&cma_bo->cma_obj.base);
+   mutex_unlock(&drm->struct_mutex);
+}
+
+static dma_addr_t cma_pin(struct host1x_bo *bo, struct sg_table **sgt)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   return cma_bo->cma_obj.paddr;
+}
+
+static void cma_unpin(struct host1x_bo *bo, struct sg_table *sgt)
+{
+}
+
+static void *cma_mmap(struct host1x_bo *bo)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   return cma_bo->cma_obj.vaddr;
+}
+
+static void cma_munmap(struct host1x_bo *bo, void *addr)
+{
+}
+
+static void *cma_kmap(struct host1x_bo *bo, unsigned int pagenum)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   return cma_bo->cma_obj.vaddr + pagenum * PAGE_SIZE;
+}
+
+static void cma_kunmap(struct host1x_bo *bo, unsigned int pagenum, void *addr)
+{
+}
+
+static struct host1x_bo *cma_get(struct host1x_bo *bo)
+{
+   struct tegra_drm_bo *cma_bo =
+   container_of(bo, struct tegra_drm_bo, base);
+   struct drm_device *drm = cma_bo->cma_obj.base.dev;
+
+   mutex_lock(&drm->struct_mutex);
+   drm_gem_object_reference(&cma_bo->cma_obj.base);
+   mutex_unlock(&drm->struct_mutex);
+
+   return bo;
+}
+
+const struct host1x_bo_ops tegra_drm_bo_ops = {
+   .get = cma_get,
+   .put = cma_put,
+   .pin = cma_pin,
+   .unpin = cma_unpin,
+   .mmap = cma_mmap,
+   .munmap = cma_munmap,
+   .kmap = cma_kmap,
+   .kunmap = cma_kunmap,
+};
diff --git a/drivers/gpu/host1x/drm/cma.h b/drivers/gpu/host1x/drm/cma.h
new file mode 100644
index 000..f35cebd
--- /dev/null
+++ b/drivers/gpu/host1x/drm/cma.h
@@ -0,0 +1,35 @@
+/*
+ * Tegra host1x cma memory manager
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __HOST1X_CMA_H
+#define __HOST1X_CMA_H
+
+#include 
+#include 
+#include 
+
+#include "host1x_bo.h"
+
+struct tegra_drm_bo {
+   struct host1x_bo base;
+   struct drm_gem_cma_object cma_obj;
+};
+
+extern const struct host1x_bo_ops tegra_d

[PATCHv7 03/10] gpu: host1x: Add syncpoint wait and interrupts

2013-03-13 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   12 ++
 drivers/gpu/host1x/dev.h |   51 +
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  143 +
 drivers/gpu/host1x/intr.c|  328 ++
 drivers/gpu/host1x/intr.h|   96 +
 drivers/gpu/host1x/syncpt.c  |  159 +++
 drivers/gpu/host1x/syncpt.h  |   14 +-
 10 files changed, 847 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o
 
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d95a9b2..4421e28 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
 #include 
 
 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"
 
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
@@ -127,12 +128,23 @@ static int host1x_probe(struct platform_device *pdev)
return err;
}
 
+   err = host1x_intr_init(host, syncpt_irq);
+   if (err) {
+   dev_err(dev, "failed to init irq");
+   goto fail_deinit_syncpt;
+   }
+
return 0;
+
+fail_deinit_syncpt:
+   host1x_syncpt_deinit(host);
+   return err;
 }
 
 static int __exit host1x_remove(struct platform_device *pdev)
 {
struct host1x *host = platform_get_drvdata(pdev);
+   host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
return 0;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 750daa3..fb5f842 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -21,6 +21,7 @@
 #include 
 
 #include "syncpt.h"
+#include "intr.h"
 
 struct host1x_syncpt;
 
@@ -33,6 +34,17 @@ struct host1x_syncpt_ops {
int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };
 
+struct host1x_intr_ops {
+   int (*init_host_sync)(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *work));
+   void (*set_syncpt_threshold)(
+   struct host1x *host, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x *host);
+   int (*free_syncpt_irq)(struct host1x *host);
+};
+
 struct host1x_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -50,7 +62,13 @@ struct host1x {
struct device *dev;
struct clk *clk;
 
+   struct mutex intr_mutex;
+   struct workqueue_struct *intr_wq;
+   int intr_syncpt_irq;
+
const struct host1x_syncpt_ops *syncpt_op;
+   const struct host1x_intr_ops *intr_op;
+
 };
 
 static inline struct host1x *host1x_get_host(struct device *dev)
@@ -101,4 +119,37 @@ static inline int host1x_hw_syncpt_patch_wait(struct 
host1x *host,
return host->syncpt_op->patch_wait(sp, patch_addr);
 }
 
+static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *))
+{
+   return host->intr_op->init_host_sync(host, cpm, syncpt_thresh_work);
+}
+
+static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
+  u32 id, u32 thresh)
+{
+   host->intr_op->set_syncpt_threshold(host, id, thresh);
+}
+
+static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
+u32 id)
+{
+   host->intr_op->enable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
+ u32 id)
+{
+   host->intr_op->disable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
+{
+   host->intr_op->disable_all_syncpt_intrs(host);
+}
+
+static inline int host1x_hw_intr_free

[PATCHv7 06/10] drm: tegra: Move drm to live under host1x

2013-03-13 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |2 ++
 drivers/gpu/host1x/Makefile|5 +
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 16 files changed, 10 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1e82882..9031bb7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -215,8 +215,6 @@ source "drivers/gpu/drm/cirrus/Kconfig"
 
 source "drivers/gpu/drm/shmobile/Kconfig"
 
-source "drivers/gpu/drm/tegra/Kconfig"
-
 source "drivers/gpu/drm/omapdrm/Kconfig"
 
 source "drivers/gpu/drm/tilcdc/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d59b24..847b830 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 00f0859..ee3af1e 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -18,4 +18,6 @@ config TEGRA_HOST1X_FIREWALL
 
  If unsure, choose Y.
 
+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 49fd580..4761e8a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -10,4 +10,9 @@ host1x-y = \
debug.o \
hw/host1x01.o
 
+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 6dd75a2..a6c011d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -7,8 +7,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef TEGRA_DRM_H
-#define TEGRA_D

[PATCHv7 00/10] Support for Tegra 2D hardware

2013-03-13 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130307.

Changes in this version:
 * host1x memory data structures refactored
 * Some "nvhost" leftovers renamed to host1x

Changes in previous version 6:
 * Rebased on latest tegradrm
 * Renamed tegradrm's host1x to host1x_drm
 * Indentation and line split fixed to follow tegradrm convention
 * Pointers to platform_device replaced with pointers to device
 * Added host1x allocator, and wired it in
 * Debug spew code fixed to access mem handles from host1x_job
 * CDMA code doesn't keep the mem handles anymore
 * Push buffer ops have been made generic code
 * Removed the pin_array optimization in host1x_job to simplify code
 * Large number of smaller changes

The driver implements an allocator using the DRM CMA helper. Each buffer is
assigned an ops structure to operate on it. In future the DRM CMA helper will
be replaced with an own allocator to implement IOMMU support.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page http://http.download.nvidia.com/tegra-public-appnotes/host1x.html
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

The changes to add support to libdrm are in
g...@gitorious.org:linux-host1x/libdrm-host1x.git

Arto Merilainen (3):
  gpu: drm: Support CMA object preallocation
  gpu: host1x: drm: Rename host1x to host1x_drm
  gpu: host1x: drm: Add CMA ops for host1x driver

Terje Bergstrom (7):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  drm: tegra: Add gr2d device

 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/drm_gem_cma_helper.c   |   78 ++-
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  217 
 drivers/gpu/drm/tegra/host1x.c |  327 
 drivers/gpu/host1x/Kconfig |   23 +
 drivers/gpu/host1x/Makefile|   20 +
 drivers/gpu/host1x/cdma.c  |  491 +
 drivers/gpu/host1x/cdma.h  |  100 
 drivers/gpu/host1x/channel.c   |  120 +
 drivers/gpu/host1x/channel.h   |   52 ++
 drivers/gpu/host1x/debug.c |  210 
 drivers/gpu/host1x/debug.h |   51 ++
 drivers/gpu/host1x/dev.c   |  248 +
 drivers/gpu/host1x/dev.h   |  316 +++
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |2 +-
 drivers/gpu/host1x/drm/cma.c   |   93 
 drivers/gpu/host1x/drm/cma.h   |   35 ++
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  673 
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   51 +-
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |6 +-
 drivers/gpu/host1x/drm/gr2d.c  |  330 
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   29 +
 drivers/gpu/host1x/host1x_bo.h |   92 
 drivers/gpu/host1x/host1x_client.h |   35 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  326 
 drivers/gpu/host1x/hw/channel_hw.c |  167 ++
 drivers/gpu/host1x/hw/debug_hw.c   |  322 
 drivers/gpu/host1x/hw/host1x01.c   |   42 ++
 drivers/gpu/host1x/hw/host1x01.h   |   25 +
 drivers/gpu/host1x/hw/host1x01_hardware.h  |  143 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h|  120 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h   |  243 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h |  174 ++
 drivers/gpu/host1x/hw/intr_hw.c|  143 +
 drivers/gpu/host1x/hw/syncpt_hw.c 

[PATCHv6 9/9] drm: tegra: Add gr2d device

2013-03-08 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from
DRM.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile   |1 +
 drivers/gpu/host1x/dev.c  |7 +
 drivers/gpu/host1x/drm/drm.c  |  239 +-
 drivers/gpu/host1x/drm/drm.h  |   28 +++-
 drivers/gpu/host1x/drm/gr2d.c |  325 +
 drivers/gpu/host1x/host1x.h   |3 +-
 include/drm/tegra_drm.h   |  131 +
 7 files changed, 730 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index d1d7e35..d90168f 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -17,4 +17,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/cma.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 6af8081..0091632 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -211,11 +211,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif

return 0;

 #ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -228,6 +234,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index dbd4808..1f0754a 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -8,13 +8,17 @@
  */

 #include 
+#include 
 #include 
 #include 
 #include 
 #include 

+#include "cma.h"
+#include "dev.h"
 #include "drm.h"
 #include "host1x_client.h"
+#include "syncpt.h"

 #define DRIVER_NAME "tegra"
 #define DRIVER_DESC "NVIDIA Tegra graphics"
@@ -77,8 +81,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -273,9 +279,24 @@ static int tegra_drm_unload(struct drm_device *drm)

 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
+   struct host1x_drm_file *fpriv;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
return 0;
 }

+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+   context->client->ops->close_channel(context);
+   kfree(context);
+}
+
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
struct host1x_drm *host1x = drm->dev_private;
@@ -283,7 +304,214 @@ static void tegra_drm_lastclose(struct drm_device *drm)
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }

+static int tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+  struct drm_file *file_priv)
+{
+   struct tegra_drm_syncpt_read_args *args = data;
+   struct host1x *host = host1x_get_host(drm->dev);
+   struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id);
+
+   if (!sp)
+   return -EINVAL;
+
+   args->value = host1x_syncpt_read_min(sp);
+   return 0;
+}
+
+static int tegra_drm_ioctl_syncpt_incr(struct drm_device *drm, void *data,
+  struct drm_file *file_priv)
+{
+ 

[PATCHv6 8/9] gpu: host1x: drm: Add CMA ops for host1x driver

2013-03-08 Thread Terje Bergstrom
From: Arto Merilainen 

This patch adds CMA memory operations for host1x driver. This allows
usage of CMA buffers inside host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/drm/cma.c |   87 ++
 drivers/gpu/host1x/drm/cma.h |   26 +
 3 files changed, 114 insertions(+)
 create mode 100644 drivers/gpu/host1x/drm/cma.c
 create mode 100644 drivers/gpu/host1x/drm/cma.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index ad39fef..d1d7e35 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/cma.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/drm/cma.c b/drivers/gpu/host1x/drm/cma.c
new file mode 100644
index 000..1c5d000
--- /dev/null
+++ b/drivers/gpu/host1x/drm/cma.c
@@ -0,0 +1,87 @@
+/*
+ * Tegra host1x CMA support
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "memmgr.h"
+
+static void cma_put(void *handle_data)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   struct drm_device *drm = obj->base.dev;
+
+   mutex_lock(&drm->struct_mutex);
+   drm_gem_object_unreference(&obj->base);
+   mutex_unlock(&drm->struct_mutex);
+}
+
+static dma_addr_t cma_pin(void *handle_data, struct sg_table **sgt)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   return obj->paddr;
+}
+
+static void cma_unpin(void *handle_data, struct sg_table *sgt)
+{
+}
+
+static void *cma_mmap(void *handle_data)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   return obj->vaddr;
+}
+
+static void cma_munmap(void *handle_data, void *addr)
+{
+}
+
+static void *cma_kmap(void *handle_data, unsigned int pagenum)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   return obj->vaddr + pagenum * PAGE_SIZE;
+}
+
+static void cma_kunmap(void *handle_data, unsigned int pagenum, void *addr)
+{
+}
+
+static struct host1x_mem_handle *cma_get(void *handle_data)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   struct drm_device *drm = obj->base.dev;
+
+   mutex_lock(&drm->struct_mutex);
+   drm_gem_object_reference(&obj->base);
+   mutex_unlock(&drm->struct_mutex);
+
+   return obj->base.driver_private;
+}
+
+const struct host1x_mem_op host1x_cma_ops = {
+   .get = cma_get,
+   .put = cma_put,
+   .pin = cma_pin,
+   .unpin = cma_unpin,
+   .mmap = cma_mmap,
+   .munmap = cma_munmap,
+   .kmap = cma_kmap,
+   .kunmap = cma_kunmap,
+};
diff --git a/drivers/gpu/host1x/drm/cma.h b/drivers/gpu/host1x/drm/cma.h
new file mode 100644
index 000..06aa0ba
--- /dev/null
+++ b/drivers/gpu/host1x/drm/cma.h
@@ -0,0 +1,26 @@
+/*
+ * Tegra host1x cma memory manager
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __HOST1X_CMA_H
+#define __HOST1X_CMA_H
+
+#include "memmgr.h"
+
+extern const struct host1x_mem_op host1x_cma_ops;
+
+#endif
-- 
1.7.9.5



[PATCHv6 7/9] gpu: host1x: Remove second host1x driver

2013-03-08 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x
driver. The logic to parse device tree and track clients is moved
to drm.c.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 ++-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|5 +-
 drivers/gpu/host1x/drm/drm.c   |  217 +++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |5 +-
 drivers/gpu/host1x/drm/host1x.c|  329 
 drivers/gpu/host1x/host1x_client.h |   35 
 10 files changed, 318 insertions(+), 344 deletions(-)
 delete mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index db4dc25..ad39fef 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -14,6 +14,6 @@ host1x-y = \
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d7c6e3e..6af8081 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -32,6 +32,19 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   return host1x->drm_data;
+}

 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -154,6 +167,8 @@ static int host1x_probe(struct platform_device *pdev)

host1x_debug_init(host);

+   host1x_drm_alloc(pdev);
+
return 0;

 fail_deinit_syncpt:
@@ -170,7 +185,7 @@ static int __exit host1x_remove(struct platform_device 
*pdev)
return 0;
 }

-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -180,8 +195,47 @@ static struct platform_driver platform_driver = {
},
 };

-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_DRM_TEGRA
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);

+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 3542c00..e74ed4a 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -125,6 +125,8 @@ struct host1x {
unsigned int num_allocated_channels;

struct dentry *debugfs;
+
+   void *drm_data;
 };

 static inline struct host1x *host1x_get_host(struct device *dev)
@@ -308,4 +310,8 @@ static inline void host1x_hw_show_mlocks(struct host1x 
*host, struct output *o)
host->debug_op->show_mlocks(host, o);
 }

+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index c92955d..8fb6545 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
select DRM_K

[PATCHv6 6/9] gpu: host1x: drm: Rename host1x to host1x_drm

2013-03-08 Thread Terje Bergstrom
From: Arto Merilainen 

Both host1x and drm drivers have host1x structures. This patch
renames the host1x structure under drm to follow name host1x_drm.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/drm/dc.c |4 ++--
 drivers/gpu/host1x/drm/drm.c|4 ++--
 drivers/gpu/host1x/drm/drm.h|   14 +++---
 drivers/gpu/host1x/drm/fb.c |6 +++---
 drivers/gpu/host1x/drm/hdmi.c   |4 ++--
 drivers/gpu/host1x/drm/host1x.c |   22 --
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index de94707..d1f6609 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -1097,7 +1097,7 @@ static const struct host1x_client_ops dc_client_ops = {

 static int tegra_dc_probe(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1160,7 +1160,7 @@ static int tegra_dc_probe(struct platform_device *pdev)

 static int tegra_dc_remove(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;

diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index 9d452df..6c59bcd 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -26,7 +26,7 @@
 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 {
struct device *dev = drm->dev;
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
int err;

host1x = dev_get_drvdata(dev);
@@ -69,7 +69,7 @@ static int tegra_drm_open(struct drm_device *drm, struct 
drm_file *filp)

 static void tegra_drm_lastclose(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index a6c011d..7fedb6c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -18,7 +18,7 @@
 #include 
 #include 

-struct host1x {
+struct host1x_drm {
struct drm_device *drm;
struct device *dev;
void __iomem *regs;
@@ -44,7 +44,7 @@ struct host1x_client_ops {
 };

 struct host1x_client {
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;

const struct host1x_client_ops *ops;
@@ -52,12 +52,12 @@ struct host1x_client {
struct list_head list;
 };

-extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm);
-extern int host1x_drm_exit(struct host1x *host1x);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);

-extern int host1x_register_client(struct host1x *host1x,
+extern int host1x_register_client(struct host1x_drm *host1x,
  struct host1x_client *client);
-extern int host1x_unregister_client(struct host1x *host1x,
+extern int host1x_unregister_client(struct host1x_drm *host1x,
struct host1x_client *client);

 struct tegra_output;
@@ -66,7 +66,7 @@ struct tegra_dc {
struct host1x_client client;
spinlock_t lock;

-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;

struct drm_crtc base;
diff --git a/drivers/gpu/host1x/drm/fb.c b/drivers/gpu/host1x/drm/fb.c
index 0391495..6ed885a 100644
--- a/drivers/gpu/host1x/drm/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -11,7 +11,7 @@

 static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_hotplug_event(host1x->fbdev);
 }
@@ -23,7 +23,7 @@ static const struct drm_mode_config_funcs 
tegra_drm_mode_funcs = {

 int tegra_drm_fb_init(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
struct drm_fbdev_cma *fbdev;

drm->mode_config.min_width = 0;
@@ -46,7 +46,7 @@ int tegra_drm_fb_init(struct drm_device *drm)

 void tegra_drm_fb_exit(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;

drm_fbdev_cma_fini(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index bb747f6..f438f80 100644
--- a/drivers/gpu/host1x/drm/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -1189,7 +1189,7 @@ static const struct

[PATCHv6 5/9] drm: tegra: Move drm to live under host1x

2013-03-08 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |2 ++
 drivers/gpu/host1x/Makefile|5 +
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 16 files changed, 10 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1e82882..9031bb7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -215,8 +215,6 @@ source "drivers/gpu/drm/cirrus/Kconfig"

 source "drivers/gpu/drm/shmobile/Kconfig"

-source "drivers/gpu/drm/tegra/Kconfig"
-
 source "drivers/gpu/drm/omapdrm/Kconfig"

 source "drivers/gpu/drm/tilcdc/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d59b24..847b830 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 00f0859..ee3af1e 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -18,4 +18,6 @@ config TEGRA_HOST1X_FIREWALL

  If unsure, choose Y.

+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index dfc6f35..db4dc25 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -11,4 +11,9 @@ host1x-y = \
memmgr.o \
hw/host1x01.o

+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 6dd75a2..a6c011d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -7,8 +7,8 @@
  * published by the Free Software Foundation.
  */

-#ifndef TEGRA_DRM_H
-#define TEGRA_

[PATCHv6 4/9] gpu: host1x: Add debug support

2013-03-08 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |5 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |3 +
 drivers/gpu/host1x/hw/channel_hw.c  |   27 ++-
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 810 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 7278bf3..dfc6f35 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
memmgr.o \
hw/host1x01.o

diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index a45bb94..f3167bf 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -29,6 +29,7 @@
 #include "cdma.h"
 #include "channel.h"
 #include "dev.h"
+#include "debug.h"
 #include "job.h"
 #include "memmgr.h"

@@ -438,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;

+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..cb8aff9
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2013 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
+   va_end(args);
+   o->fn(o->ctx, o->buf, len);
+}
+
+static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo)
+{
+   struct host1x *m = host1x_get_host(ch->dev);
+   struct output *o = data;
+
+   mutex_lock(&ch->reflock);
+   if (ch->refcount) {
+   mutex_lock(&ch->cdma.lock);
+   if (show_fifo)
+   host1x_hw_show_channel_fifo(m, ch, o);
+   host1x_hw_show_channel_cdma(m, ch, o);
+   mutex_unlock(&ch->cdma.lock);
+   }
+   mutex_unlock(&ch->reflock);
+
+   return 0;
+}
+
+static void show_syncpts(struct host1x *m, struct output *o)
+{
+   int i;
+   host1x_debug_output(o, " syncpts \n");
+   for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
+   u32 max = host1x_syncpt_read_max(m->syncpt + i);
+   u32 min = host1x_syncpt_load(m->syncpt + i);
+   if (!min && !max)
+   continue;
+   host1x_debug_output(o, "id %d (%s) min %d max %d\n",
+   i, m->syncpt[i].name, min, max);
+   }
+
+   for (i = 0; i < host1x_syncpt_nb

[PATCHv6 3/9] gpu: host1x: Add channel support

2013-03-08 Thread Terje Bergstrom
Add support for host1x client modules, and host1x channels to submit
work to the clients.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Kconfig  |   12 +
 drivers/gpu/host1x/Makefile |4 +
 drivers/gpu/host1x/cdma.c   |  486 ++
 drivers/gpu/host1x/cdma.h   |  102 +
 drivers/gpu/host1x/channel.c|  120 ++
 drivers/gpu/host1x/channel.h|   52 +++
 drivers/gpu/host1x/dev.c|   17 +
 drivers/gpu/host1x/dev.h|  114 +
 drivers/gpu/host1x/host1x.h |   28 ++
 drivers/gpu/host1x/hw/cdma_hw.c |  324 +++
 drivers/gpu/host1x/hw/channel_hw.c  |  142 +++
 drivers/gpu/host1x/hw/host1x01.c|5 +
 drivers/gpu/host1x/hw/host1x01_hardware.h   |  116 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |  102 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|   12 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |  168 
 drivers/gpu/host1x/hw/syncpt_hw.c   |   11 +
 drivers/gpu/host1x/intr.c   |   28 +-
 drivers/gpu/host1x/intr.h   |6 +
 drivers/gpu/host1x/job.c|  598 +++
 drivers/gpu/host1x/job.h|  158 +++
 drivers/gpu/host1x/memmgr.c |   82 
 drivers/gpu/host1x/memmgr.h |   64 +++
 drivers/gpu/host1x/syncpt.c |   11 +
 drivers/gpu/host1x/syncpt.h |6 +
 include/trace/events/host1x.h   |  211 ++
 26 files changed, 2978 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/cdma.c
 create mode 100644 drivers/gpu/host1x/cdma.h
 create mode 100644 drivers/gpu/host1x/channel.c
 create mode 100644 drivers/gpu/host1x/channel.h
 create mode 100644 drivers/gpu/host1x/host1x.h
 create mode 100644 drivers/gpu/host1x/hw/cdma_hw.c
 create mode 100644 drivers/gpu/host1x/hw/channel_hw.c
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_channel.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_uclass.h
 create mode 100644 drivers/gpu/host1x/job.c
 create mode 100644 drivers/gpu/host1x/job.h
 create mode 100644 drivers/gpu/host1x/memmgr.c
 create mode 100644 drivers/gpu/host1x/memmgr.h

diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index c01c450..00f0859 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -7,3 +7,15 @@ config TEGRA_HOST1X
  Tegra's graphics- and multimedia-related modules. The modules served
  by host1x are referred to as clients. host1x includes some other
  functionality, such as synchronization.
+
+if TEGRA_HOST1X
+
+config TEGRA_HOST1X_FIREWALL
+   bool "Enable HOST1X security firewall"
+   default y
+   help
+ Say yes if kernel should protect command streams from tampering.
+
+ If unsure, choose Y.
+
+endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 5ef47ff..7278bf3 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -4,6 +4,10 @@ host1x-y = \
syncpt.o \
dev.o \
intr.o \
+   cdma.o \
+   channel.o \
+   job.o \
+   memmgr.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
new file mode 100644
index 000..a45bb94
--- /dev/null
+++ b/drivers/gpu/host1x/cdma.c
@@ -0,0 +1,486 @@
+/*
+ * Tegra host1x Command DMA
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "cdma.h"
+#include "channel.h"
+#include "dev.h"
+#include "job.h"
+#include "memmgr.h"
+
+/*
+ * push_buffer
+ *
+ * The push buffer is a circular array of words to be fetched by command DMA.
+ * Note that it works slightly differently to the sync queue; fence == pos
+ * means that the push buffer is full, not empty.
+ */
+
+#define HOST1X_PUSHBUFFER_SLOTS512
+
+/*
+ * Clean up push buffer resources
+ */
+static void host1x_pushbuffer_destroy(struct push_buffer *pb)
+{
+   struct host1x_cdma *cdm

[PATCHv6 2/9] gpu: host1x: Add syncpoint wait and interrupts

2013-03-08 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   12 ++
 drivers/gpu/host1x/dev.h |   51 +
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  143 +
 drivers/gpu/host1x/intr.c|  328 ++
 drivers/gpu/host1x/intr.h|   96 +
 drivers/gpu/host1x/syncpt.c  |  159 +++
 drivers/gpu/host1x/syncpt.h  |   14 +-
 10 files changed, 847 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d95a9b2..4421e28 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
 #include 

 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"

 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
@@ -127,12 +128,23 @@ static int host1x_probe(struct platform_device *pdev)
return err;
}

+   err = host1x_intr_init(host, syncpt_irq);
+   if (err) {
+   dev_err(dev, "failed to init irq");
+   goto fail_deinit_syncpt;
+   }
+
return 0;
+
+fail_deinit_syncpt:
+   host1x_syncpt_deinit(host);
+   return err;
 }

 static int __exit host1x_remove(struct platform_device *pdev)
 {
struct host1x *host = platform_get_drvdata(pdev);
+   host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
return 0;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 750daa3..fb5f842 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -21,6 +21,7 @@
 #include 

 #include "syncpt.h"
+#include "intr.h"

 struct host1x_syncpt;

@@ -33,6 +34,17 @@ struct host1x_syncpt_ops {
int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };

+struct host1x_intr_ops {
+   int (*init_host_sync)(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *work));
+   void (*set_syncpt_threshold)(
+   struct host1x *host, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x *host);
+   int (*free_syncpt_irq)(struct host1x *host);
+};
+
 struct host1x_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -50,7 +62,13 @@ struct host1x {
struct device *dev;
struct clk *clk;

+   struct mutex intr_mutex;
+   struct workqueue_struct *intr_wq;
+   int intr_syncpt_irq;
+
const struct host1x_syncpt_ops *syncpt_op;
+   const struct host1x_intr_ops *intr_op;
+
 };

 static inline struct host1x *host1x_get_host(struct device *dev)
@@ -101,4 +119,37 @@ static inline int host1x_hw_syncpt_patch_wait(struct 
host1x *host,
return host->syncpt_op->patch_wait(sp, patch_addr);
 }

+static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *))
+{
+   return host->intr_op->init_host_sync(host, cpm, syncpt_thresh_work);
+}
+
+static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
+  u32 id, u32 thresh)
+{
+   host->intr_op->set_syncpt_threshold(host, id, thresh);
+}
+
+static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
+u32 id)
+{
+   host->intr_op->enable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
+ u32 id)
+{
+   host->intr_op->disable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
+{
+   host->intr_op->disable_all_syncpt_intrs(host);
+}
+
+static inline int host1x_hw_intr_free_syncpt_irq(s

[PATCHv6 1/9] gpu: host1x: Add host1x driver

2013-03-08 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D. The Tegra
host1x module is the DMA engine for register access to Tegra's
graphics- and multimedia-related modules. The modules served by
host1x are referred to as clients. host1x includes some other
functionality, such as synchronization.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|9 ++
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  155 +
 drivers/gpu/host1x/dev.h  |  104 ++
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   33 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   27 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   74 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  102 ++
 drivers/gpu/host1x/syncpt.c   |  212 +
 drivers/gpu/host1x/syncpt.h   |  147 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 +
 15 files changed, 966 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 30879df..d8a22c2 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..c01c450
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_HOST1X
+   tristate "NVIDIA Tegra host1x driver"
+   help
+ Driver for the NVIDIA Tegra host1x hardware.
+
+ The Tegra host1x module is the DMA engine for register access to
+ Tegra's graphics- and multimedia-related modules. The modules served
+ by host1x are referred to as clients. host1x includes some other
+ functionality, such as synchronization.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..d95a9b2
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,155 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#include "dev.h"
+#include "hw/host1x01.h"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static const struct host1x_info host1x01_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
+   { .compatible = &quo

[PATCHv6 0/9] Support for Tegra 2D hardware

2013-03-08 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130307.

Changes in this version:
 * Rebased on latest tegradrm
 * Renamed tegradrm's host1x to host1x_drm
 * Indentation and line split fixed to follow tegradrm convention
 * Pointers to platform_device replaced with pointers to device
 * Added host1x allocator, and wired it in
 * Debug spew code fixed to access mem handles from host1x_job
 * CDMA code doesn't keep the mem handles anymore
 * Push buffer ops have been made generic code
 * Removed the pin_array optimization in host1x_job to simplify code
 * Large number of smaller changes

The driver implements an allocator using the DRM CMA helper. Each buffer is
assigned an ops structure to operate on it. In future the DRM CMA helper will
be replaced with an own allocator to implement IOMMU support.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page http://http.download.nvidia.com/tegra-public-appnotes/host1x.html
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

The changes to add support to libdrm are in
git at gitorious.org:linux-host1x/libdrm-host1x.git

Arto Merilainen (2):
  gpu: host1x: drm: Rename host1x to host1x_drm
  gpu: host1x: drm: Add CMA ops for host1x driver

Terje Bergstrom (7):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  drm: tegra: Add gr2d device

 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  217 
 drivers/gpu/drm/tegra/host1x.c |  327 
 drivers/gpu/host1x/Kconfig |   23 +
 drivers/gpu/host1x/Makefile|   21 +
 drivers/gpu/host1x/cdma.c  |  491 ++
 drivers/gpu/host1x/cdma.h  |  102 
 drivers/gpu/host1x/channel.c   |  120 +
 drivers/gpu/host1x/channel.h   |   52 ++
 drivers/gpu/host1x/debug.c |  210 
 drivers/gpu/host1x/debug.h |   51 ++
 drivers/gpu/host1x/dev.c   |  248 +
 drivers/gpu/host1x/dev.h   |  317 
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |2 +-
 drivers/gpu/host1x/drm/cma.c   |   87 
 drivers/gpu/host1x/drm/cma.h   |   26 +
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  661 
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   51 +-
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |6 +-
 drivers/gpu/host1x/drm/gr2d.c  |  325 
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   29 ++
 drivers/gpu/host1x/host1x_client.h |   35 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  327 
 drivers/gpu/host1x/hw/channel_hw.c |  167 ++
 drivers/gpu/host1x/hw/debug_hw.c   |  322 
 drivers/gpu/host1x/hw/host1x01.c   |   42 ++
 drivers/gpu/host1x/hw/host1x01.h   |   25 +
 drivers/gpu/host1x/hw/host1x01_hardware.h  |  143 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h|  120 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h   |  243 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h |  174 +++
 drivers/gpu/host1x/hw/intr_hw.c|  143 +
 drivers/gpu/host1x/hw/syncpt_hw.c  |  114 
 drivers/gpu/host1x/intr.c  |  354 +
 drivers/gpu/host1x/intr.h  |  102 
 drivers/gpu/host1x/job.c   |  598 +
 drivers/gpu/host1x/job.h   |  15

[PATCHv6 1/9] gpu: host1x: Add host1x driver

2013-03-08 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D. The Tegra
host1x module is the DMA engine for register access to Tegra's
graphics- and multimedia-related modules. The modules served by
host1x are referred to as clients. host1x includes some other
functionality, such as synchronization.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|9 ++
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  155 +
 drivers/gpu/host1x/dev.h  |  104 ++
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   33 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   27 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   74 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  102 ++
 drivers/gpu/host1x/syncpt.c   |  212 +
 drivers/gpu/host1x/syncpt.h   |  147 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 +
 15 files changed, 966 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index 30879df..d8a22c2 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..c01c450
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,9 @@
+config TEGRA_HOST1X
+   tristate "NVIDIA Tegra host1x driver"
+   help
+ Driver for the NVIDIA Tegra host1x hardware.
+
+ The Tegra host1x module is the DMA engine for register access to
+ Tegra's graphics- and multimedia-related modules. The modules served
+ by host1x are referred to as clients. host1x includes some other
+ functionality, such as synchronization.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..d95a9b2
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,155 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#include "dev.h"
+#include "hw/host1x01.h"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info->sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static const struct host1x_info host1x01_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x01_info, },
+   { .compatible = &quo

[PATCHv6 8/9] gpu: host1x: drm: Add CMA ops for host1x driver

2013-03-08 Thread Terje Bergstrom
From: Arto Merilainen 

This patch adds CMA memory operations for host1x driver. This allows
usage of CMA buffers inside host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/drm/cma.c |   87 ++
 drivers/gpu/host1x/drm/cma.h |   26 +
 3 files changed, 114 insertions(+)
 create mode 100644 drivers/gpu/host1x/drm/cma.c
 create mode 100644 drivers/gpu/host1x/drm/cma.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index ad39fef..d1d7e35 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,4 +16,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/cma.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/drm/cma.c b/drivers/gpu/host1x/drm/cma.c
new file mode 100644
index 000..1c5d000
--- /dev/null
+++ b/drivers/gpu/host1x/drm/cma.c
@@ -0,0 +1,87 @@
+/*
+ * Tegra host1x CMA support
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include "memmgr.h"
+
+static void cma_put(void *handle_data)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   struct drm_device *drm = obj->base.dev;
+
+   mutex_lock(&drm->struct_mutex);
+   drm_gem_object_unreference(&obj->base);
+   mutex_unlock(&drm->struct_mutex);
+}
+
+static dma_addr_t cma_pin(void *handle_data, struct sg_table **sgt)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   return obj->paddr;
+}
+
+static void cma_unpin(void *handle_data, struct sg_table *sgt)
+{
+}
+
+static void *cma_mmap(void *handle_data)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   return obj->vaddr;
+}
+
+static void cma_munmap(void *handle_data, void *addr)
+{
+}
+
+static void *cma_kmap(void *handle_data, unsigned int pagenum)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   return obj->vaddr + pagenum * PAGE_SIZE;
+}
+
+static void cma_kunmap(void *handle_data, unsigned int pagenum, void *addr)
+{
+}
+
+static struct host1x_mem_handle *cma_get(void *handle_data)
+{
+   struct drm_gem_cma_object *obj = handle_data;
+   struct drm_device *drm = obj->base.dev;
+
+   mutex_lock(&drm->struct_mutex);
+   drm_gem_object_reference(&obj->base);
+   mutex_unlock(&drm->struct_mutex);
+
+   return obj->base.driver_private;
+}
+
+const struct host1x_mem_op host1x_cma_ops = {
+   .get = cma_get,
+   .put = cma_put,
+   .pin = cma_pin,
+   .unpin = cma_unpin,
+   .mmap = cma_mmap,
+   .munmap = cma_munmap,
+   .kmap = cma_kmap,
+   .kunmap = cma_kunmap,
+};
diff --git a/drivers/gpu/host1x/drm/cma.h b/drivers/gpu/host1x/drm/cma.h
new file mode 100644
index 000..06aa0ba
--- /dev/null
+++ b/drivers/gpu/host1x/drm/cma.h
@@ -0,0 +1,26 @@
+/*
+ * Tegra host1x cma memory manager
+ *
+ * Copyright (c) 2012-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __HOST1X_CMA_H
+#define __HOST1X_CMA_H
+
+#include "memmgr.h"
+
+extern const struct host1x_mem_op host1x_cma_ops;
+
+#endif
-- 
1.7.9.5

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCHv6 7/9] gpu: host1x: Remove second host1x driver

2013-03-08 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x
driver. The logic to parse device tree and track clients is moved
to drm.c.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 ++-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|5 +-
 drivers/gpu/host1x/drm/drm.c   |  217 +++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |5 +-
 drivers/gpu/host1x/drm/host1x.c|  329 
 drivers/gpu/host1x/host1x_client.h |   35 
 10 files changed, 318 insertions(+), 344 deletions(-)
 delete mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index db4dc25..ad39fef 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -14,6 +14,6 @@ host1x-y = \
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d7c6e3e..6af8081 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -32,6 +32,19 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"
+
+void host1x_set_drm_data(struct device *dev, void *data)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct device *dev)
+{
+   struct host1x *host1x = dev_get_drvdata(dev);
+   return host1x->drm_data;
+}
 
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
@@ -154,6 +167,8 @@ static int host1x_probe(struct platform_device *pdev)
 
host1x_debug_init(host);
 
+   host1x_drm_alloc(pdev);
+
return 0;
 
 fail_deinit_syncpt:
@@ -170,7 +185,7 @@ static int __exit host1x_remove(struct platform_device 
*pdev)
return 0;
 }
 
-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -180,8 +195,47 @@ static struct platform_driver platform_driver = {
},
 };
 
-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_DRM_TEGRA
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_DRM_TEGRA
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);
 
+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 3542c00..e74ed4a 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -125,6 +125,8 @@ struct host1x {
unsigned int num_allocated_channels;
 
struct dentry *debugfs;
+
+   void *drm_data;
 };
 
 static inline struct host1x *host1x_get_host(struct device *dev)
@@ -308,4 +310,8 @@ static inline void host1x_hw_show_mlocks(struct host1x 
*host, struct output *o)
host->debug_op->show_mlocks(host, o);
 }
 
+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index c92955d..8fb6545 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM && OF && ARCH_TEGRA
s

[PATCHv6 9/9] drm: tegra: Add gr2d device

2013-03-08 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from
DRM.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile   |1 +
 drivers/gpu/host1x/dev.c  |7 +
 drivers/gpu/host1x/drm/drm.c  |  239 +-
 drivers/gpu/host1x/drm/drm.h  |   28 +++-
 drivers/gpu/host1x/drm/gr2d.c |  325 +
 drivers/gpu/host1x/host1x.h   |3 +-
 include/drm/tegra_drm.h   |  131 +
 7 files changed, 730 insertions(+), 4 deletions(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index d1d7e35..d90168f 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -17,4 +17,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/cma.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 6af8081..0091632 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -211,11 +211,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif
 
return 0;
 
 #ifdef CONFIG_DRM_TEGRA
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -228,6 +234,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_DRM_TEGRA
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index dbd4808..1f0754a 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2012 Avionic Design GmbH
- * Copyright (C) 2012 NVIDIA CORPORATION.  All rights reserved.
+ * Copyright (C) 2012-2013 NVIDIA CORPORATION.  All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -8,13 +8,17 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 
+#include "cma.h"
+#include "dev.h"
 #include "drm.h"
 #include "host1x_client.h"
+#include "syncpt.h"
 
 #define DRIVER_NAME "tegra"
 #define DRIVER_DESC "NVIDIA Tegra graphics"
@@ -77,8 +81,10 @@ static int host1x_parse_dt(struct host1x_drm *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -273,9 +279,24 @@ static int tegra_drm_unload(struct drm_device *drm)
 
 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
+   struct host1x_drm_file *fpriv;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
return 0;
 }
 
+static void host1x_drm_context_free(struct host1x_drm_context *context)
+{
+   context->client->ops->close_channel(context);
+   kfree(context);
+}
+
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
struct host1x_drm *host1x = drm->dev_private;
@@ -283,7 +304,214 @@ static void tegra_drm_lastclose(struct drm_device *drm)
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
 
+static int tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+  struct drm_file *file_priv)
+{
+   struct tegra_drm_syncpt_read_args *args = data;
+   struct host1x *host = host1x_get_host(drm->dev);
+   struct host1x_syncpt *sp = host1x_syncpt_get(host, args->id);
+
+   if (!sp)
+   return -EINVAL;
+
+   args->value = host1x_syncpt_read_min(sp);
+   return 0;
+}
+
+static int tegra_drm_ioctl_syncpt_incr(struct drm_device *drm, void *data,
+  struct drm_file *file_priv)
+{
+ 

[PATCHv6 2/9] gpu: host1x: Add syncpoint wait and interrupts

2013-03-08 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   12 ++
 drivers/gpu/host1x/dev.h |   51 +
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  143 +
 drivers/gpu/host1x/intr.c|  328 ++
 drivers/gpu/host1x/intr.h|   96 +
 drivers/gpu/host1x/syncpt.c  |  159 +++
 drivers/gpu/host1x/syncpt.h  |   14 +-
 10 files changed, 847 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o
 
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index d95a9b2..4421e28 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,6 +28,7 @@
 #include 
 
 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"
 
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
@@ -127,12 +128,23 @@ static int host1x_probe(struct platform_device *pdev)
return err;
}
 
+   err = host1x_intr_init(host, syncpt_irq);
+   if (err) {
+   dev_err(dev, "failed to init irq");
+   goto fail_deinit_syncpt;
+   }
+
return 0;
+
+fail_deinit_syncpt:
+   host1x_syncpt_deinit(host);
+   return err;
 }
 
 static int __exit host1x_remove(struct platform_device *pdev)
 {
struct host1x *host = platform_get_drvdata(pdev);
+   host1x_intr_deinit(host);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
return 0;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 750daa3..fb5f842 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -21,6 +21,7 @@
 #include 
 
 #include "syncpt.h"
+#include "intr.h"
 
 struct host1x_syncpt;
 
@@ -33,6 +34,17 @@ struct host1x_syncpt_ops {
int (*patch_wait)(struct host1x_syncpt *syncpt, void *patch_addr);
 };
 
+struct host1x_intr_ops {
+   int (*init_host_sync)(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *work));
+   void (*set_syncpt_threshold)(
+   struct host1x *host, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_syncpt_intr)(struct host1x *host, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x *host);
+   int (*free_syncpt_irq)(struct host1x *host);
+};
+
 struct host1x_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -50,7 +62,13 @@ struct host1x {
struct device *dev;
struct clk *clk;
 
+   struct mutex intr_mutex;
+   struct workqueue_struct *intr_wq;
+   int intr_syncpt_irq;
+
const struct host1x_syncpt_ops *syncpt_op;
+   const struct host1x_intr_ops *intr_op;
+
 };
 
 static inline struct host1x *host1x_get_host(struct device *dev)
@@ -101,4 +119,37 @@ static inline int host1x_hw_syncpt_patch_wait(struct 
host1x *host,
return host->syncpt_op->patch_wait(sp, patch_addr);
 }
 
+static inline int host1x_hw_intr_init_host_sync(struct host1x *host, u32 cpm,
+   void (*syncpt_thresh_work)(struct work_struct *))
+{
+   return host->intr_op->init_host_sync(host, cpm, syncpt_thresh_work);
+}
+
+static inline void host1x_hw_intr_set_syncpt_threshold(struct host1x *host,
+  u32 id, u32 thresh)
+{
+   host->intr_op->set_syncpt_threshold(host, id, thresh);
+}
+
+static inline void host1x_hw_intr_enable_syncpt_intr(struct host1x *host,
+u32 id)
+{
+   host->intr_op->enable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_syncpt_intr(struct host1x *host,
+ u32 id)
+{
+   host->intr_op->disable_syncpt_intr(host, id);
+}
+
+static inline void host1x_hw_intr_disable_all_syncpt_intrs(struct host1x *host)
+{
+   host->intr_op->disable_all_syncpt_intrs(host);
+}
+
+static inline int host1x_hw_intr_free

[PATCHv6 4/9] gpu: host1x: Add debug support

2013-03-08 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |5 +
 drivers/gpu/host1x/debug.c  |  210 +
 drivers/gpu/host1x/debug.h  |   51 +
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   42 
 drivers/gpu/host1x/hw/cdma_hw.c |3 +
 drivers/gpu/host1x/hw/channel_hw.c  |   27 ++-
 drivers/gpu/host1x/hw/debug_hw.c|  322 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |6 +
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |5 +
 15 files changed, 810 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 7278bf3..dfc6f35 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
memmgr.o \
hw/host1x01.o
 
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index a45bb94..f3167bf 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -29,6 +29,7 @@
 #include "cdma.h"
 #include "channel.h"
 #include "dev.h"
+#include "debug.h"
 #include "job.h"
 #include "memmgr.h"
 
@@ -438,6 +439,10 @@ void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, 
u32 op2)
struct push_buffer *pb = &cdma->push_buffer;
u32 slots_free = cdma->slots_free;
 
+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(dev_name(cdma_to_channel(cdma)->dev),
+  op1, op2);
+
if (slots_free == 0) {
host1x_hw_cdma_flush(host1x, cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..cb8aff9
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2013 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args);
+   va_end(args);
+   o->fn(o->ctx, o->buf, len);
+}
+
+static int show_channels(struct host1x_channel *ch, void *data, bool show_fifo)
+{
+   struct host1x *m = host1x_get_host(ch->dev);
+   struct output *o = data;
+
+   mutex_lock(&ch->reflock);
+   if (ch->refcount) {
+   mutex_lock(&ch->cdma.lock);
+   if (show_fifo)
+   host1x_hw_show_channel_fifo(m, ch, o);
+   host1x_hw_show_channel_cdma(m, ch, o);
+   mutex_unlock(&ch->cdma.lock);
+   }
+   mutex_unlock(&ch->reflock);
+
+   return 0;
+}
+
+static void show_syncpts(struct host1x *m, struct output *o)
+{
+   int i;
+   host1x_debug_output(o, " syncpts \n");
+   for (i = 0; i < host1x_syncpt_nb_pts(m); i++) {
+   u32 max = host1x_syncpt_read_max(m->syncpt + i);
+   u32 min = host1x_syncpt_load(m->syncpt + i);
+   if (!min && !max)
+   continue;
+   host1x_debug_output(o, "id %d (%s) min %d max %d\n",
+   i, m->syncpt[i].name, min, max);
+   }
+
+   for (i = 0; i < host1x_syncpt_

[PATCHv6 5/9] drm: tegra: Move drm to live under host1x

2013-03-08 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |2 ++
 drivers/gpu/host1x/Makefile|5 +
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 16 files changed, 10 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 1e82882..9031bb7 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -215,8 +215,6 @@ source "drivers/gpu/drm/cirrus/Kconfig"
 
 source "drivers/gpu/drm/shmobile/Kconfig"
 
-source "drivers/gpu/drm/tegra/Kconfig"
-
 source "drivers/gpu/drm/omapdrm/Kconfig"
 
 source "drivers/gpu/drm/tilcdc/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 0d59b24..847b830 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,7 +49,6 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-$(CONFIG_DRM_OMAP) += omapdrm/
 obj-$(CONFIG_DRM_TILCDC)   += tilcdc/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 00f0859..ee3af1e 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -18,4 +18,6 @@ config TEGRA_HOST1X_FIREWALL
 
  If unsure, choose Y.
 
+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index dfc6f35..db4dc25 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -11,4 +11,9 @@ host1x-y = \
memmgr.o \
hw/host1x01.o
 
+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 6dd75a2..a6c011d 100644
--- a/drivers/gpu/drm/tegra/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -7,8 +7,8 @@
  * published by the Free Software Foundation.
  */
 
-#ifndef TEGRA_DRM_H
-#define TEGRA_D

[PATCHv6 6/9] gpu: host1x: drm: Rename host1x to host1x_drm

2013-03-08 Thread Terje Bergstrom
From: Arto Merilainen 

Both host1x and drm drivers have host1x structures. This patch
renames the host1x structure under drm to follow name host1x_drm.

Signed-off-by: Arto Merilainen 
Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/drm/dc.c |4 ++--
 drivers/gpu/host1x/drm/drm.c|4 ++--
 drivers/gpu/host1x/drm/drm.h|   14 +++---
 drivers/gpu/host1x/drm/fb.c |6 +++---
 drivers/gpu/host1x/drm/hdmi.c   |4 ++--
 drivers/gpu/host1x/drm/host1x.c |   22 --
 6 files changed, 28 insertions(+), 26 deletions(-)

diff --git a/drivers/gpu/host1x/drm/dc.c b/drivers/gpu/host1x/drm/dc.c
index de94707..d1f6609 100644
--- a/drivers/gpu/host1x/drm/dc.c
+++ b/drivers/gpu/host1x/drm/dc.c
@@ -1097,7 +1097,7 @@ static const struct host1x_client_ops dc_client_ops = {
 
 static int tegra_dc_probe(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct resource *regs;
struct tegra_dc *dc;
int err;
@@ -1160,7 +1160,7 @@ static int tegra_dc_probe(struct platform_device *pdev)
 
 static int tegra_dc_remove(struct platform_device *pdev)
 {
-   struct host1x *host1x = dev_get_drvdata(pdev->dev.parent);
+   struct host1x_drm *host1x = dev_get_drvdata(pdev->dev.parent);
struct tegra_dc *dc = platform_get_drvdata(pdev);
int err;
 
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index 9d452df..6c59bcd 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -26,7 +26,7 @@
 static int tegra_drm_load(struct drm_device *drm, unsigned long flags)
 {
struct device *dev = drm->dev;
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
int err;
 
host1x = dev_get_drvdata(dev);
@@ -69,7 +69,7 @@ static int tegra_drm_open(struct drm_device *drm, struct 
drm_file *filp)
 
 static void tegra_drm_lastclose(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/drm.h b/drivers/gpu/host1x/drm/drm.h
index a6c011d..7fedb6c 100644
--- a/drivers/gpu/host1x/drm/drm.h
+++ b/drivers/gpu/host1x/drm/drm.h
@@ -18,7 +18,7 @@
 #include 
 #include 
 
-struct host1x {
+struct host1x_drm {
struct drm_device *drm;
struct device *dev;
void __iomem *regs;
@@ -44,7 +44,7 @@ struct host1x_client_ops {
 };
 
 struct host1x_client {
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;
 
const struct host1x_client_ops *ops;
@@ -52,12 +52,12 @@ struct host1x_client {
struct list_head list;
 };
 
-extern int host1x_drm_init(struct host1x *host1x, struct drm_device *drm);
-extern int host1x_drm_exit(struct host1x *host1x);
+extern int host1x_drm_init(struct host1x_drm *host1x, struct drm_device *drm);
+extern int host1x_drm_exit(struct host1x_drm *host1x);
 
-extern int host1x_register_client(struct host1x *host1x,
+extern int host1x_register_client(struct host1x_drm *host1x,
  struct host1x_client *client);
-extern int host1x_unregister_client(struct host1x *host1x,
+extern int host1x_unregister_client(struct host1x_drm *host1x,
struct host1x_client *client);
 
 struct tegra_output;
@@ -66,7 +66,7 @@ struct tegra_dc {
struct host1x_client client;
spinlock_t lock;
 
-   struct host1x *host1x;
+   struct host1x_drm *host1x;
struct device *dev;
 
struct drm_crtc base;
diff --git a/drivers/gpu/host1x/drm/fb.c b/drivers/gpu/host1x/drm/fb.c
index 0391495..6ed885a 100644
--- a/drivers/gpu/host1x/drm/fb.c
+++ b/drivers/gpu/host1x/drm/fb.c
@@ -11,7 +11,7 @@
 
 static void tegra_drm_fb_output_poll_changed(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_hotplug_event(host1x->fbdev);
 }
@@ -23,7 +23,7 @@ static const struct drm_mode_config_funcs 
tegra_drm_mode_funcs = {
 
 int tegra_drm_fb_init(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
struct drm_fbdev_cma *fbdev;
 
drm->mode_config.min_width = 0;
@@ -46,7 +46,7 @@ int tegra_drm_fb_init(struct drm_device *drm)
 
 void tegra_drm_fb_exit(struct drm_device *drm)
 {
-   struct host1x *host1x = drm->dev_private;
+   struct host1x_drm *host1x = drm->dev_private;
 
drm_fbdev_cma_fini(host1x->fbdev);
 }
diff --git a/drivers/gpu/host1x/drm/hdmi.c b/drivers/gpu/host1x/drm/hdmi.c
index bb747f6..f438f80 100644
--- a/drivers/gpu/host1x/drm/hdmi.c
+++ b/drivers/gpu/host1x/drm/hdmi.c
@@ -1189,7 +1189,7 @@ st

[PATCHv6 0/9] Support for Tegra 2D hardware

2013-03-08 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130307.

Changes in this version:
 * Rebased on latest tegradrm
 * Renamed tegradrm's host1x to host1x_drm
 * Indentation and line split fixed to follow tegradrm convention
 * Pointers to platform_device replaced with pointers to device
 * Added host1x allocator, and wired it in
 * Debug spew code fixed to access mem handles from host1x_job
 * CDMA code doesn't keep the mem handles anymore
 * Push buffer ops have been made generic code
 * Removed the pin_array optimization in host1x_job to simplify code
 * Large number of smaller changes

The driver implements an allocator using the DRM CMA helper. Each buffer is
assigned an ops structure to operate on it. In future the DRM CMA helper will
be replaced with an own allocator to implement IOMMU support.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page http://http.download.nvidia.com/tegra-public-appnotes/host1x.html
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

The changes to add support to libdrm are in
g...@gitorious.org:linux-host1x/libdrm-host1x.git

Arto Merilainen (2):
  gpu: host1x: drm: Rename host1x to host1x_drm
  gpu: host1x: drm: Add CMA ops for host1x driver

Terje Bergstrom (7):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  drm: tegra: Add gr2d device

 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  217 
 drivers/gpu/drm/tegra/host1x.c |  327 
 drivers/gpu/host1x/Kconfig |   23 +
 drivers/gpu/host1x/Makefile|   21 +
 drivers/gpu/host1x/cdma.c  |  491 ++
 drivers/gpu/host1x/cdma.h  |  102 
 drivers/gpu/host1x/channel.c   |  120 +
 drivers/gpu/host1x/channel.h   |   52 ++
 drivers/gpu/host1x/debug.c |  210 
 drivers/gpu/host1x/debug.h |   51 ++
 drivers/gpu/host1x/dev.c   |  248 +
 drivers/gpu/host1x/dev.h   |  317 
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |2 +-
 drivers/gpu/host1x/drm/cma.c   |   87 
 drivers/gpu/host1x/drm/cma.h   |   26 +
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  661 
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   51 +-
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |6 +-
 drivers/gpu/host1x/drm/gr2d.c  |  325 
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |5 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   29 ++
 drivers/gpu/host1x/host1x_client.h |   35 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  327 
 drivers/gpu/host1x/hw/channel_hw.c |  167 ++
 drivers/gpu/host1x/hw/debug_hw.c   |  322 
 drivers/gpu/host1x/hw/host1x01.c   |   42 ++
 drivers/gpu/host1x/hw/host1x01.h   |   25 +
 drivers/gpu/host1x/hw/host1x01_hardware.h  |  143 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h|  120 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h   |  243 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h |  174 +++
 drivers/gpu/host1x/hw/intr_hw.c|  143 +
 drivers/gpu/host1x/hw/syncpt_hw.c  |  114 
 drivers/gpu/host1x/intr.c  |  354 +
 drivers/gpu/host1x/intr.h  |  102 
 drivers/gpu/host1x/job.c   |  598 +
 drivers/gpu/host1x/job.h   |  15

[PATCHv5,RESEND 8/8] drm: tegra: Add gr2d device

2013-01-15 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from DRM.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile   |1 +
 drivers/gpu/host1x/dev.c  |7 +
 drivers/gpu/host1x/drm/drm.c  |  226 +++-
 drivers/gpu/host1x/drm/drm.h  |   28 
 drivers/gpu/host1x/drm/gr2d.c |  325 +
 drivers/gpu/host1x/syncpt.c   |5 +
 drivers/gpu/host1x/syncpt.h   |3 +
 include/drm/tegra_drm.h   |  131 +
 8 files changed, 725 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index c35ee19..c2120ad 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -18,4 +18,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 17ee01c..40d9938 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -214,11 +214,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif

return 0;

 #ifdef CONFIG_TEGRA_DRM
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -231,6 +237,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_TEGRA_DRM
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index bef9051..f8f8508 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -14,9 +14,11 @@
 #include 
 #include 
 #include 
+#include 

 #include "drm.h"
 #include "host1x_client.h"
+#include "syncpt.h"

 #define DRIVER_NAME "tegra"
 #define DRIVER_DESC "NVIDIA Tegra graphics"
@@ -78,8 +80,10 @@ static int host1x_parse_dt(struct host1x *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -270,7 +274,29 @@ static int tegra_drm_unload(struct drm_device *drm)

 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
-   return 0;
+   struct host1x_drm_fpriv *fpriv;
+   int err = 0;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
+   return err;
+}
+
+static void tegra_drm_close(struct drm_device *drm, struct drm_file *filp)
+{
+   struct host1x_drm_fpriv *fpriv = host1x_drm_fpriv(filp);
+   struct host1x_drm_context *context, *tmp;
+
+   list_for_each_entry_safe(context, tmp, &fpriv->contexts, list) {
+   context->client->ops->close_channel(context);
+   kfree(context);
+   }
+   kfree(fpriv);
 }

 static void tegra_drm_lastclose(struct drm_device *drm)
@@ -280,7 +306,204 @@ static void tegra_drm_lastclose(struct drm_device *drm)
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }

+static int
+tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+struct drm_file *file_priv)
+{
+   struct host1x *host1x = drm->dev_private;
+   struct tegra_drm_syncpt_read_args *args = data;
+   struct host1x_syncpt *sp =
+   host1x_syncpt_get_bydev(host1x->dev, args->id);
+
+   if (!sp)
+   return -EINVAL;
+
+   args->value = host1x_syncpt_read_min(sp);
+   return 0;
+}
+
+static int
+tegra_drm_ioctl_syncpt_incr(struct drm_device *drm, void *data,
+struct drm_file *file_priv)
+{
+   struct host1x *host1x = drm->dev_private;
+   struct tegra_drm_syncpt_incr_args *args = data;
+   struct host1x_syncpt *sp =
+   host1x_syncpt_get_bydev(host1x->dev, args->id);
+
+   if (!sp)
+   

[PATCHv5,RESEND 7/8] ARM: tegra: Add board data and 2D clocks

2013-01-15 Thread Terje Bergstrom
Add a driver alias gr2d for Tegra 2D device, and assign a duplicate
of 2D clock to that driver alias.

Signed-off-by: Terje Bergstrom 
---
 arch/arm/mach-tegra/board-dt-tegra20.c|1 +
 arch/arm/mach-tegra/board-dt-tegra30.c|1 +
 arch/arm/mach-tegra/tegra20_clocks_data.c |2 +-
 arch/arm/mach-tegra/tegra30_clocks_data.c |1 +
 4 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c 
b/arch/arm/mach-tegra/board-dt-tegra20.c
index 171ba3c..9fcc800 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -96,6 +96,7 @@ static struct of_dev_auxdata tegra20_auxdata_lookup[] 
__initdata = {
OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D800, "spi_tegra.2", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000DA00, "spi_tegra.3", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-host1x", 0x5000, "host1x", NULL),
+   OF_DEV_AUXDATA("nvidia,tegra20-gr2d", 0x5414, "gr2d", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x5420, "tegradc.0", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x5424, "tegradc.1", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-hdmi", 0x5428, "hdmi", NULL),
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c 
b/arch/arm/mach-tegra/board-dt-tegra30.c
index cfe5fc0..0b4a1f0 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -59,6 +59,7 @@ static struct of_dev_auxdata tegra30_auxdata_lookup[] 
__initdata = {
OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DC00, "spi_tegra.4", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DE00, "spi_tegra.5", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-host1x", 0x5000, "host1x", NULL),
+   OF_DEV_AUXDATA("nvidia,tegra30-gr2d", 0x5414, "gr2d", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x5420, "tegradc.0", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x5424, "tegradc.1", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-hdmi", 0x5428, "hdmi", NULL),
diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c 
b/arch/arm/mach-tegra/tegra20_clocks_data.c
index a23a073..15d440a 100644
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra20_clocks_data.c
@@ -1041,7 +1041,7 @@ static struct clk_duplicate tegra_clk_duplicates[] = {
CLK_DUPLICATE("usbd",   "utmip-pad",NULL),
CLK_DUPLICATE("usbd",   "tegra-ehci.0", NULL),
CLK_DUPLICATE("usbd",   "tegra-otg",NULL),
-   CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"),
+   CLK_DUPLICATE("2d", "gr2d", "gr2d"),
CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"),
CLK_DUPLICATE("epp","tegra_grhost", "epp"),
CLK_DUPLICATE("mpe","tegra_grhost", "mpe"),
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c 
b/arch/arm/mach-tegra/tegra30_clocks_data.c
index 741d264..5c4b7b7 100644
--- a/arch/arm/mach-tegra/tegra30_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra30_clocks_data.c
@@ -1338,6 +1338,7 @@ static struct clk_duplicate tegra_clk_duplicates[] = {
CLK_DUPLICATE("pll_p", "tegradc.0", "parent"),
CLK_DUPLICATE("pll_p", "tegradc.1", "parent"),
CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"),
+   CLK_DUPLICATE("2d", "gr2d", "gr2d"),
 };

 static struct clk *tegra_ptr_clks[] = {
-- 
1.7.9.5



[PATCHv5,RESEND 6/8] gpu: host1x: Remove second host1x driver

2013-01-15 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x driver. The
logic to parse device tree and track clients is moved to drm.c.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 +-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|7 +-
 drivers/gpu/host1x/drm/drm.c   |  213 +++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |7 +-
 drivers/gpu/host1x/host1x_client.h |9 ++
 9 files changed, 294 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index ffc8bf1..c35ee19 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,6 +16,6 @@ host1x-$(CONFIG_TEGRA_HOST1X_CMA) += cma.o
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 5aa7d28..17ee01c 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,12 +28,25 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"

 #define CREATE_TRACE_POINTS
 #include 

 #define DRIVER_NAME"tegra-host1x"

+void host1x_set_drm_data(struct platform_device *pdev, void *data)
+{
+   struct host1x *host1x = platform_get_drvdata(pdev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct platform_device *pdev)
+{
+   struct host1x *host1x = platform_get_drvdata(pdev);
+   return host1x->drm_data;
+}
+
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
void __iomem *sync_regs = host1x->regs + host1x->info.sync_offset;
@@ -153,6 +166,8 @@ static int host1x_probe(struct platform_device *dev)

host1x_debug_init(host);

+   host1x_drm_alloc(dev);
+
dev_info(&dev->dev, "initialized\n");

return 0;
@@ -173,7 +188,7 @@ static int __exit host1x_remove(struct platform_device *dev)
return 0;
 }

-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -183,8 +198,47 @@ static struct platform_driver platform_driver = {
},
 };

-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_TEGRA_DRM
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_TEGRA_DRM
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_TEGRA_DRM
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);

+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 467a92e..ff3a365 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -142,6 +142,8 @@ struct host1x {
int allocated_channels;

struct dentry *debugfs;
+
+   void *drm_data;
 };

 static inline
@@ -161,4 +163,8 @@ u32 host1x_sync_readl(struct host1x *host1x, u32 r);
 void host1x_ch_writel(struct host1x_channel *ch, u32 r, u32 v);
 u32 host1x_ch_readl(struct host1x_channel *ch, u32 r);

+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index be1daf7..7db9b3a 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM &&

[PATCHv5,RESEND 5/8] drm: tegra: Move drm to live under host1x

2013-01-15 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 --
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 ---
 drivers/gpu/host1x/Kconfig |3 +++
 drivers/gpu/host1x/Makefile|6 ++
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.c|0
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|6 +++---
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |0
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x_client.h |   25 
 17 files changed, 37 insertions(+), 13 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 rename drivers/gpu/{drm/tegra => host1x/drm}/Kconfig (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/dc.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/drm.h (98%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/fb.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/host1x.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/output.c (100%)
 rename drivers/gpu/{drm/tegra => host1x/drm}/rgb.c (100%)
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 983201b..18321b68b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -210,5 +210,3 @@ source "drivers/gpu/drm/mgag200/Kconfig"
 source "drivers/gpu/drm/cirrus/Kconfig"

 source "drivers/gpu/drm/shmobile/Kconfig"
-
-source "drivers/gpu/drm/tegra/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 6f58c81..f54c72a 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,5 +49,4 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index 57680a6..558b660 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -1,4 +1,5 @@
 config TEGRA_HOST1X
+   depends on DRM
tristate "Tegra host1x driver"
help
  Driver for the Tegra host1x hardware.
@@ -26,4 +27,6 @@ config TEGRA_HOST1X_FIREWALL

  If unsure, choose Y.

+source "drivers/gpu/host1x/drm/Kconfig"
+
 endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 697d49a..ffc8bf1 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -12,4 +12,10 @@ host1x-y = \
hw/host1x01.o

 host1x-$(CONFIG_TEGRA_HOST1X_CMA) += cma.o
+
+ccflags-y += -Iinclude/drm
+ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
+
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/host1x/drm/Kconfig
similarity index 100%
rename from drivers/gpu/drm/tegra/Kconfig
rename to drivers/gpu/host1x/drm/Kconfig
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/host1x/drm/dc.c
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.c
rename to drivers/gpu/host1x/drm/dc.c
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/host1x/drm/dc.h
similarity index 100%
rename from drivers/gpu/drm/tegra/dc.h
rename to drivers/gpu/host1x/drm/dc.h
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/host1x/drm/drm.c
similarity index 100%
rename from drivers/gpu/drm/tegra/drm.c
rename to drivers/gpu/host1x/drm/drm.c
diff --git a/drivers/gpu/drm/tegra/drm.h b/drivers/gpu/host1x/drm/drm.h
similarity index 98%
rename from drivers/gpu/drm/tegra/drm.h
rename to drivers/gpu/host1x/drm/drm.h
index 741b5dc..e68b4ac 100644
--- 

[PATCHv5,RESEND 4/8] gpu: host1x: Add debug support

2013-01-15 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |   34 +++
 drivers/gpu/host1x/debug.c  |  215 ++
 drivers/gpu/host1x/debug.h  |   50 
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   17 ++
 drivers/gpu/host1x/hw/cdma_hw.c |3 +
 drivers/gpu/host1x/hw/debug_hw.c|  400 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |3 +
 13 files changed, 862 insertions(+)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index cdd87c8..697d49a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
memmgr.o \
hw/host1x01.o

diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index d6a38d2..12dd46c 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -19,6 +19,7 @@
 #include "cdma.h"
 #include "channel.h"
 #include "dev.h"
+#include "debug.h"
 #include "memmgr.h"
 #include "job.h"
 #include 
@@ -370,12 +371,42 @@ int host1x_cdma_begin(struct host1x_cdma *cdma, struct 
host1x_job *job)
return 0;
 }

+static void trace_write_gather(struct host1x_cdma *cdma,
+   struct mem_handle *ref,
+   u32 offset, u32 words)
+{
+   void *mem = NULL;
+
+   if (host1x_debug_trace_cmdbuf)
+   mem = host1x_memmgr_mmap(ref);
+
+   if (mem) {
+   u32 i;
+   /*
+* Write in batches of 128 as there seems to be a limit
+* of how much you can output to ftrace at once.
+*/
+   for (i = 0; i < words; i += TRACE_MAX_LENGTH) {
+   trace_host1x_cdma_push_gather(
+   cdma_to_channel(cdma)->dev->name,
+   (u32)ref,
+   min(words - i, TRACE_MAX_LENGTH),
+   offset + i * sizeof(u32),
+   mem);
+   }
+   host1x_memmgr_munmap(ref, mem);
+   }
+}
+
 /*
  * Push two words into a push buffer slot
  * Blocks as necessary if the push buffer is full.
  */
 void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, u32 op2)
 {
+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(cdma_to_channel(cdma)->dev->name,
+   op1, op2);
host1x_cdma_push_gather(cdma, NULL, 0, op1, op2);
 }

@@ -391,6 +422,9 @@ void host1x_cdma_push_gather(struct host1x_cdma *cdma,
u32 slots_free = cdma->slots_free;
struct push_buffer *pb = &cdma->push_buffer;

+   if (handle)
+   trace_write_gather(cdma, handle, offset, op1 & 0x);
+
if (slots_free == 0) {
host1x->cdma_op.kick(cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..29cbe93
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2012 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+static pid_t host1x_debug_null_kickoff_pid;
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args)

[PATCHv5,RESEND 3/8] gpu: host1x: Add channel support

2013-01-15 Thread Terje Bergstrom
Add support for host1x client modules, and host1x channels to submit
work to the clients. The work is submitted in GEM CMA buffers, so
this patch adds support for them.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Kconfig  |   25 +-
 drivers/gpu/host1x/Makefile |5 +
 drivers/gpu/host1x/cdma.c   |  439 +++
 drivers/gpu/host1x/cdma.h   |  107 +
 drivers/gpu/host1x/channel.c|  140 ++
 drivers/gpu/host1x/channel.h|   58 +++
 drivers/gpu/host1x/cma.c|  116 +
 drivers/gpu/host1x/cma.h|   43 ++
 drivers/gpu/host1x/dev.c|   13 +
 drivers/gpu/host1x/dev.h|   59 +++
 drivers/gpu/host1x/host1x.h |   29 ++
 drivers/gpu/host1x/hw/cdma_hw.c |  475 +
 drivers/gpu/host1x/hw/cdma_hw.h |   37 ++
 drivers/gpu/host1x/hw/channel_hw.c  |  148 +++
 drivers/gpu/host1x/hw/host1x01.c|6 +
 drivers/gpu/host1x/hw/host1x01_hardware.h   |  124 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |  102 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|   12 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |  168 
 drivers/gpu/host1x/hw/syncpt_hw.c   |   10 +
 drivers/gpu/host1x/intr.c   |   29 +-
 drivers/gpu/host1x/intr.h   |6 +
 drivers/gpu/host1x/job.c|  612 +++
 drivers/gpu/host1x/job.h|  164 +++
 drivers/gpu/host1x/memmgr.c |  173 
 drivers/gpu/host1x/memmgr.h |   72 
 drivers/gpu/host1x/syncpt.c |   11 +
 drivers/gpu/host1x/syncpt.h |4 +
 include/trace/events/host1x.h   |  211 +
 29 files changed, 3396 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/host1x/cdma.c
 create mode 100644 drivers/gpu/host1x/cdma.h
 create mode 100644 drivers/gpu/host1x/channel.c
 create mode 100644 drivers/gpu/host1x/channel.h
 create mode 100644 drivers/gpu/host1x/cma.c
 create mode 100644 drivers/gpu/host1x/cma.h
 create mode 100644 drivers/gpu/host1x/host1x.h
 create mode 100644 drivers/gpu/host1x/hw/cdma_hw.c
 create mode 100644 drivers/gpu/host1x/hw/cdma_hw.h
 create mode 100644 drivers/gpu/host1x/hw/channel_hw.c
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_channel.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_uclass.h
 create mode 100644 drivers/gpu/host1x/job.c
 create mode 100644 drivers/gpu/host1x/job.h
 create mode 100644 drivers/gpu/host1x/memmgr.c
 create mode 100644 drivers/gpu/host1x/memmgr.h

diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index e89fb2b..57680a6 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -3,4 +3,27 @@ config TEGRA_HOST1X
help
  Driver for the Tegra host1x hardware.

- Required for enabling tegradrm.
+ Required for enabling tegradrm and 2D acceleration.
+
+if TEGRA_HOST1X
+
+config TEGRA_HOST1X_CMA
+   bool "Support DRM CMA buffers"
+   depends on DRM
+   default y
+   select DRM_GEM_CMA_HELPER
+   select DRM_KMS_CMA_HELPER
+   help
+ Say yes if you wish to use DRM CMA buffers.
+
+ If unsure, choose Y.
+
+config TEGRA_HOST1X_FIREWALL
+   bool "Enable HOST1X security firewall"
+   default y
+   help
+ Say yes if kernel should protect command streams from tampering.
+
+ If unsure, choose Y.
+
+endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 5ef47ff..cdd87c8 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -4,6 +4,11 @@ host1x-y = \
syncpt.o \
dev.o \
intr.o \
+   cdma.o \
+   channel.o \
+   job.o \
+   memmgr.o \
hw/host1x01.o

+host1x-$(CONFIG_TEGRA_HOST1X_CMA) += cma.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
new file mode 100644
index 000..d6a38d2
--- /dev/null
+++ b/drivers/gpu/host1x/cdma.c
@@ -0,0 +1,439 @@
+/*
+ * Tegra host1x Command DMA
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include &qu

[PATCHv5,RESEND 2/8] gpu: host1x: Add syncpoint wait and interrupts

2013-01-15 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   21 +-
 drivers/gpu/host1x/dev.h |   17 +-
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  178 +++
 drivers/gpu/host1x/intr.c|  356 ++
 drivers/gpu/host1x/intr.h|  103 +
 drivers/gpu/host1x/syncpt.c  |  163 ++
 drivers/gpu/host1x/syncpt.h  |5 +
 10 files changed, 883 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index cd2b1ef..7f9f389 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"

 #define CREATE_TRACE_POINTS
@@ -95,7 +96,6 @@ static int host1x_probe(struct platform_device *dev)

/* set common host1x device data */
platform_set_drvdata(dev, host);
-
host->regs = devm_request_and_ioremap(&dev->dev, regs);
if (!host->regs) {
dev_err(&dev->dev, "failed to remap host registers\n");
@@ -109,28 +109,40 @@ static int host1x_probe(struct platform_device *dev)
}

err = host1x_syncpt_init(host);
-   if (err)
+   if (err) {
+   dev_err(&dev->dev, "failed to init sync points");
return err;
+   }
+
+   err = host1x_intr_init(&host->intr, syncpt_irq);
+   if (err) {
+   dev_err(&dev->dev, "failed to init irq");
+   goto fail_deinit_syncpt;
+   }

host->clk = devm_clk_get(&dev->dev, NULL);
if (IS_ERR(host->clk)) {
dev_err(&dev->dev, "failed to get clock\n");
err = PTR_ERR(host->clk);
-   goto fail_deinit_syncpt;
+   goto fail_deinit_intr;
}

err = clk_prepare_enable(host->clk);
if (err < 0) {
dev_err(&dev->dev, "failed to enable clock\n");
-   goto fail_deinit_syncpt;
+   goto fail_deinit_intr;
}

host1x_syncpt_reset(host);

+   host1x_intr_start(&host->intr, clk_get_rate(host->clk));
+
dev_info(&dev->dev, "initialized\n");

return 0;

+fail_deinit_intr:
+   host1x_intr_deinit(&host->intr);
 fail_deinit_syncpt:
host1x_syncpt_deinit(host);
return err;
@@ -139,6 +151,7 @@ fail_deinit_syncpt:
 static int __exit host1x_remove(struct platform_device *dev)
 {
struct host1x *host = platform_get_drvdata(dev);
+   host1x_intr_deinit(&host->intr);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
return 0;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index d8f5979..8376092 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -17,11 +17,12 @@
 #ifndef HOST1X_DEV_H
 #define HOST1X_DEV_H

+#include 
 #include "syncpt.h"
+#include "intr.h"

 struct host1x;
 struct host1x_syncpt;
-struct platform_device;

 struct host1x_syncpt_ops {
void (*reset)(struct host1x_syncpt *);
@@ -34,6 +35,18 @@ struct host1x_syncpt_ops {
const char * (*name)(struct host1x_syncpt *);
 };

+struct host1x_intr_ops {
+   void (*init_host_sync)(struct host1x_intr *);
+   void (*set_host_clocks_per_usec)(
+   struct host1x_intr *, u32 clocks);
+   void (*set_syncpt_threshold)(
+   struct host1x_intr *, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x_intr *, u32 id);
+   void (*disable_syncpt_intr)(struct host1x_intr *, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x_intr *);
+   int (*free_syncpt_irq)(struct host1x_intr *);
+};
+
 struct host1x_device_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -46,11 +59,13 @@ struct host1x_device_info {
 struct host1x {
void __iomem *r

[PATCHv5,RESEND 1/8] gpu: host1x: Add host1x driver

2013-01-15 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|6 +
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  161 +
 drivers/gpu/host1x/dev.h  |   73 ++
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   35 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   26 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   72 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  146 +++
 drivers/gpu/host1x/syncpt.c   |  217 +
 drivers/gpu/host1x/syncpt.h   |  153 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 
 15 files changed, 992 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index cc92778..7e227097 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/ stub/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..e89fb2b
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,6 @@
+config TEGRA_HOST1X
+   tristate "Tegra host1x driver"
+   help
+ Driver for the Tegra host1x hardware.
+
+ Required for enabling tegradrm.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..cd2b1ef
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,161 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "dev.h"
+#include "hw/host1x01.h"
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#define DRIVER_NAME"tegra-host1x"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info.sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info.sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static struct host1x_device_info host1x_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x_info, },
+   { .compatible = "nvidia,tegra20-host1x", .data = &host1x_info, },
+   { },
+};
+
+static int host1x_probe(struct platform_device *dev)
+{
+   struct host1x *host;
+   struct resource *regs;
+   int syncpt_irq;
+   int err;
+   const struct of_device_id *devid =
+   of_match_device(host1x_match, &dev->dev);
+
+   if (!devid)
+   return -EINVAL;
+
+   regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
+   if 

[PATCHv5,RESEND 0/8] Support for Tegra 2D hardware

2013-01-15 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130114. The set was regenerated with
git format-patch -M.

The fifth version merges DRM and host1x drivers into one driver. This
allowed moving include/linux/host1x.h back into the driver and removed
the need for a dummy platform device. This version also uses the code
from tegradrm driver almost as is, so there are a lot less actual code
changes.

This patch set does not have the host1x allocator, but it uses CMA
helpers for memory management.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page https://gitorious.org/linux-tegra-drm/pages/Host1xIntroduction
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.


Terje Bergstrom (8):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  ARM: tegra: Add board data and 2D clocks
  drm: tegra: Add gr2d device

 arch/arm/mach-tegra/board-dt-tegra20.c |1 +
 arch/arm/mach-tegra/board-dt-tegra30.c |1 +
 arch/arm/mach-tegra/tegra20_clocks_data.c  |2 +-
 arch/arm/mach-tegra/tegra30_clocks_data.c  |1 +
 drivers/gpu/Makefile   |1 +
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/drm.c|  115 -
 drivers/gpu/host1x/Kconfig |   32 ++
 drivers/gpu/host1x/Makefile|   22 +
 drivers/gpu/host1x/cdma.c  |  473 ++
 drivers/gpu/host1x/cdma.h  |  107 +
 drivers/gpu/host1x/channel.c   |  140 ++
 drivers/gpu/host1x/channel.h   |   58 +++
 drivers/gpu/host1x/cma.c   |  116 +
 drivers/gpu/host1x/cma.h   |   43 ++
 drivers/gpu/host1x/debug.c |  215 +
 drivers/gpu/host1x/debug.h |   50 ++
 drivers/gpu/host1x/dev.c   |  251 ++
 drivers/gpu/host1x/dev.h   |  170 +++
 drivers/gpu/{drm/tegra => host1x/drm}/Kconfig  |2 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.c |7 +-
 drivers/gpu/{drm/tegra => host1x/drm}/dc.h |0
 drivers/gpu/host1x/drm/drm.c   |  548 +
 drivers/gpu/{drm/tegra => host1x/drm}/drm.h|   37 +-
 drivers/gpu/{drm/tegra => host1x/drm}/fb.c |0
 drivers/gpu/host1x/drm/gr2d.c  |  325 +
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.c   |7 +-
 drivers/gpu/{drm/tegra => host1x/drm}/hdmi.h   |0
 drivers/gpu/{drm/tegra => host1x/drm}/host1x.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/output.c |0
 drivers/gpu/{drm/tegra => host1x/drm}/rgb.c|0
 drivers/gpu/host1x/host1x.h|   29 ++
 drivers/gpu/host1x/host1x_client.h |   34 ++
 drivers/gpu/host1x/hw/Makefile |6 +
 drivers/gpu/host1x/hw/cdma_hw.c|  478 ++
 drivers/gpu/host1x/hw/cdma_hw.h|   37 ++
 drivers/gpu/host1x/hw/channel_hw.c |  148 ++
 drivers/gpu/host1x/hw/debug_hw.c   |  400 
 drivers/gpu/host1x/hw/host1x01.c   |   45 ++
 drivers/gpu/host1x/hw/host1x01.h   |   25 +
 drivers/gpu/host1x/hw/host1x01_hardware.h  |  150 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h|  120 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h   |  241 ++
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h |  168 +++
 drivers/gpu/host1x/hw/intr_hw.c|  178 +++
 drivers/gpu/host1x/hw/syncpt_hw.c  |  157 ++
 drivers/gpu/host1x/intr.c  |  383 +++
 drivers/gpu/host1x/intr.h  |  109 +
 drivers/gpu/host1x/job.c   |  612 
 drivers/gpu/host1x/job.h   |  164 +++
 drivers/gpu/host1x/memmgr.c|  173 +++
 drivers/gpu/host1x/memmgr.h|   72 +++
 drivers/gpu/host1x/syncpt.c|  399 ++

[PATCHv5 8/8] drm: tegra: Add gr2d device

2013-01-15 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from DRM.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile   |1 +
 drivers/gpu/host1x/dev.c  |7 +
 drivers/gpu/host1x/drm/drm.c  |  226 +++-
 drivers/gpu/host1x/drm/drm.h  |   28 
 drivers/gpu/host1x/drm/gr2d.c |  325 +
 drivers/gpu/host1x/syncpt.c   |5 +
 drivers/gpu/host1x/syncpt.h   |3 +
 include/drm/tegra_drm.h   |  131 +
 8 files changed, 725 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index c35ee19..c2120ad 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -18,4 +18,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 17ee01c..40d9938 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -214,11 +214,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif

return 0;

 #ifdef CONFIG_TEGRA_DRM
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -231,6 +237,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_TEGRA_DRM
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index bef9051..f8f8508 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -14,9 +14,11 @@
 #include 
 #include 
 #include 
+#include 

 #include "drm.h"
 #include "host1x_client.h"
+#include "syncpt.h"

 #define DRIVER_NAME "tegra"
 #define DRIVER_DESC "NVIDIA Tegra graphics"
@@ -78,8 +80,10 @@ static int host1x_parse_dt(struct host1x *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -270,7 +274,29 @@ static int tegra_drm_unload(struct drm_device *drm)

 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
-   return 0;
+   struct host1x_drm_fpriv *fpriv;
+   int err = 0;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
+   return err;
+}
+
+static void tegra_drm_close(struct drm_device *drm, struct drm_file *filp)
+{
+   struct host1x_drm_fpriv *fpriv = host1x_drm_fpriv(filp);
+   struct host1x_drm_context *context, *tmp;
+
+   list_for_each_entry_safe(context, tmp, &fpriv->contexts, list) {
+   context->client->ops->close_channel(context);
+   kfree(context);
+   }
+   kfree(fpriv);
 }

 static void tegra_drm_lastclose(struct drm_device *drm)
@@ -280,7 +306,204 @@ static void tegra_drm_lastclose(struct drm_device *drm)
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }

+static int
+tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+struct drm_file *file_priv)
+{
+   struct host1x *host1x = drm->dev_private;
+   struct tegra_drm_syncpt_read_args *args = data;
+   struct host1x_syncpt *sp =
+   host1x_syncpt_get_bydev(host1x->dev, args->id);
+
+   if (!sp)
+   return -EINVAL;
+
+   args->value = host1x_syncpt_read_min(sp);
+   return 0;
+}
+
+static int
+tegra_drm_ioctl_syncpt_incr(struct drm_device *drm, void *data,
+struct drm_file *file_priv)
+{
+   struct host1x *host1x = drm->dev_private;
+   struct tegra_drm_syncpt_incr_args *args = data;
+   struct host1x_syncpt *sp =
+   host1x_syncpt_get_bydev(host1x->dev, args->id);
+
+   if (!sp)
+   

[PATCHv5 7/8] ARM: tegra: Add board data and 2D clocks

2013-01-15 Thread Terje Bergstrom
Add a driver alias gr2d for Tegra 2D device, and assign a duplicate
of 2D clock to that driver alias.

Signed-off-by: Terje Bergstrom 
---
 arch/arm/mach-tegra/board-dt-tegra20.c|1 +
 arch/arm/mach-tegra/board-dt-tegra30.c|1 +
 arch/arm/mach-tegra/tegra20_clocks_data.c |2 +-
 arch/arm/mach-tegra/tegra30_clocks_data.c |1 +
 4 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c 
b/arch/arm/mach-tegra/board-dt-tegra20.c
index 171ba3c..9fcc800 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -96,6 +96,7 @@ static struct of_dev_auxdata tegra20_auxdata_lookup[] 
__initdata = {
OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000D800, "spi_tegra.2", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-slink", 0x7000DA00, "spi_tegra.3", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-host1x", 0x5000, "host1x", NULL),
+   OF_DEV_AUXDATA("nvidia,tegra20-gr2d", 0x5414, "gr2d", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x5420, "tegradc.0", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-dc", 0x5424, "tegradc.1", NULL),
OF_DEV_AUXDATA("nvidia,tegra20-hdmi", 0x5428, "hdmi", NULL),
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c 
b/arch/arm/mach-tegra/board-dt-tegra30.c
index cfe5fc0..0b4a1f0 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -59,6 +59,7 @@ static struct of_dev_auxdata tegra30_auxdata_lookup[] 
__initdata = {
OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DC00, "spi_tegra.4", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-slink", 0x7000DE00, "spi_tegra.5", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-host1x", 0x5000, "host1x", NULL),
+   OF_DEV_AUXDATA("nvidia,tegra30-gr2d", 0x5414, "gr2d", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x5420, "tegradc.0", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-dc", 0x5424, "tegradc.1", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-hdmi", 0x5428, "hdmi", NULL),
diff --git a/arch/arm/mach-tegra/tegra20_clocks_data.c 
b/arch/arm/mach-tegra/tegra20_clocks_data.c
index a23a073..15d440a 100644
--- a/arch/arm/mach-tegra/tegra20_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra20_clocks_data.c
@@ -1041,7 +1041,7 @@ static struct clk_duplicate tegra_clk_duplicates[] = {
CLK_DUPLICATE("usbd",   "utmip-pad",NULL),
CLK_DUPLICATE("usbd",   "tegra-ehci.0", NULL),
CLK_DUPLICATE("usbd",   "tegra-otg",NULL),
-   CLK_DUPLICATE("2d", "tegra_grhost", "gr2d"),
+   CLK_DUPLICATE("2d", "gr2d", "gr2d"),
CLK_DUPLICATE("3d", "tegra_grhost", "gr3d"),
CLK_DUPLICATE("epp","tegra_grhost", "epp"),
CLK_DUPLICATE("mpe","tegra_grhost", "mpe"),
diff --git a/arch/arm/mach-tegra/tegra30_clocks_data.c 
b/arch/arm/mach-tegra/tegra30_clocks_data.c
index 741d264..5c4b7b7 100644
--- a/arch/arm/mach-tegra/tegra30_clocks_data.c
+++ b/arch/arm/mach-tegra/tegra30_clocks_data.c
@@ -1338,6 +1338,7 @@ static struct clk_duplicate tegra_clk_duplicates[] = {
CLK_DUPLICATE("pll_p", "tegradc.0", "parent"),
CLK_DUPLICATE("pll_p", "tegradc.1", "parent"),
CLK_DUPLICATE("pll_d2_out0", "hdmi", "parent"),
+   CLK_DUPLICATE("2d", "gr2d", "gr2d"),
 };

 static struct clk *tegra_ptr_clks[] = {
-- 
1.7.9.5



[PATCHv5 6/8] gpu: host1x: Remove second host1x driver

2013-01-15 Thread Terje Bergstrom
Remove second host1x driver, and bind tegra-drm to the new host1x driver. The
logic to parse device tree and track clients is moved to drm.c.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile|2 +-
 drivers/gpu/host1x/dev.c   |   58 +-
 drivers/gpu/host1x/dev.h   |6 +
 drivers/gpu/host1x/drm/Kconfig |2 +-
 drivers/gpu/host1x/drm/dc.c|7 +-
 drivers/gpu/host1x/drm/drm.c   |  213 +++-
 drivers/gpu/host1x/drm/drm.h   |3 -
 drivers/gpu/host1x/drm/hdmi.c  |7 +-
 drivers/gpu/host1x/host1x_client.h |9 ++
 9 files changed, 294 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index ffc8bf1..c35ee19 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -16,6 +16,6 @@ host1x-$(CONFIG_TEGRA_HOST1X_CMA) += cma.o
 ccflags-y += -Iinclude/drm
 ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG

-host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o drm/host1x.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 5aa7d28..17ee01c 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -28,12 +28,25 @@
 #include "channel.h"
 #include "debug.h"
 #include "hw/host1x01.h"
+#include "host1x_client.h"

 #define CREATE_TRACE_POINTS
 #include 

 #define DRIVER_NAME"tegra-host1x"

+void host1x_set_drm_data(struct platform_device *pdev, void *data)
+{
+   struct host1x *host1x = platform_get_drvdata(pdev);
+   host1x->drm_data = data;
+}
+
+void *host1x_get_drm_data(struct platform_device *pdev)
+{
+   struct host1x *host1x = platform_get_drvdata(pdev);
+   return host1x->drm_data;
+}
+
 void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
 {
void __iomem *sync_regs = host1x->regs + host1x->info.sync_offset;
@@ -153,6 +166,8 @@ static int host1x_probe(struct platform_device *dev)

host1x_debug_init(host);

+   host1x_drm_alloc(dev);
+
dev_info(&dev->dev, "initialized\n");

return 0;
@@ -173,7 +188,7 @@ static int __exit host1x_remove(struct platform_device *dev)
return 0;
 }

-static struct platform_driver platform_driver = {
+static struct platform_driver tegra_host1x_driver = {
.probe = host1x_probe,
.remove = __exit_p(host1x_remove),
.driver = {
@@ -183,8 +198,47 @@ static struct platform_driver platform_driver = {
},
 };

-module_platform_driver(platform_driver);
+static int __init tegra_host1x_init(void)
+{
+   int err;
+
+   err = platform_driver_register(&tegra_host1x_driver);
+   if (err < 0)
+   return err;
+
+#ifdef CONFIG_TEGRA_DRM
+   err = platform_driver_register(&tegra_dc_driver);
+   if (err < 0)
+   goto unregister_host1x;
+
+   err = platform_driver_register(&tegra_hdmi_driver);
+   if (err < 0)
+   goto unregister_dc;
+#endif
+
+   return 0;
+
+#ifdef CONFIG_TEGRA_DRM
+unregister_dc:
+   platform_driver_unregister(&tegra_dc_driver);
+unregister_host1x:
+   platform_driver_unregister(&tegra_host1x_driver);
+   return err;
+#endif
+}
+module_init(tegra_host1x_init);
+
+static void __exit tegra_host1x_exit(void)
+{
+#ifdef CONFIG_TEGRA_DRM
+   platform_driver_unregister(&tegra_hdmi_driver);
+   platform_driver_unregister(&tegra_dc_driver);
+#endif
+   platform_driver_unregister(&tegra_host1x_driver);
+}
+module_exit(tegra_host1x_exit);

+MODULE_AUTHOR("Thierry Reding ");
 MODULE_AUTHOR("Terje Bergstrom ");
 MODULE_DESCRIPTION("Host1x driver for Tegra products");
 MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index 467a92e..ff3a365 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -142,6 +142,8 @@ struct host1x {
int allocated_channels;

struct dentry *debugfs;
+
+   void *drm_data;
 };

 static inline
@@ -161,4 +163,8 @@ u32 host1x_sync_readl(struct host1x *host1x, u32 r);
 void host1x_ch_writel(struct host1x_channel *ch, u32 r, u32 v);
 u32 host1x_ch_readl(struct host1x_channel *ch, u32 r);

+extern struct platform_driver tegra_hdmi_driver;
+extern struct platform_driver tegra_dc_driver;
+extern struct platform_driver tegra_gr2d_driver;
+
 #endif
diff --git a/drivers/gpu/host1x/drm/Kconfig b/drivers/gpu/host1x/drm/Kconfig
index be1daf7..7db9b3a 100644
--- a/drivers/gpu/host1x/drm/Kconfig
+++ b/drivers/gpu/host1x/drm/Kconfig
@@ -1,5 +1,5 @@
 config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
+   bool "NVIDIA Tegra DRM"
depends on DRM &&

[PATCHv5 5/8] drm: tegra: Move drm to live under host1x

2013-01-15 Thread Terje Bergstrom
Make drm part of host1x driver.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/drm/Kconfig|2 -
 drivers/gpu/drm/Makefile   |1 -
 drivers/gpu/drm/tegra/Kconfig  |   23 -
 drivers/gpu/drm/tegra/Makefile |7 -
 drivers/gpu/drm/tegra/dc.c |  833 ---
 drivers/gpu/drm/tegra/dc.h |  388 ---
 drivers/gpu/drm/tegra/drm.c|  115 
 drivers/gpu/drm/tegra/drm.h|  216 --
 drivers/gpu/drm/tegra/fb.c |   56 --
 drivers/gpu/drm/tegra/hdmi.c   | 1321 
 drivers/gpu/drm/tegra/hdmi.h   |  575 
 drivers/gpu/drm/tegra/host1x.c |  327 -
 drivers/gpu/drm/tegra/output.c |  272 
 drivers/gpu/drm/tegra/rgb.c|  228 ---
 drivers/gpu/host1x/Kconfig |3 +
 drivers/gpu/host1x/Makefile|6 +
 drivers/gpu/host1x/drm/Kconfig |   23 +
 drivers/gpu/host1x/drm/dc.c|  833 +++
 drivers/gpu/host1x/drm/dc.h|  388 +++
 drivers/gpu/host1x/drm/drm.c   |  115 
 drivers/gpu/host1x/drm/drm.h   |  216 ++
 drivers/gpu/host1x/drm/fb.c|   56 ++
 drivers/gpu/host1x/drm/hdmi.c  | 1321 
 drivers/gpu/host1x/drm/hdmi.h  |  575 
 drivers/gpu/host1x/drm/host1x.c|  327 +
 drivers/gpu/host1x/drm/output.c|  272 
 drivers/gpu/host1x/drm/rgb.c   |  228 +++
 drivers/gpu/host1x/host1x_client.h |   25 +
 28 files changed, 4388 insertions(+), 4364 deletions(-)
 delete mode 100644 drivers/gpu/drm/tegra/Kconfig
 delete mode 100644 drivers/gpu/drm/tegra/Makefile
 delete mode 100644 drivers/gpu/drm/tegra/dc.c
 delete mode 100644 drivers/gpu/drm/tegra/dc.h
 delete mode 100644 drivers/gpu/drm/tegra/drm.c
 delete mode 100644 drivers/gpu/drm/tegra/drm.h
 delete mode 100644 drivers/gpu/drm/tegra/fb.c
 delete mode 100644 drivers/gpu/drm/tegra/hdmi.c
 delete mode 100644 drivers/gpu/drm/tegra/hdmi.h
 delete mode 100644 drivers/gpu/drm/tegra/host1x.c
 delete mode 100644 drivers/gpu/drm/tegra/output.c
 delete mode 100644 drivers/gpu/drm/tegra/rgb.c
 create mode 100644 drivers/gpu/host1x/drm/Kconfig
 create mode 100644 drivers/gpu/host1x/drm/dc.c
 create mode 100644 drivers/gpu/host1x/drm/dc.h
 create mode 100644 drivers/gpu/host1x/drm/drm.c
 create mode 100644 drivers/gpu/host1x/drm/drm.h
 create mode 100644 drivers/gpu/host1x/drm/fb.c
 create mode 100644 drivers/gpu/host1x/drm/hdmi.c
 create mode 100644 drivers/gpu/host1x/drm/hdmi.h
 create mode 100644 drivers/gpu/host1x/drm/host1x.c
 create mode 100644 drivers/gpu/host1x/drm/output.c
 create mode 100644 drivers/gpu/host1x/drm/rgb.c
 create mode 100644 drivers/gpu/host1x/host1x_client.h

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 983201b..18321b68b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -210,5 +210,3 @@ source "drivers/gpu/drm/mgag200/Kconfig"
 source "drivers/gpu/drm/cirrus/Kconfig"

 source "drivers/gpu/drm/shmobile/Kconfig"
-
-source "drivers/gpu/drm/tegra/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 6f58c81..f54c72a 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -49,5 +49,4 @@ obj-$(CONFIG_DRM_GMA500) += gma500/
 obj-$(CONFIG_DRM_UDL) += udl/
 obj-$(CONFIG_DRM_AST) += ast/
 obj-$(CONFIG_DRM_SHMOBILE) +=shmobile/
-obj-$(CONFIG_DRM_TEGRA) += tegra/
 obj-y  += i2c/
diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
deleted file mode 100644
index be1daf7..000
--- a/drivers/gpu/drm/tegra/Kconfig
+++ /dev/null
@@ -1,23 +0,0 @@
-config DRM_TEGRA
-   tristate "NVIDIA Tegra DRM"
-   depends on DRM && OF && ARCH_TEGRA
-   select DRM_KMS_HELPER
-   select DRM_GEM_CMA_HELPER
-   select DRM_KMS_CMA_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
-   help
- Choose this option if you have an NVIDIA Tegra SoC.
-
- To compile this driver as a module, choose M here: the module
- will be called tegra-drm.
-
-if DRM_TEGRA
-
-config DRM_TEGRA_DEBUG
-   bool "NVIDIA Tegra DRM debug support"
-   help
- Say yes here to enable debugging support.
-
-endif
diff --git a/drivers/gpu/drm/tegra/Makefile b/drivers/gpu/drm/tegra/Makefile
deleted file mode 100644
index 80f73d1..000
--- a/drivers/gpu/drm/tegra/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-ccflags-y := -Iinclude/drm
-ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
-
-tegra-drm-y := drm.o fb.o dc.o host1x.o
-tegra-drm-y += output.o rgb.o hdmi.o
-
-obj-$(CONFIG_DRM_TEGRA) += tegra-drm.o
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
deleted file mode 100644
index 656b2e3..000
--- a/drivers/gpu/drm/tegra/dc.c
+++ /dev/null
@@ -1,833 +0,0 @@

[PATCHv5 4/8] gpu: host1x: Add debug support

2013-01-15 Thread Terje Bergstrom
Add support for host1x debugging. Adds debugfs entries, and dumps
channel state to UART in case of stuck job.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile |1 +
 drivers/gpu/host1x/cdma.c   |   34 +++
 drivers/gpu/host1x/debug.c  |  215 ++
 drivers/gpu/host1x/debug.h  |   50 
 drivers/gpu/host1x/dev.c|3 +
 drivers/gpu/host1x/dev.h|   17 ++
 drivers/gpu/host1x/hw/cdma_hw.c |3 +
 drivers/gpu/host1x/hw/debug_hw.c|  400 +++
 drivers/gpu/host1x/hw/host1x01.c|2 +
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |   18 ++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  115 
 drivers/gpu/host1x/hw/syncpt_hw.c   |1 +
 drivers/gpu/host1x/syncpt.c |3 +
 13 files changed, 862 insertions(+)
 create mode 100644 drivers/gpu/host1x/debug.c
 create mode 100644 drivers/gpu/host1x/debug.h
 create mode 100644 drivers/gpu/host1x/hw/debug_hw.c

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index cdd87c8..697d49a 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -7,6 +7,7 @@ host1x-y = \
cdma.o \
channel.o \
job.o \
+   debug.o \
memmgr.o \
hw/host1x01.o

diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
index d6a38d2..12dd46c 100644
--- a/drivers/gpu/host1x/cdma.c
+++ b/drivers/gpu/host1x/cdma.c
@@ -19,6 +19,7 @@
 #include "cdma.h"
 #include "channel.h"
 #include "dev.h"
+#include "debug.h"
 #include "memmgr.h"
 #include "job.h"
 #include 
@@ -370,12 +371,42 @@ int host1x_cdma_begin(struct host1x_cdma *cdma, struct 
host1x_job *job)
return 0;
 }

+static void trace_write_gather(struct host1x_cdma *cdma,
+   struct mem_handle *ref,
+   u32 offset, u32 words)
+{
+   void *mem = NULL;
+
+   if (host1x_debug_trace_cmdbuf)
+   mem = host1x_memmgr_mmap(ref);
+
+   if (mem) {
+   u32 i;
+   /*
+* Write in batches of 128 as there seems to be a limit
+* of how much you can output to ftrace at once.
+*/
+   for (i = 0; i < words; i += TRACE_MAX_LENGTH) {
+   trace_host1x_cdma_push_gather(
+   cdma_to_channel(cdma)->dev->name,
+   (u32)ref,
+   min(words - i, TRACE_MAX_LENGTH),
+   offset + i * sizeof(u32),
+   mem);
+   }
+   host1x_memmgr_munmap(ref, mem);
+   }
+}
+
 /*
  * Push two words into a push buffer slot
  * Blocks as necessary if the push buffer is full.
  */
 void host1x_cdma_push(struct host1x_cdma *cdma, u32 op1, u32 op2)
 {
+   if (host1x_debug_trace_cmdbuf)
+   trace_host1x_cdma_push(cdma_to_channel(cdma)->dev->name,
+   op1, op2);
host1x_cdma_push_gather(cdma, NULL, 0, op1, op2);
 }

@@ -391,6 +422,9 @@ void host1x_cdma_push_gather(struct host1x_cdma *cdma,
u32 slots_free = cdma->slots_free;
struct push_buffer *pb = &cdma->push_buffer;

+   if (handle)
+   trace_write_gather(cdma, handle, offset, op1 & 0x);
+
if (slots_free == 0) {
host1x->cdma_op.kick(cdma);
slots_free = host1x_cdma_wait_locked(cdma,
diff --git a/drivers/gpu/host1x/debug.c b/drivers/gpu/host1x/debug.c
new file mode 100644
index 000..29cbe93
--- /dev/null
+++ b/drivers/gpu/host1x/debug.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ * Author: Erik Gilling 
+ *
+ * Copyright (C) 2011-2012 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+
+#include "dev.h"
+#include "debug.h"
+#include "channel.h"
+
+static pid_t host1x_debug_null_kickoff_pid;
+unsigned int host1x_debug_trace_cmdbuf;
+
+static pid_t host1x_debug_force_timeout_pid;
+static u32 host1x_debug_force_timeout_val;
+static u32 host1x_debug_force_timeout_channel;
+
+void host1x_debug_output(struct output *o, const char *fmt, ...)
+{
+   va_list args;
+   int len;
+
+   va_start(args, fmt);
+   len = vsnprintf(o->buf, sizeof(o->buf), fmt, args)

[PATCHv5 3/8] gpu: host1x: Add channel support

2013-01-15 Thread Terje Bergstrom
Add support for host1x client modules, and host1x channels to submit
work to the clients. The work is submitted in GEM CMA buffers, so
this patch adds support for them.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Kconfig  |   25 +-
 drivers/gpu/host1x/Makefile |5 +
 drivers/gpu/host1x/cdma.c   |  439 +++
 drivers/gpu/host1x/cdma.h   |  107 +
 drivers/gpu/host1x/channel.c|  140 ++
 drivers/gpu/host1x/channel.h|   58 +++
 drivers/gpu/host1x/cma.c|  116 +
 drivers/gpu/host1x/cma.h|   43 ++
 drivers/gpu/host1x/dev.c|   13 +
 drivers/gpu/host1x/dev.h|   59 +++
 drivers/gpu/host1x/host1x.h |   29 ++
 drivers/gpu/host1x/hw/cdma_hw.c |  475 +
 drivers/gpu/host1x/hw/cdma_hw.h |   37 ++
 drivers/gpu/host1x/hw/channel_hw.c  |  148 +++
 drivers/gpu/host1x/hw/host1x01.c|6 +
 drivers/gpu/host1x/hw/host1x01_hardware.h   |  124 ++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |  102 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|   12 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |  168 
 drivers/gpu/host1x/hw/syncpt_hw.c   |   10 +
 drivers/gpu/host1x/intr.c   |   29 +-
 drivers/gpu/host1x/intr.h   |6 +
 drivers/gpu/host1x/job.c|  612 +++
 drivers/gpu/host1x/job.h|  164 +++
 drivers/gpu/host1x/memmgr.c |  173 
 drivers/gpu/host1x/memmgr.h |   72 
 drivers/gpu/host1x/syncpt.c |   11 +
 drivers/gpu/host1x/syncpt.h |4 +
 include/trace/events/host1x.h   |  211 +
 29 files changed, 3396 insertions(+), 2 deletions(-)
 create mode 100644 drivers/gpu/host1x/cdma.c
 create mode 100644 drivers/gpu/host1x/cdma.h
 create mode 100644 drivers/gpu/host1x/channel.c
 create mode 100644 drivers/gpu/host1x/channel.h
 create mode 100644 drivers/gpu/host1x/cma.c
 create mode 100644 drivers/gpu/host1x/cma.h
 create mode 100644 drivers/gpu/host1x/host1x.h
 create mode 100644 drivers/gpu/host1x/hw/cdma_hw.c
 create mode 100644 drivers/gpu/host1x/hw/cdma_hw.h
 create mode 100644 drivers/gpu/host1x/hw/channel_hw.c
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_channel.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_uclass.h
 create mode 100644 drivers/gpu/host1x/job.c
 create mode 100644 drivers/gpu/host1x/job.h
 create mode 100644 drivers/gpu/host1x/memmgr.c
 create mode 100644 drivers/gpu/host1x/memmgr.h

diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
index e89fb2b..57680a6 100644
--- a/drivers/gpu/host1x/Kconfig
+++ b/drivers/gpu/host1x/Kconfig
@@ -3,4 +3,27 @@ config TEGRA_HOST1X
help
  Driver for the Tegra host1x hardware.

- Required for enabling tegradrm.
+ Required for enabling tegradrm and 2D acceleration.
+
+if TEGRA_HOST1X
+
+config TEGRA_HOST1X_CMA
+   bool "Support DRM CMA buffers"
+   depends on DRM
+   default y
+   select DRM_GEM_CMA_HELPER
+   select DRM_KMS_CMA_HELPER
+   help
+ Say yes if you wish to use DRM CMA buffers.
+
+ If unsure, choose Y.
+
+config TEGRA_HOST1X_FIREWALL
+   bool "Enable HOST1X security firewall"
+   default y
+   help
+ Say yes if kernel should protect command streams from tampering.
+
+ If unsure, choose Y.
+
+endif
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 5ef47ff..cdd87c8 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -4,6 +4,11 @@ host1x-y = \
syncpt.o \
dev.o \
intr.o \
+   cdma.o \
+   channel.o \
+   job.o \
+   memmgr.o \
hw/host1x01.o

+host1x-$(CONFIG_TEGRA_HOST1X_CMA) += cma.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/cdma.c b/drivers/gpu/host1x/cdma.c
new file mode 100644
index 000..d6a38d2
--- /dev/null
+++ b/drivers/gpu/host1x/cdma.c
@@ -0,0 +1,439 @@
+/*
+ * Tegra host1x Command DMA
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include &qu

[PATCHv5 2/8] gpu: host1x: Add syncpoint wait and interrupts

2013-01-15 Thread Terje Bergstrom
Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile  |1 +
 drivers/gpu/host1x/dev.c |   21 +-
 drivers/gpu/host1x/dev.h |   17 +-
 drivers/gpu/host1x/hw/host1x01.c |2 +
 drivers/gpu/host1x/hw/hw_host1x01_sync.h |   42 
 drivers/gpu/host1x/hw/intr_hw.c  |  178 +++
 drivers/gpu/host1x/intr.c|  356 ++
 drivers/gpu/host1x/intr.h|  103 +
 drivers/gpu/host1x/syncpt.c  |  163 ++
 drivers/gpu/host1x/syncpt.h  |5 +
 10 files changed, 883 insertions(+), 5 deletions(-)
 create mode 100644 drivers/gpu/host1x/hw/intr_hw.c
 create mode 100644 drivers/gpu/host1x/intr.c
 create mode 100644 drivers/gpu/host1x/intr.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index 363e6ab..5ef47ff 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -3,6 +3,7 @@ ccflags-y = -Idrivers/gpu/host1x
 host1x-y = \
syncpt.o \
dev.o \
+   intr.o \
hw/host1x01.o

 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index cd2b1ef..7f9f389 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include "dev.h"
+#include "intr.h"
 #include "hw/host1x01.h"

 #define CREATE_TRACE_POINTS
@@ -95,7 +96,6 @@ static int host1x_probe(struct platform_device *dev)

/* set common host1x device data */
platform_set_drvdata(dev, host);
-
host->regs = devm_request_and_ioremap(&dev->dev, regs);
if (!host->regs) {
dev_err(&dev->dev, "failed to remap host registers\n");
@@ -109,28 +109,40 @@ static int host1x_probe(struct platform_device *dev)
}

err = host1x_syncpt_init(host);
-   if (err)
+   if (err) {
+   dev_err(&dev->dev, "failed to init sync points");
return err;
+   }
+
+   err = host1x_intr_init(&host->intr, syncpt_irq);
+   if (err) {
+   dev_err(&dev->dev, "failed to init irq");
+   goto fail_deinit_syncpt;
+   }

host->clk = devm_clk_get(&dev->dev, NULL);
if (IS_ERR(host->clk)) {
dev_err(&dev->dev, "failed to get clock\n");
err = PTR_ERR(host->clk);
-   goto fail_deinit_syncpt;
+   goto fail_deinit_intr;
}

err = clk_prepare_enable(host->clk);
if (err < 0) {
dev_err(&dev->dev, "failed to enable clock\n");
-   goto fail_deinit_syncpt;
+   goto fail_deinit_intr;
}

host1x_syncpt_reset(host);

+   host1x_intr_start(&host->intr, clk_get_rate(host->clk));
+
dev_info(&dev->dev, "initialized\n");

return 0;

+fail_deinit_intr:
+   host1x_intr_deinit(&host->intr);
 fail_deinit_syncpt:
host1x_syncpt_deinit(host);
return err;
@@ -139,6 +151,7 @@ fail_deinit_syncpt:
 static int __exit host1x_remove(struct platform_device *dev)
 {
struct host1x *host = platform_get_drvdata(dev);
+   host1x_intr_deinit(&host->intr);
host1x_syncpt_deinit(host);
clk_disable_unprepare(host->clk);
return 0;
diff --git a/drivers/gpu/host1x/dev.h b/drivers/gpu/host1x/dev.h
index d8f5979..8376092 100644
--- a/drivers/gpu/host1x/dev.h
+++ b/drivers/gpu/host1x/dev.h
@@ -17,11 +17,12 @@
 #ifndef HOST1X_DEV_H
 #define HOST1X_DEV_H

+#include 
 #include "syncpt.h"
+#include "intr.h"

 struct host1x;
 struct host1x_syncpt;
-struct platform_device;

 struct host1x_syncpt_ops {
void (*reset)(struct host1x_syncpt *);
@@ -34,6 +35,18 @@ struct host1x_syncpt_ops {
const char * (*name)(struct host1x_syncpt *);
 };

+struct host1x_intr_ops {
+   void (*init_host_sync)(struct host1x_intr *);
+   void (*set_host_clocks_per_usec)(
+   struct host1x_intr *, u32 clocks);
+   void (*set_syncpt_threshold)(
+   struct host1x_intr *, u32 id, u32 thresh);
+   void (*enable_syncpt_intr)(struct host1x_intr *, u32 id);
+   void (*disable_syncpt_intr)(struct host1x_intr *, u32 id);
+   void (*disable_all_syncpt_intrs)(struct host1x_intr *);
+   int (*free_syncpt_irq)(struct host1x_intr *);
+};
+
 struct host1x_device_info {
int nb_channels;/* host1x: num channels supported */
int nb_pts; /* host1x: num syncpoints supported */
@@ -46,11 +59,13 @@ struct host1x_device_info {
 struct host1x {
void __iomem *r

[PATCHv5 1/8] gpu: host1x: Add host1x driver

2013-01-15 Thread Terje Bergstrom
Add host1x, the driver for host1x and its client unit 2D.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/Makefile  |1 +
 drivers/gpu/host1x/Kconfig|6 +
 drivers/gpu/host1x/Makefile   |8 ++
 drivers/gpu/host1x/dev.c  |  161 +
 drivers/gpu/host1x/dev.h  |   73 ++
 drivers/gpu/host1x/hw/Makefile|6 +
 drivers/gpu/host1x/hw/host1x01.c  |   35 +
 drivers/gpu/host1x/hw/host1x01.h  |   25 
 drivers/gpu/host1x/hw/host1x01_hardware.h |   26 
 drivers/gpu/host1x/hw/hw_host1x01_sync.h  |   72 ++
 drivers/gpu/host1x/hw/syncpt_hw.c |  146 +++
 drivers/gpu/host1x/syncpt.c   |  217 +
 drivers/gpu/host1x/syncpt.h   |  153 
 drivers/video/Kconfig |2 +
 include/trace/events/host1x.h |   61 
 15 files changed, 992 insertions(+)
 create mode 100644 drivers/gpu/host1x/Kconfig
 create mode 100644 drivers/gpu/host1x/Makefile
 create mode 100644 drivers/gpu/host1x/dev.c
 create mode 100644 drivers/gpu/host1x/dev.h
 create mode 100644 drivers/gpu/host1x/hw/Makefile
 create mode 100644 drivers/gpu/host1x/hw/host1x01.c
 create mode 100644 drivers/gpu/host1x/hw/host1x01.h
 create mode 100644 drivers/gpu/host1x/hw/host1x01_hardware.h
 create mode 100644 drivers/gpu/host1x/hw/hw_host1x01_sync.h
 create mode 100644 drivers/gpu/host1x/hw/syncpt_hw.c
 create mode 100644 drivers/gpu/host1x/syncpt.c
 create mode 100644 drivers/gpu/host1x/syncpt.h
 create mode 100644 include/trace/events/host1x.h

diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index cc92778..7e227097 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -1 +1,2 @@
 obj-y  += drm/ vga/ stub/
+obj-$(CONFIG_TEGRA_HOST1X) += host1x/
diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig
new file mode 100644
index 000..e89fb2b
--- /dev/null
+++ b/drivers/gpu/host1x/Kconfig
@@ -0,0 +1,6 @@
+config TEGRA_HOST1X
+   tristate "Tegra host1x driver"
+   help
+ Driver for the Tegra host1x hardware.
+
+ Required for enabling tegradrm.
diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
new file mode 100644
index 000..363e6ab
--- /dev/null
+++ b/drivers/gpu/host1x/Makefile
@@ -0,0 +1,8 @@
+ccflags-y = -Idrivers/gpu/host1x
+
+host1x-y = \
+   syncpt.o \
+   dev.o \
+   hw/host1x01.o
+
+obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
new file mode 100644
index 000..cd2b1ef
--- /dev/null
+++ b/drivers/gpu/host1x/dev.c
@@ -0,0 +1,161 @@
+/*
+ * Tegra host1x driver
+ *
+ * Copyright (c) 2010-2013, NVIDIA Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "dev.h"
+#include "hw/host1x01.h"
+
+#define CREATE_TRACE_POINTS
+#include 
+
+#define DRIVER_NAME"tegra-host1x"
+
+void host1x_sync_writel(struct host1x *host1x, u32 v, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info.sync_offset;
+
+   writel(v, sync_regs + r);
+}
+
+u32 host1x_sync_readl(struct host1x *host1x, u32 r)
+{
+   void __iomem *sync_regs = host1x->regs + host1x->info.sync_offset;
+
+   return readl(sync_regs + r);
+}
+
+static struct host1x_device_info host1x_info = {
+   .nb_channels= 8,
+   .nb_pts = 32,
+   .nb_mlocks  = 16,
+   .nb_bases   = 8,
+   .init   = host1x01_init,
+   .sync_offset= 0x3000,
+};
+
+static struct of_device_id host1x_match[] = {
+   { .compatible = "nvidia,tegra30-host1x", .data = &host1x_info, },
+   { .compatible = "nvidia,tegra20-host1x", .data = &host1x_info, },
+   { },
+};
+
+static int host1x_probe(struct platform_device *dev)
+{
+   struct host1x *host;
+   struct resource *regs;
+   int syncpt_irq;
+   int err;
+   const struct of_device_id *devid =
+   of_match_device(host1x_match, &dev->dev);
+
+   if (!devid)
+   return -EINVAL;
+
+   regs = platform_get_resource(dev, IORESOURCE_MEM, 0);
+   if 

[PATCHv5 0/8] Support for Tegra 2D hardware

2013-01-15 Thread Terje Bergstrom
This set of patches adds support for Tegra20 and Tegra30 host1x and
2D. It is based on linux-next-20130114.

The fifth version merges DRM and host1x drivers into one driver. This
allowed moving include/linux/host1x.h back into the driver and removed
the need for a dummy platform device. This version also uses the code
from tegradrm driver almost as is, so there are a lot less actual code
changes.

This patch set does not have the host1x allocator, but it uses CMA
helpers for memory management.

host1x is the driver that controls host1x hardware. It supports
host1x command channels, synchronization, and memory management. It
is sectioned into logical driver under drivers/gpu/host1x and
physical driver under drivers/host1x/hw. The physical driver is
compiled with the hardware headers of the particular host1x version.

The hardware units are described (briefly) in the Tegra2 TRM. Wiki
page https://gitorious.org/linux-tegra-drm/pages/Host1xIntroduction
also contains a short description of the functionality.

The patch set merges tegradrm into host1x and adds 2D driver, which
uses host1x channels and sync points. The patch set also adds user
space API to tegradrm for accessing host1x and 2D.

Terje Bergstrom (8):
  gpu: host1x: Add host1x driver
  gpu: host1x: Add syncpoint wait and interrupts
  gpu: host1x: Add channel support
  gpu: host1x: Add debug support
  drm: tegra: Move drm to live under host1x
  gpu: host1x: Remove second host1x driver
  ARM: tegra: Add board data and 2D clocks
  drm: tegra: Add gr2d device

 arch/arm/mach-tegra/board-dt-tegra20.c  |1 +
 arch/arm/mach-tegra/board-dt-tegra30.c  |1 +
 arch/arm/mach-tegra/tegra20_clocks_data.c   |2 +-
 arch/arm/mach-tegra/tegra30_clocks_data.c   |1 +
 drivers/gpu/Makefile|1 +
 drivers/gpu/drm/Kconfig |2 -
 drivers/gpu/drm/Makefile|1 -
 drivers/gpu/drm/tegra/Kconfig   |   23 -
 drivers/gpu/drm/tegra/Makefile  |7 -
 drivers/gpu/drm/tegra/dc.c  |  833 -
 drivers/gpu/drm/tegra/dc.h  |  388 
 drivers/gpu/drm/tegra/drm.c |  115 ---
 drivers/gpu/drm/tegra/drm.h |  216 -
 drivers/gpu/drm/tegra/fb.c  |   56 --
 drivers/gpu/drm/tegra/hdmi.c| 1321 --
 drivers/gpu/drm/tegra/hdmi.h|  575 
 drivers/gpu/drm/tegra/host1x.c  |  327 ---
 drivers/gpu/drm/tegra/output.c  |  272 --
 drivers/gpu/drm/tegra/rgb.c |  228 -
 drivers/gpu/host1x/Kconfig  |   32 +
 drivers/gpu/host1x/Makefile |   22 +
 drivers/gpu/host1x/cdma.c   |  473 ++
 drivers/gpu/host1x/cdma.h   |  107 +++
 drivers/gpu/host1x/channel.c|  140 +++
 drivers/gpu/host1x/channel.h|   58 ++
 drivers/gpu/host1x/cma.c|  116 +++
 drivers/gpu/host1x/cma.h|   43 +
 drivers/gpu/host1x/debug.c  |  215 +
 drivers/gpu/host1x/debug.h  |   50 +
 drivers/gpu/host1x/dev.c|  251 +
 drivers/gpu/host1x/dev.h|  170 
 drivers/gpu/host1x/drm/Kconfig  |   23 +
 drivers/gpu/host1x/drm/dc.c |  836 +
 drivers/gpu/host1x/drm/dc.h |  388 
 drivers/gpu/host1x/drm/drm.c|  548 +++
 drivers/gpu/host1x/drm/drm.h|  241 +
 drivers/gpu/host1x/drm/fb.c |   56 ++
 drivers/gpu/host1x/drm/gr2d.c   |  325 +++
 drivers/gpu/host1x/drm/hdmi.c   | 1324 +++
 drivers/gpu/host1x/drm/hdmi.h   |  575 
 drivers/gpu/host1x/drm/host1x.c |  327 +++
 drivers/gpu/host1x/drm/output.c |  272 ++
 drivers/gpu/host1x/drm/rgb.c|  228 +
 drivers/gpu/host1x/host1x.h |   29 +
 drivers/gpu/host1x/host1x_client.h  |   34 +
 drivers/gpu/host1x/hw/Makefile  |6 +
 drivers/gpu/host1x/hw/cdma_hw.c |  478 ++
 drivers/gpu/host1x/hw/cdma_hw.h |   37 +
 drivers/gpu/host1x/hw/channel_hw.c  |  148 +++
 drivers/gpu/host1x/hw/debug_hw.c|  400 
 drivers/gpu/host1x/hw/host1x01.c|   45 +
 drivers/gpu/host1x/hw/host1x01.h|   25 +
 drivers/gpu/host1x/hw/host1x01_hardware.h   |  150 +++
 drivers/gpu/host1x/hw/hw_host1x01_channel.h |  120 +++
 drivers/gpu/host1x/hw/hw_host1x01_sync.h|  241 +
 drivers/gpu/host1x/hw/hw_host1x01_uclass.h  |  168 
 drivers/gpu/host1x/hw/intr_hw.c |  178 
 drivers/gpu/host1x/hw/syncpt_hw.c   |  157 
 drivers/gpu/host1x/intr.c   |  383 
 drivers/gpu/host1x/intr.h

[PATCHv5,RESEND 8/8] drm: tegra: Add gr2d device

2013-01-15 Thread Terje Bergstrom
Add client driver for 2D device, and IOCTLs to pass work to host1x
channel for 2D.

Also adds functions that can be called to access sync points from DRM.

Signed-off-by: Terje Bergstrom 
---
 drivers/gpu/host1x/Makefile   |1 +
 drivers/gpu/host1x/dev.c  |7 +
 drivers/gpu/host1x/drm/drm.c  |  226 +++-
 drivers/gpu/host1x/drm/drm.h  |   28 
 drivers/gpu/host1x/drm/gr2d.c |  325 +
 drivers/gpu/host1x/syncpt.c   |5 +
 drivers/gpu/host1x/syncpt.h   |3 +
 include/drm/tegra_drm.h   |  131 +
 8 files changed, 725 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/host1x/drm/gr2d.c
 create mode 100644 include/drm/tegra_drm.h

diff --git a/drivers/gpu/host1x/Makefile b/drivers/gpu/host1x/Makefile
index c35ee19..c2120ad 100644
--- a/drivers/gpu/host1x/Makefile
+++ b/drivers/gpu/host1x/Makefile
@@ -18,4 +18,5 @@ ccflags-$(CONFIG_DRM_TEGRA_DEBUG) += -DDEBUG
 
 host1x-$(CONFIG_DRM_TEGRA) += drm/drm.o drm/fb.o drm/dc.o
 host1x-$(CONFIG_DRM_TEGRA) += drm/output.o drm/rgb.o drm/hdmi.o
+host1x-$(CONFIG_DRM_TEGRA) += drm/gr2d.o
 obj-$(CONFIG_TEGRA_HOST1X) += host1x.o
diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c
index 17ee01c..40d9938 100644
--- a/drivers/gpu/host1x/dev.c
+++ b/drivers/gpu/host1x/dev.c
@@ -214,11 +214,17 @@ static int __init tegra_host1x_init(void)
err = platform_driver_register(&tegra_hdmi_driver);
if (err < 0)
goto unregister_dc;
+
+   err = platform_driver_register(&tegra_gr2d_driver);
+   if (err < 0)
+   goto unregister_hdmi;
 #endif
 
return 0;
 
 #ifdef CONFIG_TEGRA_DRM
+unregister_hdmi:
+   platform_driver_unregister(&tegra_hdmi_driver);
 unregister_dc:
platform_driver_unregister(&tegra_dc_driver);
 unregister_host1x:
@@ -231,6 +237,7 @@ module_init(tegra_host1x_init);
 static void __exit tegra_host1x_exit(void)
 {
 #ifdef CONFIG_TEGRA_DRM
+   platform_driver_unregister(&tegra_gr2d_driver);
platform_driver_unregister(&tegra_hdmi_driver);
platform_driver_unregister(&tegra_dc_driver);
 #endif
diff --git a/drivers/gpu/host1x/drm/drm.c b/drivers/gpu/host1x/drm/drm.c
index bef9051..f8f8508 100644
--- a/drivers/gpu/host1x/drm/drm.c
+++ b/drivers/gpu/host1x/drm/drm.c
@@ -14,9 +14,11 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "drm.h"
 #include "host1x_client.h"
+#include "syncpt.h"
 
 #define DRIVER_NAME "tegra"
 #define DRIVER_DESC "NVIDIA Tegra graphics"
@@ -78,8 +80,10 @@ static int host1x_parse_dt(struct host1x *host1x)
static const char * const compat[] = {
"nvidia,tegra20-dc",
"nvidia,tegra20-hdmi",
+   "nvidia,tegra20-gr2d",
"nvidia,tegra30-dc",
"nvidia,tegra30-hdmi",
+   "nvidia,tegra30-gr2d",
};
unsigned int i;
int err;
@@ -270,7 +274,29 @@ static int tegra_drm_unload(struct drm_device *drm)
 
 static int tegra_drm_open(struct drm_device *drm, struct drm_file *filp)
 {
-   return 0;
+   struct host1x_drm_fpriv *fpriv;
+   int err = 0;
+
+   fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL);
+   if (!fpriv)
+   return -ENOMEM;
+
+   INIT_LIST_HEAD(&fpriv->contexts);
+   filp->driver_priv = fpriv;
+
+   return err;
+}
+
+static void tegra_drm_close(struct drm_device *drm, struct drm_file *filp)
+{
+   struct host1x_drm_fpriv *fpriv = host1x_drm_fpriv(filp);
+   struct host1x_drm_context *context, *tmp;
+
+   list_for_each_entry_safe(context, tmp, &fpriv->contexts, list) {
+   context->client->ops->close_channel(context);
+   kfree(context);
+   }
+   kfree(fpriv);
 }
 
 static void tegra_drm_lastclose(struct drm_device *drm)
@@ -280,7 +306,204 @@ static void tegra_drm_lastclose(struct drm_device *drm)
drm_fbdev_cma_restore_mode(host1x->fbdev);
 }
 
+static int
+tegra_drm_ioctl_syncpt_read(struct drm_device *drm, void *data,
+struct drm_file *file_priv)
+{
+   struct host1x *host1x = drm->dev_private;
+   struct tegra_drm_syncpt_read_args *args = data;
+   struct host1x_syncpt *sp =
+   host1x_syncpt_get_bydev(host1x->dev, args->id);
+
+   if (!sp)
+   return -EINVAL;
+
+   args->value = host1x_syncpt_read_min(sp);
+   return 0;
+}
+
+static int
+tegra_drm_ioctl_syncpt_incr(struct drm_device *drm, void *data,
+struct drm_file *file_priv)
+{
+   struct host1x *host1x = drm->dev_private;
+   struct tegra_drm_syncpt_incr_args *args = data;
+   struct host1x_syncpt *sp =
+   host1x_syncpt_get_bydev(host1x->dev, args->id);
+
+   if (!sp)
+  

  1   2   >