summaryrefslogtreecommitdiff
path: root/drivers/video
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2012-03-27 15:43:58 +0300
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-04-05 08:52:08 -0700
commit589961040a88d132939eb34d211d8e8b9921b446 (patch)
tree290195a349d77548add278918964ba18de8cc9af /drivers/video
parentb5e2ad69b5f5cc13f5a96b09335896d6d5dbed78 (diff)
video: tegra: host: Add syncpt sysfs entries
Expose sync point current and max values through sysfs. Bug 957639 Change-Id: I2a3b914d404bb8d7bbed86d383c859bd8237a278 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/92778 Reviewed-by: Rohan Somvanshi <rsomvanshi@nvidia.com> Tested-by: Rohan Somvanshi <rsomvanshi@nvidia.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/tegra/host/dev.c33
-rw-r--r--drivers/video/tegra/host/host1x/host1x_syncpt.c4
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.c124
-rw-r--r--drivers/video/tegra/host/nvhost_syncpt.h13
4 files changed, 145 insertions, 29 deletions
diff --git a/drivers/video/tegra/host/dev.c b/drivers/video/tegra/host/dev.c
index 0425368e6f81..50d8d2dbe07b 100644
--- a/drivers/video/tegra/host/dev.c
+++ b/drivers/video/tegra/host/dev.c
@@ -367,20 +367,8 @@ static void nvhost_remove_chip_support(struct nvhost_master *host)
kfree(host->channels);
host->channels = 0;
- kfree(host->syncpt.min_val);
- host->syncpt.min_val = 0;
-
- kfree(host->syncpt.max_val);
- host->syncpt.max_val = 0;
-
- kfree(host->syncpt.base_val);
- host->syncpt.base_val = 0;
-
kfree(host->intr.syncpt);
host->intr.syncpt = 0;
-
- kfree(host->syncpt.lock_counts);
- host->syncpt.lock_counts = 0;
}
static int __devinit nvhost_init_chip_support(struct nvhost_master *host)
@@ -405,24 +393,10 @@ static int __devinit nvhost_init_chip_support(struct nvhost_master *host)
host->channels = kzalloc(sizeof(struct nvhost_channel) *
host->nb_channels, GFP_KERNEL);
- host->syncpt.min_val = kzalloc(sizeof(atomic_t) *
- host->syncpt.nb_pts, GFP_KERNEL);
-
- host->syncpt.max_val = kzalloc(sizeof(atomic_t) *
- host->syncpt.nb_pts, GFP_KERNEL);
-
- host->syncpt.base_val = kzalloc(sizeof(u32) *
- host->syncpt.nb_bases, GFP_KERNEL);
-
host->intr.syncpt = kzalloc(sizeof(struct nvhost_intr_syncpt) *
host->syncpt.nb_pts, GFP_KERNEL);
- host->syncpt.lock_counts = kzalloc(sizeof(atomic_t) *
- host->syncpt.nb_mlocks, GFP_KERNEL);
-
- if (!(host->channels && host->syncpt.min_val &&
- host->syncpt.max_val && host->syncpt.base_val &&
- host->intr.syncpt && host->syncpt.lock_counts)) {
+ if (!(host->channels && host->intr.syncpt)) {
/* frees happen in the support removal phase */
return -ENOMEM;
}
@@ -539,6 +513,10 @@ static int __devinit nvhost_probe(struct nvhost_device *dev)
nvhost_bus_add_host(host);
+ err = nvhost_syncpt_init(&tegra_grhost_device, &host->syncpt);
+ if (err)
+ goto fail;
+
err = nvhost_intr_init(&host->intr, intr1->start, intr0->start);
if (err)
goto fail;
@@ -574,6 +552,7 @@ static int __exit nvhost_remove(struct nvhost_device *dev)
{
struct nvhost_master *host = nvhost_get_drvdata(dev);
nvhost_intr_deinit(&host->intr);
+ nvhost_syncpt_deinit(&host->syncpt);
nvhost_remove_chip_support(host);
return 0;
}
diff --git a/drivers/video/tegra/host/host1x/host1x_syncpt.c b/drivers/video/tegra/host/host1x/host1x_syncpt.c
index b0fd9970aaa0..b431fa350638 100644
--- a/drivers/video/tegra/host/host1x/host1x_syncpt.c
+++ b/drivers/video/tegra/host/host1x/host1x_syncpt.c
@@ -71,8 +71,10 @@ static u32 t20_syncpt_update_min(struct nvhost_syncpt *sp, u32 id)
if (!nvhost_syncpt_check_max(sp, id, live))
dev_err(&syncpt_to_dev(sp)->dev->dev,
- "%s failed: id=%u\n",
+ "%s failed: id=%u, min=%d, max=%d\n",
__func__,
+ nvhost_syncpt_read_min(sp, id),
+ nvhost_syncpt_read_max(sp, id),
id);
return live;
diff --git a/drivers/video/tegra/host/nvhost_syncpt.c b/drivers/video/tegra/host/nvhost_syncpt.c
index eb5176ea1bf5..13ad0fc3a3cf 100644
--- a/drivers/video/tegra/host/nvhost_syncpt.c
+++ b/drivers/video/tegra/host/nvhost_syncpt.c
@@ -20,10 +20,15 @@
#include <linux/nvhost_ioctl.h>
#include <linux/platform_device.h>
+#include <linux/slab.h>
#include "nvhost_syncpt.h"
#include "dev.h"
#define MAX_STUCK_CHECK_COUNT 15
+#define MAX_SYNCPT_LENGTH 5
+/* Name of sysfs node for min and max value */
+static const char *min_name = "min";
+static const char *max_name = "max";
/**
* Resets syncpoint and waitbase values to sw shadows
@@ -317,3 +322,122 @@ int nvhost_syncpt_wait_check(struct nvhost_syncpt *sp,
return syncpt_op(sp).wait_check(sp, nvmap,
waitchk_mask, wait, num_waitchk);
}
+
+/* Displays the current value of the sync point via sysfs */
+static ssize_t syncpt_min_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct nvhost_syncpt_attr *syncpt_attr =
+ container_of(attr, struct nvhost_syncpt_attr, attr);
+
+ return snprintf(buf, PAGE_SIZE, "%d",
+ nvhost_syncpt_read(&syncpt_attr->host->syncpt,
+ syncpt_attr->id));
+}
+
+static ssize_t syncpt_max_show(struct kobject *kobj,
+ struct kobj_attribute *attr, char *buf)
+{
+ struct nvhost_syncpt_attr *syncpt_attr =
+ container_of(attr, struct nvhost_syncpt_attr, attr);
+
+ return snprintf(buf, PAGE_SIZE, "%d",
+ nvhost_syncpt_read_max(&syncpt_attr->host->syncpt,
+ syncpt_attr->id));
+}
+
+int nvhost_syncpt_init(struct nvhost_device *dev,
+ struct nvhost_syncpt *sp)
+{
+ int i;
+ struct nvhost_master *host = syncpt_to_dev(sp);
+ int err = 0;
+
+ /* Allocate structs for min, max and base values */
+ sp->min_val = kzalloc(sizeof(atomic_t) * sp->nb_pts, GFP_KERNEL);
+ sp->max_val = kzalloc(sizeof(atomic_t) * sp->nb_pts, GFP_KERNEL);
+ sp->base_val = kzalloc(sizeof(u32) * sp->nb_bases, GFP_KERNEL);
+ sp->lock_counts = kzalloc(sizeof(atomic_t) * sp->nb_mlocks, GFP_KERNEL);
+
+ if (!(sp->min_val && sp->max_val && sp->base_val && sp->lock_counts)) {
+ /* frees happen in the deinit */
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ sp->kobj = kobject_create_and_add("syncpt", &dev->dev.kobj);
+ if (!sp->kobj) {
+ err = -EIO;
+ goto fail;
+ }
+
+ /* Allocate two attributes for each sync point: min and max */
+ sp->syncpt_attrs = kzalloc(sizeof(*sp->syncpt_attrs) * sp->nb_pts * 2,
+ GFP_KERNEL);
+ if (!sp->syncpt_attrs) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ /* Fill in the attributes */
+ for (i = 0; i < sp->nb_pts; i++) {
+ char name[MAX_SYNCPT_LENGTH];
+ struct kobject *kobj;
+ struct nvhost_syncpt_attr *min = &sp->syncpt_attrs[i*2];
+ struct nvhost_syncpt_attr *max = &sp->syncpt_attrs[i*2+1];
+
+ /* Create one directory per sync point */
+ snprintf(name, sizeof(name), "%d", i);
+ kobj = kobject_create_and_add(name, sp->kobj);
+ if (!kobj) {
+ err = -EIO;
+ goto fail;
+ }
+
+ min->id = i;
+ min->host = host;
+ min->attr.attr.name = min_name;
+ min->attr.attr.mode = S_IRUGO;
+ min->attr.show = syncpt_min_show;
+ if (sysfs_create_file(kobj, &min->attr.attr)) {
+ err = -EIO;
+ goto fail;
+ }
+
+ max->id = i;
+ max->host = host;
+ max->attr.attr.name = max_name;
+ max->attr.attr.mode = S_IRUGO;
+ max->attr.show = syncpt_max_show;
+ if (sysfs_create_file(kobj, &max->attr.attr)) {
+ err = -EIO;
+ goto fail;
+ }
+ }
+
+ return err;
+
+fail:
+ nvhost_syncpt_deinit(sp);
+ return err;
+}
+
+void nvhost_syncpt_deinit(struct nvhost_syncpt *sp)
+{
+ kobject_put(sp->kobj);
+
+ kfree(sp->min_val);
+ sp->min_val = NULL;
+
+ kfree(sp->max_val);
+ sp->max_val = NULL;
+
+ kfree(sp->base_val);
+ sp->base_val = NULL;
+
+ kfree(sp->lock_counts);
+ sp->lock_counts = 0;
+
+ kfree(sp->syncpt_attrs);
+ sp->syncpt_attrs = NULL;
+}
diff --git a/drivers/video/tegra/host/nvhost_syncpt.h b/drivers/video/tegra/host/nvhost_syncpt.h
index 5b339178d1e1..b71cb3e6287e 100644
--- a/drivers/video/tegra/host/nvhost_syncpt.h
+++ b/drivers/video/tegra/host/nvhost_syncpt.h
@@ -34,7 +34,15 @@ struct nvhost_waitchk;
#define NVSYNCPT_GRAPHICS_HOST (0)
#define NVSYNCPT_INVALID (-1)
+/* Attribute struct for sysfs min and max attributes */
+struct nvhost_syncpt_attr {
+ struct kobj_attribute attr;
+ struct nvhost_master *host;
+ int id;
+};
+
struct nvhost_syncpt {
+ struct kobject *kobj;
atomic_t *min_val;
atomic_t *max_val;
u32 *base_val;
@@ -43,9 +51,12 @@ struct nvhost_syncpt {
u32 client_managed;
atomic_t *lock_counts;
u32 nb_mlocks;
+ struct nvhost_syncpt_attr *syncpt_attrs;
};
-int nvhost_syncpt_init(struct nvhost_syncpt *);
+int nvhost_syncpt_init(struct nvhost_device *, struct nvhost_syncpt *);
+void nvhost_syncpt_deinit(struct nvhost_syncpt *);
+
#define client_managed(id) (BIT(id) & sp->client_managed)
#define syncpt_to_dev(sp) container_of(sp, struct nvhost_master, syncpt)
#define syncpt_op(sp) (syncpt_to_dev(sp)->op.syncpt)