Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7ede0b0b authored by Terje Bergstrom's avatar Terje Bergstrom Committed by Thierry Reding
Browse files

gpu: host1x: Add syncpoint wait and interrupts



Add support for sync point interrupts, and sync point wait. Sync
point wait used interrupts for unblocking wait.

Signed-off-by: default avatarArto Merilainen <amerilainen@nvidia.com>
Signed-off-by: default avatarTerje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: default avatarThierry Reding <thierry.reding@avionic-design.de>
Tested-by: default avatarThierry Reding <thierry.reding@avionic-design.de>
Tested-by: default avatarErik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@avionic-design.de>
parent 75471687
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+12 −0
Original line number Diff line number Diff line
@@ -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);

+51 −0
Original line number Diff line number Diff line
@@ -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 host->intr_op->free_syncpt_irq(host);
}
#endif
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include "hw/host1x01_hardware.h"

/* include code */
#include "hw/intr_hw.c"
#include "hw/syncpt_hw.c"

#include "dev.h"
@@ -28,6 +29,7 @@
int host1x01_init(struct host1x *host)
{
	host->syncpt_op = &host1x_syncpt_ops;
	host->intr_op = &host1x_intr_ops;

	return 0;
}
+42 −0
Original line number Diff line number Diff line
@@ -59,6 +59,48 @@ static inline u32 host1x_sync_syncpt_r(unsigned int id)
}
#define HOST1X_SYNC_SYNCPT(id) \
	host1x_sync_syncpt_r(id)
static inline u32 host1x_sync_syncpt_thresh_cpu0_int_status_r(unsigned int id)
{
	return 0x40 + id * REGISTER_STRIDE;
}
#define HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(id) \
	host1x_sync_syncpt_thresh_cpu0_int_status_r(id)
static inline u32 host1x_sync_syncpt_thresh_int_disable_r(unsigned int id)
{
	return 0x60 + id * REGISTER_STRIDE;
}
#define HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(id) \
	host1x_sync_syncpt_thresh_int_disable_r(id)
static inline u32 host1x_sync_syncpt_thresh_int_enable_cpu0_r(unsigned int id)
{
	return 0x68 + id * REGISTER_STRIDE;
}
#define HOST1X_SYNC_SYNCPT_THRESH_INT_ENABLE_CPU0(id) \
	host1x_sync_syncpt_thresh_int_enable_cpu0_r(id)
static inline u32 host1x_sync_usec_clk_r(void)
{
	return 0x1a4;
}
#define HOST1X_SYNC_USEC_CLK \
	host1x_sync_usec_clk_r()
static inline u32 host1x_sync_ctxsw_timeout_cfg_r(void)
{
	return 0x1a8;
}
#define HOST1X_SYNC_CTXSW_TIMEOUT_CFG \
	host1x_sync_ctxsw_timeout_cfg_r()
static inline u32 host1x_sync_ip_busy_timeout_r(void)
{
	return 0x1bc;
}
#define HOST1X_SYNC_IP_BUSY_TIMEOUT \
	host1x_sync_ip_busy_timeout_r()
static inline u32 host1x_sync_syncpt_int_thresh_r(unsigned int id)
{
	return 0x500 + id * REGISTER_STRIDE;
}
#define HOST1X_SYNC_SYNCPT_INT_THRESH(id) \
	host1x_sync_syncpt_int_thresh_r(id)
static inline u32 host1x_sync_syncpt_base_r(unsigned int id)
{
	return 0x600 + id * REGISTER_STRIDE;
Loading