[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(>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 host1x *host)
+{
+   return host->intr_op->free_syncpt_irq(host);
+}
 #endif
diff --git 

[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 amerilai...@nvidia.com
Signed-off-by: Terje Bergstrom tbergst...@nvidia.com
---
 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 trace/events/host1x.h
 
 #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 linux/device.h
 
 #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 host1x *host)
+{
+   return